35 #include <glib/gi18n.h> 38 #include <gdk/gdkkeysyms.h> 39 #include "dialog-options.hpp" 50 #include "dialog-reset-warnings.h" 51 #include "dialog-transfer.h" 52 #include "dialog-utils.h" 53 #include "engine-helpers.h" 55 #include "gnc-component-manager.h" 56 #include "dialog-doclink-utils.h" 64 #include "gnc-gui-query.h" 66 #include "gnc-hooks.h" 67 #include "gnc-icons.h" 68 #include "gnc-session.h" 75 #include "gnc-warnings.h" 79 #include "gnc-autosave.h" 81 #ifdef MAC_INTEGRATION 82 #include <gtkmacintegration/gtkosxapplication.h> 84 #ifdef HAVE_SYS_STAT_H 85 # define __need_system_sys_stat_h //To block Guile-2.0's evil substitute 86 # include <sys/types.h> 87 # include <sys/stat.h> 101 #define PLUGIN_PAGE_LABEL "plugin-page" 103 #define PLUGIN_PAGE_CLOSE_BUTTON "close-button" 104 #define PLUGIN_PAGE_TAB_LABEL "label" 106 #define GNC_PREF_SHOW_CLOSE_BUTTON "tab-close-buttons" 107 #define GNC_PREF_TAB_NEXT_RECENT "tab-next-recent" 108 #define GNC_PREF_TAB_POSITION_TOP "tab-position-top" 109 #define GNC_PREF_TAB_POSITION_BOTTOM "tab-position-bottom" 110 #define GNC_PREF_TAB_POSITION_LEFT "tab-position-left" 111 #define GNC_PREF_TAB_POSITION_RIGHT "tab-position-right" 112 #define GNC_PREF_TAB_WIDTH "tab-width" 113 #define GNC_PREF_TAB_COLOR "show-account-color-tabs" 114 #define GNC_PREF_SAVE_CLOSE_EXPIRES "save-on-close-expires" 115 #define GNC_PREF_SAVE_CLOSE_WAIT_TIME "save-on-close-wait-time" 116 #define GNC_PREF_TAB_OPEN_ADJACENT "tab-open-adjacent" 118 #define GNC_MAIN_WINDOW_NAME "GncMainWindow" 120 #define DIALOG_BOOK_OPTIONS_CM_CLASS "dialog-book-options" 141 static QofLogModule log_module = GNC_MOD_GUI;
143 static GQuark window_type = 0;
146 static GList *active_windows =
nullptr;
149 static guint secs_to_save = 0;
150 #define MSG_AUTO_SAVE _("Changes will be saved automatically in %u seconds") 153 static void gnc_main_window_constructed (GObject *
object);
154 static void gnc_main_window_finalize (GObject *
object);
155 static void gnc_main_window_destroy (GtkWidget *widget);
157 static void gnc_main_window_setup_window (GncMainWindow *window);
158 static void gnc_window_main_window_init (GncWindowInterface *iface);
159 #ifndef MAC_INTEGRATION 160 static void gnc_main_window_update_all_menu_items (
void);
164 static void gnc_main_window_switch_page (GtkNotebook *notebook, gpointer *notebook_page, gint pos, GncMainWindow *window);
165 static void gnc_main_window_page_reordered (GtkNotebook *notebook, GtkWidget *child, guint pos, GncMainWindow *window);
166 static void gnc_main_window_plugin_added (GncPlugin *manager, GncPlugin *plugin, GncMainWindow *window);
167 static void gnc_main_window_plugin_removed (GncPlugin *manager, GncPlugin *plugin, GncMainWindow *window);
168 static void gnc_main_window_engine_commit_error_callback( gpointer data,
QofBackendError errcode );
171 static void gnc_main_window_cmd_redirect (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
172 static void gnc_main_window_cmd_page_setup (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
173 static void gnc_main_window_cmd_file_properties (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
174 static void gnc_main_window_cmd_file_close (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
175 static void gnc_main_window_cmd_file_quit (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
176 static void gnc_main_window_cmd_edit_cut (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
177 static void gnc_main_window_cmd_edit_copy (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
178 static void gnc_main_window_cmd_edit_paste (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
179 static void gnc_main_window_cmd_edit_preferences (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
180 static void gnc_main_window_cmd_view_refresh (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
181 static void gnc_main_window_cmd_view_toolbar (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
182 static void gnc_main_window_cmd_view_summary (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
183 static void gnc_main_window_cmd_view_statusbar (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
185 static void gnc_main_window_cmd_view_tab_position (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
187 static void gnc_main_window_cmd_actions_reset_warnings (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
188 static void gnc_main_window_cmd_actions_rename_page (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
189 static void gnc_main_window_cmd_window_new (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
190 static void gnc_main_window_cmd_window_move_page (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
191 #ifndef MAC_INTEGRATION 192 static void gnc_main_window_cmd_window_raise (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
194 static void gnc_main_window_cmd_help_tutorial (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
195 static void gnc_main_window_cmd_help_contents (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
196 static void gnc_main_window_cmd_help_about (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
198 static void do_popup_menu(
GncPluginPage *page, GdkEventButton *event);
199 static GtkWidget *gnc_main_window_get_statusbar (GncWindow *window_in);
200 static void statusbar_notification_lastmodified (
void);
201 static void gnc_main_window_update_tab_position (gpointer prefs, gchar *pref, gpointer user_data);
202 static void gnc_main_window_remove_prefs (GncMainWindow *window);
204 #ifdef MAC_INTEGRATION 205 static void gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data);
206 static gboolean gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window);
207 static void gnc_quartz_set_menu (GncMainWindow* window);
209 static void gnc_main_window_init_menu_updaters (GncMainWindow *window);
259 const gchar *previous_plugin_page_name;
260 const gchar *previous_menu_qualifier;
265 GHashTable *display_item_hash;
270 G_ADD_PRIVATE (GncMainWindow)
271 G_IMPLEMENT_INTERFACE (GNC_TYPE_WINDOW,
272 gnc_window_main_window_init))
274 #define GNC_MAIN_WINDOW_GET_PRIVATE(o) \ 275 ((GncMainWindowPrivate*)gnc_main_window_get_instance_private((GncMainWindow*)o)) 279 static guint main_window_signals[LAST_SIGNAL] = { 0 };
285 static GActionEntry gnc_menu_actions [] =
287 {
"FilePageSetupAction", gnc_main_window_cmd_page_setup,
nullptr,
nullptr,
nullptr },
288 {
"FilePropertiesAction", gnc_main_window_cmd_file_properties,
nullptr,
nullptr,
nullptr },
289 {
"FileCloseAction", gnc_main_window_cmd_file_close,
nullptr,
nullptr,
nullptr },
290 {
"FilePrintAction", gnc_main_window_cmd_redirect,
nullptr,
nullptr,
nullptr },
291 {
"FileQuitAction", gnc_main_window_cmd_file_quit,
nullptr,
nullptr,
nullptr },
293 {
"EditCutAction", gnc_main_window_cmd_edit_cut,
nullptr,
nullptr,
nullptr },
294 {
"EditCopyAction", gnc_main_window_cmd_edit_copy,
nullptr,
nullptr,
nullptr },
295 {
"EditPasteAction", gnc_main_window_cmd_edit_paste,
nullptr,
nullptr,
nullptr },
296 {
"EditPreferencesAction", gnc_main_window_cmd_edit_preferences,
nullptr,
nullptr,
nullptr },
298 {
"ActionsForgetWarningsAction", gnc_main_window_cmd_actions_reset_warnings,
nullptr,
nullptr,
nullptr },
299 {
"ActionsRenamePageAction", gnc_main_window_cmd_actions_rename_page,
nullptr,
nullptr,
nullptr },
301 {
"TransactionAction",
nullptr,
nullptr,
nullptr,
nullptr },
303 {
"ViewSortByAction",
nullptr,
nullptr,
nullptr,
nullptr },
304 {
"ViewFilterByAction",
nullptr,
nullptr,
nullptr,
nullptr },
305 {
"ViewRefreshAction", gnc_main_window_cmd_view_refresh,
nullptr,
nullptr,
nullptr },
306 {
"ViewToolbarAction", gnc_main_window_cmd_view_toolbar,
nullptr,
"true",
nullptr },
307 {
"ViewSummaryAction", gnc_main_window_cmd_view_summary,
nullptr,
"true",
nullptr },
308 {
"ViewStatusbarAction", gnc_main_window_cmd_view_statusbar,
nullptr,
"true",
nullptr },
309 {
"ViewTabPositionAction", gnc_main_window_cmd_view_tab_position,
"i",
"@i 0",
nullptr },
311 {
"ScheduledAction",
nullptr,
nullptr,
nullptr,
nullptr },
313 {
"ExtensionsAction",
nullptr,
nullptr,
nullptr,
nullptr },
315 {
"WindowNewAction", gnc_main_window_cmd_window_new,
nullptr,
nullptr,
nullptr },
316 {
"WindowMovePageAction", gnc_main_window_cmd_window_move_page,
nullptr,
nullptr,
nullptr },
317 #ifndef MAC_INTEGRATION 318 {
"WindowAction", gnc_main_window_cmd_window_raise,
"i",
"@i 0",
nullptr },
320 {
"HelpTutorialAction", gnc_main_window_cmd_help_tutorial,
nullptr,
nullptr,
nullptr },
321 {
"HelpContentsAction", gnc_main_window_cmd_help_contents,
nullptr,
nullptr,
nullptr },
322 {
"HelpAboutAction", gnc_main_window_cmd_help_about,
nullptr,
nullptr,
nullptr },
325 static guint gnc_menu_n_actions = G_N_ELEMENTS(gnc_menu_actions);
331 static const gchar *always_insensitive_actions[] =
341 static const gchar *initially_insensitive_actions[] =
352 static const gchar *always_hidden_actions[] =
355 "ViewFilterByAction",
362 static const gchar *immutable_page_actions[] =
371 static const gchar *multiple_page_actions[] =
373 "WindowMovePageAction",
381 #define WINDOW_COUNT "WindowCount" 382 #define WINDOW_STRING "Window %d" 383 #define WINDOW_GEOMETRY "WindowGeometry" 384 #define WINDOW_POSITION "WindowPosition" 385 #define WINDOW_MAXIMIZED "WindowMaximized" 386 #define TOOLBAR_VISIBLE "ToolbarVisible" 387 #define STATUSBAR_VISIBLE "StatusbarVisible" 388 #define SUMMARYBAR_VISIBLE "SummarybarVisible" 389 #define WINDOW_FIRSTPAGE "FirstPage" 390 #define WINDOW_PAGECOUNT "PageCount" 391 #define WINDOW_PAGEORDER "PageOrder" 392 #define PAGE_TYPE "PageType" 393 #define PAGE_NAME "PageName" 394 #define PAGE_STRING "Page %d" 399 const gchar *group_name;
420 for (
auto w = active_windows; w; w = g_list_next(w))
422 auto window{
static_cast<GncMainWindow*
>(w->data)};
423 auto priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
424 for (
auto p = priv->installed_pages; p; p = g_list_next(p))
449 gnc_main_window_restore_page (GncMainWindow *window,
454 gchar *page_group, *page_type =
nullptr, *name =
nullptr;
455 const gchar *class_type;
456 GError *error =
nullptr;
458 ENTER(
"window %p, data %p (key file %p, window %d, page start %d, page num %d)",
459 window, data, data->key_file, data->window_num, data->page_offset,
462 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
463 page_group = g_strdup_printf(PAGE_STRING,
464 data->page_offset + data->page_num);
465 page_type = g_key_file_get_string(data->key_file, page_group,
469 g_warning(
"error reading group %s key %s: %s",
470 page_group, PAGE_TYPE, error->message);
479 class_type = GNC_PLUGIN_PAGE_GET_CLASS(page)->plugin_name;
480 if (strcmp(page_type, class_type) != 0)
482 g_warning(
"error: page types don't match: state %s, existing page %s",
483 page_type, class_type);
491 data->key_file, page_group);
495 if (page->
window ==
nullptr)
502 name = g_key_file_get_string(data->key_file, page_group,
506 g_warning(
"error reading group %s key %s: %s",
507 page_group, PAGE_NAME, error->message);
512 DEBUG(
"updating page name for %p to %s.", page, name);
527 return (page ?
true :
false);
531 intersects_some_monitor(
const GdkRectangle& rect)
533 auto display = gdk_display_get_default();
537 int n = gdk_display_get_n_monitors(display);
538 for (
int i = 0; i < n; ++i)
540 auto monitor = gdk_display_get_monitor(display, i);
541 GdkRectangle monitor_geometry;
542 gdk_monitor_get_geometry(monitor, &monitor_geometry);
543 DEBUG(
"Monitor %d: position (%d,%d), size %dx%d\n", i,
544 monitor_geometry.x, monitor_geometry.y,
545 monitor_geometry.width, monitor_geometry.height);
546 if (gdk_rectangle_intersect(&rect, &monitor_geometry,
nullptr))
557 GError *error =
nullptr;
558 gint *geom = g_key_file_get_integer_list(data->key_file, window_group,
559 WINDOW_GEOMETRY, &length, &error);
562 g_warning(
"error reading group %s key %s: %s",
563 window_group, WINDOW_GEOMETRY, error->message);
567 else if (length != 2)
569 g_warning(
"invalid number of values for group %s key %s",
570 window_group, WINDOW_GEOMETRY);
574 gtk_window_resize(GTK_WINDOW(window), geom[0], geom[1]);
575 DEBUG(
"window (%p) size %dx%d", window, geom[0], geom[1]);
580 gint *pos = g_key_file_get_integer_list(data->key_file, window_group,
581 WINDOW_POSITION, &length, &error);
584 g_warning(
"error reading group %s key %s: %s",
585 window_group, WINDOW_POSITION, error->message);
589 else if (length != 2)
591 g_warning(
"invalid number of values for group %s key %s",
592 window_group, WINDOW_POSITION);
598 GdkRectangle geometry{pos[0], pos[1], geom ? geom[0] : 1, geom ? geom[1] : 1};
599 if (intersects_some_monitor(geometry))
601 gtk_window_move(GTK_WINDOW(window), geometry.x, geometry.y);
602 auto priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
603 priv->
pos[0] = geometry.x;
604 priv->
pos[1] = geometry.y;
605 DEBUG(
"window (%p) position (%d,%d)", window, geometry.x, geometry.y);
609 DEBUG(
"position (%d,%d), size %dx%d is offscreen; will not move",
610 geometry.x, geometry.y, geometry.width, geometry.height);
616 gboolean max = g_key_file_get_boolean(data->key_file, window_group,
617 WINDOW_MAXIMIZED, &error);
620 g_warning(
"error reading group %s key %s: %s",
621 window_group, WINDOW_MAXIMIZED, error->message);
627 gtk_window_maximize(GTK_WINDOW(window));
646 gsize page_start, page_count, i;
647 GError *error =
nullptr;
648 GSList *added_page_offsets =
nullptr;
652 ENTER(
"window %p, data %p (key file %p, window %d)",
653 window, data, data->key_file, data->window_num);
654 gchar *window_group = g_strdup_printf(WINDOW_STRING, data->window_num + 1);
663 if (!g_key_file_has_group (data->key_file, window_group) ||
664 !g_key_file_has_key (data->key_file, window_group, WINDOW_PAGECOUNT, &error))
669 PINFO (
"saved state had an empty first main window\n" 670 "an account hierarchy page was added automatically to avoid confusion");
673 PINFO (
"saved state had an empty main window, skipping restore");
680 page_count = g_key_file_get_integer(data->key_file,
681 window_group, WINDOW_PAGECOUNT, &error);
684 g_warning(
"error reading group %s key %s: %s",
685 window_group, WINDOW_PAGECOUNT, error->message);
694 page_start = g_key_file_get_integer(data->key_file,
695 window_group, WINDOW_FIRSTPAGE, &error);
698 g_warning(
"error reading group %s key %s: %s",
699 window_group, WINDOW_FIRSTPAGE, error->message);
704 if (window ==
nullptr)
706 DEBUG(
"Window %d doesn't exist. Creating new window.", data->window_num);
707 DEBUG(
"active_windows %p.", active_windows);
709 DEBUG(
"first window %p.", active_windows->data);
714 set_window_geometry(window, data, window_group);
716 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
725 GVariant *state = g_action_get_state (G_ACTION(action));
726 gboolean visible = g_variant_get_boolean (state);
727 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
728 TOOLBAR_VISIBLE, &error);
732 g_warning (
"error reading group %s key %s: %s",
733 window_group, TOOLBAR_VISIBLE, error->message);
734 g_error_free (error);
737 else if (visible != desired_visibility)
739 g_action_activate (action,
nullptr);
741 g_variant_unref (state);
747 GVariant *state = g_action_get_state (G_ACTION(action));
748 gboolean visible = g_variant_get_boolean (state);
749 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
750 SUMMARYBAR_VISIBLE, &error);
754 g_warning (
"error reading group %s key %s: %s",
755 window_group, SUMMARYBAR_VISIBLE, error->message);
756 g_error_free (error);
759 else if (visible != desired_visibility)
761 g_action_activate (action,
nullptr);
763 g_variant_unref (state);
769 GVariant *state = g_action_get_state (G_ACTION(action));
770 gboolean visible = g_variant_get_boolean (state);
771 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
772 STATUSBAR_VISIBLE, &error);
776 g_warning (
"error reading group %s key %s: %s",
777 window_group, STATUSBAR_VISIBLE, error->message);
778 g_error_free (error);
781 else if (visible != desired_visibility)
783 g_action_activate (action,
nullptr);
785 g_variant_unref (state);
789 for (i = 0; i < page_count; i++)
791 data->page_offset = page_start;
793 gboolean page_added = gnc_main_window_restore_page (window, data);
795 added_page_offsets = g_slist_append (added_page_offsets, GINT_TO_POINTER(offset));
801 while (gtk_events_pending ())
802 gtk_main_iteration ();
808 order = g_key_file_get_integer_list (data->key_file, window_group,
809 WINDOW_PAGEORDER, &length, &error);
812 g_warning(
"error reading group %s key %s: %s",
813 window_group, WINDOW_PAGEORDER, error->message);
817 else if (length != page_count)
819 g_warning(
"%s key %s length %" G_GSIZE_FORMAT
" differs from window page count %" G_GSIZE_FORMAT,
820 window_group, WINDOW_PAGEORDER, length, page_count);
828 for (i = 0; i < length; i++)
830 gint offset = GPOINTER_TO_INT(g_slist_nth_data (added_page_offsets, order[i] - 1));
831 gpointer page = g_list_nth_data (priv->
installed_pages, order[i] - 1 - offset);
837 gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->
notebook),
838 order[0] - 1 - offset);
840 g_signal_emit_by_name (window,
"page_changed",
848 LEAVE(
"window %p", window);
850 g_slist_free (added_page_offsets);
853 g_free(window_group);
855 gtk_widget_show (GTK_WIDGET(window));
861 gint i, window_count;
862 GError *error =
nullptr;
867 data.key_file = (GKeyFile *) keyfile;
868 window_count = g_key_file_get_integer(data.key_file, STATE_FILE_TOP,
869 WINDOW_COUNT, &error);
872 g_warning(
"error reading group %s key %s: %s",
873 STATE_FILE_TOP, WINDOW_COUNT, error->message);
875 LEAVE(
"can't read count");
881 gnc_set_busy_cursor (
nullptr, TRUE);
882 for (i = 0; i < window_count; i++)
885 auto window{
static_cast<GncMainWindow*
>(g_list_nth_data(active_windows,
887 gnc_main_window_restore_window(window, &data);
889 gnc_unset_busy_cursor (
nullptr);
891 statusbar_notification_lastmodified();
901 DEBUG(
"no saved state file");
903 window =
static_cast<GncMainWindow*
>(g_list_nth_data(active_windows, 0));
904 gtk_widget_show (GTK_WIDGET(window));
906 "gnc-plugin-account-tree-actions",
907 "ViewAccountTreeAction");
908 g_action_activate (action,
nullptr);
924 const gchar *plugin_name, *page_name;
926 ENTER(
"page %p, data %p (key file %p, window %d, page %d)",
927 page, data, data->key_file, data->window_num, data->page_num);
930 if (!plugin_name || !page_name)
932 LEAVE(
"not saving invalid page");
935 page_group = g_strdup_printf(PAGE_STRING, data->page_num++);
936 g_key_file_set_string(data->key_file, page_group, PAGE_TYPE, plugin_name);
937 g_key_file_set_string(data->key_file, page_group, PAGE_NAME, page_name);
958 gint i, num_pages, coords[4], *order;
959 gboolean maximized, minimized, visible =
true;
963 ENTER(
"window %p, data %p (key file %p, window %d)",
964 window, data, data->key_file, data->window_num);
965 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
968 num_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->
notebook));
971 LEAVE(
"empty window %p", window);
976 window_group = g_strdup_printf(WINDOW_STRING, data->window_num++);
977 g_key_file_set_integer(data->key_file, window_group,
978 WINDOW_PAGECOUNT, num_pages);
979 g_key_file_set_integer(data->key_file, window_group,
980 WINDOW_FIRSTPAGE, data->page_num);
985 order =
static_cast<int*
>(g_malloc(
sizeof(gint) * num_pages));
986 for (i = 0; i < num_pages; i++)
988 gpointer page = g_list_nth_data(priv->
usage_order, i);
991 g_key_file_set_integer_list(data->key_file, window_group,
992 WINDOW_PAGEORDER, order, num_pages);
996 gtk_window_get_position(GTK_WINDOW(window), &coords[0], &coords[1]);
997 gtk_window_get_size(GTK_WINDOW(window), &coords[2], &coords[3]);
998 maximized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
999 & GDK_WINDOW_STATE_MAXIMIZED) != 0;
1000 minimized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
1001 & GDK_WINDOW_STATE_ICONIFIED) != 0;
1005 gint *pos = priv->
pos;
1006 g_key_file_set_integer_list(data->key_file, window_group,
1007 WINDOW_POSITION, &pos[0], 2);
1008 DEBUG(
"window minimized (%p) position (%d,%d)", window, pos[0], pos[1]);
1011 g_key_file_set_integer_list(data->key_file, window_group,
1012 WINDOW_POSITION, &coords[0], 2);
1013 g_key_file_set_integer_list(data->key_file, window_group,
1014 WINDOW_GEOMETRY, &coords[2], 2);
1015 g_key_file_set_boolean(data->key_file, window_group,
1016 WINDOW_MAXIMIZED, maximized);
1017 DEBUG(
"window (%p) position (%d,%d), size %dx%d, %s", window, coords[0], coords[1],
1018 coords[2], coords[3],
1019 maximized ?
"maximized" :
"not maximized");
1025 GVariant *state = g_action_get_state (G_ACTION(action));
1026 visible = g_variant_get_boolean (state);
1027 g_variant_unref (state);
1029 g_key_file_set_boolean (data->key_file, window_group,
1030 TOOLBAR_VISIBLE, visible);
1034 GVariant *state = g_action_get_state (G_ACTION(action));
1035 visible = g_variant_get_boolean (state);
1036 g_variant_unref (state);
1038 g_key_file_set_boolean (data->key_file, window_group,
1039 SUMMARYBAR_VISIBLE, visible);
1043 GVariant *state = g_action_get_state (G_ACTION(action));
1044 visible = g_variant_get_boolean (state);
1045 g_variant_unref (state);
1047 g_key_file_set_boolean (data->key_file, window_group,
1048 STATUSBAR_VISIBLE, visible);
1051 g_list_foreach (priv->
installed_pages, (GFunc)gnc_main_window_save_page, data);
1053 g_free(window_group);
1054 LEAVE(
"window %p", window);
1063 data.key_file = keyfile;
1064 data.window_num = 1;
1067 g_key_file_set_integer(data.key_file,
1068 STATE_FILE_TOP, WINDOW_COUNT,
1069 g_list_length(active_windows));
1071 g_list_foreach(active_windows, (GFunc)gnc_main_window_save_window, &data);
1081 g_return_val_if_fail(GNC_IS_MAIN_WINDOW(window), TRUE);
1083 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1098 const GList *windows, *item;
1101 for (item = windows; item; item = g_list_next(item))
1108 if (gnc_gui_refresh_suspended ())
1110 gnc_warning_dialog (
nullptr,
"%s",
"An operation is still running, wait for it to complete before quitting.");
1133 for (walker = active_windows; walker; walker = g_list_next(walker))
1135 auto window{
static_cast<GncMainWindow*
>(walker->data)};
1136 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1145 static gboolean auto_save_countdown (GtkWidget *dialog)
1148 gchar *timeoutstr =
nullptr;
1151 if (!GTK_IS_DIALOG (dialog))
1155 label = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
"count-down-label"));
1156 if (!GTK_IS_LABEL (label))
1162 DEBUG (
"Counting down: %d seconds", secs_to_save);
1164 timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
1165 gtk_label_set_text (GTK_LABEL (label), timeoutstr);
1166 g_free (timeoutstr);
1171 gtk_dialog_response (GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
1190 gnc_main_window_prompt_for_save (GtkWidget *window)
1192 QofSession *session;
1194 GtkWidget *dialog, *msg_area, *label;
1196 const gchar *filename, *tmp;
1197 const gchar *title = _(
"Save changes to file %s before closing?");
1199 const gchar *message_hours =
1200 _(
"If you don't save, changes from the past %d hours and %d minutes will be discarded.");
1201 const gchar *message_days =
1202 _(
"If you don't save, changes from the past %d days and %d hours will be discarded.");
1204 gint minutes, hours, days;
1205 guint timer_source = 0;
1206 if (!gnc_current_session_exist())
1208 session = gnc_get_current_session();
1212 filename = qof_session_get_url(session);
1213 if (!strlen (filename))
1214 filename = _(
"<unknown>");
1215 if ((tmp = strrchr(filename,
'/')) !=
nullptr)
1219 gnc_autosave_remove_timer(book);
1221 dialog = gtk_message_dialog_new(GTK_WINDOW(window),
1223 GTK_MESSAGE_WARNING,
1228 minutes = (
gnc_time (
nullptr) - oldest_change) / 60 + 1;
1229 hours = minutes / 60;
1230 minutes = minutes % 60;
1235 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1236 message_days, days, hours);
1240 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1241 message_hours, hours, minutes);
1245 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1246 ngettext(
"If you don't save, changes from the past %d minute will be discarded.",
1247 "If you don't save, changes from the past %d minutes will be discarded.",
1250 gtk_dialog_add_buttons(GTK_DIALOG(dialog),
1251 _(
"Close _Without Saving"), GTK_RESPONSE_CLOSE,
1252 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
1253 _(
"_Save"), GTK_RESPONSE_APPLY,
1255 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
1262 gchar *timeoutstr =
nullptr;
1264 secs_to_save =
gnc_prefs_get_int (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_CLOSE_WAIT_TIME);
1265 timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
1266 label = GTK_WIDGET(gtk_label_new (timeoutstr));
1267 g_free (timeoutstr);
1268 gtk_widget_show (label);
1270 msg_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG(dialog));
1271 gtk_box_pack_end (GTK_BOX(msg_area), label, TRUE, TRUE, 0);
1272 g_object_set (G_OBJECT (label),
"xalign", 0.0,
nullptr);
1274 g_object_set_data (G_OBJECT (dialog),
"count-down-label", label);
1275 timer_source = g_timeout_add_seconds (1, (GSourceFunc)auto_save_countdown, dialog);
1278 response = gtk_dialog_run (GTK_DIALOG (dialog));
1280 g_source_remove (timer_source);
1281 gtk_widget_destroy(dialog);
1285 case GTK_RESPONSE_APPLY:
1286 gnc_file_save (GTK_WINDOW (window));
1289 case GTK_RESPONSE_CLOSE:
1300 gnc_main_window_add_plugin (gpointer plugin,
1303 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
1304 g_return_if_fail (GNC_IS_PLUGIN (plugin));
1308 GNC_MAIN_WINDOW (window),
1314 gnc_main_window_remove_plugin (gpointer plugin,
1317 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
1318 g_return_if_fail (GNC_IS_PLUGIN (plugin));
1322 GNC_MAIN_WINDOW (window),
1329 gnc_main_window_timed_quit (gpointer dummy)
1331 if (gnc_file_save_in_progress())
1339 gnc_main_window_quit(GncMainWindow *window)
1341 QofSession *session;
1342 gboolean needs_save, do_shutdown = TRUE;
1343 if (gnc_current_session_exist())
1345 session = gnc_get_current_session();
1348 !gnc_file_save_in_progress();
1349 do_shutdown = !needs_save ||
1351 !gnc_main_window_prompt_for_save(GTK_WIDGET(window)));
1361 for (w = active_windows; w; w = next)
1364 GncMainWindow *window =
static_cast<GncMainWindow*
>(w->data);
1366 next = g_list_next (w);
1368 window->window_quitting = TRUE;
1370 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1374 gtk_widget_destroy (GTK_WIDGET(window));
1377 gnc_main_window_remove_prefs (window);
1378 g_timeout_add(250, gnc_main_window_timed_quit,
nullptr);
1385 gnc_main_window_delete_event (GtkWidget *window,
1389 static gboolean already_dead = FALSE;
1398 gchar *message = _(
"This window is closing and will not be restored.");
1400 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
1401 GTK_DIALOG_DESTROY_WITH_PARENT,
1402 GTK_MESSAGE_QUESTION,
1404 "%s", _(
"Close Window?"));
1405 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
1408 gtk_dialog_add_buttons (GTK_DIALOG(dialog),
1409 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
1410 _(
"_OK"), GTK_RESPONSE_YES,
1412 gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_YES);
1413 response = gnc_dialog_run (GTK_DIALOG(dialog), GNC_PREF_WARN_CLOSING_WINDOW_QUESTION);
1414 gtk_widget_destroy (dialog);
1416 if (response == GTK_RESPONSE_CANCEL)
1429 already_dead = gnc_main_window_quit(GNC_MAIN_WINDOW(window));
1455 gpointer user_data, gpointer event_data)
1457 GncMainWindow *window;
1463 g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
1468 if (event_type != QOF_EVENT_DESTROY)
1471 ENTER(
"entity %p, event %d, window %p, event data %p",
1472 entity, event_type, user_data, event_data);
1473 window = GNC_MAIN_WINDOW(user_data);
1474 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1481 next = g_list_next(item);
1482 page = GNC_PLUGIN_PAGE(item->data);
1487 if (GTK_IS_WIDGET(window) && window->window_quitting)
1488 gtk_widget_destroy (GTK_WIDGET(window));
1511 gnc_main_window_generate_title (GncMainWindow *window)
1517 gchar *filename =
nullptr;
1518 const gchar *uri =
nullptr;
1519 const gchar *dirty =
"";
1520 const gchar *readonly_text =
nullptr;
1524 if (gnc_current_session_exist())
1526 uri = qof_session_get_url (gnc_get_current_session ());
1527 book = gnc_get_current_book();
1534 readonly_text = _(
"(read-only)");
1537 readonly = (readonly_text !=
nullptr)
1538 ? g_strdup_printf(
" %s", readonly_text)
1541 if (!uri || g_strcmp0 (uri,
"") == 0)
1542 filename = g_strdup(_(
"Unsaved Book"));
1550 filename = g_path_get_basename ( path );
1561 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1567 title = g_strdup_printf(
"%s%s%s - %s - GnuCash", dirty, filename, readonly,
1572 title = g_strdup_printf(
"%s%s%s - GnuCash", dirty, filename, readonly);
1576 g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE);
1578 immutable_page_actions,
1581 g_signal_emit_by_name (window,
"page_changed", page);
1599 gnc_main_window_update_title (GncMainWindow *window)
1603 title = gnc_main_window_generate_title(window);
1604 gtk_window_set_title(GTK_WINDOW(window), title);
1609 gnc_main_window_update_all_titles (
void)
1611 g_list_foreach(active_windows,
1612 (GFunc)gnc_main_window_update_title,
1634 gnc_tab_clicked_cb(GtkWidget *widget, GdkEventButton *event,
GncPluginPage *page) {
1635 if (event->type == GDK_BUTTON_PRESS && event->button == 2)
1644 gnc_main_window_book_dirty_cb (QofBook *book,
1648 gnc_main_window_update_all_titles();
1651 gnc_autosave_dirty_handler(book, dirty);
1655 gnc_main_window_attach_to_book (QofSession *session)
1659 g_return_if_fail(session);
1663 gnc_main_window_update_all_titles();
1664 #ifndef MAC_INTEGRATION 1665 gnc_main_window_update_all_menu_items();
1669 static guint gnc_statusbar_notification_messageid = 0;
1671 #ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL 1674 static gboolean statusbar_notification_off(gpointer user_data_unused)
1678 if (gnc_statusbar_notification_messageid == 0)
1683 GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
1684 gtk_statusbar_remove(GTK_STATUSBAR(statusbar), 0, gnc_statusbar_notification_messageid);
1685 gnc_statusbar_notification_messageid = 0;
1689 g_warning(
"oops, no GncMainWindow obtained\n");
1693 #endif // STATUSBAR_NOTIFICATION_AUTOREMOVAL 1697 static gchar *generate_statusbar_lastmodified_message()
1699 gchar *message =
nullptr;
1700 const gchar *uri =
nullptr;
1702 if (gnc_current_session_exist())
1704 uri = qof_session_get_url (gnc_get_current_session ());
1707 if (!(uri && strlen (uri)))
1715 gchar *filename = g_path_get_basename ( filepath );
1716 GFile *file = g_file_new_for_uri (uri);
1717 GFileInfo *info = g_file_query_info (file,
1718 G_FILE_ATTRIBUTE_TIME_MODIFIED,
1719 G_FILE_QUERY_INFO_NONE,
1722 if (info && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
1725 struct stat statbuf;
1726 int r = stat(filepath, &statbuf);
1735 _(
"Last modified on %a, %b %d, %Y at %I:%M %p"));
1738 message = g_strdup_printf(_(
"File %s opened. %s"),
1739 filename, time_string);
1744 g_warning(
"Unable to read mtime for file %s\n", filepath);
1750 g_object_unref (info);
1751 g_object_unref (file);
1760 statusbar_notification_lastmodified()
1764 GtkWidget *widget =
nullptr;
1765 for (iter = active_windows; iter && !(widget && GNC_IS_MAIN_WINDOW(widget));
1766 iter = g_list_next(iter))
1768 widget =
static_cast<GtkWidget*
>(iter->data);
1770 if (widget && GNC_IS_MAIN_WINDOW(widget))
1773 GncMainWindow *mainwindow = GNC_MAIN_WINDOW(widget);
1774 GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
1776 gchar *msg = generate_statusbar_lastmodified_message();
1779 gnc_statusbar_notification_messageid = gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);
1783 #ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL 1786 g_timeout_add(10 * 1000, statusbar_notification_off,
nullptr);
1791 g_warning(
"uh oh, no GNC_IS_MAIN_WINDOW\n");
1813 #ifndef MAC_INTEGRATION 1828 gnc_main_window_update_one_menu_action (GncMainWindow *window,
1832 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
1836 ENTER(
"window %p, action %s, label %s, index %d, visible %d", window,
1837 data->action_name, data->label, data->index, data->visible);
1839 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1841 gsm->search_action_label =
nullptr;
1842 gsm->search_action_name =
"WindowsPlaceholder1";
1843 gsm->search_action_target =
nullptr;
1847 LEAVE(
"Could not find placeholder 'WindowsPlaceholder1' for windows entries");
1852 pos = gsm->index + data->index + 1;
1856 if (pos < g_menu_model_get_n_items (gsm->model))
1857 g_menu_remove (G_MENU(gsm->model), pos);
1864 item = g_menu_item_new (data->label,
"mainwin.WindowAction");
1865 g_menu_item_set_attribute (item, G_MENU_ATTRIBUTE_TARGET,
"i", data->index);
1867 if (pos < g_menu_model_get_n_items (gsm->model))
1868 g_menu_remove (G_MENU(gsm->model), pos);
1869 g_menu_insert_item (G_MENU(gsm->model), pos, item);
1870 g_object_unref (item);
1889 gnc_main_window_update_radio_button (GncMainWindow *window)
1894 ENTER(
"window %p", window);
1897 index = g_list_index (active_windows, window);
1905 action = g_action_map_lookup_action (G_ACTION_MAP(window),
1910 g_signal_handlers_block_by_func (G_OBJECT(action),
1911 (gpointer)gnc_main_window_cmd_window_raise,
1914 DEBUG(
"blocked signal on action %p, window %p", action, window);
1915 g_action_change_state (G_ACTION(action), g_variant_new_int32 (index));
1917 g_signal_handlers_unblock_by_func (G_OBJECT(action),
1918 (gpointer)gnc_main_window_cmd_window_raise,
1936 gnc_main_window_update_menu_item (GncMainWindow *window)
1939 gchar **strings, *title, *expanded;
1942 ENTER(
"window %p", window);
1944 index = g_list_index (active_windows, window);
1953 title = gnc_main_window_generate_title (window);
1954 strings = g_strsplit (title,
"_", 0);
1956 expanded = g_strjoinv (
"__", strings);
1959 data.label = g_strdup_printf (
"_%" G_GSIZE_FORMAT
" %s", (
index + 1) % 10, expanded);
1964 data.label = expanded;
1966 g_strfreev (strings);
1968 data.visible = TRUE;
1969 data.action_name = g_strdup_printf (
"Window%" G_GSIZE_FORMAT
"Action",
index);
1972 g_list_foreach (active_windows,
1973 (GFunc)gnc_main_window_update_one_menu_action,
1976 g_free (data.action_name);
1977 g_free (data.label);
1991 #ifndef MAC_INTEGRATION 1993 gnc_main_window_update_all_menu_items (
void)
1999 g_list_foreach (active_windows,
2000 (GFunc)gnc_main_window_update_menu_item,
2003 g_list_foreach (active_windows,
2004 (GFunc)gnc_main_window_update_radio_button,
2008 data.visible = FALSE;
2013 data.action_name = g_strdup_printf (
"Window%dAction", data.index);
2014 data.label = g_strdup_printf (
"mywin%" G_GSIZE_FORMAT, i % 10);
2016 g_list_foreach (active_windows,
2017 (GFunc)gnc_main_window_update_one_menu_action,
2020 g_free (data.action_name);
2021 g_free (data.label);
2039 gnc_main_window_update_tab_close_one_page (
GncPluginPage *page,
2042 auto new_value{
static_cast<gboolean*
>(user_data)};
2043 ENTER(
"page %p, visible %d", page, *new_value);
2044 auto close_button{
static_cast<GtkWidget*
>(g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON))};
2047 LEAVE(
"no close button");
2052 gtk_widget_show (close_button);
2054 gtk_widget_hide (close_button);
2072 gnc_main_window_update_tab_close (gpointer prefs, gchar *pref, gpointer user_data)
2077 new_value =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SHOW_CLOSE_BUTTON);
2079 gnc_main_window_update_tab_close_one_page,
2094 gnc_main_window_update_tab_color_one_page (
GncPluginPage *page,
2097 const gchar *color_string;
2099 ENTER(
"page %p", page);
2117 gnc_main_window_update_tab_color (gpointer gsettings, gchar *pref, gpointer user_data)
2120 g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
2121 auto window{
static_cast<GncMainWindow*
>(user_data)};
2122 auto priv{GNC_MAIN_WINDOW_GET_PRIVATE(window)};
2123 if (g_strcmp0 (GNC_PREF_TAB_COLOR, pref) == 0)
2136 gboolean tabs_left_right;
2140 populate_tab_width_struct (
void)
2146 tw->tabs_left_right =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT) ||
2174 gnc_main_window_set_tab_ellipsize (GtkWidget *
label, gint tab_width, gboolean tab_left_right)
2176 const gchar *lab_text = gtk_label_get_text (GTK_LABEL(
label));
2180 gint text_length = g_utf8_strlen (lab_text, -1);
2181 if (text_length < tab_width)
2184 gtk_label_set_width_chars (GTK_LABEL(
label), tab_width);
2186 gtk_label_set_width_chars (GTK_LABEL(
label), text_length);
2188 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_NONE);
2192 gtk_label_set_width_chars (GTK_LABEL(
label), tab_width);
2193 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_MIDDLE);
2198 gtk_label_set_width_chars (GTK_LABEL(
label), 15);
2199 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_NONE);
2215 gnc_main_window_update_tab_width_one_page (
GncPluginPage *page,
2218 auto tw{
static_cast<TabWidth*
>(user_data)};
2220 ENTER(
"page %p, tab width %d, tabs on left or right %d",
2221 page, tw->tab_width, tw->tabs_left_right);
2223 auto label{
static_cast<GtkWidget *
>(g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL))};
2229 gnc_main_window_set_tab_ellipsize (
label, tw->tab_width, tw->tabs_left_right);
2247 gnc_main_window_update_tab_width (gpointer prefs, gchar *pref, gpointer user_data)
2253 tw = populate_tab_width_struct ();
2266 main_window_find_tab_items (GncMainWindow *window,
2268 GtkWidget **label_p,
2269 GtkWidget **entry_p)
2272 GtkWidget *tab_hbox, *widget, *tab_widget;
2273 GList *children, *tmp;
2275 ENTER(
"window %p, page %p, label_p %p, entry_p %p",
2276 window, page, label_p, entry_p);
2277 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2278 *label_p = *entry_p =
nullptr;
2282 LEAVE(
"invalid notebook_page");
2286 tab_widget = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->
notebook),
2290 tab_hbox = tab_widget;
2292 if (g_strcmp0(gtk_widget_get_name(tab_hbox),
"tab-content") == 0) {
2295 GList* _children = gtk_container_get_children(GTK_CONTAINER(tab_hbox));
2296 tab_hbox = _children ? GTK_WIDGET(_children->data) : nullptr;
2297 g_list_free(_children);
2300 if (!GTK_IS_BOX(tab_hbox))
2302 PWARN (
"Unknown widget for tab label %p", tab_widget);
2306 children = gtk_container_get_children(GTK_CONTAINER(tab_hbox));
2307 for (tmp = children; tmp; tmp = g_list_next(tmp))
2309 widget =
static_cast<GtkWidget*
>(tmp->data);
2310 if (GTK_IS_LABEL(widget))
2314 else if (GTK_IS_ENTRY(widget))
2319 g_list_free(children);
2321 LEAVE(
"label %p, entry %p", *label_p, *entry_p);
2322 return (*label_p && *entry_p);
2326 main_window_find_tab_widget (GncMainWindow *window,
2328 GtkWidget **widget_p)
2332 ENTER(
"window %p, page %p, widget %p",
2333 window, page, widget_p);
2334 *widget_p =
nullptr;
2338 LEAVE(
"invalid notebook_page");
2342 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2343 *widget_p = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->
notebook),
2346 LEAVE(
"widget %p", *widget_p);
2352 const gchar *long_name_in)
2354 GtkWidget *tab_widget;
2358 if ((long_name_in ==
nullptr) || (*long_name_in ==
'\0'))
2363 gchar *long_name = g_strstrip (g_strdup (long_name_in));
2367 if (*long_name ==
'\0' || strcmp (long_name, old_long_name) == 0)
2370 LEAVE(
"empty string or name unchanged");
2376 GncMainWindow *window = GNC_MAIN_WINDOW(page->
window);
2380 LEAVE(
"no window widget available");
2385 if (main_window_find_tab_widget (window, page, &tab_widget))
2386 gtk_widget_set_tooltip_text (tab_widget, long_name);
2394 const gchar *name_in)
2396 GncMainWindow *window;
2398 GtkWidget *
label, *entry;
2404 if ((name_in ==
nullptr) || (*name_in ==
'\0'))
2409 name = g_strstrip(g_strdup(name_in));
2415 LEAVE(
"empty string or name unchanged");
2423 window = GNC_MAIN_WINDOW(page->
window);
2427 LEAVE(
"no window widget available");
2431 if (main_window_find_tab_items(window, page, &
label, &entry))
2432 gtk_label_set_text(GTK_LABEL(
label), name);
2435 tw = populate_tab_width_struct ();
2436 gnc_main_window_update_tab_width_one_page (page, tw);
2442 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2443 label = gtk_notebook_get_menu_label (GTK_NOTEBOOK(priv->
notebook),
2445 gtk_label_set_text(GTK_LABEL(
label), name);
2449 gnc_main_window_update_title(window);
2457 const gchar *color_in)
2459 GncMainWindow *window;
2461 GtkWidget *tab_widget;
2463 gchar *color_string =
nullptr;
2464 gboolean want_color = FALSE;
2468 color_string = g_strstrip(g_strdup(color_in));
2470 if (color_string && *color_string !=
'\0')
2474 window = GNC_MAIN_WINDOW(page->
window);
2481 main_window_find_tab_widget (window, page, &tab_widget);
2482 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2484 if (want_color && gdk_rgba_parse(&tab_color, color_string) && priv->
show_color_tabs)
2486 GtkCssProvider *provider = gtk_css_provider_new();
2487 GtkStyleContext *stylectxt;
2488 gchar *col_str, *widget_css;
2490 if (!GTK_IS_EVENT_BOX (tab_widget))
2492 GtkWidget *event_box = gtk_event_box_new ();
2493 g_object_ref (tab_widget);
2494 gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->
notebook),
2496 gtk_container_add (GTK_CONTAINER(event_box), tab_widget);
2497 g_object_unref (tab_widget);
2498 tab_widget = event_box;
2501 stylectxt = gtk_widget_get_style_context (GTK_WIDGET (tab_widget));
2502 col_str = gdk_rgba_to_string (&tab_color);
2503 widget_css = g_strconcat (
"*{\n background-color:", col_str,
";\n}\n",
nullptr);
2505 gtk_css_provider_load_from_data (provider, widget_css, -1,
nullptr);
2506 gtk_style_context_add_provider (stylectxt, GTK_STYLE_PROVIDER (provider),
2507 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
2508 g_object_unref (provider);
2510 g_free (widget_css);
2514 if (GTK_IS_EVENT_BOX (tab_widget))
2516 GtkWidget *tab_hbox = gtk_bin_get_child(GTK_BIN(tab_widget));
2517 g_object_ref (tab_hbox);
2518 gtk_container_remove (GTK_CONTAINER(tab_widget), tab_hbox);
2519 gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->
notebook),
2521 g_object_unref (tab_hbox);
2524 g_free(color_string);
2533 GncMainWindow *window;
2534 GtkWidget *tab_widget;
2535 GtkWidget *image = NULL;
2537 gchar *image_name = NULL;
2538 const gchar *icon_name;
2542 g_return_if_fail (page && page->
window);
2544 if (!GNC_IS_MAIN_WINDOW (page->
window))
2547 window = GNC_MAIN_WINDOW(page->
window);
2550 main_window_find_tab_widget (window, page, &tab_widget);
2554 LEAVE(
"no tab widget");
2558 if (GTK_IS_EVENT_BOX(tab_widget))
2559 tab_widget = gtk_bin_get_child (GTK_BIN(tab_widget));
2561 children = gtk_container_get_children (GTK_CONTAINER(tab_widget));
2563 for (GList *child = children; child; child = g_list_next (child))
2565 GtkWidget *widget =
static_cast<GtkWidget*
>(child->data);
2566 if (GTK_IS_IMAGE(widget))
2569 g_list_free (children);
2573 LEAVE(
"no image to replace");
2577 g_object_get (image,
"icon-name", &image_name, NULL);
2580 icon_name =
"changes-prevent-symbolic";
2582 icon_name = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
2584 if (g_strcmp0 (icon_name, image_name) == 0)
2586 LEAVE(
"page icon the same, no need to replace");
2587 g_free (image_name);
2590 gtk_container_remove (GTK_CONTAINER(tab_widget), image);
2591 image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
2592 gtk_widget_show (image);
2594 gtk_container_add (GTK_CONTAINER(tab_widget), image);
2595 gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
2596 gtk_box_reorder_child (GTK_BOX(tab_widget), image, 0);
2598 g_free (image_name);
2604 gnc_main_window_tab_entry_activate (GtkWidget *entry,
2607 GtkWidget *
label, *entry2;
2609 g_return_if_fail(GTK_IS_ENTRY(entry));
2610 g_return_if_fail(GNC_IS_PLUGIN_PAGE(page));
2613 if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->
window),
2614 page, &
label, &entry2))
2616 LEAVE(
"can't find required widgets");
2622 gtk_widget_hide(entry);
2623 gtk_widget_show(
label);
2629 gnc_main_window_tab_entry_editing_done (GtkWidget *entry,
2633 gnc_main_window_tab_entry_activate(entry, page);
2639 gnc_main_window_tab_entry_focus_out_event (GtkWidget *entry,
2644 gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(entry));
2650 gnc_main_window_tab_entry_key_press_event (GtkWidget *entry,
2654 if (event->keyval == GDK_KEY_Escape)
2656 GtkWidget *
label, *entry2;
2658 g_return_val_if_fail(GTK_IS_ENTRY(entry), FALSE);
2659 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
2662 if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->
window),
2663 page, &
label, &entry2))
2665 LEAVE(
"can't find required widgets");
2669 gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(
label)));
2670 gtk_widget_hide(entry);
2671 gtk_widget_show(
label);
2693 GObjectClass *object_class = G_OBJECT_CLASS (klass);
2694 GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS(klass);
2696 window_type = g_quark_from_static_string (
"gnc-main-window");
2698 object_class->constructed = gnc_main_window_constructed;
2699 object_class->finalize = gnc_main_window_finalize;
2702 gtkwidget_class->destroy = gnc_main_window_destroy;
2715 main_window_signals[PAGE_ADDED] =
2716 g_signal_new (
"page_added",
2717 G_OBJECT_CLASS_TYPE (object_class),
2721 g_cclosure_marshal_VOID__OBJECT,
2735 main_window_signals[PAGE_CHANGED] =
2736 g_signal_new (
"page_changed",
2737 G_OBJECT_CLASS_TYPE (object_class),
2741 g_cclosure_marshal_VOID__OBJECT,
2753 main_window_signals[MENU_CHANGED] =
2754 g_signal_new (
"menu_changed",
2755 G_OBJECT_CLASS_TYPE (object_class),
2759 g_cclosure_marshal_VOID__OBJECT,
2764 GNC_PREF_SHOW_CLOSE_BUTTON,
2765 (gpointer)gnc_main_window_update_tab_close,
2769 (gpointer)gnc_main_window_update_tab_width,
2772 gnc_hook_add_dangler(HOOK_BOOK_SAVED,
2773 (GFunc)gnc_main_window_update_all_titles,
nullptr,
nullptr);
2774 gnc_hook_add_dangler(HOOK_BOOK_OPENED,
2775 (GFunc)gnc_main_window_attach_to_book,
nullptr,
nullptr);
2786 gnc_main_window_init (GncMainWindow *window)
2791 gtk_widget_set_name (GTK_WIDGET(window),
"gnc-id-main-window");
2798 priv->display_item_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
nullptr);
2800 priv->previous_plugin_page_name =
nullptr;
2801 priv->previous_menu_qualifier =
nullptr;
2804 gtk_window_add_accel_group (GTK_WINDOW(window), priv->
accel_group);
2811 (gpointer)gnc_main_window_update_tab_color,
2814 gnc_main_window_setup_window (window);
2824 gnc_main_window_constructed (GObject *obj)
2828 G_OBJECT_CLASS (gnc_main_window_parent_class)->constructed (obj);
2842 gnc_main_window_finalize (GObject *
object)
2844 g_return_if_fail (
object !=
nullptr);
2845 g_return_if_fail (GNC_IS_MAIN_WINDOW (
object));
2847 if (active_windows ==
nullptr)
2854 G_OBJECT_CLASS (gnc_main_window_parent_class)->finalize (
object);
2859 gnc_main_window_remove_prefs (GncMainWindow *window)
2864 (gpointer)gnc_main_window_update_tab_color,
2868 GNC_PREF_SHOW_CLOSE_BUTTON,
2869 (gpointer)gnc_main_window_update_tab_close,
2874 (gpointer)gnc_main_window_update_tab_width,
2878 GNC_PREF_TAB_POSITION_TOP,
2879 (gpointer)gnc_main_window_update_tab_position,
2883 GNC_PREF_TAB_POSITION_BOTTOM,
2884 (gpointer)gnc_main_window_update_tab_position,
2888 GNC_PREF_TAB_POSITION_LEFT,
2889 (gpointer)gnc_main_window_update_tab_position,
2893 GNC_PREF_TAB_POSITION_RIGHT,
2894 (gpointer)gnc_main_window_update_tab_position,
2902 gnc_prefs_set_reg_negative_color_pref_id (0);
2910 gnc_prefs_set_reg_auto_raise_lists_id (0);
2916 gnc_main_window_destroy (GtkWidget *widget)
2918 GncMainWindow *window;
2920 GncPluginManager *manager;
2923 g_return_if_fail (widget !=
nullptr);
2924 g_return_if_fail (GNC_IS_MAIN_WINDOW (widget));
2926 window = GNC_MAIN_WINDOW (widget);
2927 #ifdef MAC_INTEGRATION 2928 auto entry = g_list_find (active_windows, window);
2929 if (entry && (entry->next || entry->prev))
2930 gnc_quartz_set_menu (GNC_MAIN_WINDOW (entry->next ? entry->next->data : entry->prev->data));
2932 active_windows = g_list_remove (active_windows, window);
2935 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2943 if (gnc_window_get_progressbar_window() == GNC_WINDOW(window))
2944 gnc_window_set_progressbar_window(
nullptr);
2945 #ifndef MAC_INTEGRATION 2947 gnc_main_window_update_all_menu_items();
2950 gnc_main_window_remove_prefs (window);
2955 g_hash_table_destroy (priv->display_item_hash);
2960 g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
2961 g_list_free (plugins);
2964 GTK_WIDGET_CLASS (gnc_main_window_parent_class)->destroy (widget);
2969 gnc_main_window_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
2972 GdkModifierType modifiers;
2974 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(widget), FALSE);
2976 priv = GNC_MAIN_WINDOW_GET_PRIVATE(widget);
2978 modifiers = gtk_accelerator_get_default_mod_mask ();
2980 if ((event->state & modifiers) == (GDK_CONTROL_MASK | GDK_MOD1_MASK))
2982 const gchar *account_key = C_ (
"lower case key for short cut to 'Accounts'",
"a");
2983 guint account_keyval = gdk_keyval_from_name (account_key);
2985 if ((account_keyval == event->keyval) || (account_keyval == gdk_keyval_to_lower (event->keyval)))
2989 for (GList *item = priv->
installed_pages; item; item = g_list_next (item))
2993 if (g_strcmp0 (pname,
"GncPluginPageAccountTree") == 0)
2995 gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->
notebook), page);
3001 else if ((GDK_KEY_Menu == event->keyval) || (GDK_KEY_space == event->keyval))
3003 GList *menu = gtk_menu_get_for_attach_widget (GTK_WIDGET(priv->
notebook));
3007 gtk_menu_popup_at_widget (GTK_MENU(menu->data),
3025 auto window{
static_cast<GncMainWindow*
>(g_object_new (GNC_TYPE_MAIN_WINDOW,
nullptr))};
3026 gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
3032 gtk_window_get_size (old_window, &width, &height);
3033 gtk_window_resize (GTK_WINDOW (window), width, height);
3034 if ((gdk_window_get_state((gtk_widget_get_window (GTK_WIDGET(old_window))))
3035 & GDK_WINDOW_STATE_MAXIMIZED) != 0)
3037 gtk_window_maximize (GTK_WINDOW (window));
3040 active_windows = g_list_append (active_windows, window);
3041 gnc_main_window_update_title(window);
3042 window->window_quitting = FALSE;
3043 window->just_plugin_prefs = FALSE;
3044 #ifdef MAC_INTEGRATION 3045 gnc_quartz_set_menu(window);
3047 gnc_main_window_update_all_menu_items();
3052 g_signal_connect (G_OBJECT(window),
"key-press-event",
3053 G_CALLBACK(gnc_main_window_key_press_event),
3064 gnc_main_window_engine_commit_error_callback( gpointer data,
3067 GncMainWindow* window = GNC_MAIN_WINDOW(data);
3069 const gchar *reason = _(
"Unable to save to database.");
3071 reason = _(
"Unable to save to database: Book is marked read-only.");
3072 dialog = gtk_message_dialog_new( GTK_WINDOW(window),
3073 GTK_DIALOG_DESTROY_WITH_PARENT,
3078 gtk_dialog_run(GTK_DIALOG (dialog));
3079 gtk_widget_destroy(dialog);
3101 gnc_main_window_connect (GncMainWindow *window,
3103 GtkWidget *tab_hbox,
3104 GtkWidget *menu_label)
3107 GtkNotebook *notebook;
3108 gint current_position = -1;
3110 page->
window = GTK_WIDGET(window);
3111 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3112 notebook = GTK_NOTEBOOK (priv->
notebook);
3120 gtk_notebook_insert_page_menu (notebook, page->
notebook_page,
3121 tab_hbox, menu_label, current_position);
3122 gtk_notebook_set_tab_reorderable (notebook, page->
notebook_page, TRUE);
3123 gnc_plugin_page_inserted (page);
3125 gtk_notebook_set_current_page (notebook, current_position);
3127 if (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)
3128 (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)(page, GTK_WIDGET(window));
3129 g_signal_emit (window, main_window_signals[PAGE_ADDED], 0, page);
3131 g_signal_connect(G_OBJECT(page->
notebook_page),
"popup-menu",
3133 g_signal_connect_after(G_OBJECT(page->
notebook_page),
"button-press-event",
3152 gnc_main_window_disconnect (GncMainWindow *window,
3156 GtkNotebook *notebook;
3161 g_signal_handlers_disconnect_by_func(G_OBJECT(page->
notebook_page),
3163 g_signal_handlers_disconnect_by_func(G_OBJECT(page->
notebook_page),
3170 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3173 gnc_plugin_page_unselected (page);
3182 notebook = GTK_NOTEBOOK (priv->
notebook);
3188 page_num = gtk_notebook_page_num(notebook, new_page->
notebook_page);
3189 gtk_notebook_set_current_page(notebook, page_num);
3194 while (gtk_events_pending())
3195 gtk_main_iteration();
3200 page_num = gtk_notebook_page_num(notebook, page->
notebook_page);
3201 gtk_notebook_remove_page (notebook, page_num);
3203 if ( gtk_notebook_get_current_page(notebook) == -1)
3209 gnc_main_window_switch_page(notebook,
nullptr, -1, window);
3213 gnc_plugin_page_removed (page);
3215 gnc_window_set_status (GNC_WINDOW(window), page,
nullptr);
3227 GncMainWindow *window;
3229 GtkNotebook *notebook;
3232 window = GNC_MAIN_WINDOW (page->
window);
3233 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3234 notebook = GTK_NOTEBOOK (priv->
notebook);
3235 page_num = gtk_notebook_page_num(notebook, page->
notebook_page);
3236 gtk_notebook_set_current_page (notebook, page_num);
3237 gtk_window_present(GTK_WINDOW(window));
3253 GtkWidget *tab_container, *tab_clickable_area;
3254 GtkWidget *
label, *entry;
3255 const gchar *icon, *text, *color_string, *lab_text;
3260 ENTER(
"window %p, page %p", window, page);
3262 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3263 g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
3266 if (gnc_main_window_page_exists(page))
3276 for (tmp = active_windows; tmp; tmp = g_list_next(tmp))
3278 window = GNC_MAIN_WINDOW(tmp->data);
3279 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3287 gtk_widget_show(GTK_WIDGET(window));
3289 else if ((window ==
nullptr) && active_windows)
3291 window =
static_cast<GncMainWindow*
>(active_windows->data);
3294 page->
window = GTK_WIDGET(window);
3311 icon = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
3313 label = gtk_label_new (lab_text);
3314 g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL,
label);
3316 tw = populate_tab_width_struct ();
3317 gnc_main_window_update_tab_width_one_page (page, tw);
3320 gtk_widget_show (
label);
3322 tab_container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
3327 gtk_widget_set_tooltip_text(tab_container, text);
3331 gtk_widget_set_name (GTK_WIDGET(tab_container),
"gnc-id-account-page-tab-box");
3333 gtk_box_set_homogeneous (GTK_BOX (tab_container), FALSE);
3334 gtk_widget_show (tab_container);
3337 tab_clickable_area = gtk_event_box_new();
3338 gtk_widget_show(tab_clickable_area);
3339 gtk_box_pack_start (GTK_BOX (tab_container), tab_clickable_area, TRUE, TRUE, 0);
3343 GtkWidget *tab_content = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
3344 gtk_widget_set_name(tab_content,
"tab-content");
3345 gtk_container_add(GTK_CONTAINER(tab_clickable_area), tab_content);
3346 gtk_widget_show(tab_content);
3348 if (icon !=
nullptr)
3350 image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
3351 gtk_widget_show (image);
3352 gtk_box_pack_start (GTK_BOX (tab_content), image, FALSE, FALSE, 0);
3353 gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
3354 gtk_box_pack_start (GTK_BOX (tab_content),
label, TRUE, TRUE, 0);
3357 gtk_box_pack_start (GTK_BOX (tab_content),
label, TRUE, TRUE, 0);
3359 entry = gtk_entry_new();
3360 gtk_widget_hide (entry);
3361 gtk_box_pack_start (GTK_BOX (tab_content), entry, TRUE, TRUE, 0);
3362 g_signal_connect(G_OBJECT(entry),
"activate",
3363 G_CALLBACK(gnc_main_window_tab_entry_activate), page);
3364 g_signal_connect(G_OBJECT(entry),
"focus-out-event",
3365 G_CALLBACK(gnc_main_window_tab_entry_focus_out_event),
3367 g_signal_connect(G_OBJECT(entry),
"key-press-event",
3368 G_CALLBACK(gnc_main_window_tab_entry_key_press_event),
3370 g_signal_connect(G_OBJECT(entry),
"editing-done",
3371 G_CALLBACK(gnc_main_window_tab_entry_editing_done),
3375 if (!g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE))
3377 GtkWidget *close_image, *close_button;
3378 GtkRequisition requisition;
3380 close_button = gtk_button_new();
3381 gtk_button_set_relief(GTK_BUTTON(close_button), GTK_RELIEF_NONE);
3382 close_image = gtk_image_new_from_icon_name (
"window-close", GTK_ICON_SIZE_MENU);
3383 gtk_widget_show(close_image);
3384 gtk_widget_get_preferred_size (close_image, &requisition,
nullptr);
3385 gtk_widget_set_size_request(close_button, requisition.width + 4,
3386 requisition.height + 2);
3387 gtk_container_add(GTK_CONTAINER(close_button), close_image);
3389 gtk_widget_show (close_button);
3391 gtk_widget_hide (close_button);
3394 g_signal_connect(G_OBJECT(tab_clickable_area),
"button-press-event",
3395 G_CALLBACK(gnc_tab_clicked_cb), page);
3397 g_signal_connect_swapped (G_OBJECT (close_button),
"clicked",
3400 gtk_box_pack_start (GTK_BOX (tab_container), close_button, FALSE, FALSE, 0);
3401 gtk_widget_set_margin_end (GTK_WIDGET(close_button), 5);
3402 g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON, close_button);
3413 gnc_main_window_connect(window, page, tab_container,
label);
3429 GncMainWindow *window;
3438 if (!GNC_IS_MAIN_WINDOW (page->
window))
3441 window = GNC_MAIN_WINDOW (page->
window);
3444 g_warning(
"Page is not in a window.");
3448 gnc_main_window_disconnect(window, page);
3450 g_object_unref(page);
3453 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3456 if (window->window_quitting)
3462 window->just_plugin_prefs = TRUE;
3463 g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
3464 window->just_plugin_prefs = FALSE;
3465 g_list_free (plugins);
3468 gnc_main_window_remove_prefs (window);
3471 gtk_widget_destroy (GTK_WIDGET(window));
3488 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3500 const gchar *group_name,
3501 GSimpleActionGroup *group)
3503 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3504 g_return_if_fail (group_name !=
nullptr);
3505 g_return_if_fail (G_IS_SIMPLE_ACTION_GROUP(group));
3507 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
3508 G_ACTION_GROUP(group));
3513 update_menu_model (GncMainWindow *window,
const gchar *ui_filename,
3514 const gchar **ui_updates)
3517 GError *error =
nullptr;
3519 GtkBuilder *builder = gtk_builder_new ();
3520 GMenuModel *menu_model_part;
3521 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
3523 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3524 g_return_if_fail (ui_filename !=
nullptr);
3525 g_return_if_fail (ui_updates !=
nullptr);
3527 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3529 gtk_builder_set_translation_domain (builder, PROJECT_NAME);
3530 res_name = g_strconcat (GNUCASH_RESOURCE_PREFIX
"/", ui_filename, NULL);
3532 gtk_builder_add_from_resource (builder, res_name, &error);
3537 g_critical (
"Failed to load, Error %s", error->message);
3538 g_error_free (error);
3542 for (gint i = 0; ui_updates[i]; i++)
3544 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, ui_updates[i]);
3546 gsm->search_action_label =
nullptr;
3547 gsm->search_action_name = ui_updates[i];
3548 gsm->search_action_target =
nullptr;
3551 g_menu_insert_section (G_MENU(gsm->model), gsm->index, NULL, G_MENU_MODEL(menu_model_part));
3553 PERR(
"Could not find '%s' in menu model", ui_updates[i]);
3556 g_object_unref (builder);
3568 const gchar *group_name,
3569 GActionEntry *actions,
3571 const gchar **ui_updates,
3572 const gchar *ui_filename,
3576 GSimpleActionGroup *simple_action_group;
3578 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3579 g_return_if_fail (group_name !=
nullptr);
3580 g_return_if_fail (actions !=
nullptr);
3581 g_return_if_fail (n_actions > 0);
3584 data->window = window;
3585 data->data = user_data;
3587 simple_action_group = g_simple_action_group_new ();
3589 g_action_map_add_action_entries (G_ACTION_MAP(simple_action_group),
3594 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
3595 G_ACTION_GROUP(simple_action_group));
3598 update_menu_model (window, ui_filename, ui_updates);
3609 const gchar *group_name)
3611 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3612 g_return_if_fail (group_name !=
nullptr);
3614 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
nullptr);
3620 GAction *action =
nullptr;
3622 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3623 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3625 action = g_action_map_lookup_action (G_ACTION_MAP(window),
3633 const gchar *group_name,
3636 GAction *action =
nullptr;
3638 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3639 g_return_val_if_fail (group_name !=
nullptr,
nullptr);
3640 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3642 auto action_group = gtk_widget_get_action_group (GTK_WIDGET(window), group_name);
3645 action = g_action_map_lookup_action (G_ACTION_MAP(action_group),
action_name);
3655 GSimpleActionGroup *
3657 const gchar *group_name)
3659 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3660 g_return_val_if_fail (group_name !=
nullptr,
nullptr);
3662 auto action_group = gtk_widget_get_action_group (GTK_WIDGET(window), group_name);
3663 return (GSimpleActionGroup*)action_group;
3671 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3672 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3674 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3683 GtkWidget *menu_item;
3685 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3686 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3688 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3690 menu_item = GTK_WIDGET(g_hash_table_lookup (priv->display_item_hash,
action_name));
3696 g_hash_table_insert (priv->display_item_hash, g_strdup (
action_name), menu_item);
3707 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3709 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3719 const gchar *tooltip)
3722 gboolean found =
false;
3724 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
false);
3725 g_return_val_if_fail (
action_name !=
nullptr,
false);
3726 g_return_val_if_fail (
label !=
nullptr,
false);
3728 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3731 nullptr, _(
label),
nullptr, _(tooltip));
3743 const gchar **action_names,
3748 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3750 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3752 for (gint i = 0; action_names[i]; i++)
3759 PINFO(
"Found menu_item %p with action name '%s', seting vis to '%s'",
3760 menu_item, action_names[i], vis ?
"true" :
"false");
3761 gtk_widget_set_visible (menu_item, vis);
3764 PINFO(
"Did not find menu_item with action name '%s' to set vis '%s'",
3765 action_names[i], vis ?
"true" :
"false");
3769 PINFO(
"Found tool_item %p with action name '%s', seting vis to '%s'",
3770 tool_item, action_names[i], vis ?
"true" :
"false");
3771 gtk_widget_set_visible (tool_item, vis);
3774 PINFO(
"Did not find tool_item with action name '%s' to set vis '%s'",
3775 action_names[i], vis ?
"true" :
"false");
3786 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3787 g_return_if_fail (toolbar_labels !=
nullptr);
3789 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3796 gnc_main_window_update_toolbar (GncMainWindow *window,
GncPluginPage *page,
3797 const gchar *toolbar_qualifier)
3800 GtkBuilder *builder;
3803 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3804 g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
3806 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3812 gchar *toolbar_name;
3815 if (toolbar_qualifier)
3816 toolbar_name = g_strconcat (
"mainwin-toolbar-", toolbar_qualifier,
nullptr);
3818 toolbar_name = g_strdup (
"mainwin-toolbar");
3820 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder, toolbar_name);
3823 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder,
"mainwin-toolbar");
3825 g_object_set (priv->
toolbar,
"toolbar-style", GTK_TOOLBAR_BOTH, NULL);
3827 g_free (toolbar_name);
3835 GVariant *state = g_action_get_state (G_ACTION(action));
3836 gtk_widget_set_visible (priv->
toolbar, g_variant_get_boolean (state));
3837 g_variant_unref (state);
3847 const gchar **ui_updates)
3850 const gchar *plugin_page_actions_group_name;
3851 GtkBuilder *builder;
3852 const gchar *menu_qualifier;
3854 GMenuModel *menu_model_part;
3855 #ifdef MAC_INTEGRATION 3856 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
3858 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3859 g_return_if_fail (page !=
nullptr);
3860 g_return_if_fail (ui_updates !=
nullptr);
3862 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3873 if (!plugin_page_actions_group_name)
3879 if ((g_strcmp0 (priv->previous_plugin_page_name,
3880 plugin_page_actions_group_name) == 0) &&
3881 (g_strcmp0 (priv->previous_menu_qualifier,
3882 menu_qualifier) == 0))
3885 priv->previous_plugin_page_name = plugin_page_actions_group_name;
3886 priv->previous_menu_qualifier = menu_qualifier;
3888 gnc_main_window_update_toolbar (window, page, menu_qualifier);
3891 g_hash_table_remove_all (priv->display_item_hash);
3893 GNC_MENU_ATTRIBUTE_TEMPORARY);
3895 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
3896 for (gint i = 0; ui_updates[i]; i++)
3901 menu_name = g_strconcat (ui_updates[i],
"-", menu_qualifier,
nullptr);
3903 menu_name = g_strdup (ui_updates[i]);
3905 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, menu_name);
3907 if (!menu_model_part)
3908 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, ui_updates[i]);
3910 gsm->search_action_label =
nullptr;
3911 gsm->search_action_name = ui_updates[i];
3912 gsm->search_action_target =
nullptr;
3915 g_menu_insert_section (G_MENU(gsm->model), gsm->index,
3916 nullptr, G_MENU_MODEL(menu_model_part));
3918 PERR(
"Could not find '%s' in menu model", ui_updates[i]);
3928 #ifdef MAC_INTEGRATION 3929 gtkosx_application_sync_menubar (theApp);
3930 g_object_unref (theApp);
3933 g_signal_emit_by_name (window,
"menu_changed", page);
3940 gnc_main_window_update_tab_position (gpointer prefs, gchar *pref, gpointer user_data)
3942 GncMainWindow *window;
3943 GtkPositionType position = GTK_POS_TOP;
3948 g_return_if_fail (GNC_IS_MAIN_WINDOW(user_data));
3950 window = GNC_MAIN_WINDOW(user_data);
3952 ENTER (
"window %p", window);
3961 position = GTK_POS_BOTTOM;
3966 position = GTK_POS_LEFT;
3971 position = GTK_POS_RIGHT;
3975 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3976 gtk_notebook_set_tab_pos (GTK_NOTEBOOK(priv->
notebook), position);
3978 action = g_action_map_lookup_action (G_ACTION_MAP(window),
3979 "ViewTabPositionAction");
3981 g_signal_handlers_block_by_func (G_OBJECT(action),
3982 (gpointer)gnc_main_window_cmd_view_tab_position,
3984 g_action_change_state (G_ACTION(action), g_variant_new_int32 (item));
3985 g_signal_handlers_unblock_by_func (G_OBJECT(action),
3986 (gpointer)gnc_main_window_cmd_view_tab_position,
3989 gnc_main_window_update_tab_width (
nullptr, (
char*)GNC_PREF_TAB_WIDTH,
nullptr);
3998 gnc_main_window_update_edit_actions_sensitivity (GncMainWindow *window, gboolean hide)
4002 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));
4004 gboolean can_copy =
false, can_cut =
false, can_paste =
false;
4006 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4009 if (page && GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)
4011 (GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)(page, hide);
4015 if (GTK_IS_EDITABLE (widget))
4017 gboolean has_selection;
4019 has_selection = gtk_editable_get_selection_bounds
4020 (GTK_EDITABLE (widget),
nullptr,
nullptr);
4022 can_copy = has_selection;
4023 can_cut = has_selection;
4026 else if (GTK_IS_TEXT_VIEW (widget))
4028 gboolean has_selection;
4029 GtkTextBuffer *text_buffer;
4031 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4032 has_selection = gtk_text_buffer_get_selection_bounds
4033 (text_buffer,
nullptr,
nullptr);
4035 can_copy = has_selection;
4036 can_cut = has_selection;
4041 #ifdef ORIGINAL_EPIPHANY_CODE 4043 can_copy = can_cut = can_paste =
true;
4047 can_copy = can_cut = can_paste =
false;
4051 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_copy);
4054 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_cut);
4057 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_paste);
4061 gnc_main_window_enable_edit_actions_sensitivity (GncMainWindow *window)
4066 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4069 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4072 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4077 gnc_main_window_edit_menu_show_cb (GtkWidget *menu,
4078 GncMainWindow *window)
4080 gnc_main_window_update_edit_actions_sensitivity (window, FALSE);
4084 gnc_main_window_edit_menu_hide_cb (GtkWidget *menu,
4085 GncMainWindow *window)
4087 gnc_main_window_enable_edit_actions_sensitivity (window);
4091 gnc_main_window_init_menu_updaters (GncMainWindow *window)
4093 GtkWidget *edit_menu_item, *edit_menu;
4097 edit_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM(edit_menu_item));
4099 g_signal_connect (edit_menu,
"show",
4100 G_CALLBACK(gnc_main_window_edit_menu_show_cb), window);
4101 g_signal_connect (edit_menu,
"hide",
4102 G_CALLBACK(gnc_main_window_edit_menu_hide_cb), window);
4107 gnc_main_window_page_focus_in (GtkWidget *widget, GdkEvent *event,
4110 auto window{
static_cast<GncMainWindow *
>(user_data)};
4113 g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
4118 gnc_main_window_get_redirect (GncMainWindow *window,
const gchar *
action_name)
4121 GAction *action =
nullptr;
4122 const gchar *group_name;
4124 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window),
nullptr);
4125 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
4127 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4141 PINFO(
"Redirect action is %p for action anme '%s' and group_name '%s'",
4147 main_window_realize_cb (GtkWidget *widget, gpointer user_data)
4149 GncMainWindow *window = (GncMainWindow*)user_data;
4156 g_signal_emit_by_name (window,
"menu_changed",
nullptr);
4160 gnc_main_window_setup_window (GncMainWindow *window)
4163 GtkWidget *main_vbox;
4164 GtkBuilder *builder;
4165 GncPluginManager *manager;
4167 GError *error =
nullptr;
4173 g_signal_connect (G_OBJECT (window),
"delete-event",
4174 G_CALLBACK (gnc_main_window_delete_event), window);
4177 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4178 gtk_box_set_homogeneous (GTK_BOX (main_vbox), FALSE);
4179 gtk_widget_show (main_vbox);
4180 gtk_container_add (GTK_CONTAINER (window), main_vbox);
4182 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4183 priv->
menu_dock = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4184 gtk_box_set_homogeneous (GTK_BOX (priv->
menu_dock), FALSE);
4186 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
menu_dock,
4189 priv->
notebook = gtk_notebook_new ();
4190 g_object_set(G_OBJECT(priv->
notebook),
4192 "enable-popup", TRUE,
4195 g_signal_connect (G_OBJECT (priv->
notebook),
"switch-page",
4196 G_CALLBACK (gnc_main_window_switch_page), window);
4197 g_signal_connect (G_OBJECT (priv->
notebook),
"page-reordered",
4198 G_CALLBACK (gnc_main_window_page_reordered), window);
4199 g_signal_connect (G_OBJECT (priv->
notebook),
"focus-in-event",
4200 G_CALLBACK (gnc_main_window_page_focus_in), window);
4201 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
notebook,
4206 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
statusbar,
4210 gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR(priv->
progressbar), TRUE);
4211 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(priv->
progressbar),
" ");
4215 gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(priv->
progressbar),
4218 builder = gtk_builder_new ();
4219 gtk_builder_set_translation_domain (builder, PROJECT_NAME);
4220 gtk_builder_add_from_resource (builder, GNUCASH_RESOURCE_PREFIX
"/gnc-main-window.ui", &error);
4224 g_critical (
"Failed to load, Error %s", error->message);
4225 g_error_free (error);
4229 g_action_map_add_action_entries (G_ACTION_MAP(window),
4234 priv->
menubar_model = (GMenuModel *)gtk_builder_get_object (builder,
"mainwin-menu");
4237 gtk_widget_show (GTK_WIDGET(priv->
menubar));
4239 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder,
"mainwin-toolbar");
4240 g_object_set (priv->
toolbar,
"toolbar-style", GTK_TOOLBAR_BOTH, NULL);
4241 gtk_container_add (GTK_CONTAINER(priv->
menu_dock), GTK_WIDGET(priv->
toolbar));
4242 gtk_widget_show (GTK_WIDGET(priv->
toolbar));
4244 g_object_unref (builder);
4247 initially_insensitive_actions,
4250 always_insensitive_actions,
4256 gtk_widget_insert_action_group (GTK_WIDGET(window),
"mainwin",
4257 G_ACTION_GROUP(window));
4260 GNC_PREF_TAB_POSITION_TOP,
4261 (gpointer)gnc_main_window_update_tab_position,
4264 GNC_PREF_TAB_POSITION_BOTTOM,
4265 (gpointer)gnc_main_window_update_tab_position,
4268 GNC_PREF_TAB_POSITION_LEFT,
4269 (gpointer)gnc_main_window_update_tab_position,
4272 GNC_PREF_TAB_POSITION_RIGHT,
4273 (gpointer)gnc_main_window_update_tab_position,
4275 gnc_main_window_update_tab_position (
nullptr,
nullptr, window);
4277 gnc_main_window_init_menu_updaters (window);
4281 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4284 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4287 if (!gnc_prefs_is_extra_enabled())
4290 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4296 g_list_foreach (plugins, gnc_main_window_add_plugin, window);
4297 g_list_free (plugins);
4299 g_signal_connect (G_OBJECT (manager),
"plugin-added",
4300 G_CALLBACK (gnc_main_window_plugin_added), window);
4301 g_signal_connect (G_OBJECT (manager),
"plugin-removed",
4302 G_CALLBACK (gnc_main_window_plugin_removed), window);
4305 g_signal_connect (G_OBJECT(window),
"realize",
4306 G_CALLBACK(main_window_realize_cb), window);
4311 #ifdef MAC_INTEGRATION 4320 gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data)
4331 gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window)
4334 gnc_main_window_quit (window);
4339 can_activate_cb(GtkWidget *widget, guint signal_id, gpointer data)
4346 gnc_quartz_set_menu (GncMainWindow* window)
4349 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
4350 GtkWidget *item =
nullptr;
4351 GClosure *quit_closure;
4353 gtk_widget_hide (priv->
menubar);
4354 gtk_widget_set_no_show_all (priv->
menubar,
true);
4356 gtkosx_application_set_menu_bar (theApp, GTK_MENU_SHELL(priv->
menubar));
4361 gtk_widget_hide (GTK_WIDGET(item));
4363 quit_closure = g_cclosure_new (G_CALLBACK (gnc_quartz_should_quit),
4365 gtk_accel_group_connect (priv->
accel_group,
'q', GDK_META_MASK,
4366 GTK_ACCEL_MASK, quit_closure);
4373 gtk_widget_hide (item);
4374 gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET(item), 0);
4381 gtk_widget_hide (GTK_WIDGET(item));
4382 gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET(item), 2);
4388 gtkosx_application_set_help_menu (theApp, GTK_MENU_ITEM(item));
4392 gtkosx_application_set_window_menu (theApp, GTK_MENU_ITEM(item));
4394 g_signal_connect (theApp,
"NSApplicationBlockTermination",
4395 G_CALLBACK(gnc_quartz_should_quit), window);
4397 g_signal_connect (priv->
menubar,
"can-activate-accel",
4398 G_CALLBACK (can_activate_cb),
nullptr);
4400 gtkosx_application_set_use_quartz_accelerators (theApp, FALSE);
4401 g_object_unref (theApp);
4403 #endif //MAC_INTEGRATION 4420 gnc_main_window_show_summarybar (GncMainWindow *window, GAction *action)
4425 if (action ==
nullptr)
4426 action = g_action_map_lookup_action (G_ACTION_MAP(window),
4427 "ViewSummaryAction");
4428 if (action ==
nullptr)
4431 state = g_action_get_state (G_ACTION(action));
4433 visible = g_variant_get_boolean (state);
4435 g_variant_unref (state);
4450 gnc_main_window_switch_page (GtkNotebook *notebook,
4451 gpointer *notebook_page,
4453 GncMainWindow *window)
4460 ENTER(
"Notebook %p, page, %p, index %d, window %p",
4461 notebook, notebook_page, pos, window);
4462 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4464 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4468 gnc_plugin_page_unselected (page);
4471 child = gtk_notebook_get_nth_page (notebook, pos);
4483 if (page !=
nullptr)
4487 visible = gnc_main_window_show_summarybar (window,
nullptr);
4491 gnc_plugin_page_selected (page);
4492 gnc_window_update_status (GNC_WINDOW(window), page);
4500 multiple_page_actions,
4503 gnc_main_window_update_title(window);
4504 #ifndef MAC_INTEGRATION 4505 gnc_main_window_update_menu_item(window);
4507 g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
4518 gnc_main_window_page_reordered (GtkNotebook *notebook,
4521 GncMainWindow *window)
4527 ENTER(
"Notebook %p, child %p, index %d, window %p",
4528 notebook, child, pos, window);
4529 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4533 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4539 if (!old_link)
return;
4550 gnc_main_window_plugin_added (GncPlugin *manager,
4552 GncMainWindow *window)
4554 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4555 g_return_if_fail (GNC_IS_PLUGIN (plugin));
4561 gnc_main_window_plugin_removed (GncPlugin *manager,
4563 GncMainWindow *window)
4565 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4566 g_return_if_fail (GNC_IS_PLUGIN (plugin));
4574 gnc_main_window_cmd_redirect (GSimpleAction *simple,
4575 GVariant *parameter,
4578 GncMainWindow *window = (GncMainWindow*)user_data;
4579 GAction *redirect_action;
4581 PINFO(
"Redirect action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4583 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4585 if (redirect_action)
4587 PINFO(
"Found action %p", redirect_action);
4588 g_action_activate (redirect_action,
nullptr);
4594 gnc_main_window_cmd_page_setup (GSimpleAction *simple,
4595 GVariant *parameter,
4598 GncMainWindow *window = (GncMainWindow*)user_data;
4599 GtkWindow *gtk_window;
4601 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
4603 gtk_window = gnc_window_get_gtk_window(GNC_WINDOW(window));
4610 QofBook *book = gnc_get_current_book ();
4611 gboolean use_split_action_for_num_before =
4613 gint use_read_only_threshold_before =
4615 gboolean use_split_action_for_num_after;
4616 gint use_read_only_threshold_after;
4617 gboolean return_val = FALSE;
4618 GList *results =
nullptr, *iter;
4620 if (!options)
return return_val;
4623 for (iter = results; iter; iter = iter->next)
4631 gtk_dialog_run(GTK_DIALOG(dialog));
4632 gtk_widget_destroy(dialog);
4633 g_free (iter->data);
4635 g_list_free (results);
4636 qof_book_begin_edit (book);
4638 use_split_action_for_num_after =
4642 book->cached_num_days_autoreadonly_isvalid = FALSE;
4645 if (use_split_action_for_num_before != use_split_action_for_num_after)
4648 use_split_action_for_num_after);
4651 if (use_read_only_threshold_before != use_read_only_threshold_after)
4654 qof_book_commit_edit (book);
4662 auto options{
static_cast<GncOptionDB *
>(user_data)};
4664 if (!options)
return;
4667 gnc_gui_refresh_all ();
4674 auto options{
static_cast<GncOptionDB *
>(user_data)};
4686 gnc_suspend_gui_refresh ();
4693 GNC_FEATURE_NUM_FIELD_SOURCE);
4695 gnc_book_option_num_field_source_change (num_action);
4696 gnc_resume_gui_refresh ();
4700 show_handler (
const char *class_name, gint component_id,
4701 gpointer user_data, gpointer iter_data)
4708 auto widget = optwin->get_widget();
4709 gtk_window_present(GTK_WINDOW(widget));
4716 auto book = gnc_get_current_book ();
4725 if (gnc_forall_gui_components(DIALOG_BOOK_OPTIONS_CM_CLASS,
4726 show_handler,
nullptr))
4731 (title ? title : _(
"Book Options")),
4732 DIALOG_BOOK_OPTIONS_CM_CLASS, parent);
4733 optionwin->build_contents(options);
4734 optionwin->set_book_help_cb();
4735 optionwin->set_apply_cb(gnc_book_options_dialog_apply_cb,
4737 optionwin->set_close_cb ( gnc_book_options_dialog_close_cb,
4741 return optionwin->get_widget();
4745 gnc_main_window_cmd_file_properties (GSimpleAction *simple,
4746 GVariant *parameter,
4749 GncMainWindow *window = (GncMainWindow*)user_data;
4754 gnc_main_window_cmd_file_close (GSimpleAction *simple,
4755 GVariant *parameter,
4758 GncMainWindow *window = (GncMainWindow*)user_data;
4762 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
4764 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4770 gnc_main_window_cmd_file_quit (GSimpleAction *simple,
4771 GVariant *parameter,
4774 GncMainWindow *window = (GncMainWindow*)user_data;
4778 gnc_main_window_quit(window);
4782 gnc_main_window_cmd_edit_cut (GSimpleAction *simple,
4783 GVariant *parameter,
4786 GncMainWindow *window = (GncMainWindow*)user_data;
4787 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4788 GAction *redirect_action;
4790 PINFO(
"Copy action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4792 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4794 if (redirect_action)
4796 PINFO(
"Found action %p", redirect_action);
4797 g_action_activate (redirect_action,
nullptr);
4801 if (GTK_IS_EDITABLE(widget))
4803 gtk_editable_cut_clipboard (GTK_EDITABLE(widget));
4805 else if (GTK_IS_TEXT_VIEW(widget))
4807 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4808 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(widget),
4809 GDK_SELECTION_CLIPBOARD);
4810 gboolean editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(widget));
4813 gtk_text_buffer_cut_clipboard (text_buffer, clipboard, editable);
4818 gnc_main_window_cmd_edit_copy (GSimpleAction *simple,
4819 GVariant *parameter,
4822 GncMainWindow *window = (GncMainWindow*)user_data;
4823 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4824 GAction *redirect_action;
4826 PINFO(
"Copy action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4828 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4830 if (redirect_action)
4832 PINFO(
"Found action %p", redirect_action);
4833 g_action_activate (redirect_action,
nullptr);
4837 if (GTK_IS_EDITABLE(widget))
4839 gtk_editable_copy_clipboard (GTK_EDITABLE(widget));
4841 else if (GTK_IS_TEXT_VIEW(widget))
4843 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4844 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(widget),
4845 GDK_SELECTION_CLIPBOARD);
4847 gtk_text_buffer_copy_clipboard (text_buffer, clipboard);
4852 gnc_main_window_cmd_edit_paste (GSimpleAction *simple,
4853 GVariant *parameter,
4856 GncMainWindow *window = (GncMainWindow*)user_data;
4857 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4858 GAction *redirect_action;
4860 PINFO(
"Paste action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4862 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4864 if (redirect_action)
4866 PINFO(
"Found action %p", redirect_action);
4867 g_action_activate (redirect_action,
nullptr);
4871 if (GTK_IS_EDITABLE(widget))
4873 gtk_editable_paste_clipboard (GTK_EDITABLE(widget));
4875 else if (GTK_IS_TEXT_VIEW(widget))
4877 auto clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
4881 auto text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4882 auto editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(widget));
4883 gtk_text_buffer_paste_clipboard (text_buffer, clipboard,
nullptr,
4890 gnc_main_window_cmd_edit_preferences (GSimpleAction *simple,
4891 GVariant *parameter,
4894 GncMainWindow *window = (GncMainWindow*)user_data;
4899 gnc_main_window_cmd_view_refresh (GSimpleAction *simple,
4900 GVariant *parameter,
4906 gnc_main_window_cmd_actions_reset_warnings (GSimpleAction *simple,
4907 GVariant *parameter,
4910 GncMainWindow *window = (GncMainWindow*)user_data;
4911 gnc_reset_warnings_dialog(GTK_WINDOW(window));
4915 gnc_main_window_cmd_actions_rename_page (GSimpleAction *simple,
4916 GVariant *parameter,
4919 GncMainWindow *window = (GncMainWindow*)user_data;
4922 GtkWidget *
label, *entry;
4925 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4929 LEAVE(
"No current page");
4933 if (!main_window_find_tab_items(window, page, &
label, &entry))
4935 LEAVE(
"can't find required widgets");
4939 gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(
label)));
4940 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
4941 gtk_widget_hide(
label);
4942 gtk_widget_show(entry);
4943 gtk_widget_grab_focus(entry);
4944 LEAVE(
"opened for editing");
4948 gnc_main_window_cmd_view_toolbar (GSimpleAction *simple,
4949 GVariant *parameter,
4952 GncMainWindow *window = (GncMainWindow*)user_data;
4954 GVariant *state = g_action_get_state (G_ACTION(simple));
4956 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4958 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!g_variant_get_boolean (state)));
4960 if (!g_variant_get_boolean (state))
4961 gtk_widget_show (priv->
toolbar);
4963 gtk_widget_hide (priv->
toolbar);
4965 g_variant_unref (state);
4969 gnc_main_window_cmd_view_summary (GSimpleAction *simple,
4970 GVariant *parameter,
4973 GncMainWindow *window = (GncMainWindow*)user_data;
4978 visible = gnc_main_window_show_summarybar (window, G_ACTION(simple));
4980 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!
visible));
4990 gnc_main_window_cmd_view_statusbar (GSimpleAction *simple,
4991 GVariant *parameter,
4994 GncMainWindow *window = (GncMainWindow*)user_data;
4996 GVariant *state = g_action_get_state (G_ACTION(simple));
4998 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5000 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!g_variant_get_boolean (state)));
5002 if (!g_variant_get_boolean (state))
5007 g_variant_unref (state);
5011 gnc_main_window_cmd_window_new (GSimpleAction *simple,
5015 GncMainWindow *new_window;
5020 gtk_widget_show(GTK_WIDGET(new_window));
5025 gnc_main_window_cmd_window_move_page (GSimpleAction *simple,
5029 GncMainWindow *window = (GncMainWindow*)user_data;
5031 GncMainWindow *new_window;
5033 GtkNotebook *notebook;
5034 GtkWidget *tab_widget, *menu_widget;
5036 ENTER(
"action %p, window %p", simple, window);
5039 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5043 LEAVE(
"invalid page");
5048 LEAVE(
"invalid notebook_page");
5052 #ifndef MAC_INTEGRATION 5054 gnc_info_dialog (GTK_WINDOW(window),
"%s",
5055 _(
"The maximum number of window menu entries reached, no more entries will be added."));
5058 notebook = GTK_NOTEBOOK (priv->
notebook);
5059 tab_widget = gtk_notebook_get_tab_label (notebook, page->
notebook_page);
5060 menu_widget = gtk_notebook_get_menu_label (notebook, page->
notebook_page);
5067 g_object_ref(tab_widget);
5068 g_object_ref(menu_widget);
5070 gnc_main_window_disconnect(window, page);
5074 gtk_widget_show(GTK_WIDGET(new_window));
5077 gnc_main_window_connect (new_window, page, tab_widget, menu_widget);
5081 g_object_unref(menu_widget);
5082 g_object_unref(tab_widget);
5083 g_object_unref(page);
5086 DEBUG(
"Moved page %p from window %p to new window %p",
5087 page, window, new_window);
5088 DEBUG(
"Old window current is %p, new window current is %p",
5091 LEAVE(
"page moved");
5095 gnc_main_window_cmd_view_tab_position (GSimpleAction *simple,
5096 GVariant *parameter,
5099 gint item = g_variant_get_int32 (parameter);
5101 g_action_change_state (G_ACTION(simple), parameter);
5103 if (item < 0 || item > 3)
5106 if (item != 0 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_TOP))
5109 if (item != 1 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_BOTTOM))
5112 if (item != 2 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT))
5115 if (item != 3 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_RIGHT))
5139 #ifndef MAC_INTEGRATION 5141 gnc_main_window_cmd_window_raise (GSimpleAction *simple,
5142 GVariant *parameter,
5145 GncMainWindow *window = (GncMainWindow*)user_data;
5146 GncMainWindow *new_window;
5149 g_return_if_fail (G_IS_SIMPLE_ACTION(simple));
5150 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
5152 item = g_variant_get_int32 (parameter);
5154 ENTER(
"action %p, window %p, item %d", simple, window, item);
5156 g_action_change_state (G_ACTION(simple), parameter);
5158 new_window =
static_cast<GncMainWindow*
>(g_list_nth_data (active_windows, item));
5159 gtk_window_present (GTK_WINDOW(new_window));
5163 g_idle_add ((GSourceFunc)gnc_main_window_update_radio_button, window);
5169 gnc_main_window_cmd_help_tutorial (GSimpleAction *simple,
5173 GncMainWindow *window = (GncMainWindow*)user_data;
5178 gnc_main_window_cmd_help_contents (GSimpleAction *simple,
5182 GncMainWindow *window = (GncMainWindow*)user_data;
5196 get_file (
const gchar *partial)
5198 gchar *filename, *text =
nullptr;
5202 if (filename && g_file_get_contents(filename, &text, &length,
nullptr))
5226 get_file_strsplit (
const gchar *partial)
5228 gchar *text, **lines;
5230 text = get_file(partial);
5234 lines = g_strsplit_set(text,
"\r\n", -1);
5245 url_signal_cb (GtkAboutDialog *dialog, gchar *uri, gpointer data)
5252 link_button_cb (GtkLinkButton *button, gpointer user_data)
5254 const gchar *uri = gtk_link_button_get_uri (button);
5255 gchar *escaped_uri = g_uri_escape_string (uri,
":/.\\",
true);
5257 g_free (escaped_uri);
5262 add_about_paths (GtkDialog *dialog)
5270 PWARN(
"Unable to find AboutDialog 'page_vbox' Widget");
5274 grid = gtk_grid_new ();
5276 for (
const auto& ep : gnc_list_all_paths ())
5278 gchar *env_name = g_strconcat (ep.env_name,
":", NULL);
5279 GtkWidget *
label = gtk_label_new (env_name);
5281 gchar *display_uri = gnc_doclink_get_unescaped_just_uri (uri);
5282 GtkWidget *widget = gtk_link_button_new_with_label (uri, display_uri);
5284 gtk_grid_attach (GTK_GRID(grid),
label, 0, i, 1, 1);
5285 gtk_widget_set_halign (
label, GTK_ALIGN_END);
5286 gtk_grid_attach (GTK_GRID(grid), widget, 1, i, 1, 1);
5287 gtk_widget_set_halign (widget, GTK_ALIGN_START);
5288 gtk_widget_set_margin_top (widget, 0);
5289 gtk_widget_set_margin_bottom (widget, 0);
5293 GtkWidget *mod_lab = gtk_label_new (_(
"(user modifiable)"));
5294 gtk_grid_attach (GTK_GRID(grid), mod_lab, 2, i, 1, 1);
5295 gtk_widget_show (mod_lab);
5297 g_signal_connect (widget,
"activate-link",
5298 G_CALLBACK(link_button_cb), dialog);
5301 g_free (display_uri);
5304 gtk_container_add_with_properties (GTK_CONTAINER(page_vbox), grid,
5305 "position", 1, NULL);
5306 gtk_widget_show_all (grid);
5312 gnc_main_window_cmd_help_about (GSimpleAction *simple,
5316 GncMainWindow *window = (GncMainWindow*)user_data;
5318 gchar *copyright = g_strdup_printf(_(
"Copyright © 1997-%s The GnuCash contributors."),
5320 gchar **authors = get_file_strsplit(
"AUTHORS");
5321 gchar **documenters = get_file_strsplit(
"DOCUMENTERS");
5322 gchar *license = get_file(
"LICENSE");
5323 GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
5324 GdkPixbuf *logo = gtk_icon_theme_load_icon (icon_theme,
5327 GTK_ICON_LOOKUP_USE_BUILTIN,
5329 gchar *version = g_strdup_printf (
"%s: %s\n%s: %s\nFinance::Quote: %s",
5331 _(
"Build ID"), gnc_build_id(),
5335 GtkDialog *dialog = GTK_DIALOG (gtk_about_dialog_new ());
5336 g_object_set (G_OBJECT (dialog),
5338 "documenters", documenters,
5339 "comments", _(
"Accounting for personal and small business finance."),
5340 "copyright", copyright,
5348 "translator-credits", _(
"translator-credits"),
5350 "website", PACKAGE_URL,
5351 "website-label", _(
"Visit the GnuCash website."),
5359 g_strfreev(documenters);
5361 g_strfreev(authors);
5362 g_object_unref (logo);
5363 g_signal_connect (dialog,
"activate-link",
5364 G_CALLBACK (url_signal_cb),
nullptr);
5367 add_about_paths (dialog);
5370 gtk_window_set_resizable(GTK_WINDOW (dialog), TRUE);
5372 gtk_window_set_transient_for (GTK_WINDOW (dialog),
5373 GTK_WINDOW (window));
5374 gtk_dialog_run (dialog);
5375 gtk_widget_destroy (GTK_WIDGET (dialog));
5387 #ifdef MAC_INTEGRATION 5388 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
5390 for (window_iter = active_windows; window_iter !=
nullptr; window_iter = window_iter->next)
5392 gtk_widget_show(GTK_WIDGET(window_iter->data));
5394 #ifdef MAC_INTEGRATION 5395 g_signal_connect(theApp,
"NSApplicationWillTerminate",
5396 G_CALLBACK(gnc_quartz_shutdown),
nullptr);
5397 gtkosx_application_ready(theApp);
5398 g_object_unref (theApp);
5405 GtkWidget *toplevel;
5410 toplevel = gtk_widget_get_toplevel (widget);
5411 if (toplevel && GTK_IS_WINDOW (toplevel))
5412 return GTK_WINDOW (toplevel);
5423 while (toplevel && !GNC_IS_MAIN_WINDOW (toplevel))
5424 toplevel = gtk_window_get_transient_for(toplevel);
5429 for (window = active_windows; window; window = window->next)
5430 if (gtk_window_is_active (GTK_WINDOW (window->data)))
5431 return static_cast<GtkWindow*
>(window->data);
5433 for (window = active_windows; window; window = window->next)
5434 if (gtk_widget_get_mapped (GTK_WIDGET(window->data)))
5435 return static_cast<GtkWindow*>(window->data);
5447 gnc_main_window_get_gtk_window (GncWindow *window)
5449 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window),
nullptr);
5450 return GTK_WINDOW(window);
5460 gnc_main_window_get_statusbar (GncWindow *window_in)
5463 GncMainWindow *window;
5465 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in),
nullptr);
5467 window = GNC_MAIN_WINDOW(window_in);
5468 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5479 gnc_main_window_get_progressbar (GncWindow *window_in)
5482 GncMainWindow *window;
5484 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in),
nullptr);
5486 window = GNC_MAIN_WINDOW(window_in);
5487 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5498 gnc_main_window_get_menubar (GncWindow *window)
5502 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5504 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5515 gnc_main_window_get_toolbar (GncWindow *window)
5519 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5521 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5532 gnc_main_window_get_menubar_model (GncWindow *window)
5536 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5538 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5548 static GtkAccelGroup *
5549 gnc_main_window_get_accel_group (GncWindow *window)
5553 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5555 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5565 gnc_window_main_window_init (GncWindowInterface *iface)
5567 iface->get_gtk_window = gnc_main_window_get_gtk_window;
5568 iface->get_statusbar = gnc_main_window_get_statusbar;
5569 iface->get_progressbar = gnc_main_window_get_progressbar;
5570 iface->get_menubar = gnc_main_window_get_menubar;
5571 iface->get_toolbar = gnc_main_window_get_toolbar;
5572 iface->get_menubar_model = gnc_main_window_get_menubar_model;
5573 iface->get_accel_group = gnc_main_window_get_accel_group;
5585 gncwin = GNC_WINDOW(window);
5586 gnc_window_set_progressbar_window(gncwin);
5605 GtkBuilder *builder;
5606 GMenuModel *menu_model;
5608 const gchar *menu_qualifier;
5609 gchar *popup_menu_name;
5610 GncWindow* gnc_window;
5611 GtkWidget *statusbar;
5613 g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
5615 ENTER(
"page %p, event %p", page, event);
5617 gnc_window = GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window);
5619 statusbar = gnc_window_get_statusbar (gnc_window);
5625 if (!menu_qualifier)
5628 if (builder ==
nullptr)
5630 LEAVE(
"no builder");
5635 popup_menu_name = g_strconcat (
"mainwin-popup-", menu_qualifier,
nullptr);
5637 popup_menu_name = g_strdup (
"mainwin-popup");
5639 menu_model = (GMenuModel *)gtk_builder_get_object (builder, popup_menu_name);
5642 menu_model = (GMenuModel *)gtk_builder_get_object (builder,
"mainwin-popup");
5644 menu = gtk_menu_new_from_model (menu_model);
5655 gtk_menu_attach_to_widget (GTK_MENU(menu), GTK_WIDGET(page->
window),
nullptr);
5656 gtk_menu_popup_at_pointer (GTK_MENU(menu), (GdkEvent *) event);
5658 g_free (popup_menu_name);
5681 ENTER(
"widget %p, page %p", widget, page);
5682 do_popup_menu(page,
nullptr);
5694 GdkEventButton *event,
5697 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
5699 ENTER(
"widget %p, event %p, page %p", whatever, event, page);
5701 if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
5703 do_popup_menu(page, event);
5704 LEAVE(
"menu shown");
5708 LEAVE(
"other click");
5716 for (
auto tmp = active_windows; tmp; tmp = g_list_next(tmp))
5719 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), sensitive);
5728 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5730 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5736 gnc_main_window_just_plugin_prefs (GncMainWindow* window)
5738 return window->just_plugin_prefs;
Holds all of the options for a book, report, or stylesheet, organized by GncOptionSections.
void gnc_preferences_dialog(GtkWindow *parent)
This function creates the preferences dialog and presents it to the user.
GncPluginPage * gnc_plugin_page_recreate_page(GtkWidget *window, const gchar *page_type, GKeyFile *key_file, const gchar *page_group)
This function looks up a specific plugin type by name, and then calls a plugin specific function to c...
GtkWidget * statusbar
A pointer to the status bar at the bottom edge of the window.
Functions to load, save and get gui state.
void gnc_menubar_model_remove_items_with_attrib(GMenuModel *menu_model, const gchar *attrib)
Remove GMenuModel entries based on having an attribute value equal to attrib, it does not matter what...
gboolean gnc_plugin_page_has_books(GncPluginPage *page)
Query a page to see if it has a reference to any book.
gboolean gnc_plugin_page_get_use_new_window(GncPluginPage *page)
Retrieve the "use new window" setting associated with this page.
void gnc_option_db_clean(GncOptionDB *odb)
Reset all ui_items to the option value.
gboolean gnc_plugin_page_finish_pending(GncPluginPage *page)
Tell a page to finish any outstanding activities.
void gnc_main_window_restore_all_windows(const GKeyFile *keyfile)
Restore the persistent state of all windows.
void gnc_main_window_update_menu_and_toolbar(GncMainWindow *window, GncPluginPage *page, const gchar **ui_updates)
Update the main window menu with the placeholders listed in ui_updates and load the page specific too...
void qof_book_load_options(QofBook *book, GncOptionLoad load_cb, GncOptionDB *odb)
Load a GncOptionsDB from KVP data.
GtkApplicationWindow gtk_application_window
The parent object for a main window.
void gnc_plugin_page_destroy_widget(GncPluginPage *plugin_page)
Destroy the display widget that corresponds to this plugin.
GtkAccelGroup * accel_group
The accelerator group for the window.
The instance data structure for a content plugin.
void qof_book_set_dirty_cb(QofBook *book, QofBookDirtyCB cb, gpointer user_data)
Set the function to call when a book transitions from clean to dirty, or vice versa.
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
gboolean gnc_main_window_button_press_cb(GtkWidget *whatever, GdkEventButton *event, GncPluginPage *page)
Callback function invoked when the user clicks in the content of any Gnucash window.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Register a callback that gets triggered when the given preference changes.
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
utility functions for the GnuCash UI
#define PINFO(format, args...)
Print an informational note.
void gnc_main_window_set_vis_of_items_by_action(GncMainWindow *window, const gchar **action_names, gboolean vis)
Show or hide menu and toolbar items based on a NULL terminated list of action names.
functions to query various version related strings that were set at build time.
void gnc_plugin_page_merge_actions(GncPluginPage *page)
Add the actions for a content page to the specified window.
QofBackendError
The errors that can be reported to the GUI & other front-end users.
void gnc_main_window_menu_add_accelerator_keys(GncMainWindow *window)
Scan the main window menu and add accelerator keys to main window accelerator group.
const gchar * gnc_plugin_page_get_page_long_name(GncPluginPage *page)
Retrieve the long name of this page.
gulong gnc_prefs_get_reg_negative_color_pref_id(void)
Get and Set registered preference id for register negative_color_pref.
void gnc_gobject_tracking_forget(GObject *object)
Tell gnucash to remember this object in the database.
time64 qof_book_get_session_dirty_time(const QofBook *book)
Retrieve the earliest modification time on the book.
GMenuModel * gnc_main_window_get_menu_model(GncMainWindow *window)
Return the GMenuModel for the main window menu bar.
gboolean gnc_menubar_model_find_item(GMenuModel *menu_model, GncMenuModelSearch *gsm)
Find a GtkMenu item from the action name.
This data structure allows the passing of the tab width and whether the tab layout is on the left or ...
void gnc_main_window_init_short_names(GncMainWindow *window, GncToolBarShortNames *toolbar_labels)
Update the labels of the toolbar items with short names.
#define DEBUG(format, args...)
Print a debugging message.
const gchar * gnc_plugin_page_get_page_name(GncPluginPage *page)
Retrieve the name of this page.
gint qof_book_get_num_days_autoreadonly(const QofBook *book)
Returns the number of days for auto-read-only transactions.
GMenuModel * menubar_model
The menubar_model.
Functions that are supported by all types of windows.
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.
gboolean qof_book_use_split_action_for_num_field(const QofBook *book)
Returns TRUE if this book uses split action field as the 'Num' field, FALSE if it uses transaction nu...
GSimpleActionGroup * gnc_plugin_page_get_action_group(GncPluginPage *page)
Retrieve the GSimpleActionGroup object associated with this page.
GtkWidget * toolbar
The toolbar.
GKeyFile helper routines.
GtkBuilder * gnc_plugin_page_get_builder(GncPluginPage *page)
Retrieve the GtkBuilder object associated with this page.
gboolean restoring_pages
Set when restoring plugin pages.
gint pos[2]
Array for window position.
Plugin management functions for the GnuCash UI.
GtkWidget * gnc_main_window_menu_find_menu_item(GncMainWindow *window, const gchar *action_name)
Find the menu item with the given action name for the window specified.
GtkWidget * window
The window that contains the display widget for this plugin.
gint event_handler_id
The identifier for this window's engine event handler.
gchar * gnc_uri_get_path(const gchar *uri)
Extracts the path part from a uri.
gboolean window_quitting
Set to TRUE when quitting from this window.
const gchar * gnc_plugin_page_get_page_color(GncPluginPage *page)
Retrieve the color of this page.
gboolean gnc_main_window_is_restoring_pages(GncMainWindow *window)
Check if the main window is restoring the plugin pages.
GtkWidget * gnc_book_options_dialog_cb(gboolean modal, gchar *title, GtkWindow *parent)
Opens the Book Options dialog.
C public interface for the Options Database.
void gnc_plugin_page_set_page_long_name(GncPluginPage *page, const char *name)
Set the long name of this page.
void gnc_main_window_merge_actions(GncMainWindow *window, const gchar *group_name, GActionEntry *actions, guint n_actions, const gchar **ui_updates, const gchar *ui_filename, gpointer user_data)
Add a set of actions to the specified window.
void gnc_engine_add_commit_error_callback(EngineCommitErrorCallback cb, gpointer data)
Set a callback function to be called in case an engine commit fails.
void gnc_shutdown(int exit_status)
Shutdown gnucash.
void gnc_ui_page_setup(GtkWindow *parent)
Run a page setup dialog and save the resulting GtkPageSetup in a static variable. ...
void gnc_main_window_foreach_page(GncMainWindowPageFunc fn, gpointer user_data)
Iterator function to walk all pages in all windows, calling the specified function for each page...
gboolean gnc_main_window_update_menu_for_action(GncMainWindow *window, const gchar *action_name, const gchar *label, const gchar *tooltip)
Find the GMenuModel item given the action name for the window specified.
void gnc_main_window_unmerge_actions(GncMainWindow *window, const gchar *group_name)
Remove a set of actions from the specified window.
const gchar * gnc_plugin_page_get_menu_qualifier(GncPluginPage *page)
Retrieve the menu qualifier for this page.
#define PERR(format, args...)
Log a serious error.
#define ENTER(format, args...)
Print a function entry debugging message.
void gnc_option_db_save(GncOptionDB *odb, QofBook *book, gboolean clear_options)
Save the GncOptionDB contents into a book's options store.
GtkWindow * gnc_ui_get_gtk_window(GtkWidget *widget)
Get a pointer to the widget's immediate top level GtkWindow.
void gnc_main_window_show_all_windows(void)
Shows all main windows.
const gchar * gnc_plugin_page_get_menu_popup_qualifier(GncPluginPage *page)
Retrieve the menu popup qualifier for this page.
void gnc_book_option_num_field_source_change_cb(gboolean num_action)
Calls gnc_book_option_num_field_source_change to initiate registered callbacks when num_field_source ...
void gnc_main_window_display_page(GncPluginPage *page)
Bring the window containing the specified page to the top of the window stack, then switch the notebo...
void gnc_main_window_save_all_windows(GKeyFile *keyfile)
Save the persistent state of all windows.
GncPluginPage * gnc_main_window_get_current_page(GncMainWindow *window)
Retrieve a pointer to the page that is currently at the front of the specified window.
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
Display a data plugin page in a window.
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Get an integer value from the preferences backend.
Functions for adding content to a window.
G_DEFINE_TYPE_WITH_CODE(GncMainWindow, gnc_main_window, GTK_TYPE_APPLICATION_WINDOW, G_IMPLEMENT_INTERFACE(GNC_TYPE_WINDOW, gnc_window_main_window_init)) static guint main_window_signals[LAST_SIGNAL]
A holding place for all the signals generated by the main window code.
GtkWidget * gnc_get_dialog_widget_from_id(GtkDialog *dialog, const gchar *id)
Find the Widget defined by 'id' in the dialog.
gint qof_event_register_handler(QofEventHandler handler, gpointer user_data)
Register a handler for events.
void main_window_update_page_long_name(GncPluginPage *page, const gchar *long_name_in)
Update the long name of the page in the main window.
#define PWARN(format, args...)
Log a warning.
void gnc_prefs_remove_cb_by_id(const gchar *group, guint id)
Remove a function that was registered for a callback when a specific preference in the settings group...
void gnc_gobject_tracking_remember(GObject *object)
Tell gnucash to remember this object in the database.
void qof_book_save_options(QofBook *book, GncOptionSave save_cb, GncOptionDB *odb, gboolean clear)
Save a GncOptionsDB back to the book's KVP.
void gnc_options_dialog_set_new_book_option_values(GncOptionDB *odb)
Set the initial values of new book options to values specified in user preferences.
GAction * gnc_main_window_find_action_in_group(GncMainWindow *window, const gchar *group_name, const gchar *action_name)
Find the GAction in a specific action group for window.
void gnc_main_window_all_action_set_sensitive(const gchar *action_name, gboolean sensitive)
Change the sensitivity of a command in all windows.
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
#define QOF_CHECK_TYPE(obj, type)
return TRUE if object is of the given type
void main_window_update_page_color(GncPluginPage *page, const gchar *color_in)
Update the color on the page tabs in the main window.
gchar * gnc_uri_normalize_uri(const gchar *uri, gboolean allow_password)
Composes a normalized uri starting from any uri (filename, db spec,...).
gchar * gnc_filepath_locate_doc_file(const gchar *name)
Given a documentation file name, find the file in the doc directory associated with this application...
gint QofEventId
Define the type of events allowed.
void qof_book_mark_session_saved(QofBook *book)
The qof_book_mark_saved() routine marks the book as having been saved (to a file, to a database)...
void gnc_plugin_page_set_use_new_window(GncPluginPage *page, gboolean use_new)
Set the "use new window" setting associated with this page.
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome's yelp for linux, and open to a given link within a gi...
GAction * gnc_main_window_find_action(GncMainWindow *window, const gchar *action_name)
Find the GAction in the main window.
gboolean gnc_prefs_set_bool(const gchar *group, const gchar *pref_name, gboolean value)
Store a boolean value into the preferences backend.
GtkWidget * notebook
The notebook containing all the pages in this window.
void gnc_plugin_page_disconnect_page_changed(GncPluginPage *page)
Disconnect the page_changed_id signal callback.
void gnc_option_db_load(GncOptionDB *odb, QofBook *book)
Load a book's options into the GncOptionDB.
void gnc_option_db_destroy(GncOptionDB *odb)
Destruct and release a GncOptionDB.
gboolean gnc_plugin_page_has_book(GncPluginPage *page, QofBook *book)
Query a page to see if it has a reference to a given book.
char * gnc_print_time64(time64 time, const char *format)
print a time64 as a date string per format
gboolean gnc_main_window_popup_menu_cb(GtkWidget *widget, GncPluginPage *page)
Callback function invoked when the user requests that Gnucash popup the contextual menu via the keybo...
The instance private data structure for an embedded window object.
The instance data structure for a main window object.
GtkWidget * gnc_menubar_model_find_menu_item(GMenuModel *menu_model, GtkWidget *menu, const gchar *action_name)
Find a GtkMenu item from the action name.
gboolean gnc_book_options_dialog_apply_helper(GncOptionDB *options)
Processes selected options in the Book Options dialog: checks book_currency and use_split_action_for_...
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
const gchar * gnc_plugin_page_get_simple_action_group_name(GncPluginPage *page)
Retrieve the simple action group name associated with this plugin page.
GncPluginManager * gnc_plugin_manager_get(void)
Retrieve a pointer to the plugin manager.
GList * usage_order
A list of pages in order of use (most recent -> least recent)
Gnome specific utility functions.
void gnc_plugin_page_save_page(GncPluginPage *page, GKeyFile *key_file, const gchar *group_name)
Call the plugin specific function that will save the state of a content page to a disk...
#define PLUGIN_PAGE_LABEL
This label is used to provide a mapping from a visible page widget back to the corresponding GncPlugi...
gboolean show_color_tabs
Show account color as background on tabs.
GtkWidget * gnc_find_toolbar_item(GtkWidget *toolbar, const gchar *action_name)
Search the toolbar for the tool item based on the action name.
Dialog for handling user preferences.
GtkWidget * menubar
The menubar.
gboolean qof_book_session_not_saved(const QofBook *book)
qof_book_not_saved() returns the value of the session_dirty flag, set when changes to any object in t...
All type declarations for the whole Gnucash engine.
const char * gnc_quote_source_fq_version(void)
This function returns the version of the Finance::Quote module installed on a user's computer...
gboolean gnc_main_window_finish_pending(GncMainWindow *window)
Tell a window to finish any outstanding activities.
Generic api to store and retrieve preferences.
Utility functions for file access.
gboolean just_plugin_prefs
Just remove preferences only from plugins.
void gnc_add_accelerator_keys_for_menu(GtkWidget *menu, GMenuModel *model, GtkAccelGroup *accel_group)
Add accelerator keys for menu item widgets.
gboolean gnc_uri_targets_local_fs(const gchar *uri)
Checks if the given uri is either a valid file uri or a local filesystem path.
void main_window_update_page_set_read_only_icon(GncPluginPage *page, gboolean read_only)
Update the icon on the page tabs in the main window.
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
GncMainWindow * gnc_main_window_new(void)
Create a new gnc main window plugin.
void gnc_plugin_page_set_page_color(GncPluginPage *page, const char *color)
Set the color of this page.
GList * gnc_option_db_commit(GncOptionDB *odb)
Write all changed ui_item values to their options.
cannot write to file/directory
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
const char * gnc_version(void)
Parse <prefix>/etc/gnucash/environment and set environment variables based on the contents of that fi...
void gnc_main_window_close_page(GncPluginPage *page)
Remove a data plugin page from a window and display the previous page.
Functions for adding plugins to a GnuCash window.
#define LEAVE(format, args...)
Print a function exit debugging message.
GList * gnc_plugin_manager_get_plugins(GncPluginManager *manager)
Get a list of all plugins being held by the plugin manager.
void gnc_plugin_page_set_page_name(GncPluginPage *page, const char *name)
Set the name of this page.
GList * installed_pages
A list of all pages that are installed in this window.
GtkWidget * progressbar
A pointer to the progress bar at the bottom right of the window that is contained in the status bar...
time64 gnc_time(time64 *tbuf)
get the current time
Utility functions for convert uri in separate components and back.
GncPluginPage * current_page
The currently selected page.
GSimpleActionGroup * gnc_main_window_get_action_group(GncMainWindow *window, const gchar *group_name)
Retrieve a specific set of user interface actions from a window.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
gulong gnc_prefs_get_reg_auto_raise_lists_id(void)
Get and Set registered preference id for register auto_raise_lists.
void gnc_launch_doclink(GtkWindow *parent, const char *uri)
Launch the default browser and open the provided URI.
void gnc_main_window_restore_default_state(GncMainWindow *window)
Restore the persistent state of one window to a sane default.
The class data structure for a main window object.
File path resolution utility functions.
gboolean gnc_main_window_all_finish_pending(void)
Tell all pages in all windows to finish any outstanding activities.
void gnc_option_db_book_options(GncOptionDB *odb)
Register the standard option set for a QofBook.
gint gnc_list_length_cmp(const GList *list, size_t len)
Scans the GList elements the minimum number of iterations required to test it against a specified siz...
void gnc_main_window_manual_merge_actions(GncMainWindow *window, const gchar *group_name, GSimpleActionGroup *group)
Manually add a set of actions to the specified window.
void main_window_update_page_name(GncPluginPage *page, const gchar *name_in)
Update the name of the page in the main window.
gboolean gnc_menubar_model_update_item(GMenuModel *menu_model, const gchar *action_name, const gchar *target, const gchar *label, const gchar *accel_name, const gchar *tooltip)
Update the GMenuModel item based on the action name by copying existing item, removing it and inserti...
GAction * gnc_plugin_page_get_action(GncPluginPage *page, const gchar *name)
Retrieve a GAction object associated with this page.
GtkWidget * notebook_page
The display widget for this plugin.
GtkWidget * menu_dock
The dock (vbox) at the top of the window containing the menubar and toolbar.
gchar * gnc_uri_create_uri(const gchar *scheme, const gchar *hostname, gint32 port, const gchar *username, const gchar *password, const gchar *path)
Composes a normalized uri starting from its separate components.
void gnc_plugin_page_show_summarybar(GncPluginPage *page, gboolean visible)
Show/hide the summarybar associated with this page.
GtkWidget * gnc_main_window_toolbar_find_tool_item(GncMainWindow *window, const gchar *action_name)
Find the toolbar item with the given action name for the window specified.
GtkWidget * gnc_plugin_page_create_widget(GncPluginPage *plugin_page)
Create the display widget that corresponds to this plugin.
constexpr auto gnc_main_window_max_number
Max number of windows allowed.
void gnc_main_window_set_progressbar_window(GncMainWindow *window)
Set the window where all progressbar updates should occur.
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)
Remove a function that was registered for a callback when the given preference changed.
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Get an float value from the preferences backend.
const gchar * gnc_plugin_page_get_plugin_name(GncPluginPage *plugin_page)
Retrieve the textual name of a plugin.
Utility functions for file access.
GncOptionDB * gnc_option_db_new(void)
Create an empty option database.