mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-16 18:25:11 -06:00
Simplify GNCQueryView's data model
It was managing a number of redudant parameters which were leaking memory all over the place. The information that was tracked could easily be extracted from the underlying GtkTreeView, GtkTreeModel or GtkTreeSelection when needed.
This commit is contained in:
parent
9bec660fba
commit
1c5eb86d90
@ -77,8 +77,6 @@ struct _GNCSearchWindow
|
||||
|
||||
/* The "results" sub-window widgets */
|
||||
GtkWidget *result_view;
|
||||
gpointer selected_item;
|
||||
GList *selected_item_list;
|
||||
|
||||
/* The search_type radio-buttons */
|
||||
GtkWidget *new_rb;
|
||||
@ -146,29 +144,24 @@ gnc_search_callback_button_execute (GNCSearchCallbackButton *cb,
|
||||
GNCSearchWindow *sw)
|
||||
{
|
||||
GNCQueryView *qview = GNC_QUERY_VIEW(sw->result_view);
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
// Sanity check
|
||||
g_assert(qview);
|
||||
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(qview));
|
||||
g_assert(gtk_tree_selection_get_mode(selection) == GTK_SELECTION_MULTIPLE);
|
||||
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(qview));
|
||||
|
||||
/* Do we have a callback for multi-selections ? */
|
||||
if (cb->cb_multiselect_fn && (!cb->cb_fcn ))
|
||||
{
|
||||
/* We have allready populated the selected_item_list from the select row callback */
|
||||
// We use g_list_prepend (for performance reasons), so we have to reverse once here
|
||||
sw->selected_item_list = g_list_reverse(sw->selected_item_list);
|
||||
|
||||
GList *entries = gnc_query_view_get_selected_entry_list (qview);
|
||||
// Call the callback
|
||||
(cb->cb_multiselect_fn)(GTK_WINDOW (sw->dialog), sw->selected_item_list, sw->user_data);
|
||||
(cb->cb_multiselect_fn)(GTK_WINDOW (sw->dialog), entries, sw->user_data);
|
||||
g_list_free (entries);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No, stick to the single-item callback
|
||||
gpointer entry = gnc_query_view_get_selected_entry (qview);
|
||||
if (cb->cb_fcn)
|
||||
(cb->cb_fcn)(GTK_WINDOW (sw->dialog), &(sw->selected_item), sw->user_data);
|
||||
(cb->cb_fcn)(GTK_WINDOW (sw->dialog), &entry, sw->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,16 +222,18 @@ gnc_search_dialog_select_buttons_enable (GNCSearchWindow *sw, gint selected)
|
||||
static void
|
||||
gnc_search_dialog_select_cb (GtkButton *button, GNCSearchWindow *sw)
|
||||
{
|
||||
gpointer entry;
|
||||
g_return_if_fail (sw->selected_cb);
|
||||
|
||||
if (sw->selected_item == NULL && sw->allow_clear == FALSE)
|
||||
entry = gnc_query_view_get_selected_entry (GNC_QUERY_VIEW (sw->result_view));
|
||||
if (!entry && !sw->allow_clear)
|
||||
{
|
||||
char *msg = _("You must select an item from the list");
|
||||
gnc_error_dialog (GTK_WINDOW (sw->dialog), "%s", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
(sw->selected_cb)(GTK_WINDOW (sw->dialog), sw->selected_item, sw->select_arg);
|
||||
(sw->selected_cb)(GTK_WINDOW (sw->dialog), entry, sw->select_arg);
|
||||
gnc_search_dialog_destroy (sw);
|
||||
}
|
||||
|
||||
@ -249,22 +244,8 @@ gnc_search_dialog_select_row_cb (GNCQueryView *qview,
|
||||
gpointer user_data)
|
||||
{
|
||||
GNCSearchWindow *sw = user_data;
|
||||
gint number_of_rows;
|
||||
|
||||
sw->selected_item_list = NULL;
|
||||
sw->selected_item = NULL;
|
||||
|
||||
number_of_rows = GPOINTER_TO_INT(item);
|
||||
|
||||
gint number_of_rows = GPOINTER_TO_INT(item);
|
||||
gnc_search_dialog_select_buttons_enable(sw, number_of_rows);
|
||||
|
||||
if(number_of_rows == 1)
|
||||
{
|
||||
sw->selected_item = qview->selected_entry;
|
||||
sw->selected_item_list = qview->selected_entry_list;
|
||||
}
|
||||
else
|
||||
sw->selected_item_list = qview->selected_entry_list;
|
||||
}
|
||||
|
||||
|
||||
@ -275,7 +256,6 @@ gnc_search_dialog_double_click_cb (GNCQueryView *qview,
|
||||
{
|
||||
GNCSearchWindow *sw = user_data;
|
||||
|
||||
sw->selected_item = item;
|
||||
if (sw->selected_cb)
|
||||
/* Select the item */
|
||||
gnc_search_dialog_select_cb (NULL, sw);
|
||||
@ -624,7 +604,15 @@ search_find_cb (GtkButton *button, GNCSearchWindow *sw)
|
||||
gnc_search_dialog_reset_widgets (sw);
|
||||
|
||||
if (sw->result_cb)
|
||||
(sw->result_cb)(sw->q, sw->user_data, &(sw->selected_item));
|
||||
{
|
||||
gpointer entry = NULL;
|
||||
if (sw->result_view)
|
||||
{
|
||||
GNCQueryView *qview = GNC_QUERY_VIEW (sw->result_view);
|
||||
entry = gnc_query_view_get_selected_entry (qview);
|
||||
}
|
||||
(sw->result_cb)(sw->q, sw->user_data, &entry);
|
||||
}
|
||||
else
|
||||
gnc_search_dialog_display_results (sw);
|
||||
}
|
||||
@ -668,7 +656,6 @@ static void
|
||||
search_cancel_cb (GtkButton *button, GNCSearchWindow *sw)
|
||||
{
|
||||
/* Don't select anything */
|
||||
sw->selected_item = NULL;
|
||||
gnc_search_dialog_destroy (sw);
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,9 @@
|
||||
#include "gnc-query-view.h"
|
||||
#include "search-param.h"
|
||||
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
static QofLogModule log_module = GNC_MOD_GUI;
|
||||
|
||||
/* Signal codes */
|
||||
enum
|
||||
{
|
||||
@ -471,44 +474,11 @@ gnc_query_view_class_init (GNCQueryViewClass *klass)
|
||||
static void
|
||||
gnc_query_view_select_row_cb (GtkTreeSelection *selection, gpointer user_data)
|
||||
{
|
||||
GNCQueryView *qview = GNC_QUERY_VIEW (gtk_tree_selection_get_tree_view (selection));
|
||||
GtkTreeModel *model;
|
||||
gint number_of_rows;
|
||||
gpointer entry = NULL;
|
||||
GList *node;
|
||||
GList *list_of_rows;
|
||||
GNCQueryView *qview = GNC_QUERY_VIEW (gtk_tree_selection_get_tree_view (selection));
|
||||
gint number_of_rows = gtk_tree_selection_count_selected_rows (selection);
|
||||
|
||||
qview->selected_entry_list = NULL;
|
||||
qview->selected_entry = NULL;
|
||||
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (qview));
|
||||
list_of_rows = gtk_tree_selection_get_selected_rows (selection, &model);
|
||||
number_of_rows = gtk_tree_selection_count_selected_rows (selection);
|
||||
|
||||
/* 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);
|
||||
if(number_of_rows == 1)
|
||||
{
|
||||
qview->selected_entry = entry;
|
||||
qview->selected_entry_list = g_list_prepend(qview->selected_entry_list, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
qview->selected_entry = NULL;
|
||||
qview->selected_entry_list = g_list_prepend(qview->selected_entry_list, entry);
|
||||
}
|
||||
}
|
||||
gtk_tree_path_free(node->data);
|
||||
}
|
||||
g_list_free(list_of_rows);
|
||||
|
||||
g_signal_emit (qview, query_view_signals[ROW_SELECTED], 0, GINT_TO_POINTER(number_of_rows));
|
||||
g_signal_emit (qview, query_view_signals[ROW_SELECTED], 0,
|
||||
GINT_TO_POINTER(number_of_rows));
|
||||
}
|
||||
|
||||
|
||||
@ -528,9 +498,6 @@ gnc_query_view_double_click_cb (GtkTreeView *view,
|
||||
if (gtk_tree_model_get_iter (model, &iter, path))
|
||||
gtk_tree_model_get (model, &iter, 0, &entry, -1);
|
||||
|
||||
qview->selected_entry = entry;
|
||||
qview->selected_entry_list = NULL;
|
||||
|
||||
g_signal_emit (qview, query_view_signals[DOUBLE_CLICK_ENTRY], 0, entry);
|
||||
}
|
||||
|
||||
@ -563,14 +530,12 @@ gnc_query_view_toggled_cb (GtkCellRendererToggle *cell_renderer,
|
||||
indices = gtk_tree_path_get_indices (treepath);
|
||||
qview->toggled_row = indices[0];
|
||||
qview->toggled_column = column;
|
||||
qview->selected_entry = entry;
|
||||
|
||||
if(toggled)
|
||||
g_signal_emit (qview, query_view_signals[COLUMN_TOGGLED], 0, GINT_TO_POINTER(0));
|
||||
else
|
||||
g_signal_emit (qview, query_view_signals[COLUMN_TOGGLED], 0, GINT_TO_POINTER(1));
|
||||
}
|
||||
qview->selected_entry = entry;
|
||||
}
|
||||
|
||||
|
||||
@ -586,12 +551,7 @@ gnc_query_view_destroy (GtkWidget *widget)
|
||||
gnc_unregister_gui_component (priv->component_id);
|
||||
priv->component_id = 0;
|
||||
}
|
||||
/* Free the selected entry list */
|
||||
if (qview->selected_entry_list)
|
||||
{
|
||||
g_list_free(qview->selected_entry_list);
|
||||
qview->selected_entry_list = NULL;
|
||||
}
|
||||
|
||||
/* Remove the query */
|
||||
if (qview->query)
|
||||
{
|
||||
@ -606,30 +566,74 @@ gnc_query_view_destroy (GtkWidget *widget)
|
||||
gint
|
||||
gnc_query_view_get_num_entries (GNCQueryView *qview)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
|
||||
g_return_val_if_fail (qview != NULL, 0);
|
||||
g_return_val_if_fail (GNC_IS_QUERY_VIEW (qview), 0);
|
||||
|
||||
return qview->num_entries;
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (qview));
|
||||
return gtk_tree_model_iter_n_children (model, NULL);
|
||||
}
|
||||
|
||||
|
||||
gpointer
|
||||
gnc_query_view_get_selected_entry (GNCQueryView *qview)
|
||||
{
|
||||
gpointer entry = NULL;
|
||||
GList *entries = NULL;
|
||||
gint num_entries = 0;
|
||||
|
||||
g_return_val_if_fail (qview != NULL, NULL);
|
||||
g_return_val_if_fail (GNC_IS_QUERY_VIEW (qview), NULL);
|
||||
|
||||
return qview->selected_entry;
|
||||
entries = gnc_query_view_get_selected_entry_list (qview);
|
||||
if (entries)
|
||||
entry = entries->data;
|
||||
|
||||
num_entries = g_list_length (entries);
|
||||
if (num_entries > 1)
|
||||
PWARN ("Expected only one selected entry but found %i. "
|
||||
"Discarding all but the first one.", num_entries);
|
||||
|
||||
g_list_free (entries);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GList *entries;
|
||||
} acc_data;
|
||||
|
||||
static void
|
||||
accumulate_entries (GtkTreeModel *model, GtkTreePath *path,
|
||||
GtkTreeIter *iter, gpointer data)
|
||||
{
|
||||
acc_data *acc_entries = (acc_data*)data;
|
||||
gpointer entry = NULL;
|
||||
GList *entries = acc_entries->entries;
|
||||
|
||||
gtk_tree_model_get (model, iter, 0, &entry, -1);
|
||||
entries = g_list_prepend (entries, entry);
|
||||
acc_entries->entries = entries;
|
||||
}
|
||||
|
||||
GList *
|
||||
gnc_query_view_get_selected_entry_list (GNCQueryView *qview)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
acc_data acc_entries;
|
||||
GList *entries = NULL;
|
||||
|
||||
g_return_val_if_fail (qview != NULL, NULL);
|
||||
g_return_val_if_fail (GNC_IS_QUERY_VIEW (qview), NULL);
|
||||
|
||||
return qview->selected_entry_list;
|
||||
acc_entries.entries = NULL;
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (qview));
|
||||
gtk_tree_selection_selected_foreach (selection, accumulate_entries,
|
||||
&acc_entries);
|
||||
acc_entries.entries = g_list_reverse (acc_entries.entries);
|
||||
return acc_entries.entries;
|
||||
}
|
||||
|
||||
|
||||
@ -685,24 +689,18 @@ void
|
||||
gnc_query_view_refresh (GNCQueryView *qview)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GList *old_entry;
|
||||
GList *selected_entries;
|
||||
|
||||
g_return_if_fail (qview != NULL);
|
||||
g_return_if_fail (GNC_IS_QUERY_VIEW (qview));
|
||||
|
||||
old_entry = qview->selected_entry_list;
|
||||
selected_entries = gnc_query_view_get_selected_entry_list (qview);
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (qview));
|
||||
gtk_list_store_clear (GTK_LIST_STORE (model));
|
||||
|
||||
qview->num_entries = 0;
|
||||
qview->selected_entry = NULL;
|
||||
qview->selected_entry_list = NULL;
|
||||
|
||||
gnc_query_view_fill (qview);
|
||||
|
||||
gnc_query_view_refresh_selected (qview, old_entry);
|
||||
|
||||
g_list_free(old_entry);
|
||||
gnc_query_view_refresh_selected (qview, selected_entries);
|
||||
g_list_free (selected_entries);
|
||||
}
|
||||
|
||||
|
||||
@ -850,8 +848,6 @@ gnc_query_view_fill (GNCQueryView *qview)
|
||||
guid = (const GncGUID*)((gup->param_getfcn)(item->data, gup));
|
||||
gnc_gui_component_watch_entity (priv->component_id, guid,
|
||||
QOF_EVENT_MODIFY | QOF_EVENT_DESTROY);
|
||||
|
||||
qview->num_entries++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -873,9 +869,6 @@ gnc_query_view_unselect_all (GNCQueryView *qview)
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (qview));
|
||||
gtk_tree_selection_unselect_all (selection);
|
||||
|
||||
qview->selected_entry = NULL;
|
||||
qview->selected_entry_list = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,11 +47,8 @@ extern "C" {
|
||||
|
||||
/* Query information */
|
||||
Query *query;
|
||||
gint num_entries;
|
||||
|
||||
/* Select information */
|
||||
gpointer selected_entry;
|
||||
GList *selected_entry_list;
|
||||
gint toggled_row;
|
||||
gint toggled_column;
|
||||
|
||||
@ -108,6 +105,8 @@ extern "C" {
|
||||
|
||||
gpointer gnc_query_view_get_selected_entry (GNCQueryView *qview);
|
||||
|
||||
/** Returns a list of selected entries in the query view.
|
||||
* The returned GList should be freed by the caller */
|
||||
GList * gnc_query_view_get_selected_entry_list (GNCQueryView *qview);
|
||||
|
||||
void gnc_query_view_refresh (GNCQueryView *qview);
|
||||
|
Loading…
Reference in New Issue
Block a user