GnuCash  5.6-150-g038405b370+
search-param.c
1 /*
2  * search-param.c -- a container for a Search Parameter
3  * Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, contact:
17  *
18  * Free Software Foundation Voice: +1-617-542-5942
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
20  * Boston, MA 02110-1301, USA gnu@gnu.org
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <gtk/gtk.h>
28 #include <string.h>
29 #include <stdarg.h>
30 
31 #include "gnc-engine.h"
32 #include "qof.h"
33 
34 #include "search-param.h"
35 
36 static void gnc_search_param_finalize (GObject *obj);
37 
38 static void gnc_search_param_simple_finalize (GObject *obj);
39 
40 static void gnc_search_param_compound_finalize (GObject *obj);
41 
42 typedef struct _GNCSearchParamPrivate GNCSearchParamPrivate;
43 
45 {
46  const char * title;
47  GtkJustification justify;
48  gboolean passive;
49  gboolean non_resizeable;
50 
51  QofIdTypeConst type;
52 };
53 
54 #define GNC_SEARCH_PARAM_GET_PRIVATE(o) \
55  ((GNCSearchParamPrivate*)gnc_search_param_get_instance_private ((GNCSearchParam*)o))
56 
58 {
59  GNCSearchParam search_param;
60 
61  GSList * converters;
62  GSList * param_path;
63 
64  GNCSearchParamFcn lookup_fcn;
65  gpointer lookup_arg;
66 };
67 
69 {
70  GNCSearchParam search_param;
71 
72  GList * sub_search;
73 
74  /* This defines the type of subsearch, either AND or OR */
75  GNCSearchParamKind kind;
76 };
77 
78 enum
79 {
80  LAST_SIGNAL
81 };
82 
83 #if LAST_SIGNAL > 0
84 static guint signals[LAST_SIGNAL] = { 0 };
85 #endif
86 
87 /* Base class */
88 
89 G_DEFINE_TYPE_WITH_PRIVATE(GNCSearchParam, gnc_search_param, G_TYPE_OBJECT)
90 
91 static void
92 gnc_search_param_class_init (GNCSearchParamClass *klass)
93 {
94  GObjectClass *object_class = G_OBJECT_CLASS(klass);
95 
96  object_class->finalize = gnc_search_param_finalize;
97 }
98 
99 static void
100 gnc_search_param_init (GNCSearchParam *o)
101 {
102 }
103 
104 static void
105 gnc_search_param_finalize (GObject *obj)
106 {
107  g_return_if_fail (obj != NULL);
108  g_return_if_fail (GNC_IS_SEARCH_PARAM(obj));
109 
110  G_OBJECT_CLASS(gnc_search_param_parent_class)->finalize (obj);
111 }
112 
113 /* subclass for simple searches of a single element */
114 
115 G_DEFINE_TYPE(GNCSearchParamSimple, gnc_search_param_simple, GNC_TYPE_SEARCH_PARAM)
116 
117 static void
118 gnc_search_param_simple_class_init (GNCSearchParamSimpleClass *klass)
119 {
120  GObjectClass *object_class = G_OBJECT_CLASS(klass);
121 
122  object_class->finalize = gnc_search_param_simple_finalize;
123 }
124 
125 static void
126 gnc_search_param_simple_init (GNCSearchParamSimple *o)
127 {
128 }
129 
130 static void
131 gnc_search_param_simple_finalize (GObject *obj)
132 {
133  GNCSearchParamSimple *o;
134 
135  g_return_if_fail (obj != NULL);
136  g_return_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(obj));
137 
138  o = GNC_SEARCH_PARAM_SIMPLE(obj);
139 
140  g_slist_free (o->param_path);
141  o->param_path = NULL;
142  g_slist_free (o->converters);
143  o->converters = NULL;
144 
145  G_OBJECT_CLASS(gnc_search_param_simple_parent_class)->finalize (obj);
146 }
147 
148 /* Subclass for compound searches consisting of AND/OR of several elements */
149 
150 G_DEFINE_TYPE(GNCSearchParamCompound, gnc_search_param_compound, GNC_TYPE_SEARCH_PARAM)
151 
152 static void
153 gnc_search_param_compound_class_init (GNCSearchParamCompoundClass *klass)
154 {
155  GObjectClass *object_class = G_OBJECT_CLASS(klass);
156 
157  object_class->finalize = gnc_search_param_compound_finalize;
158 }
159 
160 static void
161 gnc_search_param_compound_init (GNCSearchParamCompound *o)
162 {
163 }
164 
165 static void
166 gnc_search_param_compound_finalize (GObject *obj)
167 {
168  GNCSearchParamCompound *o;
169 
170  g_return_if_fail (obj != NULL);
171  g_return_if_fail (GNC_IS_SEARCH_PARAM_COMPOUND(obj));
172 
173  o = GNC_SEARCH_PARAM_COMPOUND(obj);
174 
175  g_list_free (o->sub_search);
176  o->sub_search = NULL;
177 
178  G_OBJECT_CLASS (gnc_search_param_compound_parent_class)->finalize (obj);
179 }
180 
188 GNCSearchParamSimple *
189 gnc_search_param_simple_new (void)
190 {
191  GNCSearchParamSimple *o = (GNCSearchParamSimple *)
192  g_object_new (gnc_search_param_simple_get_type (), NULL);
193  return o;
194 }
195 
203 GNCSearchParamCompound *
204 gnc_search_param_compound_new (void)
205 {
206  GNCSearchParamCompound *o = (GNCSearchParamCompound *)
207  g_object_new (gnc_search_param_compound_get_type (), NULL);
208  return o;
209 }
210 
211 void
212 gnc_search_param_set_param_path (GNCSearchParamSimple *param,
213  QofIdTypeConst search_type,
214  GSList *param_path)
215 {
216  GNCSearchParamPrivate *priv_base;
217  QofIdTypeConst type = NULL;
218  GSList *converters = NULL;
219 
220  g_return_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param));
221 
222  if (param->param_path)
223  {
224  g_slist_free (param->param_path);
225  }
226  param->param_path = g_slist_copy (param_path);
227 
228  /* Compute the parameter type */
229  for (; param_path; param_path = param_path->next)
230  {
231  QofIdType param_name = param_path->data;
232  const QofParam *objDef = qof_class_get_parameter (search_type,
233  param_name);
234 
235  /* If it doesn't exist, then we've reached the end */
236  if (objDef == NULL)
237  break;
238 
239  /* Save the converter */
240  converters = g_slist_prepend (converters, (gpointer) objDef);
241 
242  /* And reset for the next parameter */
243  type = search_type = objDef->param_type;
244  }
245 
246  /* Save the type */
247  priv_base = GNC_SEARCH_PARAM_GET_PRIVATE(param);
248  priv_base->type = type;
249 
250  /* Save the converters */
251  if (param->converters)
252  {
253  g_slist_free (param->converters);
254  }
255  param->converters = g_slist_reverse (converters);
256 }
257 
258 void
259 gnc_search_param_override_param_type (GNCSearchParamSimple *param,
260  QofIdTypeConst param_type)
261 {
262  GNCSearchParamPrivate *priv;
263 
264  g_return_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param));
265  g_return_if_fail (param_type != NULL && *param_type != '\0');
266 
267  priv = GNC_SEARCH_PARAM_GET_PRIVATE(GNC_SEARCH_PARAM(param));
268  priv->type = param_type;
269  /* XXX: What about the converters? */
270 }
271 
272 GList *
273 gnc_search_param_get_search (GNCSearchParamCompound *param)
274 {
275  g_return_val_if_fail (GNC_IS_SEARCH_PARAM_COMPOUND(param), NULL);
276 
277  return param->sub_search;
278 }
279 
280 GSList *
281 gnc_search_param_get_param_path (GNCSearchParamSimple *param)
282 {
283  g_return_val_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param), NULL);
284 
285  return g_slist_copy (param->param_path);
286 }
287 
288 GSList *
289 gnc_search_param_get_converters (GNCSearchParamSimple *param)
290 {
291  g_return_val_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param), NULL);
292 
293  return param->converters;
294 }
295 
297 gnc_search_param_get_param_type (GNCSearchParam *param)
298 {
299  GNCSearchParamPrivate *priv;
300 
301  g_return_val_if_fail (GNC_IS_SEARCH_PARAM(param), NULL);
302 
303  priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
304  return priv->type;
305 }
306 
307 GNCSearchParamKind
308 gnc_search_param_get_kind (GNCSearchParam *param)
309 {
310  if (GNC_IS_SEARCH_PARAM_SIMPLE(param))
311  return SEARCH_PARAM_ELEM;
312 
313  g_return_val_if_fail (GNC_IS_SEARCH_PARAM_COMPOUND(param), SEARCH_PARAM_ELEM);
314 
315  return GNC_SEARCH_PARAM_COMPOUND (param)->kind;
316 }
317 
318 const char*
319 gnc_search_param_get_title (GNCSearchParam *param)
320 {
321  g_return_val_if_fail (GNC_IS_SEARCH_PARAM(param), NULL);
322 
323  GNCSearchParamPrivate *priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
324  return priv->title;
325 }
326 
327 void
328 gnc_search_param_set_title (GNCSearchParam *param, const char *title)
329 {
330  g_return_if_fail (GNC_IS_SEARCH_PARAM(param));
331 
332  GNCSearchParamPrivate *priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
333  priv->title = title;
334 }
335 
336 GtkJustification
337 gnc_search_param_get_justify (GNCSearchParam *param)
338 {
339  g_return_val_if_fail (GNC_IS_SEARCH_PARAM(param), GTK_JUSTIFY_LEFT);
340 
341  GNCSearchParamPrivate *priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
342  return priv->justify;
343 }
344 
345 void
346 gnc_search_param_set_justify (GNCSearchParam *param, GtkJustification justify)
347 {
348  g_return_if_fail (GNC_IS_SEARCH_PARAM(param));
349 
350  GNCSearchParamPrivate *priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
351  priv->justify = justify;
352 }
353 
354 gboolean
355 gnc_search_param_get_passive (GNCSearchParam *param)
356 {
357  g_return_val_if_fail (GNC_IS_SEARCH_PARAM(param), FALSE);
358 
359  GNCSearchParamPrivate *priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
360  return priv->passive;
361 }
362 
363 void
364 gnc_search_param_set_passive (GNCSearchParam *param, gboolean value)
365 {
366  g_assert (GNC_IS_SEARCH_PARAM(param));
367 
368  GNCSearchParamPrivate *priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
369  priv->passive = value;
370 }
371 
372 gboolean
373 gnc_search_param_get_non_resizeable (GNCSearchParam *param)
374 {
375  g_return_val_if_fail (GNC_IS_SEARCH_PARAM(param), FALSE);
376 
377  GNCSearchParamPrivate *priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
378  return priv->non_resizeable;
379 }
380 
381 void
382 gnc_search_param_set_non_resizeable (GNCSearchParam *param, gboolean value)
383 {
384  g_assert (GNC_IS_SEARCH_PARAM(param));
385 
386  GNCSearchParamPrivate *priv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
387  priv->non_resizeable = value;
388 }
389 
390 gboolean
391 gnc_search_param_type_match (GNCSearchParam *a, GNCSearchParam *b)
392 {
393  GNCSearchParamPrivate *a_priv, *b_priv;
394 
395  g_return_val_if_fail (GNC_IS_SEARCH_PARAM(a), FALSE);
396  g_return_val_if_fail (GNC_IS_SEARCH_PARAM(b), FALSE);
397 
398  a_priv = GNC_SEARCH_PARAM_GET_PRIVATE(a);
399  b_priv = GNC_SEARCH_PARAM_GET_PRIVATE(b);
400 
401  if (a_priv->type == b_priv->type ||
402  !g_strcmp0 (a_priv->type, b_priv->type))
403  return TRUE;
404 
405  return FALSE;
406 }
407 
408 static GList *
409 gnc_search_param_prepend_internal (GList *list, char const *title,
410  GtkJustification justify,
411  QofIdTypeConst type_override,
412  QofIdTypeConst search_type,
413  const char *param, va_list args)
414 {
415  GNCSearchParamSimple *p;
416  GSList *path = NULL;
417  const char *this_param;
418 
419  p = gnc_search_param_simple_new ();
420  gnc_search_param_set_title (GNC_SEARCH_PARAM(p), title);
421  gnc_search_param_set_justify (GNC_SEARCH_PARAM(p), justify);
422 
423  for (this_param = param; this_param;
424  this_param = va_arg (args, const char *))
425  {
426  path = g_slist_prepend (path, (gpointer)this_param);
427  }
428 
429  /* put the path into the right order, and set it */
430  path = g_slist_reverse (path);
431  gnc_search_param_set_param_path (p, search_type, path);
432  g_slist_free (path);
433 
434  /* Maybe over-ride the type */
435  if (type_override)
436  gnc_search_param_override_param_type (p, type_override);
437 
438  /* And return it */
439  return g_list_prepend (list, p);
440 }
441 
442 
443 GList *
444 gnc_search_param_prepend_with_justify (GList *list, char const *title,
445  GtkJustification justify,
446  QofIdTypeConst type_override,
447  QofIdTypeConst search_type,
448  const char *param, ...)
449 {
450  GList *result;
451  va_list ap;
452 
453  g_return_val_if_fail (title, list);
454  g_return_val_if_fail (search_type, list);
455  g_return_val_if_fail (param, list);
456 
457  /* Build the parameter path */
458  va_start (ap, param);
459  result = gnc_search_param_prepend_internal (list, title, justify,
460  type_override, search_type,
461  param, ap);
462  va_end (ap);
463  return result;
464 }
465 
466 GList *
467 gnc_search_param_prepend (GList *list, char const *title,
468  QofIdTypeConst type_override,
469  QofIdTypeConst search_type,
470  const char *param, ...)
471 {
472  GList *result;
473  va_list ap;
474 
475  g_return_val_if_fail (title, list);
476  g_return_val_if_fail (search_type, list);
477  g_return_val_if_fail (param, list);
478 
479  /* Build the parameter path */
480  va_start (ap, param);
481  result = gnc_search_param_prepend_internal (list, title, GTK_JUSTIFY_LEFT,
482  type_override, search_type,
483  param, ap);
484  va_end (ap);
485  return result;
486 }
487 
488 GList *
489 gnc_search_param_prepend_compound (GList *list, char const *title,
490  GList *param_list,
491  GtkJustification justify,
492  GNCSearchParamKind kind)
493 {
494  GList *p;
495  QofIdTypeConst type = NULL;
496  GNCSearchParamCompound *param;
497  GNCSearchParamPrivate *basepriv;
498 
499  g_return_val_if_fail (title, list);
500  g_return_val_if_fail (param_list, list);
501  g_return_val_if_fail (kind == SEARCH_PARAM_ANY || kind == SEARCH_PARAM_ALL, list);
502 
503  /* "param_list" is a list of GNCSearchParamSimple. Make sure all the types are the same */
504  for (p = param_list; p; p = p->next)
505  {
506  GNCSearchParam *baseparam;
507  g_return_val_if_fail (GNC_IS_SEARCH_PARAM(p->data), list);
508  baseparam = GNC_SEARCH_PARAM(p->data);
509  if (!type)
510  type = gnc_search_param_get_param_type (baseparam);
511  else
512  g_return_val_if_fail (g_strcmp0 (type, gnc_search_param_get_param_type (baseparam)) == 0, list);
513  }
514 
515  param = gnc_search_param_compound_new ();
516  gnc_search_param_set_title (GNC_SEARCH_PARAM(param), title);
517  gnc_search_param_set_justify (GNC_SEARCH_PARAM(param), justify);
518 
519  basepriv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
520  param->sub_search = g_list_copy (param_list);
521  basepriv->type = type;
522  param->kind = kind;
523 
524  return g_list_prepend (list, param);
525 }
526 
527 void
528 gnc_search_param_set_param_fcn (GNCSearchParamSimple *param,
529  QofIdTypeConst param_type,
530  GNCSearchParamFcn fcn,
531  gpointer arg)
532 {
533  g_return_if_fail (param);
534  g_return_if_fail (param_type && *param_type);
535  g_return_if_fail (fcn);
536  g_return_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param));
537 
538  param->lookup_fcn = fcn;
539  param->lookup_arg = arg;
540  gnc_search_param_override_param_type (param, param_type);
541 }
542 
543 gboolean
544 gnc_search_param_has_param_fcn (GNCSearchParamSimple *param)
545 {
546  g_return_val_if_fail (param, FALSE);
547  g_return_val_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param), FALSE);
548 
549  if (param->lookup_fcn)
550  return TRUE;
551 
552  return FALSE;
553 }
554 
555 /* Compute the value of this parameter for this object */
556 gpointer
557 gnc_search_param_compute_value (GNCSearchParamSimple *param, gpointer object)
558 {
559  g_return_val_if_fail (param, NULL);
560  g_return_val_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param), NULL);
561 
562  if (param->lookup_fcn)
563  {
564  return ((param->lookup_fcn)(object, param->lookup_arg));
565  }
566  else
567  {
568  GSList *converters = gnc_search_param_get_converters (param);
569  gpointer res = object;
570 
571  /* Do all the object conversions */
572  for (; converters; converters = converters->next)
573  {
574  QofParam *qp = converters->data;
575  res = (qp->param_getfcn) (res, qp);
576  }
577  return res;
578  }
579 }
const gchar * QofIdTypeConst
QofIdTypeConst declaration.
Definition: qofid.h:82
const gchar * QofIdType
QofIdType declaration.
Definition: qofid.h:80
const QofParam * qof_class_get_parameter(QofIdTypeConst obj_name, const char *parameter)
Return the registered Parameter Definition for the requested parameter.
Definition: qofclass.cpp:136
All type declarations for the whole Gnucash engine.