GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
search-account.c
1 /*
2  * Copyright (C) 2002 Derek Atkins
3  *
4  * Authors: Derek Atkins <[email protected]>
5  *
6  * Copyright (c) 2006 David Hampton <[email protected]>
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 "Account.h"
32 #include "qof.h"
33 #include "gnc-tree-view-account.h"
34 #include "gnc-gui-query.h"
35 
36 #include "search-account.h"
37 #include "search-core-utils.h"
38 
39 #define d(x)
40 
41 static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe);
42 static gboolean gncs_validate (GNCSearchCoreType *fe);
43 static GtkWidget *gncs_get_widget(GNCSearchCoreType *fe);
44 static QofQueryPredData* gncs_get_predicate (GNCSearchCoreType *fe);
45 
46 static void gnc_search_account_class_init (GNCSearchAccountClass *klass);
47 static void gnc_search_account_init (GNCSearchAccount *gspaper);
48 static void gnc_search_account_finalize (GObject *obj);
49 
51 
53 {
54  gboolean match_all;
55  GList * selected_accounts;
56 };
57 
58 #define _PRIVATE(o) \
59  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_SEARCH_ACCOUNT, GNCSearchAccountPrivate))
60 
61 static GNCSearchCoreTypeClass *parent_class;
62 
63 
64 GType
65 gnc_search_account_get_type (void)
66 {
67  static GType type = 0;
68 
69  if (!type)
70  {
71  GTypeInfo type_info =
72  {
73  sizeof(GNCSearchAccountClass), /* class_size */
74  NULL, /* base_init */
75  NULL, /* base_finalize */
76  (GClassInitFunc)gnc_search_account_class_init,
77  NULL, /* class_finalize */
78  NULL, /* class_data */
79  sizeof(GNCSearchAccount), /* */
80  0, /* n_preallocs */
81  (GInstanceInitFunc)gnc_search_account_init,
82  };
83 
84  type = g_type_register_static (GNC_TYPE_SEARCH_CORE_TYPE,
85  "GNCSearchAccount",
86  &type_info, 0);
87  }
88 
89  return type;
90 }
91 
92 static void
93 gnc_search_account_class_init (GNCSearchAccountClass *klass)
94 {
95  GObjectClass *object_class;
96  GNCSearchCoreTypeClass *gnc_search_core_type = (GNCSearchCoreTypeClass *)klass;
97 
98  object_class = G_OBJECT_CLASS (klass);
99  parent_class = g_type_class_peek_parent (klass);
100 
101  object_class->finalize = gnc_search_account_finalize;
102 
103  /* override methods */
104  gnc_search_core_type->validate = gncs_validate;
105  gnc_search_core_type->get_widget = gncs_get_widget;
106  gnc_search_core_type->get_predicate = gncs_get_predicate;
107  gnc_search_core_type->clone = gncs_clone;
108 
109  g_type_class_add_private(klass, sizeof(GNCSearchAccountPrivate));
110 }
111 
112 static void
113 gnc_search_account_init (GNCSearchAccount *o)
114 {
115  o->how = QOF_GUID_MATCH_ANY;
116 }
117 
118 static void
119 gnc_search_account_finalize (GObject *obj)
120 {
122  g_assert (IS_GNCSEARCH_ACCOUNT (o));
123 
124  G_OBJECT_CLASS (parent_class)->finalize(obj);
125 }
126 
135 gnc_search_account_new (void)
136 {
137  GNCSearchAccount *o = g_object_new(GNC_TYPE_SEARCH_ACCOUNT, NULL);
138  return o;
139 }
140 
149 gnc_search_account_matchall_new (void)
150 {
151  GNCSearchAccount *o;
153 
154  o = g_object_new(GNC_TYPE_SEARCH_ACCOUNT, NULL);
155  priv = _PRIVATE(o);
156  priv->match_all = TRUE;
157  o->how = QOF_GUID_MATCH_ALL;
158  return o;
159 }
160 
161 static gboolean
162 gncs_validate (GNCSearchCoreType *fe)
163 {
166  gboolean valid = TRUE;
167 
168  g_return_val_if_fail (fi, FALSE);
169  g_return_val_if_fail (IS_GNCSEARCH_ACCOUNT (fi), FALSE);
170 
171  priv = _PRIVATE(fi);
172  if (priv->selected_accounts == NULL && fi->how )
173  {
174  valid = FALSE;
175  gnc_error_dialog (NULL, "%s", _("You have not selected any accounts"));
176  }
177 
178  /* XXX */
179 
180  return valid;
181 }
182 
183 static GtkWidget *
184 make_menu (GNCSearchCoreType *fe)
185 {
188  GtkComboBox *combo;
189  int initial = 0;
190 
191  combo = GTK_COMBO_BOX(gnc_combo_box_new_search());
192 
193  priv = _PRIVATE(fi);
194  if (priv->match_all)
195  {
196  gnc_combo_box_search_add(combo, _("matches all accounts"), QOF_GUID_MATCH_ALL);
197  initial = QOF_GUID_MATCH_ALL;
198  }
199  else
200  {
201  gnc_combo_box_search_add(combo, _("matches any account"), QOF_GUID_MATCH_ANY);
202  gnc_combo_box_search_add(combo, _("matches no accounts"), QOF_GUID_MATCH_NONE);
203  initial = QOF_GUID_MATCH_ANY;
204  }
205 
206  gnc_combo_box_search_changed(combo, &fi->how);
207  gnc_combo_box_search_set_active(combo, fi->how ? fi->how : initial);
208 
209  return GTK_WIDGET(combo);
210 }
211 
212 static char *
213 describe_button (GNCSearchAccount *fi)
214 {
216 
217  priv = _PRIVATE(fi);
218  if (priv->selected_accounts)
219  return (_("Selected Accounts"));
220  return (_("Choose Accounts"));
221 }
222 
223 static void
224 button_clicked (GtkButton *button, GNCSearchAccount *fi)
225 {
227  GtkDialog *dialog;
228  GtkWidget *account_tree;
229  GtkWidget *accounts_scroller;
230  GtkWidget *label;
231  char *desc;
232  GtkTreeSelection *selection;
233 
234  /* Create the account tree */
235  account_tree = GTK_WIDGET(gnc_tree_view_account_new (FALSE));
236  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(account_tree), FALSE);
237  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(account_tree));
238  gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
239 
240  /* Select the currently-selected accounts */
241  priv = _PRIVATE(fi);
242  if (priv->selected_accounts)
243  gnc_tree_view_account_set_selected_accounts (GNC_TREE_VIEW_ACCOUNT(account_tree),
244  priv->selected_accounts, FALSE);
245 
246  /* Create the account scroller and put the tree in it */
247  accounts_scroller = gtk_scrolled_window_new (NULL, NULL);
248  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(accounts_scroller),
249  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
250  gtk_container_add(GTK_CONTAINER(accounts_scroller), account_tree);
251  gtk_widget_set_size_request(GTK_WIDGET(accounts_scroller), 300, 300);
252 
253  /* Create the label */
254  label = gtk_label_new (_("Select Accounts to Match"));
255 
256  /* Create the dialog */
257  dialog =
258  GTK_DIALOG(gtk_dialog_new_with_buttons(_("Select the Accounts to Compare"),
259  NULL,
260  0,
261  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
262  GTK_STOCK_OK, GTK_RESPONSE_OK,
263  NULL));
264 
265  /* Put the dialog together */
266  gtk_box_pack_start ((GtkBox *)dialog->vbox, label,
267  FALSE, FALSE, 3);
268  gtk_box_pack_start ((GtkBox *)dialog->vbox, accounts_scroller,
269  TRUE, TRUE, 3);
270 
271  gtk_widget_show_all (GTK_WIDGET (dialog));
272 
273  /* Now run the dialog */
274  if (gtk_dialog_run (dialog) == GTK_RESPONSE_OK)
275  {
276  if (priv->selected_accounts)
277  g_list_free (priv->selected_accounts);
278 
279  priv->selected_accounts =
280  gnc_tree_view_account_get_selected_accounts (GNC_TREE_VIEW_ACCOUNT (account_tree));
281 
282  desc = describe_button (fi);
283  gtk_label_set_text (GTK_LABEL (GTK_BIN (button)->child), desc);
284  }
285 
286  gtk_widget_destroy (GTK_WIDGET (dialog));
287 }
288 
289 static GtkWidget *
290 gncs_get_widget (GNCSearchCoreType *fe)
291 {
292  GtkWidget *button, *label, *menu, *box;
294  char *desc;
295 
296  g_return_val_if_fail (fi, NULL);
297  g_return_val_if_fail (IS_GNCSEARCH_ACCOUNT (fi), NULL);
298 
299  box = gtk_hbox_new (FALSE, 3);
300 
301  /* Build and connect the option menu */
302  menu = make_menu (fe);
303  gtk_box_pack_start (GTK_BOX (box), menu, FALSE, FALSE, 3);
304 
305  /* Build and connect the account entry window */
306  desc = describe_button (fi);
307  label = gtk_label_new (desc);
308  gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
309 
310  button = gtk_button_new ();
311  gtk_container_add (GTK_CONTAINER (button), label);
312  g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (button_clicked), fe);
313  gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);
314 
315  /* And return the box */
316  return box;
317 }
318 
319 static QofQueryPredData* gncs_get_predicate (GNCSearchCoreType *fe)
320 {
323  GList *l = NULL, *node;
324 
325  g_return_val_if_fail (fi, NULL);
326  g_return_val_if_fail (IS_GNCSEARCH_ACCOUNT (fi), NULL);
327 
328  priv = _PRIVATE(fi);
329  for (node = priv->selected_accounts; node; node = node->next)
330  {
331  Account *acc = node->data;
332  const GncGUID *guid = xaccAccountGetGUID (acc);
333  l = g_list_prepend (l, (gpointer)guid);
334  }
335  l = g_list_reverse (l);
336 
337  return qof_query_guid_predicate (fi->how, l);
338 }
339 
340 static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe)
341 {
342  GNCSearchAccount *se, *fse = (GNCSearchAccount *)fe;
343  GNCSearchAccountPrivate *se_priv, *fse_priv;
344 
345  g_return_val_if_fail (fse, NULL);
346  g_return_val_if_fail (IS_GNCSEARCH_ACCOUNT (fse), NULL);
347  fse_priv = _PRIVATE(fse);
348 
349  se = gnc_search_account_new ();
350  se_priv = _PRIVATE(se);
351  se->how = fse->how;
352  se_priv->match_all = fse_priv->match_all;
353  se_priv->selected_accounts = g_list_copy (fse_priv->selected_accounts);
354 
355  return (GNCSearchCoreType *)se;
356 }
GList * gnc_tree_view_account_get_selected_accounts(GncTreeViewAccount *view)
void gnc_tree_view_account_set_selected_accounts(GncTreeViewAccount *view, GList *account_list, gboolean show_last)
Definition: guid.h:65
#define xaccAccountGetGUID(X)
Definition: Account.h:239
Account handling public routines.
GtkTreeView implementation for gnucash account tree.
GtkTreeView * gnc_tree_view_account_new(gboolean show_root)