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