GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dialog-options.c
1 /********************************************************************\
2  * dialog-options.c -- GNOME option handling *
3  * Copyright (C) 1998-2000 Linas Vepstas *
4  * Copyright (c) 2006 David Hampton <[email protected]> *
5  * Copyright (c) 2011 Robert Fewell *
6  * *
7  * This program is free software; you can redistribute it and/or *
8  * modify it under the terms of the GNU General Public License as *
9  * published by the Free Software Foundation; either version 2 of *
10  * the License, or (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License*
18  * along with this program; if not, contact: *
19  * *
20  * Free Software Foundation Voice: +1-617-542-5942 *
21  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
22  * Boston, MA 02110-1301, USA [email protected] *
23 \********************************************************************/
24 
25 #include "config.h"
26 
27 #include <gtk/gtk.h>
28 #include <gdk/gdk.h>
29 #include <glib/gi18n.h>
30 #include "swig-runtime.h"
31 
32 #include "gnc-tree-model-budget.h" //FIXME?
33 #include "gnc-budget.h"
34 
35 #include "dialog-options.h"
36 #include "dialog-utils.h"
37 #include "engine-helpers-guile.h"
38 #include "glib-helpers.h"
39 #include "gnc-account-sel.h"
40 #include "gnc-tree-view-account.h"
41 #include "gnc-combott.h"
42 #include "gnc-commodity-edit.h"
43 #include "gnc-component-manager.h"
44 #include "gnc-general-select.h"
45 #include "gnc-currency-edit.h"
46 #include "gnc-date-edit.h"
47 #include "gnc-engine.h"
48 #include "gnc-prefs.h"
49 #include "gnc-gui-query.h"
50 #include "gnc-session.h"
51 #include "gnc-ui.h"
52 #include "guile-util.h"
53 #include "gnc-guile-utils.h"
54 #include "option-util.h"
55 #include "guile-mappings.h"
56 #include "gnc-date-format.h"
57 #include "misc-gnome-utils.h"
58 
59 #define GNC_PREF_CLOCK_24H "clock-24h"
60 
61 #define FUNC_NAME G_STRFUNC
62 /* TODO: clean up "register-stocks" junk
63  */
64 
65 
66 /* This static indicates the debugging module that this .o belongs to. */
67 static QofLogModule log_module = GNC_MOD_GUI;
68 
69 #define DIALOG_OPTIONS_CM_CLASS "dialog-options"
70 
71 /*
72  * Point where preferences switch control method from a set of
73  * notebook tabs to a list.
74  */
75 #define MAX_TAB_COUNT 4
76 
77 /* A pointer to the last selected filename */
78 #define LAST_SELECTION "last-selection"
79 
80 /* A Hash-table of GNCOptionDef_t keyed with option names. */
81 static GHashTable *optionTable = NULL;
82 
84 {
85  GtkWidget * dialog;
86  GtkWidget * notebook;
87  GtkWidget * page_list_view;
88  GtkWidget * page_list;
89 
90  gboolean toplevel;
91 
92  GNCOptionWinCallback apply_cb;
93  gpointer apply_cb_data;
94 
95  GNCOptionWinCallback help_cb;
96  gpointer help_cb_data;
97 
98  GNCOptionWinCallback close_cb;
99  gpointer close_cb_data;
100 
101  /* Hold onto this for a complete reset */
102  GNCOptionDB * option_db;
103 };
104 
105 typedef enum
106 {
107  GNC_RD_WID_AB_BUTTON_POS = 0,
108  GNC_RD_WID_AB_WIDGET_POS,
109  GNC_RD_WID_REL_BUTTON_POS,
110  GNC_RD_WID_REL_WIDGET_POS
111 } GNCRdPositions;
112 
113 enum page_tree
114 {
115  PAGE_INDEX = 0,
116  PAGE_NAME,
117  NUM_COLUMNS
118 };
119 
120 static GNCOptionWinCallback global_help_cb = NULL;
121 gpointer global_help_cb_data = NULL;
122 
123 void gnc_options_dialog_response_cb(GtkDialog *dialog, gint response,
124  GNCOptionWin *window);
125 static void gnc_options_dialog_reset_cb(GtkWidget * w, gpointer data);
126 void gnc_options_dialog_list_select_cb (GtkTreeSelection *selection,
127  gpointer data);
128 
129 GtkWidget *
130 gnc_option_get_gtk_widget (GNCOption *option)
131 {
132  return (GtkWidget *)gnc_option_get_widget(option);
133 }
134 
135 static inline gint
136 color_d_to_i16 (double d)
137 {
138  return (d * 0xFFFF);
139 }
140 
141 static inline double
142 color_i16_to_d (gint i16)
143 {
144  return ((double)i16 / 0xFFFF);
145 }
146 
147 static void
148 gnc_options_dialog_changed_internal (GtkWidget *widget, gboolean sensitive)
149 {
150  GtkDialog *dialog;
151 
152  while (widget && !GTK_IS_DIALOG(widget))
153  widget = gtk_widget_get_parent(widget);
154  if (widget == NULL)
155  return;
156 
157  dialog = GTK_DIALOG(widget);
158  gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, sensitive);
159  gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, sensitive);
160 }
161 
162 void
163 gnc_options_dialog_changed (GNCOptionWin *win)
164 {
165  if (!win) return;
166 
167  gnc_options_dialog_changed_internal (win->dialog, TRUE);
168 }
169 
170 void
171 gnc_option_changed_widget_cb(GtkWidget *widget, GNCOption *option)
172 {
173  gnc_option_set_changed (option, TRUE);
174  gnc_option_call_option_widget_changed_proc(option);
175  gnc_options_dialog_changed_internal (widget, TRUE);
176 }
177 
178 void
179 gnc_option_changed_option_cb(GtkWidget *dummy, GNCOption *option)
180 {
181  GtkWidget *widget;
182 
183  widget = gnc_option_get_gtk_widget (option);
184  gnc_option_changed_widget_cb(widget, option);
185 }
186 
187 static void
188 gnc_date_option_set_select_method(GNCOption *option, gboolean use_absolute,
189  gboolean set_buttons)
190 {
191  GList* widget_list;
192  GtkWidget *ab_button, *rel_button, *rel_widget, *ab_widget;
193  GtkWidget *widget;
194 
195  widget = gnc_option_get_gtk_widget (option);
196 
197  widget_list = gtk_container_get_children(GTK_CONTAINER(widget));
198  ab_button = g_list_nth_data(widget_list, GNC_RD_WID_AB_BUTTON_POS);
199  ab_widget = g_list_nth_data(widget_list, GNC_RD_WID_AB_WIDGET_POS);
200  rel_button = g_list_nth_data(widget_list, GNC_RD_WID_REL_BUTTON_POS);
201  rel_widget = g_list_nth_data(widget_list, GNC_RD_WID_REL_WIDGET_POS);
202  g_list_free(widget_list);
203 
204  if (use_absolute)
205  {
206  gtk_widget_set_sensitive(ab_widget, TRUE);
207  gtk_widget_set_sensitive(rel_widget, FALSE);
208  if (set_buttons)
209  {
210  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ab_button), TRUE);
211  }
212  }
213  else
214  {
215  gtk_widget_set_sensitive(rel_widget, TRUE);
216  gtk_widget_set_sensitive(ab_widget, FALSE);
217  if (set_buttons)
218  {
219  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rel_button), TRUE);
220  }
221  }
222 }
223 
224 static void
225 gnc_rd_option_ab_set_cb(GtkWidget *widget, gpointer *raw_option)
226 {
227  GNCOption *option = (GNCOption *) raw_option;
228  gnc_date_option_set_select_method(option, TRUE, FALSE);
229  gnc_option_changed_option_cb(widget, option);
230 }
231 
232 static void
233 gnc_rd_option_rel_set_cb(GtkWidget *widget, gpointer *raw_option)
234 {
235  GNCOption *option = (GNCOption *) raw_option;
236  gnc_date_option_set_select_method(option, FALSE, FALSE);
237  gnc_option_changed_option_cb(widget, option);
238  return;
239 }
240 
241 static void
242 gnc_image_option_update_preview_cb (GtkFileChooser *chooser,
243  GNCOption *option)
244 {
245  gchar *filename;
246  GtkImage *image;
247  GdkPixbuf *pixbuf;
248  gboolean have_preview;
249 
250  g_return_if_fail(chooser != NULL);
251 
252  ENTER("chooser %p, option %p", chooser, option);
253  filename = gtk_file_chooser_get_preview_filename(chooser);
254  DEBUG("chooser preview name is %s.", filename ? filename : "(null)");
255  if (filename == NULL)
256  {
257  filename = g_strdup(g_object_get_data(G_OBJECT(chooser), LAST_SELECTION));
258  DEBUG("using last selection of %s", filename ? filename : "(null)");
259  if (filename == NULL)
260  {
261  LEAVE("no usable name");
262  return;
263  }
264  }
265 
266  image = GTK_IMAGE(gtk_file_chooser_get_preview_widget(chooser));
267  pixbuf = gdk_pixbuf_new_from_file_at_size(filename, 128, 128, NULL);
268  g_free(filename);
269  have_preview = (pixbuf != NULL);
270 
271  gtk_image_set_from_pixbuf(image, pixbuf);
272  if (pixbuf)
273  g_object_unref(pixbuf);
274 
275  gtk_file_chooser_set_preview_widget_active(chooser, have_preview);
276  LEAVE("preview visible is %d", have_preview);
277 }
278 
279 static void
280 gnc_image_option_selection_changed_cb (GtkFileChooser *chooser,
281  GNCOption *option)
282 {
283  gchar *filename;
284 
285  filename = gtk_file_chooser_get_preview_filename(chooser);
286  if (!filename)
287  return;
288  g_object_set_data_full(G_OBJECT(chooser), LAST_SELECTION, filename, g_free);
289 }
290 
291 /********************************************************************\
292  * gnc_option_set_ui_value_internal *
293  * sets the GUI representation of an option with either its *
294  * current guile value, or its default value *
295  * *
296  * Args: option - option structure containing option *
297  * use_default - if true, use the default value, otherwise *
298  * use the current value *
299  * Return: nothing *
300 \********************************************************************/
301 static void
302 gnc_option_set_ui_value_internal (GNCOption *option, gboolean use_default)
303 {
304  gboolean bad_value = FALSE;
305  GtkWidget *widget;
306  char *type;
307  SCM getter;
308  SCM value;
309  GNCOptionDef_t *option_def;
310 
311  widget = gnc_option_get_gtk_widget (option);
312  if (!widget)
313  return;
314 
315  type = gnc_option_type(option);
316 
317  if (use_default)
318  getter = gnc_option_default_getter(option);
319  else
320  getter = gnc_option_getter(option);
321 
322  value = scm_call_0(getter);
323 
324  option_def = gnc_options_ui_get_option (type);
325  if (option_def && option_def->set_value)
326  {
327  bad_value = option_def->set_value (option, use_default, widget, value);
328  if (bad_value)
329  {
330  PERR("bad value\n");
331  }
332  }
333  else
334  {
335  PERR("Unknown type. Ignoring.\n");
336  }
337 
338  free(type);
339 }
340 
341 /********************************************************************\
342  * gnc_option_get_ui_value_internal *
343  * returns the SCM representation of the GUI option value *
344  * *
345  * Args: option - option structure containing option *
346  * Return: SCM handle to GUI option value *
347 \********************************************************************/
348 static SCM
349 gnc_option_get_ui_value_internal (GNCOption *option)
350 {
351  SCM result = SCM_UNDEFINED;
352  GtkWidget *widget;
353  char *type;
354  GNCOptionDef_t *option_def;
355 
356  widget = gnc_option_get_gtk_widget (option);
357  if (!widget)
358  return result;
359 
360  type = gnc_option_type(option);
361 
362  option_def = gnc_options_ui_get_option (type);
363  if (option_def && option_def->get_value)
364  {
365  result = option_def->get_value (option, widget);
366  }
367  else
368  {
369  PERR("Unknown type for refresh. Ignoring.\n");
370  }
371 
372  free(type);
373 
374  return result;
375 }
376 
377 /********************************************************************\
378  * gnc_option_set_selectable_internal *
379  * Change the selectable state of the widget that represents a *
380  * GUI option. *
381  * *
382  * Args: option - option to change widget state for *
383  * selectable - if false, update the widget so that it *
384  * cannot be selected by the user. If true, *
385  * update the widget so that it can be selected.*
386  * Return: nothing *
387 \********************************************************************/
388 static void
389 gnc_option_set_selectable_internal (GNCOption *option, gboolean selectable)
390 {
391  GtkWidget *widget;
392 
393  widget = gnc_option_get_gtk_widget (option);
394  if (!widget)
395  return;
396 
397  gtk_widget_set_sensitive (widget, selectable);
398 }
399 
400 static void
401 gnc_option_default_cb(GtkWidget *widget, GNCOption *option)
402 {
403  gnc_option_set_ui_value (option, TRUE);
404  gnc_option_set_changed (option, TRUE);
405  gnc_options_dialog_changed_internal (widget, TRUE);
406 }
407 
408 static void
409 gnc_option_show_hidden_toggled_cb(GtkWidget *widget, GNCOption* option)
410 {
411  AccountViewInfo avi;
412  GncTreeViewAccount *tree_view;
413 
414  tree_view = GNC_TREE_VIEW_ACCOUNT(gnc_option_get_gtk_widget (option));
415  gnc_tree_view_account_get_view_info (tree_view, &avi);
416  avi.show_hidden = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
417  gnc_tree_view_account_set_view_info (tree_view, &avi);
418  gnc_option_changed_widget_cb(widget, option);
419 }
420 
421 static void
422 gnc_option_multichoice_cb(GtkWidget *widget, gpointer data)
423 {
424  GNCOption *option = data;
425  /* GtkComboBox per-item tooltip changes needed below */
426  gnc_option_changed_widget_cb(widget, option);
427 }
428 
429 static void
430 gnc_option_radiobutton_cb(GtkWidget *w, gpointer data)
431 {
432  GNCOption *option = data;
433  GtkWidget *widget;
434  gpointer _current, _new_value;
435  gint current, new_value;
436 
437  widget = gnc_option_get_gtk_widget (option);
438 
439  _current = g_object_get_data(G_OBJECT(widget), "gnc_radiobutton_index");
440  current = GPOINTER_TO_INT (_current);
441 
442  _new_value = g_object_get_data (G_OBJECT(w), "gnc_radiobutton_index");
443  new_value = GPOINTER_TO_INT (_new_value);
444 
445  if (current == new_value)
446  return;
447 
448  g_object_set_data (G_OBJECT(widget), "gnc_radiobutton_index",
449  GINT_TO_POINTER(new_value));
450  gnc_option_changed_widget_cb(widget, option);
451 }
452 
453 static GtkWidget *
454 gnc_option_create_date_widget (GNCOption *option)
455 {
456  GtkWidget * box = NULL;
457  GtkWidget *rel_button = NULL, *ab_button = NULL;
458  GtkWidget *rel_widget = NULL, *ab_widget = NULL;
459  GtkWidget *entry;
460  gboolean show_time, use24;
461  char *type;
462  int num_values;
463 
464  type = gnc_option_date_option_get_subtype(option);
465  show_time = gnc_option_show_time(option);
466  use24 = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL, GNC_PREF_CLOCK_24H);
467 
468  if (g_strcmp0(type, "relative") != 0)
469  {
470  ab_widget = gnc_date_edit_new(time(NULL), show_time, use24);
471  entry = GNC_DATE_EDIT(ab_widget)->date_entry;
472  g_signal_connect(G_OBJECT(entry), "changed",
473  G_CALLBACK(gnc_option_changed_option_cb), option);
474  if (show_time)
475  {
476  entry = GNC_DATE_EDIT(ab_widget)->time_entry;
477  g_signal_connect(G_OBJECT(entry), "changed",
478  G_CALLBACK(gnc_option_changed_option_cb), option);
479  }
480  }
481 
482  if (g_strcmp0(type, "absolute") != 0)
483  {
484  int i;
485  num_values = gnc_option_num_permissible_values(option);
486 
487  g_return_val_if_fail(num_values >= 0, NULL);
488 
489  {
490  /* GtkComboBox still does not support per-item tooltips, so have
491  created a basic one called Combott implemented in gnc-combott.
492  Have highlighted changes in this file with comments for when
493  the feature of per-item tooltips is implemented in gtk,
494  see http://bugzilla.gnome.org/show_bug.cgi?id=303717 */
495 
496  GtkListStore *store;
497  GtkTreeIter iter;
498 
499  char *itemstring;
500  char *description;
501  store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
502  /* Add values to the list store, entry and tooltip */
503  for (i = 0; i < num_values; i++)
504  {
505  itemstring = gnc_option_permissible_value_name(option, i);
506  description = gnc_option_permissible_value_description(option, i);
507  gtk_list_store_append (store, &iter);
508  gtk_list_store_set (store, &iter, 0, itemstring, 1, description, -1);
509  if (itemstring)
510  g_free(itemstring);
511  if (description)
512  g_free(description);
513  }
514  /* Create the new Combo with tooltip and add the store */
515  rel_widget = GTK_WIDGET(gnc_combott_new());
516  g_object_set( G_OBJECT(rel_widget), "model", GTK_TREE_MODEL(store), NULL );
517  g_object_unref(store);
518 
519  g_signal_connect(G_OBJECT(rel_widget), "changed",
520  G_CALLBACK(gnc_option_multichoice_cb), option);
521  }
522  }
523 
524  if (g_strcmp0(type, "absolute") == 0)
525  {
526  free(type);
527  gnc_option_set_widget (option, ab_widget);
528  return ab_widget;
529  }
530  else if (g_strcmp0(type, "relative") == 0)
531  {
532  gnc_option_set_widget (option, rel_widget);
533  free(type);
534 
535  return rel_widget;
536  }
537  else if (g_strcmp0(type, "both") == 0)
538  {
539  box = gtk_hbox_new(FALSE, 5);
540 
541  ab_button = gtk_radio_button_new(NULL);
542  g_signal_connect(G_OBJECT(ab_button), "toggled",
543  G_CALLBACK(gnc_rd_option_ab_set_cb), option);
544 
545  rel_button = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(ab_button));
546  g_signal_connect(G_OBJECT(rel_button), "toggled",
547  G_CALLBACK(gnc_rd_option_rel_set_cb), option);
548 
549  gtk_box_pack_start(GTK_BOX(box), ab_button, FALSE, FALSE, 0);
550  gtk_box_pack_start(GTK_BOX(box), ab_widget, FALSE, FALSE, 0);
551  gtk_box_pack_start(GTK_BOX(box), rel_button, FALSE, FALSE, 0);
552  gtk_box_pack_start(GTK_BOX(box), rel_widget, FALSE, FALSE, 0);
553 
554  free(type);
555 
556  gnc_option_set_widget (option, box);
557 
558  return box;
559  }
560  else /* can't happen */
561  {
562  return NULL;
563  }
564 }
565 
566 static GtkWidget *
567 gnc_option_create_budget_widget(GNCOption *option)
568 {
569  GtkTreeModel *tm;
570  GtkComboBox *cb;
571  GtkCellRenderer *cr;
572 
573  tm = gnc_tree_model_budget_new(gnc_get_current_book());
574  cb = GTK_COMBO_BOX(gtk_combo_box_new_with_model(tm));
575  g_object_unref(tm);
576  cr = gtk_cell_renderer_text_new();
577  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(cb), cr, TRUE);
578 
579  gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(cb), cr, "text",
580  BUDGET_NAME_COLUMN, NULL);
581  return GTK_WIDGET(cb);
582 }
583 
584 static GtkWidget *
585 gnc_option_create_multichoice_widget(GNCOption *option)
586 {
587  GtkWidget *widget;
588  int num_values;
589  int i;
590 
591  num_values = gnc_option_num_permissible_values(option);
592 
593  g_return_val_if_fail(num_values >= 0, NULL);
594 
595  {
596  /* GtkComboBox still does not support per-item tooltips, so have
597  created a basic one called Combott implemented in gnc-combott.
598  Have highlighted changes in this file with comments for when
599  the feature of per-item tooltips is implemented in gtk,
600  see http://bugzilla.gnome.org/show_bug.cgi?id=303717 */
601  GtkListStore *store;
602  GtkTreeIter iter;
603 
604  char *itemstring;
605  char *description;
606  store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
607  /* Add values to the list store, entry and tooltip */
608  for (i = 0; i < num_values; i++)
609  {
610  itemstring = gnc_option_permissible_value_name(option, i);
611  description = gnc_option_permissible_value_description(option, i);
612  gtk_list_store_append (store, &iter);
613  gtk_list_store_set (store, &iter, 0,
614  (itemstring && *itemstring) ? _(itemstring) : "", 1,
615  (description && *description) ? _(description) : "", -1);
616  if (itemstring)
617  g_free(itemstring);
618  if (description)
619  g_free(description);
620  }
621  /* Create the new Combo with tooltip and add the store */
622  widget = GTK_WIDGET(gnc_combott_new());
623  g_object_set( G_OBJECT( widget ), "model", GTK_TREE_MODEL(store), NULL );
624  g_object_unref(store);
625 
626  g_signal_connect(G_OBJECT(widget), "changed",
627  G_CALLBACK(gnc_option_multichoice_cb), option);
628  }
629 
630  return widget;
631 }
632 
633 static GtkWidget *
634 gnc_option_create_radiobutton_widget(char *name, GNCOption *option)
635 {
636  GtkWidget *frame, *box;
637  GtkWidget *widget = NULL;
638  int num_values;
639  char *label;
640  char *tip;
641  int i;
642 
643  num_values = gnc_option_num_permissible_values(option);
644 
645  g_return_val_if_fail(num_values >= 0, NULL);
646 
647  /* Create our button frame */
648  frame = gtk_frame_new (name);
649 
650  /* Create the button box */
651  box = gtk_hbox_new (FALSE, 5);
652  gtk_container_add (GTK_CONTAINER (frame), box);
653 
654  /* Iterate over the options and create a radio button for each one */
655  for (i = 0; i < num_values; i++)
656  {
657  label = gnc_option_permissible_value_name(option, i);
658  tip = gnc_option_permissible_value_description(option, i);
659 
660  widget =
661  gtk_radio_button_new_with_label_from_widget (widget ?
662  GTK_RADIO_BUTTON (widget) :
663  NULL,
664  label && *label ? _(label) : "");
665  g_object_set_data (G_OBJECT (widget), "gnc_radiobutton_index",
666  GINT_TO_POINTER (i));
667  gtk_widget_set_tooltip_text(widget, tip && *tip ? _(tip) : "");
668  g_signal_connect(G_OBJECT(widget), "toggled",
669  G_CALLBACK(gnc_option_radiobutton_cb), option);
670  gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
671 
672  if (label)
673  free (label);
674  if (tip)
675  free (tip);
676  }
677 
678  return frame;
679 }
680 
681 static void
682 gnc_option_account_cb(GtkTreeSelection *selection, gpointer data)
683 {
684  GNCOption *option = data;
685  GtkTreeView *tree_view;
686 
687  tree_view = gtk_tree_selection_get_tree_view(selection);
688 
689  gnc_option_changed_widget_cb(GTK_WIDGET(tree_view), option);
690 }
691 
692 static void
693 gnc_option_account_select_all_cb(GtkWidget *widget, gpointer data)
694 {
695  GNCOption *option = data;
696  GncTreeViewAccount *tree_view;
697  GtkTreeSelection *selection;
698 
699  tree_view = GNC_TREE_VIEW_ACCOUNT(gnc_option_get_gtk_widget (option));
700  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
701  gtk_tree_selection_select_all(selection);
702  gnc_option_changed_widget_cb(widget, option);
703 }
704 
705 static void
706 gnc_option_account_clear_all_cb(GtkWidget *widget, gpointer data)
707 {
708  GNCOption *option = data;
709  GncTreeViewAccount *tree_view;
710  GtkTreeSelection *selection;
711 
712  tree_view = GNC_TREE_VIEW_ACCOUNT(gnc_option_get_gtk_widget (option));
713  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
714  gtk_tree_selection_unselect_all(selection);
715  gnc_option_changed_widget_cb(widget, option);
716 }
717 
718 static void
719 gnc_option_account_select_children_cb(GtkWidget *widget, gpointer data)
720 {
721  GNCOption *option = data;
722  GncTreeViewAccount *tree_view;
723  Account *account;
724 
725  tree_view = GNC_TREE_VIEW_ACCOUNT(gnc_option_get_gtk_widget (option));
726  account = gnc_tree_view_account_get_cursor_account(tree_view);
727  if (!account)
728  return;
729 
730  gnc_tree_view_account_select_subaccounts(tree_view, account);
731 }
732 
733 static GtkWidget *
734 gnc_option_create_account_widget(GNCOption *option, char *name)
735 {
736  gboolean multiple_selection;
737  GtkWidget *scroll_win;
738  GtkWidget *button;
739  GtkWidget *frame;
740  GtkWidget *tree;
741  GtkWidget *vbox;
742  GtkWidget *bbox;
743  GList *acct_type_list;
744  GtkTreeSelection *selection;
745 
746  multiple_selection = gnc_option_multiple_selection(option);
747  acct_type_list = gnc_option_get_account_type_list(option);
748 
749  frame = gtk_frame_new(name);
750 
751  vbox = gtk_vbox_new(FALSE, 0);
752  gtk_container_add(GTK_CONTAINER(frame), vbox);
753 
754  tree = GTK_WIDGET(gnc_tree_view_account_new (FALSE));
755  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(tree), FALSE);
756  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(tree));
757  if (multiple_selection)
758  gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
759  else
760  gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
761 
762  if (acct_type_list)
763  {
764  GList *node;
765  AccountViewInfo avi;
766  int i;
767 
768  gnc_tree_view_account_get_view_info (GNC_TREE_VIEW_ACCOUNT (tree), &avi);
769 
770  for (i = 0; i < NUM_ACCOUNT_TYPES; i++)
771  avi.include_type[i] = FALSE;
772  avi.show_hidden = FALSE;
773 
774  for (node = acct_type_list; node; node = node->next)
775  {
776  GNCAccountType type = GPOINTER_TO_INT (node->data);
777  avi.include_type[type] = TRUE;
778  }
779 
780  gnc_tree_view_account_set_view_info (GNC_TREE_VIEW_ACCOUNT (tree), &avi);
781  g_list_free (acct_type_list);
782  }
783  else
784  {
785  AccountViewInfo avi;
786  int i;
787 
788  gnc_tree_view_account_get_view_info (GNC_TREE_VIEW_ACCOUNT (tree), &avi);
789 
790  for (i = 0; i < NUM_ACCOUNT_TYPES; i++)
791  avi.include_type[i] = TRUE;
792  avi.show_hidden = FALSE;
793  gnc_tree_view_account_set_view_info (GNC_TREE_VIEW_ACCOUNT (tree), &avi);
794  }
795 
796  scroll_win = gtk_scrolled_window_new(NULL, NULL);
797  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
798  GTK_POLICY_AUTOMATIC,
799  GTK_POLICY_AUTOMATIC);
800 
801  gtk_box_pack_start(GTK_BOX(vbox), scroll_win, TRUE, TRUE, 0);
802  gtk_container_set_border_width(GTK_CONTAINER(scroll_win), 5);
803  gtk_container_add(GTK_CONTAINER(scroll_win), tree);
804 
805  bbox = gtk_hbutton_box_new();
806  gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_SPREAD);
807  gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 10);
808 
809  if (multiple_selection)
810  {
811  button = gtk_button_new_with_label(_("Select All"));
812  gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
813  gtk_widget_set_tooltip_text(button, _("Select all accounts."));
814 
815  g_signal_connect(G_OBJECT(button), "clicked",
816  G_CALLBACK(gnc_option_account_select_all_cb), option);
817 
818  button = gtk_button_new_with_label(_("Clear All"));
819  gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
820  gtk_widget_set_tooltip_text(button, _("Clear the selection and unselect all accounts."));
821 
822  g_signal_connect(G_OBJECT(button), "clicked",
823  G_CALLBACK(gnc_option_account_clear_all_cb), option);
824 
825  button = gtk_button_new_with_label(_("Select Children"));
826  gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
827  gtk_widget_set_tooltip_text(button, _("Select all descendents of selected account."));
828 
829  g_signal_connect(G_OBJECT(button), "clicked",
830  G_CALLBACK(gnc_option_account_select_children_cb), option);
831  }
832 
833  button = gtk_button_new_with_label(_("Select Default"));
834  gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
835  gtk_widget_set_tooltip_text(button, _("Select the default account selection."));
836 
837  g_signal_connect(G_OBJECT(button), "clicked",
838  G_CALLBACK(gnc_option_default_cb), option);
839 
840  if (multiple_selection)
841  {
842  /* Put the "Show hidden" checkbox on a separate line since the 4 buttons make
843  the dialog too wide. */
844  bbox = gtk_hbutton_box_new();
845  gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_START);
846  gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
847  }
848 
849  button = gtk_check_button_new_with_label(_("Show Hidden Accounts"));
850  gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
851  gtk_widget_set_tooltip_text(button, _("Show accounts that have been marked hidden."));
852  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
853  g_signal_connect(G_OBJECT(button), "toggled",
854  G_CALLBACK(gnc_option_show_hidden_toggled_cb), option);
855 
856  gnc_option_set_widget (option, tree);
857 
858  return frame;
859 }
860 
861 static void
862 gnc_option_list_changed_cb(GtkTreeSelection *selection,
863  GNCOption *option)
864 {
865  GtkTreeView *view;
866 
867  view = gtk_tree_selection_get_tree_view(selection);
868  gnc_option_changed_widget_cb(GTK_WIDGET(view), option);
869 }
870 
871 static void
872 gnc_option_list_select_all_cb(GtkWidget *widget, gpointer data)
873 {
874  GNCOption *option = data;
875  GtkTreeView *view;
876  GtkTreeSelection *selection;
877 
878  view = GTK_TREE_VIEW(gnc_option_get_gtk_widget (option));
879  selection = gtk_tree_view_get_selection(view);
880  gtk_tree_selection_select_all(selection);
881  gnc_option_changed_widget_cb(GTK_WIDGET(view), option);
882 }
883 
884 static void
885 gnc_option_list_clear_all_cb(GtkWidget *widget, gpointer data)
886 {
887  GNCOption *option = data;
888  GtkTreeView *view;
889  GtkTreeSelection *selection;
890 
891  view = GTK_TREE_VIEW(gnc_option_get_gtk_widget (option));
892  selection = gtk_tree_view_get_selection(view);
893  gtk_tree_selection_unselect_all(selection);
894  gnc_option_changed_widget_cb(GTK_WIDGET(view), option);
895 }
896 
897 static GtkWidget *
898 gnc_option_create_list_widget(GNCOption *option, char *name)
899 {
900  GtkListStore *store;
901  GtkTreeView *view;
902  GtkTreeIter iter;
903  GtkTreeViewColumn *column;
904  GtkCellRenderer *renderer;
905  GtkTreeSelection *selection;
906 
907  GtkWidget *button;
908  GtkWidget *frame;
909  GtkWidget *hbox;
910  GtkWidget *bbox;
911  gint num_values;
912  gint i;
913 
914  frame = gtk_frame_new(name);
915  hbox = gtk_hbox_new(FALSE, 0);
916  gtk_container_add(GTK_CONTAINER(frame), hbox);
917 
918  store = gtk_list_store_new(1, G_TYPE_STRING);
919  view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)));
920  g_object_unref(store);
921  renderer = gtk_cell_renderer_text_new();
922  column = gtk_tree_view_column_new_with_attributes("", renderer,
923  "text", 0,
924  NULL);
925  gtk_tree_view_append_column(view, column);
926  gtk_tree_view_set_headers_visible(view, FALSE);
927 
928  num_values = gnc_option_num_permissible_values(option);
929  for (i = 0; i < num_values; i++)
930  {
931  gchar *raw_string, *string;
932 
933  raw_string = gnc_option_permissible_value_name(option, i);
934  string = (raw_string && *raw_string) ? _(raw_string) : "";
935  gtk_list_store_append(store, &iter);
936  gtk_list_store_set(store, &iter,
937  0, string ? string : "",
938  -1);
939  g_free(raw_string);
940  }
941 
942  gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(view), FALSE, FALSE, 0);
943 
944  selection = gtk_tree_view_get_selection(view);
945  gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
946  g_signal_connect(selection, "changed",
947  G_CALLBACK(gnc_option_list_changed_cb), option);
948 
949  bbox = gtk_vbutton_box_new();
950  gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_SPREAD);
951  gtk_box_pack_start(GTK_BOX(hbox), bbox, FALSE, FALSE, 10);
952 
953  button = gtk_button_new_with_label(_("Select All"));
954  gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
955  gtk_widget_set_tooltip_text(button, _("Select all entries."));
956 
957  g_signal_connect(G_OBJECT(button), "clicked",
958  G_CALLBACK(gnc_option_list_select_all_cb), option);
959 
960  button = gtk_button_new_with_label(_("Clear All"));
961  gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
962  gtk_widget_set_tooltip_text(button, _("Clear the selection and unselect all entries."));
963 
964  g_signal_connect(G_OBJECT(button), "clicked",
965  G_CALLBACK(gnc_option_list_clear_all_cb), option);
966 
967  button = gtk_button_new_with_label(_("Select Default"));
968  gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
969  gtk_widget_set_tooltip_text(button, _("Select the default selection."));
970 
971  g_signal_connect(G_OBJECT(button), "clicked",
972  G_CALLBACK(gnc_option_default_cb), option);
973 
974  gnc_option_set_widget (option, GTK_WIDGET(view));
975 
976  return frame;
977 }
978 
979 static void
980 gnc_option_color_changed_cb(GtkColorButton *color_button, GNCOption *option)
981 {
982  gnc_option_changed_widget_cb(GTK_WIDGET(color_button), option);
983 }
984 
985 static void
986 gnc_option_font_changed_cb(GtkFontButton *font_button, GNCOption *option)
987 {
988  gnc_option_changed_widget_cb(GTK_WIDGET(font_button), option);
989 }
990 
991 static void
992 gnc_option_set_ui_widget(GNCOption *option,
993  GtkBox *page_box)
994 {
995  GtkWidget *enclosing = NULL;
996  GtkWidget *value = NULL;
997  gboolean packed = FALSE;
998  char *raw_name, *raw_documentation;
999  char *name, *documentation;
1000  char *type;
1001  GNCOptionDef_t *option_def;
1002 
1003  ENTER("option %p(%s), box %p",
1004  option, gnc_option_name(option), page_box);
1005  type = gnc_option_type(option);
1006  if (type == NULL)
1007  {
1008  LEAVE("bad type");
1009  return;
1010  }
1011 
1012  raw_name = gnc_option_name(option);
1013  if (raw_name && *raw_name)
1014  name = _(raw_name);
1015  else
1016  name = NULL;
1017 
1018  raw_documentation = gnc_option_documentation(option);
1019  if (raw_documentation && *raw_documentation)
1020  documentation = _(raw_documentation);
1021  else
1022  documentation = NULL;
1023 
1024  option_def = gnc_options_ui_get_option (type);
1025  if (option_def && option_def->set_widget)
1026  {
1027  value = option_def->set_widget (option, page_box,
1028  name, documentation,
1029  /* Return values */
1030  &enclosing, &packed);
1031  }
1032  else
1033  {
1034  PERR("Unknown option type. Ignoring option \"%s\".\n", name);
1035  }
1036 
1037  if (!packed && (enclosing != NULL))
1038  {
1039  /* Pack option widget into an extra eventbox because otherwise the
1040  "documentation" tooltip is not displayed. */
1041  GtkWidget *eventbox = gtk_event_box_new();
1042 
1043  gtk_container_add (GTK_CONTAINER (eventbox), enclosing);
1044  gtk_box_pack_start (page_box, eventbox, FALSE, FALSE, 0);
1045 
1046  gtk_widget_set_tooltip_text (eventbox, documentation);
1047  }
1048 
1049  if (value != NULL)
1050  gtk_widget_set_tooltip_text(value, documentation);
1051 
1052  if (raw_name != NULL)
1053  free(raw_name);
1054  if (raw_documentation != NULL)
1055  free(raw_documentation);
1056  free(type);
1057  LEAVE(" ");
1058 }
1059 
1060 static void
1061 gnc_options_dialog_add_option(GtkWidget *page,
1062  GNCOption *option)
1063 {
1064  gnc_option_set_ui_widget(option, GTK_BOX(page));
1065 }
1066 
1067 static gint
1068 gnc_options_dialog_append_page(GNCOptionWin * propertybox,
1069  GNCOptionSection *section)
1070 {
1071  GNCOption *option;
1072  GtkWidget *page_label;
1073  GtkWidget *options_box;
1074  GtkWidget *page_content_box;
1075  GtkWidget* notebook_page;
1076  GtkWidget *reset_button;
1077  GtkWidget *listitem = NULL;
1078  GtkWidget *buttonbox;
1079  GtkWidget *options_scrolled_win;
1080  GtkTreeView *view;
1081  GtkListStore *list;
1082  GtkTreeIter iter;
1083  gint num_options;
1084  const char *name;
1085  gint i, page_count, name_offset;
1086  gboolean advanced;
1087 
1088  name = gnc_option_section_name(section);
1089  if (!name)
1090  return -1;
1091 
1092  if (strncmp(name, "__", 2) == 0)
1093  return -1;
1094  advanced = (strncmp(name, "_+", 2) == 0);
1095  name_offset = (advanced) ? 2 : 0;
1096  page_label = gtk_label_new(_(name + name_offset));
1097  PINFO("Page_label is %s", _(name + name_offset));
1098  gtk_widget_show(page_label);
1099 
1100  /* Build this options page */
1101  page_content_box = gtk_vbox_new(FALSE, 2);
1102  gtk_container_set_border_width(GTK_CONTAINER(page_content_box), 12);
1103 
1104  options_scrolled_win = gtk_scrolled_window_new(NULL, NULL);
1105  gtk_box_pack_start(GTK_BOX(page_content_box), options_scrolled_win, TRUE, TRUE, 0);
1106 
1107  /* Build space for the content - the options box */
1108  options_box = gtk_vbox_new(FALSE, 5);
1109  gtk_container_set_border_width(GTK_CONTAINER(options_box), 0);
1110  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(options_scrolled_win), options_box);
1111  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(options_scrolled_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1112 
1113  /* Create all the options */
1114  num_options = gnc_option_section_num_options(section);
1115  for (i = 0; i < num_options; i++)
1116  {
1117  option = gnc_get_option_section_option(section, i);
1118  gnc_options_dialog_add_option(options_box, option);
1119  }
1120 
1121  /* Add a button box at the bottom of the page */
1122  buttonbox = gtk_hbutton_box_new();
1123  gtk_button_box_set_layout (GTK_BUTTON_BOX (buttonbox),
1124  GTK_BUTTONBOX_EDGE);
1125  gtk_container_set_border_width(GTK_CONTAINER (buttonbox), 5);
1126  gtk_box_pack_end(GTK_BOX(page_content_box), buttonbox, FALSE, FALSE, 0);
1127 
1128  /* The reset button on each option page */
1129  reset_button = gtk_button_new_with_label (_("Reset defaults"));
1130  gtk_widget_set_tooltip_text(reset_button,
1131  _("Reset all values to their defaults."));
1132 
1133  g_signal_connect(G_OBJECT(reset_button), "clicked",
1134  G_CALLBACK(gnc_options_dialog_reset_cb), propertybox);
1135  g_object_set_data(G_OBJECT(reset_button), "section", section);
1136  gtk_box_pack_end(GTK_BOX(buttonbox), reset_button, FALSE, FALSE, 0);
1137  gtk_widget_show_all(page_content_box);
1138  gtk_notebook_append_page(GTK_NOTEBOOK(propertybox->notebook),
1139  page_content_box, page_label);
1140 
1141  /* Switch to selection from a list if the page count threshold is reached */
1142  page_count = gtk_notebook_page_num(GTK_NOTEBOOK(propertybox->notebook),
1143  page_content_box);
1144 
1145  if (propertybox->page_list_view)
1146  {
1147  /* Build the matching list item for selecting from large page sets */
1148  view = GTK_TREE_VIEW(propertybox->page_list_view);
1149  list = GTK_LIST_STORE(gtk_tree_view_get_model(view));
1150 
1151  PINFO("Page name is %s and page_count is %d", name, page_count);
1152  gtk_list_store_append(list, &iter);
1153  gtk_list_store_set(list, &iter,
1154  PAGE_NAME, _(name),
1155  PAGE_INDEX, page_count,
1156  -1);
1157 
1158  if (page_count > MAX_TAB_COUNT - 1) /* Convert 1-based -> 0-based */
1159  {
1160  gtk_widget_show(propertybox->page_list);
1161  gtk_notebook_set_show_tabs(GTK_NOTEBOOK(propertybox->notebook), FALSE);
1162  gtk_notebook_set_show_border(GTK_NOTEBOOK(propertybox->notebook), FALSE);
1163  }
1164  else
1165  gtk_widget_hide(propertybox->page_list);
1166 
1167  /* Tweak "advanced" pages for later handling. */
1168  if (advanced)
1169  {
1170  notebook_page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(propertybox->notebook),
1171  page_count);
1172 
1173  g_object_set_data(G_OBJECT(notebook_page), "listitem", listitem);
1174  g_object_set_data(G_OBJECT(notebook_page), "advanced",
1175  GINT_TO_POINTER(advanced));
1176  }
1177  }
1178  return(page_count);
1179 }
1180 
1181 /********************************************************************\
1182  * gnc_options_dialog_build_contents *
1183  * builds an options dialog given a property box and an options *
1184  * database and make the dialog visible *
1185  * *
1186  * Args: propertybox - gnome property box to use *
1187  * odb - option database to use *
1188  * Return: nothing *
1189 \********************************************************************/
1190 void
1191 gnc_options_dialog_build_contents (GNCOptionWin *propertybox,
1192  GNCOptionDB *odb)
1193 {
1194  gnc_options_dialog_build_contents_full (propertybox, odb, TRUE);
1195 }
1196 
1197 /********************************************************************\
1198  * gnc_options_dialog_build_contents *
1199  * builds an options dialog given a property box and an options *
1200  * database and make the dialog visible depending on the *
1201  * show_dialog flag *
1202  * *
1203  * Args: propertybox - gnome property box to use *
1204  * odb - option database to use *
1205  * show_dialog - should dialog be made visible or not *
1206  * Return: nothing *
1207 \********************************************************************/
1208 void
1209 gnc_options_dialog_build_contents_full (GNCOptionWin *propertybox,
1210  GNCOptionDB *odb, gboolean show_dialog)
1211 {
1212  GNCOptionSection *section;
1213  gchar *default_section_name;
1214  gint default_page = -1;
1215  gint num_sections;
1216  gint page;
1217  gint i;
1218  guint j;
1219 
1220  g_return_if_fail (propertybox != NULL);
1221  g_return_if_fail (odb != NULL);
1222 
1223  gnc_option_db_set_ui_callbacks (odb,
1224  gnc_option_get_ui_value_internal,
1225  gnc_option_set_ui_value_internal,
1226  gnc_option_set_selectable_internal);
1227 
1228  propertybox->option_db = odb;
1229 
1230  num_sections = gnc_option_db_num_sections(odb);
1231  default_section_name = gnc_option_db_get_default_section(odb);
1232 
1233  PINFO("Default Section name is %s", default_section_name);
1234 
1235  for (i = 0; i < num_sections; i++)
1236  {
1237  const char *section_name;
1238 
1239  section = gnc_option_db_get_section(odb, i);
1240  page = gnc_options_dialog_append_page(propertybox, section);
1241 
1242  section_name = gnc_option_section_name(section);
1243  if (g_strcmp0(section_name, default_section_name) == 0)
1244  default_page = page;
1245  }
1246 
1247  if (default_section_name != NULL)
1248  free(default_section_name);
1249 
1250  /* call each option widget changed callbacks once at this point,
1251  * now that all options widgets exist.
1252  */
1253  for (i = 0; i < num_sections; i++)
1254  {
1255  section = gnc_option_db_get_section(odb, i);
1256 
1257  for (j = 0; j < gnc_option_section_num_options(section); j++)
1258  {
1259  gnc_option_call_option_widget_changed_proc(
1260  gnc_get_option_section_option(section, j) );
1261  }
1262  }
1263 
1264  gtk_notebook_popup_enable(GTK_NOTEBOOK(propertybox->notebook));
1265  if (default_page >= 0)
1266  {
1267  /* Find the page list and set the selection to the default page */
1268  GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(propertybox->page_list_view));
1269  GtkTreeIter iter;
1270  GtkTreeModel *model;
1271 
1272  model = gtk_tree_view_get_model(GTK_TREE_VIEW(propertybox->page_list_view));
1273  gtk_tree_model_iter_nth_child(model, &iter, NULL, default_page);
1274  gtk_tree_selection_select_iter (selection, &iter);
1275  gtk_notebook_set_current_page(GTK_NOTEBOOK(propertybox->notebook), default_page);
1276  }
1277  gnc_options_dialog_changed_internal(propertybox->dialog, FALSE);
1278  if (show_dialog)
1279  gtk_widget_show(propertybox->dialog);
1280 }
1281 
1282 GtkWidget *
1283 gnc_options_dialog_widget(GNCOptionWin * win)
1284 {
1285  return win->dialog;
1286 }
1287 
1288 GtkWidget *
1289 gnc_options_page_list(GNCOptionWin * win)
1290 {
1291  return win->page_list;
1292 }
1293 
1294 GtkWidget *
1295 gnc_options_dialog_notebook(GNCOptionWin * win)
1296 {
1297  return win->notebook;
1298 }
1299 
1300 void
1301 gnc_options_dialog_response_cb(GtkDialog *dialog, gint response, GNCOptionWin *window)
1302 {
1303  GNCOptionWinCallback close_cb;
1304 
1305  switch (response)
1306  {
1307  case GTK_RESPONSE_HELP:
1308  if (window->help_cb)
1309  (window->help_cb)(window, window->help_cb_data);
1310  break;
1311 
1312  case GTK_RESPONSE_OK:
1313  case GTK_RESPONSE_APPLY:
1314  gnc_options_dialog_changed_internal (window->dialog, FALSE);
1315  close_cb = window->close_cb;
1316  window->close_cb = NULL;
1317  if (window->apply_cb)
1318  window->apply_cb (window, window->apply_cb_data);
1319  window->close_cb = close_cb;
1320  if (response == GTK_RESPONSE_APPLY)
1321  break;
1322  /* fall through */
1323 
1324  default:
1325  if (window->close_cb)
1326  {
1327  (window->close_cb)(window, window->close_cb_data);
1328  }
1329  else
1330  {
1331  gtk_widget_hide(window->dialog);
1332  }
1333  break;
1334  }
1335 }
1336 
1337 static void
1338 gnc_options_dialog_reset_cb(GtkWidget * w, gpointer data)
1339 {
1340  GNCOptionWin *win = data;
1341  GNCOptionSection *section;
1342  gpointer val;
1343 
1344  val = g_object_get_data(G_OBJECT(w), "section");
1345  g_return_if_fail (val);
1346  g_return_if_fail (win);
1347 
1348  section = (GNCOptionSection*)val;
1349  gnc_option_db_section_reset_widgets (section);
1350  gnc_options_dialog_changed_internal (win->dialog, TRUE);
1351 }
1352 
1353 void
1354 gnc_options_dialog_list_select_cb (GtkTreeSelection *selection,
1355  gpointer data)
1356 {
1357  GNCOptionWin * win = data;
1358  GtkTreeModel *list;
1359  GtkTreeIter iter;
1360  gint index = 0;
1361 
1362  if (!gtk_tree_selection_get_selected(selection, &list, &iter))
1363  return;
1364  gtk_tree_model_get(list, &iter,
1365  PAGE_INDEX, &index,
1366  -1);
1367  PINFO("Index is %d", index);
1368  gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), index);
1369 }
1370 
1371 void
1372 gnc_options_register_stocks (void)
1373 {
1374 #if 0
1375  static gboolean done = FALSE;
1376 
1377  GtkStockItem items[] =
1378  {
1379  { GTK_STOCK_APPLY , "gnc_option_apply_button", 0, 0, NULL },
1380  { GTK_STOCK_HELP , "gnc_options_dialog_help", 0, 0, NULL },
1381  { GTK_STOCK_OK , "gnc_options_dialog_ok", 0, 0, NULL },
1382  { GTK_STOCK_CANCEL , "gnc_options_dialog_cancel", 0, 0, NULL },
1383  };
1384 
1385  if (done)
1386  {
1387  return;
1388  }
1389  done = TRUE;
1390 
1391  gtk_stock_add (items, G_N_ELEMENTS (items));
1392 #endif
1393 }
1394 
1395 static void
1396 component_close_handler (gpointer data)
1397 {
1398  GNCOptionWin *window = data;
1399  gtk_dialog_response(GTK_DIALOG(window->dialog), GTK_RESPONSE_CANCEL);
1400 }
1401 
1402 /* gnc_options_dialog_new:
1403  *
1404  * - Opens the dialog-options glade file
1405  * - Connects signals specified in the builder file
1406  * - Sets the window's title
1407  * - Initializes a new GtkNotebook, and adds it to the window
1408  *
1409  */
1410 GNCOptionWin *
1411 gnc_options_dialog_new(gchar *title)
1412 {
1413  return gnc_options_dialog_new_modal(FALSE, title);
1414 }
1415 
1416 /* gnc_options_dialog_new_modal:
1417  *
1418  * - Opens the dialog-options glade file
1419  * - Connects signals specified in the builder file
1420  * - Sets the window's title
1421  * - Initializes a new GtkNotebook, and adds it to the window
1422  * - If modal TRUE, hides 'apply' button
1423  */
1424 GNCOptionWin *
1425 gnc_options_dialog_new_modal(gboolean modal, gchar *title)
1426 {
1427  GNCOptionWin *retval;
1428  GtkBuilder *builder;
1429  GtkWidget *hbox;
1430  gint component_id;
1431 
1432  retval = g_new0(GNCOptionWin, 1);
1433  builder = gtk_builder_new();
1434  gnc_builder_add_from_file (builder, "dialog-options.glade", "GnuCash Options");
1435  retval->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "GnuCash Options"));
1436  retval->page_list = GTK_WIDGET(gtk_builder_get_object (builder, "page_list_scroll"));
1437 
1438  /* Page List */
1439  {
1440  GtkTreeView *view;
1441  GtkListStore *store;
1442  GtkTreeSelection *selection;
1443  GtkCellRenderer *renderer;
1444  GtkTreeViewColumn *column;
1445 
1446  retval->page_list_view = GTK_WIDGET(gtk_builder_get_object (builder, "page_list_treeview"));
1447 
1448  view = GTK_TREE_VIEW(retval->page_list_view);
1449 
1450  store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING);
1451  gtk_tree_view_set_model(view, GTK_TREE_MODEL(store));
1452  g_object_unref(store);
1453 
1454  renderer = gtk_cell_renderer_text_new();
1455  column = gtk_tree_view_column_new_with_attributes(_("Page"), renderer,
1456  "text", PAGE_NAME, NULL);
1457  gtk_tree_view_append_column(view, column);
1458 
1459  gtk_tree_view_column_set_alignment(column, 0.5);
1460 
1461  selection = gtk_tree_view_get_selection(view);
1462  gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
1463  g_signal_connect (selection, "changed",
1464  G_CALLBACK (gnc_options_dialog_list_select_cb), retval);
1465 
1466  }
1467 
1468  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, retval);
1469 
1470  if (title)
1471  gtk_window_set_title(GTK_WINDOW(retval->dialog), title);
1472 
1473  /* modal */
1474  if (modal == TRUE)
1475  {
1476  GtkWidget *apply_button;
1477 
1478  apply_button = GTK_WIDGET(gtk_builder_get_object (builder, "applybutton"));
1479  gtk_widget_hide (apply_button);
1480  }
1481 
1482  /* glade doesn't suport a notebook with zero pages */
1483  hbox = GTK_WIDGET(gtk_builder_get_object (builder, "notebook placeholder"));
1484  retval->notebook = gtk_notebook_new();
1485  gtk_widget_show(retval->notebook);
1486  gtk_box_pack_start(GTK_BOX(hbox), retval->notebook, TRUE, TRUE, 5);
1487 
1488  component_id = gnc_register_gui_component (DIALOG_OPTIONS_CM_CLASS,
1489  NULL, component_close_handler,
1490  retval);
1491  gnc_gui_component_set_session (component_id, gnc_get_current_session());
1492 
1493  g_object_unref(G_OBJECT(builder));
1494 
1495  return retval;
1496 }
1497 
1498 /* Creates a new GNCOptionWin structure, but assumes you have your own
1499  dialog widget you want to plugin */
1500 GNCOptionWin *
1501 gnc_options_dialog_new_w_dialog(gchar *title, GtkWidget *dialog)
1502 {
1503  GNCOptionWin * retval;
1504 
1505  retval = g_new0(GNCOptionWin, 1);
1506  retval->dialog = dialog;
1507  return retval;
1508 }
1509 
1510 void
1511 gnc_options_dialog_set_apply_cb(GNCOptionWin * win, GNCOptionWinCallback cb,
1512  gpointer data)
1513 {
1514  win->apply_cb = cb;
1515  win->apply_cb_data = data;
1516 }
1517 
1518 void
1519 gnc_options_dialog_set_help_cb(GNCOptionWin * win, GNCOptionWinCallback cb,
1520  gpointer data)
1521 {
1522  win->help_cb = cb;
1523  win->help_cb_data = data;
1524 }
1525 
1526 void
1527 gnc_options_dialog_set_close_cb(GNCOptionWin * win, GNCOptionWinCallback cb,
1528  gpointer data)
1529 {
1530  win->close_cb = cb;
1531  win->close_cb_data = data;
1532 }
1533 
1534 void
1535 gnc_options_dialog_set_global_help_cb(GNCOptionWinCallback thunk,
1536  gpointer cb_data)
1537 {
1538  global_help_cb = thunk;
1539  global_help_cb_data = cb_data;
1540 }
1541 
1542 /* This is for global program preferences. */
1543 void
1544 gnc_options_dialog_destroy(GNCOptionWin * win)
1545 {
1546  if (!win) return;
1547 
1548  gnc_unregister_gui_component_by_data(DIALOG_OPTIONS_CM_CLASS, win);
1549 
1550  gtk_widget_destroy(win->dialog);
1551 
1552  win->dialog = NULL;
1553  win->notebook = NULL;
1554  win->apply_cb = NULL;
1555  win->help_cb = NULL;
1556 
1557  g_free(win);
1558 }
1559 
1560 /*****************************************************************/
1561 /* Option Registration */
1562 
1563 /*************************
1564  * SET WIDGET *
1565  *************************
1566  *
1567  * gnc_option_set_ui_widget_<type>():
1568  *
1569  * You should create the widget representation for the option type,
1570  * and set the top-level container widget for your control in
1571  * *enclosing. If you want to pack the widget into the page yourself,
1572  * then you may -- just set *packed to TRUE. Otherwise, the widget
1573  * you return in *enclosing will be packed for you. (*packed is
1574  * initialized to FALSE, so if you're not setting it to TRUE, you
1575  * don't have to touch it at all.)
1576  *
1577  * If you need to initialize the state of your control or to connect
1578  * any signals to you widgets, then you should do so in this function.
1579  * If you want to create a label for the widget you should use 'name'
1580  * for the label text.
1581  *
1582  * Somewhere in this function, you should also call
1583  * gnc_option_set_widget(option, value); where 'value' is the
1584  * GtkWidget you will actually store the value in.
1585  *
1586  * Also call gnc_option_set_ui_value(option, FALSE);
1587  *
1588  * You probably want to end with something like:
1589  * gtk_widget_show_all(*enclosing);
1590  *
1591  * If you can can detect state changes for your widget's value, you should also
1592  * gnc_option_changed_widget_cb() upon changes.
1593  *
1594  * The widget you return from this function should be the widget in
1595  * which you're storing the option value.
1596  */
1597 static GtkWidget *
1598 gnc_option_set_ui_widget_boolean (GNCOption *option, GtkBox *page_box,
1599  char *name, char *documentation,
1600  /* Return values */
1601  GtkWidget **enclosing, gboolean *packed)
1602 {
1603  GtkWidget *value;
1604 
1605  *enclosing = gtk_hbox_new(FALSE, 5);
1606  value = gtk_check_button_new_with_label(name);
1607 
1608  gnc_option_set_widget (option, value);
1609  gnc_option_set_ui_value(option, FALSE);
1610 
1611  g_signal_connect(G_OBJECT(value), "toggled",
1612  G_CALLBACK(gnc_option_changed_widget_cb), option);
1613 
1614  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
1615  gtk_widget_show_all(*enclosing);
1616 
1617  return value;
1618 }
1619 
1620 static GtkWidget *
1621 gnc_option_set_ui_widget_string (GNCOption *option, GtkBox *page_box,
1622  char *name, char *documentation,
1623  /* Return values */
1624  GtkWidget **enclosing, gboolean *packed)
1625 {
1626  GtkWidget *value;
1627  GtkWidget *label;
1628  gchar *colon_name;
1629 
1630  colon_name = g_strconcat(name, ":", NULL);
1631  label = gtk_label_new(colon_name);
1632  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1633  g_free(colon_name);
1634 
1635  *enclosing = gtk_hbox_new(FALSE, 5);
1636  value = gtk_entry_new();
1637 
1638  gnc_option_set_widget (option, value);
1639  gnc_option_set_ui_value(option, FALSE);
1640 
1641  g_signal_connect(G_OBJECT(value), "changed",
1642  G_CALLBACK(gnc_option_changed_widget_cb), option);
1643 
1644  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
1645  gtk_box_pack_start(GTK_BOX(*enclosing), value, TRUE, TRUE, 0);
1646  gtk_widget_show_all(*enclosing);
1647  return value;
1648 }
1649 
1650 static GtkWidget *
1651 gnc_option_set_ui_widget_text (GNCOption *option, GtkBox *page_box,
1652  char *name, char *documentation,
1653  /* Return values */
1654  GtkWidget **enclosing, gboolean *packed)
1655 {
1656  GtkWidget *value;
1657  GtkWidget *frame;
1658  GtkWidget *scroll;
1659  GtkTextBuffer* text_buffer;
1660 
1661  frame = gtk_frame_new(name);
1662 
1663  scroll = gtk_scrolled_window_new(NULL, NULL);
1664  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
1665  GTK_POLICY_NEVER,
1666  GTK_POLICY_AUTOMATIC);
1667  gtk_container_set_border_width(GTK_CONTAINER(scroll), 2);
1668 
1669  gtk_container_add(GTK_CONTAINER(frame), scroll);
1670 
1671  *enclosing = gtk_hbox_new(FALSE, 10);
1672  value = gtk_text_view_new();
1673  gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(value), GTK_WRAP_WORD);
1674  gtk_text_view_set_editable(GTK_TEXT_VIEW(value), TRUE);
1675  gtk_container_add (GTK_CONTAINER (scroll), value);
1676 
1677  gnc_option_set_widget (option, value);
1678  gnc_option_set_ui_value(option, FALSE);
1679 
1680  text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(value));
1681  g_signal_connect(G_OBJECT(text_buffer), "changed",
1682  G_CALLBACK(gnc_option_changed_option_cb), option);
1683 
1684  gtk_box_pack_start(GTK_BOX(*enclosing), frame, TRUE, TRUE, 0);
1685  gtk_widget_show_all(*enclosing);
1686  return value;
1687 }
1688 
1689 static GtkWidget *
1690 gnc_option_set_ui_widget_currency (GNCOption *option, GtkBox *page_box,
1691  char *name, char *documentation,
1692  /* Return values */
1693  GtkWidget **enclosing, gboolean *packed)
1694 {
1695  GtkWidget *value;
1696  GtkWidget *label;
1697  gchar *colon_name;
1698 
1699  colon_name = g_strconcat(name, ":", NULL);
1700  label = gtk_label_new(colon_name);
1701  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1702  g_free(colon_name);
1703 
1704  *enclosing = gtk_hbox_new(FALSE, 5);
1705  value = gnc_currency_edit_new();
1706 
1707  gnc_option_set_widget (option, value);
1708  gnc_option_set_ui_value(option, FALSE);
1709 
1710  g_signal_connect(G_OBJECT(value), "changed",
1711  G_CALLBACK(gnc_option_changed_widget_cb), option);
1712 
1713  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
1714  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
1715  gtk_widget_show_all(*enclosing);
1716  return value;
1717 }
1718 
1719 static GtkWidget *
1720 gnc_option_set_ui_widget_commodity (GNCOption *option, GtkBox *page_box,
1721  char *name, char *documentation,
1722  /* Return values */
1723  GtkWidget **enclosing, gboolean *packed)
1724 {
1725  GtkWidget *value;
1726  GtkWidget *label;
1727  gchar *colon_name;
1728 
1729  colon_name = g_strconcat(name, ":", NULL);
1730  label = gtk_label_new(colon_name);
1731  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1732  g_free(colon_name);
1733 
1734  *enclosing = gtk_hbox_new(FALSE, 5);
1735  value = gnc_general_select_new(GNC_GENERAL_SELECT_TYPE_SELECT,
1736  gnc_commodity_edit_get_string,
1737  gnc_commodity_edit_new_select,
1738  NULL);
1739 
1740  gnc_option_set_widget (option, value);
1741  gnc_option_set_ui_value(option, FALSE);
1742 
1743  if (documentation != NULL)
1744  gtk_widget_set_tooltip_text(GNC_GENERAL_SELECT(value)->entry,
1745  documentation);
1746 
1747  g_signal_connect(G_OBJECT(GNC_GENERAL_SELECT(value)->entry), "changed",
1748  G_CALLBACK(gnc_option_changed_widget_cb), option);
1749 
1750  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
1751  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
1752  gtk_widget_show_all(*enclosing);
1753  return value;
1754 }
1755 
1756 static GtkWidget *
1757 gnc_option_set_ui_widget_multichoice (GNCOption *option, GtkBox *page_box,
1758  char *name, char *documentation,
1759  /* Return values */
1760  GtkWidget **enclosing, gboolean *packed)
1761 {
1762  GtkWidget *value;
1763  GtkWidget *label;
1764  gchar *colon_name;
1765 
1766  colon_name = g_strconcat(name, ":", NULL);
1767  label = gtk_label_new(colon_name);
1768  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1769  g_free(colon_name);
1770 
1771  *enclosing = gtk_hbox_new(FALSE, 5);
1772 
1773  value = gnc_option_create_multichoice_widget(option);
1774  gnc_option_set_widget (option, value);
1775 
1776  gnc_option_set_ui_value(option, FALSE);
1777  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
1778  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
1779  gtk_widget_show_all(*enclosing);
1780  return value;
1781 }
1782 
1783 static GtkWidget *
1784 gnc_option_set_ui_widget_date (GNCOption *option, GtkBox *page_box,
1785  char *name, char *documentation,
1786  /* Return values */
1787  GtkWidget **enclosing, gboolean *packed)
1788 {
1789  GtkWidget *value;
1790  GtkWidget *label;
1791  gchar *colon_name;
1792  GtkWidget *eventbox;
1793 
1794  colon_name = g_strconcat(name, ":", NULL);
1795  label = gtk_label_new(colon_name);
1796  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1797  g_free(colon_name);
1798 
1799  *enclosing = gtk_hbox_new(FALSE, 5);
1800 
1801  value = gnc_option_create_date_widget(option);
1802 
1803  gnc_option_set_widget (option, value);
1804 
1805  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
1806  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
1807 
1808  /* Pack option widget into an extra eventbox because otherwise the
1809  "documentation" tooltip is not displayed. */
1810  eventbox = gtk_event_box_new();
1811  gtk_container_add (GTK_CONTAINER (eventbox), *enclosing);
1812  gtk_box_pack_start(page_box, eventbox, FALSE, FALSE, 5);
1813  *packed = TRUE;
1814 
1815  gtk_widget_set_tooltip_text (eventbox, documentation);
1816 
1817  gnc_option_set_ui_value(option, FALSE);
1818  gtk_widget_show_all(*enclosing);
1819  return value;
1820 }
1821 
1822 static GtkWidget *
1823 gnc_option_set_ui_widget_account_list (GNCOption *option, GtkBox *page_box,
1824  char *name, char *documentation,
1825  /* Return values */
1826  GtkWidget **enclosing, gboolean *packed)
1827 {
1828  GtkWidget *value;
1829  GtkTreeSelection *selection;
1830 
1831  *enclosing = gnc_option_create_account_widget(option, name);
1832  value = gnc_option_get_gtk_widget (option);
1833 
1834  gtk_widget_set_tooltip_text(*enclosing, documentation);
1835 
1836  gtk_box_pack_start(page_box, *enclosing, TRUE, TRUE, 5);
1837  *packed = TRUE;
1838 
1839  //gtk_widget_realize(value);
1840 
1841  gnc_option_set_ui_value(option, FALSE);
1842 
1843  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(value));
1844  g_signal_connect(G_OBJECT(selection), "changed",
1845  G_CALLBACK(gnc_option_account_cb), option);
1846 
1847  // gtk_clist_set_row_height(GTK_CLIST(value), 0);
1848  // gtk_widget_set_size_request(value, -1, GTK_CLIST(value)->row_height * 10);
1849  gtk_widget_show_all(*enclosing);
1850  return value;
1851 }
1852 
1853 static GtkWidget *
1854 gnc_option_set_ui_widget_account_sel (GNCOption *option, GtkBox *page_box,
1855  char *name, char *documentation,
1856  /* Return values */
1857  GtkWidget **enclosing, gboolean *packed)
1858 {
1859  GtkWidget *value;
1860  GtkWidget *label;
1861  GList *acct_type_list;
1862  gchar *colon_name;
1863 
1864  colon_name = g_strconcat(name, ":", NULL);
1865  label = gtk_label_new(colon_name);
1866  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1867  g_free(colon_name);
1868 
1869  acct_type_list = gnc_option_get_account_type_list(option);
1870  value = gnc_account_sel_new();
1871  gnc_account_sel_set_acct_filters(GNC_ACCOUNT_SEL(value), acct_type_list, NULL);
1872 
1873  g_signal_connect(value, "account_sel_changed",
1874  G_CALLBACK(gnc_option_changed_widget_cb), option);
1875 
1876  gnc_option_set_widget (option, value);
1877  /* DOCUMENT ME: Why is the only option type that sets use_default to
1878  TRUE? */
1879  gnc_option_set_ui_value(option, TRUE);
1880 
1881  *enclosing = gtk_hbox_new(FALSE, 5);
1882  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
1883  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
1884  gtk_widget_show_all(*enclosing);
1885  return value;
1886 }
1887 
1888 static GtkWidget *
1889 gnc_option_set_ui_widget_list (GNCOption *option, GtkBox *page_box,
1890  char *name, char *documentation,
1891  /* Return values */
1892  GtkWidget **enclosing, gboolean *packed)
1893 {
1894  GtkWidget *value;
1895  GtkWidget *eventbox;
1896 
1897  *enclosing = gnc_option_create_list_widget(option, name);
1898  value = gnc_option_get_gtk_widget (option);
1899 
1900  /* Pack option widget into an extra eventbox because otherwise the
1901  "documentation" tooltip is not displayed. */
1902  eventbox = gtk_event_box_new();
1903  gtk_container_add (GTK_CONTAINER (eventbox), *enclosing);
1904  gtk_box_pack_start(page_box, eventbox, FALSE, FALSE, 5);
1905  *packed = TRUE;
1906 
1907  gtk_widget_set_tooltip_text(eventbox, documentation);
1908 
1909  gnc_option_set_ui_value(option, FALSE);
1910  gtk_widget_show(*enclosing);
1911  return value;
1912 }
1913 
1914 static GtkWidget *
1915 gnc_option_set_ui_widget_number_range (GNCOption *option, GtkBox *page_box,
1916  char *name, char *documentation,
1917  /* Return values */
1918  GtkWidget **enclosing, gboolean *packed)
1919 {
1920  GtkWidget *value;
1921  GtkWidget *label;
1922  gchar *colon_name;
1923  GtkAdjustment *adj;
1924  gdouble lower_bound = G_MINDOUBLE;
1925  gdouble upper_bound = G_MAXDOUBLE;
1926  gdouble step_size = 1.0;
1927  int num_decimals = 0;
1928 
1929  colon_name = g_strconcat(name, ":", NULL);
1930  label = gtk_label_new(colon_name);
1931  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1932  g_free(colon_name);
1933 
1934  *enclosing = gtk_hbox_new(FALSE, 5);
1935 
1936  gnc_option_get_range_info(option, &lower_bound, &upper_bound,
1937  &num_decimals, &step_size);
1938  adj = GTK_ADJUSTMENT(gtk_adjustment_new(lower_bound, lower_bound,
1939  upper_bound, step_size,
1940  step_size * 5.0,
1941  0));
1942  value = gtk_spin_button_new(adj, step_size, num_decimals);
1943  gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(value), TRUE);
1944 
1945  {
1946  gdouble biggest;
1947  gint num_digits;
1948 
1949  biggest = ABS(lower_bound);
1950  biggest = MAX(biggest, ABS(upper_bound));
1951 
1952  num_digits = 0;
1953  while (biggest >= 1)
1954  {
1955  num_digits++;
1956  biggest = biggest / 10;
1957  }
1958 
1959  if (num_digits == 0)
1960  num_digits = 1;
1961 
1962  num_digits += num_decimals;
1963 
1964  gtk_entry_set_width_chars(GTK_ENTRY(value), num_digits);
1965  }
1966 
1967  gnc_option_set_widget (option, value);
1968  gnc_option_set_ui_value(option, FALSE);
1969 
1970  g_signal_connect(G_OBJECT(value), "changed",
1971  G_CALLBACK(gnc_option_changed_widget_cb), option);
1972 
1973  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
1974  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
1975  gtk_widget_show_all(*enclosing);
1976  return value;
1977 }
1978 
1979 static GtkWidget *
1980 gnc_option_set_ui_widget_color (GNCOption *option, GtkBox *page_box,
1981  char *name, char *documentation,
1982  /* Return values */
1983  GtkWidget **enclosing, gboolean *packed)
1984 {
1985  GtkWidget *value;
1986  GtkWidget *label;
1987  gchar *colon_name;
1988  gboolean use_alpha;
1989 
1990  colon_name = g_strconcat(name, ":", NULL);
1991  label = gtk_label_new(colon_name);
1992  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1993  g_free(colon_name);
1994 
1995  *enclosing = gtk_hbox_new(FALSE, 5);
1996 
1997  use_alpha = gnc_option_use_alpha(option);
1998 
1999  value = gtk_color_button_new();
2000  gtk_color_button_set_title(GTK_COLOR_BUTTON(value), name);
2001  gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(value), use_alpha);
2002 
2003  gnc_option_set_widget (option, value);
2004  gnc_option_set_ui_value(option, FALSE);
2005 
2006  g_signal_connect(G_OBJECT(value), "color-set",
2007  G_CALLBACK(gnc_option_color_changed_cb), option);
2008 
2009  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
2010  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
2011  gtk_widget_show_all(*enclosing);
2012  return value;
2013 }
2014 
2015 static GtkWidget *
2016 gnc_option_set_ui_widget_font (GNCOption *option, GtkBox *page_box,
2017  char *name, char *documentation,
2018  /* Return values */
2019  GtkWidget **enclosing, gboolean *packed)
2020 {
2021  GtkWidget *value;
2022  GtkWidget *label;
2023  gchar *colon_name;
2024 
2025  colon_name = g_strconcat(name, ":", NULL);
2026  label = gtk_label_new(colon_name);
2027  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
2028  g_free(colon_name);
2029 
2030  *enclosing = gtk_hbox_new(FALSE, 5);
2031  value = gtk_font_button_new();
2032  g_object_set(G_OBJECT(value),
2033  "use-font", TRUE,
2034  "show-style", TRUE,
2035  "show-size", TRUE,
2036  (char *)NULL);
2037 
2038  gnc_option_set_widget (option, value);
2039 
2040  gnc_option_set_ui_value(option, FALSE);
2041 
2042  g_signal_connect(G_OBJECT(value), "font-set",
2043  G_CALLBACK(gnc_option_font_changed_cb), option);
2044 
2045  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
2046  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
2047  gtk_widget_show_all(*enclosing);
2048  return value;
2049 }
2050 
2051 static GtkWidget *
2052 gnc_option_set_ui_widget_pixmap (GNCOption *option, GtkBox *page_box,
2053  char *name, char *documentation,
2054  /* Return values */
2055  GtkWidget **enclosing, gboolean *packed)
2056 {
2057  GtkWidget *value;
2058  GtkWidget *label;
2059  GtkWidget *button;
2060  gchar *colon_name;
2061 
2062  ENTER("option %p(%s), name %s", option, gnc_option_name(option), name);
2063  colon_name = g_strconcat(name, ":", NULL);
2064  label = gtk_label_new(colon_name);
2065  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
2066  g_free(colon_name);
2067 
2068  *enclosing = gtk_hbox_new(FALSE, 5);
2069 
2070  button = gtk_button_new_with_label(_("Clear"));
2071  gtk_widget_set_tooltip_text(button, _("Clear any selected image file."));
2072 
2073  value = gtk_file_chooser_button_new(_("Select image"),
2074  GTK_FILE_CHOOSER_ACTION_OPEN);
2075  gtk_widget_set_tooltip_text(value, _("Select an image file."));
2076  g_object_set(G_OBJECT(value),
2077  "width-chars", 30,
2078  "preview-widget", gtk_image_new(),
2079  (char *)NULL);
2080  g_signal_connect(G_OBJECT (value), "selection-changed",
2081  G_CALLBACK(gnc_option_changed_widget_cb), option);
2082  g_signal_connect(G_OBJECT (value), "selection-changed",
2083  G_CALLBACK(gnc_image_option_selection_changed_cb), option);
2084  g_signal_connect(G_OBJECT (value), "update-preview",
2085  G_CALLBACK(gnc_image_option_update_preview_cb), option);
2086  g_signal_connect_swapped(G_OBJECT (button), "clicked",
2087  G_CALLBACK(gtk_file_chooser_unselect_all), value);
2088 
2089  gnc_option_set_widget (option, value);
2090  gnc_option_set_ui_value(option, FALSE);
2091 
2092  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
2093  gtk_box_pack_end(GTK_BOX(*enclosing), button, FALSE, FALSE, 0);
2094  gtk_box_pack_end(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
2095 
2096  gtk_widget_show(value);
2097  gtk_widget_show(label);
2098  gtk_widget_show(*enclosing);
2099  LEAVE("new widget = %p", value);
2100  return value;
2101 }
2102 
2103 static GtkWidget *
2104 gnc_option_set_ui_widget_radiobutton (GNCOption *option, GtkBox *page_box,
2105  char *name, char *documentation,
2106  /* Return values */
2107  GtkWidget **enclosing, gboolean *packed)
2108 {
2109  GtkWidget *value;
2110 
2111  *enclosing = gtk_hbox_new(FALSE, 5);
2112 
2113  value = gnc_option_create_radiobutton_widget(name, option);
2114  gnc_option_set_widget (option, value);
2115 
2116  gnc_option_set_ui_value(option, FALSE);
2117  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
2118  gtk_widget_show_all(*enclosing);
2119  return value;
2120 }
2121 
2122 static GtkWidget *
2123 gnc_option_set_ui_widget_dateformat (GNCOption *option, GtkBox *page_box,
2124  char *name, char *documentation,
2125  /* Return values */
2126  GtkWidget **enclosing, gboolean *packed)
2127 {
2128  *enclosing = gnc_date_format_new_with_label(name);
2129  gnc_option_set_widget (option, *enclosing);
2130 
2131  gnc_option_set_ui_value(option, FALSE);
2132  g_signal_connect(G_OBJECT(*enclosing), "format_changed",
2133  G_CALLBACK(gnc_option_changed_option_cb), option);
2134  gtk_widget_show_all(*enclosing);
2135  return *enclosing;
2136 }
2137 
2138 static GtkWidget *
2139 gnc_option_set_ui_widget_budget (GNCOption *option, GtkBox *page_box,
2140  char *name, char *documentation,
2141  /* Return values */
2142  GtkWidget **enclosing, gboolean *packed)
2143 {
2144  GtkWidget *value;
2145  GtkWidget *label;
2146  gchar *colon_name;
2147 
2148  colon_name = g_strconcat(name, ":", NULL);
2149  label = gtk_label_new(colon_name);
2150  gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
2151  g_free(colon_name);
2152 
2153  *enclosing = gtk_hbox_new(FALSE, 5);
2154 
2155  value = gnc_option_create_budget_widget(option);
2156 
2157  gnc_option_set_widget (option, value);
2158  gnc_option_set_ui_value(option, FALSE);
2159 
2160  /* Maybe connect destroy handler for tree model here? */
2161  g_signal_connect(G_OBJECT(value), "changed",
2162  G_CALLBACK(gnc_option_changed_widget_cb), option);
2163 
2164  gtk_box_pack_start(GTK_BOX(*enclosing), label, FALSE, FALSE, 0);
2165  gtk_box_pack_start(GTK_BOX(*enclosing), value, FALSE, FALSE, 0);
2166  gtk_widget_show_all(*enclosing);
2167  return value;
2168 }
2169 
2170 /*************************
2171  * SET VALUE *
2172  *************************
2173  *
2174  * gnc_option_set_ui_value_<type>():
2175  *
2176  * In this function you should set the state of the gui widget to
2177  * correspond to the value provided in 'value'. You should return
2178  * TRUE if there was an error, FALSE otherwise.
2179  *
2180  *
2181  */
2182 static gboolean
2183 gnc_option_set_ui_value_boolean (GNCOption *option, gboolean use_default,
2184  GtkWidget *widget, SCM value)
2185 {
2186  if (scm_is_bool(value))
2187  {
2188  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
2189  scm_is_true(value));
2190  return FALSE;
2191  }
2192  else
2193  return TRUE;
2194 }
2195 
2196 static gboolean
2197 gnc_option_set_ui_value_string (GNCOption *option, gboolean use_default,
2198  GtkWidget *widget, SCM value)
2199 {
2200  if (scm_is_string(value))
2201  {
2202  const gchar *string;
2203 
2204  string = gnc_scm_to_utf8_string (value);
2205  gtk_entry_set_text(GTK_ENTRY(widget), string);
2206  g_free ((gpointer *) string);
2207  return FALSE;
2208  }
2209  else
2210  return TRUE;
2211 }
2212 
2213 static gboolean
2214 gnc_option_set_ui_value_text (GNCOption *option, gboolean use_default,
2215  GObject *object, SCM value)
2216 {
2217  GtkTextBuffer *buffer;
2218 
2219  if (GTK_IS_TEXT_BUFFER(object))
2220  buffer = GTK_TEXT_BUFFER(object);
2221  else
2222  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(object));
2223 
2224  if (scm_is_string(value))
2225  {
2226  const gchar *string;
2227 
2228  string = gnc_scm_to_utf8_string (value);
2229  gtk_text_buffer_set_text (buffer, string, scm_c_string_length(value));
2230  g_free ((gpointer *) string);
2231  return FALSE;
2232  }
2233  else
2234  return TRUE;
2235 }
2236 
2237 static gboolean
2238 gnc_option_set_ui_value_currency (GNCOption *option, gboolean use_default,
2239  GtkWidget *widget, SCM value)
2240 {
2241  gnc_commodity *commodity;
2242 
2243  commodity = gnc_scm_to_commodity (value);
2244  if (commodity)
2245  {
2246  gnc_currency_edit_set_currency(GNC_CURRENCY_EDIT(widget), commodity);
2247  return FALSE;
2248  }
2249  else
2250  return TRUE;
2251 }
2252 
2253 static gboolean
2254 gnc_option_set_ui_value_commodity (GNCOption *option, gboolean use_default,
2255  GtkWidget *widget, SCM value)
2256 {
2257  gnc_commodity *commodity;
2258 
2259  commodity = gnc_scm_to_commodity (value);
2260  if (commodity)
2261  {
2262  gnc_general_select_set_selected(GNC_GENERAL_SELECT (widget), commodity);
2263  return FALSE;
2264  }
2265  else
2266  return TRUE;
2267 }
2268 
2269 static gboolean
2270 gnc_option_set_ui_value_multichoice (GNCOption *option, gboolean use_default,
2271  GtkWidget *widget, SCM value)
2272 {
2273  int index;
2274 
2275  index = gnc_option_permissible_value_index(option, value);
2276  if (index < 0)
2277  return TRUE;
2278  else
2279  {
2280  /* GtkComboBox per-item tooltip changes needed below */
2281  gnc_combott_set_active(GNC_COMBOTT(widget), index);
2282  return FALSE;
2283  }
2284 }
2285 
2286 static gboolean
2287 gnc_option_set_ui_value_date (GNCOption *option, gboolean use_default,
2288  GtkWidget *widget, SCM value)
2289 {
2290  int index;
2291  char *date_option_type;
2292  char *symbol_str;
2293  gboolean bad_value = FALSE;
2294 
2295  date_option_type = gnc_option_date_option_get_subtype(option);
2296 
2297  if (scm_is_pair(value))
2298  {
2299  symbol_str = gnc_date_option_value_get_type (value);
2300  if (symbol_str)
2301  {
2302  if (g_strcmp0(symbol_str, "relative") == 0)
2303  {
2304  SCM relative = gnc_date_option_value_get_relative (value);
2305 
2306  index = gnc_option_permissible_value_index(option, relative);
2307  if (g_strcmp0(date_option_type, "relative") == 0)
2308  {
2309  /* GtkComboBox per-item tooltip changes needed below */
2310  gnc_combott_set_active(GNC_COMBOTT(widget), index);
2311  }
2312  else if (g_strcmp0(date_option_type, "both") == 0)
2313  {
2314  GList *widget_list;
2315  GtkWidget *rel_date_widget;
2316 
2317  widget_list = gtk_container_get_children(GTK_CONTAINER(widget));
2318  rel_date_widget = g_list_nth_data(widget_list,
2319  GNC_RD_WID_REL_WIDGET_POS);
2320  g_list_free(widget_list);
2321  gnc_date_option_set_select_method(option, FALSE, TRUE);
2322  /* GtkComboBox per-item tooltip changes needed below */
2323  gnc_combott_set_active(GNC_COMBOTT(rel_date_widget), index);
2324  }
2325  else
2326  {
2327  bad_value = TRUE;
2328  }
2329  }
2330  else if (g_strcmp0(symbol_str, "absolute") == 0)
2331  {
2332  Timespec ts;
2333 
2334  ts = gnc_date_option_value_get_absolute (value);
2335 
2336  if (g_strcmp0(date_option_type, "absolute") == 0)
2337  {
2338  gnc_date_edit_set_time(GNC_DATE_EDIT(widget), ts.tv_sec);
2339  }
2340  else if (g_strcmp0(date_option_type, "both") == 0)
2341  {
2342  GList *widget_list;
2343  GtkWidget *ab_widget;
2344 
2345  widget_list = gtk_container_get_children(GTK_CONTAINER(widget));
2346  ab_widget = g_list_nth_data(widget_list,
2347  GNC_RD_WID_AB_WIDGET_POS);
2348  g_list_free(widget_list);
2349  gnc_date_option_set_select_method(option, TRUE, TRUE);
2350  gnc_date_edit_set_time(GNC_DATE_EDIT(ab_widget), ts.tv_sec);
2351  }
2352  else
2353  {
2354  bad_value = TRUE;
2355  }
2356  }
2357  else
2358  {
2359  bad_value = TRUE;
2360  }
2361 
2362  if (symbol_str)
2363  free(symbol_str);
2364  }
2365  }
2366  else
2367  {
2368  bad_value = TRUE;
2369  }
2370 
2371  if (date_option_type)
2372  free(date_option_type);
2373 
2374  return bad_value;
2375 }
2376 
2377 static gboolean
2378 gnc_option_set_ui_value_account_list (GNCOption *option, gboolean use_default,
2379  GtkWidget *widget, SCM value)
2380 {
2381  GList *list;
2382 
2383  list = gnc_scm_list_to_glist(value);
2384 
2385  gnc_tree_view_account_set_selected_accounts (GNC_TREE_VIEW_ACCOUNT(widget),
2386  list, TRUE);
2387 
2388  g_list_free(list);
2389  return FALSE;
2390 }
2391 
2392 static gboolean
2393 gnc_option_set_ui_value_account_sel (GNCOption *option, gboolean use_default,
2394  GtkWidget *widget, SCM value)
2395 {
2396  Account *acc = NULL;
2397 
2398  if (value != SCM_BOOL_F)
2399  {
2400  if (!SWIG_IsPointer(value))
2401  scm_misc_error("gnc_option_set_ui_value_account_sel",
2402  "Option Value not a wcp.", value);
2403 
2404  acc = SWIG_MustGetPtr(value, SWIG_TypeQuery("_p_Account"), 4, 0);
2405  }
2406 
2407  //doesn't default because this function is called to set a specific account
2408  gnc_account_sel_set_account (GNC_ACCOUNT_SEL(widget), acc, FALSE);
2409 
2410  return FALSE;
2411 }
2412 
2413 static gboolean
2414 gnc_option_set_ui_value_list (GNCOption *option, gboolean use_default,
2415  GtkWidget *widget, SCM value)
2416 {
2417  GtkTreeSelection *selection;
2418  GtkTreePath *path;
2419  gint row;
2420 
2421  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
2422  gtk_tree_selection_unselect_all(selection);
2423 
2424  while (scm_is_list(value) && !scm_is_null(value))
2425  {
2426  SCM item;
2427 
2428  item = SCM_CAR(value);
2429  value = SCM_CDR(value);
2430 
2431  row = gnc_option_permissible_value_index(option, item);
2432  if (row < 0)
2433  {
2434  return TRUE;
2435  }
2436 
2437  path = gtk_tree_path_new_from_indices(row, -1);
2438  gtk_tree_selection_select_path(selection, path);
2439  gtk_tree_path_free(path);
2440  }
2441 
2442  if (!scm_is_list(value) || !scm_is_null(value))
2443  return TRUE;
2444 
2445  return FALSE;
2446 }
2447 
2448 static gboolean
2449 gnc_option_set_ui_value_number_range (GNCOption *option, gboolean use_default,
2450  GtkWidget *widget, SCM value)
2451 {
2452  GtkSpinButton *spinner;
2453  gdouble d_value;;
2454 
2455  spinner = GTK_SPIN_BUTTON(widget);
2456 
2457  if (scm_is_number(value))
2458  {
2459  d_value = scm_to_double(value);
2460  gtk_spin_button_set_value(spinner, d_value);
2461  return FALSE;
2462  }
2463  else
2464  return TRUE;
2465 }
2466 
2467 static gboolean
2468 gnc_option_set_ui_value_color (GNCOption *option, gboolean use_default,
2469  GtkWidget *widget, SCM value)
2470 {
2471  gdouble red, green, blue, alpha;
2472 
2473  if (gnc_option_get_color_info(option, use_default,
2474  &red, &green, &blue, &alpha))
2475  {
2476  GtkColorButton *color_button;
2477  GdkColor color;
2478 
2479  DEBUG("red %f, green %f, blue %f, alpha %f", red, green, blue, alpha);
2480  color_button = GTK_COLOR_BUTTON(widget);
2481 
2482  color.red = color_d_to_i16(red);
2483  color.green = color_d_to_i16(green);
2484  color.blue = color_d_to_i16(blue);
2485  gtk_color_button_set_color(color_button, &color);
2486  gtk_color_button_set_alpha(color_button, color_d_to_i16(alpha));
2487  return FALSE;
2488  }
2489 
2490  LEAVE("TRUE");
2491  return TRUE;
2492 }
2493 
2494 static gboolean
2495 gnc_option_set_ui_value_font (GNCOption *option, gboolean use_default,
2496  GtkWidget *widget, SCM value)
2497 {
2498  if (scm_is_string(value))
2499  {
2500  const gchar *string;
2501 
2502  string = gnc_scm_to_utf8_string (value);
2503  if ((string != NULL) && (*string != '\0'))
2504  {
2505  GtkFontButton *font_button = GTK_FONT_BUTTON(widget);
2506  gtk_font_button_set_font_name(font_button, string);
2507  }
2508  g_free ((gpointer *) string);
2509  return FALSE;
2510  }
2511  else
2512  return TRUE;
2513 }
2514 
2515 static gboolean
2516 gnc_option_set_ui_value_pixmap (GNCOption *option, gboolean use_default,
2517  GtkWidget *widget, SCM value)
2518 {
2519  ENTER("option %p(%s)", option, gnc_option_name(option));
2520  if (scm_is_string(value))
2521  {
2522  const gchar *string;
2523 
2524  string = gnc_scm_to_locale_string (value);
2525  if (string && *string)
2526  {
2527  gchar *test;
2528  DEBUG("string = %s", string);
2529  gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(widget), string);
2530  test = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
2531  g_object_set_data_full(G_OBJECT(widget), LAST_SELECTION,
2532  g_strdup(string), g_free);
2533  DEBUG("Set %s, retrieved %s", string, test ? test : "(null)");
2534  gnc_image_option_update_preview_cb(GTK_FILE_CHOOSER(widget), option);
2535  }
2536  LEAVE("FALSE");
2537  g_free ((gpointer *) string);
2538  return FALSE;
2539  }
2540 
2541  LEAVE("TRUE");
2542  return TRUE;
2543 }
2544 
2545 static gboolean gnc_option_set_ui_value_budget(
2546  GNCOption *option, gboolean use_default, GtkWidget *widget, SCM value)
2547 {
2548  GncBudget *bgt;
2549 
2550 // if (!scm_is_null(value)) {
2551  if (value != SCM_BOOL_F)
2552  {
2553  if (!SWIG_IsPointer(value))
2554  scm_misc_error("gnc_option_set_ui_value_budget",
2555  "Option Value not a wcp.", value);
2556 
2557  bgt = SWIG_MustGetPtr(value, SWIG_TypeQuery("GncBudget *"), 4, 0);
2558  if (bgt)
2559  {
2560  GtkComboBox *cb = GTK_COMBO_BOX(widget);
2561  GtkTreeModel *tm = gtk_combo_box_get_model(cb);
2562  GtkTreeIter iter;
2563  if (gnc_tree_model_budget_get_iter_for_budget(tm, &iter, bgt))
2564  gtk_combo_box_set_active_iter(cb, &iter);
2565  }
2566  }
2567 
2568 
2569  //FIXME: Unimplemented.
2570  return FALSE;
2571 }
2572 
2573 static gboolean
2574 gnc_option_set_ui_value_radiobutton (GNCOption *option, gboolean use_default,
2575  GtkWidget *widget, SCM value)
2576 {
2577  int index;
2578 
2579  index = gnc_option_permissible_value_index(option, value);
2580  if (index < 0)
2581  return TRUE;
2582  else
2583  {
2584  GtkWidget *box, *button;
2585  GList *list;
2586  int i;
2587  gpointer val;
2588 
2589  list = gtk_container_get_children (GTK_CONTAINER (widget));
2590  box = list->data;
2591  g_list_free(list);
2592 
2593  list = gtk_container_get_children (GTK_CONTAINER (box));
2594  for (i = 0; i < index && list; i++)
2595  list = list->next;
2596  g_return_val_if_fail (list, TRUE);
2597 
2598  button = list->data;
2599  g_list_free(list);
2600  val = g_object_get_data (G_OBJECT (button), "gnc_radiobutton_index");
2601  g_return_val_if_fail (GPOINTER_TO_INT (val) == index, TRUE);
2602 
2603  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
2604  // g_object_set_data(G_OBJECT(widget), "gnc_radiobutton_index",
2605  // GINT_TO_POINTER(index));
2606  return FALSE;
2607  }
2608 }
2609 
2610 static gboolean
2611 gnc_option_set_ui_value_dateformat (GNCOption *option, gboolean use_default,
2612  GtkWidget *widget, SCM value)
2613 {
2614  GNCDateFormat * gdf = GNC_DATE_FORMAT(widget);
2615  QofDateFormat format;
2616  GNCDateMonthFormat months;
2617  gboolean years;
2618  char *custom;
2619 
2620  if (gnc_dateformat_option_value_parse(value, &format, &months, &years, &custom))
2621  return TRUE;
2622 
2623  gnc_date_format_set_format(gdf, format);
2624  gnc_date_format_set_months(gdf, months);
2625  gnc_date_format_set_years(gdf, years);
2626  gnc_date_format_set_custom(gdf, custom);
2627  gnc_date_format_refresh(gdf);
2628 
2629  if (custom)
2630  free(custom);
2631 
2632  return FALSE;
2633 }
2634 
2635 /*************************
2636  * GET VALUE *
2637  *************************
2638  *
2639  * gnc_option_get_ui_value_<type>():
2640  *
2641  * 'widget' will be the widget returned from the
2642  * gnc_option_set_ui_widget_<type>() function.
2643  *
2644  * You should return a SCM value corresponding to the current state of the
2645  * gui widget.
2646  *
2647  */
2648 static SCM
2649 gnc_option_get_ui_value_boolean (GNCOption *option, GtkWidget *widget)
2650 {
2651  gboolean active;
2652 
2653  active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
2654  return SCM_BOOL(active);
2655 }
2656 
2657 static SCM
2658 gnc_option_get_ui_value_string (GNCOption *option, GtkWidget *widget)
2659 {
2660  char * string;
2661  SCM result;
2662 
2663  string = gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1);
2664  result = scm_from_utf8_string(string ? string : "");
2665  g_free(string);
2666  return result;
2667 }
2668 
2669 static SCM
2670 gnc_option_get_ui_value_text (GNCOption *option, GtkWidget *widget)
2671 {
2672  char * string;
2673  SCM result;
2674 
2675  string = xxxgtk_textview_get_text (GTK_TEXT_VIEW(widget));
2676  result = scm_from_utf8_string(string ? string : "");
2677  g_free(string);
2678  return result;
2679 }
2680 
2681 static SCM
2682 gnc_option_get_ui_value_currency (GNCOption *option, GtkWidget *widget)
2683 {
2684  gnc_commodity *commodity;
2685 
2686  commodity =
2687  gnc_currency_edit_get_currency(GNC_CURRENCY_EDIT(widget));
2688 
2689  return (gnc_commodity_to_scm (commodity));
2690 }
2691 
2692 static SCM
2693 gnc_option_get_ui_value_commodity (GNCOption *option, GtkWidget *widget)
2694 {
2695  gnc_commodity *commodity;
2696 
2697  commodity =
2698  gnc_general_select_get_selected(GNC_GENERAL_SELECT(widget));
2699 
2700  return (gnc_commodity_to_scm(commodity));
2701 }
2702 
2703 static SCM
2704 gnc_option_get_ui_value_multichoice (GNCOption *option, GtkWidget *widget)
2705 {
2706  int index;
2707 
2708  /* GtkComboBox per-item tooltip changes needed below */
2709  index = gnc_combott_get_active(GNC_COMBOTT(widget));
2710  return (gnc_option_permissible_value(option, index));
2711 }
2712 
2713 static SCM
2714 gnc_option_get_ui_value_date (GNCOption *option, GtkWidget *widget)
2715 {
2716  int index;
2717  SCM type, val, result = SCM_UNDEFINED;
2718  char *subtype = gnc_option_date_option_get_subtype(option);
2719 
2720  if (g_strcmp0(subtype, "relative") == 0)
2721  {
2722  /* GtkComboBox per-item tooltip changes needed below */
2723  index = gnc_combott_get_active(GNC_COMBOTT(widget));
2724 
2725  type = scm_from_locale_symbol ("relative");
2726  val = gnc_option_permissible_value(option, index);
2727  result = scm_cons(type, val);
2728  }
2729  else if (g_strcmp0(subtype, "absolute") == 0)
2730  {
2731  Timespec ts;
2732 
2733  ts.tv_sec = gnc_date_edit_get_date(GNC_DATE_EDIT(widget));
2734  ts.tv_nsec = 0;
2735 
2736  result = scm_cons(scm_from_locale_symbol ("absolute"), gnc_timespec2timepair(ts));
2737  }
2738  else if (g_strcmp0(subtype, "both") == 0)
2739  {
2740  Timespec ts;
2741  int index;
2742  SCM val;
2743  GList *widget_list;
2744  GtkWidget *ab_button, *rel_widget, *ab_widget;
2745 
2746  widget_list = gtk_container_get_children(GTK_CONTAINER(widget));
2747  ab_button = g_list_nth_data(widget_list, GNC_RD_WID_AB_BUTTON_POS);
2748  ab_widget = g_list_nth_data(widget_list, GNC_RD_WID_AB_WIDGET_POS);
2749  rel_widget = g_list_nth_data(widget_list, GNC_RD_WID_REL_WIDGET_POS);
2750  g_list_free(widget_list);
2751 
2752  /* if it's an absolute date */
2753  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ab_button)))
2754  {
2755  ts.tv_sec = gnc_date_edit_get_date(GNC_DATE_EDIT(ab_widget));
2756  ts.tv_nsec = 0;
2757  result = scm_cons(scm_from_locale_symbol ("absolute"), gnc_timespec2timepair(ts));
2758  }
2759  else
2760  {
2761  /* GtkComboBox per-item tooltip changes needed below */
2762  index = gnc_combott_get_active(GNC_COMBOTT(rel_widget));
2763 
2764  val = gnc_option_permissible_value(option, index);
2765  result = scm_cons(scm_from_locale_symbol ("relative"), val);
2766  }
2767  }
2768  g_free(subtype);
2769  return result;
2770 }
2771 
2772 static SCM
2773 gnc_option_get_ui_value_account_list (GNCOption *option, GtkWidget *widget)
2774 {
2775  GncTreeViewAccount *tree;
2776  GList *list;
2777  SCM result;
2778 
2779  tree = GNC_TREE_VIEW_ACCOUNT(widget);
2781 
2782  /* handover list */
2783  result = gnc_glist_to_scm_list(list, "_p_Account");
2784  g_list_free(list);
2785  return result;
2786 }
2787 
2788 static SCM
2789 gnc_option_get_ui_value_account_sel (GNCOption *option, GtkWidget *widget)
2790 {
2791  GNCAccountSel *gas;
2792  Account* acc;
2793 
2794  gas = GNC_ACCOUNT_SEL(widget);
2795  acc = gnc_account_sel_get_account (gas);
2796 
2797  if (!acc)
2798  return SCM_BOOL_F;
2799 
2800  return SWIG_NewPointerObj(acc, SWIG_TypeQuery("_p_Account"), 0);
2801 }
2802 
2803 static SCM
2804 gnc_option_get_ui_value_budget(GNCOption *option, GtkWidget *widget)
2805 {
2806  GncBudget *bgt;
2807  GtkComboBox *cb;
2808  GtkTreeModel *tm;
2809  GtkTreeIter iter;
2810 
2811  cb = GTK_COMBO_BOX(widget);
2812  gtk_combo_box_get_active_iter(cb, &iter);
2813  tm = gtk_combo_box_get_model(cb);
2814  bgt = gnc_tree_model_budget_get_budget(tm, &iter);
2815 
2816  if (!bgt)
2817  return SCM_BOOL_F;
2818 
2819  return SWIG_NewPointerObj(bgt, SWIG_TypeQuery("_p_budget_s"), 0);
2820 }
2821 
2822 static SCM
2823 gnc_option_get_ui_value_list (GNCOption *option, GtkWidget *widget)
2824 {
2825  GtkTreeSelection *selection;
2826  GtkTreePath *path;
2827  SCM result;
2828  gboolean selected;
2829  gint num_rows;
2830  gint row;
2831 
2832  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
2833  num_rows = gnc_option_num_permissible_values(option);
2834  result = scm_c_eval_string("'()");
2835 
2836  for (row = 0; row < num_rows; row++)
2837  {
2838  path = gtk_tree_path_new_from_indices(row, -1);
2839  selected = gtk_tree_selection_path_is_selected(selection, path);
2840  gtk_tree_path_free(path);
2841  if (selected)
2842  result = scm_cons(gnc_option_permissible_value(option, row), result);
2843  }
2844 
2845  return (scm_reverse(result));
2846 }
2847 
2848 static SCM
2849 gnc_option_get_ui_value_number_range (GNCOption *option, GtkWidget *widget)
2850 {
2851  GtkSpinButton *spinner;
2852  gdouble value;
2853 
2854  spinner = GTK_SPIN_BUTTON(widget);
2855 
2856  value = gtk_spin_button_get_value(spinner);
2857 
2858  return (scm_from_double (value));
2859 }
2860 
2861 static SCM
2862 gnc_option_get_ui_value_color (GNCOption *option, GtkWidget *widget)
2863 {
2864  SCM result;
2865  GtkColorButton *color_button;
2866  GdkColor color;
2867  gdouble red, green, blue, alpha;
2868  gdouble scale;
2869 
2870  ENTER("option %p(%s), widget %p",
2871  option, gnc_option_name(option), widget);
2872 
2873  color_button = GTK_COLOR_BUTTON(widget);
2874  gtk_color_button_get_color(color_button, &color);
2875  red = color_i16_to_d(color.red);
2876  green = color_i16_to_d(color.green);
2877  blue = color_i16_to_d(color.blue);
2878  alpha = color_i16_to_d(gtk_color_button_get_alpha(color_button));
2879 
2880  scale = gnc_option_color_range(option);
2881 
2882  result = SCM_EOL;
2883  result = scm_cons(scm_from_double (alpha * scale), result);
2884  result = scm_cons(scm_from_double (blue * scale), result);
2885  result = scm_cons(scm_from_double (green * scale), result);
2886  result = scm_cons(scm_from_double (red * scale), result);
2887  return result;
2888 }
2889 
2890 static SCM
2891 gnc_option_get_ui_value_font (GNCOption *option, GtkWidget *widget)
2892 {
2893  GtkFontButton *font_button = GTK_FONT_BUTTON(widget);
2894  const gchar * string;
2895 
2896  string = gtk_font_button_get_font_name(font_button);
2897  return (string ? scm_from_utf8_string(string) : SCM_BOOL_F);
2898 }
2899 
2900 static SCM
2901 gnc_option_get_ui_value_pixmap (GNCOption *option, GtkWidget *widget)
2902 {
2903  gchar *string;
2904  SCM result;
2905 
2906  string = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
2907  DEBUG("filename %s", string ? string : "(null)");
2908  result = scm_from_utf8_string(string ? string : "");
2909  g_free(string);
2910  return result;
2911 }
2912 
2913 static SCM
2914 gnc_option_get_ui_value_radiobutton (GNCOption *option, GtkWidget *widget)
2915 {
2916  gpointer _index;
2917  int index;
2918 
2919  _index = g_object_get_data(G_OBJECT(widget), "gnc_radiobutton_index");
2920  index = GPOINTER_TO_INT(_index);
2921 
2922  return (gnc_option_permissible_value(option, index));
2923 }
2924 
2925 static SCM
2926 gnc_option_get_ui_value_dateformat (GNCOption *option, GtkWidget *widget)
2927 {
2928  GNCDateFormat *gdf = GNC_DATE_FORMAT(widget);
2929  QofDateFormat format;
2930  GNCDateMonthFormat months;
2931  gboolean years;
2932  const char* custom;
2933 
2934  format = gnc_date_format_get_format(gdf);
2935  months = gnc_date_format_get_months(gdf);
2936  years = gnc_date_format_get_years(gdf);
2937  custom = gnc_date_format_get_custom(gdf);
2938 
2939  return (gnc_dateformat_option_set_value(format, months, years, custom));
2940 }
2941 
2942 /************************************/
2943 /* INITIALIZATION */
2944 /************************************/
2945 static void gnc_options_initialize_options (void)
2946 {
2947  static GNCOptionDef_t options[] =
2948  {
2949  {
2950  "boolean", gnc_option_set_ui_widget_boolean,
2951  gnc_option_set_ui_value_boolean, gnc_option_get_ui_value_boolean
2952  },
2953  {
2954  "string", gnc_option_set_ui_widget_string,
2955  gnc_option_set_ui_value_string, gnc_option_get_ui_value_string
2956  },
2957  {
2958  "text", gnc_option_set_ui_widget_text,
2959  (GNCOptionUISetValue)gnc_option_set_ui_value_text,
2960  gnc_option_get_ui_value_text
2961  },
2962  {
2963  "currency", gnc_option_set_ui_widget_currency,
2964  gnc_option_set_ui_value_currency, gnc_option_get_ui_value_currency
2965  },
2966  {
2967  "commodity", gnc_option_set_ui_widget_commodity,
2968  gnc_option_set_ui_value_commodity, gnc_option_get_ui_value_commodity
2969  },
2970  {
2971  "multichoice", gnc_option_set_ui_widget_multichoice,
2972  gnc_option_set_ui_value_multichoice, gnc_option_get_ui_value_multichoice
2973  },
2974  {
2975  "date", gnc_option_set_ui_widget_date,
2976  gnc_option_set_ui_value_date, gnc_option_get_ui_value_date
2977  },
2978  {
2979  "account-list", gnc_option_set_ui_widget_account_list,
2980  gnc_option_set_ui_value_account_list, gnc_option_get_ui_value_account_list
2981  },
2982  {
2983  "account-sel", gnc_option_set_ui_widget_account_sel,
2984  gnc_option_set_ui_value_account_sel, gnc_option_get_ui_value_account_sel
2985  },
2986  {
2987  "list", gnc_option_set_ui_widget_list,
2988  gnc_option_set_ui_value_list, gnc_option_get_ui_value_list
2989  },
2990  {
2991  "number-range", gnc_option_set_ui_widget_number_range,
2992  gnc_option_set_ui_value_number_range, gnc_option_get_ui_value_number_range
2993  },
2994  {
2995  "color", gnc_option_set_ui_widget_color,
2996  gnc_option_set_ui_value_color, gnc_option_get_ui_value_color
2997  },
2998  {
2999  "font", gnc_option_set_ui_widget_font,
3000  gnc_option_set_ui_value_font, gnc_option_get_ui_value_font
3001  },
3002  {
3003  "pixmap", gnc_option_set_ui_widget_pixmap,
3004  gnc_option_set_ui_value_pixmap, gnc_option_get_ui_value_pixmap
3005  },
3006  {
3007  "radiobutton", gnc_option_set_ui_widget_radiobutton,
3008  gnc_option_set_ui_value_radiobutton, gnc_option_get_ui_value_radiobutton
3009  },
3010  {
3011  "dateformat", gnc_option_set_ui_widget_dateformat,
3012  gnc_option_set_ui_value_dateformat, gnc_option_get_ui_value_dateformat
3013  },
3014  {
3015  "budget", gnc_option_set_ui_widget_budget,
3016  gnc_option_set_ui_value_budget, gnc_option_get_ui_value_budget
3017  },
3018  { NULL, NULL, NULL, NULL }
3019  };
3020  int i;
3021 
3022  for (i = 0; options[i].option_name; i++)
3023  gnc_options_ui_register_option (&(options[i]));
3024 }
3025 
3026 /* Register a new option type in the UI */
3027 void gnc_options_ui_register_option (GNCOptionDef_t *option)
3028 {
3029  g_return_if_fail (optionTable);
3030  g_return_if_fail (option);
3031 
3032  /* FIXME: should protect against repeat insertion. */
3033  g_hash_table_insert (optionTable, (gpointer)(option->option_name), option);
3034 }
3035 
3036 GNCOptionDef_t * gnc_options_ui_get_option (const char *option_name)
3037 {
3038  GNCOptionDef_t *retval;
3039  g_return_val_if_fail (optionTable, NULL);
3040  g_return_val_if_fail (option_name, NULL);
3041 
3042  retval = g_hash_table_lookup (optionTable, option_name);
3043  if (!retval)
3044  {
3045  PERR("Option lookup for type '%s' failed!", option_name);
3046  }
3047  return retval;
3048 }
3049 
3050 void gnc_options_ui_initialize (void)
3051 {
3052  SWIG_GetModule(NULL); /* Work-around for SWIG bug. */
3053  // gnc_options_register_stocks ();
3054  g_return_if_fail (optionTable == NULL);
3055  optionTable = g_hash_table_new (g_str_hash, g_str_equal);
3056 
3057  /* add known types */
3058  gnc_options_initialize_options ();
3059 }
3060 
3061 struct scm_cb
3062 {
3063  SCM apply_cb;
3064  SCM close_cb;
3065 };
3066 
3067 static void
3068 scm_apply_cb (GNCOptionWin *win, gpointer data)
3069 {
3070  struct scm_cb *cbdata = data;
3071 
3072  if (gnc_option_db_get_changed (win->option_db))
3073  {
3074  gnc_option_db_commit (win->option_db);
3075  if (cbdata->apply_cb != SCM_BOOL_F)
3076  {
3077  scm_call_0 (cbdata->apply_cb);
3078  }
3079  }
3080 }
3081 
3082 static void
3083 scm_close_cb (GNCOptionWin *win, gpointer data)
3084 {
3085  struct scm_cb *cbdata = data;
3086 
3087  if (cbdata->close_cb != SCM_BOOL_F)
3088  {
3089  scm_call_0 (cbdata->close_cb);
3090  scm_gc_unprotect_object (cbdata->close_cb);
3091  }
3092 
3093  if (cbdata->apply_cb != SCM_BOOL_F)
3094  scm_gc_unprotect_object (cbdata->apply_cb);
3095 
3096  g_free (cbdata);
3097 }
3098 
3099 /* Both apply_cb and close_cb should be scheme functions with 0 arguments.
3100  * References to these functions will be held until the close_cb is called
3101  */
3102 void
3103 gnc_options_dialog_set_scm_callbacks (GNCOptionWin *win, SCM apply_cb,
3104  SCM close_cb)
3105 {
3106  struct scm_cb *cbdata;
3107 
3108  cbdata = g_new0 (struct scm_cb, 1);
3109  cbdata->apply_cb = apply_cb;
3110  cbdata->close_cb = close_cb;
3111 
3112  if (apply_cb != SCM_BOOL_F)
3113  scm_gc_protect_object (cbdata->apply_cb);
3114 
3115  if (close_cb != SCM_BOOL_F)
3116  scm_gc_protect_object (cbdata->close_cb);
3117 
3118  gnc_options_dialog_set_apply_cb (win, scm_apply_cb, cbdata);
3119  gnc_options_dialog_set_close_cb (win, scm_close_cb, cbdata);
3120 }
void gnc_tree_view_account_get_view_info(GncTreeViewAccount *account_view, AccountViewInfo *avi)
void gnc_currency_edit_set_currency(GNCCurrencyEdit *gce, const gnc_commodity *currency)
GList * gnc_tree_view_account_get_selected_accounts(GncTreeViewAccount *view)
Account * gnc_tree_view_account_get_cursor_account(GncTreeViewAccount *view)
#define PINFO(format, args...)
Definition: qoflog.h:249
GnuCash Budgets.
#define DEBUG(format, args...)
Definition: qoflog.h:255
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
void gnc_tree_view_account_set_view_info(GncTreeViewAccount *account_view, AccountViewInfo *avi)
#define PERR(format, args...)
Definition: qoflog.h:237
#define ENTER(format, args...)
Definition: qoflog.h:261
void gnc_tree_view_account_set_selected_accounts(GncTreeViewAccount *view, GList *account_list, gboolean show_last)
Currency selection widget.
void gnc_tree_view_account_select_subaccounts(GncTreeViewAccount *view, Account *account)
GtkTreeView implementation for gnucash account tree.
GtkTreeView * gnc_tree_view_account_new(gboolean show_root)
gnc_commodity * gnc_currency_edit_get_currency(GNCCurrencyEdit *gce)
GNCDateMonthFormat
Definition: gnc-date.h:150
All type declarations for the whole Gnucash engine.
GNCAccountType
Definition: Account.h:96
Generic api to store and retrieve preferences.
GtkWidget * gnc_currency_edit_new(void)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:196
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofDateFormat
Definition: gnc-date.h:121
provides some utilities for working with the list of budgets in a book.
const gchar * QofLogModule
Definition: qofid.h:89