A new generic search dialog for gnome, and a test to show how it

works.  Still more to come...


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@6698 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Derek Atkins
2002-02-08 05:09:52 +00:00
parent 4f98e2cb49
commit 4c948bdabc
19 changed files with 2353 additions and 0 deletions

View File

@@ -843,6 +843,7 @@ AC_OUTPUT(
src/gnome/glade/Makefile
src/gnome-utils/Makefile
src/gnome-utils/test/Makefile
src/gnome-search/Makefile
src/import-export/Makefile
src/import-export/binary-import/Makefile
src/import-export/binary-import/test/Makefile

View File

@@ -16,6 +16,7 @@ GUI_SUBDIRS_1 = \
tax \
app-utils \
gnome-utils \
gnome-search \
app-file
GUI_SUBDIRS_2 = \

View File

@@ -4,6 +4,7 @@
(gnc:module-load "gnucash/gnome-utils" 0)
(gnc:module-load "gnucash/business-core" 0)
(gnc:module-load "gnucash/gnome-search" 0)
(define (add-customer-extensions)
(let ((last-cust (gnc:owner-create)))
@@ -167,9 +168,17 @@
(lambda ()
(gnc:invoice-edit #f gnc:extensions-last-invoice))))
(define test-search
(gnc:make-menu-item (N_ "Test Search Dialog")
(N_ "Test Search Dialog")
(list "Extensions" "")
(lambda ()
(gnc:search-dialog-test))))
;; (gnc:add-extension edit-invoice-item)
;; (gnc:add-extension edit-order-item)
(gnc:add-extension test-search)
(gnc:add-extension select-employee-item)
(gnc:add-extension new-employee-item)
(gnc:add-extension select-job-item)

View File

@@ -0,0 +1,11 @@
*.lo
*.la
.deps
.libs
.scm-links
Makefile
Makefile.in
gw-gnome-search.c
gw-gnome-search.h
gw-gnome-search.html
gw-gnome-search.scm

View File

@@ -0,0 +1,83 @@
pkglib_LTLIBRARIES = libgncmod-gnome-search.la libgw-gnome-search.la
AM_CFLAGS = \
-I${top_srcdir}/src \
-I${top_srcdir}/src/engine \
-I${top_srcdir}/src/app-utils \
-I${top_srcdir}/src/gnome-utils \
-I${top_srcdir}/src/gnc-module \
-I${top_srcdir}/src/business/business-core \
${G_WRAP_COMPILE_ARGS} \
${GUILE_INCS} \
${GTKHTML_CFLAGS} \
${GLADE_CFLAGS} \
${GNOME_INCLUDEDIR} \
${GLIB_CFLAGS}
libgncmod_gnome_search_la_SOURCES = \
gncmod-gnome-search.c \
dialog-search.c \
search-core-type.c \
search-date.c \
search-param.c \
search-string.c
noinst_HEADERS = \
search-core-type.h \
search-date.h \
search-param.h \
search-string.h
libgncmod_gnome_search_la_LDFLAGS = -module
libgncmod_gnome_search_la_LIBADD = \
${top_srcdir}/src/gnc-module/libgncmodule.la \
${GUILE_LIBS} \
${GNOME_LIBDIR} \
${GNOMEUI_LIBS} \
${GTKHTML_LIBS} \
${GLADE_LIBS} \
${GLIB_LIBS}
libgw_gnome_search_la_SOURCES = gw-gnome-search.c
libgw_gnome_search_la_LDFLAGS = -module ${G_WRAP_LINK_ARGS}
gncmoddir = ${GNC_SHAREDIR}/guile-modules/gnucash
gncmod_DATA = gnome-search.scm
gladedir = $(GNC_GLADE_DIR)
glade_DATA = \
search.glade
gwmoddir = ${GNC_GWRAP_LIBDIR}
gwmod_DATA = \
gw-gnome-search.scm \
gw-gnome-search-spec.scm
EXTRA_DIST = \
.cvsignore \
${glade_DATA} \
${gncmod_DATA} \
${gwmod_DATA}
.scm-links:
rm -f gnucash g-wrapped
ln -sf . gnucash
ln -sf . g-wrapped
touch .scm-links
gncmod-gnome-search.c: gw-gnome-search.h
gw-gnome-search.scm gw-gnome-search.c gw-gnome-search.h: .scm-links gw-gnome-search-spec.scm
FLAVOR=gnome guile -c \
"(set! %load-path (cons \"${G_WRAP_MODULE_DIR}\" %load-path)) \
(set! %load-path (cons \"${PWD}\" %load-path)) \
(set! %load-path (cons \"../engine\" %load-path)) \
(set! %load-path (cons \"../app-utils\" %load-path)) \
(set! %load-path (cons \"../gnome-utils\" %load-path)) \
(primitive-load \"./gw-gnome-search-spec.scm\") \
(gw:generate-wrapset \"gw-gnome-search\")"
BUILT_SOURCES = gw-gnome-search.scm gw-gnome-search.c gw-gnome-search.h
CLEANFILES = gw-gnome-search.scm gw-gnome-search.c gw-gnome-search.h gw-gnome-search.html

View File

@@ -0,0 +1,428 @@
/*
* dialog-search.c -- Search Dialog
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*/
#include "config.h"
#include <gnome.h>
#include <glib.h>
#include "dialog-utils.h"
#include "window-help.h"
#include "gnc-component-manager.h"
#include "gncObject.h"
#include "QueryNew.h"
#include "dialog-search.h"
#include "search-core-type.h"
#include "search-param.h"
#define DIALOG_SEARCH_CM_CLASS "dialog-search"
struct _GNCSearchWindow {
GtkWidget * dialog;
GtkWidget * criteria_table;
GNCIdTypeConst search_for;
GNCSearchType grouping; /* Match Any, Match All */
int search_type; /* New, Narrow, Add, Delete */
QueryNew * q;
GNCSearchParam * last_param;
GList * params_list; /* List of GNCSearchParams */
GList * crit_list; /* list of crit_data */
};
struct _crit_data {
GNCSearchParam * param;
GNCSearchCoreType * element;
GtkWidget * elemwidget;
GtkWidget * container;
};
static void
match_all (GtkWidget *widget, GNCSearchWindow *sw)
{
sw->grouping = GNC_SEARCH_MATCH_ALL;
}
static void
match_any (GtkWidget *widget, GNCSearchWindow *sw)
{
sw->grouping = GNC_SEARCH_MATCH_ANY;
}
static void
search_type_cb (GtkToggleButton *button, GNCSearchWindow *sw)
{
GSList * buttongroup = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
sw->search_type =
g_slist_length (buttongroup) - g_slist_index (buttongroup, button) - 1;
}
}
static void
search_find_cb (GtkButton *button, GNCSearchWindow *sw)
{
/* XXX */
}
static void
search_cancel_cb (GtkButton *button, GNCSearchWindow *sw)
{
gnc_search_dialog_destroy (sw);
}
static void
search_help_cb (GtkButton *button, GNCSearchWindow *sw)
{
helpWindow (NULL, NULL, ""); /* XXX */
}
static void
remove_element (GtkWidget *button, GNCSearchWindow *sw)
{
GtkWidget *element;
struct _elem_data *data;
if (g_list_length (sw->crit_list) < 2)
return;
element = gtk_object_get_data (GTK_OBJECT (button), "element");
data = gtk_object_get_data (GTK_OBJECT (element), "data");
/* remove the element from the list */
sw->crit_list = g_list_remove (sw->crit_list, data);
/* and from the display */
gtk_container_remove (GTK_CONTAINER (sw->criteria_table), element);
gtk_container_remove (GTK_CONTAINER (sw->criteria_table), button);
gtk_object_destroy (GTK_OBJECT (element));
gtk_object_destroy (GTK_OBJECT (button));
}
static void
attach_element (GtkWidget *element, GNCSearchWindow *sw, int row)
{
GtkWidget *pixmap, *remove;
gtk_table_attach (GTK_TABLE (sw->criteria_table), element, 0, 1, row, row+1,
GTK_EXPAND | GTK_FILL, 0, 0, 0);
pixmap = gnome_stock_new_with_icon (GNOME_STOCK_PIXMAP_REMOVE);
remove = gnome_pixmap_button (pixmap, _("Remove"));
gtk_object_set_data (GTK_OBJECT (remove), "element", element);
gtk_signal_connect (GTK_OBJECT (remove), "clicked", remove_element, sw);
gtk_table_attach (GTK_TABLE (sw->criteria_table), remove, 1, 2, row, row+1,
0, 0, 0, 0);
gtk_widget_show (remove);
}
static void
option_activate (GtkMenuItem *item, struct _crit_data *data)
{
GNCSearchParam *param = gtk_object_get_data (GTK_OBJECT (item), "param");
GNCSearchCoreType *newelem;
if (gnc_search_param_type_match (param, data->param)) {
/* The param type is the same, just save the new param */
data->param = param;
return;
}
data->param = param;
/* OK, let's do a widget shuffle, throw away the old widget/element,
* and create another one here. No need to change the crit_list --
* the pointer to data stays the same.
*/
if (data->elemwidget)
gtk_container_remove (GTK_CONTAINER (data->container), data->elemwidget);
gtk_object_destroy (GTK_OBJECT (data->element));
newelem = gnc_search_core_type_new_type_name
(gnc_search_param_get_param_type (param));
data->element = newelem;
data->elemwidget = gnc_search_core_type_get_widget (newelem);
if (data->elemwidget)
gtk_box_pack_start (GTK_BOX (data->container), data->elemwidget,
FALSE, FALSE, 0);
/* Make sure it's visible */
gtk_widget_show_all (data->container);
}
static GtkWidget *
get_element_widget (GNCSearchWindow *sw, GNCSearchCoreType *element)
{
GtkWidget *menu, *item, *omenu, *hbox, *p;
GList *l;
struct _crit_data *data;
int index = 0, current = 0;
data = g_new0 (struct _crit_data, 1);
data->element = element;
hbox = gtk_hbox_new (FALSE, 0);
/* only set to automaticaly clean up the memory */
gtk_object_set_data_full (GTK_OBJECT (hbox), "data", data, g_free);
p = gnc_search_core_type_get_widget (element);
data->elemwidget = p;
data->container = hbox;
data->param = sw->last_param;
menu = gtk_menu_new ();
for (l = sw->params_list; l; l = l->next) {
GNCSearchParam *param = l->data;
item = gtk_menu_item_new_with_label (_(param->title));
gtk_object_set_data (GTK_OBJECT (item), "param", param);
gtk_signal_connect (GTK_OBJECT (item), "activate", option_activate, data);
gtk_menu_append (GTK_MENU (menu), item);
gtk_widget_show (item);
if (param == sw->last_param) /* is this the right parameter to start? */
current = index;
index++;
}
omenu = gtk_option_menu_new ();
gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), current);
gtk_widget_show (omenu);
gtk_box_pack_start (GTK_BOX (hbox), omenu, FALSE, FALSE, 0);
if (p)
gtk_box_pack_start (GTK_BOX (hbox), p, FALSE, FALSE, 0);
gtk_widget_show_all (hbox);
return hbox;
}
static void
gnc_search_dialog_add_criterion (GNCSearchWindow *sw)
{
GNCSearchCoreType *new;
/* First, make sure that the last criterion is ok */
if (sw->crit_list) {
struct _crit_data *data;
GList *l;
l = g_list_last (sw->crit_list);
data = l->data;
if (!gnc_search_core_type_validate (data->element))
return;
sw->last_param = data->param;
} else
sw->last_param = sw->params_list->data;
/* create a new criterion element */
new = gnc_search_core_type_new_type_name
(gnc_search_param_get_param_type (sw->last_param));
if (new) {
struct _crit_data *data;
GtkWidget *w;
int rows;
w = get_element_widget (sw, new);
data = gtk_object_get_data (GTK_OBJECT (w), "data");
sw->crit_list = g_list_append (sw->crit_list, data);
rows = GTK_TABLE (sw->criteria_table)->nrows;
gtk_table_resize (GTK_TABLE (sw->criteria_table), rows+1, 2);
attach_element (w, sw, rows);
}
}
static void
add_criterion (GtkWidget *button, GNCSearchWindow *sw)
{
gnc_search_dialog_add_criterion (sw);
}
static int
gnc_search_dialog_close_cb (GnomeDialog *dialog, GNCSearchWindow *sw)
{
gnc_unregister_gui_component_by_data (DIALOG_SEARCH_CM_CLASS, sw);
/* XXX: Clear the params_list? */
g_list_free (sw->crit_list);
g_free (sw);
return FALSE;
}
static void
close_handler (GNCSearchWindow *sw)
{
gnome_dialog_close (GNOME_DIALOG (sw->dialog));
}
static void
gnc_search_dialog_init_widgets (GNCSearchWindow *sw)
{
GladeXML *xml;
GtkWidget *label, *pixmap, *add, *box;
GtkWidget *menu, *item, *omenu;
GtkWidget *new_rb, *narrow_rb, *add_rb, *del_rb;
xml = gnc_glade_xml_new ("search.glade", "Search Dialog");
/* Grab the dialog */
sw->dialog = glade_xml_get_widget (xml, "Search Dialog");
/* Grab the search-table widget */
sw->criteria_table = glade_xml_get_widget (xml, "criteria_table");
/* Set the type label */
label = glade_xml_get_widget (xml, "type_label");
gtk_label_set_text (GTK_LABEL (label),
gncObjectGetTypeLabel (sw->search_for));
/* Set the 'add criterion' button */
pixmap = gnome_stock_new_with_icon (GNOME_STOCK_PIXMAP_ADD);
add = gnome_pixmap_button (pixmap, _("Add criterion"));
gtk_signal_connect (GTK_OBJECT (add), "clicked", add_criterion, sw);
box = glade_xml_get_widget (xml, "add_button_box");
gtk_box_pack_start (GTK_BOX (box), add, FALSE, FALSE, 3);
/* Set the match-type menu */
menu = gtk_menu_new ();
item = gtk_menu_item_new_with_label (_("all criteria are met"));
gtk_signal_connect (GTK_OBJECT (item), "activate", match_all, sw);
gtk_menu_append (GTK_MENU (menu), item);
gtk_widget_show (item);
item = gtk_menu_item_new_with_label (_("any criteria are met"));
gtk_signal_connect (GTK_OBJECT (item), "activate", match_any, sw);
gtk_menu_append (GTK_MENU (menu), item);
gtk_widget_show (item);
omenu = gtk_option_menu_new ();
gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), sw->grouping);
gtk_widget_show (omenu);
box = glade_xml_get_widget (xml, "type_menu_box");
gtk_box_pack_start (GTK_BOX (box), omenu, FALSE, FALSE, 3);
/* add the first criterion */
gnc_search_dialog_add_criterion (sw);
/* if there's no original query, make the narrow, add, delete
* buttons inaccessible */
new_rb = glade_xml_get_widget (xml, "new_search_radiobutton");
narrow_rb = glade_xml_get_widget (xml, "narrow_search_radiobutton");
add_rb = glade_xml_get_widget (xml, "add_search_radiobutton");
del_rb = glade_xml_get_widget (xml, "delete_search_radiobutton");
if(!sw->q) {
gtk_widget_set_sensitive(GTK_WIDGET(narrow_rb), 0);
gtk_widget_set_sensitive(GTK_WIDGET(add_rb), 0);
gtk_widget_set_sensitive(GTK_WIDGET(del_rb), 0);
}
else {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (new_rb), 0);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (narrow_rb), 1);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (add_rb), 0);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (del_rb), 0);
}
/* show it all */
gtk_widget_show_all (sw->dialog);
/* Connect XML signals */
glade_xml_signal_connect_data (xml, "gnc_ui_search_type_cb",
GTK_SIGNAL_FUNC (search_type_cb), sw);
glade_xml_signal_connect_data (xml, "gnc_ui_search_find_cb",
GTK_SIGNAL_FUNC (search_find_cb), sw);
glade_xml_signal_connect_data (xml, "gnc_ui_search_cancel_cb",
GTK_SIGNAL_FUNC (search_cancel_cb), sw);
glade_xml_signal_connect_data (xml, "gnc_ui_search_help_cb",
GTK_SIGNAL_FUNC (search_help_cb), sw);
/* Register ourselves */
gnc_register_gui_component (DIALOG_SEARCH_CM_CLASS, NULL, close_handler, sw);
/* And setup the close callback */
gtk_signal_connect (GTK_OBJECT (sw->dialog), "close",
GTK_SIGNAL_FUNC (gnc_search_dialog_close_cb), sw);
}
void
gnc_search_dialog_destroy (GNCSearchWindow *sw)
{
if (!sw) return;
gnc_close_gui_component_by_data (DIALOG_SEARCH_CM_CLASS, sw);
}
static GList *
get_params_list (GNCIdTypeConst type)
{
GList *list = NULL;
GNCSearchParam *param;
param = gnc_search_param_new ();
gnc_search_param_set_title (param, "Split Memo");
gnc_search_param_set_param_path (param, type,
g_slist_prepend (NULL, SPLIT_MEMO));
list = g_list_prepend (list, param);
param = gnc_search_param_new ();
gnc_search_param_set_title (param, "Date Reconciled");
gnc_search_param_set_param_path (param, type,
g_slist_prepend (NULL, SPLIT_DATE_RECONCILED));
list = g_list_prepend (list, param);
return list;
}
GNCSearchWindow *
gnc_search_dialog_create (GNCIdTypeConst obj_type)
{
GNCSearchWindow *sw = g_new0 (GNCSearchWindow, 1);
sw->search_for = obj_type;
sw->params_list = get_params_list (obj_type);
gnc_search_dialog_init_widgets (sw);
return sw;
}
static int
on_close_cb (GnomeDialog *dialog, gpointer *data)
{
if (data) {
*data = "FOO";
}
gtk_main_quit ();
return FALSE;
}
void
gnc_search_dialog_test (void)
{
gpointer result = NULL;
GNCSearchWindow *sw = gnc_search_dialog_create (GNC_ID_SPLIT);
gtk_signal_connect (GTK_OBJECT (sw->dialog), "close",
GTK_SIGNAL_FUNC (on_close_cb), &result);
gtk_main ();
}

