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 "qof.h"
32 #include "gnc-ui-util.h"
33 #include "gnc-gui-query.h"
34 #include "gncOwner.h"
35
36 #include "business-gnome-utils.h"
37 #include "search-owner.h"
38 #include "search-core-utils.h"
39
40 #define d(x)
41
42 static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe);
43 static void pass_parent (GNCSearchCoreType *fe, gpointer parent);
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_owner_class_init (GNCSearchOwnerClass *klass);
49 static void gnc_search_owner_init (GNCSearchOwner *gspaper);
50 static void gnc_search_owner_finalize (GObject *obj);
51
52 typedef struct _GNCSearchOwnerPrivate
53 {
54 GncOwner owner;
55 GtkWindow * parent;
56 GtkWidget * owner_box;
57 GtkWidget * owner_choice;
58 } GNCSearchOwnerPrivate;
59
60 G_DEFINE_TYPE_WITH_PRIVATE(GNCSearchOwner, gnc_search_owner, GNC_TYPE_SEARCH_CORE_TYPE);
61
62 #define _PRIVATE(o) \
63 ((GNCSearchOwnerPrivate*)g_type_instance_get_private((GTypeInstance*)o, GNC_TYPE_SEARCH_OWNER))
64
65 static GNCSearchCoreTypeClass *parent_class;
66
67 enum
68 {
69 LAST_SIGNAL
70 };
71
72 #if LAST_SIGNAL > 0
73 static guint signals[LAST_SIGNAL] = { 0 };
74 #endif
75
76 static void
gnc_search_owner_class_init(GNCSearchOwnerClass * klass)77 gnc_search_owner_class_init (GNCSearchOwnerClass *klass)
78 {
79 GObjectClass *object_class;
80 GNCSearchCoreTypeClass *gnc_search_core_type = (GNCSearchCoreTypeClass *)klass;
81
82 object_class = G_OBJECT_CLASS (klass);
83 parent_class = g_type_class_peek_parent (klass);
84
85 object_class->finalize = gnc_search_owner_finalize;
86
87 /* override methods */
88 gnc_search_core_type->validate = gncs_validate;
89 gnc_search_core_type->pass_parent = pass_parent;
90 gnc_search_core_type->get_widget = gncs_get_widget;
91 gnc_search_core_type->get_predicate = gncs_get_predicate;
92 gnc_search_core_type->clone = gncs_clone;
93 }
94
95 static void
gnc_search_owner_init(GNCSearchOwner * o)96 gnc_search_owner_init (GNCSearchOwner *o)
97 {
98 }
99
100 static void
gnc_search_owner_finalize(GObject * obj)101 gnc_search_owner_finalize (GObject *obj)
102 {
103 g_assert (IS_GNCSEARCH_OWNER (obj));
104
105 G_OBJECT_CLASS (parent_class)->finalize(obj);
106 }
107
108 /**
109 * gnc_search_owner_new:
110 *
111 * Create a new GNCSearchOwner object.
112 *
113 * Return value: A new #GNCSearchOwner object.
114 **/
115 GNCSearchOwner *
gnc_search_owner_new(void)116 gnc_search_owner_new (void)
117 {
118 GNCSearchOwner *o = g_object_new(gnc_search_owner_get_type (), NULL);
119 return o;
120 }
121
122 static gboolean
gncs_validate(GNCSearchCoreType * fe)123 gncs_validate (GNCSearchCoreType *fe)
124 {
125 GNCSearchOwner *fi = (GNCSearchOwner *)fe;
126 GNCSearchOwnerPrivate *priv;
127 gboolean valid = TRUE;
128
129 g_return_val_if_fail (fi, FALSE);
130 g_return_val_if_fail (IS_GNCSEARCH_OWNER (fi), FALSE);
131
132 priv = _PRIVATE(fi);
133 if (priv->owner.owner.undefined == NULL)
134 {
135 valid = FALSE;
136 gnc_error_dialog (GTK_WINDOW(priv->parent), "%s", _("You have not selected an owner"));
137 }
138
139 /* XXX */
140
141 return valid;
142 }
143
144 static int
owner_changed_cb(GtkWidget * widget,gpointer data)145 owner_changed_cb (GtkWidget *widget, gpointer data)
146 {
147 GNCSearchOwner *fe = data;
148 GNCSearchOwnerPrivate *priv;
149
150 priv = _PRIVATE(fe);
151 gnc_owner_get_owner (priv->owner_choice, &(priv->owner));
152 return FALSE;
153 }
154
155 static void
set_owner_widget(GNCSearchOwner * fe)156 set_owner_widget (GNCSearchOwner *fe)
157 {
158 GNCSearchOwnerPrivate *priv;
159
160 /* Remove the old choice widget */
161 priv = _PRIVATE(fe);
162 if (priv->owner_choice)
163 gtk_container_remove (GTK_CONTAINER (priv->owner_box), priv->owner_choice);
164
165 /* Create a new choice widget */
166 priv->owner_choice =
167 gnc_owner_select_create (NULL, priv->owner_box,
168 gnc_get_current_book(), &(priv->owner));
169
170 /* Setup the "changed" callback */
171 g_signal_connect (G_OBJECT (priv->owner_choice), "changed",
172 G_CALLBACK (owner_changed_cb), fe);
173
174 gtk_widget_show_all (priv->owner_choice);
175 }
176
177 static void
type_combo_changed(GtkWidget * widget,GNCSearchOwner * fe)178 type_combo_changed (GtkWidget *widget, GNCSearchOwner *fe)
179 {
180 GNCSearchOwnerPrivate *priv;
181 GncOwnerType type;
182
183 g_return_if_fail(GTK_IS_COMBO_BOX(widget));
184
185 type = gnc_combo_box_search_get_active(GTK_COMBO_BOX(widget));
186
187 /* If the type changed or if we don't have a type create the owner_choice */
188 priv = _PRIVATE(fe);
189 if (type != gncOwnerGetType (&(priv->owner)))
190 {
191 priv->owner.type = type;
192 priv->owner.owner.undefined = NULL;
193 set_owner_widget (fe);
194 }
195 else if (priv->owner_choice == NULL)
196 set_owner_widget (fe);
197 }
198
199 static GtkWidget *
make_type_menu(GNCSearchCoreType * fe)200 make_type_menu (GNCSearchCoreType *fe)
201 {
202 GNCSearchOwner *fi = (GNCSearchOwner *)fe;
203 GNCSearchOwnerPrivate *priv;
204 GtkComboBox *combo;
205 GncOwnerType type;
206
207 priv = _PRIVATE(fi);
208 type = gncOwnerGetType (&(priv->owner));
209
210 combo = GTK_COMBO_BOX(gnc_combo_box_new_search());
211 gnc_combo_box_search_add(combo, _("Customer"), GNC_OWNER_CUSTOMER);
212 gnc_combo_box_search_add(combo, _("Vendor"), GNC_OWNER_VENDOR);
213 gnc_combo_box_search_add(combo, _("Employee"), GNC_OWNER_EMPLOYEE);
214 gnc_combo_box_search_add(combo, _("Job"), GNC_OWNER_JOB);
215
216 g_signal_connect (combo, "changed", G_CALLBACK (type_combo_changed), fe);
217 gnc_combo_box_search_set_active(combo, type);
218
219 return GTK_WIDGET(combo);
220
221
222 }
223
224 static GtkWidget *
make_how_menu(GNCSearchCoreType * fe)225 make_how_menu (GNCSearchCoreType *fe)
226 {
227 GNCSearchOwner *fi = (GNCSearchOwner *)fe;
228 GtkComboBox *combo;
229
230 combo = GTK_COMBO_BOX(gnc_combo_box_new_search());
231 gnc_combo_box_search_add(combo, _("is"), QOF_GUID_MATCH_ANY);
232 gnc_combo_box_search_add(combo, _("is not"), QOF_GUID_MATCH_NONE);
233 gnc_combo_box_search_changed(combo, &fi->how);
234 gnc_combo_box_search_set_active(combo, fi->how ? fi->how : QOF_GUID_MATCH_ANY);
235
236 return GTK_WIDGET(combo);
237 }
238
239 static void
pass_parent(GNCSearchCoreType * fe,gpointer parent)240 pass_parent (GNCSearchCoreType *fe, gpointer parent)
241 {
242 GNCSearchOwner *fi = (GNCSearchOwner *)fe;
243 GNCSearchOwnerPrivate *priv;
244
245 g_return_if_fail (fi);
246 g_return_if_fail (IS_GNCSEARCH_OWNER (fi));
247
248 priv = _PRIVATE(fi);
249 priv->parent = GTK_WINDOW(parent);
250 }
251
252 static GtkWidget *
gncs_get_widget(GNCSearchCoreType * fe)253 gncs_get_widget (GNCSearchCoreType *fe)
254 {
255 GtkWidget *how_menu, *type_menu, *box;
256 GNCSearchOwner *fi = (GNCSearchOwner *)fe;
257 GNCSearchOwnerPrivate *priv;
258
259 g_return_val_if_fail (fi, NULL);
260 g_return_val_if_fail (IS_GNCSEARCH_OWNER (fi), NULL);
261
262 priv = _PRIVATE(fi);
263 box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
264 gtk_box_set_homogeneous (GTK_BOX (box), FALSE);
265
266 /* Build and connect the "how" option menu. */
267 how_menu = make_how_menu (fe);
268 gtk_box_pack_start (GTK_BOX (box), how_menu, FALSE, FALSE, 3);
269
270 /* Create the owner box */
271 priv->owner_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
272 gtk_box_set_homogeneous (GTK_BOX (priv->owner_box), FALSE);
273
274 /* Build and connect the "type" option menu.
275 * Note that this will build the owner_choice and
276 * put it in the owner_box we just created.
277 */
278 type_menu = make_type_menu (fe);
279 gtk_box_pack_start (GTK_BOX (box), type_menu, FALSE, FALSE, 3);
280
281 /* connect the owner box */
282 gtk_box_pack_start (GTK_BOX (box), priv->owner_box, FALSE, FALSE, 3);
283
284 /* And return the box */
285 return box;
286 }
287
gncs_get_predicate(GNCSearchCoreType * fe)288 static QofQueryPredData* gncs_get_predicate (GNCSearchCoreType *fe)
289 {
290 GNCSearchOwner *fi = (GNCSearchOwner *)fe;
291 GNCSearchOwnerPrivate *priv;
292 const GncGUID *guid;
293 GList *l = NULL;
294
295 g_return_val_if_fail (fi, NULL);
296 g_return_val_if_fail (IS_GNCSEARCH_OWNER (fi), NULL);
297
298 priv = _PRIVATE(fi);
299 guid = gncOwnerGetGUID (&(priv->owner));
300 l = g_list_prepend (l, (gpointer)guid);
301
302 return qof_query_guid_predicate (fi->how, l);
303 }
304
gncs_clone(GNCSearchCoreType * fe)305 static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe)
306 {
307 GNCSearchOwner *se, *fse = (GNCSearchOwner *)fe;
308 GNCSearchOwnerPrivate *se_priv, *fse_priv;
309
310 g_return_val_if_fail (fse, NULL);
311 g_return_val_if_fail (IS_GNCSEARCH_OWNER (fse), NULL);
312
313 se = gnc_search_owner_new ();
314 se->how = fse->how;
315 se_priv = _PRIVATE(se);
316 fse_priv = _PRIVATE(fse);
317 gncOwnerCopy (&(fse_priv->owner), &(se_priv->owner));
318
319 return (GNCSearchCoreType *)se;
320 }
321