gnucash maint: Bug 745354: Enhance the Find Transactions dialog

Mike Alexander mta at code.gnucash.org
Tue Mar 3 23:56:17 EST 2015


Updated	 via  https://github.com/Gnucash/gnucash/commit/87286039 (commit)
	from  https://github.com/Gnucash/gnucash/commit/6cf3e379 (commit)



commit 8728603926d077db2e5128c39020386b297d7f48
Author: Mike Alexander <mta at umich.edu>
Date:   Sun Mar 1 01:38:14 2015 -0500

    Bug 745354: Enhance the Find Transactions dialog
    
    Make it possible to define search criteria that consist of multiple terms
    anded or ored together.  Use this to define a new criterion to look for specified
    text in any of the Description, Notes, or Memo fields.

diff --git a/src/gnome-search/dialog-search.c b/src/gnome-search/dialog-search.c
index f308c97..87e911b 100644
--- a/src/gnome-search/dialog-search.c
+++ b/src/gnome-search/dialog-search.c
@@ -120,7 +120,7 @@ struct _GNCSearchWindow
     /* The list of criteria */
     GNCSearchParam           *last_param;
     GList                    *params_list;  /* List of GNCSearchParams */
-    GList                    *display_list; /* List of GNCSearchParams for Display */
+    GList                    *display_list; /* List of GNCSearchParamSimples for Display */
     gint                      num_cols;     /* Number of Display Columns */
     GList                    *crit_list;    /* List of crit_data */
 
@@ -426,6 +426,38 @@ search_active_only_cb (GtkToggleButton *button, GNCSearchWindow *sw)
                        gtk_toggle_button_get_active (button));
 }
 
+static QofQuery *
+create_query_fragment (QofIdTypeConst search_for, GNCSearchParam *param, QofQueryPredData *pdata)
+{
+    GNCSearchParamKind kind = gnc_search_param_get_kind (param);
+    QofQuery *q = qof_query_create_for (search_for);
+    
+    if (kind == SEARCH_PARAM_ELEM)
+    {
+        /* The "op" parameter below will be ignored since q has no terms. */
+        qof_query_add_term (q, gnc_search_param_get_param_path (GNC_SEARCH_PARAM_SIMPLE (param)),
+                            pdata, QOF_QUERY_OR);
+    } 
+    else
+    {
+        GList *plist = gnc_search_param_get_search (GNC_SEARCH_PARAM_COMPOUND (param));
+        
+        for ( ; plist; plist  = plist->next)
+        {
+            QofQuery *new_q;
+            GNCSearchParam *param2 = plist->data;
+            QofQuery *q2 = create_query_fragment (search_for, param2, 
+                                                  qof_query_core_predicate_copy (pdata));
+            new_q = qof_query_merge (q, q2, kind == SEARCH_PARAM_ANY ? 
+                                                    QOF_QUERY_OR : QOF_QUERY_AND);
+            qof_query_destroy (q);
+            qof_query_destroy (q2);
+            q = new_q;
+        }
+        qof_query_core_predicate_free (pdata);
+    }
+    return q;
+}
 
 static void
 search_update_query (GNCSearchWindow *sw)
@@ -434,7 +466,6 @@ search_update_query (GNCSearchWindow *sw)
     QofQuery *q, *q2, *new_q;
     GList *node;
     QofQueryOp op;
-    QofQueryPredData* pdata;
 
     if (sw->grouping == GNC_SEARCH_MATCH_ANY)
         op = QOF_QUERY_OR;
@@ -463,11 +494,14 @@ search_update_query (GNCSearchWindow *sw)
     for (node = sw->crit_list; node; node = node->next)
     {
         struct _crit_data *data = node->data;
+        QofQueryPredData* pdata;
 
         pdata = gnc_search_core_type_get_predicate (data->element);
         if (pdata)
-            qof_query_add_term (q, gnc_search_param_get_param_path (data->param),
-                                pdata, op);
+        {
+            q2 = create_query_fragment(sw->search_for, GNC_SEARCH_PARAM (data->param), pdata);
+            q = qof_query_merge (q, q2, op);
+        }
     }
 
     /* Now combine this query with the existing query, depending on
diff --git a/src/gnome-search/dialog-search.h b/src/gnome-search/dialog-search.h
index d9358a9..f61f4ee 100644
--- a/src/gnome-search/dialog-search.h
+++ b/src/gnome-search/dialog-search.h
@@ -85,8 +85,9 @@ typedef struct
  * buttons.  The caller MUST NOT supply both.
  *
  * Both the param_list and display_list are the property of the dialog
- * but will NOT be destroyed..  They should be a GList of
- * GNCSearchParam objects.  The display_list defines which paramters
+ * but will NOT be destroyed..  The param_list should be a GList of
+ * GNCSearchParam objects.  The display_list should be a GList of
+ * GNCSearchParamSimple objects which defines which paramters
  * of the found transactions are printed, and how.
  *
  * The start_query is the property of the caller and will only be copied.
diff --git a/src/gnome-search/search-core-type.h b/src/gnome-search/search-core-type.h
index 77bd267..87c0508 100644
--- a/src/gnome-search/search-core-type.h
+++ b/src/gnome-search/search-core-type.h
@@ -35,6 +35,7 @@ typedef struct
 {
     GtkObject parent;
 
+    /* This appears to be unused */
     GNCSearchParam *	param;
 } GNCSearchCoreType;
 
