1 /********************************************************************\
2  * dialog-find-account.c -- Find Account dialog                     *
3  * Copyright (C) 2016 Robert Fewell                                 *
4  *                                                                  *
5  * This program is free software; you can redistribute it and/or    *
6  * modify it under the terms of the GNU General Public License as   *
7  * published by the Free Software Foundation; either version 2 of   *
8  * the License, or (at your option) any later version.              *
9  *                                                                  *
10  * This program is distributed in the hope that it will be useful,  *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
13  * GNU General Public License for more details.                     *
14  *                                                                  *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact:                        *
17  *                                                                  *
18  * Free Software Foundation           Voice:  +1-617-542-5942       *
19  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
20  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
21 \********************************************************************/
22 
23 #include <config.h>
24 
25 #include <gtk/gtk.h>
26 #include <glib/gi18n.h>
27 
28 #include "dialog-find-account.h"
29 
30 #include "dialog-utils.h"
31 #include "gnc-component-manager.h"
32 #include "gnc-session.h"
33 
34 #include "gnc-ui-util.h"
35 #include "Account.h"
36 #include "gnc-plugin-page-account-tree.h"
37 #include "dialog-account.h"
38 
39 #define DIALOG_FIND_ACCOUNT_CM_CLASS    "dialog-find-account"
40 #define GNC_PREFS_GROUP                 "dialogs.find-account"
41 
42 /** Enumeration for the tree-store */
43 enum GncFindAccountColumn {ACC_FULL_NAME, ACCOUNT, PLACE_HOLDER, HIDDEN, NOT_USED, BAL_ZERO, TAX};
44 
45 typedef struct
46 {
47     GtkWidget    *window;
48     GtkWidget    *parent;
49     QofSession   *session;
50     Account      *account;
51     GtkWidget    *view;
52 
53     GtkWidget    *radio_frame;
54     GtkWidget    *radio_root;
55     GtkWidget    *radio_subroot;
56 
57     GtkWidget    *filter_button;
58     GtkWidget    *filter_text_entry;
59     GtkWidget    *sub_label;
60 
61     gboolean      jump_close;
62     gchar        *saved_filter_text;
63     gint          event_handler_id;
64 
65 }FindAccountDialog;
66 
67 /* This static indicates the debugging module that this .o belongs to.  */
68 static QofLogModule log_module = GNC_MOD_GUI;
69 
70 static void close_handler (gpointer user_data);
71 
72 static gboolean
gnc_find_account_dialog_window_delete_event_cb(GtkWidget * widget,GdkEvent * event,gpointer user_data)73 gnc_find_account_dialog_window_delete_event_cb (GtkWidget *widget,
74                                                 GdkEvent  *event,
75                                                 gpointer   user_data)
76 {
77     FindAccountDialog *facc_dialog = user_data;
78     // this cb allows the window size to be saved on closing with the X
79     gnc_save_window_size (GNC_PREFS_GROUP,
80                           GTK_WINDOW(facc_dialog->window));
81     return FALSE;
82 }
83 
84 static void
gnc_find_account_dialog_window_destroy_cb(GtkWidget * object,gpointer user_data)85 gnc_find_account_dialog_window_destroy_cb (GtkWidget *object, gpointer user_data)
86 {
87     FindAccountDialog *facc_dialog = user_data;
88 
89     ENTER(" ");
90     gnc_unregister_gui_component_by_data (DIALOG_FIND_ACCOUNT_CM_CLASS, facc_dialog);
91 
92     if (facc_dialog->event_handler_id)
93     {
94         qof_event_unregister_handler (facc_dialog->event_handler_id);
95         facc_dialog->event_handler_id = 0;
96     }
97 
98     if (facc_dialog->saved_filter_text)
99         g_free (facc_dialog->saved_filter_text);
100 
101     if (facc_dialog->window)
102     {
103         gtk_widget_destroy (facc_dialog->window);
104         facc_dialog->window = NULL;
105     }
106     g_free (facc_dialog);
107     LEAVE(" ");
108 }
109 
110 static gboolean
gnc_find_account_dialog_window_key_press_cb(GtkWidget * widget,GdkEventKey * event,gpointer user_data)111 gnc_find_account_dialog_window_key_press_cb (GtkWidget *widget,
112                                              GdkEventKey *event,
113                                              gpointer user_data)
114 {
115     FindAccountDialog *facc_dialog = user_data;
116 
117     if (event->keyval == GDK_KEY_Escape)
118     {
119         close_handler (facc_dialog);
120         return TRUE;
121     }
122     else
123         return FALSE;
124 }
125 
126 static void
jump_to_account(FindAccountDialog * facc_dialog,Account * jump_account)127 jump_to_account (FindAccountDialog *facc_dialog, Account *jump_account)
128 {
129     if (jump_account != NULL)
130         gnc_plugin_page_account_tree_open (jump_account, GTK_WINDOW(facc_dialog->parent));
131 
132     if (facc_dialog->jump_close == TRUE)
133         gnc_close_gui_component_by_data (DIALOG_FIND_ACCOUNT_CM_CLASS, facc_dialog);
134 }
135 
136 static void
gnc_find_account_dialog_jump_set(FindAccountDialog * facc_dialog)137 gnc_find_account_dialog_jump_set (FindAccountDialog *facc_dialog)
138 {
139     if (facc_dialog->jump_close == TRUE)
140         facc_dialog->jump_close = FALSE;
141     else
142         facc_dialog->jump_close = TRUE;
143 }
144 
145 static void
gnc_find_account_dialog_jump_to(FindAccountDialog * facc_dialog)146 gnc_find_account_dialog_jump_to (FindAccountDialog *facc_dialog)
147 {
148     Account          *jump_account = NULL;
149     GtkTreeModel     *model;
150     GtkTreeIter       iter;
151     GtkTreeSelection *selection;
152 
153     model = gtk_tree_view_get_model (GTK_TREE_VIEW(facc_dialog->view));
154     selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(facc_dialog->view));
155 
156     if (gtk_tree_selection_get_selected (selection, &model, &iter))
157         gtk_tree_model_get (model, &iter, ACCOUNT, &jump_account,  -1);
158 
159     jump_to_account (facc_dialog, jump_account);
160 }
161 
162 static void
row_double_clicked(GtkTreeView * treeview,GtkTreePath * path,GtkTreeViewColumn * col,FindAccountDialog * facc_dialog)163 row_double_clicked (GtkTreeView *treeview, GtkTreePath *path,
164                     GtkTreeViewColumn *col, FindAccountDialog *facc_dialog)
165 {
166     Account      *jump_account = NULL;
167     GtkTreeModel *model;
168     GtkTreeIter   iter;
169 
170     model = gtk_tree_view_get_model (treeview);
171 
172     if (gtk_tree_model_get_iter (model, &iter, path))
173        gtk_tree_model_get (model, &iter, ACCOUNT, &jump_account, -1);
174 
175     jump_to_account (facc_dialog, jump_account);
176 }
177 
178 static void
gnc_find_account_dialog_jump_button_cb(GtkWidget * widget,gpointer user_data)179 gnc_find_account_dialog_jump_button_cb (GtkWidget * widget, gpointer user_data)
180 {
181     FindAccountDialog *facc_dialog = user_data;
182     gnc_find_account_dialog_jump_to (facc_dialog);
183 }
184 
185 static void
gnc_find_account_dialog_check_button_cb(GtkWidget * widget,gpointer user_data)186 gnc_find_account_dialog_check_button_cb (GtkWidget * widget, gpointer user_data)
187 {
188     FindAccountDialog *facc_dialog = user_data;
189     gnc_find_account_dialog_jump_set (facc_dialog);
190 }
191 
192 static void
gnc_find_account_dialog_close_button_cb(GtkWidget * widget,gpointer user_data)193 gnc_find_account_dialog_close_button_cb (GtkWidget * widget, gpointer user_data)
194 {
195     FindAccountDialog *facc_dialog = user_data;
196     gnc_close_gui_component_by_data (DIALOG_FIND_ACCOUNT_CM_CLASS, facc_dialog);
197 }
198 
199 static void
fill_model(GtkTreeModel * model,Account * account)200 fill_model (GtkTreeModel *model, Account *account)
201 {
202     GtkTreeIter   iter;
203     gchar        *fullname = gnc_account_get_full_name (account);
204     gboolean      acc_empty = gnc_account_and_descendants_empty (account);
205     gnc_numeric   total = xaccAccountGetBalanceInCurrency (account, NULL, TRUE);
206 
207     PINFO("Add to Store: Account '%s'", fullname);
208 
209     gtk_list_store_append (GTK_LIST_STORE(model), &iter);
210 
211     gtk_list_store_set (GTK_LIST_STORE(model), &iter,
212                         ACC_FULL_NAME, fullname, ACCOUNT, account,
213                         PLACE_HOLDER, (xaccAccountGetPlaceholder (account) == TRUE ? "emblem-default" : NULL),
214                         HIDDEN, (xaccAccountGetHidden (account) == TRUE ? "emblem-default" : NULL),
215                         NOT_USED, (acc_empty ? "emblem-default" : NULL),
216                         BAL_ZERO, (gnc_numeric_zero_p (total) == TRUE ? "emblem-default" : NULL),
217                         TAX, (xaccAccountGetTaxRelated (account) == TRUE ? "emblem-default" : NULL), -1);
218     g_free (fullname);
219 }
220 
221 static void
get_account_info(FindAccountDialog * facc_dialog,gboolean use_saved_filter)222 get_account_info (FindAccountDialog *facc_dialog, gboolean use_saved_filter)
223 {
224     Account      *root;
225     GList        *accts;
226     GList        *ptr;
227     gchar        *filter_text;
228     gboolean      radio_root;
229     GtkTreeModel *model;
230 
231     /* Get the state of the root radio button */
232     radio_root = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(facc_dialog->radio_root));
233 
234      /* Get list of Accounts */
235     if ((facc_dialog->account == NULL) || (radio_root == TRUE))
236         root = gnc_book_get_root_account (gnc_get_current_book());
237     else
238         root = facc_dialog->account;
239 
240     accts = gnc_account_get_descendants_sorted (root);
241 
242     if (use_saved_filter)
243         filter_text = g_ascii_strdown (facc_dialog->saved_filter_text, -1);
244     else
245         filter_text = g_ascii_strdown (gtk_entry_get_text (GTK_ENTRY(facc_dialog->filter_text_entry)), -1);
246 
247     /* disconnect the model from the treeview */
248     model = gtk_tree_view_get_model (GTK_TREE_VIEW(facc_dialog->view));
249     g_object_ref (G_OBJECT(model));
250     gtk_tree_view_set_model (GTK_TREE_VIEW(facc_dialog->view), NULL);
251 
252     // Clear the list store
253     gtk_list_store_clear (GTK_LIST_STORE(model));
254 
255     /* Go through list of accounts */
256     for (ptr = accts; ptr; ptr = g_list_next (ptr))
257     {
258         Account *acc = ptr->data;
259         gchar   *full_name = gnc_account_get_full_name (acc);
260         gchar   *match_string = g_ascii_strdown (full_name, -1);
261 
262         if ((g_strcmp0 (filter_text, "") == 0) || (g_strrstr (match_string, filter_text) != NULL))
263             fill_model (model, acc);
264 
265         g_free (match_string);
266         g_free (full_name);
267     }
268     g_free (filter_text);
269     g_list_free (accts);
270 
271     /* reconnect the model to the treeview */
272     gtk_tree_view_set_model (GTK_TREE_VIEW(facc_dialog->view), model);
273     g_object_unref(G_OBJECT(model));
274 
275     gtk_tree_view_columns_autosize (GTK_TREE_VIEW(facc_dialog->view));
276 }
277 
278 static void
list_type_selected_cb(GtkToggleButton * button,FindAccountDialog * facc_dialog)279 list_type_selected_cb (GtkToggleButton* button, FindAccountDialog *facc_dialog)
280 {
281     get_account_info (facc_dialog, FALSE);
282 }
283 
284 static void
filter_button_cb(GtkButton * button,FindAccountDialog * facc_dialog)285 filter_button_cb (GtkButton *button, FindAccountDialog *facc_dialog)
286 {
287     get_account_info (facc_dialog, FALSE);
288 
289     if (facc_dialog->saved_filter_text)
290         g_free (facc_dialog->saved_filter_text);
291 
292     // save the filter in case of an account event
293     facc_dialog->saved_filter_text = g_strdup (gtk_entry_get_text
294                                      (GTK_ENTRY(facc_dialog->filter_text_entry)));
295 
296     // Clear the filter
297     gtk_entry_set_text (GTK_ENTRY(facc_dialog->filter_text_entry), "");
298 }
299 
300 static void
filter_active_cb(GtkEntry * entry,FindAccountDialog * facc_dialog)301 filter_active_cb (GtkEntry *entry, FindAccountDialog *facc_dialog)
302 {
303     get_account_info (facc_dialog, FALSE);
304 
305     if (facc_dialog->saved_filter_text)
306         g_free (facc_dialog->saved_filter_text);
307 
308     // save the filter in case of an account event
309     facc_dialog->saved_filter_text = g_strdup (gtk_entry_get_text
310                                      (GTK_ENTRY(facc_dialog->filter_text_entry)));
311 
312     gtk_editable_select_region (GTK_EDITABLE(facc_dialog->filter_text_entry), 0, -1);
313 }
314 
315 static void
gnc_find_account_event_handler(QofInstance * entity,QofEventId event_type,FindAccountDialog * facc_dialog,gpointer evt_data)316 gnc_find_account_event_handler (QofInstance *entity,
317                                 QofEventId event_type,
318                                 FindAccountDialog *facc_dialog,
319                                 gpointer evt_data)
320 {
321     Account *account = NULL;
322 
323     g_return_if_fail (facc_dialog);    /* Required */
324 
325     if (!GNC_IS_ACCOUNT(entity))
326         return;
327 
328     ENTER("entity %p of type %d, dialog %p, event_data %p",
329           entity, event_type, facc_dialog, evt_data);
330 
331     account = GNC_ACCOUNT(entity);
332 
333     switch (event_type)
334     {
335     case QOF_EVENT_ADD:
336     case QOF_EVENT_REMOVE:
337     case QOF_EVENT_MODIFY:
338         DEBUG("account change on %p (%s)", account, xaccAccountGetName (account));
339         get_account_info (facc_dialog, TRUE);
340         LEAVE(" ");
341         break;
342 
343     default:
344         LEAVE("unknown event type");
345         return;
346     }
347     LEAVE(" ");
348     return;
349 }
350 
351 static void
gnc_find_account_dialog_create(GtkWidget * parent,FindAccountDialog * facc_dialog)352 gnc_find_account_dialog_create (GtkWidget *parent, FindAccountDialog *facc_dialog)
353 {
354     GtkWidget         *window;
355     GtkBuilder        *builder;
356     GtkTreeSelection  *selection;
357 
358     GtkTreeViewColumn *tree_column;
359     GtkCellRenderer   *cr;
360     GtkWidget         *button;
361 
362     ENTER(" ");
363     builder = gtk_builder_new();
364     gnc_builder_add_from_file (builder, "dialog-find-account.glade", "list-store");
365     gnc_builder_add_from_file (builder, "dialog-find-account.glade", "find_account_window");
366 
367     window = GTK_WIDGET(gtk_builder_get_object (builder, "find_account_window"));
368     facc_dialog->window = window;
369 
370     // Set the name for this dialog so it can be easily manipulated with css
371     gtk_widget_set_name (GTK_WIDGET(window), "gnc-id-find-account");
372     gnc_widget_style_context_add_class (GTK_WIDGET(window), "gnc-class-account");
373 
374     facc_dialog->session = gnc_get_current_session();
375     facc_dialog->parent = parent;
376     facc_dialog->saved_filter_text = g_strdup ("");
377 
378     gtk_window_set_title (GTK_WINDOW(facc_dialog->window), _("Find Account"));
379 
380     /* Connect the radio buttons...*/
381     facc_dialog->radio_root = GTK_WIDGET(gtk_builder_get_object (builder, "radio-root"));
382     facc_dialog->radio_subroot = GTK_WIDGET(gtk_builder_get_object (builder, "radio-subroot"));
383 
384     g_signal_connect (facc_dialog->radio_root, "toggled",
385                       G_CALLBACK(list_type_selected_cb), (gpointer)facc_dialog);
386 
387     facc_dialog->filter_text_entry = GTK_WIDGET(gtk_builder_get_object (builder, "filter-text-entry"));
388     facc_dialog->sub_label = GTK_WIDGET(gtk_builder_get_object (builder, "sub-label"));
389     facc_dialog->radio_frame = GTK_WIDGET(gtk_builder_get_object (builder, "frame-radio"));
390     facc_dialog->filter_button = GTK_WIDGET(gtk_builder_get_object (builder, "filter-button"));
391     g_signal_connect (facc_dialog->filter_button, "clicked",
392                       G_CALLBACK(filter_button_cb), (gpointer)facc_dialog);
393     g_signal_connect (facc_dialog->filter_text_entry, "activate",
394                       G_CALLBACK(filter_active_cb), (gpointer)facc_dialog);
395 
396     button = GTK_WIDGET(gtk_builder_get_object (builder, "jumpto_button"));
397     g_signal_connect(button, "clicked", G_CALLBACK(gnc_find_account_dialog_jump_button_cb), facc_dialog);
398     button = GTK_WIDGET(gtk_builder_get_object (builder, "check_button"));
399     g_signal_connect(button, "clicked", G_CALLBACK(gnc_find_account_dialog_check_button_cb), facc_dialog);
400     button = GTK_WIDGET(gtk_builder_get_object (builder, "close_button"));
401     g_signal_connect(button, "clicked", G_CALLBACK(gnc_find_account_dialog_close_button_cb), facc_dialog);
402 
403     facc_dialog->view = GTK_WIDGET(gtk_builder_get_object (builder, "treeview"));
404     g_signal_connect (facc_dialog->view, "row-activated",
405                      G_CALLBACK(row_double_clicked), (gpointer)facc_dialog);
406 
407     // Set grid lines option to preference
408     gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(facc_dialog->view), gnc_tree_view_get_grid_lines_pref ());
409 
410     selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(facc_dialog->view));
411     gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
412 
413     /* Need to add pixbuf renderers here to get the xalign to work. */
414     tree_column = gtk_tree_view_column_new();
415     gtk_tree_view_column_set_title (tree_column, _("Place Holder"));
416     gtk_tree_view_append_column (GTK_TREE_VIEW(facc_dialog->view), tree_column);
417     gtk_tree_view_column_set_alignment (tree_column, 0.5);
418     gtk_tree_view_column_set_expand (tree_column, TRUE);
419     cr = gtk_cell_renderer_pixbuf_new();
420     gtk_tree_view_column_pack_start (tree_column, cr, TRUE);
421     // connect 'active' and set 'xalign' property of the cell renderer
422     gtk_tree_view_column_set_attributes (tree_column, cr, "icon-name", PLACE_HOLDER, NULL);
423     gtk_cell_renderer_set_alignment (cr, 0.5, 0.5);
424 
425     tree_column = gtk_tree_view_column_new();
426     gtk_tree_view_column_set_title (tree_column, _("Hidden"));
427     gtk_tree_view_append_column (GTK_TREE_VIEW(facc_dialog->view), tree_column);
428     gtk_tree_view_column_set_alignment (tree_column, 0.5);
429     gtk_tree_view_column_set_expand (tree_column, TRUE);
430     cr = gtk_cell_renderer_pixbuf_new();
431     gtk_tree_view_column_pack_start (tree_column, cr, TRUE);
432     // connect 'active' and set 'xalign' property of the cell renderer
433     gtk_tree_view_column_set_attributes (tree_column, cr, "icon-name", HIDDEN, NULL);
434     gtk_cell_renderer_set_alignment (cr, 0.5, 0.5);
435 
436     tree_column = gtk_tree_view_column_new();
437     gtk_tree_view_column_set_title (tree_column, _("Not Used"));
438     gtk_tree_view_append_column (GTK_TREE_VIEW(facc_dialog->view), tree_column);
439     gtk_tree_view_column_set_alignment (tree_column, 0.5);
440     gtk_tree_view_column_set_expand (tree_column, TRUE);
441     cr = gtk_cell_renderer_pixbuf_new();
442     gtk_tree_view_column_pack_start (tree_column, cr, TRUE);
443     // connect 'active' and set 'xalign' property of the cell renderer
444     gtk_tree_view_column_set_attributes (tree_column, cr, "icon-name", NOT_USED, NULL);
445     gtk_cell_renderer_set_alignment (cr, 0.5, 0.5);
446 
447     tree_column = gtk_tree_view_column_new();
448     gtk_tree_view_column_set_title (tree_column, _("Balance Zero"));
449     gtk_tree_view_append_column (GTK_TREE_VIEW(facc_dialog->view), tree_column);
450     gtk_tree_view_column_set_alignment (tree_column, 0.5);
451     gtk_tree_view_column_set_expand (tree_column, TRUE);
452     cr = gtk_cell_renderer_pixbuf_new();
453     gtk_tree_view_column_pack_start (tree_column, cr, TRUE);
454     // connect 'active' and set 'xalign' property of the cell renderer
455     gtk_tree_view_column_set_attributes (tree_column, cr, "icon-name", BAL_ZERO, NULL);
456     gtk_cell_renderer_set_alignment (cr, 0.5, 0.5);
457 
458     tree_column = gtk_tree_view_column_new();
459     gtk_tree_view_column_set_title (tree_column, _("Tax related"));
460     gtk_tree_view_append_column (GTK_TREE_VIEW(facc_dialog->view), tree_column);
461     gtk_tree_view_column_set_alignment (tree_column, 0.5);
462     gtk_tree_view_column_set_expand (tree_column, TRUE);
463     cr = gtk_cell_renderer_pixbuf_new();
464     gtk_tree_view_column_pack_start (tree_column, cr, TRUE);
465     // connect 'active' and set 'xalign' property of the cell renderer
466     gtk_tree_view_column_set_attributes (tree_column, cr, "icon-name", TAX, NULL);
467     gtk_cell_renderer_set_alignment (cr, 0.5, 0.5);
468 
469     g_signal_connect (facc_dialog->window, "destroy",
470                       G_CALLBACK(gnc_find_account_dialog_window_destroy_cb), facc_dialog);
471 
472     g_signal_connect (facc_dialog->window, "delete-event",
473                       G_CALLBACK(gnc_find_account_dialog_window_delete_event_cb), facc_dialog);
474 
475     g_signal_connect (facc_dialog->window, "key_press_event",
476                       G_CALLBACK(gnc_find_account_dialog_window_key_press_cb), facc_dialog);
477 
478     gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, facc_dialog);
479 
480     g_object_unref (G_OBJECT(builder));
481 
482     gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(facc_dialog->window), GTK_WINDOW(parent));
483 
484     gtk_widget_show_all (GTK_WIDGET(facc_dialog->window));
485 
486     if (facc_dialog->account != NULL)
487     {
488         gchar *sub_full_name = gnc_account_get_full_name (facc_dialog->account);
489         /* Translators: %s is a full account name.
490            This is a label in Search Account from context menu. */
491         gchar *sub_label = g_strdup_printf (_("Su_b-accounts of '%s'"),
492                                             sub_full_name);
493 
494         gtk_button_set_label (GTK_BUTTON(facc_dialog->radio_subroot), sub_label);
495 
496         g_free (sub_full_name);
497         g_free (sub_label);
498 
499         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(facc_dialog->radio_subroot), TRUE);
500     }
501     else
502         gtk_widget_hide (facc_dialog->radio_frame);
503 
504     // Set the filter to Wildcard
505     gtk_entry_set_text (GTK_ENTRY(facc_dialog->filter_text_entry), "");
506 
507     // add a handler to listen for account events
508     facc_dialog->event_handler_id = qof_event_register_handler
509                              ((QofEventHandler)gnc_find_account_event_handler, facc_dialog);
510 
511     get_account_info (facc_dialog, FALSE);
512     LEAVE(" ");
513 }
514 
515 static void
close_handler(gpointer user_data)516 close_handler (gpointer user_data)
517 {
518     FindAccountDialog *facc_dialog = user_data;
519 
520     ENTER(" ");
521     gnc_save_window_size (GNC_PREFS_GROUP,
522                           GTK_WINDOW(facc_dialog->window));
523     gtk_widget_destroy (GTK_WIDGET(facc_dialog->window));
524     LEAVE(" ");
525 }
526 
527 static void
refresh_handler(GHashTable * changes,gpointer user_data)528 refresh_handler (GHashTable *changes, gpointer user_data)
529 {
530     ENTER(" ");
531     LEAVE(" ");
532 }
533 
534 static gboolean
show_handler(const char * klass,gint component_id,gpointer user_data,gpointer iter_data)535 show_handler (const char *klass, gint component_id,
536               gpointer user_data, gpointer iter_data)
537 {
538     FindAccountDialog *facc_dialog = user_data;
539 
540     ENTER(" ");
541     if (!facc_dialog)
542     {
543         LEAVE("No data structure");
544         return(FALSE);
545     }
546     gtk_window_present (GTK_WINDOW(facc_dialog->window));
547     LEAVE(" ");
548     return(TRUE);
549 }
550 
551 /********************************************************************\
552  * gnc_find_account_dialog                                          *
553  * opens a window allowing for searches on account names            *
554  *                                                                  *
555  * Args:   parent  - the parent of the window to be created         *
556  * Return: nothing                                                  *
557 \********************************************************************/
558 void
gnc_find_account_dialog(GtkWidget * parent,Account * account)559 gnc_find_account_dialog (GtkWidget *parent, Account *account)
560 {
561     FindAccountDialog *facc_dialog;
562     gint component_id;
563 
564     ENTER(" ");
565     if (gnc_forall_gui_components (DIALOG_FIND_ACCOUNT_CM_CLASS, show_handler, NULL))
566     {
567         LEAVE("Existing dialog raised");
568         return;
569     }
570     facc_dialog = g_new0 (FindAccountDialog, 1);
571 
572     facc_dialog->account = account;
573     facc_dialog->jump_close = TRUE;
574 
575     gnc_find_account_dialog_create (parent, facc_dialog);
576 
577     component_id = gnc_register_gui_component (DIALOG_FIND_ACCOUNT_CM_CLASS,
578                    refresh_handler, close_handler,
579                    facc_dialog);
580 
581     gnc_gui_component_set_session (component_id, facc_dialog->session);
582     LEAVE(" ");
583 }
584