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