View File

@@ -0,0 +1,24 @@
/*
* dialog-search.h -- Search Dialog
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*/
#ifndef _GNC_DIALOG_SEARCH_H
#define _GNC_DIALOG_SEARCH_H
#include "GNCId.h"
typedef struct _GNCSearchWindow GNCSearchWindow;
typedef enum {
GNC_SEARCH_MATCH_ALL = 0,
GNC_SEARCH_MATCH_ANY = 1
} GNCSearchType;
void gnc_search_dialog_destroy (GNCSearchWindow *sw);
GNCSearchWindow * gnc_search_dialog_create (GNCIdTypeConst obj_type);
void gnc_search_dialog_test (void);
#endif

View File

@@ -0,0 +1,58 @@
/*********************************************************************
* gncmod-gnome-search
* GNC Module initialization for the Gnome Search UI
*
* Copyright (c) 2002 Derek Atkins <warlord@MIT.EDU>
*********************************************************************/
#include <stdio.h>
#include <guile/gh.h>
#include <glib.h>
#include "gnc-module.h"
#include "gnc-module-api.h"
/* version of the gnc module system interface we require */
int gnc_module_system_interface = 0;
/* module versioning uses libtool semantics. */
int gnc_module_current = 0;
int gnc_module_revision = 0;
int gnc_module_age = 0;
char *
gnc_module_path(void)
{
return g_strdup("gnucash/gnome-search");
}
char *
gnc_module_description(void)
{
return g_strdup("The Gnucash Gnome Search UI");
}
int
gnc_module_init(int refcount)
{
/* load the engine (we depend on it) */
if(!gnc_module_load("gnucash/engine", 0)) {
return FALSE;
}
if(refcount == 0)
{
/* initialize known types */
;
}
gh_eval_str("(use-modules (g-wrapped gw-gnome-search))");
gh_eval_str("(use-modules (gnucash gnome-search))");
return TRUE;
}
int
gnc_module_end(int refcount) {
return TRUE;
}

