GnuCash  4.11-627-g58c1a51897
dialog-options.cpp
1 /********************************************************************\
2  * dialog-options.cpp -- option handling *
3  * Copyright (C) 1998-2000 Linas Vepstas *
4  * Copyright (c) 2006 David Hampton <hampton@employees.org> *
5  * Copyright (c) 2011 Robert Fewell *
6  * Copyright 2020 John Ralls *
7  * *
8  * This program is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU General Public License as *
10  * published by the Free Software Foundation; either version 2 of *
11  * the License, or (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License*
19  * along with this program; if not, contact: *
20  * *
21  * Free Software Foundation Voice: +1-617-542-5942 *
22  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
23  * Boston, MA 02110-1301, USA gnu@gnu.org *
24 \********************************************************************/
25 
26 extern "C"
27 {
28 #include <config.h> // Need this to include Account.h
29 }
30 
31 #include <Account.h> // To include as C++ overriding later indirect includes
32 #include <libguile.h>
33 #include <gtk/gtk.h>
34 #include <gdk/gdk.h>
35 #include <glib/gi18n.h>
36 
37 extern "C"
38 {
39 #include <qofbookslots.h> // for OPTION_SECTION_ACCOUNTS
40 
41 #include "dialog-utils.h"
42 #include "gnc-component-manager.h"
43 #include <gnc-prefs.h> // for GNC_PREFS_NUM_SOURCE
44 #include "gnc-session.h" // for gnc_get_current_session
45 #include "gnc-ui.h" // for HF_HELP
46 }
47 
48 #include <iostream>
49 #include <sstream>
50 
51 #include "dialog-options.hpp"
52 #include "gnc-option-gtk-ui.hpp"
53 #include <gnc-optiondb.hpp>
54 #include <gnc-optiondb-impl.hpp>
55 
56 #define GNC_PREF_CLOCK_24H "clock-24h"
57 
58 /* This static indicates the debugging module that this .o belongs to. */
59 static QofLogModule log_module = GNC_MOD_GUI;
60 
61 static constexpr const char* DIALOG_OPTIONS_CM_CLASS{"dialog-options"};
62 static constexpr const char* GNC_PREFS_GROUP{"dialogs.options"};
63 
64 /*
65  * Point where preferences switch control method from a set of
66  * notebook tabs to a list.
67  */
68 #define MAX_TAB_COUNT 6
69 
70 
71 
72 enum page_tree
73 {
74  PAGE_INDEX = 0,
75  PAGE_NAME,
76  NUM_COLUMNS
77 };
78 
79 
80 static void dialog_reset_cb(GtkWidget * w, gpointer data);
81 static void dialog_list_select_cb (GtkTreeSelection *selection, gpointer data);
82 static void component_close_handler (gpointer data);
83 
84 static void
85 section_reset_widgets(GncOptionSection* section)
86 {
87 }
88 
89 static inline GtkWidget* const
90 option_get_gtk_widget (const GncOption* option)
91 {
92  if (!option) return nullptr;
93  auto ui_item{dynamic_cast<const GncOptionGtkUIItem*>(option->get_ui_item())};
94  if (ui_item)
95  return ui_item->get_widget();
96 
97  return nullptr;
98 }
99 
100 static void
101 dialog_changed_internal (GtkWidget *widget, bool sensitive)
102 {
103  g_return_if_fail(widget);
104 
105  auto toplevel{gtk_widget_get_toplevel(widget)};
106  if (toplevel == widget && !GTK_IS_WINDOW(toplevel))
107  return;
108  g_assert(toplevel && GTK_IS_WINDOW(toplevel));
109 
110  auto option_win =
111  static_cast<GncOptionsDialog*>(g_object_get_data(G_OBJECT(toplevel),
112  "optionwin"));
113 
114  if (option_win) // this null when part of assistant
115  option_win->set_sensitive(sensitive);
116 }
117 
118 void
119 GncOptionsDialog::set_sensitive(bool sensitive) noexcept
120 {
121  gtk_widget_set_sensitive (GTK_WIDGET(m_apply_button), sensitive);
122  gtk_widget_set_sensitive (GTK_WIDGET(m_ok_button), sensitive);
123  gtk_button_set_label (m_cancel_button,
124  sensitive ? _("_Cancel") : _("_Close"));
125 }
126 
127 void
128 GncOptionsDialog::changed() noexcept
129 {
130  set_sensitive(true);
131 }
132 
133 void
134 gnc_option_changed_widget_cb(GtkWidget *widget, GncOption* option)
135 {
136  if (!option) return;
137  auto ui_item{option->get_ui_item()};
138  auto widget_changed_cb{option->get_widget_changed()};
139  auto gtk_ui_item{dynamic_cast<GncOptionGtkUIItem*>(ui_item)};
140  if (widget_changed_cb && gtk_ui_item)
141  {
142  SCM widget_value{gtk_ui_item->get_widget_scm_value(*option)};
143  scm_call_1(static_cast<SCM>(widget_changed_cb), widget_value);
144  }
145  const_cast<GncOptionUIItem*>(ui_item)->set_dirty(true);
146  dialog_changed_internal(widget, true);
147 }
148 
149 void
150 gnc_option_changed_option_cb(GtkWidget *dummy, GncOption* option)
151 {
152  if (!option) return;
153  auto widget{option_get_gtk_widget(option)};
154  gnc_option_changed_widget_cb(widget, option);
155 }
156 
157 
158 // This do-nothing template is specialized for each GncOptionUIType.
159 template<GncOptionUIType type> GtkWidget*
160 create_option_widget(GncOption& option, GtkGrid*, GtkLabel*, char*, GtkWidget**,
161  bool*)
162 {
163  return nullptr;
164 }
165 
166 static void
167 gnc_option_set_ui_widget(GncOption& option, GtkGrid *page_box, gint grid_row)
168 {
169  ENTER("option %p(%s), box %p",
170  &option, option.get_name().c_str(), page_box);
171  auto type = option.get_ui_type();
172  if (type == GncOptionUIType::INTERNAL)
173  {
174  LEAVE("internal type");
175  return;
176  }
177 
178  GncOptionUIFactory::create(option, page_box, grid_row);
179 
180  LEAVE(" ");
181 }
182 
183 static GtkBox*
184 create_content_box()
185 {
186  auto content_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
187  gtk_widget_set_name (content_box, "page-content-box");
188  gtk_box_set_homogeneous (GTK_BOX (content_box), FALSE);
189 
190  gtk_container_set_border_width(GTK_CONTAINER(content_box), 12);
191  return GTK_BOX(content_box);
192 }
193 
194 static GtkGrid*
195 create_options_box(GtkBox* content_box)
196 {
197  auto options_scrolled_win = gtk_scrolled_window_new(NULL, NULL);
198  gtk_box_pack_start(GTK_BOX(content_box), options_scrolled_win,
199  TRUE, TRUE, 0);
200 
201  /* Build space for the content - the options box */
202  auto options_box = gtk_grid_new(); // this will have two columns
203  gtk_widget_set_name (options_box, "options-box");
204  gtk_grid_set_row_homogeneous (GTK_GRID(options_box), FALSE);
205  gtk_grid_set_column_homogeneous (GTK_GRID(options_box), FALSE);
206  gtk_grid_set_row_spacing (GTK_GRID(options_box), 6);
207  gtk_grid_set_column_spacing (GTK_GRID(options_box), 6);
208 
209  gtk_container_set_border_width(GTK_CONTAINER(options_box), 0);
210  gtk_container_add (GTK_CONTAINER(options_scrolled_win),
211  GTK_WIDGET(options_box));
212  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(options_scrolled_win),
213  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
214  return GTK_GRID(options_box);
215 }
216 
217 static GtkButtonBox*
218 create_reset_button_box(GtkBox* page_content_box)
219 {
220  auto buttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
221  gtk_button_box_set_layout (GTK_BUTTON_BOX (buttonbox),
222  GTK_BUTTONBOX_EDGE);
223  gtk_container_set_border_width(GTK_CONTAINER (buttonbox), 5);
224  gtk_box_pack_end(GTK_BOX(page_content_box), buttonbox, FALSE, FALSE, 0);
225  return GTK_BUTTON_BOX(buttonbox);
226 }
227 
228 static int
229 setup_notebook_pages(GncOptionsDialog* dlg, GtkBox* page_content_box,
230  const char* name)
231 {
232  auto notebook{dlg->get_notebook()};
233  auto page_count = gtk_notebook_page_num(GTK_NOTEBOOK(notebook),
234  GTK_WIDGET(page_content_box));
235 
236  if (dlg->get_page_list_view())
237  {
238  /* Build the matching list item for selecting from large page sets */
239  auto view = GTK_TREE_VIEW(dlg->get_page_list_view());
240  auto list = GTK_LIST_STORE(gtk_tree_view_get_model(view));
241 
242  PINFO("Page name is %s and page_count is %d", name, page_count);
243  GtkTreeIter iter;
244  gtk_list_store_append(list, &iter);
245  gtk_list_store_set(list, &iter,
246  PAGE_NAME, _(name),
247  PAGE_INDEX, page_count,
248  -1);
249 
250  if (page_count > MAX_TAB_COUNT - 1) /* Convert 1-based -> 0-based */
251  {
252  gtk_widget_show(dlg->get_page_list());
253  gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);
254  gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), FALSE);
255  }
256  else
257  gtk_widget_hide(dlg->get_page_list());
258 
259  }
260  return page_count;
261 }
262 
263 static int
264 dialog_append_page(GncOptionsDialog* dlg, GncOptionSectionPtr& section)
265 {
266  auto name = section->get_name().c_str();
267  if (!name || *name == '\0')
268  return -1;
269 
270  if (strncmp(name, "__", 2) == 0)
271  return -1;
272 
273  auto page_label = gtk_label_new(_(name));
274  PINFO("Page_label is %s", _(name));
275  gtk_widget_show(page_label);
276 
277  /* Build this options page */
278  auto page_content_box = create_content_box();
279  auto options_box = create_options_box(page_content_box);
280 
281  /* Create all the options */
282  size_t row = 0;
283  section->foreach_option(
284  [options_box, &row](GncOption& option) {
285  g_object_set_data (G_OBJECT(options_box), "options-grid-row",
286  GINT_TO_POINTER(row));
287  gnc_option_set_ui_widget(option, GTK_GRID(options_box), row);
288  ++row;
289  });
290 
291  /* Add a button box at the bottom of the page */
292  auto buttonbox = create_reset_button_box(page_content_box);
293  /* The reset button on each option page */
294  auto reset_button = gtk_button_new_with_label (_("Reset defaults"));
295  gtk_widget_set_tooltip_text(reset_button,
296  _("Reset all values to their defaults."));
297 
298  g_signal_connect(G_OBJECT(reset_button), "clicked",
299  G_CALLBACK(dialog_reset_cb), dlg);
300  g_object_set_data(G_OBJECT(reset_button), "section",
301  static_cast<void*>(section.get()));
302  gtk_box_pack_end(GTK_BOX(buttonbox), reset_button, FALSE, FALSE, 0);
303  gtk_widget_show_all(GTK_WIDGET(page_content_box));
304  gtk_notebook_append_page(GTK_NOTEBOOK(dlg->get_notebook()),
305  GTK_WIDGET(page_content_box), page_label);
306 
307  /* Switch to selection from a list if the page count threshold is reached */
308  /* Run any callbacks on the default widget values. */
309  section->foreach_option(
310  [](GncOption& option) {
311  gnc_option_changed_option_cb(nullptr, &option);
312  });
313  return setup_notebook_pages(dlg, page_content_box, name);
314 }
315 
322 void
323 GncOptionsDialog::build_contents(GncOptionDB *odb, bool show_dialog)
324 {
325  gint default_page = -1;
326 
327  g_return_if_fail (odb != NULL);
328 
329  m_option_db = odb;
330 
331  auto num_sections = odb->num_sections();
332  auto default_section = odb->get_default_section();
333 
334  PINFO("Default Section name is %s",
335  default_section ? default_section->get_name().c_str() : "NULL");
336 
337  odb->foreach_section(
338  [this, default_section, &default_page]
339  (GncOptionSectionPtr& section) {
340  auto page = dialog_append_page(this, section);
341  if (default_section && section.get() == default_section)
342  default_page = page;
343  });
344 
345  gtk_notebook_popup_enable(GTK_NOTEBOOK(m_notebook));
346  if (default_page >= 0)
347  {
348  /* Find the page list and set the selection to the default page */
349  auto selection{gtk_tree_view_get_selection(GTK_TREE_VIEW(m_page_list_view))};
350  GtkTreeIter iter;
351 
352  auto model{gtk_tree_view_get_model(GTK_TREE_VIEW(m_page_list_view))};
353  gtk_tree_model_iter_nth_child(model, &iter, NULL, default_page);
354  gtk_tree_selection_select_iter (selection, &iter);
355  gtk_notebook_set_current_page(GTK_NOTEBOOK(m_notebook), default_page);
356  }
357  dialog_changed_internal(m_window, FALSE);
358  if (show_dialog)
359  gtk_widget_show(m_window);
360 }
361 
362 void GncOptionsDialog::call_apply_cb() noexcept
363 {
364  auto close_cb = m_close_cb;
365 
366  m_close_cb = nullptr;
367  if (m_apply_cb)
368  (m_apply_cb)(this, m_apply_cb_data);
369  m_close_cb = close_cb;
370  set_sensitive(false);
371 }
372 
373 void GncOptionsDialog::call_help_cb() noexcept
374 {
375  if (m_help_cb)
376  (m_help_cb)(this, m_help_cb_data);
377 }
378 
379 void GncOptionsDialog::call_close_cb() noexcept
380 {
381  if (m_close_cb)
382  {
383  gtk_window_close(GTK_WINDOW(m_window));
384  (m_close_cb)(this, m_close_cb_data);
385  }
386  else
387  {
388  gtk_widget_hide(m_window);
389  }
390 }
391 
392 void GncOptionsDialog::call_book_help_cb() noexcept
393 {
394 /* if (m_book_options_help_cb)
395  (m_book_options_help_cb)(this, m_book_options_help_cb_data);
396 */
397 }
398 
399 void GncOptionsDialog::call_style_sheet_help_cb() noexcept
400 {
401 /*
402  if (m_style_sheet_help_cb)
403  (m_style_shet_help_cb)(this, m_style_sheet_help_cb_data);
404 */
405 }
406 
407 // Help button signal handler
408 static void
409 dialog_help_button_cb(GtkWidget * widget, GncOptionsDialog *win)
410 {
411  win->call_help_cb();
412 }
413 
414 // Cancel/close button clicked signal handler
415 static void
416 dialog_cancel_button_cb(GtkWidget * widget, GncOptionsDialog *win)
417 {
418  gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(win->get_widget()));
419  win->call_close_cb();
420 }
421 
422 // Apply button clicked signal handler
423 static void
424 dialog_apply_button_cb(GtkWidget * widget, GncOptionsDialog *win)
425 {
426  gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(win->get_widget()));
427  win->call_apply_cb();
428 }
429 
430 // OK Button clicked signal handler
431 static void
432 dialog_ok_button_cb(GtkWidget * widget, GncOptionsDialog *win)
433 {
434  win->call_apply_cb();
435  gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(win->get_widget()));
436  win->call_close_cb();
437 }
438 
439 // "destroy" signal handler
440 static void
441 dialog_destroy_cb (GtkWidget *object, GncOptionsDialog *win)
442 {
443  win->call_close_cb();
444 }
445 
446 // "key_press_event" signal handler
447 static bool
448 dialog_window_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
449 {
450  GncOptionsDialog *win = static_cast<decltype(win)>(data);
451 
452  if (event->keyval == GDK_KEY_Escape)
453  {
454  component_close_handler (win);
455  return TRUE;
456  }
457  else
458  return FALSE;
459 }
460 
461 static void
462 dialog_reset_cb(GtkWidget * w, gpointer data)
463 {
464  GncOptionsDialog *win = static_cast<decltype(win)>(data);
465  gpointer val;
466  bool dialog_changed = false;
467 
468  val = g_object_get_data(G_OBJECT(w), "section");
469  g_return_if_fail (val);
470  g_return_if_fail (win);
471 
472  auto section = static_cast<GncOptionSection*>(val);
473  section->foreach_option(
474  [&dialog_changed](GncOption& option) {
475  if (option.is_changed())
476  {
477  option.reset_default_value();
478  option.get_ui_item()->set_dirty(true);
479  dialog_changed = true;
480  }
481  option.set_ui_item_from_option();
482  });
483 
484  dialog_changed_internal (win->get_widget(), dialog_changed);
485 }
486 
487 // changed signal handler
488 static void
489 dialog_list_select_cb (GtkTreeSelection *selection, gpointer data)
490 {
491  GncOptionsDialog * win = static_cast<decltype(win)>(data);
492  GtkTreeModel *list;
493  GtkTreeIter iter;
494  gint index = 0;
495 
496  if (!gtk_tree_selection_get_selected(selection, &list, &iter))
497  return;
498  gtk_tree_model_get(list, &iter,
499  PAGE_INDEX, &index,
500  -1);
501  PINFO("Index is %d", index);
502  gtk_notebook_set_current_page(GTK_NOTEBOOK(win->get_notebook()), index);
503 }
504 
505 static void
506 component_close_handler (gpointer data)
507 {
508  GncOptionsDialog *win = static_cast<decltype(win)>(data);
509  dialog_cancel_button_cb (NULL, win);
510 }
511 
522 GncOptionsDialog::GncOptionsDialog(bool modal, const char* title,
523  const char* component_class,
524  GtkWindow *parent) :
525  m_component_class{component_class ? component_class : DIALOG_OPTIONS_CM_CLASS}
526 {
527  auto builder = gtk_builder_new();
528  gnc_builder_add_from_file (builder, "dialog-options.glade", "gnucash_options_window");
529  m_window = GTK_WIDGET(gtk_builder_get_object (builder, "gnucash_options_window"));
530  g_object_ref(m_window);
531  m_page_list = GTK_WIDGET(gtk_builder_get_object (builder, "page_list_scroll"));
532  g_object_set_data(G_OBJECT(m_window), "optionwin", this);
533 
534  // Set the name for this dialog so it can be easily manipulated with css
535  gtk_widget_set_name (GTK_WIDGET(m_window), "gnc-id-options");
536 
537  /* Page List */
538 
539  m_page_list_view = GTK_WIDGET(gtk_builder_get_object (builder, "page_list_treeview"));
540 
541  auto view = GTK_TREE_VIEW(m_page_list_view);
542 
543  auto store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING);
544  gtk_tree_view_set_model(view, GTK_TREE_MODEL(store));
545  g_object_unref(store);
546 
547  auto renderer = gtk_cell_renderer_text_new();
548  auto column =
549  gtk_tree_view_column_new_with_attributes(_("Page"), renderer,
550  "text", PAGE_NAME,
551  nullptr);
552  gtk_tree_view_append_column(view, column);
553 
554  gtk_tree_view_column_set_alignment(column, 0.5);
555 
556  auto selection = gtk_tree_view_get_selection(view);
557  gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
558  g_signal_connect (selection, "changed",
559  G_CALLBACK (dialog_list_select_cb), this);
560 
561  m_help_button = GTK_BUTTON(gtk_builder_get_object (builder, "helpbutton"));
562  g_signal_connect(m_help_button, "clicked",
563  G_CALLBACK(dialog_help_button_cb), this);
564  m_cancel_button = GTK_BUTTON(gtk_builder_get_object (builder, "cancelbutton"));
565  g_signal_connect(m_cancel_button, "clicked",
566  G_CALLBACK(dialog_cancel_button_cb), this);
567  m_apply_button = GTK_BUTTON(gtk_builder_get_object (builder, "applybutton"));
568  g_signal_connect(m_apply_button, "clicked",
569  G_CALLBACK(dialog_apply_button_cb), this);
570  m_ok_button = GTK_BUTTON(gtk_builder_get_object (builder, "okbutton"));
571  g_signal_connect(m_ok_button, "clicked",
572  G_CALLBACK(dialog_ok_button_cb), this);
573 
574  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func,
575  this);
576 
577  // when added to a page of the hierarchy assistant there will be no parent
578  if (parent)
579  gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(m_window),
580  parent);
581 
582  if (title)
583  gtk_window_set_title(GTK_WINDOW(m_window), title);
584 
585  /* modal */
586  if (modal)
587  gtk_widget_hide (GTK_WIDGET(m_apply_button));
588 
589  /* glade doesn't support a notebook with zero pages */
590  auto hbox = GTK_WIDGET(gtk_builder_get_object (builder,
591  "notebook_placeholder"));
592  m_notebook = gtk_notebook_new();
593 
594  gtk_widget_set_vexpand (m_notebook, TRUE);
595 
596  gtk_widget_show(m_notebook);
597  gtk_box_pack_start(GTK_BOX(hbox), m_notebook, TRUE, TRUE, 5);
598 
599  auto component_id = gnc_register_gui_component (m_component_class,
600  nullptr,
601  component_close_handler,
602  this);
603  gnc_gui_component_set_session (component_id, gnc_get_current_session());
604 
605  g_signal_connect (m_window, "destroy", G_CALLBACK(dialog_destroy_cb), this);
606 
607  g_signal_connect (m_window, "key_press_event",
608  G_CALLBACK(dialog_window_key_press_cb), this);
609 
610  g_object_unref(G_OBJECT(builder));
611 }
612 
613 GncOptionsDialog::~GncOptionsDialog()
614 {
615  if (m_destroying)
616  return;
617  m_destroying = true;
618  gnc_unregister_gui_component_by_data(m_component_class, this);
619  g_signal_handlers_disconnect_by_func(m_window, (gpointer)dialog_destroy_cb, this);
620  g_signal_handlers_disconnect_by_func(m_window, (gpointer)dialog_window_key_press_cb, this);
621  g_object_unref(m_window);
622 }
623 
624 void
625 GncOptionsDialog::set_apply_cb(GncOptionsDialogCallback cb, gpointer data) noexcept
626 {
627  m_apply_cb = cb;
628  m_apply_cb_data = data;
629 }
630 
631 void
632 GncOptionsDialog::set_help_cb(GncOptionsDialogCallback cb, gpointer data) noexcept
633 {
634  m_help_cb = cb;
635  m_help_cb_data = data;
636 }
637 
638 void
639 GncOptionsDialog::set_close_cb( GncOptionsDialogCallback cb, gpointer data) noexcept
640 {
641  m_close_cb = cb;
642  m_close_cb_data = data;
643 }
644 
645 
646 static void
647 gnc_book_options_help_cb (GncOptionsDialog *win, gpointer dat)
648 {
649  gnc_gnome_help (GTK_WINDOW (win->get_widget()), HF_HELP, HL_BOOK_OPTIONS);
650 }
651 
652 void
653 GncOptionsDialog::set_book_help_cb() noexcept
654 {
655  set_help_cb((GncOptionsDialogCallback)gnc_book_options_help_cb, nullptr);
656 }
657 
658 static void
659 gnc_global_options_help_cb (GncOptionsDialog *win, gpointer dat)
660 {
661  gnc_gnome_help (GTK_WINDOW(win->get_widget()), HF_HELP, HL_GLOBPREFS);
662 }
663 
664 static void
665 gnc_style_sheet_options_help_cb (GncOptionsDialog *win, gpointer dat)
666 {
667  gnc_gnome_help (GTK_WINDOW(win->get_widget()), HF_HELP, HL_STYLE_SHEET);
668 }
669 
670 void
671 GncOptionsDialog::set_style_sheet_help_cb () noexcept
672 {
673  set_help_cb ((GncOptionsDialogCallback)gnc_style_sheet_options_help_cb,
674  nullptr);
675 }
676 
677 
678 
679 void
681 {
682  if (!odb) return;
683  auto num_split_action = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL,
684  GNC_PREF_NUM_SOURCE);
685  if (num_split_action)
686  {
687  auto option{odb->find_option(OPTION_SECTION_ACCOUNTS,
688  OPTION_NAME_NUM_FIELD_SOURCE)};
689  auto num_source_button{option_get_gtk_widget(option)};
690  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (num_source_button),
691  num_split_action);
692  }
693 }
694 
Holds all of the options for a book, report, or stylesheet, organized by GncOptionSections.
#define PINFO(format, args...)
Print an informational note.
Definition: qoflog.h:256
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
Represents the public interface for an option.
Definition: gnc-option.hpp:130
void gnc_options_dialog_set_new_book_option_values(GncOptionDB *odb)
Set the initial values of new book options to values specified in user preferences.
Account handling public routines.
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome&#39;s yelp for linux, and open to a given link within a gi...
class GncOptionSection The upper-level classification implmentation.
Generic api to store and retrieve preferences.
The primary C++ interface to options for books, reports, and stylesheets.
Holds a pointer to the UI item which will control the option and an enum representing the type of the...
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
static void create(GncOption &option, GtkGrid *page, int row)
Create a widget.
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
Implementation details for GncOptionDB.
class GncOptionGtkUIItem Gtk-specific Interface class for Option Widget