Bug #463969 - Allow Selection of Multiple Transactions During Reconcile

Bug #628402 - Ctrl-F in Reconcile doesn't invoke search, but (F)inishes
the reconciliation

Author: Robert Fewell <14ubobit@gmail.com>

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@22312 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Geert Janssens 2012-08-15 09:54:59 +00:00
parent 0835f8b730
commit f6119b2a39
4 changed files with 201 additions and 33 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -21,6 +21,8 @@
<menuitem name="TransNew" action="TransNewAction"/>
<menuitem name="TransBalance" action="TransBalanceAction"/>
<menuitem name="TransEdit" action="TransEditAction"/>
<menuitem name="TransRec" action="TransRecAction"/>
<menuitem name="TransUnRec" action="TransUnRecAction"/>
<menuitem name="TransDelete" action="TransDeleteAction"/>
</menu>
@ -32,6 +34,8 @@
<popup name="MainPopup" action="FakeToplevel">
<menuitem name="TransNew" action="TransNewAction"/>
<menuitem name="TransEdit" action="TransEditAction"/>
<menuitem name="TransRec" action="TransRecAction"/>
<menuitem name="TransUnRec" action="TransUnRecAction"/>
<menuitem name="TransDelete" action="TransDeleteAction"/>
</popup>
@ -39,6 +43,8 @@
<toolitem name="TransNew" action="TransNewAction"/>
<toolitem name="TransBalance" action="TransBalanceAction"/>
<toolitem name="TransEdit" action="TransEditAction"/>
<toolitem name="TransRec" action="TransRecAction"/>
<toolitem name="TransUnRec" action="TransUnRecAction"/>
<toolitem name="TransDelete" action="TransDeleteAction"/>
<separator name="ToolbarSep2"/>
<toolitem name="AccountOpenAccount" action="AccountOpenAccountAction"/>

View File

@ -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"), "<control>f",
"RecnFinishAction", GTK_STOCK_YES, N_("_Finish"), "<control>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"), "<control>r",
N_("Reconcile the selected transactions"),
G_CALLBACK(gnc_ui_reconcile_window_rec_cb)
},
{
"TransUnRecAction", GTK_STOCK_CLEAR, N_("_Unreconcile Selection"), "<control>u",
N_("Unreconcile the selected transactions"),
G_CALLBACK(gnc_ui_reconcile_window_unrec_cb)
},
/* Help menu */