mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Bug 753283 - Highlight missing when returning from schedule edit.
When you return from editing a scheduled transaction the highlight is missing in the tree view. This is partly due to the model being recreated when ever a change is made to a scheduled transaction. To overcome this, the selected schedules are added to a GList which is used in a new call back signal that has been added to indicate when the model is populated. When this happens, the model is scanned for the schedules that are in the GList so they can be reselected.
This commit is contained in:
parent
33b8a19253
commit
c2a7b8eaaf
@ -52,6 +52,16 @@ struct _GncSxListTreeModelAdapter
|
||||
struct _GncSxListTreeModelAdapterClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
|
||||
/* This signal is emitted when the model is populated */
|
||||
void (*model_populated) (GncSxListTreeModelAdapter *model, gpointer user_data);
|
||||
};
|
||||
|
||||
/* Signal codes */
|
||||
enum
|
||||
{
|
||||
MODEL_POPULATED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
@ -63,6 +73,8 @@ static void gnc_sx_list_tree_model_adapter_init(GTypeInstance *instance, gpointe
|
||||
static void gnc_sx_list_tree_model_adapter_dispose(GObject *obj);
|
||||
static void gnc_sx_list_tree_model_adapter_finalize(GObject *obj);
|
||||
|
||||
static guint gnc_sx_list_tree_model_adapter_signals[LAST_SIGNAL] = {0};
|
||||
|
||||
static GncSxInstances* gsltma_get_sx_instances_from_orig_iter(GncSxListTreeModelAdapter *model, GtkTreeIter *orig_iter);
|
||||
|
||||
GType
|
||||
@ -119,6 +131,16 @@ gnc_sx_list_tree_model_adapter_class_init(GncSxListTreeModelAdapterClass *klass)
|
||||
obj_class->dispose = gnc_sx_list_tree_model_adapter_dispose;
|
||||
obj_class->finalize = gnc_sx_list_tree_model_adapter_finalize;
|
||||
|
||||
gnc_sx_list_tree_model_adapter_signals[MODEL_POPULATED] =
|
||||
g_signal_new("model_populated",
|
||||
G_TYPE_FROM_CLASS (obj_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GncSxListTreeModelAdapterClass, model_populated),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
klass->model_populated = NULL;
|
||||
}
|
||||
|
||||
static GtkTreeModelFlags
|
||||
@ -525,6 +547,7 @@ gsltma_populate_tree_store(GncSxListTreeModelAdapter *model)
|
||||
-1);
|
||||
g_free(frequency_str);
|
||||
}
|
||||
g_signal_emit_by_name (model, "model_populated");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -95,6 +95,7 @@ typedef struct GncPluginPageSxListPrivate
|
||||
|
||||
GncSxInstanceModel* instances;
|
||||
GtkTreeView* tree_view;
|
||||
GList *selected_list;
|
||||
|
||||
} GncPluginPageSxListPrivate;
|
||||
|
||||
@ -351,6 +352,64 @@ gppsl_selection_changed_cb(GtkTreeSelection *selection, gpointer user_data)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gppsl_update_selected_list (GncPluginPageSxList *page, gboolean reset, SchedXaction *sx)
|
||||
{
|
||||
GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
|
||||
if (reset && priv->selected_list)
|
||||
{
|
||||
g_list_free (priv->selected_list);
|
||||
priv->selected_list = NULL;
|
||||
}
|
||||
if (sx)
|
||||
priv->selected_list = g_list_prepend (priv->selected_list, sx);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gppsl_model_populated_cb (GtkTreeModel *tree_model, GncPluginPageSxList *page)
|
||||
{
|
||||
GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->tree_view));
|
||||
gboolean found = FALSE;
|
||||
|
||||
if (priv->selected_list)
|
||||
{
|
||||
// walk the list to see if we can reselect the sx
|
||||
for (GList *list = priv->selected_list; list != NULL; list = list->next)
|
||||
{
|
||||
SchedXaction *sx = list->data;
|
||||
GtkTreePath *path = gtk_tree_path_new_first ();
|
||||
|
||||
// loop through the model trying to find selected sx's
|
||||
while (gnc_tree_view_path_is_valid (GNC_TREE_VIEW(priv->tree_view), path))
|
||||
{
|
||||
SchedXaction *sx_tmp = gnc_tree_view_sx_list_get_sx_from_path (
|
||||
GNC_TREE_VIEW_SX_LIST(priv->tree_view), path);
|
||||
if (sx_tmp == sx)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
gtk_tree_path_next (path);
|
||||
}
|
||||
if (found)
|
||||
gtk_tree_selection_select_path (selection, path);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
}
|
||||
// this could be on load or if sx is deleted
|
||||
if (!found)
|
||||
{
|
||||
GtkTreePath *path = gtk_tree_path_new_first ();
|
||||
gtk_tree_selection_select_path (selection, path);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static GtkWidget *
|
||||
gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
|
||||
{
|
||||
@ -420,6 +479,7 @@ gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
|
||||
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreePath *path = gtk_tree_path_new_first ();
|
||||
|
||||
priv->tree_view = GTK_TREE_VIEW(gnc_tree_view_sx_list_new(priv->instances));
|
||||
g_object_set(G_OBJECT(priv->tree_view),
|
||||
@ -430,8 +490,13 @@ gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
|
||||
|
||||
selection = gtk_tree_view_get_selection(priv->tree_view);
|
||||
gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
|
||||
gtk_tree_selection_select_path (selection, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
g_signal_connect(G_OBJECT(selection), "changed", (GCallback)gppsl_selection_changed_cb, (gpointer)page);
|
||||
g_signal_connect(G_OBJECT(priv->tree_view), "row-activated", (GCallback)gppsl_row_activated_cb, (gpointer)page);
|
||||
g_signal_connect (G_OBJECT(gtk_tree_view_get_model (GTK_TREE_VIEW(priv->tree_view))),
|
||||
"model-populated", (GCallback)gppsl_model_populated_cb, (gpointer)page);
|
||||
}
|
||||
|
||||
/* Add vbox and label */
|
||||
@ -503,6 +568,9 @@ gnc_plugin_page_sx_list_destroy_widget (GncPluginPage *plugin_page)
|
||||
priv->widget = NULL;
|
||||
}
|
||||
|
||||
if (priv->selected_list)
|
||||
g_list_free (priv->selected_list);
|
||||
|
||||
if (priv->gnc_component_id)
|
||||
{
|
||||
gnc_unregister_gui_component(priv->gnc_component_id);
|
||||
@ -611,6 +679,7 @@ gnc_plugin_page_sx_list_cmd_new(GtkAction *action, GncPluginPageSxList *page)
|
||||
gnc_sx_set_schedule(new_sx, schedule);
|
||||
}
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create(window, new_sx, new_sx_flag);
|
||||
gppsl_update_selected_list (page, TRUE, new_sx);
|
||||
}
|
||||
|
||||
#ifdef REGISTER2_ENABLED
|
||||
@ -696,6 +765,14 @@ gnc_plugin_page_sx_list_cmd_edit(GtkAction *action, GncPluginPageSxList *page)
|
||||
to_edit = gnc_g_list_map(selected_paths,
|
||||
(GncGMapFunc)_argument_reorder_fn,
|
||||
priv->tree_view);
|
||||
|
||||
gppsl_update_selected_list (page, TRUE, NULL);
|
||||
for (GList *list = to_edit; list != NULL; list = list->next)
|
||||
{
|
||||
g_debug("to-edit [%s]\n", xaccSchedXactionGetName ((SchedXaction*)list->data));
|
||||
gppsl_update_selected_list (page, FALSE, list->data);
|
||||
}
|
||||
|
||||
g_list_foreach(to_edit, (GFunc)_edit_sx, window);
|
||||
g_list_free(to_edit);
|
||||
g_list_foreach(selected_paths, (GFunc)gtk_tree_path_free, NULL);
|
||||
@ -744,6 +821,7 @@ gppsl_row_activated_cb(GtkTreeView *tree_view,
|
||||
|
||||
SchedXaction *sx = gnc_tree_view_sx_list_get_sx_from_path(GNC_TREE_VIEW_SX_LIST(priv->tree_view), path);
|
||||
gnc_ui_scheduled_xaction_editor_dialog_create(window, sx, FALSE);
|
||||
gppsl_update_selected_list (page, TRUE, sx);
|
||||
}
|
||||
|
||||
|
||||
@ -769,6 +847,8 @@ gnc_plugin_page_sx_list_cmd_delete(GtkAction *action, GncPluginPageSxList *page)
|
||||
GList *selected_paths, *to_delete = NULL;
|
||||
GtkTreeModel *model;
|
||||
GtkWindow *window;
|
||||
gchar *message = NULL;
|
||||
gint length;
|
||||
|
||||
selection = gtk_tree_view_get_selection(priv->tree_view);
|
||||
selected_paths = gtk_tree_selection_get_selected_rows(selection, &model);
|
||||
@ -781,24 +861,28 @@ gnc_plugin_page_sx_list_cmd_delete(GtkAction *action, GncPluginPageSxList *page)
|
||||
to_delete = gnc_g_list_map(selected_paths,
|
||||
(GncGMapFunc)_argument_reorder_fn,
|
||||
priv->tree_view);
|
||||
{
|
||||
GList *list;
|
||||
for (list = to_delete; list != NULL; list = list->next)
|
||||
{
|
||||
g_debug("to-delete [%s]\n", xaccSchedXactionGetName((SchedXaction*)list->data));
|
||||
}
|
||||
}
|
||||
|
||||
window = GTK_WINDOW (gnc_plugin_page_get_window (GNC_PLUGIN_PAGE (page)));
|
||||
/* FIXME: Does this always refer to only one transaction? Or could
|
||||
multiple SXs be deleted as well? Ideally, the number of
|
||||
to-be-deleted SXs should be mentioned here; see
|
||||
dialog-sx-since-last-run.c:807 */
|
||||
if (gnc_verify_dialog (window, FALSE, "%s", _("Do you really want to delete this scheduled transaction?")))
|
||||
|
||||
length = g_list_length (to_delete);
|
||||
|
||||
/* Translators: This is a ngettext(3) message, %d is the number of scheduled transactions deleted */
|
||||
message = g_strdup_printf (ngettext ("Do you really want to delete this scheduled transaction?",
|
||||
"Do you really want to delete %d scheduled transactions?",
|
||||
length), length);
|
||||
|
||||
if (gnc_verify_dialog (window, FALSE, "%s", message))
|
||||
{
|
||||
gppsl_update_selected_list (page, TRUE, NULL);
|
||||
for (GList *list = to_delete; list != NULL; list = list->next)
|
||||
{
|
||||
g_debug("to-delete [%s]\n", xaccSchedXactionGetName((SchedXaction*)list->data));
|
||||
gppsl_update_selected_list (page, FALSE, list->data);
|
||||
}
|
||||
g_list_foreach(to_delete, (GFunc)_destroy_sx, NULL);
|
||||
}
|
||||
|
||||
g_free (message);
|
||||
g_list_free(to_delete);
|
||||
g_list_foreach(selected_paths, (GFunc)gtk_tree_path_free, NULL);
|
||||
g_list_free(selected_paths);
|
||||
|
Loading…
Reference in New Issue
Block a user