Line data Source code
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-double.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_double_finalize (GObject *obj);
49 :
50 : struct _GNCSearchDouble
51 : {
52 : GNCSearchCoreType parent_instance;
53 :
54 : QofQueryCompare how;
55 : double value;
56 :
57 : GtkWidget * entry;
58 : GNCAmountEdit *gae;
59 : GtkWindow *parent;
60 : };
61 :
62 0 : G_DEFINE_TYPE(GNCSearchDouble, gnc_search_double, GNC_TYPE_SEARCH_CORE_TYPE)
63 :
64 : static void
65 0 : gnc_search_double_class_init (GNCSearchDoubleClass *klass)
66 : {
67 : GObjectClass *object_class;
68 0 : GNCSearchCoreTypeClass *gnc_search_core_type = (GNCSearchCoreTypeClass *)klass;
69 :
70 0 : object_class = G_OBJECT_CLASS (klass);
71 :
72 0 : object_class->finalize = gnc_search_double_finalize;
73 :
74 : /* override methods */
75 0 : gnc_search_core_type->pass_parent = pass_parent;
76 0 : gnc_search_core_type->editable_enters = editable_enters;
77 0 : gnc_search_core_type->grab_focus = grab_focus;
78 0 : gnc_search_core_type->validate = gncs_validate;
79 0 : gnc_search_core_type->get_widget = gncs_get_widget;
80 0 : gnc_search_core_type->get_predicate = gncs_get_predicate;
81 0 : gnc_search_core_type->clone = gncs_clone;
82 0 : }
83 :
84 : static void
85 0 : gnc_search_double_init (GNCSearchDouble *o)
86 : {
87 0 : o->how = QOF_COMPARE_EQUAL;
88 0 : }
89 :
90 : static void
91 0 : gnc_search_double_finalize (GObject *obj)
92 : {
93 0 : GNCSearchDouble *o = (GNCSearchDouble *)obj;
94 0 : g_assert (GNC_IS_SEARCH_DOUBLE (o));
95 :
96 0 : G_OBJECT_CLASS (gnc_search_double_parent_class)->finalize(obj);
97 0 : }
98 :
99 : /**
100 : * gnc_search_double_new:
101 : *
102 : * Create a new GNCSearchDouble object.
103 : *
104 : * Return value: A new #GNCSearchDouble object.
105 : **/
106 : GNCSearchDouble *
107 0 : gnc_search_double_new (void)
108 : {
109 0 : GNCSearchDouble *o = g_object_new(GNC_TYPE_SEARCH_DOUBLE, NULL);
110 0 : return o;
111 : }
112 :
113 : void
114 0 : gnc_search_double_set_value (GNCSearchDouble *fi, double value)
115 : {
116 0 : g_return_if_fail (fi);
117 0 : g_return_if_fail (GNC_IS_SEARCH_DOUBLE (fi));
118 :
119 0 : fi->value = value;
120 : }
121 :
122 : void
123 0 : gnc_search_double_set_how (GNCSearchDouble *fi, QofQueryCompare how)
124 : {
125 0 : g_return_if_fail (fi);
126 0 : g_return_if_fail (GNC_IS_SEARCH_DOUBLE (fi));
127 0 : fi->how = how;
128 : }
129 :
130 : static void
131 0 : pass_parent (GNCSearchCoreType *fe, gpointer parent)
132 : {
133 0 : GNCSearchDouble *fi = (GNCSearchDouble *)fe;
134 :
135 0 : g_return_if_fail (fi);
136 0 : g_return_if_fail (GNC_IS_SEARCH_DOUBLE (fi));
137 :
138 0 : fi->parent = GTK_WINDOW(parent);
139 : }
140 :
141 : static gboolean
142 0 : gncs_validate (GNCSearchCoreType *fe)
143 : {
144 0 : GNCSearchDouble *fi = (GNCSearchDouble *)fe;
145 0 : gboolean valid = TRUE;
146 0 : GError *error = NULL;
147 :
148 0 : g_return_val_if_fail (fi, FALSE);
149 0 : g_return_val_if_fail (GNC_IS_SEARCH_DOUBLE (fi), FALSE);
150 :
151 0 : if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT(fi->gae), &error))
152 : {
153 0 : gnc_error_dialog (GTK_WINDOW(fi->parent), "%s", error->message);
154 0 : valid = FALSE;
155 0 : g_error_free (error);
156 : }
157 :
158 0 : return valid;
159 : }
160 :
161 : static void
162 0 : entry_changed (GNCAmountEdit *entry, GNCSearchDouble *fe)
163 : {
164 0 : fe->value = gnc_amount_edit_get_damount (entry);
165 0 : }
166 :
167 : static GtkWidget *
168 0 : make_menu (GNCSearchCoreType *fe)
169 : {
170 0 : GNCSearchDouble *fi = (GNCSearchDouble *)fe;
171 : GtkComboBox *combo;
172 :
173 0 : combo = GTK_COMBO_BOX(gnc_combo_box_new_search());
174 :
175 0 : gnc_combo_box_search_add(combo, _("is less than"), QOF_COMPARE_LT);
176 0 : gnc_combo_box_search_add(combo, _("is less than or equal to"), QOF_COMPARE_LTE);
177 0 : gnc_combo_box_search_add(combo, _("equals"), QOF_COMPARE_EQUAL);
178 0 : gnc_combo_box_search_add(combo, _("does not equal"), QOF_COMPARE_NEQ);
179 0 : gnc_combo_box_search_add(combo, _("is greater than"), QOF_COMPARE_GT);
180 0 : gnc_combo_box_search_add(combo, _("is greater than or equal to"), QOF_COMPARE_GTE);
181 0 : gnc_combo_box_search_changed(combo, &fi->how);
182 0 : gnc_combo_box_search_set_active(combo, fi->how ? fi->how : QOF_COMPARE_LT);
183 :
184 0 : return GTK_WIDGET(combo);
185 : }
186 :
187 : static void
188 0 : grab_focus (GNCSearchCoreType *fe)
189 : {
190 0 : GNCSearchDouble *fi = (GNCSearchDouble *)fe;
191 :
192 0 : g_return_if_fail (fi);
193 0 : g_return_if_fail (GNC_IS_SEARCH_DOUBLE (fi));
194 :
195 0 : if (fi->entry)
196 0 : gtk_widget_grab_focus (fi->entry);
197 : }
198 :
199 : static void
200 0 : editable_enters (GNCSearchCoreType *fe)
201 : {
202 0 : GNCSearchDouble *fi = (GNCSearchDouble *)fe;
203 :
204 0 : g_return_if_fail (fi);
205 0 : g_return_if_fail (GNC_IS_SEARCH_DOUBLE (fi));
206 :
207 0 : if (fi->entry)
208 0 : gtk_entry_set_activates_default(GTK_ENTRY (fi->entry), TRUE);
209 : }
210 :
211 : static GtkWidget *
212 0 : gncs_get_widget (GNCSearchCoreType *fe)
213 : {
214 : GtkWidget *entry, *menu, *box;
215 0 : GNCSearchDouble *fi = (GNCSearchDouble *)fe;
216 :
217 0 : g_return_val_if_fail (fi, NULL);
218 0 : g_return_val_if_fail (GNC_IS_SEARCH_DOUBLE (fi), NULL);
219 :
220 0 : box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
221 0 : gtk_box_set_homogeneous (GTK_BOX (box), FALSE);
222 :
223 : /* Build and connect the option menu */
224 0 : menu = make_menu (fe);
225 0 : gtk_box_pack_start (GTK_BOX (box), menu, FALSE, FALSE, 3);
226 :
227 : /* Build and connect the entry window */
228 0 : entry = gnc_amount_edit_new ();
229 0 : if (fi->value)
230 0 : gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT (entry), fi->value);
231 0 : g_signal_connect (G_OBJECT (entry), "amount_changed", G_CALLBACK (entry_changed), fe);
232 0 : gtk_box_pack_start (GTK_BOX (box), entry, FALSE, FALSE, 3);
233 0 : fi->entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT (entry));
234 0 : fi->gae = GNC_AMOUNT_EDIT (entry);
235 :
236 : /* And return the box */
237 0 : return box;
238 : }
239 :
240 0 : static QofQueryPredData* gncs_get_predicate (GNCSearchCoreType *fe)
241 : {
242 0 : GNCSearchDouble *fi = (GNCSearchDouble *)fe;
243 :
244 0 : g_return_val_if_fail (fi, NULL);
245 0 : g_return_val_if_fail (GNC_IS_SEARCH_DOUBLE (fi), NULL);
246 :
247 : /* force the computation of the entry, because we may not get the signal */
248 0 : entry_changed (fi->gae, fi);
249 :
250 0 : return qof_query_double_predicate (fi->how, fi->value);
251 : }
252 :
253 0 : static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe)
254 : {
255 0 : GNCSearchDouble *se, *fse = (GNCSearchDouble *)fe;
256 :
257 0 : g_return_val_if_fail (fse, NULL);
258 0 : g_return_val_if_fail (GNC_IS_SEARCH_DOUBLE (fse), NULL);
259 :
260 0 : se = gnc_search_double_new ();
261 0 : gnc_search_double_set_value (se, fse->value);
262 0 : gnc_search_double_set_how (se, fse->how);
263 :
264 0 : return (GNCSearchCoreType *)se;
265 : }
|