mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Bug 798438 - on reconcile window, 'R' column sorting broken
Sorting on the 'R' column was enabled in version 3.0 by mistake and never worked as expected. Due to the 'R' column using a function to populate the model, the existing sorting method would not work as this was achieved by changing the query. To fix this add a sorting function to sort the model for the 'R' column.
This commit is contained in:
@@ -691,6 +691,13 @@ gnc_query_view_set_query_sort (GNCQueryView *qview, gboolean new_column)
|
||||
|
||||
g_assert (GNC_IS_SEARCH_PARAM_SIMPLE(param));
|
||||
|
||||
/* If param values are based on a param function, sorting is not possible */
|
||||
if (gnc_search_param_has_param_fcn (param))
|
||||
{
|
||||
gnc_query_view_refresh (qview);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're asked to invert numerics, and if this is a numeric or
|
||||
* debred column, then invert the sort order.
|
||||
*/
|
||||
|
||||
@@ -538,6 +538,22 @@ gnc_search_param_set_param_fcn (GNCSearchParamSimple *param,
|
||||
gnc_search_param_override_param_type (param, param_type);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_search_param_has_param_fcn (GNCSearchParamSimple *param)
|
||||
{
|
||||
GNCSearchParamSimplePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (param, FALSE);
|
||||
g_return_val_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param), FALSE);
|
||||
|
||||
priv = GNC_SEARCH_PARAM_SIMPLE_GET_PRIVATE(param);
|
||||
|
||||
if (priv->lookup_fcn)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Compute the value of this parameter for this object */
|
||||
gpointer
|
||||
gnc_search_param_compute_value (GNCSearchParamSimple *param, gpointer object)
|
||||
|
||||
@@ -184,6 +184,9 @@ void gnc_search_param_set_param_fcn (GNCSearchParamSimple *param,
|
||||
GNCSearchParamFcn fcn,
|
||||
gpointer arg);
|
||||
|
||||
/* check to see if this parameter is a lookup function */
|
||||
gboolean gnc_search_param_has_param_fcn (GNCSearchParamSimple *param);
|
||||
|
||||
/* Compute the value of this parameter for this object */
|
||||
gpointer gnc_search_param_compute_value (GNCSearchParamSimple *param,
|
||||
gpointer object);
|
||||
|
||||
@@ -315,17 +315,58 @@ gnc_reconcile_view_construct (GNCReconcileView *view, Query *query)
|
||||
G_CALLBACK(gnc_reconcile_view_tooltip_cb), view);
|
||||
}
|
||||
|
||||
static gint
|
||||
sort_date_helper (time64 date_a, time64 date_b)
|
||||
{
|
||||
gint ret = 0;
|
||||
|
||||
if (date_a < date_b)
|
||||
ret = -1;
|
||||
else if (date_a > date_b)
|
||||
ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gint
|
||||
sort_iter_compare_func (GtkTreeModel *model,
|
||||
GtkTreeIter *a,
|
||||
GtkTreeIter *b,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean rec_a, rec_b;
|
||||
Split *split_a, *split_b;
|
||||
time64 date_a, date_b;
|
||||
gint ret = 0;
|
||||
|
||||
gtk_tree_model_get (model, a, REC_POINTER, &split_a, REC_RECN, &rec_a, -1);
|
||||
gtk_tree_model_get (model, b, REC_POINTER, &split_b, REC_RECN, &rec_b, -1);
|
||||
|
||||
date_a = xaccTransGetDate (xaccSplitGetParent (split_a));
|
||||
date_b = xaccTransGetDate (xaccSplitGetParent (split_b));
|
||||
|
||||
if (rec_a > rec_b)
|
||||
ret = -1;
|
||||
else if (rec_b > rec_a)
|
||||
ret = 1;
|
||||
else ret = sort_date_helper (date_a, date_b);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gnc_reconcile_view_new (Account *account, GNCReconcileViewType type,
|
||||
time64 statement_date)
|
||||
{
|
||||
GNCReconcileView *view;
|
||||
GtkListStore *liststore;
|
||||
gboolean include_children, auto_check;
|
||||
GList *accounts = NULL;
|
||||
GList *splits;
|
||||
Query *query;
|
||||
QofNumericMatch sign;
|
||||
GNCReconcileView *view;
|
||||
GtkListStore *liststore;
|
||||
GtkTreeSortable *sortable;
|
||||
GtkTreeViewColumn *col;
|
||||
gboolean include_children, auto_check;
|
||||
GList *accounts = NULL;
|
||||
GList *splits;
|
||||
Query *query;
|
||||
QofNumericMatch sign;
|
||||
|
||||
g_return_val_if_fail (account, NULL);
|
||||
g_return_val_if_fail ((type == RECLIST_DEBIT) ||
|
||||
@@ -392,6 +433,13 @@ gnc_reconcile_view_new (Account *account, GNCReconcileViewType type,
|
||||
}
|
||||
}
|
||||
|
||||
/* set up a separate sort function for the recn column as it is
|
||||
* derived from a search function */
|
||||
sortable = GTK_TREE_SORTABLE(gtk_tree_view_get_model (GTK_TREE_VIEW(view)));
|
||||
col = gtk_tree_view_get_column (GTK_TREE_VIEW(view), REC_RECN -1);
|
||||
gtk_tree_sortable_set_sort_func (sortable, REC_RECN, sort_iter_compare_func,
|
||||
GINT_TO_POINTER (REC_RECN), NULL);
|
||||
|
||||
/* Free the query -- we don't need it anymore */
|
||||
qof_query_destroy (query);
|
||||
|
||||
@@ -519,6 +567,28 @@ gnc_reconcile_view_toggle (GNCReconcileView *view, Split *split)
|
||||
reconcile_view_signals[TOGGLE_RECONCILED], 0, split);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
follow_select_tree_path (GNCReconcileView *view)
|
||||
{
|
||||
if (view->rowref)
|
||||
{
|
||||
GtkTreePath *tree_path = gtk_tree_row_reference_get_path (view->rowref);
|
||||
GNCQueryView qview = view->qview;
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(&qview));
|
||||
|
||||
gtk_tree_selection_unselect_all (selection);
|
||||
gtk_tree_selection_select_path (selection, tree_path);
|
||||
|
||||
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(&qview),
|
||||
tree_path, NULL, FALSE, 0.0, 0.0);
|
||||
|
||||
gtk_tree_path_free (tree_path);
|
||||
gtk_tree_row_reference_free (view->rowref);
|
||||
view->rowref = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_reconcile_view_line_toggled (GNCQueryView *qview,
|
||||
gpointer item,
|
||||
@@ -528,6 +598,7 @@ gnc_reconcile_view_line_toggled (GNCQueryView *qview,
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
gpointer entry;
|
||||
GtkTreePath *tree_path;
|
||||
|
||||
g_return_if_fail (user_data);
|
||||
g_return_if_fail (GNC_IS_QUERY_VIEW(qview));
|
||||
@@ -536,10 +607,32 @@ gnc_reconcile_view_line_toggled (GNCQueryView *qview,
|
||||
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW(qview));
|
||||
gtk_tree_model_iter_nth_child (model, &iter, NULL, qview->toggled_row);
|
||||
gtk_list_store_set (GTK_LIST_STORE(model), &iter, qview->toggled_column, GPOINTER_TO_INT(item), -1);
|
||||
gtk_tree_model_get (model, &iter, REC_POINTER, &entry, -1);
|
||||
|
||||
gnc_reconcile_view_toggle (view, entry);
|
||||
tree_path = gtk_tree_model_get_path (model, &iter);
|
||||
view->rowref = gtk_tree_row_reference_new (model, tree_path);
|
||||
gtk_tree_path_free (tree_path);
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE(model), &iter, qview->toggled_column,
|
||||
GPOINTER_TO_INT(item), -1);
|
||||
|
||||
tree_path = gtk_tree_row_reference_get_path (view->rowref);
|
||||
|
||||
if (gtk_tree_model_get_iter (model, &iter, tree_path))
|
||||
{
|
||||
gtk_tree_model_get (model, &iter, REC_POINTER, &entry, -1);
|
||||
gnc_reconcile_view_toggle (view, entry);
|
||||
}
|
||||
|
||||
// See if sorting on rec column, -1 to allow for the model pointer column at 0
|
||||
if (qview->sort_column == REC_RECN - 1)
|
||||
g_idle_add ((GSourceFunc)follow_select_tree_path, view);
|
||||
else
|
||||
{
|
||||
gtk_tree_row_reference_free (view->rowref);
|
||||
view->rowref = NULL;
|
||||
}
|
||||
|
||||
gtk_tree_path_free (tree_path);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -586,16 +679,30 @@ gnc_reconcile_view_set_list (GNCReconcileView *view, gboolean reconcile)
|
||||
gboolean toggled;
|
||||
GList *node;
|
||||
GList *list_of_rows;
|
||||
GList *rr_list = NULL;
|
||||
GtkTreePath *last_tree_path = NULL;
|
||||
|
||||
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 */
|
||||
/* First create a list of Row references */
|
||||
for (node = list_of_rows; node; node = node->next)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
if (gtk_tree_model_get_iter(model, &iter, node->data))
|
||||
GtkTreeRowReference *rowref = gtk_tree_row_reference_new (model, node->data);
|
||||
rr_list = g_list_append (rr_list, rowref);
|
||||
gtk_tree_path_free (node->data);
|
||||
}
|
||||
|
||||
for (node = rr_list; node; node = node->next)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
GtkTreeRowReference *rowref = node->data;
|
||||
|
||||
path = gtk_tree_row_reference_get_path (rowref);
|
||||
|
||||
if (gtk_tree_model_get_iter (model, &iter, path))
|
||||
{
|
||||
/* now iter is a valid row iterator */
|
||||
gtk_tree_model_get (model, &iter, REC_POINTER, &entry,
|
||||
@@ -603,11 +710,30 @@ gnc_reconcile_view_set_list (GNCReconcileView *view, gboolean reconcile)
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE(model), &iter, REC_RECN, reconcile, -1);
|
||||
|
||||
if (last_tree_path)
|
||||
gtk_tree_path_free (last_tree_path);
|
||||
last_tree_path = gtk_tree_row_reference_get_path (rowref);
|
||||
|
||||
if (reconcile != toggled)
|
||||
gnc_reconcile_view_toggle (view, entry);
|
||||
}
|
||||
gtk_tree_path_free (node->data);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
if (last_tree_path)
|
||||
{
|
||||
// See if sorting on rec column, -1 to allow for the model pointer column at 0
|
||||
if (qview->sort_column == REC_RECN -1)
|
||||
{
|
||||
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(qview),
|
||||
last_tree_path, NULL, FALSE, 0.0, 0.0);
|
||||
}
|
||||
gtk_tree_path_free (last_tree_path);
|
||||
last_tree_path = NULL;
|
||||
}
|
||||
g_list_foreach (rr_list, (GFunc) gtk_tree_row_reference_free, NULL);
|
||||
g_list_free (rr_list);
|
||||
|
||||
// Out of site toggles on selected rows may not appear correctly drawn so
|
||||
// queue a draw for the treeview widget
|
||||
gtk_widget_queue_draw (GTK_WIDGET(qview));
|
||||
|
||||
@@ -67,6 +67,8 @@ struct GNCReconcileView
|
||||
GNCReconcileView *sibling;
|
||||
GNCReconcileViewType view_type;
|
||||
gboolean no_toggle;
|
||||
|
||||
GtkTreeRowReference *rowref;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
|
||||
Reference in New Issue
Block a user