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