diff --git a/src/gnome/reconcile-view.c b/src/gnome/reconcile-view.c index d51c23d548..cd2ba548d2 100644 --- a/src/gnome/reconcile-view.c +++ b/src/gnome/reconcile-view.c @@ -87,7 +87,6 @@ gnc_reconcile_view_get_type (void) "GncReconcileView", &gnc_reconcile_view_info, 0); } - return gnc_reconcile_view_type; } @@ -122,7 +121,7 @@ gnc_reconcile_view_construct (GNCReconcileView *view, Query *query) /* Set the selection method */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (qview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); /* Now set up the signals for the QueryView */ g_signal_connect (G_OBJECT (qview), "column_toggled", @@ -135,6 +134,7 @@ gnc_reconcile_view_construct (GNCReconcileView *view, Query *query) G_CALLBACK(gnc_reconcile_view_key_press_cb), view); } + GtkWidget * gnc_reconcile_view_new (Account *account, GNCReconcileViewType type, time_t statement_date) @@ -420,7 +420,7 @@ gnc_reconcile_view_double_click_entry (GNCQueryView *qview, gpointer user_data) { GNCReconcileView *view; - + /* item is the entry */ g_return_if_fail (user_data); g_return_if_fail (GNC_IS_QUERY_VIEW (qview)); @@ -437,7 +437,7 @@ gnc_reconcile_view_row_selected (GNCQueryView *qview, gpointer user_data) { GNCReconcileView *view; - + /* item is the number of selected entries */ g_return_if_fail(user_data); g_return_if_fail(GNC_IS_QUERY_VIEW(qview)); @@ -448,6 +448,99 @@ gnc_reconcile_view_row_selected (GNCQueryView *qview, } +void +gnc_reconcile_view_set_list ( GNCReconcileView *view, gboolean reconcile) +{ + GNCQueryView *qview = GNC_QUERY_VIEW(view); + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + gpointer entry; + gboolean toggled; + GList *node; + GList *list_of_rows; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (qview)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (qview)); + list_of_rows = gtk_tree_selection_get_selected_rows (selection, &model); + + /* We get a list of TreePaths */ + for(node = list_of_rows; node; node = node->next) + { + GtkTreeIter iter; + if(gtk_tree_model_get_iter(model, &iter, node->data)) + { + /* now iter is a valid row iterator */ + gtk_tree_model_get (model, &iter, 0, &entry, -1); + gtk_tree_model_get (model, &iter, 5, &toggled, -1); + + if(reconcile) + gtk_list_store_set (GTK_LIST_STORE (model), &iter, 5, 1, -1); + else + gtk_list_store_set (GTK_LIST_STORE (model), &iter, 5, 0, -1); + + if(reconcile != toggled) + gnc_reconcile_view_toggle (view, entry); + } + gtk_tree_path_free(node->data); + } + g_list_free(list_of_rows); +} + + +gint +gnc_reconcile_view_num_selected (GNCReconcileView *view ) +{ + GNCQueryView *qview = GNC_QUERY_VIEW(view); + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (qview)); + return gtk_tree_selection_count_selected_rows (selection); +} + + +static gboolean +gnc_reconcile_view_set_toggle (GNCReconcileView *view) +{ + GNCQueryView *qview = GNC_QUERY_VIEW(view); + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean toggled; + GList *node; + GList *list_of_rows; + gint num_toggled = 0; + gint num_selected = 0; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (qview)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (qview)); + list_of_rows = gtk_tree_selection_get_selected_rows (selection, &model); + num_selected = gtk_tree_selection_count_selected_rows (selection); + + /* We get a list of TreePaths */ + for(node = list_of_rows; node; node = node->next) + { + GtkTreeIter iter; + toggled = FALSE; + if(gtk_tree_model_get_iter(model, &iter, node->data)) + { + /* now iter is a valid row iterator */ + gtk_tree_model_get (model, &iter, 5, &toggled, -1); + + if(toggled) + num_toggled++; + } + gtk_tree_path_free(node->data); + } + g_list_free(list_of_rows); + + if(num_toggled == num_selected) + return FALSE; + else + return TRUE; +} + + static gboolean gnc_reconcile_view_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data) @@ -464,33 +557,44 @@ gnc_reconcile_view_key_press_cb (GtkWidget *widget, GdkEventKey *event, case GDK_space: g_signal_stop_emission_by_name (widget, "key_press_event"); - entry = gnc_query_view_get_selected_entry (qview); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (qview)); - valid = gtk_tree_model_get_iter_first (model, &iter); - - while (valid) + if (gnc_reconcile_view_num_selected (view) == 1) { - /* Walk through the list, reading each row, column 0 - has a pointer to the required entry */ - gtk_tree_model_get (model, &iter, 0, &pointer, -1); - if(pointer == entry) + entry = gnc_query_view_get_selected_entry (qview); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (qview)); + valid = gtk_tree_model_get_iter_first (model, &iter); + + while (valid) { - /* Column 5 is the toggle column */ - gtk_tree_model_get (model, &iter, 5, &toggle, -1); + /* Walk through the list, reading each row, column 0 + has a pointer to the required entry */ + gtk_tree_model_get (model, &iter, 0, &pointer, -1); - if(toggle) - gtk_list_store_set (GTK_LIST_STORE (model), &iter, 5, 0, -1); - else - gtk_list_store_set (GTK_LIST_STORE (model), &iter, 5, 1, -1); + if(pointer == entry) + { + /* Column 5 is the toggle column */ + gtk_tree_model_get (model, &iter, 5, &toggle, -1); + + if(toggle) + gtk_list_store_set (GTK_LIST_STORE (model), &iter, 5, 0, -1); + else + gtk_list_store_set (GTK_LIST_STORE (model), &iter, 5, 1, -1); + } + valid = gtk_tree_model_iter_next (model, &iter); } - valid = gtk_tree_model_iter_next (model, &iter); - } - gnc_reconcile_view_toggle (view, entry); + gnc_reconcile_view_toggle (view, entry); - return TRUE; - break; + return TRUE; + break; + } + else + { + toggle = gnc_reconcile_view_set_toggle (view); + gnc_reconcile_view_set_list (view, toggle); + return TRUE; + break; + } default: return FALSE; @@ -508,7 +612,6 @@ gnc_reconcile_view_finalize (GObject *object) g_hash_table_destroy (view->reconciled); view->reconciled = NULL; } - G_OBJECT_CLASS (parent_class)->finalize (object); } diff --git a/src/gnome/reconcile-view.h b/src/gnome/reconcile-view.h index 8aa48a9129..36ef15f483 100644 --- a/src/gnome/reconcile-view.h +++ b/src/gnome/reconcile-view.h @@ -64,7 +64,7 @@ typedef struct GtkTreeViewClass parent_class; void (*toggle_reconciled) (GNCReconcileView *view, Split *split); - void (*line_selected) (GNCReconcileView *view, Split *split); + void (*line_selected) (GNCReconcileView *view, gpointer item); void (*double_click_split) (GNCReconcileView *view, Split *split); } GNCReconcileViewClass; @@ -82,8 +82,12 @@ GtkWidget * gnc_reconcile_view_new (Account * account, gint gnc_reconcile_view_get_num_splits (GNCReconcileView *view); +gint gnc_reconcile_view_num_selected (GNCReconcileView *view ); + Split * gnc_reconcile_view_get_current_split (GNCReconcileView *view); +void gnc_reconcile_view_set_list (GNCReconcileView *view, gboolean reconcile); + void gnc_reconcile_view_refresh (GNCReconcileView *view); gnc_numeric gnc_reconcile_view_reconciled_balance (GNCReconcileView *view); diff --git a/src/gnome/ui/gnc-reconcile-window-ui.xml b/src/gnome/ui/gnc-reconcile-window-ui.xml index e4aa826a06..5c9c721adf 100644 --- a/src/gnome/ui/gnc-reconcile-window-ui.xml +++ b/src/gnome/ui/gnc-reconcile-window-ui.xml @@ -21,6 +21,8 @@ + + @@ -32,6 +34,8 @@ + + @@ -39,6 +43,8 @@ + + diff --git a/src/gnome/window-reconcile.c b/src/gnome/window-reconcile.c index 50841e30df..e098d7635b 100644 --- a/src/gnome/window-reconcile.c +++ b/src/gnome/window-reconcile.c @@ -816,11 +816,11 @@ gnc_reconcile_window_set_sensitivity(RecnWindow *recnData) GtkAction *action; view = GNC_RECONCILE_VIEW(recnData->debit); - if (gnc_reconcile_view_get_current_split(view) != NULL) + if (gnc_reconcile_view_num_selected(view) == 1) sensitive = TRUE; view = GNC_RECONCILE_VIEW(recnData->credit); - if (gnc_reconcile_view_get_current_split(view) != NULL) + if (gnc_reconcile_view_num_selected(view) == 1) sensitive = TRUE; action = gtk_action_group_get_action (recnData->action_group, @@ -829,11 +829,28 @@ gnc_reconcile_window_set_sensitivity(RecnWindow *recnData) action = gtk_action_group_get_action (recnData->action_group, "TransDeleteAction"); gtk_action_set_sensitive(action, sensitive); + + sensitive = FALSE; + + view = GNC_RECONCILE_VIEW(recnData->debit); + if (gnc_reconcile_view_num_selected(view) > 0) + sensitive = TRUE; + + view = GNC_RECONCILE_VIEW(recnData->credit); + if (gnc_reconcile_view_num_selected(view) > 0) + sensitive = TRUE; + + action = gtk_action_group_get_action (recnData->action_group, + "TransRecAction"); + gtk_action_set_sensitive(action, sensitive); + action = gtk_action_group_get_action (recnData->action_group, + "TransUnRecAction"); + gtk_action_set_sensitive(action, sensitive); } static void -gnc_reconcile_window_list_cb(GNCReconcileView *view, Split *split, +gnc_reconcile_window_toggled_cb(GNCReconcileView *view, Split *split, gpointer data) { RecnWindow *recnData = data; @@ -843,7 +860,7 @@ gnc_reconcile_window_list_cb(GNCReconcileView *view, Split *split, static void -gnc_reconcile_window_row_cb(GNCReconcileView *view, Split *split, +gnc_reconcile_window_row_cb(GNCReconcileView *view, gpointer item, gpointer data) { RecnWindow *recnData = data; @@ -1090,7 +1107,7 @@ gnc_reconcile_window_create_view_box(Account *account, *list_save = view; g_signal_connect(view, "toggle_reconciled", - G_CALLBACK(gnc_reconcile_window_list_cb), + G_CALLBACK(gnc_reconcile_window_toggled_cb), recnData); g_signal_connect(view, "line_selected", G_CALLBACK(gnc_reconcile_window_row_cb), @@ -1221,6 +1238,34 @@ gnc_ui_reconcile_window_balance_cb(GtkButton *button, gpointer data) } +static void +gnc_ui_reconcile_window_rec_cb(GtkButton *button, gpointer data) +{ + RecnWindow *recnData = data; + GNCReconcileView *debit, *credit; + + debit = GNC_RECONCILE_VIEW(recnData->debit); + credit = GNC_RECONCILE_VIEW(recnData->credit); + + gnc_reconcile_view_set_list (debit, TRUE); + gnc_reconcile_view_set_list (credit, TRUE); +} + + +static void +gnc_ui_reconcile_window_unrec_cb(GtkButton *button, gpointer data) +{ + RecnWindow *recnData = data; + GNCReconcileView *debit, *credit; + + debit = GNC_RECONCILE_VIEW(recnData->debit); + credit = GNC_RECONCILE_VIEW(recnData->credit); + + gnc_reconcile_view_set_list (debit, FALSE); + gnc_reconcile_view_set_list (credit, FALSE); +} + + static void gnc_ui_reconcile_window_delete_cb(GtkButton *button, gpointer data) { @@ -2179,7 +2224,7 @@ static GtkActionEntry recnWindow_actions [] = G_CALLBACK (gnc_ui_reconcile_window_change_cb) }, { - "RecnFinishAction", GTK_STOCK_YES, N_("_Finish"), "f", + "RecnFinishAction", GTK_STOCK_YES, N_("_Finish"), "w", N_("Finish the reconciliation of this account"), G_CALLBACK(recnFinishCB) }, @@ -2240,6 +2285,16 @@ static GtkActionEntry recnWindow_actions [] = N_("Delete the selected transaction"), G_CALLBACK(gnc_ui_reconcile_window_delete_cb) }, + { + "TransRecAction", GTK_STOCK_APPLY, N_("_Reconcile Selection"), "r", + N_("Reconcile the selected transactions"), + G_CALLBACK(gnc_ui_reconcile_window_rec_cb) + }, + { + "TransUnRecAction", GTK_STOCK_CLEAR, N_("_Unreconcile Selection"), "u", + N_("Unreconcile the selected transactions"), + G_CALLBACK(gnc_ui_reconcile_window_unrec_cb) + }, /* Help menu */