GnuCash c935c2f+
Loading...
Searching...
No Matches
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
40static void pass_parent (GNCSearchCoreType *fe, gpointer parent);
41static void editable_enters (GNCSearchCoreType *fe);
42static void grab_focus (GNCSearchCoreType *fe);
43static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe);
44static gboolean gncs_validate (GNCSearchCoreType *fe);
45static GtkWidget *gncs_get_widget(GNCSearchCoreType *fe);
46static QofQueryPredData* gncs_get_predicate (GNCSearchCoreType *fe);
47
48static void gnc_search_numeric_finalize (GObject *obj);
49
51{
52 GNCSearchCoreType parent_instance;
53
55 gnc_numeric value;
56 QofNumericMatch option;
57
58 gboolean is_debcred;
59 GtkWidget * entry;
60 GNCAmountEdit *gae;
61 GtkWindow *parent;
62};
63
64G_DEFINE_TYPE(GNCSearchNumeric, gnc_search_numeric, GNC_TYPE_SEARCH_CORE_TYPE)
65
66static void
67gnc_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
86static void
87gnc_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
94static void
95gnc_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
110GNCSearchNumeric *
111gnc_search_numeric_new (void)
112{
113 GNCSearchNumeric *o = g_object_new(GNC_TYPE_SEARCH_NUMERIC, NULL);
114 return o;
115}
116
124GNCSearchNumeric *
125gnc_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
134void
135gnc_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
143void
144gnc_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
151void
152gnc_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
159static void
160pass_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
170static gboolean
171gncs_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
189static void
190entry_changed (GNCAmountEdit *entry, GNCSearchNumeric *fe)
191{
192 fe->value = gnc_amount_edit_get_amount (entry);
193}
194
195static GtkWidget *
196make_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
229static GtkWidget *
230make_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
245static void
246grab_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
257static void
258editable_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
269static GtkWidget *
270gncs_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
303static 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
316static 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}
QofNumericMatch
Comparisons for QOF_TYPE_NUMERIC, QOF_TYPE_DEBCRED.
QofQueryCompare
Standard Query comparators, for how to compare objects in a predicate.