diff --git a/src/gnome-utils/gnc-query-view.c b/src/gnome-utils/gnc-query-view.c
index 8420ae8..05d1267 100644
--- a/src/gnome-utils/gnc-query-view.c
+++ b/src/gnome-utils/gnc-query-view.c
@@ -160,8 +160,11 @@ gnc_query_view_new (GList *param_list, Query *query)
     /* Get the types for the list store */
     for (i = 0, node = param_list; node; node = node->next, i++)
     {
-        GNCSearchParam *param = node->data;
-        const char *type = gnc_search_param_get_param_type (param);
+        GNCSearchParamSimple *param = node->data;
+        const char *type;
+
+        g_assert (GNC_IS_SEARCH_PARAM_SIMPLE (param));
+        type = gnc_search_param_get_param_type ((GNCSearchParam *) param);
 
         if (g_strcmp0 (type, QOF_TYPE_BOOLEAN) == 0)
             types[i+1] = G_TYPE_BOOLEAN;
@@ -323,24 +326,26 @@ gnc_query_view_init_view (GNCQueryView *qview)
     {
         const char *type;
         gfloat algn = 0;
-        GNCSearchParam *param = node->data;
+        GNCSearchParamSimple *param = node->data;
+
+        g_assert (GNC_IS_SEARCH_PARAM_SIMPLE (param));
 
         col = gtk_tree_view_column_new ();
 
         /* Set the column title */
-        gtk_tree_view_column_set_title (col, (gchar *)param->title);
+        gtk_tree_view_column_set_title (col, (gchar *) ((GNCSearchParam *) param)->title);
 
         /* pack tree view column into tree view */
         gtk_tree_view_append_column (view, col);
 
         /* Get justification */
-        if (param->justify == GTK_JUSTIFY_CENTER)
+        if (((GNCSearchParam *) param)->justify == GTK_JUSTIFY_CENTER)
             algn = 0.5;
-        else if (param->justify == GTK_JUSTIFY_RIGHT)
+        else if (((GNCSearchParam *) param)->justify == GTK_JUSTIFY_RIGHT)
             algn = 1.0;
 
         /* Set column resizeable */
-        if (param->non_resizeable)
+        if (((GNCSearchParam *) param)->non_resizeable)
         {
             gtk_tree_view_column_set_resizable (col, FALSE);
             gtk_tree_view_column_set_expand (col, FALSE);
@@ -349,7 +354,7 @@ gnc_query_view_init_view (GNCQueryView *qview)
             gtk_tree_view_column_set_resizable (col, TRUE);
 
         /* Set column clickable */
-        if (param->passive)
+        if (((GNCSearchParam *) param)->passive)
             gtk_tree_view_column_set_clickable (col, FALSE);
         else
 	{
@@ -360,7 +365,7 @@ gnc_query_view_init_view (GNCQueryView *qview)
                                     GINT_TO_POINTER (i+1), NULL);
 	}
 
-        type = gnc_search_param_get_param_type (param);
+        type = gnc_search_param_get_param_type (((GNCSearchParam *) param));
 
         if (g_strcmp0 (type, QOF_TYPE_BOOLEAN) == 0)
         {
@@ -713,18 +718,19 @@ gnc_query_view_set_query_sort (GNCQueryView *qview, gboolean new_column)
 {
     gboolean        sort_order = qview->increasing;
     GList          *node;
-    GNCSearchParam *param;
+    GNCSearchParamSimple *param;
 
     /* Find the column parameter definition */
     node = g_list_nth (qview->column_params, qview->sort_column);
     param = node->data;
+    g_assert (GNC_IS_SEARCH_PARAM_SIMPLE (param));
 
     /* If we're asked to invert numerics, and if this is a numeric or
      * debred column, then invert the sort order.
      */
     if (qview->numeric_inv_sort)
     {
-        const char *type = gnc_search_param_get_param_type (param);
+        const char *type = gnc_search_param_get_param_type ((GNCSearchParam *) param);
         if (!g_strcmp0(type, QOF_TYPE_NUMERIC) ||
                 !g_strcmp0(type, QOF_TYPE_DEBCRED))
             sort_order = !sort_order;
@@ -789,9 +795,10 @@ gnc_query_view_fill (GNCQueryView *qview)
         for (i = 0, node = qview->column_params; node; node = node->next)
         {
             gboolean result;
-            GNCSearchParam *param = node->data;
+            GNCSearchParamSimple *param = node->data;
+            g_assert (GNC_IS_SEARCH_PARAM_SIMPLE (param));
             GSList *converters = gnc_search_param_get_converters (param);
-            const char *type = gnc_search_param_get_param_type (param);
+            const char *type = gnc_search_param_get_param_type ((GNCSearchParam *) param);
             gpointer res = item->data;
             gchar *qofstring;
 
diff --git a/src/gnome-utils/search-param.c b/src/gnome-utils/search-param.c
index 4943de0..1dd8eb2 100644
--- a/src/gnome-utils/search-param.c
+++ b/src/gnome-utils/search-param.c
@@ -37,22 +37,53 @@ static void gnc_search_param_class_init	(GNCSearchParamClass *klass);
 static void gnc_search_param_init	(GNCSearchParam *gspaper);
 static void gnc_search_param_finalize	(GObject *obj);
 
+static void gnc_search_param_simple_class_init	(GNCSearchParamSimpleClass *klass);
+static void gnc_search_param_simple_init	(GNCSearchParamSimple *gspaper);
+static void gnc_search_param_simple_finalize	(GObject *obj);
+
+static void gnc_search_param_compound_class_init	(GNCSearchParamCompoundClass *klass);
+static void gnc_search_param_compound_init	(GNCSearchParamCompound *gspaper);
+static void gnc_search_param_compound_finalize	(GObject *obj);
+
 typedef struct _GNCSearchParamPrivate	GNCSearchParamPrivate;
 
 struct _GNCSearchParamPrivate
 {
+    QofIdTypeConst	type;
+};
+
+#define GNC_SEARCH_PARAM_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_SEARCH_PARAM, GNCSearchParamPrivate))
+
+typedef struct _GNCSearchParamSimplePrivate	GNCSearchParamSimplePrivate;
+
+struct _GNCSearchParamSimplePrivate
+{
     GSList *		converters;
     GSList *		param_path;
-    QofIdTypeConst	type;
 
     GNCSearchParamFcn	lookup_fcn;
     gpointer		lookup_arg;
 };
 
-#define GNC_SEARCH_PARAM_GET_PRIVATE(o)  \
-   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_SEARCH_PARAM, GNCSearchParamPrivate))
+#define GNC_SEARCH_PARAM_SIMPLE_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_SEARCH_PARAM_SIMPLE, GNCSearchParamSimplePrivate))
+
+typedef struct _GNCSearchParamCompoundPrivate	GNCSearchParamCompoundPrivate;
+
+struct _GNCSearchParamCompoundPrivate
+{
+    GList *         sub_search;
+
+    /* This defines the type of subsearch, either AND or OR */
+    GNCSearchParamKind kind;
+};
+
+#define GNC_SEARCH_PARAM_COMPOUND_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_SEARCH_PARAM_COMPOUND, GNCSearchParamCompoundPrivate))
 
-static GObjectClass *parent_class;
+static GObjectClass *parent_gobject_class;
+static GNCSearchParamClass *parent_search_param_class;
 
 enum
 {
@@ -63,6 +94,7 @@ enum
 static guint signals[LAST_SIGNAL] = { 0 };
 #endif
 
+/* Base class */
 GType
 gnc_search_param_get_type (void)
 {
@@ -95,7 +127,7 @@ gnc_search_param_class_init (GNCSearchParamClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-    parent_class = g_type_class_peek_parent (klass);
+    parent_gobject_class = g_type_class_peek_parent (klass);
 
     object_class->finalize = gnc_search_param_finalize;
 
@@ -110,49 +142,183 @@ gnc_search_param_init (GNCSearchParam *o)
 static void
 gnc_search_param_finalize (GObject *obj)
 {
-    GNCSearchParam *o;
-    GNCSearchParamPrivate *priv;
-
     g_return_if_fail (obj != NULL);
     g_return_if_fail (GNC_IS_SEARCH_PARAM (obj));
 
-    o = GNC_SEARCH_PARAM (obj);
-    priv = GNC_SEARCH_PARAM_GET_PRIVATE(o);
+    G_OBJECT_CLASS (parent_gobject_class)->finalize(obj);
+}
+
+/* subclass for simple searches of a single element */
+GType
+gnc_search_param_simple_get_type (void)
+{
+    static GType type = 0;
+
+    if (type == 0)
+    {
+        static GTypeInfo type_info =
+        {
+            sizeof(GNCSearchParamSimpleClass),
+            NULL,
+            NULL,
+            (GClassInitFunc)gnc_search_param_simple_class_init,
+            NULL,
+            NULL,
+            sizeof(GNCSearchParamSimple),
+            0,
+            (GInstanceInitFunc)gnc_search_param_simple_init
+        };
+
+        type = g_type_register_static (GNC_TYPE_SEARCH_PARAM, "GNCSearchParamSimple",
+                                       &type_info, 0);
+    }
+
+    return type;
+}
+
+static void
+gnc_search_param_simple_class_init (GNCSearchParamSimpleClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    parent_search_param_class = g_type_class_peek_parent (klass);
+
+    object_class->finalize = gnc_search_param_simple_finalize;
+
+    g_type_class_add_private(klass, sizeof(GNCSearchParamSimplePrivate));
+}
+
+static void
+gnc_search_param_simple_init (GNCSearchParamSimple *o)
+{
+}
+
+static void
+gnc_search_param_simple_finalize (GObject *obj)
+{
+    GNCSearchParamSimple *o;
+    GNCSearchParamSimplePrivate *priv;
+
+    g_return_if_fail (obj != NULL);
+    g_return_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE (obj));
+
+    o = GNC_SEARCH_PARAM_SIMPLE (obj);
+    priv = GNC_SEARCH_PARAM_SIMPLE_GET_PRIVATE(o);
 
     g_slist_free (priv->param_path);
     priv->param_path = NULL;
     g_slist_free (priv->converters);
     priv->converters = NULL;
 
-    G_OBJECT_CLASS (parent_class)->finalize(obj);
+    G_OBJECT_CLASS (parent_search_param_class)->finalize(obj);
+}
+
+/* Subclass for compound searches consisting of AND/OR of several elements */
+GType
+gnc_search_param_compound_get_type (void)
+{
+    static GType type = 0;
+
+    if (type == 0)
+    {
+        static GTypeInfo type_info =
+        {
+            sizeof(GNCSearchParamCompoundClass),
+            NULL,
+            NULL,
+            (GClassInitFunc)gnc_search_param_compound_class_init,
+            NULL,
+            NULL,
+            sizeof(GNCSearchParamCompound),
+            0,
+            (GInstanceInitFunc)gnc_search_param_compound_init
+        };
+
+        type = g_type_register_static (GNC_TYPE_SEARCH_PARAM, "GNCSearchParamCompound",
+                                       &type_info, 0);
+    }
+
+    return type;
+}
+
+static void
+gnc_search_param_compound_class_init (GNCSearchParamCompoundClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    parent_search_param_class = g_type_class_peek_parent (klass);
+
+    object_class->finalize = gnc_search_param_compound_finalize;
+
+    g_type_class_add_private(klass, sizeof(GNCSearchParamCompoundPrivate));
+}
+
+static void
+gnc_search_param_compound_init (GNCSearchParamCompound *o)
+{
+}
+
+static void
+gnc_search_param_compound_finalize (GObject *obj)
+{
+    GNCSearchParamCompound *o;
+    GNCSearchParamCompoundPrivate *priv;
+
+    g_return_if_fail (obj != NULL);
+    g_return_if_fail (GNC_IS_SEARCH_PARAM_COMPOUND (obj));
+
+    o = GNC_SEARCH_PARAM_COMPOUND (obj);
+    priv = GNC_SEARCH_PARAM_COMPOUND_GET_PRIVATE(o);
+
+    g_list_free (priv->sub_search);
+    priv->sub_search = NULL;
+
+    G_OBJECT_CLASS (parent_search_param_class)->finalize(obj);
 }
 
 /**
- * gnc_search_param_new:
+ * gnc_search_param_simple_new:
  *
- * Create a new GNCSearchParam object.
+ * Create a new GNCSearchParamSimple object.
  *
  * Return value: A new #GNCSearchParam object.
  **/
-GNCSearchParam *
-gnc_search_param_new (void)
+GNCSearchParamSimple *
+gnc_search_param_simple_new (void)
+{
+    GNCSearchParamSimple *o = 
+        (GNCSearchParamSimple *)g_object_new(gnc_search_param_simple_get_type (), NULL);
+    return o;
+}
+
+/**
+ * gnc_search_param_compound_new:
+ *
+ * Create a new GNCSearchParam object.
+ *
+ * Return value: A new #GNCSearchParamCompound object.
+ **/
+GNCSearchParamCompound *
+gnc_search_param_compound_new (void)
 {
-    GNCSearchParam *o = (GNCSearchParam *)g_object_new(gnc_search_param_get_type (), NULL);
+    GNCSearchParamCompound *o = 
+        (GNCSearchParamCompound *)g_object_new(gnc_search_param_compound_get_type (), NULL);
     return o;
 }
 
 void
-gnc_search_param_set_param_path (GNCSearchParam *param,
+gnc_search_param_set_param_path (GNCSearchParamSimple *param,
                                  QofIdTypeConst search_type,
                                  GSList *param_path)
 {
-    GNCSearchParamPrivate *priv;
+    GNCSearchParamSimplePrivate *priv;
+    GNCSearchParamPrivate *priv_base;
     QofIdTypeConst type = NULL;
     GSList *converters = NULL;
 
-    g_return_if_fail (GNC_IS_SEARCH_PARAM (param));
+    g_return_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE (param));
 
-    priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
+    priv = GNC_SEARCH_PARAM_SIMPLE_GET_PRIVATE(param);
     if (priv->param_path)
     {
         g_slist_free (priv->param_path);
@@ -178,7 +344,8 @@ gnc_search_param_set_param_path (GNCSearchParam *param,
     }
 
     /* Save the type */
-    priv->type = type;
+    priv_base = GNC_SEARCH_PARAM_GET_PRIVATE(param);
+    priv_base->type = type;
 
     /* Save the converters */
     if (priv->converters)
@@ -189,38 +356,49 @@ gnc_search_param_set_param_path (GNCSearchParam *param,
 }
 
 void
-gnc_search_param_override_param_type (GNCSearchParam *param,
+gnc_search_param_override_param_type (GNCSearchParamSimple *param,
                                       QofIdTypeConst param_type)
 {
     GNCSearchParamPrivate *priv;
 
-    g_return_if_fail (GNC_IS_SEARCH_PARAM (param));
+    g_return_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE (param));
     g_return_if_fail (param_type != NULL && *param_type != '\0');
 
-    priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
+    priv = GNC_SEARCH_PARAM_GET_PRIVATE (GNC_SEARCH_PARAM (param));
     priv->type = param_type;
     /* XXX: What about the converters? */
 }
 
+GList *
+gnc_search_param_get_search (GNCSearchParamCompound *param)
+{
+    GNCSearchParamCompoundPrivate *priv;
+
+    g_return_val_if_fail (GNC_IS_SEARCH_PARAM_COMPOUND (param), NULL);
+
+    priv = GNC_SEARCH_PARAM_COMPOUND_GET_PRIVATE(param);
+    return priv->sub_search;
+}
+
 GSList *
-gnc_search_param_get_param_path (GNCSearchParam *param)
+gnc_search_param_get_param_path (GNCSearchParamSimple *param)
 {
-    GNCSearchParamPrivate *priv;
+    GNCSearchParamSimplePrivate *priv;
 
-    g_return_val_if_fail (GNC_IS_SEARCH_PARAM (param), NULL);
+    g_return_val_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE (param), NULL);
 
-    priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
+    priv = GNC_SEARCH_PARAM_SIMPLE_GET_PRIVATE(param);
     return g_slist_copy (priv->param_path);
 }
 
 GSList *
-gnc_search_param_get_converters (GNCSearchParam *param)
+gnc_search_param_get_converters (GNCSearchParamSimple *param)
 {
-    GNCSearchParamPrivate *priv;
+    GNCSearchParamSimplePrivate *priv;
 
-    g_return_val_if_fail (GNC_IS_SEARCH_PARAM (param), NULL);
+    g_return_val_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE (param), NULL);
 
-    priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
+    priv = GNC_SEARCH_PARAM_SIMPLE_GET_PRIVATE(param);
     return priv->converters;
 }
 
@@ -235,6 +413,20 @@ gnc_search_param_get_param_type (GNCSearchParam *param)
     return priv->type;
 }
 
+GNCSearchParamKind
+gnc_search_param_get_kind (GNCSearchParam *param)
+{
+    GNCSearchParamCompoundPrivate *priv;
+
+    if (GNC_IS_SEARCH_PARAM_SIMPLE (param))
+        return SEARCH_PARAM_ELEM;
+        
+    g_return_val_if_fail (GNC_IS_SEARCH_PARAM_COMPOUND (param), SEARCH_PARAM_ELEM);
+
+    priv = GNC_SEARCH_PARAM_COMPOUND_GET_PRIVATE(param);
+    return priv->kind;
+}
+
 void
 gnc_search_param_set_title (GNCSearchParam *param, const char *title)
 {
@@ -291,13 +483,13 @@ gnc_search_param_prepend_internal (GList *list, char const *title,
                                    QofIdTypeConst search_type,
                                    const char *param, va_list args)
 {
-    GNCSearchParam *p;
+    GNCSearchParamSimple *p;
     GSList *path = NULL;
     const char *this_param;
 
-    p = gnc_search_param_new ();
-    gnc_search_param_set_title (p, title);
-    gnc_search_param_set_justify (p, justify);
+    p = gnc_search_param_simple_new ();
+    gnc_search_param_set_title (GNC_SEARCH_PARAM (p), title);
+    gnc_search_param_set_justify (GNC_SEARCH_PARAM (p), justify);
 
     for (this_param = param; this_param;
             this_param = va_arg (args, const char *))
@@ -363,20 +555,62 @@ gnc_search_param_prepend (GList *list, char const *title,
     return result;
 }
 
+GList *
+gnc_search_param_prepend_compound (GList *list, char const *title,
+                                   GList *param_list,
+                                   GtkJustification justify,
+                                   GNCSearchParamKind kind)
+{
+    GList *result;
+    GList *p;
+    QofIdTypeConst type = NULL;
+    GNCSearchParamCompound *param;
+    GNCSearchParamPrivate *basepriv;
+    GNCSearchParamCompoundPrivate *priv;
+    
+    g_return_val_if_fail (title, list);
+    g_return_val_if_fail (param_list, list);
+    g_return_val_if_fail (kind == SEARCH_PARAM_ANY || kind == SEARCH_PARAM_ALL, list);
+    
+    /* "param_list" is a list of GNCSearchParamSimple.  Make sure all the types are the same */
+    for (p = param_list; p; p = p->next)
+    {
+        GNCSearchParam *baseparam;
+        g_return_val_if_fail (GNC_IS_SEARCH_PARAM (p->data), list);
+        baseparam = GNC_SEARCH_PARAM(p->data);
+        if (!type)
+            type = gnc_search_param_get_param_type (baseparam);
+        else
+            g_return_val_if_fail (g_strcmp0 (type, gnc_search_param_get_param_type (baseparam)) == 0, list);
+    }
+    
+    param = gnc_search_param_compound_new ();
+    gnc_search_param_set_title (GNC_SEARCH_PARAM (param), title);
+    gnc_search_param_set_justify (GNC_SEARCH_PARAM (param), justify);
+
+    priv = GNC_SEARCH_PARAM_COMPOUND_GET_PRIVATE(param);
+    basepriv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
+    priv->sub_search = g_list_copy (param_list);
+    basepriv->type = type;
+    priv->kind = kind;
+    
+    return g_list_prepend (list, param);
+}
+
 void
-gnc_search_param_set_param_fcn (GNCSearchParam *param,
+gnc_search_param_set_param_fcn (GNCSearchParamSimple *param,
                                 QofIdTypeConst param_type,
                                 GNCSearchParamFcn fcn,
                                 gpointer arg)
 {
-    GNCSearchParamPrivate *priv;
+    GNCSearchParamSimplePrivate *priv;
 
     g_return_if_fail (param);
     g_return_if_fail (param_type && *param_type);
     g_return_if_fail (fcn);
-    g_return_if_fail (GNC_IS_SEARCH_PARAM(param));
+    g_return_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param));
 
-    priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
+    priv = GNC_SEARCH_PARAM_SIMPLE_GET_PRIVATE(param);
     priv->lookup_fcn = fcn;
     priv->lookup_arg = arg;
     gnc_search_param_override_param_type (param, param_type);
@@ -384,14 +618,14 @@ gnc_search_param_set_param_fcn (GNCSearchParam *param,
 
 /* Compute the value of this parameter for this object */
 gpointer
-gnc_search_param_compute_value (GNCSearchParam *param, gpointer object)
+gnc_search_param_compute_value (GNCSearchParamSimple *param, gpointer object)
 {
-    GNCSearchParamPrivate *priv;
+    GNCSearchParamSimplePrivate *priv;
 
     g_return_val_if_fail(param, NULL);
-    g_return_val_if_fail(GNC_IS_SEARCH_PARAM(param), NULL);
+    g_return_val_if_fail(GNC_IS_SEARCH_PARAM_SIMPLE(param), NULL);
 
-    priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
+    priv = GNC_SEARCH_PARAM_SIMPLE_GET_PRIVATE(param);
     if (priv->lookup_fcn)
     {
         return ((priv->lookup_fcn)(object, priv->lookup_arg));
diff --git a/src/gnome-utils/search-param.h b/src/gnome-utils/search-param.h
index 59257fc..6fce06e 100644
--- a/src/gnome-utils/search-param.h
+++ b/src/gnome-utils/search-param.h
@@ -51,24 +51,84 @@ struct _GNCSearchParamClass
     /* signals */
 };
 
+#define GNC_TYPE_SEARCH_PARAM_SIMPLE	 (gnc_search_param_simple_get_type ())
+#define GNC_SEARCH_PARAM_SIMPLE(o)	 \
+    (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_SEARCH_PARAM_SIMPLE, GNCSearchParamSimple))
+#define GNCSEARCH_PARAM_SIMPLE_CLASS(k) \
+    (G_TYPE_CHECK_CLASS_CAST ((k), GNC_TYPE_SEARCH_PARAM_SIMPLE, GNCSearchParamSimpleClass)
+#define GNC_IS_SEARCH_PARAM_SIMPLE(o)	 (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNC_TYPE_SEARCH_PARAM_SIMPLE))
+
+typedef struct _GNCSearchParamSimple	GNCSearchParamSimple;
+typedef struct _GNCSearchParamSimpleClass	GNCSearchParamSimpleClass;
+
+struct _GNCSearchParamSimple
+{
+    GNCSearchParam  search_param;
+};
+
+struct _GNCSearchParamSimpleClass
+{
+    GNCSearchParamClass search_param_class;
+
+    /* virtual methods */
+
+    /* signals */
+};
+
+#define GNC_TYPE_SEARCH_PARAM_COMPOUND	 (gnc_search_param_compound_get_type ())
+#define GNC_SEARCH_PARAM_COMPOUND(o)	 \
+    (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_SEARCH_PARAM_COMPOUND, GNCSearchParamCompound))
+#define GNCSEARCH_PARAM_COMPOUND_CLASS(k) \
+    (G_TYPE_CHECK_CLASS_CAST ((k), GNC_TYPE_SEARCH_PARAM_COMPOUND, GNCSearchParamCompoundClass)
+#define GNC_IS_SEARCH_PARAM_COMPOUND(o)	 (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNC_TYPE_SEARCH_PARAM_COMPOUND))
+
+typedef struct _GNCSearchParamCompound	GNCSearchParamCompound;
+typedef struct _GNCSearchParamCompoundClass	GNCSearchParamCompoundClass;
+
+struct _GNCSearchParamCompound
+{
+    GNCSearchParam  search_param;
+};
+
+struct _GNCSearchParamCompoundClass
+{
+    GNCSearchParamClass search_param_class;
+
+    /* virtual methods */
+
+    /* signals */
+};
+
+typedef enum
+{
+    SEARCH_PARAM_ELEM = 0,
+    SEARCH_PARAM_ANY = 1,
+    SEARCH_PARAM_ALL = 2
+} GNCSearchParamKind;
+
 /* These are internal functions */
 GType			gnc_search_param_get_type (void);
+GType			gnc_search_param_simple_get_type (void);
+GType			gnc_search_param_compound_get_type (void);
 
 /* Create a new search param */
-GNCSearchParam *	gnc_search_param_new (void);
+GNCSearchParamSimple *	gnc_search_param_simple_new (void);
+GNCSearchParamCompound *	gnc_search_param_compound_new (void);
 
 /* use the param_path for this parameter.  This will automatically
  * compute the parameter type and the converter functions.
  */
-void			gnc_search_param_set_param_path (GNCSearchParam *param,
+void			gnc_search_param_set_param_path (GNCSearchParamSimple *param,
         QofIdTypeConst search_type,
         GSList *param_path);
 
 /* List is property of the caller */
-GSList *		gnc_search_param_get_param_path (GNCSearchParam *param);
+GList *         gnc_search_param_get_search (GNCSearchParamCompound *param);
+GSList *		gnc_search_param_get_param_path (GNCSearchParamSimple *param);
 QofIdTypeConst		gnc_search_param_get_param_type (GNCSearchParam *param);
 void			gnc_search_param_set_title (GNCSearchParam *param,
         const char *title);
+GNCSearchParamKind gnc_search_param_get_kind (GNCSearchParam *param);
 void			gnc_search_param_set_justify (GNCSearchParam *param,
         GtkJustification justify);
 void			gnc_search_param_set_passive (GNCSearchParam *param,
@@ -80,7 +140,7 @@ gboolean		gnc_search_param_type_match (GNCSearchParam *a,
 
 /* Return the list of QofAccessFunc functions for this parameter.  This list
  * is owned by the param object -- users should not change it */
-GSList *		gnc_search_param_get_converters (GNCSearchParam *param);
+GSList *		gnc_search_param_get_converters (GNCSearchParamSimple *param);
 
 /* This will override the automatic param_type logic from "set_param_path()"
  * so that the programmer can force a particular UI to appear for a given
@@ -88,7 +148,7 @@ GSList *		gnc_search_param_get_converters (GNCSearchParam *param);
  * it could result in an invalid Query Term, where the path and the predicate
  * don't match types properly.
  */
-void			gnc_search_param_override_param_type (GNCSearchParam *param,
+void			gnc_search_param_override_param_type (GNCSearchParamSimple *param,
         QofIdTypeConst param_type);
 
 
@@ -109,6 +169,11 @@ GList *			gnc_search_param_prepend_with_justify (GList *list, char const *title,
         QofIdTypeConst search_type,
         const char *param, ...);
 
+GList *         gnc_search_param_prepend_compound (GList *list, char const *title,
+                                   GList *param_list,
+                                   GtkJustification justify,
+                                   GNCSearchParamKind kind);
+
 /* set a lookup function for this parameter (in lieu of setting the
  * param path) if you want to specify a direct lookup function when
  * using the compute_value interface.  Note that this wont work with
@@ -116,13 +181,13 @@ GList *			gnc_search_param_prepend_with_justify (GList *list, char const *title,
  * query-list.
  */
 typedef gpointer (*GNCSearchParamFcn)(gpointer object, gpointer arg);
-void		gnc_search_param_set_param_fcn (GNCSearchParam *param,
+void		gnc_search_param_set_param_fcn (GNCSearchParamSimple *param,
         QofIdTypeConst param_type,
         GNCSearchParamFcn fcn,
         gpointer arg);
 
 /* Compute the value of this parameter for this object */
-gpointer gnc_search_param_compute_value (GNCSearchParam *param, gpointer object);
+gpointer gnc_search_param_compute_value (GNCSearchParamSimple *param, gpointer object);
 
 
 #endif /* _GNCSEARCH_PARAM_H */
diff --git a/src/gnome/dialog-find-transactions.c b/src/gnome/dialog-find-transactions.c
index 46a29fd..a8a4ce2 100644
--- a/src/gnome/dialog-find-transactions.c
+++ b/src/gnome/dialog-find-transactions.c
@@ -124,8 +124,6 @@ gnc_ui_find_transactions_dialog_create(GNCLedgerDisplay * orig_ledg)
         params = gnc_search_param_prepend (params, N_("Date Posted"), NULL,
                                            type, SPLIT_TRANS, TRANS_DATE_POSTED,
                                            NULL);
-        params = gnc_search_param_prepend (params, N_("Notes"), NULL,
-                                           type, SPLIT_TRANS, TRANS_NOTES, NULL);
         params = gnc_search_param_prepend (params, (num_action
                                                     ? N_("Number/Action")
                                                     : N_("Action")), NULL,
@@ -134,8 +132,24 @@ gnc_ui_find_transactions_dialog_create(GNCLedgerDisplay * orig_ledg)
                                                     ? N_("Transaction Number")
                                                     : N_("Number")), NULL,
                                            type, SPLIT_TRANS, TRANS_NUM, NULL);
+        {
+            GList *params2 = NULL;
+            params2 = gnc_search_param_prepend (params2, "", NULL,
+                                               type, SPLIT_MEMO, NULL);
+            params2 = gnc_search_param_prepend (params2, "", NULL,
+                                               type, SPLIT_TRANS, TRANS_DESCRIPTION,
+                                               NULL);
+            params2 = gnc_search_param_prepend (params2, "", NULL,
+                                               type, SPLIT_TRANS, TRANS_NOTES, NULL);
+            params = gnc_search_param_prepend_compound (params, 
+                                                        N_("Description, Notes, or Memo"),
+                                                        params2,
+                                                        GTK_JUSTIFY_LEFT, SEARCH_PARAM_ANY);
+        }
         params = gnc_search_param_prepend (params, N_("Memo"), NULL,
                                            type, SPLIT_MEMO, NULL);
+        params = gnc_search_param_prepend (params, N_("Notes"), NULL,
+                                           type, SPLIT_TRANS, TRANS_NOTES, NULL);
         params = gnc_search_param_prepend (params, N_("Description"), NULL,
                                            type, SPLIT_TRANS, TRANS_DESCRIPTION,
                                            NULL);
diff --git a/src/gnome/dialog-find-transactions2.c b/src/gnome/dialog-find-transactions2.c
index 32f1bde..65968e5 100644
--- a/src/gnome/dialog-find-transactions2.c
+++ b/src/gnome/dialog-find-transactions2.c
@@ -125,8 +125,6 @@ gnc_ui_find_transactions_dialog_create2 (GNCLedgerDisplay2 * orig_ledg)
         params = gnc_search_param_prepend (params, N_("Date Posted"), NULL,
                                            type, SPLIT_TRANS, TRANS_DATE_POSTED,
                                            NULL);
-        params = gnc_search_param_prepend (params, N_("Notes"), NULL,
-                                           type, SPLIT_TRANS, TRANS_NOTES, NULL);
         params = gnc_search_param_prepend (params, (num_action
                                                     ? N_("Number/Action")
                                                     : N_("Action")), NULL,
@@ -135,8 +133,24 @@ gnc_ui_find_transactions_dialog_create2 (GNCLedgerDisplay2 * orig_ledg)
                                                     ? N_("Transaction Number")
                                                     : N_("Number")), NULL,
                                            type, SPLIT_TRANS, TRANS_NUM, NULL);
+        {
+            GList *params2 = NULL;
+            params2 = gnc_search_param_prepend (params2, "", NULL,
+                                               type, SPLIT_MEMO, NULL);
+            params2 = gnc_search_param_prepend (params2, "", NULL,
+                                               type, SPLIT_TRANS, TRANS_DESCRIPTION,
+                                               NULL);
+            params2 = gnc_search_param_prepend (params2, "", NULL,
+                                               type, SPLIT_TRANS, TRANS_NOTES, NULL);
+            params = gnc_search_param_prepend_compound (params, 
+                                                        N_("Description, Notes, or Memo"),
+                                                        params2,
+                                                        GTK_JUSTIFY_LEFT, SEARCH_PARAM_ANY);
+        }
         params = gnc_search_param_prepend (params, N_("Memo"), NULL,
                                            type, SPLIT_MEMO, NULL);
+        params = gnc_search_param_prepend (params, N_("Notes"), NULL,
+                                           type, SPLIT_TRANS, TRANS_NOTES, NULL);
         params = gnc_search_param_prepend (params, N_("Description"), NULL,
                                            type, SPLIT_TRANS, TRANS_DESCRIPTION,
                                            NULL);
diff --git a/src/gnome/reconcile-view.c b/src/gnome/reconcile-view.c
index 120bdef..60f5818 100644
--- a/src/gnome/reconcile-view.c
+++ b/src/gnome/reconcile-view.c
@@ -353,7 +353,7 @@ gnc_reconcile_view_new (Account *account, GNCReconcileViewType type,
 static void
 gnc_reconcile_view_init (GNCReconcileView *view)
 {
-    GNCSearchParam *param;
+    GNCSearchParamSimple *param;
     GList          *columns = NULL;
     gboolean num_action =
                 qof_book_use_split_action_for_num_field(gnc_get_current_book());
@@ -362,13 +362,13 @@ gnc_reconcile_view_init (GNCReconcileView *view)
     view->account = NULL;
     view->sibling = NULL;
 
-    param = gnc_search_param_new();
+    param = gnc_search_param_simple_new();
     gnc_search_param_set_param_fcn (param, QOF_TYPE_BOOLEAN,
                                     gnc_reconcile_view_is_reconciled, view);
-    gnc_search_param_set_title (param, _("Reconciled:R") + 11);
-    gnc_search_param_set_justify (param, GTK_JUSTIFY_CENTER);
-    gnc_search_param_set_passive (param, TRUE);
-    gnc_search_param_set_non_resizeable (param, TRUE);
+    gnc_search_param_set_title ((GNCSearchParam *) param, _("Reconciled:R") + 11);
+    gnc_search_param_set_justify ((GNCSearchParam *) param, GTK_JUSTIFY_CENTER);
+    gnc_search_param_set_passive ((GNCSearchParam *) param, TRUE);
+    gnc_search_param_set_non_resizeable ((GNCSearchParam *) param, TRUE);
     columns = g_list_prepend (columns, param);
     columns = gnc_search_param_prepend_with_justify (columns, _("Amount"),
               GTK_JUSTIFY_RIGHT,



Summary of changes:
 src/gnome-search/dialog-search.c      |  42 ++++-
 src/gnome-search/dialog-search.h      |   5 +-
 src/gnome-search/search-core-type.h   |   1 +
 src/gnome-utils/gnc-query-view.c      |  33 ++--
 src/gnome-utils/search-param.c        | 322 +++++++++++++++++++++++++++++-----
 src/gnome-utils/search-param.h        |  79 ++++++++-
 src/gnome/dialog-find-transactions.c  |  18 +-
 src/gnome/dialog-find-transactions2.c |  18 +-
 src/gnome/reconcile-view.c            |  12 +-
 9 files changed, 450 insertions(+), 80 deletions(-)



More information about the gnucash-changes mailing list