* src/gnome-utils/gnc-query-list.[ch]: an abstracted Query list

widget to display the results of a Query.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@8307 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Derek Atkins 2003-05-13 00:46:20 +00:00
parent 661bd34cc4
commit 0a883ac5e0
3 changed files with 880 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2003-05-12 Derek Atkins <derek@ihtfp.com>
* src/gnome-utils/gnc-query-list.[ch]: an abstracted Query list
widget to display the results of a Query.
2003-05-11 David Hampton <hampton@employees.org>
* src/gnome/dialog-commodities.c:

View File

@ -0,0 +1,773 @@
/********************************************************************\
* gnc-query-list.c -- A query display list. *
* Copyright (C) 2003 Derek Atkins <derek@ihtfp.com> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License*
* along with this program; if not, contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
#include "config.h"
#include <gnome.h>
#include "dialog-utils.h"
#include "gnc-ui-util.h"
#include "gnc-engine-util.h"
#include "messages.h"
#include "gnc-query-list.h"
#include "search-param.h"
/* Signal codes */
enum
{
LINE_TOGGLED,
DOUBLE_CLICK_ENTRY,
LAST_SIGNAL
};
/* Impossible to get at runtime. Assume this is a reasonable number */
#define ARROW_SIZE 14
#define VSCROLLBAR_SLOP 40
/** Static Globals ****************************************************/
static GtkCListClass *parent_class = NULL;
static guint query_list_signals[LAST_SIGNAL] = {0};
/** Static function declarations **************************************/
static void gnc_query_list_init(GNCQueryList *list);
static void gnc_query_list_init_clist (GNCQueryList *list);
static void gnc_query_list_class_init(GNCQueryListClass *klass);
static void gnc_query_list_select_row(GtkCList *clist, gint row,
gint column, GdkEvent *event);
static void gnc_query_list_unselect_row(GtkCList *clist, gint row,
gint column, GdkEvent *event);
static void gnc_query_list_destroy(GtkObject *object);
static void gnc_query_list_fill(GNCQueryList *list);
static void gnc_query_list_click_column_cb(GtkWidget *w, gint column,
gpointer data);
static void gnc_query_list_size_allocate_cb(GtkWidget *w,
GtkAllocation *allocation,
gpointer data);
static void gnc_query_list_set_query_sort (GNCQueryList *list, gboolean new_column);
GtkType
gnc_query_list_get_type (void)
{
static GtkType gnc_query_list_type = 0;
if (!gnc_query_list_type)
{
static const GtkTypeInfo gnc_query_list_info =
{
"GNCQueryList",
sizeof (GNCQueryList),
sizeof (GNCQueryListClass),
(GtkClassInitFunc) gnc_query_list_class_init,
(GtkObjectInitFunc) gnc_query_list_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
gnc_query_list_type = gtk_type_unique(GTK_TYPE_CLIST,
&gnc_query_list_info);
}
return gnc_query_list_type;
}
/********************************************************************\
* gnc_query_list_new *
* creates the query list *
* *
* Args: param_list - the list of params *
* query - the query to use to find entries *
* Returns: the query list widget, or NULL if there was a problem. *
\********************************************************************/
GtkWidget *
gnc_query_list_new(GList *param_list, Query *query)
{
GNCQueryList *list;
g_return_val_if_fail(param_list, NULL);
g_return_val_if_fail(query, NULL);
list = GNC_QUERY_LIST(gtk_type_new(gnc_query_list_get_type()));
/* more configuration */
list->query = gncQueryCopy(query);
list->column_params = param_list;
/* Initialize the CList */
gnc_query_list_init_clist(list);
return GTK_WIDGET(list);
}
void gnc_query_list_reset_query (GNCQueryList *list, Query *query)
{
g_return_if_fail(list);
g_return_if_fail(query);
g_return_if_fail (IS_GNC_QUERY_LIST(list));
gncQueryDestroy(list->query);
list->query = gncQueryCopy(query);
gnc_query_list_set_query_sort(list, TRUE);
}
static void
update_booleans (GNCQueryList *list, gint row)
{
GtkCList *clist = GTK_CLIST(list);
gpointer entry;
GList *node;
gint i;
gboolean result;
entry = gtk_clist_get_row_data (clist, row);
for (i = 0, node = list->column_params; node; node = node->next, i++)
{
GNCSearchParam *param = node->data;
const char *type = gnc_search_param_get_param_type (param);
/* if this is a boolean, ignore it now -- we'll use a checkmark later */
if (safe_strcmp (type, QUERYCORE_BOOLEAN))
continue;
result = (gboolean)(gnc_search_param_compute_value(param, entry));
gnc_clist_set_check (clist, row, i, result);
}
}
static void
gnc_query_list_column_title (GNCQueryList *list, gint column, const gchar *title)
{
GtkWidget *hbox, *label, *arrow;
hbox = gtk_hbox_new(FALSE, 2);
gtk_widget_show(hbox);
gtk_clist_set_column_widget(GTK_CLIST(list), column, hbox);
label = gtk_label_new(title);
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_ETCHED_IN);
list->title_arrows[column] = arrow;
if (column == 0)
gtk_widget_show(arrow);
gtk_box_pack_end(GTK_BOX(hbox), arrow, FALSE, FALSE, 0);
}
static void
gnc_query_list_init (GNCQueryList *list)
{
list->query = NULL;
list->no_toggle = FALSE;
list->num_columns = 0;
list->column_params = NULL;
list->sort_column = 0;
list->increasing = TRUE;
list->title_arrows = NULL;
list->prev_allocation = -1;
list->title_widths = NULL;
}
static void
gnc_query_list_init_clist (GNCQueryList *list)
{
GtkCList *clist = GTK_CLIST (list);
GtkStyle *style;
GList *node;
gchar **titles;
gint i;
/* compute the number of columns and fill in the rest of the list */
list->num_columns = g_list_length(list->column_params);
list->title_arrows = g_new0(GtkWidget*, list->num_columns);
list->title_widths = g_new0(gint, list->num_columns);
/* build an array of titles */
titles = g_new0(gchar*, list->num_columns);
for (i = 0, node = list->column_params; node; node = node->next, i++) {
GNCSearchParam *param = node->data;
titles[i] = (gchar *)param->title;
}
/* construct the clist */
gtk_clist_construct (clist, list->num_columns, titles);
gtk_clist_set_shadow_type (clist, GTK_SHADOW_IN);
/* build all the column titles */
for (i = 0; i < list->num_columns; i++)
gnc_query_list_column_title(list, i, titles[i]);
/* set the column justification */
for (i = 0, node = list->column_params; node; node = node->next, i++) {
GNCSearchParam *param = node->data;
gtk_clist_set_column_justification (clist, i, param->justify);
if (param->passive)
gtk_clist_column_title_passive (clist, i);
if (param->non_resizeable)
gtk_clist_set_column_resizeable (clist, i, FALSE);
}
gtk_signal_connect (GTK_OBJECT (clist), "click_column",
GTK_SIGNAL_FUNC(gnc_query_list_click_column_cb),
NULL);
gtk_signal_connect (GTK_OBJECT (clist), "size_allocate",
GTK_SIGNAL_FUNC(gnc_query_list_size_allocate_cb),
NULL);
style = gtk_widget_get_style (GTK_WIDGET(list));
{
GdkFont *font = NULL;
gint width;
font = style->font;
if (font != NULL)
{
for (i = 0, node = list->column_params; node; node = node->next, i++)
{
GNCSearchParam *param = node->data;
width = gdk_string_width (font, titles[i]) + 5;
if (!param->passive)
width += ARROW_SIZE;
gtk_clist_set_column_min_width (clist, i, width);
list->title_widths[i] = width;
}
}
}
g_free(titles);
}
static void
gnc_query_list_class_init (GNCQueryListClass *klass)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
GtkCListClass *clist_class;
object_class = (GtkObjectClass*) klass;
widget_class = (GtkWidgetClass*) klass;
container_class = (GtkContainerClass*) klass;
clist_class = (GtkCListClass*) klass;
parent_class = gtk_type_class(GTK_TYPE_CLIST);
query_list_signals[LINE_TOGGLED] =
gtk_signal_new("line_toggled",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET(GNCQueryListClass,
line_toggled),
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1,
GTK_TYPE_POINTER);
query_list_signals[DOUBLE_CLICK_ENTRY] =
gtk_signal_new("double_click_entry",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET(GNCQueryListClass,
double_click_entry),
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1,
GTK_TYPE_POINTER);
gtk_object_class_add_signals(object_class,
query_list_signals,
LAST_SIGNAL);
object_class->destroy = gnc_query_list_destroy;
clist_class->select_row = gnc_query_list_select_row;
clist_class->unselect_row = gnc_query_list_unselect_row;
klass->line_toggled = NULL;
klass->double_click_entry = NULL;
}
static void
gnc_query_list_toggle (GNCQueryList *list)
{
gpointer entry;
gint row;
g_return_if_fail (IS_GNC_QUERY_LIST(list));
if (list->no_toggle)
return;
row = list->current_row;
entry = gtk_clist_get_row_data (GTK_CLIST(list), row);
list->current_entry = entry;
gtk_signal_emit (GTK_OBJECT (list), query_list_signals[LINE_TOGGLED], entry);
update_booleans (list, row);
}
static void
gnc_query_list_select_row (GtkCList *clist, gint row, gint column,
GdkEvent *event)
{
GNCQueryList *list = GNC_QUERY_LIST(clist);
list->current_row = row;
gnc_query_list_toggle (list);
if (event == NULL) {
/* User pressed the space key */
parent_class->scroll_vertical(clist, GTK_SCROLL_STEP_FORWARD, 0.0);
}
/* This will trigger an unselect event for the currently selected row */
parent_class->select_row (clist, row, column, event);
if (event && (event->type == GDK_2BUTTON_PRESS))
{
gpointer entry;
entry = gtk_clist_get_row_data (clist, row);
gtk_signal_emit(GTK_OBJECT(list),
query_list_signals[DOUBLE_CLICK_ENTRY], entry);
}
}
static void
gnc_query_list_unselect_row (GtkCList *clist, gint row, gint column,
GdkEvent *event)
{
GNCQueryList *list = GNC_QUERY_LIST(clist);
if (row == list->current_row)
{
gnc_query_list_toggle (list);
if (event == NULL) {
/* User pressed the space key */
parent_class->scroll_vertical(clist, GTK_SCROLL_STEP_FORWARD, 0.0);
}
/* XXX
if (!list->always_unselect)
return;
*/
}
parent_class->unselect_row (clist, row, column, event);
if (event && (event->type == GDK_2BUTTON_PRESS))
{
gpointer entry;
entry = gtk_clist_get_row_data (clist, row);
gtk_signal_emit (GTK_OBJECT(list),
query_list_signals[DOUBLE_CLICK_ENTRY], entry);
}
}
static void
gnc_query_list_destroy (GtkObject *object)
{
GNCQueryList *list = GNC_QUERY_LIST(object);
if (list->query)
{
xaccFreeQuery(list->query);
list->query = NULL;
}
if (list->column_params)
{
/* XXX: free the params list??? */
}
if (list->title_arrows)
{
g_free(list->title_arrows);
list->title_arrows = NULL;
}
if (list->title_widths)
{
g_free(list->title_widths);
list->title_widths = NULL;
}
if (GTK_OBJECT_CLASS(parent_class)->destroy)
GTK_OBJECT_CLASS(parent_class)->destroy (object);
}
gint
gnc_query_list_get_needed_height (GNCQueryList *list, gint num_rows)
{
GtkCList *clist;
gint list_height;
gint title_height;
g_return_val_if_fail (list != NULL, 0);
g_return_val_if_fail (IS_GNC_QUERY_LIST(list), 0);
if (!GTK_WIDGET_REALIZED (list))
return 0;
clist = GTK_CLIST (list);
/* sync with gtkclist.c */
title_height = (clist->column_title_area.height +
(GTK_WIDGET(list)->style->klass->ythickness +
GTK_CONTAINER(list)->border_width) * 2);
list_height = (clist->row_height * num_rows) + (num_rows + 1);
return title_height + list_height;
}
gint
gnc_query_list_get_num_entries (GNCQueryList *list)
{
g_return_val_if_fail (list != NULL, 0);
g_return_val_if_fail (IS_GNC_QUERY_LIST(list), 0);
return list->num_entries;
}
gpointer
gnc_query_list_get_current_entry (GNCQueryList *list)
{
g_return_val_if_fail (list != NULL, NULL);
g_return_val_if_fail (IS_GNC_QUERY_LIST(list), NULL);
return list->current_entry;
}
/********************************************************************\
* gnc_query_list_recompute_widths *
* Given a new widget width, recompute the widths of each column. *
* Give any excess allocation to the description field. This also *
* handles the case of allocating column widths when the list is *
* first filled with data. *
* *
* Args: list - a GncQueryList widget *
* allocated - the allocated width for this list *
* Returns: nothing *
\********************************************************************/
static void
gnc_query_list_recompute_widths (GNCQueryList *list, gint allocated)
{
GtkCList *clist = GTK_CLIST(list);
gint total_width, desc_width = 0, excess, i;
/* Prevent loops when allocation is bigger than total widths */
if (allocated == list->prev_allocation)
return;
/* Enforce column minimum widths */
total_width = 0;
for (i = 0; i < list->num_columns; i++)
{
gint width;
width = gtk_clist_optimal_column_width(clist, i);
if (width < list->title_widths[i])
width = list->title_widths[i];
total_width += width;
gtk_clist_set_column_width (clist, i, width);
if (i == 2)
desc_width = width;
}
/* Did the list use its full allocation?
*
* Add/subtract any underage/overage to/from the description column
*/
if (allocated <= 1)
allocated = list->prev_allocation;
list->prev_allocation = allocated;
excess = allocated - total_width - VSCROLLBAR_SLOP;
/* XXX: Choose a generic column to resize */
gtk_clist_set_column_width (clist, 2, desc_width + excess);
}
/********************************************************************\
* gnc_query_list_size_allocate_cb *
* The allocated size has changed. Need to recompute the *
* column widths *
* *
* Args: w - a GncQueryList widget *
* allocation - a widget allocation desctiption *
* data - unused *
* Returns: nothing *
\********************************************************************/
static void
gnc_query_list_size_allocate_cb (GtkWidget *w,
GtkAllocation *allocation,
gpointer data)
{
GNCQueryList *list = GNC_QUERY_LIST(w);
g_return_if_fail (list != NULL);
gnc_query_list_recompute_widths(list, allocation->width);
}
/********************************************************************\
* gnc_query_list_refresh *
* refreshes the list *
* *
* Args: list - list to refresh *
* Returns: nothing *
\********************************************************************/
void
gnc_query_list_refresh (GNCQueryList *list)
{
GtkCList *clist = GTK_CLIST(list);
GtkAdjustment *adjustment;
gfloat save_value = 0.0;
gpointer *old_focus_entry;
gpointer *old_entry;
gint old_focus_row;
gint new_row;
g_return_if_fail (list != NULL);
g_return_if_fail (IS_GNC_QUERY_LIST(list));
adjustment = gtk_clist_get_vadjustment (GTK_CLIST(list));
if (adjustment != NULL)
save_value = adjustment->value;
old_focus_row = clist->focus_row;
old_focus_entry = gtk_clist_get_row_data (clist, old_focus_row);
gtk_clist_freeze (clist);
gtk_clist_clear (clist);
old_entry = list->current_entry;
list->num_entries = 0;
list->current_row = -1;
list->current_entry = NULL;
gnc_query_list_fill (list);
gnc_query_list_recompute_widths (list, -1);
if (adjustment)
{
save_value = CLAMP (save_value, adjustment->lower, adjustment->upper);
gtk_adjustment_set_value (adjustment, save_value);
}
if (old_entry)
{
new_row = gtk_clist_find_row_from_data (clist, old_entry);
if (new_row >= 0)
{
list->no_toggle = TRUE;
gtk_clist_select_row (clist, new_row, 0);
list->no_toggle = FALSE;
list->current_entry = old_entry;
}
}
if (old_focus_entry)
{
new_row = gtk_clist_find_row_from_data (clist, old_focus_entry);
if (new_row < 0)
new_row = old_focus_row;
if (new_row >= 0)
clist->focus_row = new_row;
}
gtk_clist_thaw (clist);
}
/********************************************************************\
* gnc_query_list_set_query_sort *
* sets the sorting order of entries in the list *
* *
* Args: list - list to change the sort order for *
* new_column - is this a new column (so should we set the *
* query sort order or just set the 'increasing' *
* Returns: nothing *
\********************************************************************/
static void
gnc_query_list_set_query_sort (GNCQueryList *list, gboolean new_column)
{
gboolean sort_order = list->increasing;
GList *node;
GNCSearchParam *param;
/* Find the column parameter definition */
node = g_list_nth(list->column_params, list->sort_column);
param = node->data;
/* XXX: Maybe invert the sort order?
if ((list->list_type == RECLIST_CREDIT) && (key == BY_AMOUNT))
sort_order = !sort_order;
*/
/* Set the sort order for the engine, if the key changed */
if (new_column)
{
GSList *p1, *p2;
p1 = gnc_search_param_get_param_path(param);
p2 = g_slist_prepend(NULL, QUERY_DEFAULT_SORT);
gncQuerySetSortOrder (list->query, p1, p2, NULL);
}
xaccQuerySetSortIncreasing (list->query,
sort_order,
sort_order,
sort_order);
/*
* Recompute the list. Is this really necessary? Why not just sort
* the rows already in the clist? Answer: it would be an n-squared
* algorithm to get the clist to match the resulting list.
*/
gnc_query_list_refresh(list);
}
/********************************************************************\
* gnc_query_list_set_sort_column *
* sets the sorting order of entries in the list *
* *
* Args: list - list to change the sort order for *
* column - the column to sort on *
* Returns: nothing *
\********************************************************************/
static void
gnc_query_list_set_sort_column (GNCQueryList *list, gint sort_column)
{
gint column;
gboolean new_column = FALSE;
g_return_if_fail (list != NULL);
g_return_if_fail (IS_GNC_QUERY_LIST(list));
g_return_if_fail (list->query != NULL);
/* Clear all arrows */
for (column = 0; column < list->num_columns; column++)
{
if (list->title_arrows[column])
gtk_widget_hide(list->title_arrows[column]);
}
/* Is this a new column or a re-click on the existing column? */
column = sort_column;
new_column = (list->sort_column != sort_column);
list->increasing = new_column ? TRUE : !list->increasing;
list->sort_column = sort_column;
/* Set the appropriate arrow */
gtk_arrow_set(GTK_ARROW(list->title_arrows[column]),
list->increasing ? GTK_ARROW_DOWN : GTK_ARROW_UP,
GTK_SHADOW_ETCHED_IN);
gtk_widget_show(list->title_arrows[column]);
gnc_query_list_set_query_sort (list, new_column);
}
static void
gnc_query_list_click_column_cb(GtkWidget *w, gint column, gpointer data)
{
GNCQueryList *list = GNC_QUERY_LIST(w);
gnc_query_list_set_sort_column(list, column);
}
static void
gnc_query_list_fill(GNCQueryList *list)
{
gchar *strings[list->num_columns + 1];
GList *entries, *item;
gint i;
/* Reverse the list now because 'append()' takes too long */
entries = gncQueryRun(list->query);
entries = g_list_reverse(entries);
for (item = entries; item; item = item->next)
{
GList *node;
gint row;
for (i = 0, node = list->column_params; node; node = node->next)
{
GNCSearchParam *param = node->data;
GSList *converters = gnc_search_param_get_converters (param);
const char *type = gnc_search_param_get_param_type (param);
gpointer res = item->data;
QueryAccess fcn = NULL;
/* if this is a boolean, ignore it now -- we'll use a checkmark later */
if (!safe_strcmp (type, QUERYCORE_BOOLEAN)) {
strings[i++] = g_strdup("");
continue;
}
/* Do all the object conversions */
for (; converters; converters = converters->next) {
fcn = converters->data;
if (converters->next)
res = fcn (res);
}
/* Now convert this to a text value for the row */
if (!safe_strcmp(type, QUERYCORE_DEBCRED) ||
!safe_strcmp(type, QUERYCORE_NUMERIC))
{
gnc_numeric (*nfcn)(gpointer) = (gnc_numeric(*)(gpointer))fcn;
gnc_numeric value = nfcn(res);
strings[i++] = g_strdup(xaccPrintAmount(value,gnc_default_print_info(FALSE)));
} else
strings[i++] = gncQueryCoreToString (type, res, fcn);
}
row = gtk_clist_prepend (GTK_CLIST(list), (gchar **) strings);
gtk_clist_set_row_data (GTK_CLIST(list), row, item->data);
/* Free up our strings */
for (i = 0; i < list->num_columns; i++) {
if (strings[i])
g_free (strings[i]);
}
/* Now update any checkmarks */
update_booleans (list, row);
list->num_entries++;
}
/* Reverse the list again for the query code */
g_list_reverse(entries);
}

