35 #include <glib/gi18n.h> 38 #include <gdk/gdkkeysyms.h> 39 #include "dialog-options.hpp" 50 #include "dialog-reset-warnings.h" 51 #include "dialog-transfer.h" 52 #include "dialog-utils.h" 53 #include "engine-helpers.h" 55 #include "gnc-component-manager.h" 56 #include "dialog-doclink-utils.h" 64 #include "gnc-gui-query.h" 66 #include "gnc-hooks.h" 67 #include "gnc-icons.h" 68 #include "gnc-session.h" 75 #include "gnc-warnings.h" 79 #include "gnc-autosave.h" 81 #ifdef MAC_INTEGRATION 82 #include <gtkmacintegration/gtkosxapplication.h> 84 #ifdef HAVE_SYS_STAT_H 85 # define __need_system_sys_stat_h //To block Guile-2.0's evil substitute 86 # include <sys/types.h> 87 # include <sys/stat.h> 101 #define PLUGIN_PAGE_LABEL "plugin-page" 103 #define PLUGIN_PAGE_CLOSE_BUTTON "close-button" 104 #define PLUGIN_PAGE_TAB_LABEL "label" 106 #define GNC_PREF_SHOW_CLOSE_BUTTON "tab-close-buttons" 107 #define GNC_PREF_TAB_NEXT_RECENT "tab-next-recent" 108 #define GNC_PREF_TAB_POSITION_TOP "tab-position-top" 109 #define GNC_PREF_TAB_POSITION_BOTTOM "tab-position-bottom" 110 #define GNC_PREF_TAB_POSITION_LEFT "tab-position-left" 111 #define GNC_PREF_TAB_POSITION_RIGHT "tab-position-right" 112 #define GNC_PREF_TAB_WIDTH "tab-width" 113 #define GNC_PREF_TAB_COLOR "show-account-color-tabs" 114 #define GNC_PREF_SAVE_CLOSE_EXPIRES "save-on-close-expires" 115 #define GNC_PREF_SAVE_CLOSE_WAIT_TIME "save-on-close-wait-time" 116 #define GNC_PREF_TAB_OPEN_ADJACENT "tab-open-adjacent" 118 #define GNC_MAIN_WINDOW_NAME "GncMainWindow" 120 #define DIALOG_BOOK_OPTIONS_CM_CLASS "dialog-book-options" 141 static QofLogModule log_module = GNC_MOD_GUI;
143 static GQuark window_type = 0;
146 static GList *active_windows =
nullptr;
149 static guint secs_to_save = 0;
150 #define MSG_AUTO_SAVE _("Changes will be saved automatically in %u seconds") 153 static void gnc_main_window_constructed (GObject *
object);
154 static void gnc_main_window_finalize (GObject *
object);
155 static void gnc_main_window_destroy (GtkWidget *widget);
157 static void gnc_main_window_setup_window (GncMainWindow *window);
158 static void gnc_window_main_window_init (GncWindowInterface *iface);
159 #ifndef MAC_INTEGRATION 160 static void gnc_main_window_update_all_menu_items (
void);
164 static void gnc_main_window_switch_page (GtkNotebook *notebook, gpointer *notebook_page, gint pos, GncMainWindow *window);
165 static void gnc_main_window_page_reordered (GtkNotebook *notebook, GtkWidget *child, guint pos, GncMainWindow *window);
166 static void gnc_main_window_plugin_added (GncPlugin *manager, GncPlugin *plugin, GncMainWindow *window);
167 static void gnc_main_window_plugin_removed (GncPlugin *manager, GncPlugin *plugin, GncMainWindow *window);
168 static void gnc_main_window_engine_commit_error_callback( gpointer data,
QofBackendError errcode );
171 static void gnc_main_window_cmd_redirect (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
172 static void gnc_main_window_cmd_page_setup (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
173 static void gnc_main_window_cmd_file_properties (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
174 static void gnc_main_window_cmd_file_close (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
175 static void gnc_main_window_cmd_file_quit (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
176 static void gnc_main_window_cmd_edit_cut (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
177 static void gnc_main_window_cmd_edit_copy (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
178 static void gnc_main_window_cmd_edit_paste (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
179 static void gnc_main_window_cmd_edit_preferences (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
180 static void gnc_main_window_cmd_view_refresh (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
181 static void gnc_main_window_cmd_view_toolbar (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
182 static void gnc_main_window_cmd_view_summary (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
183 static void gnc_main_window_cmd_view_statusbar (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
185 static void gnc_main_window_cmd_view_tab_position (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
187 static void gnc_main_window_cmd_actions_reset_warnings (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
188 static void gnc_main_window_cmd_actions_rename_page (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
189 static void gnc_main_window_cmd_window_new (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
190 static void gnc_main_window_cmd_window_move_page (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
191 #ifndef MAC_INTEGRATION 192 static void gnc_main_window_cmd_window_raise (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
194 static void gnc_main_window_cmd_help_tutorial (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
195 static void gnc_main_window_cmd_help_contents (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
196 static void gnc_main_window_cmd_help_about (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
198 static void do_popup_menu(
GncPluginPage *page, GdkEventButton *event);
199 static GtkWidget *gnc_main_window_get_statusbar (GncWindow *window_in);
200 static void statusbar_notification_lastmodified (
void);
201 static void gnc_main_window_update_tab_position (gpointer prefs, gchar *pref, gpointer user_data);
202 static void gnc_main_window_remove_prefs (GncMainWindow *window);
204 #ifdef MAC_INTEGRATION 205 static void gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data);
206 static gboolean gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window);
207 static void gnc_quartz_set_menu (GncMainWindow* window);
209 static void gnc_main_window_init_menu_updaters (GncMainWindow *window);
259 const gchar *previous_plugin_page_name;
260 const gchar *previous_menu_qualifier;
265 GHashTable *display_item_hash;
270 G_ADD_PRIVATE (GncMainWindow)
271 G_IMPLEMENT_INTERFACE (GNC_TYPE_WINDOW,
272 gnc_window_main_window_init))
274 #define GNC_MAIN_WINDOW_GET_PRIVATE(o) \ 275 ((GncMainWindowPrivate*)gnc_main_window_get_instance_private((GncMainWindow*)o)) 279 static guint main_window_signals[LAST_SIGNAL] = { 0 };
285 static GActionEntry gnc_menu_actions [] =
287 {
"FilePageSetupAction", gnc_main_window_cmd_page_setup,
nullptr,
nullptr,
nullptr },
288 {
"FilePropertiesAction", gnc_main_window_cmd_file_properties,
nullptr,
nullptr,
nullptr },
289 {
"FileCloseAction", gnc_main_window_cmd_file_close,
nullptr,
nullptr,
nullptr },
290 {
"FilePrintAction", gnc_main_window_cmd_redirect,
nullptr,
nullptr,
nullptr },
291 {
"FileQuitAction", gnc_main_window_cmd_file_quit,
nullptr,
nullptr,
nullptr },
293 {
"EditCutAction", gnc_main_window_cmd_edit_cut,
nullptr,
nullptr,
nullptr },
294 {
"EditCopyAction", gnc_main_window_cmd_edit_copy,
nullptr,
nullptr,
nullptr },
295 {
"EditPasteAction", gnc_main_window_cmd_edit_paste,
nullptr,
nullptr,
nullptr },
296 {
"EditPreferencesAction", gnc_main_window_cmd_edit_preferences,
nullptr,
nullptr,
nullptr },
298 {
"ActionsForgetWarningsAction", gnc_main_window_cmd_actions_reset_warnings,
nullptr,
nullptr,
nullptr },
299 {
"ActionsRenamePageAction", gnc_main_window_cmd_actions_rename_page,
nullptr,
nullptr,
nullptr },
301 {
"TransactionAction",
nullptr,
nullptr,
nullptr,
nullptr },
303 {
"ViewSortByAction",
nullptr,
nullptr,
nullptr,
nullptr },
304 {
"ViewFilterByAction",
nullptr,
nullptr,
nullptr,
nullptr },
305 {
"ViewRefreshAction", gnc_main_window_cmd_view_refresh,
nullptr,
nullptr,
nullptr },
306 {
"ViewToolbarAction", gnc_main_window_cmd_view_toolbar,
nullptr,
"true",
nullptr },
307 {
"ViewSummaryAction", gnc_main_window_cmd_view_summary,
nullptr,
"true",
nullptr },
308 {
"ViewStatusbarAction", gnc_main_window_cmd_view_statusbar,
nullptr,
"true",
nullptr },
309 {
"ViewTabPositionAction", gnc_main_window_cmd_view_tab_position,
"i",
"@i 0",
nullptr },
311 {
"ScheduledAction",
nullptr,
nullptr,
nullptr,
nullptr },
313 {
"ExtensionsAction",
nullptr,
nullptr,
nullptr,
nullptr },
315 {
"WindowNewAction", gnc_main_window_cmd_window_new,
nullptr,
nullptr,
nullptr },
316 {
"WindowMovePageAction", gnc_main_window_cmd_window_move_page,
nullptr,
nullptr,
nullptr },
317 #ifndef MAC_INTEGRATION 318 {
"WindowAction", gnc_main_window_cmd_window_raise,
"i",
"@i 0",
nullptr },
320 {
"HelpTutorialAction", gnc_main_window_cmd_help_tutorial,
nullptr,
nullptr,
nullptr },
321 {
"HelpContentsAction", gnc_main_window_cmd_help_contents,
nullptr,
nullptr,
nullptr },
322 {
"HelpAboutAction", gnc_main_window_cmd_help_about,
nullptr,
nullptr,
nullptr },
325 static guint gnc_menu_n_actions = G_N_ELEMENTS(gnc_menu_actions);
331 static const gchar *always_insensitive_actions[] =
341 static const gchar *initially_insensitive_actions[] =
352 static const gchar *always_hidden_actions[] =
355 "ViewFilterByAction",
362 static const gchar *immutable_page_actions[] =
371 static const gchar *multiple_page_actions[] =
373 "WindowMovePageAction",
381 #define WINDOW_COUNT "WindowCount" 382 #define WINDOW_STRING "Window %d" 383 #define WINDOW_GEOMETRY "WindowGeometry" 384 #define WINDOW_POSITION "WindowPosition" 385 #define WINDOW_MAXIMIZED "WindowMaximized" 386 #define TOOLBAR_VISIBLE "ToolbarVisible" 387 #define STATUSBAR_VISIBLE "StatusbarVisible" 388 #define SUMMARYBAR_VISIBLE "SummarybarVisible" 389 #define WINDOW_FIRSTPAGE "FirstPage" 390 #define WINDOW_PAGECOUNT "PageCount" 391 #define WINDOW_PAGEORDER "PageOrder" 392 #define PAGE_TYPE "PageType" 393 #define PAGE_NAME "PageName" 394 #define PAGE_STRING "Page %d" 399 const gchar *group_name;
420 for (
auto w = active_windows; w; w = g_list_next(w))
422 auto window{
static_cast<GncMainWindow*
>(w->data)};
423 auto priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
424 for (
auto p = priv->installed_pages; p; p = g_list_next(p))
449 gnc_main_window_restore_page (GncMainWindow *window,
454 gchar *page_group, *page_type =
nullptr, *name =
nullptr;
455 const gchar *class_type;
456 GError *error =
nullptr;
458 ENTER(
"window %p, data %p (key file %p, window %d, page start %d, page num %d)",
459 window, data, data->key_file, data->window_num, data->page_offset,
462 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
463 page_group = g_strdup_printf(PAGE_STRING,
464 data->page_offset + data->page_num);
465 page_type = g_key_file_get_string(data->key_file, page_group,
469 g_warning(
"error reading group %s key %s: %s",
470 page_group, PAGE_TYPE, error->message);
479 class_type = GNC_PLUGIN_PAGE_GET_CLASS(page)->plugin_name;
480 if (strcmp(page_type, class_type) != 0)
482 g_warning(
"error: page types don't match: state %s, existing page %s",
483 page_type, class_type);
491 data->key_file, page_group);
495 if (page->
window ==
nullptr)
502 name = g_key_file_get_string(data->key_file, page_group,
506 g_warning(
"error reading group %s key %s: %s",
507 page_group, PAGE_NAME, error->message);
512 DEBUG(
"updating page name for %p to %s.", page, name);
527 return (page ?
true :
false);
531 intersects_some_monitor(
const GdkRectangle& rect)
533 auto display = gdk_display_get_default();
537 int n = gdk_display_get_n_monitors(display);
538 for (
int i = 0; i < n; ++i)
540 auto monitor = gdk_display_get_monitor(display, i);
541 GdkRectangle monitor_geometry;
542 gdk_monitor_get_geometry(monitor, &monitor_geometry);
543 DEBUG(
"Monitor %d: position (%d,%d), size %dx%d\n", i,
544 monitor_geometry.x, monitor_geometry.y,
545 monitor_geometry.width, monitor_geometry.height);
546 if (gdk_rectangle_intersect(&rect, &monitor_geometry,
nullptr))
557 GError *error =
nullptr;
558 gint *geom = g_key_file_get_integer_list(data->key_file, window_group,
559 WINDOW_GEOMETRY, &length, &error);
562 g_warning(
"error reading group %s key %s: %s",
563 window_group, WINDOW_GEOMETRY, error->message);
567 else if (length != 2)
569 g_warning(
"invalid number of values for group %s key %s",
570 window_group, WINDOW_GEOMETRY);
574 gtk_window_resize(GTK_WINDOW(window), geom[0], geom[1]);
575 DEBUG(
"window (%p) size %dx%d", window, geom[0], geom[1]);
580 gint *pos = g_key_file_get_integer_list(data->key_file, window_group,
581 WINDOW_POSITION, &length, &error);
584 g_warning(
"error reading group %s key %s: %s",
585 window_group, WINDOW_POSITION, error->message);
589 else if (length != 2)
591 g_warning(
"invalid number of values for group %s key %s",
592 window_group, WINDOW_POSITION);
598 GdkRectangle geometry{pos[0], pos[1], geom ? geom[0] : 1, geom ? geom[1] : 1};
599 if (intersects_some_monitor(geometry))
601 gtk_window_move(GTK_WINDOW(window), geometry.x, geometry.y);
602 auto priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
603 priv->
pos[0] = geometry.x;
604 priv->
pos[1] = geometry.y;
605 DEBUG(
"window (%p) position (%d,%d)", window, geometry.x, geometry.y);
609 DEBUG(
"position (%d,%d), size %dx%d is offscreen; will not move",
610 geometry.x, geometry.y, geometry.width, geometry.height);
616 gboolean max = g_key_file_get_boolean(data->key_file, window_group,
617 WINDOW_MAXIMIZED, &error);
620 g_warning(
"error reading group %s key %s: %s",
621 window_group, WINDOW_MAXIMIZED, error->message);
627 gtk_window_maximize(GTK_WINDOW(window));
646 gsize page_start, page_count, i;
647 GError *error =
nullptr;
648 GSList *added_page_offsets =
nullptr;
652 ENTER(
"window %p, data %p (key file %p, window %d)",
653 window, data, data->key_file, data->window_num);
654 gchar *window_group = g_strdup_printf(WINDOW_STRING, data->window_num + 1);
663 if (!g_key_file_has_group (data->key_file, window_group) ||
664 !g_key_file_has_key (data->key_file, window_group, WINDOW_PAGECOUNT, &error))
669 PINFO (
"saved state had an empty first main window\n" 670 "an account hierarchy page was added automatically to avoid confusion");
673 PINFO (
"saved state had an empty main window, skipping restore");
680 page_count = g_key_file_get_integer(data->key_file,
681 window_group, WINDOW_PAGECOUNT, &error);
684 g_warning(
"error reading group %s key %s: %s",
685 window_group, WINDOW_PAGECOUNT, error->message);
694 page_start = g_key_file_get_integer(data->key_file,
695 window_group, WINDOW_FIRSTPAGE, &error);
698 g_warning(
"error reading group %s key %s: %s",
699 window_group, WINDOW_FIRSTPAGE, error->message);
704 if (window ==
nullptr)
706 DEBUG(
"Window %d doesn't exist. Creating new window.", data->window_num);
707 DEBUG(
"active_windows %p.", active_windows);
709 DEBUG(
"first window %p.", active_windows->data);
714 set_window_geometry(window, data, window_group);
716 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
725 GVariant *state = g_action_get_state (G_ACTION(action));
726 gboolean visible = g_variant_get_boolean (state);
727 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
728 TOOLBAR_VISIBLE, &error);
732 g_warning (
"error reading group %s key %s: %s",
733 window_group, TOOLBAR_VISIBLE, error->message);
734 g_error_free (error);
737 else if (visible != desired_visibility)
739 g_action_activate (action,
nullptr);
741 g_variant_unref (state);
747 GVariant *state = g_action_get_state (G_ACTION(action));
748 gboolean visible = g_variant_get_boolean (state);
749 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
750 SUMMARYBAR_VISIBLE, &error);
754 g_warning (
"error reading group %s key %s: %s",
755 window_group, SUMMARYBAR_VISIBLE, error->message);
756 g_error_free (error);
759 else if (visible != desired_visibility)
761 g_action_activate (action,
nullptr);
763 g_variant_unref (state);
769 GVariant *state = g_action_get_state (G_ACTION(action));
770 gboolean visible = g_variant_get_boolean (state);
771 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
772 STATUSBAR_VISIBLE, &error);
776 g_warning (
"error reading group %s key %s: %s",
777 window_group, STATUSBAR_VISIBLE, error->message);
778 g_error_free (error);
781 else if (visible != desired_visibility)
783 g_action_activate (action,
nullptr);
785 g_variant_unref (state);
789 for (i = 0; i < page_count; i++)
791 data->page_offset = page_start;
793 gboolean page_added = gnc_main_window_restore_page (window, data);
798 added_page_offsets = g_slist_append (added_page_offsets,
799 GINT_TO_POINTER(-1));
802 added_page_offsets = g_slist_append (added_page_offsets,
803 GINT_TO_POINTER(offset));
806 while (gtk_events_pending ())
807 gtk_main_iteration ();
813 order = g_key_file_get_integer_list (data->key_file, window_group,
814 WINDOW_PAGEORDER, &length, &error);
817 g_warning(
"error reading group %s key %s: %s",
818 window_group, WINDOW_PAGEORDER, error->message);
822 else if (length != page_count)
824 g_warning(
"%s key %s length %" G_GSIZE_FORMAT
" differs from window page count %" G_GSIZE_FORMAT,
825 window_group, WINDOW_PAGEORDER, length, page_count);
833 gint default_page_position = -1;
836 for (i = 0; i < length; i++)
838 gint zero_based_page_number = order[i] - 1;
840 gint offset = GPOINTER_TO_INT(g_slist_nth_data (added_page_offsets,
841 zero_based_page_number));
847 zero_based_page_number - offset);
849 if (default_page_position == -1)
850 default_page_position = zero_based_page_number - offset;
855 gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->
notebook),
856 default_page_position);
858 g_signal_emit_by_name (window,
"page_changed",
866 LEAVE(
"window %p", window);
868 g_slist_free (added_page_offsets);
871 g_free(window_group);
873 gtk_widget_show (GTK_WIDGET(window));
879 gint i, window_count;
880 GError *error =
nullptr;
885 data.key_file = (GKeyFile *) keyfile;
886 window_count = g_key_file_get_integer(data.key_file, STATE_FILE_TOP,
887 WINDOW_COUNT, &error);
890 g_warning(
"error reading group %s key %s: %s",
891 STATE_FILE_TOP, WINDOW_COUNT, error->message);
893 LEAVE(
"can't read count");
899 gnc_set_busy_cursor (
nullptr, TRUE);
900 for (i = 0; i < window_count; i++)
903 auto window{
static_cast<GncMainWindow*
>(g_list_nth_data(active_windows,
905 gnc_main_window_restore_window(window, &data);
907 gnc_unset_busy_cursor (
nullptr);
909 statusbar_notification_lastmodified();
919 DEBUG(
"no saved state file");
921 window =
static_cast<GncMainWindow*
>(g_list_nth_data(active_windows, 0));
922 gtk_widget_show (GTK_WIDGET(window));
924 "gnc-plugin-account-tree-actions",
925 "ViewAccountTreeAction");
926 g_action_activate (action,
nullptr);
942 const gchar *plugin_name, *page_name;
944 ENTER(
"page %p, data %p (key file %p, window %d, page %d)",
945 page, data, data->key_file, data->window_num, data->page_num);
948 if (!plugin_name || !page_name)
950 LEAVE(
"not saving invalid page");
953 page_group = g_strdup_printf(PAGE_STRING, data->page_num++);
954 g_key_file_set_string(data->key_file, page_group, PAGE_TYPE, plugin_name);
955 g_key_file_set_string(data->key_file, page_group, PAGE_NAME, page_name);
976 gint i, num_pages, coords[4], *order;
977 gboolean maximized, minimized, visible =
true;
981 ENTER(
"window %p, data %p (key file %p, window %d)",
982 window, data, data->key_file, data->window_num);
983 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
986 num_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->
notebook));
989 LEAVE(
"empty window %p", window);
994 window_group = g_strdup_printf(WINDOW_STRING, data->window_num++);
995 g_key_file_set_integer(data->key_file, window_group,
996 WINDOW_PAGECOUNT, num_pages);
997 g_key_file_set_integer(data->key_file, window_group,
998 WINDOW_FIRSTPAGE, data->page_num);
1003 order =
static_cast<int*
>(g_malloc(
sizeof(gint) * num_pages));
1004 for (i = 0; i < num_pages; i++)
1006 gpointer page = g_list_nth_data(priv->
usage_order, i);
1009 g_key_file_set_integer_list(data->key_file, window_group,
1010 WINDOW_PAGEORDER, order, num_pages);
1014 gtk_window_get_position(GTK_WINDOW(window), &coords[0], &coords[1]);
1015 gtk_window_get_size(GTK_WINDOW(window), &coords[2], &coords[3]);
1016 maximized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
1017 & GDK_WINDOW_STATE_MAXIMIZED) != 0;
1018 minimized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
1019 & GDK_WINDOW_STATE_ICONIFIED) != 0;
1023 gint *pos = priv->
pos;
1024 g_key_file_set_integer_list(data->key_file, window_group,
1025 WINDOW_POSITION, &pos[0], 2);
1026 DEBUG(
"window minimized (%p) position (%d,%d)", window, pos[0], pos[1]);
1029 g_key_file_set_integer_list(data->key_file, window_group,
1030 WINDOW_POSITION, &coords[0], 2);
1031 g_key_file_set_integer_list(data->key_file, window_group,
1032 WINDOW_GEOMETRY, &coords[2], 2);
1033 g_key_file_set_boolean(data->key_file, window_group,
1034 WINDOW_MAXIMIZED, maximized);
1035 DEBUG(
"window (%p) position (%d,%d), size %dx%d, %s", window, coords[0], coords[1],
1036 coords[2], coords[3],
1037 maximized ?
"maximized" :
"not maximized");
1043 GVariant *state = g_action_get_state (G_ACTION(action));
1044 visible = g_variant_get_boolean (state);
1045 g_variant_unref (state);
1047 g_key_file_set_boolean (data->key_file, window_group,
1048 TOOLBAR_VISIBLE, visible);
1052 GVariant *state = g_action_get_state (G_ACTION(action));
1053 visible = g_variant_get_boolean (state);
1054 g_variant_unref (state);
1056 g_key_file_set_boolean (data->key_file, window_group,
1057 SUMMARYBAR_VISIBLE, visible);
1061 GVariant *state = g_action_get_state (G_ACTION(action));
1062 visible = g_variant_get_boolean (state);
1063 g_variant_unref (state);
1065 g_key_file_set_boolean (data->key_file, window_group,
1066 STATUSBAR_VISIBLE, visible);
1069 g_list_foreach (priv->
installed_pages, (GFunc)gnc_main_window_save_page, data);
1071 g_free(window_group);
1072 LEAVE(
"window %p", window);
1081 data.key_file = keyfile;
1082 data.window_num = 1;
1085 g_key_file_set_integer(data.key_file,
1086 STATE_FILE_TOP, WINDOW_COUNT,
1087 g_list_length(active_windows));
1089 g_list_foreach(active_windows, (GFunc)gnc_main_window_save_window, &data);
1099 g_return_val_if_fail(GNC_IS_MAIN_WINDOW(window), TRUE);
1101 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1116 const GList *windows, *item;
1119 for (item = windows; item; item = g_list_next(item))
1126 if (gnc_gui_refresh_suspended ())
1128 gnc_warning_dialog (
nullptr,
"%s",
"An operation is still running, wait for it to complete before quitting.");
1151 for (walker = active_windows; walker; walker = g_list_next(walker))
1153 auto window{
static_cast<GncMainWindow*
>(walker->data)};
1154 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1163 static gboolean auto_save_countdown (GtkWidget *dialog)
1166 gchar *timeoutstr =
nullptr;
1169 if (!GTK_IS_DIALOG (dialog))
1173 label = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
"count-down-label"));
1174 if (!GTK_IS_LABEL (label))
1180 DEBUG (
"Counting down: %d seconds", secs_to_save);
1182 timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
1183 gtk_label_set_text (GTK_LABEL (label), timeoutstr);
1184 g_free (timeoutstr);
1189 gtk_dialog_response (GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
1208 gnc_main_window_prompt_for_save (GtkWidget *window)
1210 QofSession *session;
1212 GtkWidget *dialog, *msg_area, *label;
1214 const gchar *filename, *tmp;
1215 const gchar *title = _(
"Save changes to file %s before closing?");
1217 const gchar *message_hours =
1218 _(
"If you don't save, changes from the past %d hours and %d minutes will be discarded.");
1219 const gchar *message_days =
1220 _(
"If you don't save, changes from the past %d days and %d hours will be discarded.");
1222 gint minutes, hours, days;
1223 guint timer_source = 0;
1224 if (!gnc_current_session_exist())
1226 session = gnc_get_current_session();
1230 filename = qof_session_get_url(session);
1231 if (!strlen (filename))
1232 filename = _(
"<unknown>");
1233 if ((tmp = strrchr(filename,
'/')) !=
nullptr)
1237 gnc_autosave_remove_timer(book);
1239 dialog = gtk_message_dialog_new(GTK_WINDOW(window),
1241 GTK_MESSAGE_WARNING,
1246 minutes = (
gnc_time (
nullptr) - oldest_change) / 60 + 1;
1247 hours = minutes / 60;
1248 minutes = minutes % 60;
1253 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1254 message_days, days, hours);
1258 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1259 message_hours, hours, minutes);
1263 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1264 ngettext(
"If you don't save, changes from the past %d minute will be discarded.",
1265 "If you don't save, changes from the past %d minutes will be discarded.",
1268 gtk_dialog_add_buttons(GTK_DIALOG(dialog),
1269 _(
"Close _Without Saving"), GTK_RESPONSE_CLOSE,
1270 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
1271 _(
"_Save"), GTK_RESPONSE_APPLY,
1273 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
1280 gchar *timeoutstr =
nullptr;
1282 secs_to_save =
gnc_prefs_get_int (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_CLOSE_WAIT_TIME);
1283 timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
1284 label = GTK_WIDGET(gtk_label_new (timeoutstr));
1285 g_free (timeoutstr);
1286 gtk_widget_show (label);
1288 msg_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG(dialog));
1289 gtk_box_pack_end (GTK_BOX(msg_area), label, TRUE, TRUE, 0);
1290 g_object_set (G_OBJECT (label),
"xalign", 0.0,
nullptr);
1292 g_object_set_data (G_OBJECT (dialog),
"count-down-label", label);
1293 timer_source = g_timeout_add_seconds (1, (GSourceFunc)auto_save_countdown, dialog);
1296 response = gtk_dialog_run (GTK_DIALOG (dialog));
1298 g_source_remove (timer_source);
1299 gtk_widget_destroy(dialog);
1303 case GTK_RESPONSE_APPLY:
1304 gnc_file_save (GTK_WINDOW (window));
1307 case GTK_RESPONSE_CLOSE:
1318 gnc_main_window_add_plugin (gpointer plugin,
1321 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
1322 g_return_if_fail (GNC_IS_PLUGIN (plugin));
1326 GNC_MAIN_WINDOW (window),
1332 gnc_main_window_remove_plugin (gpointer plugin,
1335 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
1336 g_return_if_fail (GNC_IS_PLUGIN (plugin));
1340 GNC_MAIN_WINDOW (window),
1347 gnc_main_window_timed_quit (gpointer dummy)
1349 if (gnc_file_save_in_progress())
1357 gnc_main_window_quit(GncMainWindow *window)
1359 QofSession *session;
1360 gboolean needs_save, do_shutdown = TRUE;
1361 if (gnc_current_session_exist())
1363 session = gnc_get_current_session();
1366 !gnc_file_save_in_progress();
1367 do_shutdown = !needs_save ||
1369 !gnc_main_window_prompt_for_save(GTK_WIDGET(window)));
1379 for (w = active_windows; w; w = next)
1382 GncMainWindow *window =
static_cast<GncMainWindow*
>(w->data);
1384 next = g_list_next (w);
1386 window->window_quitting = TRUE;
1388 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1392 gtk_widget_destroy (GTK_WIDGET(window));
1395 gnc_main_window_remove_prefs (window);
1396 g_timeout_add(250, gnc_main_window_timed_quit,
nullptr);
1405 g_return_val_if_fail(GNC_IS_MAIN_WINDOW(window), FALSE);
1406 return window->window_quitting;
1410 gnc_main_window_delete_event (GtkWidget *window,
1414 static gboolean already_dead = FALSE;
1423 gchar *message = _(
"This window is closing and will not be restored.");
1425 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
1426 GTK_DIALOG_DESTROY_WITH_PARENT,
1427 GTK_MESSAGE_QUESTION,
1429 "%s", _(
"Close Window?"));
1430 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
1433 gtk_dialog_add_buttons (GTK_DIALOG(dialog),
1434 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
1435 _(
"_OK"), GTK_RESPONSE_YES,
1437 gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_YES);
1438 response = gnc_dialog_run (GTK_DIALOG(dialog), GNC_PREF_WARN_CLOSING_WINDOW_QUESTION);
1439 gtk_widget_destroy (dialog);
1441 if (response == GTK_RESPONSE_CANCEL)
1454 already_dead = gnc_main_window_quit(GNC_MAIN_WINDOW(window));
1480 gpointer user_data, gpointer event_data)
1482 GncMainWindow *window;
1488 g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
1493 if (event_type != QOF_EVENT_DESTROY)
1496 ENTER(
"entity %p, event %d, window %p, event data %p",
1497 entity, event_type, user_data, event_data);
1498 window = GNC_MAIN_WINDOW(user_data);
1499 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1506 next = g_list_next(item);
1507 page = GNC_PLUGIN_PAGE(item->data);
1512 if (GTK_IS_WIDGET(window) && window->window_quitting)
1513 gtk_widget_destroy (GTK_WIDGET(window));
1536 gnc_main_window_generate_title (GncMainWindow *window)
1542 gchar *filename =
nullptr;
1543 const gchar *uri =
nullptr;
1544 const gchar *dirty =
"";
1545 const gchar *readonly_text =
nullptr;
1549 if (gnc_current_session_exist())
1551 uri = qof_session_get_url (gnc_get_current_session ());
1552 book = gnc_get_current_book();
1559 readonly_text = _(
"(read-only)");
1562 readonly = (readonly_text !=
nullptr)
1563 ? g_strdup_printf(
" %s", readonly_text)
1566 if (!uri || g_strcmp0 (uri,
"") == 0)
1567 filename = g_strdup(_(
"Unsaved Book"));
1575 filename = g_path_get_basename ( path );
1586 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1592 title = g_strdup_printf(
"%s%s%s - %s - GnuCash", dirty, filename, readonly,
1597 title = g_strdup_printf(
"%s%s%s - GnuCash", dirty, filename, readonly);
1601 g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE);
1603 immutable_page_actions,
1606 g_signal_emit_by_name (window,
"page_changed", page);
1624 gnc_main_window_update_title (GncMainWindow *window)
1628 title = gnc_main_window_generate_title(window);
1629 gtk_window_set_title(GTK_WINDOW(window), title);
1634 gnc_main_window_update_all_titles (
void)
1636 g_list_foreach(active_windows,
1637 (GFunc)gnc_main_window_update_title,
1659 gnc_tab_clicked_cb(GtkWidget *widget, GdkEventButton *event,
GncPluginPage *page) {
1660 if (event->type == GDK_BUTTON_PRESS && event->button == 2)
1669 gnc_main_window_book_dirty_cb (QofBook *book,
1673 gnc_main_window_update_all_titles();
1676 gnc_autosave_dirty_handler(book, dirty);
1680 gnc_main_window_attach_to_book (QofSession *session)
1684 g_return_if_fail(session);
1688 gnc_main_window_update_all_titles();
1689 #ifndef MAC_INTEGRATION 1690 gnc_main_window_update_all_menu_items();
1694 static guint gnc_statusbar_notification_messageid = 0;
1696 #ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL 1699 static gboolean statusbar_notification_off(gpointer user_data_unused)
1703 if (gnc_statusbar_notification_messageid == 0)
1708 GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
1709 gtk_statusbar_remove(GTK_STATUSBAR(statusbar), 0, gnc_statusbar_notification_messageid);
1710 gnc_statusbar_notification_messageid = 0;
1714 g_warning(
"oops, no GncMainWindow obtained\n");
1718 #endif // STATUSBAR_NOTIFICATION_AUTOREMOVAL 1722 static gchar *generate_statusbar_lastmodified_message()
1724 gchar *message =
nullptr;
1725 const gchar *uri =
nullptr;
1727 if (gnc_current_session_exist())
1729 uri = qof_session_get_url (gnc_get_current_session ());
1732 if (!(uri && strlen (uri)))
1740 gchar *filename = g_path_get_basename ( filepath );
1741 GFile *file = g_file_new_for_uri (uri);
1742 GFileInfo *info = g_file_query_info (file,
1743 G_FILE_ATTRIBUTE_TIME_MODIFIED,
1744 G_FILE_QUERY_INFO_NONE,
1747 if (info && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
1750 struct stat statbuf;
1751 int r = stat(filepath, &statbuf);
1760 _(
"Last modified on %a, %b %d, %Y at %I:%M %p"));
1763 message = g_strdup_printf(_(
"File %s opened. %s"),
1764 filename, time_string);
1769 g_warning(
"Unable to read mtime for file %s\n", filepath);
1775 g_object_unref (info);
1776 g_object_unref (file);
1785 statusbar_notification_lastmodified()
1789 GtkWidget *widget =
nullptr;
1790 for (iter = active_windows; iter && !(widget && GNC_IS_MAIN_WINDOW(widget));
1791 iter = g_list_next(iter))
1793 widget =
static_cast<GtkWidget*
>(iter->data);
1795 if (widget && GNC_IS_MAIN_WINDOW(widget))
1798 GncMainWindow *mainwindow = GNC_MAIN_WINDOW(widget);
1799 GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
1801 gchar *msg = generate_statusbar_lastmodified_message();
1804 gnc_statusbar_notification_messageid = gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);
1808 #ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL 1811 g_timeout_add(10 * 1000, statusbar_notification_off,
nullptr);
1816 g_warning(
"uh oh, no GNC_IS_MAIN_WINDOW\n");
1838 #ifndef MAC_INTEGRATION 1853 gnc_main_window_update_one_menu_action (GncMainWindow *window,
1857 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
1861 ENTER(
"window %p, action %s, label %s, index %d, visible %d", window,
1862 data->action_name, data->label, data->index, data->visible);
1864 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1866 gsm->search_action_label =
nullptr;
1867 gsm->search_action_name =
"WindowsPlaceholder1";
1868 gsm->search_action_target =
nullptr;
1872 LEAVE(
"Could not find placeholder 'WindowsPlaceholder1' for windows entries");
1877 pos = gsm->index + data->index + 1;
1881 if (pos < g_menu_model_get_n_items (gsm->model))
1882 g_menu_remove (G_MENU(gsm->model), pos);
1889 item = g_menu_item_new (data->label,
"mainwin.WindowAction");
1890 g_menu_item_set_attribute (item, G_MENU_ATTRIBUTE_TARGET,
"i", data->index);
1892 if (pos < g_menu_model_get_n_items (gsm->model))
1893 g_menu_remove (G_MENU(gsm->model), pos);
1894 g_menu_insert_item (G_MENU(gsm->model), pos, item);
1895 g_object_unref (item);
1914 gnc_main_window_update_radio_button (GncMainWindow *window)
1919 ENTER(
"window %p", window);
1922 index = g_list_index (active_windows, window);
1930 action = g_action_map_lookup_action (G_ACTION_MAP(window),
1935 g_signal_handlers_block_by_func (G_OBJECT(action),
1936 (gpointer)gnc_main_window_cmd_window_raise,
1939 DEBUG(
"blocked signal on action %p, window %p", action, window);
1940 g_action_change_state (G_ACTION(action), g_variant_new_int32 (index));
1942 g_signal_handlers_unblock_by_func (G_OBJECT(action),
1943 (gpointer)gnc_main_window_cmd_window_raise,
1961 gnc_main_window_update_menu_item (GncMainWindow *window)
1964 gchar **strings, *title, *expanded;
1967 ENTER(
"window %p", window);
1969 index = g_list_index (active_windows, window);
1978 title = gnc_main_window_generate_title (window);
1979 strings = g_strsplit (title,
"_", 0);
1981 expanded = g_strjoinv (
"__", strings);
1984 data.label = g_strdup_printf (
"_%" G_GSIZE_FORMAT
" %s", (
index + 1) % 10, expanded);
1989 data.label = expanded;
1991 g_strfreev (strings);
1993 data.visible = TRUE;
1994 data.action_name = g_strdup_printf (
"Window%" G_GSIZE_FORMAT
"Action",
index);
1997 g_list_foreach (active_windows,
1998 (GFunc)gnc_main_window_update_one_menu_action,
2001 g_free (data.action_name);
2002 g_free (data.label);
2016 #ifndef MAC_INTEGRATION 2018 gnc_main_window_update_all_menu_items (
void)
2024 g_list_foreach (active_windows,
2025 (GFunc)gnc_main_window_update_menu_item,
2028 g_list_foreach (active_windows,
2029 (GFunc)gnc_main_window_update_radio_button,
2033 data.visible = FALSE;
2038 data.action_name = g_strdup_printf (
"Window%dAction", data.index);
2039 data.label = g_strdup_printf (
"mywin%" G_GSIZE_FORMAT, i % 10);
2041 g_list_foreach (active_windows,
2042 (GFunc)gnc_main_window_update_one_menu_action,
2045 g_free (data.action_name);
2046 g_free (data.label);
2064 gnc_main_window_update_tab_close_one_page (
GncPluginPage *page,
2067 auto new_value{
static_cast<gboolean*
>(user_data)};
2068 ENTER(
"page %p, visible %d", page, *new_value);
2069 auto close_button{
static_cast<GtkWidget*
>(g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON))};
2072 LEAVE(
"no close button");
2077 gtk_widget_show (close_button);
2079 gtk_widget_hide (close_button);
2097 gnc_main_window_update_tab_close (gpointer prefs, gchar *pref, gpointer user_data)
2102 new_value =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SHOW_CLOSE_BUTTON);
2104 gnc_main_window_update_tab_close_one_page,
2119 gnc_main_window_update_tab_color_one_page (
GncPluginPage *page,
2122 const gchar *color_string;
2124 ENTER(
"page %p", page);
2142 gnc_main_window_update_tab_color (gpointer gsettings, gchar *pref, gpointer user_data)
2145 g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
2146 auto window{
static_cast<GncMainWindow*
>(user_data)};
2147 auto priv{GNC_MAIN_WINDOW_GET_PRIVATE(window)};
2148 if (g_strcmp0 (GNC_PREF_TAB_COLOR, pref) == 0)
2161 gboolean tabs_left_right;
2165 populate_tab_width_struct (
void)
2171 tw->tabs_left_right =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT) ||
2199 gnc_main_window_set_tab_ellipsize (GtkWidget *
label, gint tab_width, gboolean tab_left_right)
2201 const gchar *lab_text = gtk_label_get_text (GTK_LABEL(
label));
2205 gint text_length = g_utf8_strlen (lab_text, -1);
2206 if (text_length < tab_width)
2209 gtk_label_set_width_chars (GTK_LABEL(
label), tab_width);
2211 gtk_label_set_width_chars (GTK_LABEL(
label), text_length);
2213 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_NONE);
2217 gtk_label_set_width_chars (GTK_LABEL(
label), tab_width);
2218 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_MIDDLE);
2223 gtk_label_set_width_chars (GTK_LABEL(
label), 15);
2224 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_NONE);
2240 gnc_main_window_update_tab_width_one_page (
GncPluginPage *page,
2243 auto tw{
static_cast<TabWidth*
>(user_data)};
2245 ENTER(
"page %p, tab width %d, tabs on left or right %d",
2246 page, tw->tab_width, tw->tabs_left_right);
2248 auto label{
static_cast<GtkWidget *
>(g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL))};
2254 gnc_main_window_set_tab_ellipsize (
label, tw->tab_width, tw->tabs_left_right);
2272 gnc_main_window_update_tab_width (gpointer prefs, gchar *pref, gpointer user_data)
2278 tw = populate_tab_width_struct ();
2291 main_window_find_tab_items (GncMainWindow *window,
2293 GtkWidget **label_p,
2294 GtkWidget **entry_p)
2297 GtkWidget *tab_hbox, *widget, *tab_widget;
2298 GList *children, *tmp;
2300 ENTER(
"window %p, page %p, label_p %p, entry_p %p",
2301 window, page, label_p, entry_p);
2302 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2303 *label_p = *entry_p =
nullptr;
2307 LEAVE(
"invalid notebook_page");
2311 tab_widget = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->
notebook),
2315 tab_hbox = tab_widget;
2317 if (g_strcmp0(gtk_widget_get_name(tab_hbox),
"tab-content") == 0) {
2320 GList* _children = gtk_container_get_children(GTK_CONTAINER(tab_hbox));
2321 tab_hbox = _children ? GTK_WIDGET(_children->data) : nullptr;
2322 g_list_free(_children);
2325 if (!GTK_IS_BOX(tab_hbox))
2327 PWARN (
"Unknown widget for tab label %p", tab_widget);
2331 children = gtk_container_get_children(GTK_CONTAINER(tab_hbox));
2332 for (tmp = children; tmp; tmp = g_list_next(tmp))
2334 widget =
static_cast<GtkWidget*
>(tmp->data);
2335 if (GTK_IS_LABEL(widget))
2339 else if (GTK_IS_ENTRY(widget))
2344 g_list_free(children);
2346 LEAVE(
"label %p, entry %p", *label_p, *entry_p);
2347 return (*label_p && *entry_p);
2351 main_window_find_tab_widget (GncMainWindow *window,
2353 GtkWidget **widget_p)
2357 ENTER(
"window %p, page %p, widget %p",
2358 window, page, widget_p);
2359 *widget_p =
nullptr;
2363 LEAVE(
"invalid notebook_page");
2367 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2368 *widget_p = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->
notebook),
2371 LEAVE(
"widget %p", *widget_p);
2377 const gchar *long_name_in)
2379 GtkWidget *tab_widget;
2383 if ((long_name_in ==
nullptr) || (*long_name_in ==
'\0'))
2388 gchar *long_name = g_strstrip (g_strdup (long_name_in));
2392 if (*long_name ==
'\0' || strcmp (long_name, old_long_name) == 0)
2395 LEAVE(
"empty string or name unchanged");
2401 GncMainWindow *window = GNC_MAIN_WINDOW(page->
window);
2405 LEAVE(
"no window widget available");
2410 if (main_window_find_tab_widget (window, page, &tab_widget))
2411 gtk_widget_set_tooltip_text (tab_widget, long_name);
2419 const gchar *name_in)
2421 GncMainWindow *window;
2423 GtkWidget *
label, *entry;
2429 if ((name_in ==
nullptr) || (*name_in ==
'\0'))
2434 name = g_strstrip(g_strdup(name_in));
2440 LEAVE(
"empty string or name unchanged");
2448 window = GNC_MAIN_WINDOW(page->
window);
2452 LEAVE(
"no window widget available");
2456 if (main_window_find_tab_items(window, page, &
label, &entry))
2457 gtk_label_set_text(GTK_LABEL(
label), name);
2460 tw = populate_tab_width_struct ();
2461 gnc_main_window_update_tab_width_one_page (page, tw);
2467 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2468 label = gtk_notebook_get_menu_label (GTK_NOTEBOOK(priv->
notebook),
2470 gtk_label_set_text(GTK_LABEL(
label), name);
2474 gnc_main_window_update_title(window);
2482 const gchar *color_in)
2484 GncMainWindow *window;
2486 GtkWidget *tab_widget;
2488 gchar *color_string =
nullptr;
2489 gboolean want_color = FALSE;
2493 color_string = g_strstrip(g_strdup(color_in));
2495 if (color_string && *color_string !=
'\0')
2499 window = GNC_MAIN_WINDOW(page->
window);
2506 main_window_find_tab_widget (window, page, &tab_widget);
2507 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2509 if (want_color && gdk_rgba_parse(&tab_color, color_string) && priv->
show_color_tabs)
2511 GtkCssProvider *provider = gtk_css_provider_new();
2512 GtkStyleContext *stylectxt;
2513 gchar *col_str, *widget_css;
2515 if (!GTK_IS_EVENT_BOX (tab_widget))
2517 GtkWidget *event_box = gtk_event_box_new ();
2518 g_object_ref (tab_widget);
2519 gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->
notebook),
2521 gtk_container_add (GTK_CONTAINER(event_box), tab_widget);
2522 g_object_unref (tab_widget);
2523 tab_widget = event_box;
2526 stylectxt = gtk_widget_get_style_context (GTK_WIDGET (tab_widget));
2527 col_str = gdk_rgba_to_string (&tab_color);
2528 widget_css = g_strconcat (
"*{\n background-color:", col_str,
";\n}\n",
nullptr);
2530 gtk_css_provider_load_from_data (provider, widget_css, -1,
nullptr);
2531 gtk_style_context_add_provider (stylectxt, GTK_STYLE_PROVIDER (provider),
2532 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
2533 g_object_unref (provider);
2535 g_free (widget_css);
2539 if (GTK_IS_EVENT_BOX (tab_widget))
2541 GtkWidget *tab_hbox = gtk_bin_get_child(GTK_BIN(tab_widget));
2542 g_object_ref (tab_hbox);
2543 gtk_container_remove (GTK_CONTAINER(tab_widget), tab_hbox);
2544 gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->
notebook),
2546 g_object_unref (tab_hbox);
2549 g_free(color_string);
2558 GncMainWindow *window;
2559 GtkWidget *tab_widget;
2560 GtkWidget *image = NULL;
2562 gchar *image_name = NULL;
2563 const gchar *icon_name;
2567 g_return_if_fail (page && page->
window);
2569 if (!GNC_IS_MAIN_WINDOW (page->
window))
2572 window = GNC_MAIN_WINDOW(page->
window);
2575 main_window_find_tab_widget (window, page, &tab_widget);
2579 LEAVE(
"no tab widget");
2583 if (GTK_IS_EVENT_BOX(tab_widget))
2584 tab_widget = gtk_bin_get_child (GTK_BIN(tab_widget));
2586 children = gtk_container_get_children (GTK_CONTAINER(tab_widget));
2588 for (GList *child = children; child; child = g_list_next (child))
2590 GtkWidget *widget =
static_cast<GtkWidget*
>(child->data);
2591 if (GTK_IS_IMAGE(widget))
2594 g_list_free (children);
2598 LEAVE(
"no image to replace");
2602 g_object_get (image,
"icon-name", &image_name, NULL);
2605 icon_name =
"changes-prevent-symbolic";
2607 icon_name = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
2609 if (g_strcmp0 (icon_name, image_name) == 0)
2611 LEAVE(
"page icon the same, no need to replace");
2612 g_free (image_name);
2615 gtk_container_remove (GTK_CONTAINER(tab_widget), image);
2616 image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
2617 gtk_widget_show (image);
2619 gtk_container_add (GTK_CONTAINER(tab_widget), image);
2620 gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
2621 gtk_box_reorder_child (GTK_BOX(tab_widget), image, 0);
2623 g_free (image_name);
2629 gnc_main_window_tab_entry_activate (GtkWidget *entry,
2632 GtkWidget *
label, *entry2;
2634 g_return_if_fail(GTK_IS_ENTRY(entry));
2635 g_return_if_fail(GNC_IS_PLUGIN_PAGE(page));
2638 if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->
window),
2639 page, &
label, &entry2))
2641 LEAVE(
"can't find required widgets");
2647 gtk_widget_hide(entry);
2648 gtk_widget_show(
label);
2654 gnc_main_window_tab_entry_editing_done (GtkWidget *entry,
2658 gnc_main_window_tab_entry_activate(entry, page);
2664 gnc_main_window_tab_entry_focus_out_event (GtkWidget *entry,
2669 gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(entry));
2675 gnc_main_window_tab_entry_key_press_event (GtkWidget *entry,
2679 if (event->keyval == GDK_KEY_Escape)
2681 GtkWidget *
label, *entry2;
2683 g_return_val_if_fail(GTK_IS_ENTRY(entry), FALSE);
2684 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
2687 if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->
window),
2688 page, &
label, &entry2))
2690 LEAVE(
"can't find required widgets");
2694 gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(
label)));
2695 gtk_widget_hide(entry);
2696 gtk_widget_show(
label);
2718 GObjectClass *object_class = G_OBJECT_CLASS (klass);
2719 GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS(klass);
2721 window_type = g_quark_from_static_string (
"gnc-main-window");
2723 object_class->constructed = gnc_main_window_constructed;
2724 object_class->finalize = gnc_main_window_finalize;
2727 gtkwidget_class->destroy = gnc_main_window_destroy;
2740 main_window_signals[PAGE_ADDED] =
2741 g_signal_new (
"page_added",
2742 G_OBJECT_CLASS_TYPE (object_class),
2746 g_cclosure_marshal_VOID__OBJECT,
2760 main_window_signals[PAGE_CHANGED] =
2761 g_signal_new (
"page_changed",
2762 G_OBJECT_CLASS_TYPE (object_class),
2766 g_cclosure_marshal_VOID__OBJECT,
2778 main_window_signals[MENU_CHANGED] =
2779 g_signal_new (
"menu_changed",
2780 G_OBJECT_CLASS_TYPE (object_class),
2784 g_cclosure_marshal_VOID__OBJECT,
2789 GNC_PREF_SHOW_CLOSE_BUTTON,
2790 (gpointer)gnc_main_window_update_tab_close,
2794 (gpointer)gnc_main_window_update_tab_width,
2797 gnc_hook_add_dangler(HOOK_BOOK_SAVED,
2798 (GFunc)gnc_main_window_update_all_titles,
nullptr,
nullptr);
2799 gnc_hook_add_dangler(HOOK_BOOK_OPENED,
2800 (GFunc)gnc_main_window_attach_to_book,
nullptr,
nullptr);
2811 gnc_main_window_init (GncMainWindow *window)
2816 gtk_widget_set_name (GTK_WIDGET(window),
"gnc-id-main-window");
2823 priv->display_item_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
nullptr);
2825 priv->previous_plugin_page_name =
nullptr;
2826 priv->previous_menu_qualifier =
nullptr;
2829 gtk_window_add_accel_group (GTK_WINDOW(window), priv->
accel_group);
2836 (gpointer)gnc_main_window_update_tab_color,
2839 gnc_main_window_setup_window (window);
2849 gnc_main_window_constructed (GObject *obj)
2853 G_OBJECT_CLASS (gnc_main_window_parent_class)->constructed (obj);
2867 gnc_main_window_finalize (GObject *
object)
2869 g_return_if_fail (
object !=
nullptr);
2870 g_return_if_fail (GNC_IS_MAIN_WINDOW (
object));
2872 if (active_windows ==
nullptr)
2879 G_OBJECT_CLASS (gnc_main_window_parent_class)->finalize (
object);
2884 gnc_main_window_remove_prefs (GncMainWindow *window)
2889 (gpointer)gnc_main_window_update_tab_color,
2893 GNC_PREF_SHOW_CLOSE_BUTTON,
2894 (gpointer)gnc_main_window_update_tab_close,
2899 (gpointer)gnc_main_window_update_tab_width,
2903 GNC_PREF_TAB_POSITION_TOP,
2904 (gpointer)gnc_main_window_update_tab_position,
2908 GNC_PREF_TAB_POSITION_BOTTOM,
2909 (gpointer)gnc_main_window_update_tab_position,
2913 GNC_PREF_TAB_POSITION_LEFT,
2914 (gpointer)gnc_main_window_update_tab_position,
2918 GNC_PREF_TAB_POSITION_RIGHT,
2919 (gpointer)gnc_main_window_update_tab_position,
2927 gnc_prefs_set_reg_negative_color_pref_id (0);
2935 gnc_prefs_set_reg_auto_raise_lists_id (0);
2941 gnc_main_window_destroy (GtkWidget *widget)
2943 GncMainWindow *window;
2945 GncPluginManager *manager;
2948 g_return_if_fail (widget !=
nullptr);
2949 g_return_if_fail (GNC_IS_MAIN_WINDOW (widget));
2951 window = GNC_MAIN_WINDOW (widget);
2952 #ifdef MAC_INTEGRATION 2953 auto entry = g_list_find (active_windows, window);
2954 if (entry && (entry->next || entry->prev))
2955 gnc_quartz_set_menu (GNC_MAIN_WINDOW (entry->next ? entry->next->data : entry->prev->data));
2957 active_windows = g_list_remove (active_windows, window);
2960 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2968 if (gnc_window_get_progressbar_window() == GNC_WINDOW(window))
2969 gnc_window_set_progressbar_window(
nullptr);
2970 #ifndef MAC_INTEGRATION 2972 gnc_main_window_update_all_menu_items();
2975 gnc_main_window_remove_prefs (window);
2980 g_hash_table_destroy (priv->display_item_hash);
2985 g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
2986 g_list_free (plugins);
2989 GTK_WIDGET_CLASS (gnc_main_window_parent_class)->destroy (widget);
2994 gnc_main_window_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
2997 GdkModifierType modifiers;
2999 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(widget), FALSE);
3001 priv = GNC_MAIN_WINDOW_GET_PRIVATE(widget);
3003 modifiers = gtk_accelerator_get_default_mod_mask ();
3005 if ((event->state & modifiers) == (GDK_CONTROL_MASK | GDK_MOD1_MASK))
3007 const gchar *account_key = C_ (
"lower case key for short cut to 'Accounts'",
"a");
3008 guint account_keyval = gdk_keyval_from_name (account_key);
3010 if ((account_keyval == event->keyval) || (account_keyval == gdk_keyval_to_lower (event->keyval)))
3014 for (GList *item = priv->
installed_pages; item; item = g_list_next (item))
3018 if (g_strcmp0 (pname,
"GncPluginPageAccountTree") == 0)
3020 gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->
notebook), page);
3026 else if ((GDK_KEY_Menu == event->keyval) || (GDK_KEY_space == event->keyval))
3028 GList *menu = gtk_menu_get_for_attach_widget (GTK_WIDGET(priv->
notebook));
3032 gtk_menu_popup_at_widget (GTK_MENU(menu->data),
3050 auto window{
static_cast<GncMainWindow*
>(g_object_new (GNC_TYPE_MAIN_WINDOW,
nullptr))};
3051 gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
3057 gtk_window_get_size (old_window, &width, &height);
3058 gtk_window_resize (GTK_WINDOW (window), width, height);
3059 if ((gdk_window_get_state((gtk_widget_get_window (GTK_WIDGET(old_window))))
3060 & GDK_WINDOW_STATE_MAXIMIZED) != 0)
3062 gtk_window_maximize (GTK_WINDOW (window));
3065 active_windows = g_list_append (active_windows, window);
3066 gnc_main_window_update_title(window);
3067 window->window_quitting = FALSE;
3068 window->just_plugin_prefs = FALSE;
3069 #ifdef MAC_INTEGRATION 3070 gnc_quartz_set_menu(window);
3072 gnc_main_window_update_all_menu_items();
3077 g_signal_connect (G_OBJECT(window),
"key-press-event",
3078 G_CALLBACK(gnc_main_window_key_press_event),
3089 gnc_main_window_engine_commit_error_callback( gpointer data,
3092 GncMainWindow* window = GNC_MAIN_WINDOW(data);
3094 const gchar *reason = _(
"Unable to save to database.");
3096 reason = _(
"Unable to save to database: Book is marked read-only.");
3097 dialog = gtk_message_dialog_new( GTK_WINDOW(window),
3098 GTK_DIALOG_DESTROY_WITH_PARENT,
3103 gtk_dialog_run(GTK_DIALOG (dialog));
3104 gtk_widget_destroy(dialog);
3126 gnc_main_window_connect (GncMainWindow *window,
3128 GtkWidget *tab_hbox,
3129 GtkWidget *menu_label)
3132 GtkNotebook *notebook;
3133 gint current_position = -1;
3135 page->
window = GTK_WIDGET(window);
3136 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3137 notebook = GTK_NOTEBOOK (priv->
notebook);
3145 gtk_notebook_insert_page_menu (notebook, page->
notebook_page,
3146 tab_hbox, menu_label, current_position);
3147 gtk_notebook_set_tab_reorderable (notebook, page->
notebook_page, TRUE);
3148 gnc_plugin_page_inserted (page);
3150 gtk_notebook_set_current_page (notebook, current_position);
3152 if (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)
3153 (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)(page, GTK_WIDGET(window));
3154 g_signal_emit (window, main_window_signals[PAGE_ADDED], 0, page);
3156 g_signal_connect(G_OBJECT(page->
notebook_page),
"popup-menu",
3158 g_signal_connect_after(G_OBJECT(page->
notebook_page),
"button-press-event",
3177 gnc_main_window_disconnect (GncMainWindow *window,
3181 GtkNotebook *notebook;
3186 g_signal_handlers_disconnect_by_func(G_OBJECT(page->
notebook_page),
3188 g_signal_handlers_disconnect_by_func(G_OBJECT(page->
notebook_page),
3195 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3198 gnc_plugin_page_unselected (page);
3207 notebook = GTK_NOTEBOOK (priv->
notebook);
3213 page_num = gtk_notebook_page_num(notebook, new_page->
notebook_page);
3214 gtk_notebook_set_current_page(notebook, page_num);
3219 while (gtk_events_pending())
3220 gtk_main_iteration();
3225 page_num = gtk_notebook_page_num(notebook, page->
notebook_page);
3226 gtk_notebook_remove_page (notebook, page_num);
3228 if ( gtk_notebook_get_current_page(notebook) == -1)
3234 gnc_main_window_switch_page(notebook,
nullptr, -1, window);
3238 gnc_plugin_page_removed (page);
3240 gnc_window_set_status (GNC_WINDOW(window), page,
nullptr);
3252 GncMainWindow *window;
3254 GtkNotebook *notebook;
3257 window = GNC_MAIN_WINDOW (page->
window);
3258 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3259 notebook = GTK_NOTEBOOK (priv->
notebook);
3260 page_num = gtk_notebook_page_num(notebook, page->
notebook_page);
3261 gtk_notebook_set_current_page (notebook, page_num);
3262 gtk_window_present(GTK_WINDOW(window));
3278 GtkWidget *tab_container, *tab_clickable_area;
3279 GtkWidget *
label, *entry;
3280 const gchar *icon, *text, *color_string, *lab_text;
3285 ENTER(
"window %p, page %p", window, page);
3287 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3288 g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
3291 if (gnc_main_window_page_exists(page))
3301 for (tmp = active_windows; tmp; tmp = g_list_next(tmp))
3303 window = GNC_MAIN_WINDOW(tmp->data);
3304 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3312 gtk_widget_show(GTK_WIDGET(window));
3314 else if ((window ==
nullptr) && active_windows)
3316 window =
static_cast<GncMainWindow*
>(active_windows->data);
3319 page->
window = GTK_WIDGET(window);
3336 icon = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
3338 label = gtk_label_new (lab_text);
3339 g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL,
label);
3341 tw = populate_tab_width_struct ();
3342 gnc_main_window_update_tab_width_one_page (page, tw);
3345 gtk_widget_show (
label);
3347 tab_container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
3352 gtk_widget_set_tooltip_text(tab_container, text);
3356 gtk_widget_set_name (GTK_WIDGET(tab_container),
"gnc-id-account-page-tab-box");
3358 gtk_box_set_homogeneous (GTK_BOX (tab_container), FALSE);
3359 gtk_widget_show (tab_container);
3362 tab_clickable_area = gtk_event_box_new();
3363 gtk_widget_show(tab_clickable_area);
3364 gtk_box_pack_start (GTK_BOX (tab_container), tab_clickable_area, TRUE, TRUE, 0);
3368 GtkWidget *tab_content = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
3369 gtk_widget_set_name(tab_content,
"tab-content");
3370 gtk_container_add(GTK_CONTAINER(tab_clickable_area), tab_content);
3371 gtk_widget_show(tab_content);
3373 if (icon !=
nullptr)
3375 image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
3376 gtk_widget_show (image);
3377 gtk_box_pack_start (GTK_BOX (tab_content), image, FALSE, FALSE, 0);
3378 gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
3379 gtk_box_pack_start (GTK_BOX (tab_content),
label, TRUE, TRUE, 0);
3382 gtk_box_pack_start (GTK_BOX (tab_content),
label, TRUE, TRUE, 0);
3384 entry = gtk_entry_new();
3385 gtk_widget_hide (entry);
3386 gtk_box_pack_start (GTK_BOX (tab_content), entry, TRUE, TRUE, 0);
3387 g_signal_connect(G_OBJECT(entry),
"activate",
3388 G_CALLBACK(gnc_main_window_tab_entry_activate), page);
3389 g_signal_connect(G_OBJECT(entry),
"focus-out-event",
3390 G_CALLBACK(gnc_main_window_tab_entry_focus_out_event),
3392 g_signal_connect(G_OBJECT(entry),
"key-press-event",
3393 G_CALLBACK(gnc_main_window_tab_entry_key_press_event),
3395 g_signal_connect(G_OBJECT(entry),
"editing-done",
3396 G_CALLBACK(gnc_main_window_tab_entry_editing_done),
3400 if (!g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE))
3402 GtkWidget *close_image, *close_button;
3403 GtkRequisition requisition;
3405 close_button = gtk_button_new();
3406 gtk_button_set_relief(GTK_BUTTON(close_button), GTK_RELIEF_NONE);
3407 close_image = gtk_image_new_from_icon_name (
"window-close", GTK_ICON_SIZE_MENU);
3408 gtk_widget_show(close_image);
3409 gtk_widget_get_preferred_size (close_image, &requisition,
nullptr);
3410 gtk_widget_set_size_request(close_button, requisition.width + 4,
3411 requisition.height + 2);
3412 gtk_container_add(GTK_CONTAINER(close_button), close_image);
3414 gtk_widget_show (close_button);
3416 gtk_widget_hide (close_button);
3419 g_signal_connect(G_OBJECT(tab_clickable_area),
"button-press-event",
3420 G_CALLBACK(gnc_tab_clicked_cb), page);
3422 g_signal_connect_swapped (G_OBJECT (close_button),
"clicked",
3425 gtk_box_pack_start (GTK_BOX (tab_container), close_button, FALSE, FALSE, 0);
3426 gtk_widget_set_margin_end (GTK_WIDGET(close_button), 5);
3427 g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON, close_button);
3438 gnc_main_window_connect(window, page, tab_container,
label);
3454 GncMainWindow *window;
3463 if (!GNC_IS_MAIN_WINDOW (page->
window))
3466 window = GNC_MAIN_WINDOW (page->
window);
3469 g_warning(
"Page is not in a window.");
3473 gnc_main_window_disconnect(window, page);
3475 g_object_unref(page);
3478 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3481 if (window->window_quitting)
3487 window->just_plugin_prefs = TRUE;
3488 g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
3489 window->just_plugin_prefs = FALSE;
3490 g_list_free (plugins);
3493 gnc_main_window_remove_prefs (window);
3496 gtk_widget_destroy (GTK_WIDGET(window));
3513 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3525 const gchar *group_name,
3526 GSimpleActionGroup *group)
3528 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3529 g_return_if_fail (group_name !=
nullptr);
3530 g_return_if_fail (G_IS_SIMPLE_ACTION_GROUP(group));
3532 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
3533 G_ACTION_GROUP(group));
3538 update_menu_model (GncMainWindow *window,
const gchar *ui_filename,
3539 const gchar **ui_updates)
3542 GError *error =
nullptr;
3544 GtkBuilder *builder = gtk_builder_new ();
3545 GMenuModel *menu_model_part;
3546 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
3548 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3549 g_return_if_fail (ui_filename !=
nullptr);
3550 g_return_if_fail (ui_updates !=
nullptr);
3552 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3554 gtk_builder_set_translation_domain (builder, PROJECT_NAME);
3555 res_name = g_strconcat (GNUCASH_RESOURCE_PREFIX
"/", ui_filename, NULL);
3557 gtk_builder_add_from_resource (builder, res_name, &error);
3562 g_critical (
"Failed to load, Error %s", error->message);
3563 g_error_free (error);
3567 for (gint i = 0; ui_updates[i]; i++)
3569 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, ui_updates[i]);
3571 gsm->search_action_label =
nullptr;
3572 gsm->search_action_name = ui_updates[i];
3573 gsm->search_action_target =
nullptr;
3576 g_menu_insert_section (G_MENU(gsm->model), gsm->index, NULL, G_MENU_MODEL(menu_model_part));
3578 PERR(
"Could not find '%s' in menu model", ui_updates[i]);
3581 g_object_unref (builder);
3593 const gchar *group_name,
3594 GActionEntry *actions,
3596 const gchar **ui_updates,
3597 const gchar *ui_filename,
3601 GSimpleActionGroup *simple_action_group;
3603 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3604 g_return_if_fail (group_name !=
nullptr);
3605 g_return_if_fail (actions !=
nullptr);
3606 g_return_if_fail (n_actions > 0);
3609 data->window = window;
3610 data->data = user_data;
3612 simple_action_group = g_simple_action_group_new ();
3614 g_action_map_add_action_entries (G_ACTION_MAP(simple_action_group),
3619 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
3620 G_ACTION_GROUP(simple_action_group));
3623 update_menu_model (window, ui_filename, ui_updates);
3634 const gchar *group_name)
3636 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3637 g_return_if_fail (group_name !=
nullptr);
3639 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
nullptr);
3645 GAction *action =
nullptr;
3647 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3648 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3650 action = g_action_map_lookup_action (G_ACTION_MAP(window),
3658 const gchar *group_name,
3661 GAction *action =
nullptr;
3663 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3664 g_return_val_if_fail (group_name !=
nullptr,
nullptr);
3665 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3667 auto action_group = gtk_widget_get_action_group (GTK_WIDGET(window), group_name);
3670 action = g_action_map_lookup_action (G_ACTION_MAP(action_group),
action_name);
3680 GSimpleActionGroup *
3682 const gchar *group_name)
3684 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3685 g_return_val_if_fail (group_name !=
nullptr,
nullptr);
3687 auto action_group = gtk_widget_get_action_group (GTK_WIDGET(window), group_name);
3688 return (GSimpleActionGroup*)action_group;
3696 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3697 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3699 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3708 GtkWidget *menu_item;
3710 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3711 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3713 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3715 menu_item = GTK_WIDGET(g_hash_table_lookup (priv->display_item_hash,
action_name));
3721 g_hash_table_insert (priv->display_item_hash, g_strdup (
action_name), menu_item);
3732 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3734 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3744 const gchar *tooltip)
3747 gboolean found =
false;
3749 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
false);
3750 g_return_val_if_fail (
action_name !=
nullptr,
false);
3751 g_return_val_if_fail (
label !=
nullptr,
false);
3753 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3756 nullptr, _(
label),
nullptr, _(tooltip));
3768 const gchar **action_names,
3773 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3775 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3777 for (gint i = 0; action_names[i]; i++)
3784 PINFO(
"Found menu_item %p with action name '%s', seting vis to '%s'",
3785 menu_item, action_names[i], vis ?
"true" :
"false");
3786 gtk_widget_set_visible (menu_item, vis);
3789 PINFO(
"Did not find menu_item with action name '%s' to set vis '%s'",
3790 action_names[i], vis ?
"true" :
"false");
3794 PINFO(
"Found tool_item %p with action name '%s', seting vis to '%s'",
3795 tool_item, action_names[i], vis ?
"true" :
"false");
3796 gtk_widget_set_visible (tool_item, vis);
3799 PINFO(
"Did not find tool_item with action name '%s' to set vis '%s'",
3800 action_names[i], vis ?
"true" :
"false");
3811 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3812 g_return_if_fail (toolbar_labels !=
nullptr);
3814 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3821 gnc_main_window_update_toolbar (GncMainWindow *window,
GncPluginPage *page,
3822 const gchar *toolbar_qualifier)
3825 GtkBuilder *builder;
3828 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3829 g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
3831 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3837 gchar *toolbar_name;
3840 if (toolbar_qualifier)
3841 toolbar_name = g_strconcat (
"mainwin-toolbar-", toolbar_qualifier,
nullptr);
3843 toolbar_name = g_strdup (
"mainwin-toolbar");
3845 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder, toolbar_name);
3848 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder,
"mainwin-toolbar");
3850 g_object_set (priv->
toolbar,
"toolbar-style", GTK_TOOLBAR_BOTH, NULL);
3852 g_free (toolbar_name);
3860 GVariant *state = g_action_get_state (G_ACTION(action));
3861 gtk_widget_set_visible (priv->
toolbar, g_variant_get_boolean (state));
3862 g_variant_unref (state);
3872 const gchar **ui_updates)
3875 const gchar *plugin_page_actions_group_name;
3876 GtkBuilder *builder;
3877 const gchar *menu_qualifier;
3879 GMenuModel *menu_model_part;
3880 #ifdef MAC_INTEGRATION 3881 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
3883 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3884 g_return_if_fail (page !=
nullptr);
3885 g_return_if_fail (ui_updates !=
nullptr);
3887 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3898 if (!plugin_page_actions_group_name)
3904 if ((g_strcmp0 (priv->previous_plugin_page_name,
3905 plugin_page_actions_group_name) == 0) &&
3906 (g_strcmp0 (priv->previous_menu_qualifier,
3907 menu_qualifier) == 0))
3910 priv->previous_plugin_page_name = plugin_page_actions_group_name;
3911 priv->previous_menu_qualifier = menu_qualifier;
3913 gnc_main_window_update_toolbar (window, page, menu_qualifier);
3916 g_hash_table_remove_all (priv->display_item_hash);
3918 GNC_MENU_ATTRIBUTE_TEMPORARY);
3920 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
3921 for (gint i = 0; ui_updates[i]; i++)
3926 menu_name = g_strconcat (ui_updates[i],
"-", menu_qualifier,
nullptr);
3928 menu_name = g_strdup (ui_updates[i]);
3930 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, menu_name);
3932 if (!menu_model_part)
3933 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, ui_updates[i]);
3935 gsm->search_action_label =
nullptr;
3936 gsm->search_action_name = ui_updates[i];
3937 gsm->search_action_target =
nullptr;
3940 g_menu_insert_section (G_MENU(gsm->model), gsm->index,
3941 nullptr, G_MENU_MODEL(menu_model_part));
3943 PERR(
"Could not find '%s' in menu model", ui_updates[i]);
3953 #ifdef MAC_INTEGRATION 3954 gtkosx_application_sync_menubar (theApp);
3955 g_object_unref (theApp);
3958 g_signal_emit_by_name (window,
"menu_changed", page);
3965 gnc_main_window_update_tab_position (gpointer prefs, gchar *pref, gpointer user_data)
3967 GncMainWindow *window;
3968 GtkPositionType position = GTK_POS_TOP;
3973 g_return_if_fail (GNC_IS_MAIN_WINDOW(user_data));
3975 window = GNC_MAIN_WINDOW(user_data);
3977 ENTER (
"window %p", window);
3986 position = GTK_POS_BOTTOM;
3991 position = GTK_POS_LEFT;
3996 position = GTK_POS_RIGHT;
4000 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4001 gtk_notebook_set_tab_pos (GTK_NOTEBOOK(priv->
notebook), position);
4003 action = g_action_map_lookup_action (G_ACTION_MAP(window),
4004 "ViewTabPositionAction");
4006 g_signal_handlers_block_by_func (G_OBJECT(action),
4007 (gpointer)gnc_main_window_cmd_view_tab_position,
4009 g_action_change_state (G_ACTION(action), g_variant_new_int32 (item));
4010 g_signal_handlers_unblock_by_func (G_OBJECT(action),
4011 (gpointer)gnc_main_window_cmd_view_tab_position,
4014 gnc_main_window_update_tab_width (
nullptr, (
char*)GNC_PREF_TAB_WIDTH,
nullptr);
4023 gnc_main_window_update_edit_actions_sensitivity (GncMainWindow *window, gboolean hide)
4027 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));
4029 gboolean can_copy =
false, can_cut =
false, can_paste =
false;
4031 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4034 if (page && GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)
4036 (GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)(page, hide);
4040 if (GTK_IS_EDITABLE (widget))
4042 gboolean has_selection;
4044 has_selection = gtk_editable_get_selection_bounds
4045 (GTK_EDITABLE (widget),
nullptr,
nullptr);
4047 can_copy = has_selection;
4048 can_cut = has_selection;
4051 else if (GTK_IS_TEXT_VIEW (widget))
4053 gboolean has_selection;
4054 GtkTextBuffer *text_buffer;
4056 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4057 has_selection = gtk_text_buffer_get_selection_bounds
4058 (text_buffer,
nullptr,
nullptr);
4060 can_copy = has_selection;
4061 can_cut = has_selection;
4066 #ifdef ORIGINAL_EPIPHANY_CODE 4068 can_copy = can_cut = can_paste =
true;
4072 can_copy = can_cut = can_paste =
false;
4076 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_copy);
4079 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_cut);
4082 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_paste);
4086 gnc_main_window_enable_edit_actions_sensitivity (GncMainWindow *window)
4091 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4094 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4097 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4102 gnc_main_window_edit_menu_show_cb (GtkWidget *menu,
4103 GncMainWindow *window)
4105 gnc_main_window_update_edit_actions_sensitivity (window, FALSE);
4109 gnc_main_window_edit_menu_hide_cb (GtkWidget *menu,
4110 GncMainWindow *window)
4112 gnc_main_window_enable_edit_actions_sensitivity (window);
4116 gnc_main_window_init_menu_updaters (GncMainWindow *window)
4118 GtkWidget *edit_menu_item, *edit_menu;
4122 edit_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM(edit_menu_item));
4124 g_signal_connect (edit_menu,
"show",
4125 G_CALLBACK(gnc_main_window_edit_menu_show_cb), window);
4126 g_signal_connect (edit_menu,
"hide",
4127 G_CALLBACK(gnc_main_window_edit_menu_hide_cb), window);
4132 gnc_main_window_page_focus_in (GtkWidget *widget, GdkEvent *event,
4135 auto window{
static_cast<GncMainWindow *
>(user_data)};
4138 g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
4143 gnc_main_window_get_redirect (GncMainWindow *window,
const gchar *
action_name)
4146 GAction *action =
nullptr;
4147 const gchar *group_name;
4149 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window),
nullptr);
4150 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
4152 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4166 PINFO(
"Redirect action is %p for action anme '%s' and group_name '%s'",
4172 main_window_realize_cb (GtkWidget *widget, gpointer user_data)
4174 GncMainWindow *window = (GncMainWindow*)user_data;
4181 g_signal_emit_by_name (window,
"menu_changed",
nullptr);
4185 gnc_main_window_setup_window (GncMainWindow *window)
4188 GtkWidget *main_vbox;
4189 GtkBuilder *builder;
4190 GncPluginManager *manager;
4192 GError *error =
nullptr;
4198 g_signal_connect (G_OBJECT (window),
"delete-event",
4199 G_CALLBACK (gnc_main_window_delete_event), window);
4202 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4203 gtk_box_set_homogeneous (GTK_BOX (main_vbox), FALSE);
4204 gtk_widget_show (main_vbox);
4205 gtk_container_add (GTK_CONTAINER (window), main_vbox);
4207 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4208 priv->
menu_dock = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4209 gtk_box_set_homogeneous (GTK_BOX (priv->
menu_dock), FALSE);
4211 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
menu_dock,
4214 priv->
notebook = gtk_notebook_new ();
4215 g_object_set(G_OBJECT(priv->
notebook),
4217 "enable-popup", TRUE,
4220 g_signal_connect (G_OBJECT (priv->
notebook),
"switch-page",
4221 G_CALLBACK (gnc_main_window_switch_page), window);
4222 g_signal_connect (G_OBJECT (priv->
notebook),
"page-reordered",
4223 G_CALLBACK (gnc_main_window_page_reordered), window);
4224 g_signal_connect (G_OBJECT (priv->
notebook),
"focus-in-event",
4225 G_CALLBACK (gnc_main_window_page_focus_in), window);
4226 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
notebook,
4231 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
statusbar,
4235 gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR(priv->
progressbar), TRUE);
4236 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(priv->
progressbar),
" ");
4240 gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(priv->
progressbar),
4243 builder = gtk_builder_new ();
4244 gtk_builder_set_translation_domain (builder, PROJECT_NAME);
4245 gtk_builder_add_from_resource (builder, GNUCASH_RESOURCE_PREFIX
"/gnc-main-window.ui", &error);
4249 g_critical (
"Failed to load, Error %s", error->message);
4250 g_error_free (error);
4254 g_action_map_add_action_entries (G_ACTION_MAP(window),
4259 priv->
menubar_model = (GMenuModel *)gtk_builder_get_object (builder,
"mainwin-menu");
4262 gtk_widget_show (GTK_WIDGET(priv->
menubar));
4264 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder,
"mainwin-toolbar");
4265 g_object_set (priv->
toolbar,
"toolbar-style", GTK_TOOLBAR_BOTH, NULL);
4266 gtk_container_add (GTK_CONTAINER(priv->
menu_dock), GTK_WIDGET(priv->
toolbar));
4267 gtk_widget_show (GTK_WIDGET(priv->
toolbar));
4269 g_object_unref (builder);
4272 initially_insensitive_actions,
4275 always_insensitive_actions,
4281 gtk_widget_insert_action_group (GTK_WIDGET(window),
"mainwin",
4282 G_ACTION_GROUP(window));
4285 GNC_PREF_TAB_POSITION_TOP,
4286 (gpointer)gnc_main_window_update_tab_position,
4289 GNC_PREF_TAB_POSITION_BOTTOM,
4290 (gpointer)gnc_main_window_update_tab_position,
4293 GNC_PREF_TAB_POSITION_LEFT,
4294 (gpointer)gnc_main_window_update_tab_position,
4297 GNC_PREF_TAB_POSITION_RIGHT,
4298 (gpointer)gnc_main_window_update_tab_position,
4300 gnc_main_window_update_tab_position (
nullptr,
nullptr, window);
4302 gnc_main_window_init_menu_updaters (window);
4306 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4309 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4312 if (!gnc_prefs_is_extra_enabled())
4315 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4321 g_list_foreach (plugins, gnc_main_window_add_plugin, window);
4322 g_list_free (plugins);
4324 g_signal_connect (G_OBJECT (manager),
"plugin-added",
4325 G_CALLBACK (gnc_main_window_plugin_added), window);
4326 g_signal_connect (G_OBJECT (manager),
"plugin-removed",
4327 G_CALLBACK (gnc_main_window_plugin_removed), window);
4330 g_signal_connect (G_OBJECT(window),
"realize",
4331 G_CALLBACK(main_window_realize_cb), window);
4336 #ifdef MAC_INTEGRATION 4345 gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data)
4356 gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window)
4359 gnc_main_window_quit (window);
4364 can_activate_cb(GtkWidget *widget, guint signal_id, gpointer data)
4371 gnc_quartz_set_menu (GncMainWindow* window)
4374 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
4375 GtkWidget *item =
nullptr;
4376 GClosure *quit_closure;
4378 gtk_widget_hide (priv->
menubar);
4379 gtk_widget_set_no_show_all (priv->
menubar,
true);
4381 gtkosx_application_set_menu_bar (theApp, GTK_MENU_SHELL(priv->
menubar));
4386 gtk_widget_hide (GTK_WIDGET(item));
4388 quit_closure = g_cclosure_new (G_CALLBACK (gnc_quartz_should_quit),
4390 gtk_accel_group_connect (priv->
accel_group,
'q', GDK_META_MASK,
4391 GTK_ACCEL_MASK, quit_closure);
4398 gtk_widget_hide (item);
4399 gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET(item), 0);
4406 gtk_widget_hide (GTK_WIDGET(item));
4407 gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET(item), 2);
4413 gtkosx_application_set_help_menu (theApp, GTK_MENU_ITEM(item));
4417 gtkosx_application_set_window_menu (theApp, GTK_MENU_ITEM(item));
4419 g_signal_connect (theApp,
"NSApplicationBlockTermination",
4420 G_CALLBACK(gnc_quartz_should_quit), window);
4422 g_signal_connect (priv->
menubar,
"can-activate-accel",
4423 G_CALLBACK (can_activate_cb),
nullptr);
4425 gtkosx_application_set_use_quartz_accelerators (theApp, FALSE);
4426 g_object_unref (theApp);
4428 #endif //MAC_INTEGRATION 4445 gnc_main_window_show_summarybar (GncMainWindow *window, GAction *action)
4450 if (action ==
nullptr)
4451 action = g_action_map_lookup_action (G_ACTION_MAP(window),
4452 "ViewSummaryAction");
4453 if (action ==
nullptr)
4456 state = g_action_get_state (G_ACTION(action));
4458 visible = g_variant_get_boolean (state);
4460 g_variant_unref (state);
4475 gnc_main_window_switch_page (GtkNotebook *notebook,
4476 gpointer *notebook_page,
4478 GncMainWindow *window)
4485 ENTER(
"Notebook %p, page, %p, index %d, window %p",
4486 notebook, notebook_page, pos, window);
4487 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4489 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4493 gnc_plugin_page_unselected (page);
4496 child = gtk_notebook_get_nth_page (notebook, pos);
4508 if (page !=
nullptr)
4512 visible = gnc_main_window_show_summarybar (window,
nullptr);
4516 gnc_plugin_page_selected (page);
4517 gnc_window_update_status (GNC_WINDOW(window), page);
4525 multiple_page_actions,
4528 gnc_main_window_update_title(window);
4529 #ifndef MAC_INTEGRATION 4530 gnc_main_window_update_menu_item(window);
4532 g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
4543 gnc_main_window_page_reordered (GtkNotebook *notebook,
4546 GncMainWindow *window)
4552 ENTER(
"Notebook %p, child %p, index %d, window %p",
4553 notebook, child, pos, window);
4554 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4558 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4564 if (!old_link)
return;
4575 gnc_main_window_plugin_added (GncPlugin *manager,
4577 GncMainWindow *window)
4579 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4580 g_return_if_fail (GNC_IS_PLUGIN (plugin));
4586 gnc_main_window_plugin_removed (GncPlugin *manager,
4588 GncMainWindow *window)
4590 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4591 g_return_if_fail (GNC_IS_PLUGIN (plugin));
4599 gnc_main_window_cmd_redirect (GSimpleAction *simple,
4600 GVariant *parameter,
4603 GncMainWindow *window = (GncMainWindow*)user_data;
4604 GAction *redirect_action;
4606 PINFO(
"Redirect action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4608 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4610 if (redirect_action)
4612 PINFO(
"Found action %p", redirect_action);
4613 g_action_activate (redirect_action,
nullptr);
4619 gnc_main_window_cmd_page_setup (GSimpleAction *simple,
4620 GVariant *parameter,
4623 GncMainWindow *window = (GncMainWindow*)user_data;
4624 GtkWindow *gtk_window;
4626 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
4628 gtk_window = gnc_window_get_gtk_window(GNC_WINDOW(window));
4635 QofBook *book = gnc_get_current_book ();
4636 gboolean use_split_action_for_num_before =
4638 gint use_read_only_threshold_before =
4640 gboolean use_split_action_for_num_after;
4641 gint use_read_only_threshold_after;
4642 gboolean return_val = FALSE;
4643 GList *results =
nullptr, *iter;
4645 if (!options)
return return_val;
4648 for (iter = results; iter; iter = iter->next)
4656 gtk_dialog_run(GTK_DIALOG(dialog));
4657 gtk_widget_destroy(dialog);
4658 g_free (iter->data);
4660 g_list_free (results);
4661 qof_book_begin_edit (book);
4663 use_split_action_for_num_after =
4667 book->cached_num_days_autoreadonly_isvalid = FALSE;
4670 if (use_split_action_for_num_before != use_split_action_for_num_after)
4673 use_split_action_for_num_after);
4676 if (use_read_only_threshold_before != use_read_only_threshold_after)
4679 qof_book_commit_edit (book);
4687 auto options{
static_cast<GncOptionDB *
>(user_data)};
4689 if (!options)
return;
4692 gnc_gui_refresh_all ();
4699 auto options{
static_cast<GncOptionDB *
>(user_data)};
4711 gnc_suspend_gui_refresh ();
4718 GNC_FEATURE_NUM_FIELD_SOURCE);
4720 gnc_book_option_num_field_source_change (num_action);
4721 gnc_resume_gui_refresh ();
4725 show_handler (
const char *class_name, gint component_id,
4726 gpointer user_data, gpointer iter_data)
4733 auto widget = optwin->get_widget();
4734 gtk_window_present(GTK_WINDOW(widget));
4741 auto book = gnc_get_current_book ();
4750 if (gnc_forall_gui_components(DIALOG_BOOK_OPTIONS_CM_CLASS,
4751 show_handler,
nullptr))
4756 (title ? title : _(
"Book Options")),
4757 DIALOG_BOOK_OPTIONS_CM_CLASS, parent);
4758 optionwin->build_contents(options);
4759 optionwin->set_book_help_cb();
4760 optionwin->set_apply_cb(gnc_book_options_dialog_apply_cb,
4762 optionwin->set_close_cb ( gnc_book_options_dialog_close_cb,
4766 return optionwin->get_widget();
4770 gnc_main_window_cmd_file_properties (GSimpleAction *simple,
4771 GVariant *parameter,
4774 GncMainWindow *window = (GncMainWindow*)user_data;
4779 gnc_main_window_cmd_file_close (GSimpleAction *simple,
4780 GVariant *parameter,
4783 GncMainWindow *window = (GncMainWindow*)user_data;
4787 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
4789 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4795 gnc_main_window_cmd_file_quit (GSimpleAction *simple,
4796 GVariant *parameter,
4799 GncMainWindow *window = (GncMainWindow*)user_data;
4803 gnc_main_window_quit(window);
4807 gnc_main_window_cmd_edit_cut (GSimpleAction *simple,
4808 GVariant *parameter,
4811 GncMainWindow *window = (GncMainWindow*)user_data;
4812 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4813 GAction *redirect_action;
4815 PINFO(
"Copy action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4817 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4819 if (redirect_action)
4821 PINFO(
"Found action %p", redirect_action);
4822 g_action_activate (redirect_action,
nullptr);
4826 if (GTK_IS_EDITABLE(widget))
4828 gtk_editable_cut_clipboard (GTK_EDITABLE(widget));
4830 else if (GTK_IS_TEXT_VIEW(widget))
4832 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4833 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(widget),
4834 GDK_SELECTION_CLIPBOARD);
4835 gboolean editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(widget));
4838 gtk_text_buffer_cut_clipboard (text_buffer, clipboard, editable);
4843 gnc_main_window_cmd_edit_copy (GSimpleAction *simple,
4844 GVariant *parameter,
4847 GncMainWindow *window = (GncMainWindow*)user_data;
4848 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4849 GAction *redirect_action;
4851 PINFO(
"Copy action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4853 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4855 if (redirect_action)
4857 PINFO(
"Found action %p", redirect_action);
4858 g_action_activate (redirect_action,
nullptr);
4862 if (GTK_IS_EDITABLE(widget))
4864 gtk_editable_copy_clipboard (GTK_EDITABLE(widget));
4866 else if (GTK_IS_TEXT_VIEW(widget))
4868 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4869 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(widget),
4870 GDK_SELECTION_CLIPBOARD);
4872 gtk_text_buffer_copy_clipboard (text_buffer, clipboard);
4877 gnc_main_window_cmd_edit_paste (GSimpleAction *simple,
4878 GVariant *parameter,
4881 GncMainWindow *window = (GncMainWindow*)user_data;
4882 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4883 GAction *redirect_action;
4885 PINFO(
"Paste action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4887 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4889 if (redirect_action)
4891 PINFO(
"Found action %p", redirect_action);
4892 g_action_activate (redirect_action,
nullptr);
4896 if (GTK_IS_EDITABLE(widget))
4898 gtk_editable_paste_clipboard (GTK_EDITABLE(widget));
4900 else if (GTK_IS_TEXT_VIEW(widget))
4902 auto clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
4906 auto text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4907 auto editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(widget));
4908 gtk_text_buffer_paste_clipboard (text_buffer, clipboard,
nullptr,
4915 gnc_main_window_cmd_edit_preferences (GSimpleAction *simple,
4916 GVariant *parameter,
4919 GncMainWindow *window = (GncMainWindow*)user_data;
4924 gnc_main_window_cmd_view_refresh (GSimpleAction *simple,
4925 GVariant *parameter,
4931 gnc_main_window_cmd_actions_reset_warnings (GSimpleAction *simple,
4932 GVariant *parameter,
4935 GncMainWindow *window = (GncMainWindow*)user_data;
4936 gnc_reset_warnings_dialog(GTK_WINDOW(window));
4940 gnc_main_window_cmd_actions_rename_page (GSimpleAction *simple,
4941 GVariant *parameter,
4944 GncMainWindow *window = (GncMainWindow*)user_data;
4947 GtkWidget *
label, *entry;
4950 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4954 LEAVE(
"No current page");
4958 if (!main_window_find_tab_items(window, page, &
label, &entry))
4960 LEAVE(
"can't find required widgets");
4964 gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(
label)));
4965 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
4966 gtk_widget_hide(
label);
4967 gtk_widget_show(entry);
4968 gtk_widget_grab_focus(entry);
4969 LEAVE(
"opened for editing");
4973 gnc_main_window_cmd_view_toolbar (GSimpleAction *simple,
4974 GVariant *parameter,
4977 GncMainWindow *window = (GncMainWindow*)user_data;
4979 GVariant *state = g_action_get_state (G_ACTION(simple));
4981 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4983 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!g_variant_get_boolean (state)));
4985 if (!g_variant_get_boolean (state))
4986 gtk_widget_show (priv->
toolbar);
4988 gtk_widget_hide (priv->
toolbar);
4990 g_variant_unref (state);
4994 gnc_main_window_cmd_view_summary (GSimpleAction *simple,
4995 GVariant *parameter,
4998 GncMainWindow *window = (GncMainWindow*)user_data;
5003 visible = gnc_main_window_show_summarybar (window, G_ACTION(simple));
5005 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!
visible));
5015 gnc_main_window_cmd_view_statusbar (GSimpleAction *simple,
5016 GVariant *parameter,
5019 GncMainWindow *window = (GncMainWindow*)user_data;
5021 GVariant *state = g_action_get_state (G_ACTION(simple));
5023 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5025 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!g_variant_get_boolean (state)));
5027 if (!g_variant_get_boolean (state))
5032 g_variant_unref (state);
5036 gnc_main_window_cmd_window_new (GSimpleAction *simple,
5040 GncMainWindow *new_window;
5045 gtk_widget_show(GTK_WIDGET(new_window));
5050 gnc_main_window_cmd_window_move_page (GSimpleAction *simple,
5054 GncMainWindow *window = (GncMainWindow*)user_data;
5056 GncMainWindow *new_window;
5058 GtkNotebook *notebook;
5059 GtkWidget *tab_widget, *menu_widget;
5061 ENTER(
"action %p, window %p", simple, window);
5064 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5068 LEAVE(
"invalid page");
5073 LEAVE(
"invalid notebook_page");
5077 #ifndef MAC_INTEGRATION 5079 gnc_info_dialog (GTK_WINDOW(window),
"%s",
5080 _(
"The maximum number of window menu entries reached, no more entries will be added."));
5083 notebook = GTK_NOTEBOOK (priv->
notebook);
5084 tab_widget = gtk_notebook_get_tab_label (notebook, page->
notebook_page);
5085 menu_widget = gtk_notebook_get_menu_label (notebook, page->
notebook_page);
5092 g_object_ref(tab_widget);
5093 g_object_ref(menu_widget);
5095 gnc_main_window_disconnect(window, page);
5099 gtk_widget_show(GTK_WIDGET(new_window));
5102 gnc_main_window_connect (new_window, page, tab_widget, menu_widget);
5106 g_object_unref(menu_widget);
5107 g_object_unref(tab_widget);
5108 g_object_unref(page);
5111 DEBUG(
"Moved page %p from window %p to new window %p",
5112 page, window, new_window);
5113 DEBUG(
"Old window current is %p, new window current is %p",
5116 LEAVE(
"page moved");
5120 gnc_main_window_cmd_view_tab_position (GSimpleAction *simple,
5121 GVariant *parameter,
5124 gint item = g_variant_get_int32 (parameter);
5126 g_action_change_state (G_ACTION(simple), parameter);
5128 if (item < 0 || item > 3)
5131 if (item != 0 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_TOP))
5134 if (item != 1 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_BOTTOM))
5137 if (item != 2 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT))
5140 if (item != 3 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_RIGHT))
5164 #ifndef MAC_INTEGRATION 5166 gnc_main_window_cmd_window_raise (GSimpleAction *simple,
5167 GVariant *parameter,
5170 GncMainWindow *window = (GncMainWindow*)user_data;
5171 GncMainWindow *new_window;
5174 g_return_if_fail (G_IS_SIMPLE_ACTION(simple));
5175 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
5177 item = g_variant_get_int32 (parameter);
5179 ENTER(
"action %p, window %p, item %d", simple, window, item);
5181 g_action_change_state (G_ACTION(simple), parameter);
5183 new_window =
static_cast<GncMainWindow*
>(g_list_nth_data (active_windows, item));
5184 gtk_window_present (GTK_WINDOW(new_window));
5188 g_idle_add ((GSourceFunc)gnc_main_window_update_radio_button, window);
5194 gnc_main_window_cmd_help_tutorial (GSimpleAction *simple,
5198 GncMainWindow *window = (GncMainWindow*)user_data;
5203 gnc_main_window_cmd_help_contents (GSimpleAction *simple,
5207 GncMainWindow *window = (GncMainWindow*)user_data;
5221 get_file (
const gchar *partial)
5223 gchar *filename, *text =
nullptr;
5227 if (filename && g_file_get_contents(filename, &text, &length,
nullptr))
5251 get_file_strsplit (
const gchar *partial)
5253 gchar *text, **lines;
5255 text = get_file(partial);
5259 lines = g_strsplit_set(text,
"\r\n", -1);
5270 url_signal_cb (GtkAboutDialog *dialog, gchar *uri, gpointer data)
5276 #define DEFAULT_MARGIN 5 5279 set_text_cursor (GdkWindow *win, GdkCursorType type)
5284 GdkCursor *current = gdk_window_get_cursor (win);
5285 if (type == gdk_cursor_get_cursor_type (current))
5288 GdkCursor *cur = gdk_cursor_new_for_display (gdk_window_get_display (win), type);
5289 gdk_window_set_cursor (win, cur);
5293 textview_motion_notify_cb (GtkWidget *textview,
5294 GdkEventMotion *event,
5297 if ((event->state & GDK_BUTTON1_MASK) ||
5298 gtk_text_buffer_get_has_selection (gtk_text_view_get_buffer
5299 (GTK_TEXT_VIEW(textview))))
5303 gboolean valid = gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW(textview),
5304 &iter, event->x, event->y);
5306 if (valid && (event->y > DEFAULT_MARGIN))
5308 GSList *tt_list = gtk_text_iter_get_tags (&iter);
5312 GtkTextTag *tt = (GtkTextTag*)g_slist_nth_data (tt_list, 0);
5314 if (g_object_get_data (G_OBJECT(tt),
"link"))
5315 set_text_cursor (event->window, GDK_HAND1);
5317 set_text_cursor (event->window, GDK_XTERM);
5319 g_slist_free (tt_list);
5322 set_text_cursor (event->window, GDK_XTERM);
5325 set_text_cursor (event->window, GDK_XTERM);
5331 textview_url_activate (GtkTextTag *tag,
5337 GdkEventButton *event_button = (GdkEventButton*)event;
5339 if ((event->type == GDK_BUTTON_RELEASE) &&
5340 (event_button->button == 1) &&
5341 !gtk_text_buffer_get_has_selection (gtk_text_view_get_buffer
5342 (GTK_TEXT_VIEW (
object))) &&
5343 (event_button->y > DEFAULT_MARGIN))
5345 gchar *link = (gchar*)g_object_get_data (G_OBJECT(tag),
"link");
5346 PINFO(
"Link is '%s'", link);
5347 gchar *escaped_uri = g_uri_escape_string (link,
":/.\\",
true);
5348 PINFO(
"Escaped Link is '%s'", escaped_uri);
5350 g_free (escaped_uri);
5358 get_max_text_width (GtkTextView *textview, std::vector<EnvPaths> ep_vec)
5360 gint max_text_width = 0;
5361 for (
const auto& ep : ep_vec)
5364 gchar *env_name = g_strconcat (ep.env_name,
":",
nullptr);
5366 PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET(textview),
5369 pango_layout_get_pixel_size (layout, &text_width,
nullptr);
5370 g_object_unref (layout);
5373 max_text_width = MAX(max_text_width, text_width);
5375 return max_text_width;
5379 create_left_margin_text_tag (GtkTextView *textview,
5387 GtkTextTag *lmargin_tt = gtk_text_tag_new (lmargin_tag);
5390 PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET(textview), text);
5391 pango_layout_get_pixel_size (layout, &text_width,
nullptr);
5392 g_object_unref (layout);
5394 g_object_set (G_OBJECT(lmargin_tt),
"left_margin",
5395 DEFAULT_MARGIN + max_width - text_width,
nullptr);
5401 get_link_color (
void)
5404 GtkWidget *dummy_link_button = gtk_link_button_new_with_label (
"https://www.gnucash.org",
"Dummy");
5405 GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET(dummy_link_button));
5406 gtk_style_context_get_color (context, GTK_STATE_FLAG_LINK, &link_color);
5412 create_url_text_tag (GtkDialog *dialog,
5420 GtkTextTag *url_tt = gtk_text_tag_new (url_tag);
5421 g_object_set (G_OBJECT(url_tt),
"underline", PANGO_UNDERLINE_SINGLE,
5422 "underline-set",
true,
nullptr);
5423 g_object_set (G_OBJECT(url_tt),
"foreground-rgba", &link_color,
nullptr);
5425 g_object_set_data_full (G_OBJECT(url_tt),
"link", g_strdup (uri), g_free);
5427 g_signal_connect (G_OBJECT(url_tt),
"event",
5428 G_CALLBACK(textview_url_activate), dialog);
5433 add_textview_css_class (GtkTextView *textview)
5436 GtkStyleContext *stylectxt = gtk_widget_get_style_context (GTK_WIDGET(textview));
5437 gtk_style_context_get_color (stylectxt, GTK_STATE_FLAG_NORMAL, &color);
5440 gtk_style_context_add_class (stylectxt,
"gnc-class-textview-dark");
5442 gtk_style_context_add_class (stylectxt,
"gnc-class-textview");
5446 add_about_paths (GtkDialog *dialog)
5452 PWARN(
"Unable to find AboutDialog 'page_vbox' Widget");
5456 GtkWidget *textview = gtk_text_view_new ();
5457 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(textview));
5458 GtkTextTagTable *ttt = gtk_text_buffer_get_tag_table (buffer);
5461 std::vector<EnvPaths> ep_vec = gnc_list_all_paths ();
5462 int ep_size = (int)ep_vec.size();
5465 GdkRGBA link_color = get_link_color ();
5466 gint max_text_width = get_max_text_width (GTK_TEXT_VIEW(textview), ep_vec);
5468 add_textview_css_class (GTK_TEXT_VIEW(textview));
5470 gtk_text_view_set_left_margin (GTK_TEXT_VIEW(textview), DEFAULT_MARGIN);
5471 gtk_text_view_set_right_margin (GTK_TEXT_VIEW(textview), DEFAULT_MARGIN);
5472 gtk_text_view_set_top_margin (GTK_TEXT_VIEW(textview), DEFAULT_MARGIN);
5473 gtk_text_view_set_bottom_margin (GTK_TEXT_VIEW(textview), DEFAULT_MARGIN);
5474 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW(textview), GTK_WRAP_NONE);
5476 gtk_text_buffer_create_tag (buffer,
"italic",
"style", PANGO_STYLE_ITALIC,
nullptr);
5478 gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
5480 for (
const auto& ep : ep_vec)
5482 gchar *env_name = g_strconcat (ep.env_name,
":",
nullptr);
5483 const gchar *uri =
gnc_uri_create_uri (
"file",
nullptr, 0,
nullptr,
nullptr, ep.env_path);
5484 gchar *display_uri = gnc_doclink_get_unescaped_just_uri (uri);
5486 gchar *url_tag = g_strdup_printf (
"%s%d",
"url_tag", row);
5487 gchar *lmargin_tag = g_strdup_printf (
"%s%d",
"lmargin_tag", row);
5489 gtk_text_tag_table_add (ttt, create_left_margin_text_tag (GTK_TEXT_VIEW(textview),
5493 gtk_text_tag_table_add (ttt, create_url_text_tag (dialog,
5498 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, env_name, -1, lmargin_tag,
nullptr);
5499 gtk_text_buffer_insert (buffer, &iter,
" ", -1);
5500 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, display_uri, -1, url_tag,
nullptr);
5503 g_free (lmargin_tag);
5504 g_free (display_uri);
5509 gtk_text_buffer_insert (buffer, &iter,
" ", -1);
5510 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, _(
"(User modifiable)"), -1,
"italic",
nullptr);
5514 gtk_text_buffer_insert (buffer, &iter,
"\n", -1);
5518 gtk_text_view_set_editable (GTK_TEXT_VIEW(textview),
false);
5520 g_signal_connect (G_OBJECT(textview),
"motion-notify-event",
5521 G_CALLBACK(textview_motion_notify_cb),
nullptr);
5523 gtk_container_add_with_properties (GTK_CONTAINER(page_vbox), textview,
5524 "position", 1,
nullptr);
5525 gtk_widget_show_all (page_vbox);
5531 gnc_main_window_cmd_help_about (GSimpleAction *simple,
5535 GncMainWindow *window = (GncMainWindow*)user_data;
5537 gchar *copyright = g_strdup_printf(_(
"Copyright © 1997-%s The GnuCash contributors."),
5539 gchar **authors = get_file_strsplit(
"AUTHORS");
5540 gchar **documenters = get_file_strsplit(
"DOCUMENTERS");
5541 gchar *license = get_file(
"LICENSE");
5542 GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
5543 GdkPixbuf *logo = gtk_icon_theme_load_icon (icon_theme,
5546 GTK_ICON_LOOKUP_USE_BUILTIN,
5548 gchar *version = g_strdup_printf (
"%s: %s\n%s: %s\nFinance::Quote: %s",
5550 _(
"Build ID"), gnc_build_id(),
5554 GtkDialog *dialog = GTK_DIALOG (gtk_about_dialog_new ());
5555 g_object_set(G_OBJECT(dialog),
"authors", authors,
"documenters",
5556 documenters,
"comments",
5557 _(
"Accounting for personal and small business finance."),
5558 "copyright", copyright,
"license", license,
"logo", logo,
5567 "translator-credits", _(
"translator-credits\n"),
5569 "website", PACKAGE_URL,
5570 "website-label", _(
"Visit the GnuCash website."),
5578 g_strfreev(documenters);
5580 g_strfreev(authors);
5581 g_object_unref (logo);
5582 g_signal_connect (dialog,
"activate-link",
5583 G_CALLBACK (url_signal_cb),
nullptr);
5586 add_about_paths (dialog);
5589 gtk_window_set_resizable(GTK_WINDOW (dialog), TRUE);
5591 gtk_window_set_transient_for (GTK_WINDOW (dialog),
5592 GTK_WINDOW (window));
5593 gtk_dialog_run (dialog);
5594 gtk_widget_destroy (GTK_WIDGET (dialog));
5606 #ifdef MAC_INTEGRATION 5607 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
5609 for (window_iter = active_windows; window_iter !=
nullptr; window_iter = window_iter->next)
5611 gtk_widget_show(GTK_WIDGET(window_iter->data));
5613 #ifdef MAC_INTEGRATION 5614 g_signal_connect(theApp,
"NSApplicationWillTerminate",
5615 G_CALLBACK(gnc_quartz_shutdown),
nullptr);
5616 gtkosx_application_ready(theApp);
5617 g_object_unref (theApp);
5624 GtkWidget *toplevel;
5629 toplevel = gtk_widget_get_toplevel (widget);
5630 if (toplevel && GTK_IS_WINDOW (toplevel))
5631 return GTK_WINDOW (toplevel);
5642 while (toplevel && !GNC_IS_MAIN_WINDOW (toplevel))
5643 toplevel = gtk_window_get_transient_for(toplevel);
5648 for (window = active_windows; window; window = window->next)
5649 if (gtk_window_is_active (GTK_WINDOW (window->data)))
5650 return static_cast<GtkWindow*
>(window->data);
5652 for (window = active_windows; window; window = window->next)
5653 if (gtk_widget_get_mapped (GTK_WIDGET(window->data)))
5654 return static_cast<GtkWindow*>(window->data);
5666 gnc_main_window_get_gtk_window (GncWindow *window)
5668 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window),
nullptr);
5669 return GTK_WINDOW(window);
5679 gnc_main_window_get_statusbar (GncWindow *window_in)
5682 GncMainWindow *window;
5684 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in),
nullptr);
5686 window = GNC_MAIN_WINDOW(window_in);
5687 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5698 gnc_main_window_get_progressbar (GncWindow *window_in)
5701 GncMainWindow *window;
5703 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in),
nullptr);
5705 window = GNC_MAIN_WINDOW(window_in);
5706 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5717 gnc_main_window_get_menubar (GncWindow *window)
5721 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5723 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5734 gnc_main_window_get_toolbar (GncWindow *window)
5738 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5740 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5751 gnc_main_window_get_menubar_model (GncWindow *window)
5755 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5757 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5767 static GtkAccelGroup *
5768 gnc_main_window_get_accel_group (GncWindow *window)
5772 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5774 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5784 gnc_window_main_window_init (GncWindowInterface *iface)
5786 iface->get_gtk_window = gnc_main_window_get_gtk_window;
5787 iface->get_statusbar = gnc_main_window_get_statusbar;
5788 iface->get_progressbar = gnc_main_window_get_progressbar;
5789 iface->get_menubar = gnc_main_window_get_menubar;
5790 iface->get_toolbar = gnc_main_window_get_toolbar;
5791 iface->get_menubar_model = gnc_main_window_get_menubar_model;
5792 iface->get_accel_group = gnc_main_window_get_accel_group;
5804 gncwin = GNC_WINDOW(window);
5805 gnc_window_set_progressbar_window(gncwin);
5824 GtkBuilder *builder;
5825 GMenuModel *menu_model;
5827 const gchar *menu_qualifier;
5828 gchar *popup_menu_name;
5829 GncWindow* gnc_window;
5830 GtkWidget *statusbar;
5832 g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
5834 ENTER(
"page %p, event %p", page, event);
5836 gnc_window = GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window);
5838 statusbar = gnc_window_get_statusbar (gnc_window);
5844 if (!menu_qualifier)
5847 if (builder ==
nullptr)
5849 LEAVE(
"no builder");
5854 popup_menu_name = g_strconcat (
"mainwin-popup-", menu_qualifier,
nullptr);
5856 popup_menu_name = g_strdup (
"mainwin-popup");
5858 menu_model = (GMenuModel *)gtk_builder_get_object (builder, popup_menu_name);
5861 menu_model = (GMenuModel *)gtk_builder_get_object (builder,
"mainwin-popup");
5863 menu = gtk_menu_new_from_model (menu_model);
5874 gtk_menu_attach_to_widget (GTK_MENU(menu), GTK_WIDGET(page->
window),
nullptr);
5875 gtk_menu_popup_at_pointer (GTK_MENU(menu), (GdkEvent *) event);
5877 g_free (popup_menu_name);
5900 ENTER(
"widget %p, page %p", widget, page);
5901 do_popup_menu(page,
nullptr);
5913 GdkEventButton *event,
5916 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
5918 ENTER(
"widget %p, event %p, page %p", whatever, event, page);
5920 if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
5922 do_popup_menu(page, event);
5923 LEAVE(
"menu shown");
5927 LEAVE(
"other click");
5935 for (
auto tmp = active_windows; tmp; tmp = g_list_next(tmp))
5938 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), sensitive);
5947 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5949 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5955 gnc_main_window_just_plugin_prefs (GncMainWindow* window)
5957 return window->just_plugin_prefs;
Holds all of the options for a book, report, or stylesheet, organized by GncOptionSections.
void gnc_preferences_dialog(GtkWindow *parent)
This function creates the preferences dialog and presents it to the user.
GncPluginPage * gnc_plugin_page_recreate_page(GtkWidget *window, const gchar *page_type, GKeyFile *key_file, const gchar *page_group)
This function looks up a specific plugin type by name, and then calls a plugin specific function to c...
GtkWidget * statusbar
A pointer to the status bar at the bottom edge of the window.
Functions to load, save and get gui state.
void gnc_menubar_model_remove_items_with_attrib(GMenuModel *menu_model, const gchar *attrib)
Remove GMenuModel entries based on having an attribute value equal to attrib, it does not matter what...
gboolean gnc_plugin_page_has_books(GncPluginPage *page)
Query a page to see if it has a reference to any book.
gboolean gnc_plugin_page_get_use_new_window(GncPluginPage *page)
Retrieve the "use new window" setting associated with this page.
void gnc_option_db_clean(GncOptionDB *odb)
Reset all ui_items to the option value.
gboolean gnc_plugin_page_finish_pending(GncPluginPage *page)
Tell a page to finish any outstanding activities.
void gnc_main_window_restore_all_windows(const GKeyFile *keyfile)
Restore the persistent state of all windows.
void gnc_main_window_update_menu_and_toolbar(GncMainWindow *window, GncPluginPage *page, const gchar **ui_updates)
Update the main window menu with the placeholders listed in ui_updates and load the page specific too...
void qof_book_load_options(QofBook *book, GncOptionLoad load_cb, GncOptionDB *odb)
Load a GncOptionsDB from KVP data.
GtkApplicationWindow gtk_application_window
The parent object for a main window.
void gnc_plugin_page_destroy_widget(GncPluginPage *plugin_page)
Destroy the display widget that corresponds to this plugin.
GtkAccelGroup * accel_group
The accelerator group for the window.
The instance data structure for a content plugin.
void qof_book_set_dirty_cb(QofBook *book, QofBookDirtyCB cb, gpointer user_data)
Set the function to call when a book transitions from clean to dirty, or vice versa.
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
gboolean gnc_main_window_button_press_cb(GtkWidget *whatever, GdkEventButton *event, GncPluginPage *page)
Callback function invoked when the user clicks in the content of any Gnucash window.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Register a callback that gets triggered when the given preference changes.
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
utility functions for the GnuCash UI
#define PINFO(format, args...)
Print an informational note.
void gnc_main_window_set_vis_of_items_by_action(GncMainWindow *window, const gchar **action_names, gboolean vis)
Show or hide menu and toolbar items based on a NULL terminated list of action names.
functions to query various version related strings that were set at build time.
void gnc_plugin_page_merge_actions(GncPluginPage *page)
Add the actions for a content page to the specified window.
QofBackendError
The errors that can be reported to the GUI & other front-end users.
void gnc_main_window_menu_add_accelerator_keys(GncMainWindow *window)
Scan the main window menu and add accelerator keys to main window accelerator group.
const gchar * gnc_plugin_page_get_page_long_name(GncPluginPage *page)
Retrieve the long name of this page.
gulong gnc_prefs_get_reg_negative_color_pref_id(void)
Get and Set registered preference id for register negative_color_pref.
void gnc_gobject_tracking_forget(GObject *object)
Tell gnucash to remember this object in the database.
time64 qof_book_get_session_dirty_time(const QofBook *book)
Retrieve the earliest modification time on the book.
GMenuModel * gnc_main_window_get_menu_model(GncMainWindow *window)
Return the GMenuModel for the main window menu bar.
gboolean gnc_menubar_model_find_item(GMenuModel *menu_model, GncMenuModelSearch *gsm)
Find a GtkMenu item from the action name.
This data structure allows the passing of the tab width and whether the tab layout is on the left or ...
void gnc_main_window_init_short_names(GncMainWindow *window, GncToolBarShortNames *toolbar_labels)
Update the labels of the toolbar items with short names.
#define DEBUG(format, args...)
Print a debugging message.
const gchar * gnc_plugin_page_get_page_name(GncPluginPage *page)
Retrieve the name of this page.
gint qof_book_get_num_days_autoreadonly(const QofBook *book)
Returns the number of days for auto-read-only transactions.
GMenuModel * menubar_model
The menubar_model.
Functions that are supported by all types of windows.
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.
gboolean qof_book_use_split_action_for_num_field(const QofBook *book)
Returns TRUE if this book uses split action field as the 'Num' field, FALSE if it uses transaction nu...
GSimpleActionGroup * gnc_plugin_page_get_action_group(GncPluginPage *page)
Retrieve the GSimpleActionGroup object associated with this page.
GtkWidget * toolbar
The toolbar.
GKeyFile helper routines.
GtkBuilder * gnc_plugin_page_get_builder(GncPluginPage *page)
Retrieve the GtkBuilder object associated with this page.
gboolean restoring_pages
Set when restoring plugin pages.
gboolean gnc_is_dark_theme(GdkRGBA *fg_color)
Return whether the current gtk theme is a dark one.
gint pos[2]
Array for window position.
Plugin management functions for the GnuCash UI.
GtkWidget * gnc_main_window_menu_find_menu_item(GncMainWindow *window, const gchar *action_name)
Find the menu item with the given action name for the window specified.
GtkWidget * window
The window that contains the display widget for this plugin.
gint event_handler_id
The identifier for this window's engine event handler.
gchar * gnc_uri_get_path(const gchar *uri)
Extracts the path part from a uri.
gboolean window_quitting
Set to TRUE when quitting from this window.
const gchar * gnc_plugin_page_get_page_color(GncPluginPage *page)
Retrieve the color of this page.
gboolean gnc_main_window_is_restoring_pages(GncMainWindow *window)
Check if the main window is restoring the plugin pages.
GtkWidget * gnc_book_options_dialog_cb(gboolean modal, gchar *title, GtkWindow *parent)
Opens the Book Options dialog.
C public interface for the Options Database.
void gnc_plugin_page_set_page_long_name(GncPluginPage *page, const char *name)
Set the long name of this page.
void gnc_main_window_merge_actions(GncMainWindow *window, const gchar *group_name, GActionEntry *actions, guint n_actions, const gchar **ui_updates, const gchar *ui_filename, gpointer user_data)
Add a set of actions to the specified window.
void gnc_engine_add_commit_error_callback(EngineCommitErrorCallback cb, gpointer data)
Set a callback function to be called in case an engine commit fails.
void gnc_shutdown(int exit_status)
Shutdown gnucash.
void gnc_ui_page_setup(GtkWindow *parent)
Run a page setup dialog and save the resulting GtkPageSetup in a static variable. ...
void gnc_main_window_foreach_page(GncMainWindowPageFunc fn, gpointer user_data)
Iterator function to walk all pages in all windows, calling the specified function for each page...
gboolean gnc_main_window_update_menu_for_action(GncMainWindow *window, const gchar *action_name, const gchar *label, const gchar *tooltip)
Find the GMenuModel item given the action name for the window specified.
void gnc_main_window_unmerge_actions(GncMainWindow *window, const gchar *group_name)
Remove a set of actions from the specified window.
const gchar * gnc_plugin_page_get_menu_qualifier(GncPluginPage *page)
Retrieve the menu qualifier for this page.
#define PERR(format, args...)
Log a serious error.
#define ENTER(format, args...)
Print a function entry debugging message.
void gnc_option_db_save(GncOptionDB *odb, QofBook *book, gboolean clear_options)
Save the GncOptionDB contents into a book's options store.
GtkWindow * gnc_ui_get_gtk_window(GtkWidget *widget)
Get a pointer to the widget's immediate top level GtkWindow.
void gnc_main_window_show_all_windows(void)
Shows all main windows.
const gchar * gnc_plugin_page_get_menu_popup_qualifier(GncPluginPage *page)
Retrieve the menu popup qualifier for this page.
void gnc_book_option_num_field_source_change_cb(gboolean num_action)
Calls gnc_book_option_num_field_source_change to initiate registered callbacks when num_field_source ...
void gnc_main_window_display_page(GncPluginPage *page)
Bring the window containing the specified page to the top of the window stack, then switch the notebo...
void gnc_main_window_save_all_windows(GKeyFile *keyfile)
Save the persistent state of all windows.
GncPluginPage * gnc_main_window_get_current_page(GncMainWindow *window)
Retrieve a pointer to the page that is currently at the front of the specified window.
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
Display a data plugin page in a window.
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Get an integer value from the preferences backend.
Functions for adding content to a window.
G_DEFINE_TYPE_WITH_CODE(GncMainWindow, gnc_main_window, GTK_TYPE_APPLICATION_WINDOW, G_IMPLEMENT_INTERFACE(GNC_TYPE_WINDOW, gnc_window_main_window_init)) static guint main_window_signals[LAST_SIGNAL]
A holding place for all the signals generated by the main window code.
GtkWidget * gnc_get_dialog_widget_from_id(GtkDialog *dialog, const gchar *id)
Find the Widget defined by 'id' in the dialog.
gint qof_event_register_handler(QofEventHandler handler, gpointer user_data)
Register a handler for events.
void main_window_update_page_long_name(GncPluginPage *page, const gchar *long_name_in)
Update the long name of the page in the main window.
#define PWARN(format, args...)
Log a warning.
void gnc_prefs_remove_cb_by_id(const gchar *group, guint id)
Remove a function that was registered for a callback when a specific preference in the settings group...
void gnc_gobject_tracking_remember(GObject *object)
Tell gnucash to remember this object in the database.
void qof_book_save_options(QofBook *book, GncOptionSave save_cb, GncOptionDB *odb, gboolean clear)
Save a GncOptionsDB back to the book's KVP.
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.
GAction * gnc_main_window_find_action_in_group(GncMainWindow *window, const gchar *group_name, const gchar *action_name)
Find the GAction in a specific action group for window.
gboolean gnc_main_window_is_quitting(GncMainWindow *window)
Check if the main window is quitting.
void gnc_main_window_all_action_set_sensitive(const gchar *action_name, gboolean sensitive)
Change the sensitivity of a command in all windows.
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
#define QOF_CHECK_TYPE(obj, type)
return TRUE if object is of the given type
void main_window_update_page_color(GncPluginPage *page, const gchar *color_in)
Update the color on the page tabs in the main window.
gchar * gnc_uri_normalize_uri(const gchar *uri, gboolean allow_password)
Composes a normalized uri starting from any uri (filename, db spec,...).
gchar * gnc_filepath_locate_doc_file(const gchar *name)
Given a documentation file name, find the file in the doc directory associated with this application...
gint QofEventId
Define the type of events allowed.
void qof_book_mark_session_saved(QofBook *book)
The qof_book_mark_saved() routine marks the book as having been saved (to a file, to a database)...
void gnc_plugin_page_set_use_new_window(GncPluginPage *page, gboolean use_new)
Set the "use new window" setting associated with this page.
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...
GAction * gnc_main_window_find_action(GncMainWindow *window, const gchar *action_name)
Find the GAction in the main window.
gboolean gnc_prefs_set_bool(const gchar *group, const gchar *pref_name, gboolean value)
Store a boolean value into the preferences backend.
GtkWidget * notebook
The notebook containing all the pages in this window.
void gnc_plugin_page_disconnect_page_changed(GncPluginPage *page)
Disconnect the page_changed_id signal callback.
void gnc_option_db_load(GncOptionDB *odb, QofBook *book)
Load a book's options into the GncOptionDB.
void gnc_option_db_destroy(GncOptionDB *odb)
Destruct and release a GncOptionDB.
gboolean gnc_plugin_page_has_book(GncPluginPage *page, QofBook *book)
Query a page to see if it has a reference to a given book.
char * gnc_print_time64(time64 time, const char *format)
print a time64 as a date string per format
gboolean gnc_main_window_popup_menu_cb(GtkWidget *widget, GncPluginPage *page)
Callback function invoked when the user requests that Gnucash popup the contextual menu via the keybo...
The instance private data structure for an embedded window object.
The instance data structure for a main window object.
GtkWidget * gnc_menubar_model_find_menu_item(GMenuModel *menu_model, GtkWidget *menu, const gchar *action_name)
Find a GtkMenu item from the action name.
gboolean gnc_book_options_dialog_apply_helper(GncOptionDB *options)
Processes selected options in the Book Options dialog: checks book_currency and use_split_action_for_...
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
const gchar * gnc_plugin_page_get_simple_action_group_name(GncPluginPage *page)
Retrieve the simple action group name associated with this plugin page.
GncPluginManager * gnc_plugin_manager_get(void)
Retrieve a pointer to the plugin manager.
GList * usage_order
A list of pages in order of use (most recent -> least recent)
Gnome specific utility functions.
void gnc_plugin_page_save_page(GncPluginPage *page, GKeyFile *key_file, const gchar *group_name)
Call the plugin specific function that will save the state of a content page to a disk...
#define PLUGIN_PAGE_LABEL
This label is used to provide a mapping from a visible page widget back to the corresponding GncPlugi...
gboolean show_color_tabs
Show account color as background on tabs.
GtkWidget * gnc_find_toolbar_item(GtkWidget *toolbar, const gchar *action_name)
Search the toolbar for the tool item based on the action name.
Dialog for handling user preferences.
GtkWidget * menubar
The menubar.
gboolean qof_book_session_not_saved(const QofBook *book)
qof_book_not_saved() returns the value of the session_dirty flag, set when changes to any object in t...
All type declarations for the whole Gnucash engine.
const char * gnc_quote_source_fq_version(void)
This function returns the version of the Finance::Quote module installed on a user's computer...
gboolean gnc_main_window_finish_pending(GncMainWindow *window)
Tell a window to finish any outstanding activities.
Generic api to store and retrieve preferences.
Utility functions for file access.
gboolean just_plugin_prefs
Just remove preferences only from plugins.
void gnc_add_accelerator_keys_for_menu(GtkWidget *menu, GMenuModel *model, GtkAccelGroup *accel_group)
Add accelerator keys for menu item widgets.
gboolean gnc_uri_targets_local_fs(const gchar *uri)
Checks if the given uri is either a valid file uri or a local filesystem path.
void main_window_update_page_set_read_only_icon(GncPluginPage *page, gboolean read_only)
Update the icon on the page tabs in the main window.
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
GncMainWindow * gnc_main_window_new(void)
Create a new gnc main window plugin.
void gnc_plugin_page_set_page_color(GncPluginPage *page, const char *color)
Set the color of this page.
GList * gnc_option_db_commit(GncOptionDB *odb)
Write all changed ui_item values to their options.
cannot write to file/directory
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
const char * gnc_version(void)
Parse <prefix>/etc/gnucash/environment and set environment variables based on the contents of that fi...
void gnc_main_window_close_page(GncPluginPage *page)
Remove a data plugin page from a window and display the previous page.
Functions for adding plugins to a GnuCash window.
#define LEAVE(format, args...)
Print a function exit debugging message.
GList * gnc_plugin_manager_get_plugins(GncPluginManager *manager)
Get a list of all plugins being held by the plugin manager.
void gnc_plugin_page_set_page_name(GncPluginPage *page, const char *name)
Set the name of this page.
GList * installed_pages
A list of all pages that are installed in this window.
GtkWidget * progressbar
A pointer to the progress bar at the bottom right of the window that is contained in the status bar...
time64 gnc_time(time64 *tbuf)
get the current time
Utility functions for convert uri in separate components and back.
GncPluginPage * current_page
The currently selected page.
GSimpleActionGroup * gnc_main_window_get_action_group(GncMainWindow *window, const gchar *group_name)
Retrieve a specific set of user interface actions from a window.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
gulong gnc_prefs_get_reg_auto_raise_lists_id(void)
Get and Set registered preference id for register auto_raise_lists.
void gnc_launch_doclink(GtkWindow *parent, const char *uri)
Launch the default browser and open the provided URI.
void gnc_main_window_restore_default_state(GncMainWindow *window)
Restore the persistent state of one window to a sane default.
The class data structure for a main window object.
File path resolution utility functions.
gboolean gnc_main_window_all_finish_pending(void)
Tell all pages in all windows to finish any outstanding activities.
void gnc_option_db_book_options(GncOptionDB *odb)
Register the standard option set for a QofBook.
gint gnc_list_length_cmp(const GList *list, size_t len)
Scans the GList elements the minimum number of iterations required to test it against a specified siz...
void gnc_main_window_manual_merge_actions(GncMainWindow *window, const gchar *group_name, GSimpleActionGroup *group)
Manually add a set of actions to the specified window.
void main_window_update_page_name(GncPluginPage *page, const gchar *name_in)
Update the name of the page in the main window.
gboolean gnc_menubar_model_update_item(GMenuModel *menu_model, const gchar *action_name, const gchar *target, const gchar *label, const gchar *accel_name, const gchar *tooltip)
Update the GMenuModel item based on the action name by copying existing item, removing it and inserti...
GAction * gnc_plugin_page_get_action(GncPluginPage *page, const gchar *name)
Retrieve a GAction object associated with this page.
GtkWidget * notebook_page
The display widget for this plugin.
GtkWidget * menu_dock
The dock (vbox) at the top of the window containing the menubar and toolbar.
gchar * gnc_uri_create_uri(const gchar *scheme, const gchar *hostname, gint32 port, const gchar *username, const gchar *password, const gchar *path)
Composes a normalized uri starting from its separate components.
void gnc_plugin_page_show_summarybar(GncPluginPage *page, gboolean visible)
Show/hide the summarybar associated with this page.
GtkWidget * gnc_main_window_toolbar_find_tool_item(GncMainWindow *window, const gchar *action_name)
Find the toolbar item with the given action name for the window specified.
GtkWidget * gnc_plugin_page_create_widget(GncPluginPage *plugin_page)
Create the display widget that corresponds to this plugin.
constexpr auto gnc_main_window_max_number
Max number of windows allowed.
void gnc_main_window_set_progressbar_window(GncMainWindow *window)
Set the window where all progressbar updates should occur.
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)
Remove a function that was registered for a callback when the given preference changed.
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Get an float value from the preferences backend.
const gchar * gnc_plugin_page_get_plugin_name(GncPluginPage *plugin_page)
Retrieve the textual name of a plugin.
Utility functions for file access.
GncOptionDB * gnc_option_db_new(void)
Create an empty option database.