View File

@@ -0,0 +1 @@
(define-module (gnucash gnome-search))

View File

@@ -0,0 +1,50 @@
;;; -*-scheme-*-
;(debug-enable 'backtrace)
;(debug-enable 'debug)
;(read-enable 'positions)
(debug-set! maxdepth 100000)
(debug-set! stack 2000000)
(define-module (g-wrapped gw-gnome-search-spec)
:use-module (g-wrap))
(use-modules (g-wrap))
(use-modules (g-wrap gw-standard-spec))
(use-modules (g-wrap gw-wct-spec))
(use-modules (g-wrapped gw-gnome-utils-spec))
(let ((ws (gw:new-wrapset "gw-gnome-search")))
(gw:wrapset-depends-on ws "gw-standard")
(gw:wrapset-depends-on ws "gw-engine")
(gw:wrapset-depends-on ws "gw-gnome-utils")
(gw:wrapset-set-guile-module! ws '(g-wrapped gw-gnome-search))
(gw:wrapset-add-cs-declarations!
ws
(lambda (wrapset client-wrapset)
(list
"#include <dialog-search.h>\n"
)))
(gw:wrapset-add-cs-initializers!
ws
(lambda (wrapset client-wrapset status-var)
(if client-wrapset
'()
(gw:inline-scheme '(use-modules (gnucash gnome-search))))))
(gw:wrap-function
ws
'gnc:search-dialog-test
'<gw:void>
"gnc_search_dialog_test"
'()
"Dialog: create a test Search Dialog.")
)

View File

@@ -0,0 +1,234 @@
/*
* Copyright (C) 2002 Derek Atkins
*
* Authors: Derek Atkins <warlord@MIT.EDU>
*
* 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 <config.h>
#endif
#include <string.h>
#include <gnome.h>
#include "QueryNew.h"
#include "search-core-type.h"
#include "search-string.h"
#include "search-date.h"
#if 0
#include "search-input.h"
#include "search-option.h"
#include "search-code.h"
#include "search-colour.h"
#include "search-datespec.h"
#include "search-score.h"
#include "search-int.h"
#include "search-folder.h"
#include "search-source.h"
#endif
static gboolean validate (GNCSearchCoreType *fe);
static void gnc_search_core_type_class_init (GNCSearchCoreTypeClass *class);
static void gnc_search_core_type_init (GNCSearchCoreType *gspaper);
static void gnc_search_core_type_finalise (GtkObject *obj);
#define _PRIVATE(x) (((GNCSearchCoreType *)(x))->priv)
struct _GNCSearchCoreTypePrivate {
};
static GtkObjectClass *parent_class;
enum {
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
guint
gnc_search_core_type_get_type (void)
{
static guint type = 0;
if (!type) {
GtkTypeInfo type_info = {
"GNCSearchCoreType",
sizeof(GNCSearchCoreType),
sizeof(GNCSearchCoreTypeClass),
(GtkClassInitFunc)gnc_search_core_type_class_init,
(GtkObjectInitFunc)gnc_search_core_type_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL
};
type = gtk_type_unique(gtk_object_get_type (), &type_info);
}
return type;
}
static void
gnc_search_core_type_class_init (GNCSearchCoreTypeClass *class)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass *)class;
parent_class = gtk_type_class (gtk_object_get_type ());
object_class->finalize = gnc_search_core_type_finalise;
/* override methods */
class->validate = validate;
/* signals */
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
}
static void
gnc_search_core_type_init (GNCSearchCoreType *o)
{
o->priv = g_malloc0 (sizeof (*o->priv));
}
static void
gnc_search_core_type_finalise (GtkObject *obj)
{
GNCSearchCoreType *o = (GNCSearchCoreType *)obj;
g_free(o->priv);
((GtkObjectClass *)(parent_class))->finalize(obj);
}
/**
* gnc_search_core_type_new:
*
* Create a new GNCSearchCoreType object.
*
* Return value: A new #GNCSearchCoreType object.
**/
GNCSearchCoreType *
gnc_search_core_type_new (void)
{
GNCSearchCoreType *o = (GNCSearchCoreType *)gtk_type_new(gnc_search_core_type_get_type ());
return o;
}
gboolean
gnc_search_core_type_validate (GNCSearchCoreType *fe)
{
return ((GNCSearchCoreTypeClass *)((GtkObject *)fe)->klass)->validate (fe);
}
/**
* gnc_search_core_type_clone:
* @fe: search core_type
*
* Clones the GNCSearchCoreType @fe.
*
* Return value:
**/
GNCSearchCoreType *
gnc_search_core_type_clone (GNCSearchCoreType *fe)
{
return ((GNCSearchCoreTypeClass *)((GtkObject *)fe)->klass)->clone(fe);
}
/**
* gnc_search_core_type_get_widget:
* @fe: search core_type
* @node: xml node
*
* Create a widget to represent this core_type.
*
* Return value:
**/
GtkWidget *
gnc_search_core_type_get_widget (GNCSearchCoreType *fe)
{
return ((GNCSearchCoreTypeClass *)((GtkObject *)fe)->klass)->get_widget(fe);
}
/**
* gnc_search_core_type_get_predicate:
* @fe: search core_type
*
* Create a Predicate Data that matches this core_type
*
* Return value:
**/
QueryPredData_t
gnc_search_core_type_get_predicate (GNCSearchCoreType *fe)
{
return ((GNCSearchCoreTypeClass *)((GtkObject *)fe)->klass)->get_predicate(fe);
}
/**
* gnc_search_core_type_new_type_name:
* @type: search core_type type
*
* Create a new search core_type based on its type name.
*
* Return value:
**/
GNCSearchCoreType *
gnc_search_core_type_new_type_name (const char *type)
{
if (type == NULL)
return NULL;
if (!strcmp (type, QUERYCORE_STRING)) {
return (GNCSearchCoreType *)gnc_search_string_new ();
} else if (!strcmp (type, QUERYCORE_DATE)) {
return (GNCSearchCoreType *)gnc_search_date_new ();
#if 0
} else if (!strcmp (type, "folder")) {
return (GNCSearchCoreType *)gnc_search_folder_new ();
} else if (!strcmp (type, "address")) {
/* FIXME: temporary ... need real address type */
return (GNCSearchCoreType *)gnc_search_input_new_type_name (type);
} else if (!strcmp (type, "code")) {
return (GNCSearchCoreType *)gnc_search_code_new ();
} else if (!strcmp (type, "colour")) {
return (GNCSearchCoreType *)gnc_search_colour_new ();
} else if (!strcmp (type, "optionlist") || !strcmp (type, "system-flag")) {
return (GNCSearchCoreType *)gnc_search_option_new ();
} else if (!strcmp (type, "datespec")) {
return (GNCSearchCoreType *)gnc_search_datespec_new ();
} else if (!strcmp (type, "score")) {
return (GNCSearchCoreType *)gnc_search_score_new ();
} else if (!strcmp (type, "integer")) {
return (GNCSearchCoreType *)gnc_search_int_new ();
} else if (!strcmp (type, "regex")) {
return (GNCSearchCoreType *)gnc_search_input_new_type_name (type);
} else if (!strcmp (type, "source")) {
return (GNCSearchCoreType *)gnc_search_source_new ();
#endif
} else {
g_warning("Unknown search type '%s'", type);
return 0;
}
}
/* default implementations */
static gboolean
validate (GNCSearchCoreType *fe)
{
return TRUE;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2002 Derek Atkins
*
* Authors: Derek Atkins <warlord@MIT.EDU>
*
* 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_CORE_TYPE_H
#define _GNCSEARCH_CORE_TYPE_H
#include <gnome.h>
#include "QueryNew.h"
#include "search-param.h"
#define GNCSEARCH_CORE_TYPE(obj) GTK_CHECK_CAST (obj, gnc_search_core_type_get_type (), GNCSearchCoreType)
#define GNCSEARCH_CORE_TYPE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gnc_search_core_type_get_type (), GNCSearchCoreTypeClass)
#define IS_GNCSEARCH_CORE_TYPE(obj) GTK_CHECK_TYPE (obj, gnc_search_core_type_get_type ())
typedef struct _GNCSearchCoreType GNCSearchCoreType;
typedef struct _GNCSearchCoreTypeClass GNCSearchCoreTypeClass;
struct _GNCSearchCoreType {
GtkObject parent;
struct _GNCSearchCoreTypePrivate *priv;
GNCSearchParam * param;
};
struct _GNCSearchCoreTypeClass {
GtkObjectClass parent_class;
/* virtual methods */
gboolean (*validate) (GNCSearchCoreType *fe);
GNCSearchCoreType * (*clone) (GNCSearchCoreType *fe);
GtkWidget * (*get_widget) (GNCSearchCoreType *);
QueryPredData_t (*get_predicate) (GNCSearchCoreType *);
/* signals */
};
/* These are internal functions */
guint gnc_search_core_type_get_type (void);
GNCSearchCoreType * gnc_search_core_type_new (void);
/* Create a new search core_type */
GNCSearchCoreType * gnc_search_core_type_new_type_name (const char *type);
/* methods */
gboolean gnc_search_core_type_validate (GNCSearchCoreType *fe);
GNCSearchCoreType * gnc_search_core_type_clone (GNCSearchCoreType *fe);
GtkWidget * gnc_search_core_type_get_widget (GNCSearchCoreType *fe);
QueryPredData_t gnc_search_core_type_get_predicate (GNCSearchCoreType *fe);
#endif /* ! _GNCSEARCH_CORE_TYPE_H */

View File

@@ -0,0 +1,270 @@
/*
* Copyright (C) 2002 Derek Atkins
*
* Authors: Derek Atkins <warlord@MIT.EDU>
*
* 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 <config.h>
#endif
#include <gnome.h>
#include "date.h"
#include "gnc-date-edit.h"
#include "QueryCore.h"
#include "search-date.h"
#define d(x)
static GNCSearchCoreType *clone(GNCSearchCoreType *fe);
static gboolean validate (GNCSearchCoreType *fe);
static GtkWidget *get_widget(GNCSearchCoreType *fe);
static QueryPredData_t get_predicate (GNCSearchCoreType *fe);
static void gnc_search_date_class_init (GNCSearchDateClass *class);
static void gnc_search_date_init (GNCSearchDate *gspaper);
static void gnc_search_date_finalise (GtkObject *obj);
#define _PRIVATE(x) (((GNCSearchDate *)(x))->priv)
struct _GNCSearchDatePrivate {
};
static GNCSearchCoreTypeClass *parent_class;
enum {
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
guint
gnc_search_date_get_type (void)
{
static guint type = 0;
if (!type) {
GtkTypeInfo type_info = {
"GNCSearchDate",
sizeof(GNCSearchDate),
sizeof(GNCSearchDateClass),
(GtkClassInitFunc)gnc_search_date_class_init,
(GtkObjectInitFunc)gnc_search_date_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL
};
type = gtk_type_unique(gnc_search_core_type_get_type (), &type_info);
}
return type;
}
static void
gnc_search_date_class_init (GNCSearchDateClass *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_date_finalise;
/* override methods */
gnc_search_core_type->validate = validate;
gnc_search_core_type->get_widget = get_widget;
gnc_search_core_type->get_predicate = get_predicate;
gnc_search_core_type->clone = clone;
/* signals */
gtk_object_class_add_signals(object_class, signals, LAST_SIGNAL);
}
static void
gnc_search_date_init (GNCSearchDate *o)
{
o->priv = g_malloc0 (sizeof (*o->priv));
o->ts.tv_sec = time(NULL);
o->how = COMPARE_LT;
}
static void
gnc_search_date_finalise (GtkObject *obj)
{
GNCSearchDate *o = (GNCSearchDate *)obj;
g_assert (IS_GNCSEARCH_DATE (o));
g_free(o->priv);
((GtkObjectClass *)(parent_class))->finalize(obj);
}
/**
* gnc_search_date_new:
*
* Create a new GNCSearchDate object.
*
* Return value: A new #GNCSearchDate object.
**/
GNCSearchDate *
gnc_search_date_new (void)
{
GNCSearchDate *o = (GNCSearchDate *)gtk_type_new(gnc_search_date_get_type ());
return o;
}
void
gnc_search_date_set_date (GNCSearchDate *fi, Timespec ts)
{
g_return_if_fail (fi);
g_return_if_fail (IS_GNCSEARCH_DATE (fi));
fi->ts = ts;
}
void
gnc_search_date_set_how (GNCSearchDate *fi, query_compare_t how)
{
g_return_if_fail (fi);
g_return_if_fail (IS_GNCSEARCH_DATE (fi));
fi->how = how;
}
static gboolean
validate (GNCSearchCoreType *fe)
{
GNCSearchDate *fi = (GNCSearchDate *)fe;
gboolean valid = TRUE;
g_return_val_if_fail (fi, FALSE);
g_return_val_if_fail (IS_GNCSEARCH_DATE (fi), FALSE);
/* XXX */
return valid;
}
static void
option_changed (GtkWidget *widget, GNCSearchDate *fe)
{
fe->how = (query_compare_t)
gtk_object_get_data (GTK_OBJECT (widget), "option");
}
static void
date_changed (GNCDateEdit *date_edit, GNCSearchDate *fe)
{
time_t tt;
fe->ts = gnc_date_edit_get_date_ts (date_edit);
}
static GtkWidget *
add_menu_item (GtkWidget *menu, gpointer user_data, char *label,
query_compare_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)
{
GNCSearchDate *fi = (GNCSearchDate *)fe;
GtkWidget *menu, *item, *first, *opmenu;
int current = 0, index = 0;
menu = gtk_menu_new ();
ADD_MENU_ITEM (_("is before"), COMPARE_LT);
first = item; /* Force one */
ADD_MENU_ITEM (_("is before or on"), COMPARE_LTE);
ADD_MENU_ITEM (_("is on"), COMPARE_EQUAL);
ADD_MENU_ITEM (_("is not on"), COMPARE_NEQ);
ADD_MENU_ITEM (_("is after"), COMPARE_GT);
ADD_MENU_ITEM (_("is on or after"), COMPARE_GTE);
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 *
get_widget (GNCSearchCoreType *fe)
{
GtkWidget *entry, *menu, *box;
GNCSearchDate *fi = (GNCSearchDate *)fe;
g_return_val_if_fail (fi, NULL);
g_return_val_if_fail (IS_GNCSEARCH_DATE (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 date entry window */
entry = gnc_date_edit_new_ts (fi->ts, FALSE, FALSE);
gtk_signal_connect (GTK_OBJECT (entry), "date_changed", date_changed, fe);
gtk_box_pack_start (GTK_BOX (box), entry, FALSE, FALSE, 3);
/* And return the box */
return box;
}
static QueryPredData_t get_predicate (GNCSearchCoreType *fe)
{
GNCSearchDate *fi = (GNCSearchDate *)fe;
g_return_val_if_fail (fi, NULL);
g_return_val_if_fail (IS_GNCSEARCH_DATE (fi), NULL);
return gncQueryDatePredicate (fi->how, DATE_MATCH_NORMAL, fi->ts);
}
static GNCSearchCoreType *clone(GNCSearchCoreType *fe)
{
GNCSearchDate *se, *fse = (GNCSearchDate *)fe;
g_return_val_if_fail (fse, NULL);
g_return_val_if_fail (IS_GNCSEARCH_DATE (fse), NULL);
se = gnc_search_date_new ();
gnc_search_date_set_date (se, fse->ts);
gnc_search_date_set_how (se, fse->how);
return (GNCSearchCoreType *)se;
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2002 Derek Atkins
*
* Authors: Derek Atkins <warlord@MIT.EDU>
*
* 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_DATE_H
#define _GNCSEARCH_DATE_H
#include "search-core-type.h"
#include "QueryNew.h"
#include "date.h"
#define GNCSEARCH_DATE(obj) GTK_CHECK_CAST (obj, gnc_search_date_get_type (), GNCSearchDate)
#define GNCSEARCH_DATE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gnc_search_date_get_type (), GNCSearchDateClass)
#define IS_GNCSEARCH_DATE(obj) GTK_CHECK_TYPE (obj, gnc_search_date_get_type ())
typedef struct _GNCSearchDate GNCSearchDate;
typedef struct _GNCSearchDateClass GNCSearchDateClass;
struct _GNCSearchDate {
GNCSearchCoreType parent;
struct _GNCSearchDatePrivate *priv;
query_compare_t how;
Timespec ts;
};
struct _GNCSearchDateClass {
GNCSearchCoreTypeClass parent_class;
/* virtual methods */
/* signals */
};
guint gnc_search_date_get_type (void);
GNCSearchDate *gnc_search_date_new (void);
/* methods */
void gnc_search_date_set_date (GNCSearchDate *fi, Timespec ts);
void gnc_search_date_set_how (GNCSearchDate *fi, query_compare_t how);
#endif /* ! _GNCSEARCH_DATE_H */

View File

@@ -0,0 +1,186 @@
/*
* search-param.c -- a container for a Search Parameter
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <gnome.h>
#include "gnc-engine-util.h"
#include "GNCId.h"
#include "QueryObject.h"
#include "search-param.h"
static void gnc_search_param_class_init (GNCSearchParamClass *class);
static void gnc_search_param_init (GNCSearchParam *gspaper);
static void gnc_search_param_finalise (GtkObject *obj);
#define _PRIVATE(x) (((GNCSearchParam *)(x))->priv)
struct _GNCSearchParamPrivate {
GSList * param_path;
GNCIdTypeConst type;
};
static GtkObjectClass *parent_class;
enum {
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
guint
gnc_search_param_get_type (void)
{
static guint type = 0;
if (!type) {
GtkTypeInfo type_info = {
"GNCSearchParam",
sizeof(GNCSearchParam),
sizeof(GNCSearchParamClass),
(GtkClassInitFunc)gnc_search_param_class_init,
(GtkObjectInitFunc)gnc_search_param_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL
};
type = gtk_type_unique(gtk_object_get_type (), &type_info);
}
return type;
}
static void
gnc_search_param_class_init (GNCSearchParamClass *class)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass *)class;
parent_class = gtk_type_class (gtk_object_get_type ());
object_class->finalize = gnc_search_param_finalise;
/* override methods */
/* signals */
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
}
static void
gnc_search_param_init (GNCSearchParam *o)
{
o->priv = g_malloc0 (sizeof (*o->priv));
}
static void
gnc_search_param_finalise (GtkObject *obj)
{
GNCSearchParam *o = (GNCSearchParam *)obj;
g_slist_free (o->priv->param_path);
o->priv->param_path = NULL;
g_free(o->priv);
((GtkObjectClass *)(parent_class))->finalize(obj);
}
/**
* gnc_search_param_new:
*
* Create a new GNCSearchParam object.
*
* Return value: A new #GNCSearchParam object.
**/
GNCSearchParam *
gnc_search_param_new (void)
{
GNCSearchParam *o = (GNCSearchParam *)gtk_type_new(gnc_search_param_get_type ());
return o;
}
GNCSearchParam *
gnc_search_param_clone (GNCSearchParam *param)
{
GNCSearchParam *n;
g_assert (IS_GNCSEARCH_PARAM (param));
n = gnc_search_param_new ();
n->title = param->title;
n->priv->param_path = g_slist_copy (param->priv->param_path);
n->priv->type = param->priv->type;
return n;
}
void
gnc_search_param_set_param_path (GNCSearchParam *param,
GNCIdTypeConst search_type,
GSList *param_path)
{
GNCIdTypeConst type = NULL;
g_assert (IS_GNCSEARCH_PARAM (param));
if (param->priv->param_path)
g_slist_free (param->priv->param_path);
param->priv->param_path = g_slist_copy (param_path);
/* Compute the parameter type */
for (; param_path; param_path = param_path->next) {
GNCIdType param_name = param_path->data;
const QueryObjectDef *objDef =
gncQueryObjectGetParameter (search_type, param_name);
/* If it doesn't exist, then we've reached the end */
if (!objDef)
break;
/* And reset for the next parameter */
type = search_type = objDef->param_type;
}
param->priv->type = type;
}
GSList *
gnc_search_param_get_param_path (GNCSearchParam *param)
{
g_assert (IS_GNCSEARCH_PARAM (param));
return param->priv->param_path;
}
GNCIdTypeConst
gnc_search_param_get_param_type (GNCSearchParam *param)
{
g_assert (IS_GNCSEARCH_PARAM (param));
return param->priv->type;
}
void
gnc_search_param_set_title (GNCSearchParam *param, const char *title)
{
g_assert (IS_GNCSEARCH_PARAM (param));
param->title = title;
}
gboolean
gnc_search_param_type_match (GNCSearchParam *a, GNCSearchParam *b)
{
g_assert (IS_GNCSEARCH_PARAM (a));
g_assert (IS_GNCSEARCH_PARAM (b));
if (a->priv->type == b->priv->type ||
!safe_strcmp (a->priv->type, b->priv->type))
return TRUE;
return FALSE;
}

View File

@@ -0,0 +1,50 @@
/*
* search-param.h -- a container for a Search Parameter
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU
*/
#ifndef _GNCSEARCH_PARAM_H
#define _GNCSEARCH_PARAM_H
#include "GNCId.h"
#define GNCSEARCH_PARAM(obj) GTK_CHECK_CAST (obj, gnc_search_param_get_type (), GNCSearchParam)
#define GNCSEARCH_PARAM_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gnc_search_param_get_type (), GNCSearchParamClass)
#define IS_GNCSEARCH_PARAM(obj) GTK_CHECK_TYPE (obj, gnc_search_param_get_type ())
typedef struct _GNCSearchParam GNCSearchParam;
typedef struct _GNCSearchParamClass GNCSearchParamClass;
struct _GNCSearchParam {
GtkObject parent;
struct _GNCSearchParamPrivate *priv;
const char * title;
};
struct _GNCSearchParamClass {
GtkObjectClass parent_class;
/* virtual methods */
/* signals */
};
/* These are internal functions */
guint gnc_search_param_get_type (void);
/* Create a new search param */
GNCSearchParam * gnc_search_param_new (void);
GNCSearchParam * gnc_search_param_clone (GNCSearchParam *param);
void gnc_search_param_set_param_path (GNCSearchParam *param,
GNCIdTypeConst search_type,
GSList *param_path);
GSList * gnc_search_param_get_param_path (GNCSearchParam *param);
GNCIdTypeConst gnc_search_param_get_param_type (GNCSearchParam *param);
void gnc_search_param_set_title (GNCSearchParam *param,
const char *title);
gboolean gnc_search_param_type_match (GNCSearchParam *a,
GNCSearchParam *b);
#endif /* _GNCSEARCH_PARAM_H */

View File

@@ -0,0 +1,363 @@
/*
* Copyright (C) 2002 Derek Atkins
*
* Authors: Derek Atkins <warlord@MIT.EDU>
*
* 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 <config.h>
#endif
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#include <gnome.h>
#include "search-string.h"
#include "QueryCore.h"
#define d(x)
static GNCSearchCoreType *clone(GNCSearchCoreType *fe);
static gboolean validate (GNCSearchCoreType *fe);
static GtkWidget *get_widget(GNCSearchCoreType *fe);
static QueryPredData_t get_predicate (GNCSearchCoreType *fe);
static void gnc_search_string_class_init (GNCSearchStringClass *class);
static void gnc_search_string_init (GNCSearchString *gspaper);
static void gnc_search_string_finalise (GtkObject *obj);
#define _PRIVATE(x) (((GNCSearchString *)(x))->priv)
struct _GNCSearchStringPrivate {
};
static GNCSearchCoreTypeClass *parent_class;
enum {
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
guint
gnc_search_string_get_type (void)
{
static guint type = 0;
if (!type) {
GtkTypeInfo type_info = {
"GNCSearchString",
sizeof(GNCSearchString),
sizeof(GNCSearchStringClass),
(GtkClassInitFunc)gnc_search_string_class_init,
(GtkObjectInitFunc)gnc_search_string_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL
};
type = gtk_type_unique(gnc_search_core_type_get_type (), &type_info);
}
return type;
}
static void
gnc_search_string_class_init (GNCSearchStringClass *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_string_finalise;
/* override methods */
gnc_search_core_type->validate = validate;
gnc_search_core_type->get_widget = get_widget;
gnc_search_core_type->get_predicate = get_predicate;
gnc_search_core_type->clone = clone;
/* signals */
gtk_object_class_add_signals(object_class, signals, LAST_SIGNAL);
}
static void
gnc_search_string_init (GNCSearchString *o)
{
o->priv = g_malloc0 (sizeof (*o->priv));
o->value = NULL;
o->how = SEARCH_STRING_CONTAINS;
o->ign_case = FALSE;
}
static void
gnc_search_string_finalise (GtkObject *obj)
{
GNCSearchString *o = (GNCSearchString *)obj;
g_assert (IS_GNCSEARCH_STRING (o));
g_free (o->value);
g_free(o->priv);
((GtkObjectClass *)(parent_class))->finalize(obj);
}
/**
* gnc_search_string_new:
*
* Create a new GNCSearchString object.
*
* Return value: A new #GNCSearchString object.
**/
GNCSearchString *
gnc_search_string_new (void)
{
GNCSearchString *o = (GNCSearchString *)gtk_type_new(gnc_search_string_get_type ());
return o;
}
void
gnc_search_string_set_value (GNCSearchString *fi, const char *value)
{
g_return_if_fail (fi);
g_return_if_fail (IS_GNCSEARCH_STRING (fi));
if (fi->value)
g_free (fi->value);
fi->value = g_strdup (value);
}
void
gnc_search_string_set_how (GNCSearchString *fi, GNCSearchString_Type how)
{
g_return_if_fail (fi);
g_return_if_fail (IS_GNCSEARCH_STRING (fi));
fi->how = how;
}
void
gnc_search_string_set_case (GNCSearchString *fi, gboolean ignore_case)
{
g_return_if_fail (fi);
g_return_if_fail (IS_GNCSEARCH_STRING (fi));
fi->ign_case = ignore_case;
}
static gboolean
validate (GNCSearchCoreType *fe)
{
GNCSearchString *fi = (GNCSearchString *)fe;
gboolean valid = TRUE;
g_return_val_if_fail (fi, FALSE);
g_return_val_if_fail (IS_GNCSEARCH_STRING (fi), FALSE);
if (fi->how == SEARCH_STRING_MATCHES_REGEX ||
fi->how == SEARCH_STRING_NOT_MATCHES_REGEX) {
regex_t regexpat; /* regex patern */
gint regerr;
int flags = REG_EXTENDED;
if (fi->ign_case)
flags |= REG_ICASE;
regerr = regcomp (&regexpat, fi->value, flags);
if (regerr) {
GtkWidget *dialog;
gchar *regmsg, *errmsg;
size_t reglen;
/* regerror gets called twice to get the full error string
length to do proper posix error reporting */
reglen = regerror (regerr, &regexpat, 0, 0);
regmsg = g_malloc0 (reglen + 1);
regerror (regerr, &regexpat, regmsg, reglen);
errmsg = g_strdup_printf (_("Error in regular expression '%s':\n%s"),
fi->value, regmsg);
g_free (regmsg);
dialog = gnome_ok_dialog (errmsg);
gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
g_free (errmsg);
valid = FALSE;
}
regfree (&regexpat);
}
return valid;
}
static void
toggle_changed (GtkToggleButton *button, GNCSearchString *fe)
{
fe->ign_case = gtk_toggle_button_get_active (button);
}
static void
option_changed (GtkWidget *widget, GNCSearchString *fe)
{
fe->how = (GNCSearchString_Type)
gtk_object_get_data (GTK_OBJECT (widget), "option");
}
static void
entry_changed (GtkEntry *entry, GNCSearchString *fe)
{
char *new;
new = gtk_entry_get_text(entry);
if (fe->value)
g_free (fe->value);
fe->value = new;
}
static GtkWidget *
add_menu_item (GtkWidget *menu, gpointer user_data, char *label,
GNCSearchString_Type 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;
}
static GtkWidget *
make_menu (GNCSearchCoreType *fe)
{
GNCSearchString *fi = (GNCSearchString *)fe;
GtkWidget *menu, *item, *first, *opmenu;
int current = 0;
menu = gtk_menu_new ();
item = add_menu_item (menu, fe, _("contains"), SEARCH_STRING_CONTAINS);
first = item;
item = add_menu_item (menu, fe, _("does not contain"),
SEARCH_STRING_NOT_CONTAINS);
if (fi->how == SEARCH_STRING_NOT_CONTAINS) { current = 1; first = item; }
item = add_menu_item (menu, fe, _("matches regex"),
SEARCH_STRING_MATCHES_REGEX);
if (fi->how == SEARCH_STRING_MATCHES_REGEX) { current = 2; first = item; }
item = add_menu_item (menu, fe, _("does not match regex"),
SEARCH_STRING_NOT_MATCHES_REGEX);
if (fi->how == SEARCH_STRING_NOT_MATCHES_REGEX)
{ current = 3; first = item; }
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 *
get_widget (GNCSearchCoreType *fe)
{
GtkWidget *entry, *toggle, *menu, *box;
GNCSearchString *fi = (GNCSearchString *)fe;
g_return_val_if_fail (fi, NULL);
g_return_val_if_fail (IS_GNCSEARCH_STRING (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 entry window */
entry = gtk_entry_new ();
if (fi->value)
gtk_entry_set_text (GTK_ENTRY (entry), fi->value);
gtk_signal_connect (GTK_OBJECT (entry), "changed", entry_changed, fe);
gtk_box_pack_start (GTK_BOX (box), entry, FALSE, FALSE, 3);
/* Build and connect the toggle button */
toggle = gtk_toggle_button_new_with_label (_("Case Insensitive?"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), fi->ign_case);
gtk_signal_connect (GTK_OBJECT(toggle), "toggled", toggle_changed, fe);
gtk_box_pack_start (GTK_BOX (box), toggle, FALSE, FALSE, 3);
/* And return the box */
return box;
}
static QueryPredData_t get_predicate (GNCSearchCoreType *fe)
{
GNCSearchString *ss = (GNCSearchString *)fe;
query_compare_t how;
string_match_t options = STRING_MATCH_NORMAL;
gboolean is_regex = FALSE;
g_return_val_if_fail (ss, NULL);
g_return_val_if_fail (IS_GNCSEARCH_STRING (ss), NULL);
switch (ss->how) {
case SEARCH_STRING_MATCHES_REGEX:
is_regex = TRUE;
/* FALLTHROUGH */
case SEARCH_STRING_CONTAINS:
how = COMPARE_EQUAL;
break;
case SEARCH_STRING_NOT_MATCHES_REGEX:
is_regex = TRUE;
/* FALLTHROUGH */
case SEARCH_STRING_NOT_CONTAINS:
how = COMPARE_NEQ;
break;
default:
g_warning ("invalid string choice: %d", ss->how);
return NULL;
}
if (ss->ign_case)
options = STRING_MATCH_CASEINSENSITIVE;
return gncQueryStringPredicate (how, ss->value, options, is_regex);
}
static GNCSearchCoreType *clone(GNCSearchCoreType *fe)
{
GNCSearchString *se, *fse = (GNCSearchString *)fe;
g_return_val_if_fail (fse, NULL);
g_return_val_if_fail (IS_GNCSEARCH_STRING (fse), NULL);
se = gnc_search_string_new ();
gnc_search_string_set_value (se, fse->value);
gnc_search_string_set_how (se, fse->how);
gnc_search_string_set_case (se, fse->ign_case);
return (GNCSearchCoreType *)se;
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2002 Derek Atkins
*
* Authors: Derek Atkins <warlord@MIT.EDU>
*
* 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_STRING_H
#define _GNCSEARCH_STRING_H
#include "search-core-type.h"
#define GNCSEARCH_STRING(obj) GTK_CHECK_CAST (obj, gnc_search_string_get_type (), GNCSearchString)
#define GNCSEARCH_STRING_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gnc_search_string_get_type (), GNCSearchStringClass)
#define IS_GNCSEARCH_STRING(obj) GTK_CHECK_TYPE (obj, gnc_search_string_get_type ())
typedef struct _GNCSearchString GNCSearchString;
typedef struct _GNCSearchStringClass GNCSearchStringClass;
typedef enum _search_string_how {
SEARCH_STRING_CONTAINS,
SEARCH_STRING_NOT_CONTAINS,
SEARCH_STRING_MATCHES_REGEX,
SEARCH_STRING_NOT_MATCHES_REGEX
} GNCSearchString_Type;
struct _GNCSearchString {
GNCSearchCoreType parent;
struct _GNCSearchStringPrivate *priv;
GNCSearchString_Type how;
gboolean ign_case;
char * value;
};
struct _GNCSearchStringClass {
GNCSearchCoreTypeClass parent_class;
/* virtual methods */
/* signals */
};
guint gnc_search_string_get_type (void);
GNCSearchString *gnc_search_string_new (void);
/* methods */
void gnc_search_string_set_value(GNCSearchString *fi, const char *value);
void gnc_search_string_set_how (GNCSearchString *fi, GNCSearchString_Type how);
void gnc_search_string_set_case (GNCSearchString *fi, gboolean ignore_case);
#endif /* ! _GNCSEARCH_STRING_H */

View File

@@ -0,0 +1,392 @@
<?xml version="1.0"?>
<GTK-Interface>
<project>
<name>Glade</name>
<program_name>glade</program_name>
<directory></directory>
<source_directory></source_directory>
<pixmaps_directory></pixmaps_directory>
<language>C</language>
<gnome_support>True</gnome_support>
<gettext_support>True</gettext_support>
<output_main_file>False</output_main_file>
<output_support_files>False</output_support_files>
<output_build_files>False</output_build_files>
<backup_source_files>False</backup_source_files>
</project>
<widget>
<class>GnomeDialog</class>
<name>Search Dialog</name>
<title>Search for...</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
<modal>False</modal>
<allow_shrink>True</allow_shrink>
<allow_grow>True</allow_grow>
<auto_shrink>False</auto_shrink>
<auto_close>False</auto_close>
<hide_on_close>False</hide_on_close>
<widget>
<class>GtkVBox</class>
<child_name>GnomeDialog:vbox</child_name>
<name>dialog_vbox</name>
<homogeneous>False</homogeneous>
<spacing>8</spacing>
<child>
<padding>4</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkHButtonBox</class>
<child_name>GnomeDialog:action_area</child_name>
<name>dialog-action_area7</name>
<layout_style>GTK_BUTTONBOX_SPREAD</layout_style>
<spacing>8</spacing>
<child_min_width>85</child_min_width>
<child_min_height>27</child_min_height>
<child_ipad_x>7</child_ipad_x>
<child_ipad_y>0</child_ipad_y>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
<pack>GTK_PACK_END</pack>
</child>
<widget>
<class>GtkButton</class>
<name>button26</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>gnc_ui_search_find_cb</handler>
<data>Search Dialog</data>
<last_modification_time>Thu, 07 Feb 2002 02:21:36 GMT</last_modification_time>
</signal>
<label>Find</label>
<stock_pixmap>GNOME_STOCK_PIXMAP_SEARCH</stock_pixmap>
</widget>
<widget>
<class>GtkButton</class>
<name>button27</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>gnc_ui_search_cancel_cb</handler>
<data>Search Dialog</data>
<last_modification_time>Thu, 07 Feb 2002 02:22:27 GMT</last_modification_time>
</signal>
<stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
</widget>
<widget>
<class>GtkButton</class>
<name>button28</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>gnc_ui_search_help_cb</handler>
<data>Search Dialog</data>
<last_modification_time>Thu, 07 Feb 2002 02:23:16 GMT</last_modification_time>
</signal>
<stock_button>GNOME_STOCK_BUTTON_HELP</stock_button>
</widget>
</widget>
<widget>
<class>GtkHBox</class>
<name>hbox71</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkHBox</class>
<name>hbox72</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>type_label</name>
<label>()</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkLabel</class>
<name>label844</name>
<label> Search </label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
<widget>
<class>GtkFrame</class>
<name>search_frame</name>
<border_width>3</border_width>
<label>Search Criteria</label>
<label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkVBox</class>
<name>vbox88</name>
<border_width>3</border_width>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkHBox</class>
<name>hbox73</name>
<border_width>3</border_width>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkHBox</class>
<name>add_button_box</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>Placeholder</class>
</widget>
</widget>
<widget>
<class>GtkHBox</class>
<name>type_menu_box</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
<pack>GTK_PACK_END</pack>
</child>
<widget>
<class>Placeholder</class>
</widget>
</widget>
<widget>
<class>GtkLabel</class>
<name>label846</name>
<label>Search for items where</label>
<justify>GTK_JUSTIFY_RIGHT</justify>
<wrap>False</wrap>
<xalign>1</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
<pack>GTK_PACK_END</pack>
</child>
</widget>
</widget>
<widget>
<class>GtkTable</class>
<name>criteria_table</name>
<border_width>3</border_width>
<rows>1</rows>
<columns>2</columns>
<homogeneous>False</homogeneous>
<row_spacing>0</row_spacing>
<column_spacing>0</column_spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
<widget>
<class>GtkHBox</class>
<name>hbox20</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkHBox</class>
<name>hbox23</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkFrame</class>
<name>frame12</name>
<label>Type of search</label>
<label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkVBox</class>
<name>vbox24</name>
<border_width>3</border_width>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkRadioButton</class>
<name>new_search_radiobutton</name>
<can_focus>True</can_focus>
<signal>
<name>toggled</name>
<handler>gnc_ui_search_type_cb</handler>
<data>Search Dialog</data>
<last_modification_time>Thu, 07 Feb 2002 01:25:13 GMT</last_modification_time>
</signal>
<label>New search</label>
<active>True</active>
<draw_indicator>True</draw_indicator>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkRadioButton</class>
<name>narrow_search_radiobutton</name>
<can_focus>True</can_focus>
<signal>
<name>toggled</name>
<handler>gnc_ui_find_transactions_dialog_search_type_cb</handler>
<data>Find_Transactions</data>
<last_modification_time>Wed, 05 Apr 2000 14:20:05 GMT</last_modification_time>
</signal>
<label>Refine current search</label>
<active>False</active>
<draw_indicator>True</draw_indicator>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkRadioButton</class>
<name>add_search_radiobutton</name>
<can_focus>True</can_focus>
<signal>
<name>toggled</name>
<handler>gnc_ui_find_transactions_dialog_search_type_cb</handler>
<data>Find_Transactions</data>
<last_modification_time>Wed, 05 Apr 2000 14:20:17 GMT</last_modification_time>
</signal>
<label>Add results to current search</label>
<active>False</active>
<draw_indicator>True</draw_indicator>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkRadioButton</class>
<name>delete_search_radiobutton</name>
<can_focus>True</can_focus>
<signal>
<name>toggled</name>
<handler>gnc_ui_find_transactions_dialog_search_type_cb</handler>
<data>Find_Transactions</data>
<last_modification_time>Wed, 05 Apr 2000 14:20:26 GMT</last_modification_time>
</signal>
<label>Delete results from current search</label>
<active>False</active>
<draw_indicator>True</draw_indicator>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
</widget>
</widget>
</widget>
</widget>
</GTK-Interface>