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 
433  /* Maybe over-ride the type */
434  if (type_override)
435  gnc_search_param_override_param_type (p, type_override);
436 
437  /* And return it */
438  return g_list_prepend (list, p);
439 }
440 
441 
442 GList *
443 gnc_search_param_prepend_with_justify (GList *list, char const *title,
444  GtkJustification justify,
445  QofIdTypeConst type_override,
446  QofIdTypeConst search_type,
447  const char *param, ...)
448 {
449  GList *result;
450  va_list ap;
451 
452  g_return_val_if_fail (title, list);
453  g_return_val_if_fail (search_type, list);
454  g_return_val_if_fail (param, list);
455 
456  /* Build the parameter path */
457  va_start (ap, param);
458  result = gnc_search_param_prepend_internal (list, title, justify,
459  type_override, search_type,
460  param, ap);
461  va_end (ap);
462  return result;
463 }
464 
465 GList *
466 gnc_search_param_prepend (GList *list, char const *title,
467  QofIdTypeConst type_override,
468  QofIdTypeConst search_type,
469  const char *param, ...)
470 {
471  GList *result;
472  va_list ap;
473 
474  g_return_val_if_fail (title, list);
475  g_return_val_if_fail (search_type, list);
476  g_return_val_if_fail (param, list);
477 
478  /* Build the parameter path */
479  va_start (ap, param);
480  result = gnc_search_param_prepend_internal (list, title, GTK_JUSTIFY_LEFT,
481  type_override, search_type,
482  param, ap);
483  va_end (ap);
484  return result;
485 }
486 
487 GList *
488 gnc_search_param_prepend_compound (GList *list, char const *title,
489  GList *param_list,
490  GtkJustification justify,
491  GNCSearchParamKind kind)
492 {
493  GList *p;
494  QofIdTypeConst type = NULL;
495  GNCSearchParamCompound *param;
496  GNCSearchParamPrivate *basepriv;
497 
498  g_return_val_if_fail (title, list);
499  g_return_val_if_fail (param_list, list);
500  g_return_val_if_fail (kind == SEARCH_PARAM_ANY || kind == SEARCH_PARAM_ALL, list);
501 
502  /* "param_list" is a list of GNCSearchParamSimple. Make sure all the types are the same */
503  for (p = param_list; p; p = p->next)
504  {
505  GNCSearchParam *baseparam;
506  g_return_val_if_fail (GNC_IS_SEARCH_PARAM(p->data), list);
507  baseparam = GNC_SEARCH_PARAM(p->data);
508  if (!type)
509  type = gnc_search_param_get_param_type (baseparam);
510  else
511  g_return_val_if_fail (g_strcmp0 (type, gnc_search_param_get_param_type (baseparam)) == 0, list);
512  }
513 
514  param = gnc_search_param_compound_new ();
515  gnc_search_param_set_title (GNC_SEARCH_PARAM(param), title);
516  gnc_search_param_set_justify (GNC_SEARCH_PARAM(param), justify);
517 
518  basepriv = GNC_SEARCH_PARAM_GET_PRIVATE(param);
519  param->sub_search = g_list_copy (param_list);
520  basepriv->type = type;
521  param->kind = kind;
522 
523  return g_list_prepend (list, param);
524 }
525 
526 void
527 gnc_search_param_set_param_fcn (GNCSearchParamSimple *param,
528  QofIdTypeConst param_type,
529  GNCSearchParamFcn fcn,
530  gpointer arg)
531 {
532  g_return_if_fail (param);
533  g_return_if_fail (param_type && *param_type);
534  g_return_if_fail (fcn);
535  g_return_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param));
536 
537  param->lookup_fcn = fcn;
538  param->lookup_arg = arg;
539  gnc_search_param_override_param_type (param, param_type);
540 }
541 
542 gboolean
543 gnc_search_param_has_param_fcn (GNCSearchParamSimple *param)
544 {
545  g_return_val_if_fail (param, FALSE);
546  g_return_val_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param), FALSE);
547 
548  if (param->lookup_fcn)
549  return TRUE;
550 
551  return FALSE;
552 }
553 
554 /* Compute the value of this parameter for this object */
555 gpointer
556 gnc_search_param_compute_value (GNCSearchParamSimple *param, gpointer object)
557 {
558  g_return_val_if_fail (param, NULL);
559  g_return_val_if_fail (GNC_IS_SEARCH_PARAM_SIMPLE(param), NULL);
560 
561  if (param->lookup_fcn)
562  {
563  return ((param->lookup_fcn)(object, param->lookup_arg));
564  }
565  else
566  {
567  GSList *converters = gnc_search_param_get_converters (param);
568  gpointer res = object;
569 
570  /* Do all the object conversions */
571  for (; converters; converters = converters->next)
572  {
573  QofParam *qp = converters->data;
574  res = (qp->param_getfcn) (res, qp);
575  }
576  return res;
577  }
578 }
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.