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 GObjectClass *parent_class =
nullptr;
145 static GQuark window_type = 0;
148 static GList *active_windows =
nullptr;
151 static guint secs_to_save = 0;
152 #define MSG_AUTO_SAVE _("Changes will be saved automatically in %u seconds") 158 static void gnc_main_window_finalize (GObject *
object);
159 static void gnc_main_window_destroy (GtkWidget *widget);
161 static void gnc_main_window_setup_window (
GncMainWindow *window);
163 #ifndef MAC_INTEGRATION 164 static void gnc_main_window_update_all_menu_items (
void);
168 static void gnc_main_window_switch_page (GtkNotebook *notebook, gpointer *notebook_page, gint pos,
GncMainWindow *window);
169 static void gnc_main_window_page_reordered (GtkNotebook *notebook, GtkWidget *child, guint pos,
GncMainWindow *window);
172 static void gnc_main_window_engine_commit_error_callback( gpointer data,
QofBackendError errcode );
175 static void gnc_main_window_cmd_redirect (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
176 static void gnc_main_window_cmd_page_setup (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
177 static void gnc_main_window_cmd_file_properties (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
178 static void gnc_main_window_cmd_file_close (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
179 static void gnc_main_window_cmd_file_quit (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
180 static void gnc_main_window_cmd_edit_cut (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
181 static void gnc_main_window_cmd_edit_copy (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
182 static void gnc_main_window_cmd_edit_paste (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
183 static void gnc_main_window_cmd_edit_preferences (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
184 static void gnc_main_window_cmd_view_refresh (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
185 static void gnc_main_window_cmd_view_toolbar (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
186 static void gnc_main_window_cmd_view_summary (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
187 static void gnc_main_window_cmd_view_statusbar (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
189 static void gnc_main_window_cmd_view_tab_position (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
191 static void gnc_main_window_cmd_actions_reset_warnings (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
192 static void gnc_main_window_cmd_actions_rename_page (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
193 static void gnc_main_window_cmd_window_new (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
194 static void gnc_main_window_cmd_window_move_page (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
195 #ifndef MAC_INTEGRATION 196 static void gnc_main_window_cmd_window_raise (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
198 static void gnc_main_window_cmd_help_tutorial (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
199 static void gnc_main_window_cmd_help_contents (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
200 static void gnc_main_window_cmd_help_about (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
202 static void do_popup_menu(
GncPluginPage *page, GdkEventButton *event);
203 static GtkWidget *gnc_main_window_get_statusbar (GncWindow *window_in);
204 static void statusbar_notification_lastmodified (
void);
205 static void gnc_main_window_update_tab_position (gpointer prefs, gchar *pref, gpointer user_data);
206 static void gnc_main_window_remove_prefs (
GncMainWindow *window);
208 #ifdef MAC_INTEGRATION 209 static void gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data);
210 static gboolean gnc_quartz_should_quit (GtkosxApplication *theApp,
GncMainWindow *window);
213 static void gnc_main_window_init_menu_updaters (
GncMainWindow *window);
257 const gchar *previous_plugin_page_name;
258 const gchar *previous_menu_qualifier;
263 GHashTable *display_item_hash;
269 G_IMPLEMENT_INTERFACE (GNC_TYPE_WINDOW,
270 gnc_window_main_window_init))
272 #define GNC_MAIN_WINDOW_GET_PRIVATE(o) \ 273 ((GncMainWindowPrivate*)gnc_main_window_get_instance_private((GncMainWindow*)o)) 277 static guint main_window_signals[LAST_SIGNAL] = { 0 };
280 toggle_change_state (GSimpleAction *simple,
284 g_simple_action_set_state (simple, state);
288 radio_change_state (GSimpleAction *simple,
292 g_simple_action_set_state (simple, state);
299 static GActionEntry gnc_menu_actions [] =
301 {
"FilePageSetupAction", gnc_main_window_cmd_page_setup,
nullptr,
nullptr,
nullptr },
302 {
"FilePropertiesAction", gnc_main_window_cmd_file_properties,
nullptr,
nullptr,
nullptr },
303 {
"FileCloseAction", gnc_main_window_cmd_file_close,
nullptr,
nullptr,
nullptr },
304 {
"FilePrintAction", gnc_main_window_cmd_redirect,
nullptr,
nullptr,
nullptr },
305 {
"FileQuitAction", gnc_main_window_cmd_file_quit,
nullptr,
nullptr,
nullptr },
307 {
"EditCutAction", gnc_main_window_cmd_edit_cut,
nullptr,
nullptr,
nullptr },
308 {
"EditCopyAction", gnc_main_window_cmd_edit_copy,
nullptr,
nullptr,
nullptr },
309 {
"EditPasteAction", gnc_main_window_cmd_edit_paste,
nullptr,
nullptr,
nullptr },
310 {
"EditPreferencesAction", gnc_main_window_cmd_edit_preferences,
nullptr,
nullptr,
nullptr },
312 {
"ActionsForgetWarningsAction", gnc_main_window_cmd_actions_reset_warnings,
nullptr,
nullptr,
nullptr },
313 {
"ActionsRenamePageAction", gnc_main_window_cmd_actions_rename_page,
nullptr,
nullptr,
nullptr },
315 {
"TransactionAction",
nullptr,
nullptr,
nullptr,
nullptr },
317 {
"ViewSortByAction",
nullptr,
nullptr,
nullptr,
nullptr },
318 {
"ViewFilterByAction",
nullptr,
nullptr,
nullptr,
nullptr },
319 {
"ViewRefreshAction", gnc_main_window_cmd_view_refresh,
nullptr,
nullptr,
nullptr },
320 {
"ViewToolbarAction", gnc_main_window_cmd_view_toolbar,
nullptr,
"true", toggle_change_state },
321 {
"ViewSummaryAction", gnc_main_window_cmd_view_summary,
nullptr,
"true", toggle_change_state },
322 {
"ViewStatusbarAction", gnc_main_window_cmd_view_statusbar,
nullptr,
"true", toggle_change_state },
323 {
"ViewTabPositionAction", gnc_main_window_cmd_view_tab_position,
"i",
"@i 0", radio_change_state },
325 {
"ScheduledAction",
nullptr,
nullptr,
nullptr,
nullptr },
327 {
"ExtensionsAction",
nullptr,
nullptr,
nullptr,
nullptr },
329 {
"WindowNewAction", gnc_main_window_cmd_window_new,
nullptr,
nullptr,
nullptr },
330 {
"WindowMovePageAction", gnc_main_window_cmd_window_move_page,
nullptr,
nullptr,
nullptr },
331 #ifndef MAC_INTEGRATION 332 {
"WindowAction", gnc_main_window_cmd_window_raise,
"i",
"@i 0", radio_change_state },
334 {
"HelpTutorialAction", gnc_main_window_cmd_help_tutorial,
nullptr,
nullptr,
nullptr },
335 {
"HelpContentsAction", gnc_main_window_cmd_help_contents,
nullptr,
nullptr,
nullptr },
336 {
"HelpAboutAction", gnc_main_window_cmd_help_about,
nullptr,
nullptr,
nullptr },
339 static guint gnc_menu_n_actions = G_N_ELEMENTS(gnc_menu_actions);
345 static const gchar *always_insensitive_actions[] =
355 static const gchar *initially_insensitive_actions[] =
366 static const gchar *always_hidden_actions[] =
369 "ViewFilterByAction",
376 static const gchar *immutable_page_actions[] =
385 static const gchar *multiple_page_actions[] =
387 "WindowMovePageAction",
395 #define WINDOW_COUNT "WindowCount" 396 #define WINDOW_STRING "Window %d" 397 #define WINDOW_GEOMETRY "WindowGeometry" 398 #define WINDOW_POSITION "WindowPosition" 399 #define WINDOW_MAXIMIZED "WindowMaximized" 400 #define TOOLBAR_VISIBLE "ToolbarVisible" 401 #define STATUSBAR_VISIBLE "StatusbarVisible" 402 #define SUMMARYBAR_VISIBLE "SummarybarVisible" 403 #define WINDOW_FIRSTPAGE "FirstPage" 404 #define WINDOW_PAGECOUNT "PageCount" 405 #define WINDOW_PAGEORDER "PageOrder" 406 #define PAGE_TYPE "PageType" 407 #define PAGE_NAME "PageName" 408 #define PAGE_STRING "Page %d" 413 const gchar *group_name;
434 for (
auto w = active_windows; w; w = g_list_next(w))
437 auto priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
438 for (
auto p = priv->installed_pages; p; p = g_list_next(p))
465 gchar *page_group, *page_type =
nullptr, *name =
nullptr;
466 const gchar *class_type;
467 GError *error =
nullptr;
469 ENTER(
"window %p, data %p (key file %p, window %d, page start %d, page num %d)",
470 window, data, data->key_file, data->window_num, data->page_offset,
473 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
474 page_group = g_strdup_printf(PAGE_STRING,
475 data->page_offset + data->page_num);
476 page_type = g_key_file_get_string(data->key_file, page_group,
480 g_warning(
"error reading group %s key %s: %s",
481 page_group, PAGE_TYPE, error->message);
490 class_type = GNC_PLUGIN_PAGE_GET_CLASS(page)->plugin_name;
491 if (strcmp(page_type, class_type) != 0)
493 g_warning(
"error: page types don't match: state %s, existing page %s",
494 page_type, class_type);
502 data->key_file, page_group);
506 if (page->
window ==
nullptr)
513 name = g_key_file_get_string(data->key_file, page_group,
517 g_warning(
"error reading group %s key %s: %s",
518 page_group, PAGE_NAME, error->message);
523 DEBUG(
"updating page name for %p to %s.", page, name);
553 gint *pos, *geom, *order;
557 gsize page_start, page_count, i;
558 GError *error =
nullptr;
561 ENTER(
"window %p, data %p (key file %p, window %d)",
562 window, data, data->key_file, data->window_num);
563 window_group = g_strdup_printf(WINDOW_STRING, data->window_num + 1);
572 if (!g_key_file_has_group (data->key_file, window_group) ||
573 !g_key_file_has_key (data->key_file, window_group, WINDOW_PAGECOUNT, &error))
578 PINFO (
"saved state had an empty first main window\n" 579 "an account hierarchy page was added automatically to avoid confusion");
582 PINFO (
"saved state had an empty main window, skipping restore");
589 page_count = g_key_file_get_integer(data->key_file,
590 window_group, WINDOW_PAGECOUNT, &error);
593 g_warning(
"error reading group %s key %s: %s",
594 window_group, WINDOW_PAGECOUNT, error->message);
603 page_start = g_key_file_get_integer(data->key_file,
604 window_group, WINDOW_FIRSTPAGE, &error);
607 g_warning(
"error reading group %s key %s: %s",
608 window_group, WINDOW_FIRSTPAGE, error->message);
613 if (window ==
nullptr)
615 DEBUG(
"Window %d doesn't exist. Creating new window.", data->window_num);
616 DEBUG(
"active_windows %p.", active_windows);
618 DEBUG(
"first window %p.", active_windows->data);
622 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
625 geom = g_key_file_get_integer_list(data->key_file, window_group,
626 WINDOW_GEOMETRY, &length, &error);
629 g_warning(
"error reading group %s key %s: %s",
630 window_group, WINDOW_GEOMETRY, error->message);
634 else if (length != 2)
636 g_warning(
"invalid number of values for group %s key %s",
637 window_group, WINDOW_GEOMETRY);
641 gtk_window_resize(GTK_WINDOW(window), geom[0], geom[1]);
642 DEBUG(
"window (%p) size %dx%d", window, geom[0], geom[1]);
647 pos = g_key_file_get_integer_list(data->key_file, window_group,
648 WINDOW_POSITION, &length, &error);
651 g_warning(
"error reading group %s key %s: %s",
652 window_group, WINDOW_POSITION, error->message);
656 else if (length != 2)
658 g_warning(
"invalid number of values for group %s key %s",
659 window_group, WINDOW_POSITION);
662 else if ((pos[0] + (geom ? geom[0] : 0) < 0) ||
663 (pos[0] > gdk_screen_width()) ||
664 (pos[1] + (geom ? geom[1] : 0) < 0) ||
665 (pos[1] > gdk_screen_height()))
667 DEBUG(
"position %dx%d, size%dx%d is offscreen; will not move",
668 pos[0], pos[1], geom ? geom[0] : 0, geom ? geom[1] : 0);
672 gtk_window_move(GTK_WINDOW(window), pos[0], pos[1]);
673 priv->
pos[0] = pos[0];
674 priv->
pos[1] = pos[1];
675 DEBUG(
"window (%p) position %dx%d", window, pos[0], pos[1]);
686 max = g_key_file_get_boolean(data->key_file, window_group,
687 WINDOW_MAXIMIZED, &error);
690 g_warning(
"error reading group %s key %s: %s",
691 window_group, WINDOW_MAXIMIZED, error->message);
697 gtk_window_maximize(GTK_WINDOW(window));
707 GVariant *state = g_action_get_state (G_ACTION(action));
708 gboolean visible = g_variant_get_boolean (state);
709 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
710 TOOLBAR_VISIBLE, &error);
714 g_warning (
"error reading group %s key %s: %s",
715 window_group, TOOLBAR_VISIBLE, error->message);
716 g_error_free (error);
719 else if (visible != desired_visibility)
721 g_action_activate (action,
nullptr);
723 g_variant_unref (state);
729 GVariant *state = g_action_get_state (G_ACTION(action));
730 gboolean visible = g_variant_get_boolean (state);
731 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
732 SUMMARYBAR_VISIBLE, &error);
736 g_warning (
"error reading group %s key %s: %s",
737 window_group, SUMMARYBAR_VISIBLE, error->message);
738 g_error_free (error);
741 else if (visible != desired_visibility)
743 g_action_activate (action,
nullptr);
745 g_variant_unref (state);
751 GVariant *state = g_action_get_state (G_ACTION(action));
752 gboolean visible = g_variant_get_boolean (state);
753 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
754 STATUSBAR_VISIBLE, &error);
758 g_warning (
"error reading group %s key %s: %s",
759 window_group, STATUSBAR_VISIBLE, error->message);
760 g_error_free (error);
763 else if (visible != desired_visibility)
765 g_action_activate (action,
nullptr);
767 g_variant_unref (state);
771 for (i = 0; i < page_count; i++)
773 data->page_offset = page_start;
775 gnc_main_window_restore_page(window, data);
778 while (gtk_events_pending ())
779 gtk_main_iteration ();
785 order = g_key_file_get_integer_list (data->key_file, window_group,
786 WINDOW_PAGEORDER, &length, &error);
789 g_warning(
"error reading group %s key %s: %s",
790 window_group, WINDOW_PAGEORDER, error->message);
794 else if (length != page_count)
796 g_warning(
"%s key %s length %" G_GSIZE_FORMAT
" differs from window page count %" G_GSIZE_FORMAT,
797 window_group, WINDOW_PAGEORDER, length, page_count);
805 for (i = 0; i < length; i++)
813 gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->
notebook),
816 g_signal_emit_by_name (window,
"page_changed",
824 LEAVE(
"window %p", window);
828 g_free(window_group);
830 gtk_widget_show (GTK_WIDGET(window));
836 gint i, window_count;
837 GError *error =
nullptr;
842 data.key_file = (GKeyFile *) keyfile;
843 window_count = g_key_file_get_integer(data.key_file, STATE_FILE_TOP,
844 WINDOW_COUNT, &error);
847 g_warning(
"error reading group %s key %s: %s",
848 STATE_FILE_TOP, WINDOW_COUNT, error->message);
850 LEAVE(
"can't read count");
856 gnc_set_busy_cursor (
nullptr, TRUE);
857 for (i = 0; i < window_count; i++)
860 auto window{
static_cast<GncMainWindow*
>(g_list_nth_data(active_windows,
862 gnc_main_window_restore_window(window, &data);
864 gnc_unset_busy_cursor (
nullptr);
866 statusbar_notification_lastmodified();
876 DEBUG(
"no saved state file");
878 window =
static_cast<GncMainWindow*
>(g_list_nth_data(active_windows, 0));
879 gtk_widget_show (GTK_WIDGET(window));
881 "gnc-plugin-account-tree-actions",
882 "ViewAccountTreeAction");
883 g_action_activate (action,
nullptr);
899 const gchar *plugin_name, *page_name;
901 ENTER(
"page %p, data %p (key file %p, window %d, page %d)",
902 page, data, data->key_file, data->window_num, data->page_num);
905 if (!plugin_name || !page_name)
907 LEAVE(
"not saving invalid page");
910 page_group = g_strdup_printf(PAGE_STRING, data->page_num++);
911 g_key_file_set_string(data->key_file, page_group, PAGE_TYPE, plugin_name);
912 g_key_file_set_string(data->key_file, page_group, PAGE_NAME, page_name);
933 gint i, num_pages, coords[4], *order;
934 gboolean maximized, minimized, visible =
true;
938 ENTER(
"window %p, data %p (key file %p, window %d)",
939 window, data, data->key_file, data->window_num);
940 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
943 num_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->
notebook));
946 LEAVE(
"empty window %p", window);
951 window_group = g_strdup_printf(WINDOW_STRING, data->window_num++);
952 g_key_file_set_integer(data->key_file, window_group,
953 WINDOW_PAGECOUNT, num_pages);
954 g_key_file_set_integer(data->key_file, window_group,
955 WINDOW_FIRSTPAGE, data->page_num);
960 order =
static_cast<int*
>(g_malloc(
sizeof(gint) * num_pages));
961 for (i = 0; i < num_pages; i++)
963 gpointer page = g_list_nth_data(priv->
usage_order, i);
966 g_key_file_set_integer_list(data->key_file, window_group,
967 WINDOW_PAGEORDER, order, num_pages);
971 gtk_window_get_position(GTK_WINDOW(window), &coords[0], &coords[1]);
972 gtk_window_get_size(GTK_WINDOW(window), &coords[2], &coords[3]);
973 maximized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
974 & GDK_WINDOW_STATE_MAXIMIZED) != 0;
975 minimized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
976 & GDK_WINDOW_STATE_ICONIFIED) != 0;
980 gint *pos = priv->
pos;
981 g_key_file_set_integer_list(data->key_file, window_group,
982 WINDOW_POSITION, &pos[0], 2);
983 DEBUG(
"window minimized (%p) position %dx%d", window, pos[0], pos[1]);
986 g_key_file_set_integer_list(data->key_file, window_group,
987 WINDOW_POSITION, &coords[0], 2);
988 g_key_file_set_integer_list(data->key_file, window_group,
989 WINDOW_GEOMETRY, &coords[2], 2);
990 g_key_file_set_boolean(data->key_file, window_group,
991 WINDOW_MAXIMIZED, maximized);
992 DEBUG(
"window (%p) position %dx%d, size %dx%d, %s", window, coords[0], coords[1],
993 coords[2], coords[3],
994 maximized ?
"maximized" :
"not maximized");
1000 GVariant *state = g_action_get_state (G_ACTION(action));
1001 visible = g_variant_get_boolean (state);
1002 g_variant_unref (state);
1004 g_key_file_set_boolean (data->key_file, window_group,
1005 TOOLBAR_VISIBLE, visible);
1009 GVariant *state = g_action_get_state (G_ACTION(action));
1010 visible = g_variant_get_boolean (state);
1011 g_variant_unref (state);
1013 g_key_file_set_boolean (data->key_file, window_group,
1014 SUMMARYBAR_VISIBLE, visible);
1018 GVariant *state = g_action_get_state (G_ACTION(action));
1019 visible = g_variant_get_boolean (state);
1020 g_variant_unref (state);
1022 g_key_file_set_boolean (data->key_file, window_group,
1023 STATUSBAR_VISIBLE, visible);
1026 g_list_foreach (priv->
installed_pages, (GFunc)gnc_main_window_save_page, data);
1028 g_free(window_group);
1029 LEAVE(
"window %p", window);
1038 data.key_file = keyfile;
1039 data.window_num = 1;
1042 g_key_file_set_integer(data.key_file,
1043 STATE_FILE_TOP, WINDOW_COUNT,
1044 g_list_length(active_windows));
1046 g_list_foreach(active_windows, (GFunc)gnc_main_window_save_window, &data);
1056 g_return_val_if_fail(GNC_IS_MAIN_WINDOW(window), TRUE);
1058 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1073 const GList *windows, *item;
1076 for (item = windows; item; item = g_list_next(item))
1083 if (gnc_gui_refresh_suspended ())
1085 gnc_warning_dialog (
nullptr,
"%s",
"An operation is still running, wait for it to complete before quitting.");
1108 for (walker = active_windows; walker; walker = g_list_next(walker))
1111 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1120 static gboolean auto_save_countdown (GtkWidget *dialog)
1123 gchar *timeoutstr =
nullptr;
1126 if (!GTK_IS_DIALOG (dialog))
1130 label = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
"count-down-label"));
1131 if (!GTK_IS_LABEL (label))
1137 DEBUG (
"Counting down: %d seconds", secs_to_save);
1139 timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
1140 gtk_label_set_text (GTK_LABEL (label), timeoutstr);
1141 g_free (timeoutstr);
1146 gtk_dialog_response (GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
1165 gnc_main_window_prompt_for_save (GtkWidget *window)
1167 QofSession *session;
1169 GtkWidget *dialog, *msg_area, *label;
1171 const gchar *filename, *tmp;
1172 const gchar *title = _(
"Save changes to file %s before closing?");
1174 const gchar *message_hours =
1175 _(
"If you don't save, changes from the past %d hours and %d minutes will be discarded.");
1176 const gchar *message_days =
1177 _(
"If you don't save, changes from the past %d days and %d hours will be discarded.");
1179 gint minutes, hours, days;
1180 guint timer_source = 0;
1181 if (!gnc_current_session_exist())
1183 session = gnc_get_current_session();
1187 filename = qof_session_get_url(session);
1188 if (!strlen (filename))
1189 filename = _(
"<unknown>");
1190 if ((tmp = strrchr(filename,
'/')) !=
nullptr)
1194 gnc_autosave_remove_timer(book);
1196 dialog = gtk_message_dialog_new(GTK_WINDOW(window),
1198 GTK_MESSAGE_WARNING,
1203 minutes = (
gnc_time (
nullptr) - oldest_change) / 60 + 1;
1204 hours = minutes / 60;
1205 minutes = minutes % 60;
1210 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1211 message_days, days, hours);
1215 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1216 message_hours, hours, minutes);
1220 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1221 ngettext(
"If you don't save, changes from the past %d minute will be discarded.",
1222 "If you don't save, changes from the past %d minutes will be discarded.",
1225 gtk_dialog_add_buttons(GTK_DIALOG(dialog),
1226 _(
"Close _Without Saving"), GTK_RESPONSE_CLOSE,
1227 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
1228 _(
"_Save"), GTK_RESPONSE_APPLY,
1230 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
1237 gchar *timeoutstr =
nullptr;
1239 secs_to_save =
gnc_prefs_get_int (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_CLOSE_WAIT_TIME);
1240 timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
1241 label = GTK_WIDGET(gtk_label_new (timeoutstr));
1242 g_free (timeoutstr);
1243 gtk_widget_show (label);
1245 msg_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG(dialog));
1246 gtk_box_pack_end (GTK_BOX(msg_area), label, TRUE, TRUE, 0);
1247 g_object_set (G_OBJECT (label),
"xalign", 0.0,
nullptr);
1249 g_object_set_data (G_OBJECT (dialog),
"count-down-label", label);
1250 timer_source = g_timeout_add_seconds (1, (GSourceFunc)auto_save_countdown, dialog);
1253 response = gtk_dialog_run (GTK_DIALOG (dialog));
1255 g_source_remove (timer_source);
1256 gtk_widget_destroy(dialog);
1260 case GTK_RESPONSE_APPLY:
1261 gnc_file_save (GTK_WINDOW (window));
1264 case GTK_RESPONSE_CLOSE:
1275 gnc_main_window_add_plugin (gpointer plugin,
1278 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
1279 g_return_if_fail (GNC_IS_PLUGIN (plugin));
1283 GNC_MAIN_WINDOW (window),
1289 gnc_main_window_remove_plugin (gpointer plugin,
1292 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
1293 g_return_if_fail (GNC_IS_PLUGIN (plugin));
1297 GNC_MAIN_WINDOW (window),
1304 gnc_main_window_timed_quit (gpointer dummy)
1306 if (gnc_file_save_in_progress())
1316 QofSession *session;
1317 gboolean needs_save, do_shutdown = TRUE;
1318 if (gnc_current_session_exist())
1320 session = gnc_get_current_session();
1323 !gnc_file_save_in_progress();
1324 do_shutdown = !needs_save ||
1326 !gnc_main_window_prompt_for_save(GTK_WIDGET(window)));
1336 for (w = active_windows; w; w = next)
1341 next = g_list_next (w);
1343 window->window_quitting = TRUE;
1345 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1349 gtk_widget_destroy (GTK_WIDGET(window));
1352 gnc_main_window_remove_prefs (window);
1353 g_timeout_add(250, gnc_main_window_timed_quit,
nullptr);
1360 gnc_main_window_delete_event (GtkWidget *window,
1364 static gboolean already_dead = FALSE;
1373 gchar *message = _(
"This window is closing and will not be restored.");
1375 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
1376 GTK_DIALOG_DESTROY_WITH_PARENT,
1377 GTK_MESSAGE_QUESTION,
1379 "%s", _(
"Close Window?"));
1380 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
1383 gtk_dialog_add_buttons (GTK_DIALOG(dialog),
1384 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
1385 _(
"_OK"), GTK_RESPONSE_YES,
1387 gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_YES);
1388 response = gnc_dialog_run (GTK_DIALOG(dialog), GNC_PREF_WARN_CLOSING_WINDOW_QUESTION);
1389 gtk_widget_destroy (dialog);
1391 if (response == GTK_RESPONSE_CANCEL)
1404 already_dead = gnc_main_window_quit(GNC_MAIN_WINDOW(window));
1430 gpointer user_data, gpointer event_data)
1438 g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
1443 if (event_type != QOF_EVENT_DESTROY)
1446 ENTER(
"entity %p, event %d, window %p, event data %p",
1447 entity, event_type, user_data, event_data);
1448 window = GNC_MAIN_WINDOW(user_data);
1449 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1456 next = g_list_next(item);
1457 page = GNC_PLUGIN_PAGE(item->data);
1462 if (GTK_IS_WIDGET(window) && window->window_quitting)
1463 gtk_widget_destroy (GTK_WIDGET(window));
1492 gchar *filename =
nullptr;
1493 const gchar *uri =
nullptr;
1494 const gchar *dirty =
"";
1495 const gchar *readonly_text =
nullptr;
1499 if (gnc_current_session_exist())
1501 uri = qof_session_get_url (gnc_get_current_session ());
1502 book = gnc_get_current_book();
1509 readonly_text = _(
"(read-only)");
1512 readonly = (readonly_text !=
nullptr)
1513 ? g_strdup_printf(
" %s", readonly_text)
1516 if (!uri || g_strcmp0 (uri,
"") == 0)
1517 filename = g_strdup(_(
"Unsaved Book"));
1525 filename = g_path_get_basename ( path );
1536 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1542 title = g_strdup_printf(
"%s%s%s - %s - GnuCash", dirty, filename, readonly,
1547 title = g_strdup_printf(
"%s%s%s - GnuCash", dirty, filename, readonly);
1551 g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE);
1553 immutable_page_actions,
1556 g_signal_emit_by_name (window,
"page_changed", page);
1578 title = gnc_main_window_generate_title(window);
1579 gtk_window_set_title(GTK_WINDOW(window), title);
1584 gnc_main_window_update_all_titles (
void)
1586 g_list_foreach(active_windows,
1587 (GFunc)gnc_main_window_update_title,
1592 gnc_main_window_book_dirty_cb (QofBook *book,
1596 gnc_main_window_update_all_titles();
1599 gnc_autosave_dirty_handler(book, dirty);
1603 gnc_main_window_attach_to_book (QofSession *session)
1607 g_return_if_fail(session);
1611 gnc_main_window_update_all_titles();
1612 #ifndef MAC_INTEGRATION 1613 gnc_main_window_update_all_menu_items();
1617 static guint gnc_statusbar_notification_messageid = 0;
1619 #ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL 1622 static gboolean statusbar_notification_off(gpointer user_data_unused)
1626 if (gnc_statusbar_notification_messageid == 0)
1631 GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
1632 gtk_statusbar_remove(GTK_STATUSBAR(statusbar), 0, gnc_statusbar_notification_messageid);
1633 gnc_statusbar_notification_messageid = 0;
1637 g_warning(
"oops, no GncMainWindow obtained\n");
1641 #endif // STATUSBAR_NOTIFICATION_AUTOREMOVAL 1645 static gchar *generate_statusbar_lastmodified_message()
1647 gchar *message =
nullptr;
1648 const gchar *uri =
nullptr;
1650 if (gnc_current_session_exist())
1652 uri = qof_session_get_url (gnc_get_current_session ());
1655 if (!(uri && strlen (uri)))
1663 gchar *filename = g_path_get_basename ( filepath );
1664 GFile *file = g_file_new_for_uri (uri);
1665 GFileInfo *info = g_file_query_info (file,
1666 G_FILE_ATTRIBUTE_TIME_MODIFIED,
1667 G_FILE_QUERY_INFO_NONE,
1670 if (info && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
1673 struct stat statbuf;
1674 int r = stat(filepath, &statbuf);
1683 _(
"Last modified on %a, %b %d, %Y at %I:%M %p"));
1686 message = g_strdup_printf(_(
"File %s opened. %s"),
1687 filename, time_string);
1692 g_warning(
"Unable to read mtime for file %s\n", filepath);
1698 g_object_unref (info);
1699 g_object_unref (file);
1708 statusbar_notification_lastmodified()
1712 GtkWidget *widget =
nullptr;
1713 for (iter = active_windows; iter && !(widget && GNC_IS_MAIN_WINDOW(widget));
1714 iter = g_list_next(iter))
1716 widget =
static_cast<GtkWidget*
>(iter->data);
1718 if (widget && GNC_IS_MAIN_WINDOW(widget))
1722 GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
1724 gchar *msg = generate_statusbar_lastmodified_message();
1727 gnc_statusbar_notification_messageid = gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);
1731 #ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL 1734 g_timeout_add(10 * 1000, statusbar_notification_off,
nullptr);
1739 g_warning(
"uh oh, no GNC_IS_MAIN_WINDOW\n");
1761 #ifndef MAC_INTEGRATION 1776 gnc_main_window_update_one_menu_action (
GncMainWindow *window,
1780 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
1784 ENTER(
"window %p, action %s, label %s, index %d, visible %d", window,
1785 data->action_name, data->label, data->index, data->visible);
1787 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1789 gsm->search_action_label =
nullptr;
1790 gsm->search_action_name =
"WindowsPlaceholder1";
1794 LEAVE(
"Could not find placeholder 'WindowsPlaceholder1' for windows entries");
1799 pos = gsm->index + data->index + 1;
1803 if (pos < g_menu_model_get_n_items (gsm->model))
1804 g_menu_remove (G_MENU(gsm->model), pos);
1811 item = g_menu_item_new (data->label,
"mainwin.WindowAction");
1812 g_menu_item_set_attribute (item, G_MENU_ATTRIBUTE_TARGET,
"i", data->index);
1814 if (pos < g_menu_model_get_n_items (gsm->model))
1815 g_menu_remove (G_MENU(gsm->model), pos);
1816 g_menu_insert_item (G_MENU(gsm->model), pos, item);
1841 ENTER(
"window %p", window);
1844 index = g_list_index (active_windows, window);
1852 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1854 action = g_action_map_lookup_action (G_ACTION_MAP(window),
1859 g_signal_handlers_block_by_func (G_OBJECT(action),
1860 (gpointer)gnc_main_window_cmd_window_raise,
1863 DEBUG(
"blocked signal on action %p, window %p", action, window);
1864 g_action_change_state (G_ACTION(action), g_variant_new_int32 (index));
1866 g_signal_handlers_unblock_by_func (G_OBJECT(action),
1867 (gpointer)gnc_main_window_cmd_window_raise,
1888 gchar **strings, *title, *expanded;
1891 ENTER(
"window %p", window);
1893 index = g_list_index (active_windows, window);
1902 title = gnc_main_window_generate_title (window);
1903 strings = g_strsplit (title,
"_", 0);
1905 expanded = g_strjoinv (
"__", strings);
1908 data.label = g_strdup_printf (
"_%" G_GSIZE_FORMAT
" %s", (
index + 1) % 10, expanded);
1913 data.label = expanded;
1915 g_strfreev (strings);
1917 data.visible = TRUE;
1921 g_list_foreach (active_windows,
1922 (GFunc)gnc_main_window_update_one_menu_action,
1926 g_free (data.label);
1940 #ifndef MAC_INTEGRATION 1942 gnc_main_window_update_all_menu_items (
void)
1948 g_list_foreach (active_windows,
1949 (GFunc)gnc_main_window_update_menu_item,
1952 g_list_foreach (active_windows,
1953 (GFunc)gnc_main_window_update_radio_button,
1957 data.visible = FALSE;
1962 data.action_name = g_strdup_printf (
"Window%dAction", data.index);
1963 data.label = g_strdup_printf (
"mywin%" G_GSIZE_FORMAT, i % 10);
1965 g_list_foreach (active_windows,
1966 (GFunc)gnc_main_window_update_one_menu_action,
1969 g_free (data.action_name);
1970 g_free (data.label);
1988 gnc_main_window_update_tab_close_one_page (
GncPluginPage *page,
1991 auto new_value{
static_cast<gboolean*
>(user_data)};
1992 ENTER(
"page %p, visible %d", page, *new_value);
1993 auto close_button{
static_cast<GtkWidget*
>(g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON))};
1996 LEAVE(
"no close button");
2001 gtk_widget_show (close_button);
2003 gtk_widget_hide (close_button);
2021 gnc_main_window_update_tab_close (gpointer prefs, gchar *pref, gpointer user_data)
2026 new_value =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SHOW_CLOSE_BUTTON);
2028 gnc_main_window_update_tab_close_one_page,
2043 gnc_main_window_update_tab_color_one_page (
GncPluginPage *page,
2046 const gchar *color_string;
2048 ENTER(
"page %p", page);
2066 gnc_main_window_update_tab_color (gpointer gsettings, gchar *pref, gpointer user_data)
2069 g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
2071 auto priv{GNC_MAIN_WINDOW_GET_PRIVATE(window)};
2072 if (g_strcmp0 (GNC_PREF_TAB_COLOR, pref) == 0)
2085 gboolean tabs_left_right;
2089 populate_tab_width_struct (
void)
2095 tw->tabs_left_right =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT) ||
2123 gnc_main_window_set_tab_ellipsize (GtkWidget *
label, gint tab_width, gboolean tab_left_right)
2125 const gchar *lab_text = gtk_label_get_text (GTK_LABEL(
label));
2129 gint text_length = g_utf8_strlen (lab_text, -1);
2130 if (text_length < tab_width)
2133 gtk_label_set_width_chars (GTK_LABEL(
label), tab_width);
2135 gtk_label_set_width_chars (GTK_LABEL(
label), text_length);
2137 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_NONE);
2141 gtk_label_set_width_chars (GTK_LABEL(
label), tab_width);
2142 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_MIDDLE);
2147 gtk_label_set_width_chars (GTK_LABEL(
label), 15);
2148 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_NONE);
2164 gnc_main_window_update_tab_width_one_page (
GncPluginPage *page,
2167 auto tw{
static_cast<TabWidth*
>(user_data)};
2169 ENTER(
"page %p, tab width %d, tabs on left or right %d",
2170 page, tw->tab_width, tw->tabs_left_right);
2172 auto label{
static_cast<GtkWidget *
>(g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL))};
2178 gnc_main_window_set_tab_ellipsize (
label, tw->tab_width, tw->tabs_left_right);
2196 gnc_main_window_update_tab_width (gpointer prefs, gchar *pref, gpointer user_data)
2202 tw = populate_tab_width_struct ();
2217 GtkWidget **label_p,
2218 GtkWidget **entry_p)
2221 GtkWidget *tab_hbox, *widget, *tab_widget;
2222 GList *children, *tmp;
2224 ENTER(
"window %p, page %p, label_p %p, entry_p %p",
2225 window, page, label_p, entry_p);
2226 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2227 *label_p = *entry_p =
nullptr;
2231 LEAVE(
"invalid notebook_page");
2235 tab_widget = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->
notebook),
2237 if (GTK_IS_EVENT_BOX (tab_widget))
2238 tab_hbox = gtk_bin_get_child(GTK_BIN(tab_widget));
2239 else if (GTK_IS_BOX (tab_widget))
2240 tab_hbox = tab_widget;
2243 PWARN (
"Unknown widget for tab label %p", tab_widget);
2247 children = gtk_container_get_children(GTK_CONTAINER(tab_hbox));
2248 for (tmp = children; tmp; tmp = g_list_next(tmp))
2250 widget =
static_cast<GtkWidget*
>(tmp->data);
2251 if (GTK_IS_LABEL(widget))
2255 else if (GTK_IS_ENTRY(widget))
2260 g_list_free(children);
2262 LEAVE(
"label %p, entry %p", *label_p, *entry_p);
2263 return (*label_p && *entry_p);
2269 GtkWidget **widget_p)
2273 ENTER(
"window %p, page %p, widget %p",
2274 window, page, widget_p);
2275 *widget_p =
nullptr;
2279 LEAVE(
"invalid notebook_page");
2283 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2284 *widget_p = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->
notebook),
2287 LEAVE(
"widget %p", *widget_p);
2293 const gchar *name_in)
2297 GtkWidget *
label, *entry;
2298 gchar *name, *old_page_name, *old_page_long_name;
2303 if ((name_in ==
nullptr) || (*name_in ==
'\0'))
2308 name = g_strstrip(g_strdup(name_in));
2314 LEAVE(
"empty string or name unchanged");
2325 window = GNC_MAIN_WINDOW(page->
window);
2328 g_free(old_page_name);
2329 g_free(old_page_long_name);
2331 LEAVE(
"no window widget available");
2335 if (main_window_find_tab_items(window, page, &
label, &entry))
2336 gtk_label_set_text(GTK_LABEL(
label), name);
2339 tw = populate_tab_width_struct ();
2340 gnc_main_window_update_tab_width_one_page (page, tw);
2344 if (old_page_long_name && old_page_name
2345 && g_strrstr(old_page_long_name, old_page_name) !=
nullptr)
2347 gchar *new_page_long_name;
2348 gint string_position;
2349 GtkWidget *tab_widget;
2351 string_position = strlen(old_page_long_name) - strlen(old_page_name);
2352 new_page_long_name = g_strconcat(g_strndup(old_page_long_name, string_position), name,
nullptr);
2356 if (main_window_find_tab_widget(window, page, &tab_widget))
2357 gtk_widget_set_tooltip_text(tab_widget, new_page_long_name);
2359 g_free(new_page_long_name);
2365 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2366 label = gtk_notebook_get_menu_label (GTK_NOTEBOOK(priv->
notebook),
2368 gtk_label_set_text(GTK_LABEL(
label), name);
2372 gnc_main_window_update_title(window);
2373 g_free(old_page_long_name);
2374 g_free(old_page_name);
2382 const gchar *color_in)
2386 GtkWidget *tab_widget;
2388 gchar *color_string =
nullptr;
2389 gboolean want_color = FALSE;
2393 color_string = g_strstrip(g_strdup(color_in));
2395 if (color_string && *color_string !=
'\0')
2399 window = GNC_MAIN_WINDOW(page->
window);
2406 main_window_find_tab_widget (window, page, &tab_widget);
2407 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2409 if (want_color && gdk_rgba_parse(&tab_color, color_string) && priv->
show_color_tabs)
2411 GtkCssProvider *provider = gtk_css_provider_new();
2412 GtkStyleContext *stylectxt;
2413 gchar *col_str, *widget_css;
2415 if (!GTK_IS_EVENT_BOX (tab_widget))
2417 GtkWidget *event_box = gtk_event_box_new ();
2418 g_object_ref (tab_widget);
2419 gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->
notebook),
2421 gtk_container_add (GTK_CONTAINER(event_box), tab_widget);
2422 g_object_unref (tab_widget);
2423 tab_widget = event_box;
2426 stylectxt = gtk_widget_get_style_context (GTK_WIDGET (tab_widget));
2427 col_str = gdk_rgba_to_string (&tab_color);
2428 widget_css = g_strconcat (
"*{\n background-color:", col_str,
";\n}\n",
nullptr);
2430 gtk_css_provider_load_from_data (provider, widget_css, -1,
nullptr);
2431 gtk_style_context_add_provider (stylectxt, GTK_STYLE_PROVIDER (provider),
2432 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
2433 g_object_unref (provider);
2435 g_free (widget_css);
2439 if (GTK_IS_EVENT_BOX (tab_widget))
2441 GtkWidget *tab_hbox = gtk_bin_get_child(GTK_BIN(tab_widget));
2442 g_object_ref (tab_hbox);
2443 gtk_container_remove (GTK_CONTAINER(tab_widget), tab_hbox);
2444 gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->
notebook),
2446 g_object_unref (tab_hbox);
2449 g_free(color_string);
2460 GtkWidget *tab_widget;
2461 GtkWidget *image = NULL;
2463 gchar *image_name = NULL;
2464 const gchar *icon_name;
2468 g_return_if_fail (page && page->
window);
2470 if (!GNC_IS_MAIN_WINDOW (page->
window))
2473 window = GNC_MAIN_WINDOW(page->
window);
2476 main_window_find_tab_widget (window, page, &tab_widget);
2477 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2481 LEAVE(
"no tab widget");
2485 if (GTK_IS_EVENT_BOX(tab_widget))
2486 tab_widget = gtk_bin_get_child (GTK_BIN(tab_widget));
2488 children = gtk_container_get_children (GTK_CONTAINER(tab_widget));
2490 for (GList *child = children; child; child = g_list_next (child))
2492 GtkWidget *widget =
static_cast<GtkWidget*
>(child->data);
2493 if (GTK_IS_IMAGE(widget))
2496 g_list_free (children);
2500 LEAVE(
"no image to replace");
2504 g_object_get (image,
"icon-name", &image_name, NULL);
2507 icon_name =
"changes-prevent-symbolic";
2509 icon_name = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
2511 if (g_strcmp0 (icon_name, image_name) == 0)
2513 LEAVE(
"page icon the same, no need to replace");
2514 g_free (image_name);
2517 gtk_container_remove (GTK_CONTAINER(tab_widget), image);
2518 image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
2519 gtk_widget_show (image);
2521 gtk_container_add (GTK_CONTAINER(tab_widget), image);
2522 gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
2523 gtk_box_reorder_child (GTK_BOX(tab_widget), image, 0);
2525 g_free (image_name);
2531 gnc_main_window_tab_entry_activate (GtkWidget *entry,
2534 GtkWidget *
label, *entry2;
2536 g_return_if_fail(GTK_IS_ENTRY(entry));
2537 g_return_if_fail(GNC_IS_PLUGIN_PAGE(page));
2540 if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->
window),
2541 page, &
label, &entry2))
2543 LEAVE(
"can't find required widgets");
2549 gtk_widget_hide(entry);
2550 gtk_widget_show(
label);
2556 gnc_main_window_tab_entry_editing_done (GtkWidget *entry,
2560 gnc_main_window_tab_entry_activate(entry, page);
2566 gnc_main_window_tab_entry_focus_out_event (GtkWidget *entry,
2571 gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(entry));
2577 gnc_main_window_tab_entry_key_press_event (GtkWidget *entry,
2581 if (event->keyval == GDK_KEY_Escape)
2583 GtkWidget *
label, *entry2;
2585 g_return_val_if_fail(GTK_IS_ENTRY(entry), FALSE);
2586 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
2589 if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->
window),
2590 page, &
label, &entry2))
2592 LEAVE(
"can't find required widgets");
2596 gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(
label)));
2597 gtk_widget_hide(entry);
2598 gtk_widget_show(
label);
2620 GObjectClass *object_class = G_OBJECT_CLASS (klass);
2621 GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS(klass);
2623 parent_class =
static_cast<GObjectClass*
>(g_type_class_peek_parent (klass));
2625 window_type = g_quark_from_static_string (
"gnc-main-window");
2627 object_class->finalize = gnc_main_window_finalize;
2630 gtkwidget_class->destroy = gnc_main_window_destroy;
2643 main_window_signals[PAGE_ADDED] =
2644 g_signal_new (
"page_added",
2645 G_OBJECT_CLASS_TYPE (object_class),
2649 g_cclosure_marshal_VOID__OBJECT,
2663 main_window_signals[PAGE_CHANGED] =
2664 g_signal_new (
"page_changed",
2665 G_OBJECT_CLASS_TYPE (object_class),
2669 g_cclosure_marshal_VOID__OBJECT,
2681 main_window_signals[MENU_CHANGED] =
2682 g_signal_new (
"menu_changed",
2683 G_OBJECT_CLASS_TYPE (object_class),
2687 g_cclosure_marshal_VOID__OBJECT,
2692 GNC_PREF_SHOW_CLOSE_BUTTON,
2693 (gpointer)gnc_main_window_update_tab_close,
2697 (gpointer)gnc_main_window_update_tab_width,
2700 gnc_hook_add_dangler(HOOK_BOOK_SAVED,
2701 (GFunc)gnc_main_window_update_all_titles,
nullptr,
nullptr);
2702 gnc_hook_add_dangler(HOOK_BOOK_OPENED,
2703 (GFunc)gnc_main_window_attach_to_book,
nullptr,
nullptr);
2723 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2726 gtk_widget_set_name (GTK_WIDGET(window),
"gnc-id-main-window");
2733 priv->display_item_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
nullptr);
2735 priv->previous_plugin_page_name =
nullptr;
2736 priv->previous_menu_qualifier =
nullptr;
2739 gtk_window_add_accel_group (GTK_WINDOW(window), priv->
accel_group);
2746 (gpointer)gnc_main_window_update_tab_color,
2749 gnc_main_window_setup_window (window);
2751 G_OBJECT_CLASS(klass));
2766 gnc_main_window_finalize (GObject *
object)
2768 g_return_if_fail (
object !=
nullptr);
2769 g_return_if_fail (GNC_IS_MAIN_WINDOW (
object));
2771 if (active_windows ==
nullptr)
2778 G_OBJECT_CLASS (parent_class)->finalize (
object);
2788 (gpointer)gnc_main_window_update_tab_color,
2792 GNC_PREF_SHOW_CLOSE_BUTTON,
2793 (gpointer)gnc_main_window_update_tab_close,
2798 (gpointer)gnc_main_window_update_tab_width,
2802 GNC_PREF_TAB_POSITION_TOP,
2803 (gpointer)gnc_main_window_update_tab_position,
2807 GNC_PREF_TAB_POSITION_BOTTOM,
2808 (gpointer)gnc_main_window_update_tab_position,
2812 GNC_PREF_TAB_POSITION_LEFT,
2813 (gpointer)gnc_main_window_update_tab_position,
2817 GNC_PREF_TAB_POSITION_RIGHT,
2818 (gpointer)gnc_main_window_update_tab_position,
2826 gnc_prefs_set_reg_negative_color_pref_id (0);
2834 gnc_prefs_set_reg_auto_raise_lists_id (0);
2840 gnc_main_window_destroy (GtkWidget *widget)
2847 g_return_if_fail (widget !=
nullptr);
2848 g_return_if_fail (GNC_IS_MAIN_WINDOW (widget));
2850 window = GNC_MAIN_WINDOW (widget);
2852 active_windows = g_list_remove (active_windows, window);
2855 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2863 if (gnc_window_get_progressbar_window() == GNC_WINDOW(window))
2864 gnc_window_set_progressbar_window(
nullptr);
2865 #ifndef MAC_INTEGRATION 2867 gnc_main_window_update_all_menu_items();
2870 gnc_main_window_remove_prefs (window);
2875 g_hash_table_destroy (priv->display_item_hash);
2880 g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
2881 g_list_free (plugins);
2883 GTK_WIDGET_CLASS (parent_class)->destroy (widget);
2888 gnc_main_window_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
2891 GdkModifierType modifiers;
2893 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(widget), FALSE);
2895 priv = GNC_MAIN_WINDOW_GET_PRIVATE(widget);
2897 modifiers = gtk_accelerator_get_default_mod_mask ();
2899 if ((event->state & modifiers) == (GDK_CONTROL_MASK | GDK_MOD1_MASK))
2901 const gchar *account_key = C_ (
"lower case key for short cut to 'Accounts'",
"a");
2902 guint account_keyval = gdk_keyval_from_name (account_key);
2904 if ((account_keyval == event->keyval) || (account_keyval == gdk_keyval_to_lower (event->keyval)))
2908 for (GList *item = priv->
installed_pages; item; item = g_list_next (item))
2912 if (g_strcmp0 (pname,
"GncPluginPageAccountTree") == 0)
2914 gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->
notebook), page);
2920 else if ((GDK_KEY_Menu == event->keyval) || (GDK_KEY_space == event->keyval))
2922 GList *menu = gtk_menu_get_for_attach_widget (GTK_WIDGET(priv->
notebook));
2926 gtk_menu_popup_at_widget (GTK_MENU(menu->data),
2944 auto window{
static_cast<GncMainWindow*
>(g_object_new (GNC_TYPE_MAIN_WINDOW,
nullptr))};
2945 gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
2951 gtk_window_get_size (old_window, &width, &height);
2952 gtk_window_resize (GTK_WINDOW (window), width, height);
2953 if ((gdk_window_get_state((gtk_widget_get_window (GTK_WIDGET(old_window))))
2954 & GDK_WINDOW_STATE_MAXIMIZED) != 0)
2956 gtk_window_maximize (GTK_WINDOW (window));
2959 active_windows = g_list_append (active_windows, window);
2960 gnc_main_window_update_title(window);
2961 window->window_quitting = FALSE;
2962 window->just_plugin_prefs = FALSE;
2963 #ifdef MAC_INTEGRATION 2964 gnc_quartz_set_menu(window);
2966 gnc_main_window_update_all_menu_items();
2971 g_signal_connect (G_OBJECT(window),
"key-press-event",
2972 G_CALLBACK(gnc_main_window_key_press_event),
2983 gnc_main_window_engine_commit_error_callback( gpointer data,
2988 const gchar *reason = _(
"Unable to save to database.");
2990 reason = _(
"Unable to save to database: Book is marked read-only.");
2991 dialog = gtk_message_dialog_new( GTK_WINDOW(window),
2992 GTK_DIALOG_DESTROY_WITH_PARENT,
2997 gtk_dialog_run(GTK_DIALOG (dialog));
2998 gtk_widget_destroy(dialog);
3022 GtkWidget *tab_hbox,
3023 GtkWidget *menu_label)
3026 GtkNotebook *notebook;
3027 gint current_position = -1;
3029 page->
window = GTK_WIDGET(window);
3030 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3031 notebook = GTK_NOTEBOOK (priv->
notebook);
3038 gtk_notebook_insert_page_menu (notebook, page->
notebook_page,
3039 tab_hbox, menu_label, current_position);
3040 gtk_notebook_set_tab_reorderable (notebook, page->
notebook_page, TRUE);
3041 gnc_plugin_page_inserted (page);
3042 gtk_notebook_set_current_page (notebook, current_position);
3044 if (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)
3045 (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)(page, GTK_WIDGET(window));
3046 g_signal_emit (window, main_window_signals[PAGE_ADDED], 0, page);
3048 g_signal_connect(G_OBJECT(page->
notebook_page),
"popup-menu",
3050 g_signal_connect_after(G_OBJECT(page->
notebook_page),
"button-press-event",
3073 GtkNotebook *notebook;
3078 g_signal_handlers_disconnect_by_func(G_OBJECT(page->
notebook_page),
3080 g_signal_handlers_disconnect_by_func(G_OBJECT(page->
notebook_page),
3087 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3090 gnc_plugin_page_unselected (page);
3099 notebook = GTK_NOTEBOOK (priv->
notebook);
3105 page_num = gtk_notebook_page_num(notebook, new_page->
notebook_page);
3106 gtk_notebook_set_current_page(notebook, page_num);
3111 while (gtk_events_pending())
3112 gtk_main_iteration();
3117 page_num = gtk_notebook_page_num(notebook, page->
notebook_page);
3118 gtk_notebook_remove_page (notebook, page_num);
3120 if ( gtk_notebook_get_current_page(notebook) == -1)
3126 gnc_main_window_switch_page(notebook,
nullptr, -1, window);
3130 gnc_plugin_page_removed (page);
3132 gnc_window_set_status (GNC_WINDOW(window), page,
nullptr);
3146 GtkNotebook *notebook;
3149 window = GNC_MAIN_WINDOW (page->
window);
3150 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3151 notebook = GTK_NOTEBOOK (priv->
notebook);
3152 page_num = gtk_notebook_page_num(notebook, page->
notebook_page);
3153 gtk_notebook_set_current_page (notebook, page_num);
3154 gtk_window_present(GTK_WINDOW(window));
3170 GtkWidget *tab_hbox;
3171 GtkWidget *
label, *entry;
3172 const gchar *icon, *text, *color_string, *lab_text;
3177 ENTER(
"window %p, page %p", window, page);
3179 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3180 g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
3183 if (gnc_main_window_page_exists(page))
3193 for (tmp = active_windows; tmp; tmp = g_list_next(tmp))
3195 window = GNC_MAIN_WINDOW(tmp->data);
3196 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3204 gtk_widget_show(GTK_WIDGET(window));
3206 else if ((window ==
nullptr) && active_windows)
3211 page->
window = GTK_WIDGET(window);
3219 icon = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
3221 label = gtk_label_new (lab_text);
3222 g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL,
label);
3224 tw = populate_tab_width_struct ();
3225 gnc_main_window_update_tab_width_one_page (page, tw);
3228 gtk_widget_show (
label);
3230 tab_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
3233 gtk_widget_set_name (GTK_WIDGET(tab_hbox),
"gnc-id-account-page-tab-box");
3235 gtk_box_set_homogeneous (GTK_BOX (tab_hbox), FALSE);
3236 gtk_widget_show (tab_hbox);
3238 if (icon !=
nullptr)
3240 image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
3241 gtk_widget_show (image);
3242 gtk_box_pack_start (GTK_BOX (tab_hbox), image, FALSE, FALSE, 0);
3243 gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
3244 gtk_box_pack_start (GTK_BOX (tab_hbox),
label, TRUE, TRUE, 0);
3247 gtk_box_pack_start (GTK_BOX (tab_hbox),
label, TRUE, TRUE, 0);
3252 gtk_widget_set_tooltip_text(tab_hbox, text);
3255 entry = gtk_entry_new();
3256 gtk_widget_hide (entry);
3257 gtk_box_pack_start (GTK_BOX (tab_hbox), entry, TRUE, TRUE, 0);
3258 g_signal_connect(G_OBJECT(entry),
"activate",
3259 G_CALLBACK(gnc_main_window_tab_entry_activate), page);
3260 g_signal_connect(G_OBJECT(entry),
"focus-out-event",
3261 G_CALLBACK(gnc_main_window_tab_entry_focus_out_event),
3263 g_signal_connect(G_OBJECT(entry),
"key-press-event",
3264 G_CALLBACK(gnc_main_window_tab_entry_key_press_event),
3266 g_signal_connect(G_OBJECT(entry),
"editing-done",
3267 G_CALLBACK(gnc_main_window_tab_entry_editing_done),
3271 if (!g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE))
3273 GtkWidget *close_image, *close_button;
3274 GtkRequisition requisition;
3276 close_button = gtk_button_new();
3277 gtk_button_set_relief(GTK_BUTTON(close_button), GTK_RELIEF_NONE);
3278 close_image = gtk_image_new_from_icon_name (
"window-close", GTK_ICON_SIZE_MENU);
3279 gtk_widget_show(close_image);
3280 gtk_widget_get_preferred_size (close_image, &requisition,
nullptr);
3281 gtk_widget_set_size_request(close_button, requisition.width + 4,
3282 requisition.height + 2);
3283 gtk_container_add(GTK_CONTAINER(close_button), close_image);
3285 gtk_widget_show (close_button);
3287 gtk_widget_hide (close_button);
3289 g_signal_connect_swapped (G_OBJECT (close_button),
"clicked",
3292 gtk_box_pack_start (GTK_BOX (tab_hbox), close_button, FALSE, FALSE, 0);
3293 gtk_widget_set_margin_end (GTK_WIDGET(close_button), 5);
3294 g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON, close_button);
3305 gnc_main_window_connect(window, page, tab_hbox,
label);
3330 if (!GNC_IS_MAIN_WINDOW (page->
window))
3333 window = GNC_MAIN_WINDOW (page->
window);
3336 g_warning(
"Page is not in a window.");
3340 gnc_main_window_disconnect(window, page);
3342 g_object_unref(page);
3345 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3348 if (window->window_quitting)
3354 window->just_plugin_prefs = TRUE;
3355 g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
3356 window->just_plugin_prefs = FALSE;
3357 g_list_free (plugins);
3360 gnc_main_window_remove_prefs (window);
3363 gtk_widget_destroy (GTK_WIDGET(window));
3380 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3392 const gchar *group_name,
3393 GSimpleActionGroup *group)
3395 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3396 g_return_if_fail (group_name !=
nullptr);
3397 g_return_if_fail (G_IS_SIMPLE_ACTION_GROUP(group));
3399 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
3400 G_ACTION_GROUP(group));
3405 update_menu_model (
GncMainWindow *window,
const gchar *ui_filename,
3406 const gchar **ui_updates)
3409 GError *error =
nullptr;
3411 GtkBuilder *builder = gtk_builder_new ();
3412 GMenuModel *menu_model_part;
3413 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
3415 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3416 g_return_if_fail (ui_filename !=
nullptr);
3417 g_return_if_fail (ui_updates !=
nullptr);
3419 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3421 gtk_builder_set_translation_domain (builder, PROJECT_NAME);
3422 res_name = g_strconcat (GNUCASH_RESOURCE_PREFIX
"/", ui_filename, NULL);
3424 gtk_builder_add_from_resource (builder, res_name, &error);
3429 g_critical (
"Failed to load, Error %s", error->message);
3430 g_error_free (error);
3434 for (gint i = 0; ui_updates[i]; i++)
3436 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, ui_updates[i]);
3438 gsm->search_action_label =
nullptr;
3439 gsm->search_action_name = ui_updates[i];
3442 g_menu_insert_section (G_MENU(gsm->model), gsm->index, NULL, G_MENU_MODEL(menu_model_part));
3444 PERR(
"Could not find '%s' in menu model", ui_updates[i]);
3447 g_object_unref (builder);
3459 const gchar *group_name,
3460 GActionEntry *actions,
3462 const gchar **ui_updates,
3463 const gchar *ui_filename,
3468 GSimpleActionGroup *simple_action_group;
3470 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3471 g_return_if_fail (group_name !=
nullptr);
3472 g_return_if_fail (actions !=
nullptr);
3473 g_return_if_fail (n_actions > 0);
3476 data->window = window;
3477 data->data = user_data;
3479 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3481 simple_action_group = g_simple_action_group_new ();
3483 g_action_map_add_action_entries (G_ACTION_MAP(simple_action_group),
3488 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
3489 G_ACTION_GROUP(simple_action_group));
3492 update_menu_model (window, ui_filename, ui_updates);
3503 const gchar *group_name)
3505 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3506 g_return_if_fail (group_name !=
nullptr);
3508 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
nullptr);
3515 GAction *action =
nullptr;
3517 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3518 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3520 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3522 action = g_action_map_lookup_action (G_ACTION_MAP(window),
3530 const gchar *group_name,
3533 GAction *action =
nullptr;
3535 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3536 g_return_val_if_fail (group_name !=
nullptr,
nullptr);
3537 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3539 auto action_group = gtk_widget_get_action_group (GTK_WIDGET(window), group_name);
3541 action = g_action_map_lookup_action (G_ACTION_MAP(window),
action_name);
3551 GSimpleActionGroup *
3553 const gchar *group_name)
3555 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3556 g_return_val_if_fail (group_name !=
nullptr,
nullptr);
3558 auto action_group = gtk_widget_get_action_group (GTK_WIDGET(window), group_name);
3559 return (GSimpleActionGroup*)action_group;
3567 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3568 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3570 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3579 GtkWidget *menu_item;
3581 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3582 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3584 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3586 menu_item = GTK_WIDGET(g_hash_table_lookup (priv->display_item_hash,
action_name));
3592 g_hash_table_insert (priv->display_item_hash, g_strdup (
action_name), menu_item);
3603 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3605 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3615 const gchar *tooltip)
3618 gboolean found =
false;
3620 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
false);
3621 g_return_val_if_fail (
action_name !=
nullptr,
false);
3622 g_return_val_if_fail (
label !=
nullptr,
false);
3624 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3627 _(
label), _(tooltip));
3639 const gchar **action_names,
3644 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3646 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3648 for (gint i = 0; action_names[i]; i++)
3655 PINFO(
"Found menu_item %p with action name '%s', seting vis to '%s'",
3656 menu_item, action_names[i], vis ?
"true" :
"false");
3657 gtk_widget_set_visible (menu_item, vis);
3660 PINFO(
"Did not find menu_item with action name '%s' to set vis '%s'",
3661 action_names[i], vis ?
"true" :
"false");
3665 PINFO(
"Found tool_item %p with action name '%s', seting vis to '%s'",
3666 tool_item, action_names[i], vis ?
"true" :
"false");
3667 gtk_widget_set_visible (tool_item, vis);
3670 PINFO(
"Did not find tool_item with action name '%s' to set vis '%s'",
3671 action_names[i], vis ?
"true" :
"false");
3682 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3683 g_return_if_fail (toolbar_labels !=
nullptr);
3685 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3693 const gchar *toolbar_qualifier)
3696 GtkBuilder *builder;
3699 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3700 g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
3702 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3708 gchar *toolbar_name;
3711 if (toolbar_qualifier)
3712 toolbar_name = g_strconcat (
"mainwin-toolbar-", toolbar_qualifier,
nullptr);
3714 toolbar_name = g_strdup (
"mainwin-toolbar");
3716 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder, toolbar_name);
3719 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder,
"mainwin-toolbar");
3721 g_object_set (priv->
toolbar,
"toolbar-style", GTK_TOOLBAR_BOTH, NULL);
3723 g_free (toolbar_name);
3731 GVariant *state = g_action_get_state (G_ACTION(action));
3732 gtk_widget_set_visible (priv->
toolbar, g_variant_get_boolean (state));
3733 g_variant_unref (state);
3743 const gchar **ui_updates)
3746 const gchar *plugin_page_actions_group_name;
3747 GtkBuilder *builder;
3748 const gchar *menu_qualifier;
3750 GMenuModel *menu_model_part;
3751 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
3753 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3754 g_return_if_fail (page !=
nullptr);
3755 g_return_if_fail (ui_updates !=
nullptr);
3757 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3768 if (!plugin_page_actions_group_name)
3774 if ((g_strcmp0 (priv->previous_plugin_page_name,
3775 plugin_page_actions_group_name) == 0) &&
3776 (g_strcmp0 (priv->previous_menu_qualifier,
3777 menu_qualifier) == 0))
3780 priv->previous_plugin_page_name = plugin_page_actions_group_name;
3781 priv->previous_menu_qualifier = menu_qualifier;
3783 gnc_main_window_update_toolbar (window, page, menu_qualifier);
3786 g_hash_table_remove_all (priv->display_item_hash);
3788 GNC_MENU_ATTRIBUTE_TEMPORARY);
3790 for (gint i = 0; ui_updates[i]; i++)
3795 menu_name = g_strconcat (ui_updates[i],
"-", menu_qualifier,
nullptr);
3797 menu_name = g_strdup (ui_updates[i]);
3799 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, menu_name);
3801 if (!menu_model_part)
3802 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, ui_updates[i]);
3804 gsm->search_action_label =
nullptr;
3805 gsm->search_action_name = ui_updates[i];
3808 g_menu_insert_section (G_MENU(gsm->model), gsm->index,
3809 nullptr, G_MENU_MODEL(menu_model_part));
3811 PERR(
"Could not find '%s' in menu model", ui_updates[i]);
3823 g_signal_emit_by_name (window,
"menu_changed", page);
3830 gnc_main_window_update_tab_position (gpointer prefs, gchar *pref, gpointer user_data)
3833 GtkPositionType position = GTK_POS_TOP;
3838 g_return_if_fail (GNC_IS_MAIN_WINDOW(user_data));
3840 window = GNC_MAIN_WINDOW(user_data);
3842 ENTER (
"window %p", window);
3851 position = GTK_POS_BOTTOM;
3856 position = GTK_POS_LEFT;
3861 position = GTK_POS_RIGHT;
3865 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3866 gtk_notebook_set_tab_pos (GTK_NOTEBOOK(priv->
notebook), position);
3868 action = g_action_map_lookup_action (G_ACTION_MAP(window),
3869 "ViewTabPositionAction");
3871 g_signal_handlers_block_by_func (G_OBJECT(action),
3872 (gpointer)gnc_main_window_cmd_view_tab_position,
3874 g_action_change_state (G_ACTION(action), g_variant_new_int32 (item));
3875 g_signal_handlers_unblock_by_func (G_OBJECT(action),
3876 (gpointer)gnc_main_window_cmd_view_tab_position,
3879 gnc_main_window_update_tab_width (
nullptr, (
char*)GNC_PREF_TAB_WIDTH,
nullptr);
3888 gnc_main_window_update_edit_actions_sensitivity (
GncMainWindow *window, gboolean hide)
3892 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));
3894 gboolean can_copy =
false, can_cut =
false, can_paste =
false;
3896 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3899 if (page && GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)
3901 (GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)(page, hide);
3905 if (GTK_IS_EDITABLE (widget))
3907 gboolean has_selection;
3909 has_selection = gtk_editable_get_selection_bounds
3910 (GTK_EDITABLE (widget),
nullptr,
nullptr);
3912 can_copy = has_selection;
3913 can_cut = has_selection;
3916 else if (GTK_IS_TEXT_VIEW (widget))
3918 gboolean has_selection;
3919 GtkTextBuffer *text_buffer;
3921 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
3922 has_selection = gtk_text_buffer_get_selection_bounds
3923 (text_buffer,
nullptr,
nullptr);
3925 can_copy = has_selection;
3926 can_cut = has_selection;
3931 #ifdef ORIGINAL_EPIPHANY_CODE 3933 can_copy = can_cut = can_paste =
true;
3937 can_copy = can_cut = can_paste =
false;
3941 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_copy);
3944 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_cut);
3947 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_paste);
3951 gnc_main_window_enable_edit_actions_sensitivity (
GncMainWindow *window)
3956 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
3959 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
3962 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
3967 gnc_main_window_edit_menu_show_cb (GtkWidget *menu,
3970 gnc_main_window_update_edit_actions_sensitivity (window, FALSE);
3974 gnc_main_window_edit_menu_hide_cb (GtkWidget *menu,
3977 gnc_main_window_enable_edit_actions_sensitivity (window);
3983 GtkWidget *edit_menu_item, *edit_menu;
3987 edit_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM(edit_menu_item));
3989 g_signal_connect (edit_menu,
"show",
3990 G_CALLBACK(gnc_main_window_edit_menu_show_cb), window);
3991 g_signal_connect (edit_menu,
"hide",
3992 G_CALLBACK(gnc_main_window_edit_menu_hide_cb), window);
3997 gnc_main_window_page_focus_in (GtkWidget *widget, GdkEvent *event,
4003 g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
4011 GAction *action =
nullptr;
4012 const gchar *group_name;
4014 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window),
nullptr);
4015 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
4017 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4031 PINFO(
"Redirect action is %p for action anme '%s' and group_name '%s'",
4037 main_window_realize_cb (GtkWidget *widget, gpointer user_data)
4046 g_signal_emit_by_name (window,
"menu_changed",
nullptr);
4053 GtkWidget *main_vbox;
4054 GtkBuilder *builder;
4057 GError *error =
nullptr;
4063 g_signal_connect (G_OBJECT (window),
"delete-event",
4064 G_CALLBACK (gnc_main_window_delete_event), window);
4067 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4068 gtk_box_set_homogeneous (GTK_BOX (main_vbox), FALSE);
4069 gtk_widget_show (main_vbox);
4070 gtk_container_add (GTK_CONTAINER (window), main_vbox);
4072 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4073 priv->
menu_dock = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4074 gtk_box_set_homogeneous (GTK_BOX (priv->
menu_dock), FALSE);
4076 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
menu_dock,
4079 priv->
notebook = gtk_notebook_new ();
4080 g_object_set(G_OBJECT(priv->
notebook),
4082 "enable-popup", TRUE,
4085 g_signal_connect (G_OBJECT (priv->
notebook),
"switch-page",
4086 G_CALLBACK (gnc_main_window_switch_page), window);
4087 g_signal_connect (G_OBJECT (priv->
notebook),
"page-reordered",
4088 G_CALLBACK (gnc_main_window_page_reordered), window);
4089 g_signal_connect (G_OBJECT (priv->
notebook),
"focus-in-event",
4090 G_CALLBACK (gnc_main_window_page_focus_in), window);
4091 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
notebook,
4096 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
statusbar,
4100 gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR(priv->
progressbar), TRUE);
4101 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(priv->
progressbar),
" ");
4105 gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(priv->
progressbar),
4108 builder = gtk_builder_new ();
4109 gtk_builder_set_translation_domain (builder, PROJECT_NAME);
4110 gtk_builder_add_from_resource (builder, GNUCASH_RESOURCE_PREFIX
"/gnc-main-window.ui", &error);
4114 g_critical (
"Failed to load, Error %s", error->message);
4115 g_error_free (error);
4119 g_action_map_add_action_entries (G_ACTION_MAP(window),
4124 priv->
menubar_model = (GMenuModel *)gtk_builder_get_object (builder,
"mainwin-menu");
4127 gtk_widget_show (GTK_WIDGET(priv->
menubar));
4129 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder,
"mainwin-toolbar");
4130 g_object_set (priv->
toolbar,
"toolbar-style", GTK_TOOLBAR_BOTH, NULL);
4131 gtk_container_add (GTK_CONTAINER(priv->
menu_dock), GTK_WIDGET(priv->
toolbar));
4132 gtk_widget_show (GTK_WIDGET(priv->
toolbar));
4134 g_object_unref (builder);
4137 initially_insensitive_actions,
4140 always_insensitive_actions,
4146 gtk_widget_insert_action_group (GTK_WIDGET(window),
"mainwin",
4147 G_ACTION_GROUP(window));
4150 GNC_PREF_TAB_POSITION_TOP,
4151 (gpointer)gnc_main_window_update_tab_position,
4154 GNC_PREF_TAB_POSITION_BOTTOM,
4155 (gpointer)gnc_main_window_update_tab_position,
4158 GNC_PREF_TAB_POSITION_LEFT,
4159 (gpointer)gnc_main_window_update_tab_position,
4162 GNC_PREF_TAB_POSITION_RIGHT,
4163 (gpointer)gnc_main_window_update_tab_position,
4165 gnc_main_window_update_tab_position (
nullptr,
nullptr, window);
4167 gnc_main_window_init_menu_updaters (window);
4171 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4174 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4177 if (!gnc_prefs_is_extra_enabled())
4180 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4186 g_list_foreach (plugins, gnc_main_window_add_plugin, window);
4187 g_list_free (plugins);
4189 g_signal_connect (G_OBJECT (manager),
"plugin-added",
4190 G_CALLBACK (gnc_main_window_plugin_added), window);
4191 g_signal_connect (G_OBJECT (manager),
"plugin-removed",
4192 G_CALLBACK (gnc_main_window_plugin_removed), window);
4195 g_signal_connect (G_OBJECT(window),
"realize",
4196 G_CALLBACK(main_window_realize_cb), window);
4201 #ifdef MAC_INTEGRATION 4210 gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data)
4221 gnc_quartz_should_quit (GtkosxApplication *theApp,
GncMainWindow *window)
4224 gnc_main_window_quit (window);
4229 can_activate_cb(GtkWidget *widget, guint signal_id, gpointer data)
4239 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
4240 GtkWidget *item =
nullptr;
4241 GClosure *quit_closure;
4243 gtk_widget_hide (priv->
menubar);
4244 gtk_widget_set_no_show_all (priv->
menubar,
true);
4246 gtkosx_application_set_menu_bar (theApp, GTK_MENU_SHELL(priv->
menubar));
4251 gtk_widget_hide (GTK_WIDGET(item));
4253 quit_closure = g_cclosure_new (G_CALLBACK (gnc_quartz_should_quit),
4255 gtk_accel_group_connect (priv->
accel_group,
'q', GDK_META_MASK,
4256 GTK_ACCEL_MASK, quit_closure);
4263 gtk_widget_hide (item);
4264 gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET(item), 0);
4271 gtk_widget_hide (GTK_WIDGET(item));
4272 gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET(item), 2);
4278 gtkosx_application_set_help_menu (theApp, GTK_MENU_ITEM(item));
4282 gtkosx_application_set_window_menu (theApp, GTK_MENU_ITEM(item));
4284 g_signal_connect (theApp,
"NSApplicationBlockTermination",
4285 G_CALLBACK(gnc_quartz_should_quit), window);
4287 g_signal_connect (priv->
menubar,
"can-activate-accel",
4288 G_CALLBACK (can_activate_cb),
nullptr);
4290 gtkosx_application_set_use_quartz_accelerators (theApp, FALSE);
4291 g_object_unref (theApp);
4293 #endif //MAC_INTEGRATION 4310 gnc_main_window_show_summarybar (
GncMainWindow *window, GAction *action)
4315 if (action ==
nullptr)
4316 action = g_action_map_lookup_action (G_ACTION_MAP(window),
4317 "ViewSummaryAction");
4318 if (action ==
nullptr)
4321 state = g_action_get_state (G_ACTION(action));
4323 visible = g_variant_get_boolean (state);
4325 g_variant_unref (state);
4340 gnc_main_window_switch_page (GtkNotebook *notebook,
4341 gpointer *notebook_page,
4350 ENTER(
"Notebook %p, page, %p, index %d, window %p",
4351 notebook, notebook_page, pos, window);
4352 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4354 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4358 gnc_plugin_page_unselected (page);
4361 child = gtk_notebook_get_nth_page (notebook, pos);
4373 if (page !=
nullptr)
4377 visible = gnc_main_window_show_summarybar (window,
nullptr);
4381 gnc_plugin_page_selected (page);
4382 gnc_window_update_status (GNC_WINDOW(window), page);
4390 multiple_page_actions,
4393 gnc_main_window_update_title(window);
4394 #ifndef MAC_INTEGRATION 4395 gnc_main_window_update_menu_item(window);
4397 g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
4408 gnc_main_window_page_reordered (GtkNotebook *notebook,
4417 ENTER(
"Notebook %p, child %p, index %d, window %p",
4418 notebook, child, pos, window);
4419 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4423 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4429 if (!old_link)
return;
4440 gnc_main_window_plugin_added (
GncPlugin *manager,
4444 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4445 g_return_if_fail (GNC_IS_PLUGIN (plugin));
4451 gnc_main_window_plugin_removed (
GncPlugin *manager,
4455 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4456 g_return_if_fail (GNC_IS_PLUGIN (plugin));
4464 gnc_main_window_cmd_redirect (GSimpleAction *simple,
4465 GVariant *parameter,
4469 GAction *redirect_action;
4471 PINFO(
"Redirect action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4473 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4475 if (redirect_action)
4477 PINFO(
"Found action %p", redirect_action);
4478 g_action_activate (redirect_action,
nullptr);
4484 gnc_main_window_cmd_page_setup (GSimpleAction *simple,
4485 GVariant *parameter,
4489 GtkWindow *gtk_window;
4491 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
4493 gtk_window = gnc_window_get_gtk_window(GNC_WINDOW(window));
4500 QofBook *book = gnc_get_current_book ();
4501 gboolean use_split_action_for_num_before =
4503 gint use_read_only_threshold_before =
4505 gboolean use_split_action_for_num_after;
4506 gint use_read_only_threshold_after;
4507 gboolean return_val = FALSE;
4508 GList *results =
nullptr, *iter;
4510 if (!options)
return return_val;
4513 for (iter = results; iter; iter = iter->next)
4521 gtk_dialog_run(GTK_DIALOG(dialog));
4522 gtk_widget_destroy(dialog);
4523 g_free (iter->data);
4525 g_list_free (results);
4526 qof_book_begin_edit (book);
4528 use_split_action_for_num_after =
4532 book->cached_num_days_autoreadonly_isvalid = FALSE;
4535 if (use_split_action_for_num_before != use_split_action_for_num_after)
4538 use_split_action_for_num_after);
4541 if (use_read_only_threshold_before != use_read_only_threshold_after)
4544 qof_book_commit_edit (book);
4552 auto options{
static_cast<GncOptionDB *
>(user_data)};
4554 if (!options)
return;
4557 gnc_gui_refresh_all ();
4564 auto options{
static_cast<GncOptionDB *
>(user_data)};
4576 gnc_suspend_gui_refresh ();
4583 GNC_FEATURE_NUM_FIELD_SOURCE);
4585 gnc_book_option_num_field_source_change (num_action);
4586 gnc_resume_gui_refresh ();
4590 show_handler (
const char *class_name, gint component_id,
4591 gpointer user_data, gpointer iter_data)
4598 auto widget = optwin->get_widget();
4599 gtk_window_present(GTK_WINDOW(widget));
4606 auto book = gnc_get_current_book ();
4615 if (gnc_forall_gui_components(DIALOG_BOOK_OPTIONS_CM_CLASS,
4616 show_handler,
nullptr))
4621 (title ? title : _(
"Book Options")),
4622 DIALOG_BOOK_OPTIONS_CM_CLASS, parent);
4623 optionwin->build_contents(options);
4624 optionwin->set_book_help_cb();
4625 optionwin->set_apply_cb(gnc_book_options_dialog_apply_cb,
4627 optionwin->set_close_cb ( gnc_book_options_dialog_close_cb,
4631 return optionwin->get_widget();
4635 gnc_main_window_cmd_file_properties (GSimpleAction *simple,
4636 GVariant *parameter,
4644 gnc_main_window_cmd_file_close (GSimpleAction *simple,
4645 GVariant *parameter,
4652 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
4654 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4660 gnc_main_window_cmd_file_quit (GSimpleAction *simple,
4661 GVariant *parameter,
4668 gnc_main_window_quit(window);
4672 gnc_main_window_cmd_edit_cut (GSimpleAction *simple,
4673 GVariant *parameter,
4677 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4678 GAction *redirect_action;
4680 PINFO(
"Copy action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4682 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4684 if (redirect_action)
4686 PINFO(
"Found action %p", redirect_action);
4687 g_action_activate (redirect_action,
nullptr);
4691 if (GTK_IS_EDITABLE(widget))
4693 gtk_editable_cut_clipboard (GTK_EDITABLE(widget));
4695 else if (GTK_IS_TEXT_VIEW(widget))
4697 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4698 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(widget),
4699 GDK_SELECTION_CLIPBOARD);
4700 gboolean editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(widget));
4703 gtk_text_buffer_cut_clipboard (text_buffer, clipboard, editable);
4708 gnc_main_window_cmd_edit_copy (GSimpleAction *simple,
4709 GVariant *parameter,
4713 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4714 GAction *redirect_action;
4716 PINFO(
"Copy action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4718 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4720 if (redirect_action)
4722 PINFO(
"Found action %p", redirect_action);
4723 g_action_activate (redirect_action,
nullptr);
4727 if (GTK_IS_EDITABLE(widget))
4729 gtk_editable_copy_clipboard (GTK_EDITABLE(widget));
4731 else if (GTK_IS_TEXT_VIEW(widget))
4733 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4734 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(widget),
4735 GDK_SELECTION_CLIPBOARD);
4737 gtk_text_buffer_copy_clipboard (text_buffer, clipboard);
4742 gnc_main_window_cmd_edit_paste (GSimpleAction *simple,
4743 GVariant *parameter,
4747 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4748 GAction *redirect_action;
4750 PINFO(
"Paste action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4752 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4754 if (redirect_action)
4756 PINFO(
"Found action %p", redirect_action);
4757 g_action_activate (redirect_action,
nullptr);
4761 if (GTK_IS_EDITABLE(widget))
4763 gtk_editable_paste_clipboard (GTK_EDITABLE(widget));
4765 else if (GTK_IS_TEXT_VIEW(widget))
4767 auto text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4768 auto clipboard = gtk_widget_get_clipboard (GTK_WIDGET(text_buffer),
4769 GDK_SELECTION_CLIPBOARD);
4772 auto editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(widget));
4773 gtk_text_buffer_paste_clipboard (text_buffer, clipboard,
nullptr,
4780 gnc_main_window_cmd_edit_preferences (GSimpleAction *simple,
4781 GVariant *parameter,
4789 gnc_main_window_cmd_view_refresh (GSimpleAction *simple,
4790 GVariant *parameter,
4796 gnc_main_window_cmd_actions_reset_warnings (GSimpleAction *simple,
4797 GVariant *parameter,
4801 gnc_reset_warnings_dialog(GTK_WINDOW(window));
4805 gnc_main_window_cmd_actions_rename_page (GSimpleAction *simple,
4806 GVariant *parameter,
4812 GtkWidget *
label, *entry;
4815 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4819 LEAVE(
"No current page");
4823 if (!main_window_find_tab_items(window, page, &
label, &entry))
4825 LEAVE(
"can't find required widgets");
4829 gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(
label)));
4830 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
4831 gtk_widget_hide(
label);
4832 gtk_widget_show(entry);
4833 gtk_widget_grab_focus(entry);
4834 LEAVE(
"opened for editing");
4838 gnc_main_window_cmd_view_toolbar (GSimpleAction *simple,
4839 GVariant *parameter,
4844 GVariant *state = g_action_get_state (G_ACTION(simple));
4846 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4848 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!g_variant_get_boolean (state)));
4850 if (!g_variant_get_boolean (state))
4851 gtk_widget_show (priv->
toolbar);
4853 gtk_widget_hide (priv->
toolbar);
4855 g_variant_unref (state);
4859 gnc_main_window_cmd_view_summary (GSimpleAction *simple,
4860 GVariant *parameter,
4868 visible = gnc_main_window_show_summarybar (window, G_ACTION(simple));
4870 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!
visible));
4880 gnc_main_window_cmd_view_statusbar (GSimpleAction *simple,
4881 GVariant *parameter,
4886 GVariant *state = g_action_get_state (G_ACTION(simple));
4888 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4890 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!g_variant_get_boolean (state)));
4892 if (!g_variant_get_boolean (state))
4897 g_variant_unref (state);
4901 gnc_main_window_cmd_window_new (GSimpleAction *simple,
4910 gtk_widget_show(GTK_WIDGET(new_window));
4915 gnc_main_window_cmd_window_move_page (GSimpleAction *simple,
4923 GtkNotebook *notebook;
4924 GtkWidget *tab_widget, *menu_widget;
4926 ENTER(
"action %p, window %p", simple, window);
4929 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4933 LEAVE(
"invalid page");
4938 LEAVE(
"invalid notebook_page");
4942 #ifndef MAC_INTEGRATION 4944 gnc_info_dialog (GTK_WINDOW(window),
"%s",
4945 _(
"The maximum number of window menu entries reached, no more entries will be added."));
4948 notebook = GTK_NOTEBOOK (priv->
notebook);
4949 tab_widget = gtk_notebook_get_tab_label (notebook, page->
notebook_page);
4950 menu_widget = gtk_notebook_get_menu_label (notebook, page->
notebook_page);
4957 g_object_ref(tab_widget);
4958 g_object_ref(menu_widget);
4960 gnc_main_window_disconnect(window, page);
4964 gtk_widget_show(GTK_WIDGET(new_window));
4967 gnc_main_window_connect (new_window, page, tab_widget, menu_widget);
4971 g_object_unref(menu_widget);
4972 g_object_unref(tab_widget);
4973 g_object_unref(page);
4976 DEBUG(
"Moved page %p from window %p to new window %p",
4977 page, window, new_window);
4978 DEBUG(
"Old window current is %p, new window current is %p",
4981 LEAVE(
"page moved");
4985 gnc_main_window_cmd_view_tab_position (GSimpleAction *simple,
4986 GVariant *parameter,
4989 gint item = g_variant_get_int32 (parameter);
4991 g_action_change_state (G_ACTION(simple), parameter);
4993 if (item < 0 || item > 3)
4996 if (item != 0 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_TOP))
4999 if (item != 1 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_BOTTOM))
5002 if (item != 2 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT))
5005 if (item != 3 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_RIGHT))
5029 #ifndef MAC_INTEGRATION 5031 gnc_main_window_cmd_window_raise (GSimpleAction *simple,
5032 GVariant *parameter,
5039 g_return_if_fail (G_IS_SIMPLE_ACTION(simple));
5040 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
5042 item = g_variant_get_int32 (parameter);
5044 ENTER(
"action %p, window %p, item %d", simple, window, item);
5046 g_action_change_state (G_ACTION(simple), parameter);
5048 new_window =
static_cast<GncMainWindow*
>(g_list_nth_data (active_windows, item));
5049 gtk_window_present (GTK_WINDOW(new_window));
5053 g_idle_add ((GSourceFunc)gnc_main_window_update_radio_button, window);
5059 gnc_main_window_cmd_help_tutorial (GSimpleAction *simple,
5068 gnc_main_window_cmd_help_contents (GSimpleAction *simple,
5086 get_file (
const gchar *partial)
5088 gchar *filename, *text =
nullptr;
5092 if (filename && g_file_get_contents(filename, &text, &length,
nullptr))
5116 get_file_strsplit (
const gchar *partial)
5118 gchar *text, **lines;
5120 text = get_file(partial);
5124 lines = g_strsplit_set(text,
"\r\n", -1);
5135 url_signal_cb (GtkAboutDialog *dialog, gchar *uri, gpointer data)
5142 link_button_cb (GtkLinkButton *button, gpointer user_data)
5144 const gchar *uri = gtk_link_button_get_uri (button);
5150 add_about_paths (GtkDialog *dialog)
5159 PWARN(
"Unable to find AboutDialog 'page_vbox' Widget");
5163 grid = gtk_grid_new ();
5166 for (GList *path_node = paths; path_node; path_node = g_list_next (path_node))
5170 gchar *env_name = g_strconcat (ep->env_name,
":", NULL);
5171 GtkWidget *
label = gtk_label_new (env_name);
5173 gchar *display_uri = gnc_doclink_get_unescaped_just_uri (uri);
5174 GtkWidget *widget = gtk_link_button_new_with_label (uri, display_uri);
5176 gtk_grid_attach (GTK_GRID(grid),
label, 0, i, 1, 1);
5177 gtk_widget_set_halign (
label, GTK_ALIGN_END);
5178 gtk_grid_attach (GTK_GRID(grid), widget, 1, i, 1, 1);
5179 gtk_widget_set_halign (widget, GTK_ALIGN_START);
5180 gtk_widget_set_margin_top (widget, 0);
5181 gtk_widget_set_margin_bottom (widget, 0);
5185 GtkWidget *mod_lab = gtk_label_new (_(
"(user modifiable)"));
5186 gtk_grid_attach (GTK_GRID(grid), mod_lab, 2, i, 1, 1);
5187 gtk_widget_show (mod_lab);
5189 g_signal_connect (widget,
"activate-link",
5190 G_CALLBACK(link_button_cb), dialog);
5193 g_free (display_uri);
5196 gtk_container_add_with_properties (GTK_CONTAINER(page_vbox), grid,
5197 "position", 1, NULL);
5198 gtk_widget_show_all (grid);
5199 g_list_free_full (paths, g_free);
5205 gnc_main_window_cmd_help_about (GSimpleAction *simple,
5211 gchar *copyright = g_strdup_printf(_(
"Copyright © 1997-%s The GnuCash contributors."),
5213 gchar **authors = get_file_strsplit(
"AUTHORS");
5214 gchar **documenters = get_file_strsplit(
"DOCUMENTERS");
5215 gchar *license = get_file(
"LICENSE");
5216 GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
5217 GdkPixbuf *logo = gtk_icon_theme_load_icon (icon_theme,
5220 GTK_ICON_LOOKUP_USE_BUILTIN,
5222 gchar *version = g_strdup_printf (
"%s: %s\n%s: %s\nFinance::Quote: %s",
5224 _(
"Build ID"), gnc_build_id(),
5228 GtkDialog *dialog = GTK_DIALOG (gtk_about_dialog_new ());
5229 g_object_set (G_OBJECT (dialog),
5231 "documenters", documenters,
5232 "comments", _(
"Accounting for personal and small business finance."),
5233 "copyright", copyright,
5241 "translator-credits", _(
"translator-credits"),
5243 "website", PACKAGE_URL,
5244 "website-label", _(
"Visit the GnuCash website."),
5252 g_strfreev(documenters);
5254 g_strfreev(authors);
5255 g_object_unref (logo);
5256 g_signal_connect (dialog,
"activate-link",
5257 G_CALLBACK (url_signal_cb),
nullptr);
5260 add_about_paths (dialog);
5263 gtk_window_set_resizable(GTK_WINDOW (dialog), TRUE);
5265 gtk_window_set_transient_for (GTK_WINDOW (dialog),
5266 GTK_WINDOW (window));
5267 gtk_dialog_run (dialog);
5268 gtk_widget_destroy (GTK_WIDGET (dialog));
5280 #ifdef MAC_INTEGRATION 5281 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
5283 for (window_iter = active_windows; window_iter !=
nullptr; window_iter = window_iter->next)
5285 gtk_widget_show(GTK_WIDGET(window_iter->data));
5287 #ifdef MAC_INTEGRATION 5288 g_signal_connect(theApp,
"NSApplicationWillTerminate",
5289 G_CALLBACK(gnc_quartz_shutdown),
nullptr);
5290 gtkosx_application_ready(theApp);
5291 g_object_unref (theApp);
5298 GtkWidget *toplevel;
5303 toplevel = gtk_widget_get_toplevel (widget);
5304 if (toplevel && GTK_IS_WINDOW (toplevel))
5305 return GTK_WINDOW (toplevel);
5316 while (toplevel && !GNC_IS_MAIN_WINDOW (toplevel))
5317 toplevel = gtk_window_get_transient_for(toplevel);
5322 for (window = active_windows; window; window = window->next)
5323 if (gtk_window_is_active (GTK_WINDOW (window->data)))
5324 return static_cast<GtkWindow*
>(window->data);
5326 for (window = active_windows; window; window = window->next)
5327 if (gtk_widget_get_mapped (GTK_WIDGET(window->data)))
5328 return static_cast<GtkWindow*>(window->data);
5340 gnc_main_window_get_gtk_window (GncWindow *window)
5342 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window),
nullptr);
5343 return GTK_WINDOW(window);
5353 gnc_main_window_get_statusbar (GncWindow *window_in)
5358 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in),
nullptr);
5360 window = GNC_MAIN_WINDOW(window_in);
5361 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5372 gnc_main_window_get_progressbar (GncWindow *window_in)
5377 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in),
nullptr);
5379 window = GNC_MAIN_WINDOW(window_in);
5380 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5391 gnc_main_window_get_menubar (GncWindow *window)
5395 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5397 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5408 gnc_main_window_get_toolbar (GncWindow *window)
5412 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5414 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5425 gnc_main_window_get_menubar_model (GncWindow *window)
5429 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5431 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5444 iface->get_gtk_window = gnc_main_window_get_gtk_window;
5445 iface->get_statusbar = gnc_main_window_get_statusbar;
5446 iface->get_progressbar = gnc_main_window_get_progressbar;
5447 iface->get_menubar = gnc_main_window_get_menubar;
5448 iface->get_toolbar = gnc_main_window_get_toolbar;
5449 iface->get_menubar_model = gnc_main_window_get_menubar_model;
5461 gncwin = GNC_WINDOW(window);
5462 gnc_window_set_progressbar_window(gncwin);
5481 GtkBuilder *builder;
5482 GMenuModel *menu_model;
5484 const gchar *menu_qualifier;
5485 gchar *popup_menu_name;
5487 g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
5489 ENTER(
"page %p, event %p", page, event);
5495 if (builder ==
nullptr)
5497 LEAVE(
"no builder");
5502 popup_menu_name = g_strconcat (
"mainwin-popup-", menu_qualifier, NULL);
5504 popup_menu_name = g_strdup (
"mainwin-popup");
5506 menu_model = (GMenuModel *)gtk_builder_get_object (builder, popup_menu_name);
5509 menu_model = (GMenuModel *)gtk_builder_get_object (builder,
"mainwin-popup");
5511 menu = gtk_menu_new_from_model (menu_model);
5518 gtk_menu_attach_to_widget (GTK_MENU(menu), GTK_WIDGET(page->
window),
nullptr);
5519 gtk_menu_popup_at_pointer (GTK_MENU(menu), (GdkEvent *) event);
5521 g_free (popup_menu_name);
5544 ENTER(
"widget %p, page %p", widget, page);
5545 do_popup_menu(page,
nullptr);
5557 GdkEventButton *event,
5560 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
5562 ENTER(
"widget %p, event %p, page %p", whatever, event, page);
5564 if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
5566 do_popup_menu(page, event);
5567 LEAVE(
"menu shown");
5571 LEAVE(
"other click");
5579 for (
auto tmp = active_windows; tmp; tmp = g_list_next(tmp))
5582 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), sensitive);
5591 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5593 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
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.
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.
void gnc_gobject_tracking_remember(GObject *object, GObjectClass *klass)
Tell gnucash to remember this object in the database.
gboolean gnc_menubar_model_update_item(GMenuModel *menu_model, const gchar *action_name, const gchar *label, const gchar *tooltip)
Update the GMenuModel item based on the action name by copying existing item, removing it and inserti...
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_add_accelerator_keys_for_menu(GtkWidget *menu, GtkAccelGroup *accel_group)
Add accelerator keys for menu item widgets.
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.
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.
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.
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.
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.
#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 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.
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.
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 gnc_uri_targets_local_fs(const gchar *uri)
Checks if the given uri is either a valid file uri or a local filesystem path.
GList * gnc_list_all_paths(void)
Returns a GList* of the environment variables used by GnuCash.
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.
GNC_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.
The instance data structure for a menu-only plugin.
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 local 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
Many systems, including Microsoft Windows and BSD-derived Unixes like Darwin, are retaining the int-3...
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.
The instance data structure for a main window object.
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.
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.