diff --git a/ChangeLog b/ChangeLog index ba40cd3e0f..1ea7735552 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,12 @@ so that the new-account-window can be called using the modal dialog interfaces. * use the GNCAccoutSel in the date-close dialog (fixes bug #94973) + + * create search-reconciled.[ch] to implement searches by reconcile flag + * gnome-search/search-core-type.c: hook in "reconciled" type, + via the RECONCILED_MATCH_TYPE string + * src/engine/Transaction.h -- add RECONCILED_MATCH_TYPE string + * hook into the Find Transactions window (fixes bug #95634) 2002-10-16 Joshua Sled diff --git a/src/engine/Transaction.h b/src/engine/Transaction.h index ebf921efb8..5f5ff1aca6 100644 --- a/src/engine/Transaction.h +++ b/src/engine/Transaction.h @@ -575,4 +575,6 @@ Timespec xaccTransGetVoidTime(Transaction *tr); * override so the gnome-search dialog displays the right type. */ +#define RECONCILED_MATCH_TYPE "reconciled-match" + #endif /* XACC_TRANSACTION_H */ diff --git a/src/gnome-search/Makefile.am b/src/gnome-search/Makefile.am index 85af605f6e..850cdcf1d1 100644 --- a/src/gnome-search/Makefile.am +++ b/src/gnome-search/Makefile.am @@ -27,6 +27,7 @@ libgncmod_gnome_search_la_SOURCES = \ search-int64.c \ search-numeric.c \ search-param.c \ + search-reconciled.c \ search-string.c gncincludedir = ${GNC_INCLUDE_DIR} @@ -43,6 +44,7 @@ noinst_HEADERS = \ search-int64.h \ search-numeric.h \ search-param.h \ + search-reconciled.h \ search-string.h libgncmod_gnome_search_la_LDFLAGS = -module diff --git a/src/gnome-search/search-core-type.c b/src/gnome-search/search-core-type.c index a4976115bc..242f614e38 100644 --- a/src/gnome-search/search-core-type.c +++ b/src/gnome-search/search-core-type.c @@ -27,9 +27,11 @@ #include "QueryNew.h" #include "Account.h" /* for ACCOUNT_MATCH_ALL_TYPE */ +#include "Transaction.h" /* for RECONCILED_MATCH_TYPE */ #include "search-core-type.h" #include "search-string.h" +#include "search-reconciled.h" #include "search-date.h" #include "search-double.h" #include "search-int64.h" @@ -268,6 +270,9 @@ init_table (void) gnc_search_core_register_type (ACCOUNT_MATCH_ALL_TYPE, (GNCSearchCoreNew) gnc_search_account_matchall_new); + gnc_search_core_register_type (RECONCILED_MATCH_TYPE, + (GNCSearchCoreNew) gnc_search_reconciled_new); + } void diff --git a/src/gnome-search/search-reconciled.c b/src/gnome-search/search-reconciled.c new file mode 100644 index 0000000000..135fffb576 --- /dev/null +++ b/src/gnome-search/search-reconciled.c @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2002 Derek Atkins + * + * Authors: Derek Atkins + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "QueryCore.h" +#include "Transaction.h" /* for ?REC */ + +#include "search-reconciled.h" + +#define d(x) + +static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe); +static gboolean gncs_validate (GNCSearchCoreType *fe); +static GtkWidget *gncs_get_widget(GNCSearchCoreType *fe); +static QueryPredData_t gncs_get_predicate (GNCSearchCoreType *fe); + +static void gnc_search_reconciled_class_init (GNCSearchReconciledClass *class); +static void gnc_search_reconciled_init (GNCSearchReconciled *gspaper); +static void gnc_search_reconciled_finalise (GtkObject *obj); + +#define _PRIVATE(x) (((GNCSearchReconciled *)(x))->priv) + +struct _GNCSearchReconciledPrivate { +}; + +static GNCSearchCoreTypeClass *parent_class; + +enum { + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +guint +gnc_search_reconciled_get_type (void) +{ + static guint type = 0; + + if (!type) { + GtkTypeInfo type_info = { + "GNCSearchReconciled", + sizeof(GNCSearchReconciled), + sizeof(GNCSearchReconciledClass), + (GtkClassInitFunc)gnc_search_reconciled_class_init, + (GtkObjectInitFunc)gnc_search_reconciled_init, + (GtkArgSetFunc)NULL, + (GtkArgGetFunc)NULL + }; + + type = gtk_type_unique(gnc_search_core_type_get_type (), &type_info); + } + + return type; +} + +static void +gnc_search_reconciled_class_init (GNCSearchReconciledClass *class) +{ + GtkObjectClass *object_class; + GNCSearchCoreTypeClass *gnc_search_core_type = (GNCSearchCoreTypeClass *)class; + + object_class = (GtkObjectClass *)class; + parent_class = gtk_type_class(gnc_search_core_type_get_type ()); + + object_class->finalize = gnc_search_reconciled_finalise; + + /* override methods */ + gnc_search_core_type->validate = gncs_validate; + gnc_search_core_type->get_widget = gncs_get_widget; + gnc_search_core_type->get_predicate = gncs_get_predicate; + gnc_search_core_type->clone = gncs_clone; + + /* signals */ + + gtk_object_class_add_signals(object_class, signals, LAST_SIGNAL); +} + +static void +gnc_search_reconciled_init (GNCSearchReconciled *o) +{ + o->priv = g_malloc0 (sizeof (*o->priv)); + o->how = COMPARE_EQUAL; + o->value = CLEARED_NO; +} + +static void +gnc_search_reconciled_finalise (GtkObject *obj) +{ + GNCSearchReconciled *o = (GNCSearchReconciled *)obj; + g_assert (IS_GNCSEARCH_RECONCILED (o)); + + g_free(o->priv); + + ((GtkObjectClass *)(parent_class))->finalize(obj); +} + +/** + * gnc_search_reconciled_new: + * + * Create a new GNCSearchReconciled object. + * + * Return value: A new #GNCSearchReconciled object. + **/ +GNCSearchReconciled * +gnc_search_reconciled_new (void) +{ + GNCSearchReconciled *o = (GNCSearchReconciled *)gtk_type_new(gnc_search_reconciled_get_type ()); + return o; +} + +void +gnc_search_reconciled_set_value (GNCSearchReconciled *fi, cleared_match_t value) +{ + g_return_if_fail (fi); + g_return_if_fail (IS_GNCSEARCH_RECONCILED (fi)); + + fi->value = value; +} + +void +gnc_search_reconciled_set_how (GNCSearchReconciled *fi, char_match_t how) +{ + g_return_if_fail (fi); + g_return_if_fail (IS_GNCSEARCH_RECONCILED (fi)); + fi->how = how; +} + +static gboolean +gncs_validate (GNCSearchCoreType *fe) +{ + GNCSearchReconciled *fi = (GNCSearchReconciled *)fe; + gboolean valid = TRUE; + + g_return_val_if_fail (fi, FALSE); + g_return_val_if_fail (IS_GNCSEARCH_RECONCILED (fi), FALSE); + + /* XXX */ + + return valid; +} + +static void +option_changed (GtkWidget *widget, GNCSearchReconciled *fe) +{ + fe->how = (char_match_t) + gtk_object_get_data (GTK_OBJECT (widget), "option"); +} + +static void +toggle_changed (GtkToggleButton *button, GNCSearchReconciled *fe) +{ + gboolean is_on = gtk_toggle_button_get_active (button); + cleared_match_t value = + (cleared_match_t) gtk_object_get_data (GTK_OBJECT (button), "button-value"); + + if (is_on) + fe->value |= value; + else + fe->value &= ~value; +} + +static GtkWidget * +add_menu_item (GtkWidget *menu, gpointer user_data, char *label, + char_match_t option) +{ + GtkWidget *item = gtk_menu_item_new_with_label (label); + gtk_object_set_data (GTK_OBJECT (item), "option", (gpointer) option); + gtk_signal_connect (GTK_OBJECT (item), "activate", option_changed, user_data); + gtk_menu_append (GTK_MENU (menu), item); + gtk_widget_show (item); + return item; +} + +#define ADD_MENU_ITEM(str,op) { \ + item = add_menu_item (menu, fe, str, op); \ + if (fi->how == op) { current = index; first = item; } \ + index++; \ +} + +static GtkWidget * +make_menu (GNCSearchCoreType *fe) +{ + GNCSearchReconciled *fi = (GNCSearchReconciled *)fe; + GtkWidget *menu, *item, *first, *opmenu; + int current = 0, index = 0; + + menu = gtk_menu_new (); + + ADD_MENU_ITEM (_("is"), CHAR_MATCH_ANY); + first = item; /* Force one */ + ADD_MENU_ITEM (_("is not"), CHAR_MATCH_NONE); + + opmenu = gtk_option_menu_new (); + gtk_option_menu_set_menu (GTK_OPTION_MENU (opmenu), menu); + + gtk_signal_emit_by_name (GTK_OBJECT (first), "activate", fe); + gtk_option_menu_set_history (GTK_OPTION_MENU (opmenu), current); + + return opmenu; +} + +static GtkWidget * +make_toggle (GNCSearchReconciled *fi, char *label, char_match_t option) +{ + GtkWidget *toggle; + + toggle = gtk_toggle_button_new_with_label (label); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), (fi->value & option)); + gtk_object_set_data (GTK_OBJECT (toggle), "button-value", (gpointer) option); + gtk_signal_connect (GTK_OBJECT (toggle), "toggled", toggle_changed, fi); + + return toggle; +} + +static GtkWidget * +gncs_get_widget (GNCSearchCoreType *fe) +{ + GtkWidget *toggle, *menu, *box; + GNCSearchReconciled *fi = (GNCSearchReconciled *)fe; + + g_return_val_if_fail (fi, NULL); + g_return_val_if_fail (IS_GNCSEARCH_RECONCILED (fi), NULL); + + box = gtk_hbox_new (FALSE, 3); + + /* Build and connect the option menu */ + menu = make_menu (fe); + gtk_box_pack_start (GTK_BOX (box), menu, FALSE, FALSE, 3); + + /* Build and connect the toggles */ + toggle = make_toggle (fi, _("Not Cleared"), CLEARED_NO); + gtk_box_pack_start (GTK_BOX (box), toggle, FALSE, FALSE, 3); + + toggle = make_toggle (fi, _("Cleared"), CLEARED_CLEARED); + gtk_box_pack_start (GTK_BOX (box), toggle, FALSE, FALSE, 3); + + toggle = make_toggle (fi, _("Reconciled"), CLEARED_RECONCILED); + gtk_box_pack_start (GTK_BOX (box), toggle, FALSE, FALSE, 3); + + toggle = make_toggle (fi, _("Frozen"), CLEARED_FROZEN); + gtk_box_pack_start (GTK_BOX (box), toggle, FALSE, FALSE, 3); + + toggle = make_toggle (fi, _("Voided"), CLEARED_VOIDED); + gtk_box_pack_start (GTK_BOX (box), toggle, FALSE, FALSE, 3); + + /* And return the box */ + return box; +} + +static QueryPredData_t gncs_get_predicate (GNCSearchCoreType *fe) +{ + GNCSearchReconciled *fi = (GNCSearchReconciled *)fe; + char chars[6]; + cleared_match_t value; + int i; + + g_return_val_if_fail (fi, NULL); + g_return_val_if_fail (IS_GNCSEARCH_RECONCILED (fi), NULL); + + /* This code should look a lot like xaccQueryAddClearedMatch() */ + + value = fi->value; + i = 0; + + if (value & CLEARED_CLEARED) + chars[i++] = CREC; + if (value & CLEARED_RECONCILED) + chars[i++] = YREC; + if (value & CLEARED_FROZEN) + chars[i++] = FREC; + if (value & CLEARED_NO) + chars[i++] = NREC; + if (value & CLEARED_VOIDED) + chars[i++] = VREC; + chars[i] = '\0'; + + return gncQueryCharPredicate (fi->how, chars); +} + +static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe) +{ + GNCSearchReconciled *se, *fse = (GNCSearchReconciled *)fe; + + g_return_val_if_fail (fse, NULL); + g_return_val_if_fail (IS_GNCSEARCH_RECONCILED (fse), NULL); + + se = gnc_search_reconciled_new (); + gnc_search_reconciled_set_value (se, fse->value); + gnc_search_reconciled_set_how (se, fse->how); + + return (GNCSearchCoreType *)se; +} diff --git a/src/gnome-search/search-reconciled.h b/src/gnome-search/search-reconciled.h new file mode 100644 index 0000000000..d854c2c9e7 --- /dev/null +++ b/src/gnome-search/search-reconciled.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2002 Derek Atkins + * + * Authors: Derek Atkins + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GNCSEARCH_RECONCILED_H +#define _GNCSEARCH_RECONCILED_H + +#include "search-core-type.h" +#include "Query.h" /* for cleared_match_t */ + +#define GNCSEARCH_RECONCILED(obj) GTK_CHECK_CAST (obj, gnc_search_reconciled_get_type (), GNCSearchReconciled) +#define GNCSEARCH_RECONCILED_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gnc_search_reconciled_get_type (), GNCSearchReconciledClass) +#define IS_GNCSEARCH_RECONCILED(obj) GTK_CHECK_TYPE (obj, gnc_search_reconciled_get_type ()) + +typedef struct _GNCSearchReconciled GNCSearchReconciled; +typedef struct _GNCSearchReconciledClass GNCSearchReconciledClass; + +struct _GNCSearchReconciled { + GNCSearchCoreType parent; + struct _GNCSearchReconciledPrivate *priv; + + char_match_t how; + cleared_match_t value; +}; + +struct _GNCSearchReconciledClass { + GNCSearchCoreTypeClass parent_class; + + /* virtual methods */ + + /* signals */ +}; + +guint gnc_search_reconciled_get_type (void); +GNCSearchReconciled *gnc_search_reconciled_new (void); + +/* methods */ +void gnc_search_reconciled_set_value(GNCSearchReconciled *fi, cleared_match_t value); +void gnc_search_reconciled_set_how (GNCSearchReconciled *fi, char_match_t how); + +#endif /* ! _GNCSEARCH_RECONCILED_H */ diff --git a/src/gnome/dialog-find-transactions.c b/src/gnome/dialog-find-transactions.c index ce22717797..86fd0c5b94 100644 --- a/src/gnome/dialog-find-transactions.c +++ b/src/gnome/dialog-find-transactions.c @@ -102,7 +102,8 @@ gnc_ui_find_transactions_dialog_create(GNCLedgerDisplay * orig_ledg) params = gnc_search_param_prepend (params, "Balanced", NULL, type, SPLIT_TRANS, TRANS_IS_BALANCED, NULL); - /* XXX:FIXME add the 'cleared' parameter here */ + params = gnc_search_param_prepend (params, "Reconcile", RECONCILED_MATCH_TYPE, + type, SPLIT_RECONCILE, NULL); params = gnc_search_param_prepend (params, "Share Price", NULL, type, SPLIT_SHARE_PRICE, NULL); params = gnc_search_param_prepend (params, "Share Price", NULL,