View File

@ -0,0 +1,102 @@
/********************************************************************\
* gnc-query-list.h -- GnuCash GNOME query display list widget *
* Copyright (C) 2003 Derek Atkins <derek@ihtfp.com> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License*
* along with this program; if not, contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
#ifndef GNC_QUERY_LIST_H
#define GNC_QUERY_LIST_H
#include <gtk/gtkclist.h>
#include "Query.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GTK_TYPE_GNC_QUERY_LIST (gnc_query_list_get_type ())
#define GNC_QUERY_LIST(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_GNC_QUERY_LIST, GNCQueryList))
#define GNC_QUERY_LIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_GNC_QUERY_LIST, GNCQueryListClass))
#define IS_GNC_QUERY_LIST(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_GNC_QUERY_LIST))
#define IS_GNC_QUERY_LIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_GNC_QUERY_LIST))
typedef struct _GNCQueryList GNCQueryList;
typedef struct _GNCQueryListClass GNCQueryListClass;
struct _GNCQueryList
{
GtkCList clist;
/* Query information */
Query *query;
gboolean no_toggle;
gint current_row;
gint num_entries;
gpointer current_entry;
/* Column information */
gint num_columns;
GList *column_params;
/* Sorting info */
gint sort_column;
gboolean increasing;
GtkWidget **title_arrows;
/* Column resizing */
gint prev_allocation;
gint *title_widths;
};
struct _GNCQueryListClass
{
GtkCListClass parent_class;
void (*line_toggled) (GNCQueryList *list, gpointer entry);
void (*double_click_entry) (GNCQueryList *list, gpointer entry);
};
/***********************************************************
* public functions *
***********************************************************/
GtkType gnc_query_list_get_type (void);
/* The param_list remains owned by the caller but is used by the
* query-list; do not destroy it until you destroy this query-list.
* The query will be copied by the query-list so the caller may do
* whatever they want.
*/
GtkWidget * gnc_query_list_new (GList *param_list, Query *query);
void gnc_query_list_reset_query (GNCQueryList *list, Query *query);
gint gnc_query_list_get_needed_height(GNCQueryList *list, gint num_rows);
gint gnc_query_list_get_num_entries(GNCQueryList *list);
gpointer gnc_query_list_get_current_entry(GNCQueryList *list);
void gnc_query_list_refresh (GNCQueryList *list);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* GNC_QUERY_LIST_H */