GnuCash  5.6-150-g038405b370+
search-numeric.c
1 /*
2  * Copyright (C) 2002 Derek Atkins
3  *
4  * Authors: Derek Atkins <warlord@MIT.EDU>
5  *
6  * Copyright (c) 2006 David Hampton <hampton@employees.org>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public
19  * License along with this program; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 #include <gtk/gtk.h>
29 #include <glib/gi18n.h>
30 
31 #include "gnc-amount-edit.h"
32 #include "qof.h"
33 #include "gnc-gui-query.h"
34 
35 #include "search-numeric.h"
36 #include "search-core-utils.h"
37 
38 #define d(x)
39 
40 static void pass_parent (GNCSearchCoreType *fe, gpointer parent);
41 static void editable_enters (GNCSearchCoreType *fe);
42 static void grab_focus (GNCSearchCoreType *fe);
43 static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe);
44 static gboolean gncs_validate (GNCSearchCoreType *fe);
45 static GtkWidget *gncs_get_widget(GNCSearchCoreType *fe);
46 static QofQueryPredData* gncs_get_predicate (GNCSearchCoreType *fe);
47 
48 static void gnc_search_numeric_finalize (GObject *obj);
49 
51 {
52  GNCSearchCoreType parent_instance;
53 
54  QofQueryCompare how;
55  gnc_numeric value;
56  QofNumericMatch option;
57 
58  gboolean is_debcred;
59  GtkWidget * entry;
60  GNCAmountEdit *gae;
61  GtkWindow *parent;
62 };
63 
64 G_DEFINE_TYPE(GNCSearchNumeric, gnc_search_numeric, GNC_TYPE_SEARCH_CORE_TYPE)
65 
66 static void
67 gnc_search_numeric_class_init (GNCSearchNumericClass *klass)
68 {
69  GObjectClass *object_class;
70  GNCSearchCoreTypeClass *gnc_search_core_type = (GNCSearchCoreTypeClass *)klass;
71 
72  object_class = G_OBJECT_CLASS (klass);
73 
74  object_class->finalize = gnc_search_numeric_finalize;
75 
76  /* override methods */
77  gnc_search_core_type->pass_parent = pass_parent;
78  gnc_search_core_type->editable_enters = editable_enters;
79  gnc_search_core_type->grab_focus = grab_focus;
80  gnc_search_core_type->validate = gncs_validate;
81  gnc_search_core_type->get_widget = gncs_get_widget;
82  gnc_search_core_type->get_predicate = gncs_get_predicate;
83  gnc_search_core_type->clone = gncs_clone;
84 }
85 
86 static void
87 gnc_search_numeric_init (GNCSearchNumeric *o)
88 {
89  o->value = gnc_numeric_zero ();
90  o->how = QOF_COMPARE_EQUAL;
91  o->option = QOF_NUMERIC_MATCH_ANY;
92 }
93 
94 static void
95 gnc_search_numeric_finalize (GObject *obj)
96 {
97  GNCSearchNumeric *o = (GNCSearchNumeric *)obj;
98  g_assert (GNC_IS_SEARCH_NUMERIC (o));
99 
100  G_OBJECT_CLASS (gnc_search_numeric_parent_class)->finalize(obj);
101 }
102 
110 GNCSearchNumeric *
111 gnc_search_numeric_new (void)
112 {
113  GNCSearchNumeric *o = g_object_new(GNC_TYPE_SEARCH_NUMERIC, NULL);
114  return o;
115 }
116 
124 GNCSearchNumeric *
125 gnc_search_numeric_debcred_new (void)
126 {
127  GNCSearchNumeric *o;
128 
129  o = g_object_new(GNC_TYPE_SEARCH_NUMERIC, NULL);
130  o->is_debcred = TRUE;
131  return o;
132 }
133 
134 void
135 gnc_search_numeric_set_value (GNCSearchNumeric *fi, gnc_numeric value)
136 {
137  g_return_if_fail (fi);
138  g_return_if_fail (GNC_IS_SEARCH_NUMERIC (fi));
139 
140  fi->value = value;
141 }
142 
143 void
144 gnc_search_numeric_set_how (GNCSearchNumeric *fi, QofQueryCompare how)
145 {
146  g_return_if_fail (fi);
147  g_return_if_fail (GNC_IS_SEARCH_NUMERIC (fi));
148  fi->how = how;
149 }
150 
151 void
152 gnc_search_numeric_set_option (GNCSearchNumeric *fi, QofNumericMatch option)
153 {
154  g_return_if_fail (fi);
155  g_return_if_fail (GNC_IS_SEARCH_NUMERIC (fi));
156  fi->option = option;
157 }
158 
159 static void
160 pass_parent (GNCSearchCoreType *fe, gpointer parent)
161 {
162  GNCSearchNumeric *fi = (GNCSearchNumeric *)fe;
163 
164  g_return_if_fail (fi);
165  g_return_if_fail (GNC_IS_SEARCH_NUMERIC (fi));
166 
167  fi->parent = GTK_WINDOW(parent);
168 }
169 
170 static gboolean
171 gncs_validate (GNCSearchCoreType *fe)
172 {
173  GNCSearchNumeric *fi = (GNCSearchNumeric *)fe;
174  gboolean valid = TRUE;
175  GError *error = NULL;
176 
177  g_return_val_if_fail (fi, FALSE);
178  g_return_val_if_fail (GNC_IS_SEARCH_NUMERIC (fi), FALSE);
179 
180  if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT(fi->gae), &error))
181  {
182  gnc_error_dialog (GTK_WINDOW(fi->parent), "%s", error->message);
183  valid = FALSE;
184  g_error_free (error);
185  }
186  return valid;
187 }
188 
189 static void
190 entry_changed (GNCAmountEdit *entry, GNCSearchNumeric *fe)
191 {
192  fe->value = gnc_amount_edit_get_amount (entry);
193 }
194 
195 static GtkWidget *
196 make_how_menu (GNCSearchCoreType *fe)
197 {
198  GNCSearchNumeric *fi = (GNCSearchNumeric *)fe;
199  GtkComboBox *combo;
200 
201  combo = GTK_COMBO_BOX(gnc_combo_box_new_search());
202  gnc_combo_box_search_add(combo, (fi->is_debcred ?
203  _("less than") : _("is less than")),
204  QOF_COMPARE_LT);
205  gnc_combo_box_search_add(combo, (fi->is_debcred ?
206  _("less than or equal to") :
207  _("is less than or equal to")),
208  QOF_COMPARE_LTE);
209  gnc_combo_box_search_add(combo, (fi->is_debcred ?
210  _("equal to") : _("equals")),
211  QOF_COMPARE_EQUAL);
212  gnc_combo_box_search_add(combo, (fi->is_debcred ?
213  _("not equal to") : _("does not equal")),
214  QOF_COMPARE_NEQ);
215  gnc_combo_box_search_add(combo, (fi->is_debcred ?
216  _("greater than") : _("is greater than")),
217  QOF_COMPARE_GT);
218  gnc_combo_box_search_add(combo, (fi->is_debcred ?
219  _("greater than or equal to") :
220  _("is greater than or equal to")),
221  QOF_COMPARE_GTE);
222 
223  gnc_combo_box_search_changed(combo, &fi->how);
224  gnc_combo_box_search_set_active(combo, fi->how ? fi->how : QOF_COMPARE_LT);
225 
226  return GTK_WIDGET(combo);
227 }
228 
229 static GtkWidget *
230 make_option_menu (GNCSearchCoreType *fe)
231 {
232  GNCSearchNumeric *fi = (GNCSearchNumeric *)fe;
233  GtkComboBox *combo;
234 
235  combo = GTK_COMBO_BOX(gnc_combo_box_new_search());
236  gnc_combo_box_search_add(combo, _("has credits or debits"), QOF_NUMERIC_MATCH_ANY);
237  gnc_combo_box_search_add(combo, _("has debits"), QOF_NUMERIC_MATCH_DEBIT);
238  gnc_combo_box_search_add(combo, _("has credits"), QOF_NUMERIC_MATCH_CREDIT);
239  gnc_combo_box_search_changed(combo, &fi->option);
240  gnc_combo_box_search_set_active(combo, fi->option ? fi->option : QOF_NUMERIC_MATCH_ANY);
241 
242  return GTK_WIDGET(combo);
243 }
244 
245 static void
246 grab_focus (GNCSearchCoreType *fe)
247 {
248  GNCSearchNumeric *fi = (GNCSearchNumeric *)fe;
249 
250  g_return_if_fail (fi);
251  g_return_if_fail (GNC_IS_SEARCH_NUMERIC (fi));
252 
253  if (fi->entry)
254  gtk_widget_grab_focus (fi->entry);
255 }
256 
257 static void
258 editable_enters (GNCSearchCoreType *fe)
259 {
260  GNCSearchNumeric *fi = (GNCSearchNumeric *)fe;
261 
262  g_return_if_fail (fi);
263  g_return_if_fail (GNC_IS_SEARCH_NUMERIC (fi));
264 
265  if (fi->entry)
266  gtk_entry_set_activates_default(GTK_ENTRY (fi->entry), TRUE);
267 }
268 
269 static GtkWidget *
270 gncs_get_widget (GNCSearchCoreType *fe)
271 {
272  GtkWidget *entry, *menu, *box;
273  GNCSearchNumeric *fi = (GNCSearchNumeric *)fe;
274 
275  g_return_val_if_fail (fi, NULL);
276  g_return_val_if_fail (GNC_IS_SEARCH_NUMERIC (fi), NULL);
277 
278  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
279  gtk_box_set_homogeneous (GTK_BOX (box), FALSE);
280 
281  /* Build and connect the option menu(s) */
282  if (fi->is_debcred)
283  {
284  menu = make_option_menu (fe);
285  gtk_box_pack_start (GTK_BOX (box), menu, FALSE, FALSE, 3);
286  }
287 
288  menu = make_how_menu (fe);
289  gtk_box_pack_start (GTK_BOX (box), menu, FALSE, FALSE, 3);
290 
291  /* Build and connect the entry window */
292  entry = gnc_amount_edit_new ();
293  gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (entry), fi->value);
294  g_signal_connect (G_OBJECT (entry), "amount_changed", G_CALLBACK (entry_changed), fe);
295  gtk_box_pack_start (GTK_BOX (box), entry, FALSE, FALSE, 3);
296  fi->gae = GNC_AMOUNT_EDIT (entry);
297  fi->entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT (entry));
298 
299  /* And return the box */
300  return box;
301 }
302 
303 static QofQueryPredData* gncs_get_predicate (GNCSearchCoreType *fe)
304 {
305  GNCSearchNumeric *fi = (GNCSearchNumeric *)fe;
306 
307  g_return_val_if_fail (fi, NULL);
308  g_return_val_if_fail (GNC_IS_SEARCH_NUMERIC (fi), NULL);
309 
310  /* force the computation of the entry, because we may not get the signal */
311  entry_changed (fi->gae, fi);
312 
313  return qof_query_numeric_predicate (fi->how, fi->option, fi->value);
314 }
315 
316 static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe)
317 {
318  GNCSearchNumeric *se, *fse = (GNCSearchNumeric *)fe;
319 
320  g_return_val_if_fail (fse, NULL);
321  g_return_val_if_fail (GNC_IS_SEARCH_NUMERIC (fse), NULL);
322 
323  se = gnc_search_numeric_new ();
324  gnc_search_numeric_set_value (se, fse->value);
325  gnc_search_numeric_set_how (se, fse->how);
326  gnc_search_numeric_set_option (se, fse->option);
327  se->is_debcred = fse->is_debcred;
328 
329  return (GNCSearchCoreType *)se;
330 }
QofQueryCompare
Standard Query comparators, for how to compare objects in a predicate.
Definition: qofquerycore.h:54
QofNumericMatch
Comparisons for QOF_TYPE_NUMERIC, QOF_TYPE_DEBCRED.
Definition: qofquerycore.h:101