35 #include <glib/gi18n.h> 38 #include <gdk/gdkkeysyms.h> 39 #include "dialog-options.hpp" 50 #include "dialog-reset-warnings.h" 51 #include "dialog-transfer.h" 52 #include "dialog-utils.h" 53 #include "engine-helpers.h" 55 #include "gnc-component-manager.h" 56 #include "dialog-doclink-utils.h" 64 #include "gnc-gui-query.h" 66 #include "gnc-hooks.h" 67 #include "gnc-icons.h" 68 #include "gnc-session.h" 75 #include "gnc-warnings.h" 79 #include "gnc-autosave.h" 81 #ifdef MAC_INTEGRATION 82 #include <gtkmacintegration/gtkosxapplication.h> 84 #ifdef HAVE_SYS_STAT_H 85 # define __need_system_sys_stat_h //To block Guile-2.0's evil substitute 86 # include <sys/types.h> 87 # include <sys/stat.h> 101 #define PLUGIN_PAGE_LABEL "plugin-page" 103 #define PLUGIN_PAGE_CLOSE_BUTTON "close-button" 104 #define PLUGIN_PAGE_TAB_LABEL "label" 106 #define GNC_PREF_SHOW_CLOSE_BUTTON "tab-close-buttons" 107 #define GNC_PREF_TAB_NEXT_RECENT "tab-next-recent" 108 #define GNC_PREF_TAB_POSITION_TOP "tab-position-top" 109 #define GNC_PREF_TAB_POSITION_BOTTOM "tab-position-bottom" 110 #define GNC_PREF_TAB_POSITION_LEFT "tab-position-left" 111 #define GNC_PREF_TAB_POSITION_RIGHT "tab-position-right" 112 #define GNC_PREF_TAB_WIDTH "tab-width" 113 #define GNC_PREF_TAB_COLOR "show-account-color-tabs" 114 #define GNC_PREF_SAVE_CLOSE_EXPIRES "save-on-close-expires" 115 #define GNC_PREF_SAVE_CLOSE_WAIT_TIME "save-on-close-wait-time" 116 #define GNC_PREF_TAB_OPEN_ADJACENT "tab-open-adjacent" 118 #define GNC_MAIN_WINDOW_NAME "GncMainWindow" 120 #define DIALOG_BOOK_OPTIONS_CM_CLASS "dialog-book-options" 141 static QofLogModule log_module = GNC_MOD_GUI;
143 static GQuark window_type = 0;
146 static GList *active_windows =
nullptr;
149 static guint secs_to_save = 0;
150 #define MSG_AUTO_SAVE _("Changes will be saved automatically in %u seconds") 153 static void gnc_main_window_constructed (GObject *
object);
154 static void gnc_main_window_finalize (GObject *
object);
155 static void gnc_main_window_destroy (GtkWidget *widget);
157 static void gnc_main_window_setup_window (GncMainWindow *window);
158 static void gnc_window_main_window_init (GncWindowInterface *iface);
159 #ifndef MAC_INTEGRATION 160 static void gnc_main_window_update_all_menu_items (
void);
164 static void gnc_main_window_switch_page (GtkNotebook *notebook, gpointer *notebook_page, gint pos, GncMainWindow *window);
165 static void gnc_main_window_page_reordered (GtkNotebook *notebook, GtkWidget *child, guint pos, GncMainWindow *window);
166 static void gnc_main_window_plugin_added (GncPlugin *manager, GncPlugin *plugin, GncMainWindow *window);
167 static void gnc_main_window_plugin_removed (GncPlugin *manager, GncPlugin *plugin, GncMainWindow *window);
168 static void gnc_main_window_engine_commit_error_callback( gpointer data,
QofBackendError errcode );
171 static void gnc_main_window_cmd_redirect (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
172 static void gnc_main_window_cmd_page_setup (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
173 static void gnc_main_window_cmd_file_properties (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
174 static void gnc_main_window_cmd_file_close (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
175 static void gnc_main_window_cmd_file_quit (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
176 static void gnc_main_window_cmd_edit_cut (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
177 static void gnc_main_window_cmd_edit_copy (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
178 static void gnc_main_window_cmd_edit_paste (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
179 static void gnc_main_window_cmd_edit_preferences (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
180 static void gnc_main_window_cmd_view_refresh (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
181 static void gnc_main_window_cmd_view_toolbar (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
182 static void gnc_main_window_cmd_view_summary (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
183 static void gnc_main_window_cmd_view_statusbar (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
185 static void gnc_main_window_cmd_view_tab_position (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
187 static void gnc_main_window_cmd_actions_reset_warnings (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
188 static void gnc_main_window_cmd_actions_rename_page (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
189 static void gnc_main_window_cmd_window_new (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
190 static void gnc_main_window_cmd_window_move_page (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
191 #ifndef MAC_INTEGRATION 192 static void gnc_main_window_cmd_window_raise (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
194 static void gnc_main_window_cmd_help_tutorial (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
195 static void gnc_main_window_cmd_help_contents (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
196 static void gnc_main_window_cmd_help_about (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
198 static void do_popup_menu(
GncPluginPage *page, GdkEventButton *event);
199 static GtkWidget *gnc_main_window_get_statusbar (GncWindow *window_in);
200 static void statusbar_notification_lastmodified (
void);
201 static void gnc_main_window_update_tab_position (gpointer prefs, gchar *pref, gpointer user_data);
202 static void gnc_main_window_remove_prefs (GncMainWindow *window);
204 #ifdef MAC_INTEGRATION 205 static void gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data);
206 static gboolean gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window);
207 static void gnc_quartz_set_menu (GncMainWindow* window);
209 static void gnc_main_window_init_menu_updaters (GncMainWindow *window);
259 const gchar *previous_plugin_page_name;
260 const gchar *previous_menu_qualifier;
265 GHashTable *display_item_hash;
270 G_ADD_PRIVATE (GncMainWindow)
271 G_IMPLEMENT_INTERFACE (GNC_TYPE_WINDOW,
272 gnc_window_main_window_init))
274 #define GNC_MAIN_WINDOW_GET_PRIVATE(o) \ 275 ((GncMainWindowPrivate*)gnc_main_window_get_instance_private((GncMainWindow*)o)) 279 static guint main_window_signals[LAST_SIGNAL] = { 0 };
285 static GActionEntry gnc_menu_actions [] =
287 {
"FilePageSetupAction", gnc_main_window_cmd_page_setup,
nullptr,
nullptr,
nullptr },
288 {
"FilePropertiesAction", gnc_main_window_cmd_file_properties,
nullptr,
nullptr,
nullptr },
289 {
"FileCloseAction", gnc_main_window_cmd_file_close,
nullptr,
nullptr,
nullptr },
290 {
"FilePrintAction", gnc_main_window_cmd_redirect,
nullptr,
nullptr,
nullptr },
291 {
"FileQuitAction", gnc_main_window_cmd_file_quit,
nullptr,
nullptr,
nullptr },
293 {
"EditCutAction", gnc_main_window_cmd_edit_cut,
nullptr,
nullptr,
nullptr },
294 {
"EditCopyAction", gnc_main_window_cmd_edit_copy,
nullptr,
nullptr,
nullptr },
295 {
"EditPasteAction", gnc_main_window_cmd_edit_paste,
nullptr,
nullptr,
nullptr },
296 {
"EditPreferencesAction", gnc_main_window_cmd_edit_preferences,
nullptr,
nullptr,
nullptr },
298 {
"ActionsForgetWarningsAction", gnc_main_window_cmd_actions_reset_warnings,
nullptr,
nullptr,
nullptr },
299 {
"ActionsRenamePageAction", gnc_main_window_cmd_actions_rename_page,
nullptr,
nullptr,
nullptr },
301 {
"TransactionAction",
nullptr,
nullptr,
nullptr,
nullptr },
303 {
"ViewSortByAction",
nullptr,
nullptr,
nullptr,
nullptr },
304 {
"ViewFilterByAction",
nullptr,
nullptr,
nullptr,
nullptr },
305 {
"ViewRefreshAction", gnc_main_window_cmd_view_refresh,
nullptr,
nullptr,
nullptr },
306 {
"ViewToolbarAction", gnc_main_window_cmd_view_toolbar,
nullptr,
"true",
nullptr },
307 {
"ViewSummaryAction", gnc_main_window_cmd_view_summary,
nullptr,
"true",
nullptr },
308 {
"ViewStatusbarAction", gnc_main_window_cmd_view_statusbar,
nullptr,
"true",
nullptr },
309 {
"ViewTabPositionAction", gnc_main_window_cmd_view_tab_position,
"i",
"@i 0",
nullptr },
311 {
"ScheduledAction",
nullptr,
nullptr,
nullptr,
nullptr },
313 {
"ExtensionsAction",
nullptr,
nullptr,
nullptr,
nullptr },
315 {
"WindowNewAction", gnc_main_window_cmd_window_new,
nullptr,
nullptr,
nullptr },
316 {
"WindowMovePageAction", gnc_main_window_cmd_window_move_page,
nullptr,
nullptr,
nullptr },
317 #ifndef MAC_INTEGRATION 318 {
"WindowAction", gnc_main_window_cmd_window_raise,
"i",
"@i 0",
nullptr },
320 {
"HelpTutorialAction", gnc_main_window_cmd_help_tutorial,
nullptr,
nullptr,
nullptr },
321 {
"HelpContentsAction", gnc_main_window_cmd_help_contents,
nullptr,
nullptr,
nullptr },
322 {
"HelpAboutAction", gnc_main_window_cmd_help_about,
nullptr,
nullptr,
nullptr },
325 static guint gnc_menu_n_actions = G_N_ELEMENTS(gnc_menu_actions);
331 static const gchar *always_insensitive_actions[] =
341 static const gchar *initially_insensitive_actions[] =
352 static const gchar *always_hidden_actions[] =
355 "ViewFilterByAction",
362 static const gchar *immutable_page_actions[] =
371 static const gchar *multiple_page_actions[] =
373 "WindowMovePageAction",
381 #define WINDOW_COUNT "WindowCount" 382 #define WINDOW_STRING "Window %d" 383 #define WINDOW_GEOMETRY "WindowGeometry" 384 #define WINDOW_POSITION "WindowPosition" 385 #define WINDOW_MAXIMIZED "WindowMaximized" 386 #define TOOLBAR_VISIBLE "ToolbarVisible" 387 #define STATUSBAR_VISIBLE "StatusbarVisible" 388 #define SUMMARYBAR_VISIBLE "SummarybarVisible" 389 #define WINDOW_FIRSTPAGE "FirstPage" 390 #define WINDOW_PAGECOUNT "PageCount" 391 #define WINDOW_PAGEORDER "PageOrder" 392 #define PAGE_TYPE "PageType" 393 #define PAGE_NAME "PageName" 394 #define PAGE_STRING "Page %d" 399 const gchar *group_name;
420 for (
auto w = active_windows; w; w = g_list_next(w))
422 auto window{
static_cast<GncMainWindow*
>(w->data)};
423 auto priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
424 for (
auto p = priv->installed_pages; p; p = g_list_next(p))
449 gnc_main_window_restore_page (GncMainWindow *window,
454 gchar *page_group, *page_type =
nullptr, *name =
nullptr;
455 const gchar *class_type;
456 GError *error =
nullptr;
458 ENTER(
"window %p, data %p (key file %p, window %d, page start %d, page num %d)",
459 window, data, data->key_file, data->window_num, data->page_offset,
462 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
463 page_group = g_strdup_printf(PAGE_STRING,
464 data->page_offset + data->page_num);
465 page_type = g_key_file_get_string(data->key_file, page_group,
469 g_warning(
"error reading group %s key %s: %s",
470 page_group, PAGE_TYPE, error->message);
479 class_type = GNC_PLUGIN_PAGE_GET_CLASS(page)->plugin_name;
480 if (strcmp(page_type, class_type) != 0)
482 g_warning(
"error: page types don't match: state %s, existing page %s",
483 page_type, class_type);
491 data->key_file, page_group);
495 if (page->
window ==
nullptr)
502 name = g_key_file_get_string(data->key_file, page_group,
506 g_warning(
"error reading group %s key %s: %s",
507 page_group, PAGE_NAME, error->message);
512 DEBUG(
"updating page name for %p to %s.", page, name);
527 return (page ?
true :
false);
531 intersects_some_monitor(
const GdkRectangle& rect)
533 auto display = gdk_display_get_default();
537 int n = gdk_display_get_n_monitors(display);
538 for (
int i = 0; i < n; ++i)
540 auto monitor = gdk_display_get_monitor(display, i);
541 GdkRectangle monitor_geometry;
542 gdk_monitor_get_geometry(monitor, &monitor_geometry);
543 DEBUG(
"Monitor %d: position (%d,%d), size %dx%d\n", i,
544 monitor_geometry.x, monitor_geometry.y,
545 monitor_geometry.width, monitor_geometry.height);
546 if (gdk_rectangle_intersect(&rect, &monitor_geometry,
nullptr))
557 GError *error =
nullptr;
558 gint *geom = g_key_file_get_integer_list(data->key_file, window_group,
559 WINDOW_GEOMETRY, &length, &error);
562 g_warning(
"error reading group %s key %s: %s",
563 window_group, WINDOW_GEOMETRY, error->message);
567 else if (length != 2)
569 g_warning(
"invalid number of values for group %s key %s",
570 window_group, WINDOW_GEOMETRY);
574 gtk_window_resize(GTK_WINDOW(window), geom[0], geom[1]);
575 DEBUG(
"window (%p) size %dx%d", window, geom[0], geom[1]);
580 gint *pos = g_key_file_get_integer_list(data->key_file, window_group,
581 WINDOW_POSITION, &length, &error);
584 g_warning(
"error reading group %s key %s: %s",
585 window_group, WINDOW_POSITION, error->message);
589 else if (length != 2)
591 g_warning(
"invalid number of values for group %s key %s",
592 window_group, WINDOW_POSITION);
598 GdkRectangle geometry{pos[0], pos[1], geom ? geom[0] : 1, geom ? geom[1] : 1};
599 if (intersects_some_monitor(geometry))
601 gtk_window_move(GTK_WINDOW(window), geometry.x, geometry.y);
602 auto priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
603 priv->
pos[0] = geometry.x;
604 priv->
pos[1] = geometry.y;
605 DEBUG(
"window (%p) position (%d,%d)", window, geometry.x, geometry.y);
609 DEBUG(
"position (%d,%d), size %dx%d is offscreen; will not move",
610 geometry.x, geometry.y, geometry.width, geometry.height);
616 gboolean max = g_key_file_get_boolean(data->key_file, window_group,
617 WINDOW_MAXIMIZED, &error);
620 g_warning(
"error reading group %s key %s: %s",
621 window_group, WINDOW_MAXIMIZED, error->message);
627 gtk_window_maximize(GTK_WINDOW(window));
646 gsize page_start, page_count, i;
647 GError *error =
nullptr;
648 GSList *added_page_offsets =
nullptr;
652 ENTER(
"window %p, data %p (key file %p, window %d)",
653 window, data, data->key_file, data->window_num);
654 gchar *window_group = g_strdup_printf(WINDOW_STRING, data->window_num + 1);
663 if (!g_key_file_has_group (data->key_file, window_group) ||
664 !g_key_file_has_key (data->key_file, window_group, WINDOW_PAGECOUNT, &error))
669 PINFO (
"saved state had an empty first main window\n" 670 "an account hierarchy page was added automatically to avoid confusion");
673 PINFO (
"saved state had an empty main window, skipping restore");
680 page_count = g_key_file_get_integer(data->key_file,
681 window_group, WINDOW_PAGECOUNT, &error);
684 g_warning(
"error reading group %s key %s: %s",
685 window_group, WINDOW_PAGECOUNT, error->message);
694 page_start = g_key_file_get_integer(data->key_file,
695 window_group, WINDOW_FIRSTPAGE, &error);
698 g_warning(
"error reading group %s key %s: %s",
699 window_group, WINDOW_FIRSTPAGE, error->message);
704 if (window ==
nullptr)
706 DEBUG(
"Window %d doesn't exist. Creating new window.", data->window_num);
707 DEBUG(
"active_windows %p.", active_windows);
709 DEBUG(
"first window %p.", active_windows->data);
714 set_window_geometry(window, data, window_group);
716 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
725 GVariant *state = g_action_get_state (G_ACTION(action));
726 gboolean visible = g_variant_get_boolean (state);
727 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
728 TOOLBAR_VISIBLE, &error);
732 g_warning (
"error reading group %s key %s: %s",
733 window_group, TOOLBAR_VISIBLE, error->message);
734 g_error_free (error);
737 else if (visible != desired_visibility)
739 g_action_activate (action,
nullptr);
741 g_variant_unref (state);
747 GVariant *state = g_action_get_state (G_ACTION(action));
748 gboolean visible = g_variant_get_boolean (state);
749 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
750 SUMMARYBAR_VISIBLE, &error);
754 g_warning (
"error reading group %s key %s: %s",
755 window_group, SUMMARYBAR_VISIBLE, error->message);
756 g_error_free (error);
759 else if (visible != desired_visibility)
761 g_action_activate (action,
nullptr);
763 g_variant_unref (state);
769 GVariant *state = g_action_get_state (G_ACTION(action));
770 gboolean visible = g_variant_get_boolean (state);
771 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
772 STATUSBAR_VISIBLE, &error);
776 g_warning (
"error reading group %s key %s: %s",
777 window_group, STATUSBAR_VISIBLE, error->message);
778 g_error_free (error);
781 else if (visible != desired_visibility)
783 g_action_activate (action,
nullptr);
785 g_variant_unref (state);
789 for (i = 0; i < page_count; i++)
791 data->page_offset = page_start;
793 gboolean page_added = gnc_main_window_restore_page (window, data);
798 added_page_offsets = g_slist_append (added_page_offsets,
799 GINT_TO_POINTER(-1));
802 added_page_offsets = g_slist_append (added_page_offsets,
803 GINT_TO_POINTER(offset));
806 while (gtk_events_pending ())
807 gtk_main_iteration ();
813 order = g_key_file_get_integer_list (data->key_file, window_group,
814 WINDOW_PAGEORDER, &length, &error);
817 g_warning(
"error reading group %s key %s: %s",
818 window_group, WINDOW_PAGEORDER, error->message);
822 else if (length != page_count)
824 g_warning(
"%s key %s length %" G_GSIZE_FORMAT
" differs from window page count %" G_GSIZE_FORMAT,
825 window_group, WINDOW_PAGEORDER, length, page_count);
833 gint default_page_position = -1;
836 for (i = 0; i < length; i++)
838 gint zero_based_page_number = order[i] - 1;
840 gint offset = GPOINTER_TO_INT(g_slist_nth_data (added_page_offsets,
841 zero_based_page_number));
847 zero_based_page_number - offset);
849 if (default_page_position == -1)
850 default_page_position = zero_based_page_number - offset;
855 gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->
notebook),
856 default_page_position);
858 g_signal_emit_by_name (window,
"page_changed",
866 LEAVE(
"window %p", window);
868 g_slist_free (added_page_offsets);
871 g_free(window_group);
873 gtk_widget_show (GTK_WIDGET(window));
879 gint i, window_count;
880 GError *error =
nullptr;
885 data.key_file = (GKeyFile *) keyfile;
886 window_count = g_key_file_get_integer(data.key_file, STATE_FILE_TOP,
887 WINDOW_COUNT, &error);
890 g_warning(
"error reading group %s key %s: %s",
891 STATE_FILE_TOP, WINDOW_COUNT, error->message);
893 LEAVE(
"can't read count");
899 gnc_set_busy_cursor (
nullptr, TRUE);
900 for (i = 0; i < window_count; i++)
903 auto window{
static_cast<GncMainWindow*
>(g_list_nth_data(active_windows,
905 gnc_main_window_restore_window(window, &data);
907 gnc_unset_busy_cursor (
nullptr);
909 statusbar_notification_lastmodified();
919 DEBUG(
"no saved state file");
921 window =
static_cast<GncMainWindow*
>(g_list_nth_data(active_windows, 0));
922 gtk_widget_show (GTK_WIDGET(window));
924 "gnc-plugin-account-tree-actions",
925 "ViewAccountTreeAction");
926 g_action_activate (action,
nullptr);
942 const gchar *plugin_name, *page_name;
944 ENTER(
"page %p, data %p (key file %p, window %d, page %d)",
945 page, data, data->key_file, data->window_num, data->page_num);
948 if (!plugin_name || !page_name)
950 LEAVE(
"not saving invalid page");
953 page_group = g_strdup_printf(PAGE_STRING, data->page_num++);
954 g_key_file_set_string(data->key_file, page_group, PAGE_TYPE, plugin_name);
955 g_key_file_set_string(data->key_file, page_group, PAGE_NAME, page_name);
976 gint i, num_pages, coords[4], *order;
977 gboolean maximized, minimized, visible =
true;
981 ENTER(
"window %p, data %p (key file %p, window %d)",
982 window, data, data->key_file, data->window_num);
983 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
986 num_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->
notebook));
989 LEAVE(
"empty window %p", window);
994 window_group = g_strdup_printf(WINDOW_STRING, data->window_num++);
995 g_key_file_set_integer(data->key_file, window_group,
996 WINDOW_PAGECOUNT, num_pages);
997 g_key_file_set_integer(data->key_file, window_group,
998 WINDOW_FIRSTPAGE, data->page_num);
1003 order =
static_cast<int*
>(g_malloc(
sizeof(gint) * num_pages));
1004 for (i = 0; i < num_pages; i++)
1006 gpointer page = g_list_nth_data(priv->
usage_order, i);
1009 g_key_file_set_integer_list(data->key_file, window_group,
1010 WINDOW_PAGEORDER, order, num_pages);
1014 gtk_window_get_position(GTK_WINDOW(window), &coords[0], &coords[1]);
1015 gtk_window_get_size(GTK_WINDOW(window), &coords[2], &coords[3]);
1016 maximized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
1017 & GDK_WINDOW_STATE_MAXIMIZED) != 0;
1018 minimized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
1019 & GDK_WINDOW_STATE_ICONIFIED) != 0;
1023 gint *pos = priv->
pos;
1024 g_key_file_set_integer_list(data->key_file, window_group,
1025 WINDOW_POSITION, &pos[0], 2);
1026 DEBUG(
"window minimized (%p) position (%d,%d)", window, pos[0], pos[1]);
1029 g_key_file_set_integer_list(data->key_file, window_group,
1030 WINDOW_POSITION, &coords[0], 2);
1031 g_key_file_set_integer_list(data->key_file, window_group,
1032 WINDOW_GEOMETRY, &coords[2], 2);
1033 g_key_file_set_boolean(data->key_file, window_group,
1034 WINDOW_MAXIMIZED, maximized);
1035 DEBUG(
"window (%p) position (%d,%d), size %dx%d, %s", window, coords[0], coords[1],
1036 coords[2], coords[3],
1037 maximized ?
"maximized" :
"not maximized");
1043 GVariant *state = g_action_get_state (G_ACTION(action));
1044 visible = g_variant_get_boolean (state);
1045 g_variant_unref (state);
1047 g_key_file_set_boolean (data->key_file, window_group,
1048 TOOLBAR_VISIBLE, visible);
1052 GVariant *state = g_action_get_state (G_ACTION(action));
1053 visible = g_variant_get_boolean (state);
1054 g_variant_unref (state);
1056 g_key_file_set_boolean (data->key_file, window_group,
1057 SUMMARYBAR_VISIBLE, visible);
1061 GVariant *state = g_action_get_state (G_ACTION(action));
1062 visible = g_variant_get_boolean (state);
1063 g_variant_unref (state);
1065 g_key_file_set_boolean (data->key_file, window_group,
1066 STATUSBAR_VISIBLE, visible);
1069 g_list_foreach (priv->
installed_pages, (GFunc)gnc_main_window_save_page, data);
1071 g_free(window_group);
1072 LEAVE(
"window %p", window);
1081 data.key_file = keyfile;
1082 data.window_num = 1;
1085 g_key_file_set_integer(data.key_file,
1086 STATE_FILE_TOP, WINDOW_COUNT,
1087 g_list_length(active_windows));
1089 g_list_foreach(active_windows, (GFunc)gnc_main_window_save_window, &data);
1099 g_return_val_if_fail(GNC_IS_MAIN_WINDOW(window), TRUE);
1101 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1116 const GList *windows, *item;
1119 for (item = windows; item; item = g_list_next(item))
1126 if (gnc_gui_refresh_suspended ())
1128 gnc_warning_dialog (
nullptr,
"%s",
"An operation is still running, wait for it to complete before quitting.");
1151 for (walker = active_windows; walker; walker = g_list_next(walker))
1153 auto window{
static_cast<GncMainWindow*
>(walker->data)};
1154 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1163 static gboolean auto_save_countdown (GtkWidget *dialog)
1166 gchar *timeoutstr =
nullptr;
1169 if (!GTK_IS_DIALOG (dialog))
1173 label = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
"count-down-label"));
1174 if (!GTK_IS_LABEL (label))
1180 DEBUG (
"Counting down: %d seconds", secs_to_save);
1182 timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
1183 gtk_label_set_text (GTK_LABEL (label), timeoutstr);
1184 g_free (timeoutstr);
1189 gtk_dialog_response (GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
1208 gnc_main_window_prompt_for_save (GtkWidget *window)
1210 QofSession *session;
1212 GtkWidget *dialog, *msg_area, *label;
1214 const gchar *filename, *tmp;
1215 const gchar *title = _(
"Save changes to file %s before closing?");
1217 const gchar *message_hours =
1218 _(
"If you don't save, changes from the past %d hours and %d minutes will be discarded.");
1219 const gchar *message_days =
1220 _(
"If you don't save, changes from the past %d days and %d hours will be discarded.");
1222 gint minutes, hours, days;
1223 guint timer_source = 0;
1224 if (!gnc_current_session_exist())
1226 session = gnc_get_current_session();
1230 filename = qof_session_get_url(session);
1231 if (!strlen (filename))
1232 filename = _(
"<unknown>");
1233 if ((tmp = strrchr(filename,
'/')) !=
nullptr)
1237 gnc_autosave_remove_timer(book);
1239 dialog = gtk_message_dialog_new(GTK_WINDOW(window),
1241 GTK_MESSAGE_WARNING,
1246 minutes = (
gnc_time (
nullptr) - oldest_change) / 60 + 1;
1247 hours = minutes / 60;
1248 minutes = minutes % 60;
1253 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1254 message_days, days, hours);
1258 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1259 message_hours, hours, minutes);
1263 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1264 ngettext(
"If you don't save, changes from the past %d minute will be discarded.",
1265 "If you don't save, changes from the past %d minutes will be discarded.",
1268 gtk_dialog_add_buttons(GTK_DIALOG(dialog),
1269 _(
"Close _Without Saving"), GTK_RESPONSE_CLOSE,
1270 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
1271 _(
"_Save"), GTK_RESPONSE_APPLY,
1273 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
1280 gchar *timeoutstr =
nullptr;
1282 secs_to_save =
gnc_prefs_get_int (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_CLOSE_WAIT_TIME);
1283 timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
1284 label = GTK_WIDGET(gtk_label_new (timeoutstr));
1285 g_free (timeoutstr);
1286 gtk_widget_show (label);
1288 msg_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG(dialog));
1289 gtk_box_pack_end (GTK_BOX(msg_area), label, TRUE, TRUE, 0);
1290 g_object_set (G_OBJECT (label),
"xalign", 0.0,
nullptr);
1292 g_object_set_data (G_OBJECT (dialog),
"count-down-label", label);
1293 timer_source = g_timeout_add_seconds (1, (GSourceFunc)auto_save_countdown, dialog);
1296 response = gtk_dialog_run (GTK_DIALOG (dialog));
1298 g_source_remove (timer_source);
1299 gtk_widget_destroy(dialog);
1303 case GTK_RESPONSE_APPLY:
1304 gnc_file_save (GTK_WINDOW (window));
1307 case GTK_RESPONSE_CLOSE:
1318 gnc_main_window_add_plugin (gpointer plugin,
1321 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
1322 g_return_if_fail (GNC_IS_PLUGIN (plugin));
1326 GNC_MAIN_WINDOW (window),
1332 gnc_main_window_remove_plugin (gpointer plugin,
1335 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
1336 g_return_if_fail (GNC_IS_PLUGIN (plugin));
1340 GNC_MAIN_WINDOW (window),
1347 gnc_main_window_timed_quit (gpointer dummy)
1349 if (gnc_file_save_in_progress())
1357 gnc_main_window_quit(GncMainWindow *window)
1359 QofSession *session;
1360 gboolean needs_save, do_shutdown = TRUE;
1361 if (gnc_current_session_exist())
1363 session = gnc_get_current_session();
1366 !gnc_file_save_in_progress();
1367 do_shutdown = !needs_save ||
1369 !gnc_main_window_prompt_for_save(GTK_WIDGET(window)));
1379 for (w = active_windows; w; w = next)
1382 GncMainWindow *window =
static_cast<GncMainWindow*
>(w->data);
1384 next = g_list_next (w);
1386 window->window_quitting = TRUE;
1388 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1392 gtk_widget_destroy (GTK_WIDGET(window));
1395 gnc_main_window_remove_prefs (window);
1396 g_timeout_add(250, gnc_main_window_timed_quit,
nullptr);
1403 gnc_main_window_delete_event (GtkWidget *window,
1407 static gboolean already_dead = FALSE;
1416 gchar *message = _(
"This window is closing and will not be restored.");
1418 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
1419 GTK_DIALOG_DESTROY_WITH_PARENT,
1420 GTK_MESSAGE_QUESTION,
1422 "%s", _(
"Close Window?"));
1423 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
1426 gtk_dialog_add_buttons (GTK_DIALOG(dialog),
1427 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
1428 _(
"_OK"), GTK_RESPONSE_YES,
1430 gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_YES);
1431 response = gnc_dialog_run (GTK_DIALOG(dialog), GNC_PREF_WARN_CLOSING_WINDOW_QUESTION);
1432 gtk_widget_destroy (dialog);
1434 if (response == GTK_RESPONSE_CANCEL)
1447 already_dead = gnc_main_window_quit(GNC_MAIN_WINDOW(window));
1473 gpointer user_data, gpointer event_data)
1475 GncMainWindow *window;
1481 g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
1486 if (event_type != QOF_EVENT_DESTROY)
1489 ENTER(
"entity %p, event %d, window %p, event data %p",
1490 entity, event_type, user_data, event_data);
1491 window = GNC_MAIN_WINDOW(user_data);
1492 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1499 next = g_list_next(item);
1500 page = GNC_PLUGIN_PAGE(item->data);
1505 if (GTK_IS_WIDGET(window) && window->window_quitting)
1506 gtk_widget_destroy (GTK_WIDGET(window));
1529 gnc_main_window_generate_title (GncMainWindow *window)
1535 gchar *filename =
nullptr;
1536 const gchar *uri =
nullptr;
1537 const gchar *dirty =
"";
1538 const gchar *readonly_text =
nullptr;
1542 if (gnc_current_session_exist())
1544 uri = qof_session_get_url (gnc_get_current_session ());
1545 book = gnc_get_current_book();
1552 readonly_text = _(
"(read-only)");
1555 readonly = (readonly_text !=
nullptr)
1556 ? g_strdup_printf(
" %s", readonly_text)
1559 if (!uri || g_strcmp0 (uri,
"") == 0)
1560 filename = g_strdup(_(
"Unsaved Book"));
1568 filename = g_path_get_basename ( path );
1579 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1585 title = g_strdup_printf(
"%s%s%s - %s - GnuCash", dirty, filename, readonly,
1590 title = g_strdup_printf(
"%s%s%s - GnuCash", dirty, filename, readonly);
1594 g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE);
1596 immutable_page_actions,
1599 g_signal_emit_by_name (window,
"page_changed", page);
1617 gnc_main_window_update_title (GncMainWindow *window)
1621 title = gnc_main_window_generate_title(window);
1622 gtk_window_set_title(GTK_WINDOW(window), title);
1627 gnc_main_window_update_all_titles (
void)
1629 g_list_foreach(active_windows,
1630 (GFunc)gnc_main_window_update_title,
1652 gnc_tab_clicked_cb(GtkWidget *widget, GdkEventButton *event,
GncPluginPage *page) {
1653 if (event->type == GDK_BUTTON_PRESS && event->button == 2)
1662 gnc_main_window_book_dirty_cb (QofBook *book,
1666 gnc_main_window_update_all_titles();
1669 gnc_autosave_dirty_handler(book, dirty);
1673 gnc_main_window_attach_to_book (QofSession *session)
1677 g_return_if_fail(session);
1681 gnc_main_window_update_all_titles();
1682 #ifndef MAC_INTEGRATION 1683 gnc_main_window_update_all_menu_items();
1687 static guint gnc_statusbar_notification_messageid = 0;
1689 #ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL 1692 static gboolean statusbar_notification_off(gpointer user_data_unused)
1696 if (gnc_statusbar_notification_messageid == 0)
1701 GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
1702 gtk_statusbar_remove(GTK_STATUSBAR(statusbar), 0, gnc_statusbar_notification_messageid);
1703 gnc_statusbar_notification_messageid = 0;
1707 g_warning(
"oops, no GncMainWindow obtained\n");
1711 #endif // STATUSBAR_NOTIFICATION_AUTOREMOVAL 1715 static gchar *generate_statusbar_lastmodified_message()
1717 gchar *message =
nullptr;
1718 const gchar *uri =
nullptr;
1720 if (gnc_current_session_exist())
1722 uri = qof_session_get_url (gnc_get_current_session ());
1725 if (!(uri && strlen (uri)))
1733 gchar *filename = g_path_get_basename ( filepath );
1734 GFile *file = g_file_new_for_uri (uri);
1735 GFileInfo *info = g_file_query_info (file,
1736 G_FILE_ATTRIBUTE_TIME_MODIFIED,
1737 G_FILE_QUERY_INFO_NONE,
1740 if (info && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
1743 struct stat statbuf;
1744 int r = stat(filepath, &statbuf);
1753 _(
"Last modified on %a, %b %d, %Y at %I:%M %p"));
1756 message = g_strdup_printf(_(
"File %s opened. %s"),
1757 filename, time_string);
1762 g_warning(
"Unable to read mtime for file %s\n", filepath);
1768 g_object_unref (info);
1769 g_object_unref (file);
1778 statusbar_notification_lastmodified()
1782 GtkWidget *widget =
nullptr;
1783 for (iter = active_windows; iter && !(widget && GNC_IS_MAIN_WINDOW(widget));
1784 iter = g_list_next(iter))
1786 widget =
static_cast<GtkWidget*
>(iter->data);
1788 if (widget && GNC_IS_MAIN_WINDOW(widget))
1791 GncMainWindow *mainwindow = GNC_MAIN_WINDOW(widget);
1792 GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
1794 gchar *msg = generate_statusbar_lastmodified_message();
1797 gnc_statusbar_notification_messageid = gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);
1801 #ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL 1804 g_timeout_add(10 * 1000, statusbar_notification_off,
nullptr);
1809 g_warning(
"uh oh, no GNC_IS_MAIN_WINDOW\n");
1831 #ifndef MAC_INTEGRATION 1846 gnc_main_window_update_one_menu_action (GncMainWindow *window,
1850 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
1854 ENTER(
"window %p, action %s, label %s, index %d, visible %d", window,
1855 data->action_name, data->label, data->index, data->visible);
1857 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1859 gsm->search_action_label =
nullptr;
1860 gsm->search_action_name =
"WindowsPlaceholder1";
1861 gsm->search_action_target =
nullptr;
1865 LEAVE(
"Could not find placeholder 'WindowsPlaceholder1' for windows entries");
1870 pos = gsm->index + data->index + 1;
1874 if (pos < g_menu_model_get_n_items (gsm->model))
1875 g_menu_remove (G_MENU(gsm->model), pos);
1882 item = g_menu_item_new (data->label,
"mainwin.WindowAction");
1883 g_menu_item_set_attribute (item, G_MENU_ATTRIBUTE_TARGET,
"i", data->index);
1885 if (pos < g_menu_model_get_n_items (gsm->model))
1886 g_menu_remove (G_MENU(gsm->model), pos);
1887 g_menu_insert_item (G_MENU(gsm->model), pos, item);
1888 g_object_unref (item);
1907 gnc_main_window_update_radio_button (GncMainWindow *window)
1912 ENTER(
"window %p", window);
1915 index = g_list_index (active_windows, window);
1923 action = g_action_map_lookup_action (G_ACTION_MAP(window),
1928 g_signal_handlers_block_by_func (G_OBJECT(action),
1929 (gpointer)gnc_main_window_cmd_window_raise,
1932 DEBUG(
"blocked signal on action %p, window %p", action, window);
1933 g_action_change_state (G_ACTION(action), g_variant_new_int32 (index));
1935 g_signal_handlers_unblock_by_func (G_OBJECT(action),
1936 (gpointer)gnc_main_window_cmd_window_raise,
1954 gnc_main_window_update_menu_item (GncMainWindow *window)
1957 gchar **strings, *title, *expanded;
1960 ENTER(
"window %p", window);
1962 index = g_list_index (active_windows, window);
1971 title = gnc_main_window_generate_title (window);
1972 strings = g_strsplit (title,
"_", 0);
1974 expanded = g_strjoinv (
"__", strings);
1977 data.label = g_strdup_printf (
"_%" G_GSIZE_FORMAT
" %s", (
index + 1) % 10, expanded);
1982 data.label = expanded;
1984 g_strfreev (strings);
1986 data.visible = TRUE;
1987 data.action_name = g_strdup_printf (
"Window%" G_GSIZE_FORMAT
"Action",
index);
1990 g_list_foreach (active_windows,
1991 (GFunc)gnc_main_window_update_one_menu_action,
1994 g_free (data.action_name);
1995 g_free (data.label);
2009 #ifndef MAC_INTEGRATION 2011 gnc_main_window_update_all_menu_items (
void)
2017 g_list_foreach (active_windows,
2018 (GFunc)gnc_main_window_update_menu_item,
2021 g_list_foreach (active_windows,
2022 (GFunc)gnc_main_window_update_radio_button,
2026 data.visible = FALSE;
2031 data.action_name = g_strdup_printf (
"Window%dAction", data.index);
2032 data.label = g_strdup_printf (
"mywin%" G_GSIZE_FORMAT, i % 10);
2034 g_list_foreach (active_windows,
2035 (GFunc)gnc_main_window_update_one_menu_action,
2038 g_free (data.action_name);
2039 g_free (data.label);
2057 gnc_main_window_update_tab_close_one_page (
GncPluginPage *page,
2060 auto new_value{
static_cast<gboolean*
>(user_data)};
2061 ENTER(
"page %p, visible %d", page, *new_value);
2062 auto close_button{
static_cast<GtkWidget*
>(g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON))};
2065 LEAVE(
"no close button");
2070 gtk_widget_show (close_button);
2072 gtk_widget_hide (close_button);
2090 gnc_main_window_update_tab_close (gpointer prefs, gchar *pref, gpointer user_data)
2095 new_value =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SHOW_CLOSE_BUTTON);
2097 gnc_main_window_update_tab_close_one_page,
2112 gnc_main_window_update_tab_color_one_page (
GncPluginPage *page,
2115 const gchar *color_string;
2117 ENTER(
"page %p", page);
2135 gnc_main_window_update_tab_color (gpointer gsettings, gchar *pref, gpointer user_data)
2138 g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
2139 auto window{
static_cast<GncMainWindow*
>(user_data)};
2140 auto priv{GNC_MAIN_WINDOW_GET_PRIVATE(window)};
2141 if (g_strcmp0 (GNC_PREF_TAB_COLOR, pref) == 0)
2154 gboolean tabs_left_right;
2158 populate_tab_width_struct (
void)
2164 tw->tabs_left_right =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT) ||
2192 gnc_main_window_set_tab_ellipsize (GtkWidget *
label, gint tab_width, gboolean tab_left_right)
2194 const gchar *lab_text = gtk_label_get_text (GTK_LABEL(
label));
2198 gint text_length = g_utf8_strlen (lab_text, -1);
2199 if (text_length < tab_width)
2202 gtk_label_set_width_chars (GTK_LABEL(
label), tab_width);
2204 gtk_label_set_width_chars (GTK_LABEL(
label), text_length);
2206 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_NONE);
2210 gtk_label_set_width_chars (GTK_LABEL(
label), tab_width);
2211 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_MIDDLE);
2216 gtk_label_set_width_chars (GTK_LABEL(
label), 15);
2217 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_NONE);
2233 gnc_main_window_update_tab_width_one_page (
GncPluginPage *page,
2236 auto tw{
static_cast<TabWidth*
>(user_data)};
2238 ENTER(
"page %p, tab width %d, tabs on left or right %d",
2239 page, tw->tab_width, tw->tabs_left_right);
2241 auto label{
static_cast<GtkWidget *
>(g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL))};
2247 gnc_main_window_set_tab_ellipsize (
label, tw->tab_width, tw->tabs_left_right);
2265 gnc_main_window_update_tab_width (gpointer prefs, gchar *pref, gpointer user_data)
2271 tw = populate_tab_width_struct ();
2284 main_window_find_tab_items (GncMainWindow *window,
2286 GtkWidget **label_p,
2287 GtkWidget **entry_p)
2290 GtkWidget *tab_hbox, *widget, *tab_widget;
2291 GList *children, *tmp;
2293 ENTER(
"window %p, page %p, label_p %p, entry_p %p",
2294 window, page, label_p, entry_p);
2295 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2296 *label_p = *entry_p =
nullptr;
2300 LEAVE(
"invalid notebook_page");
2304 tab_widget = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->
notebook),
2308 tab_hbox = tab_widget;
2310 if (g_strcmp0(gtk_widget_get_name(tab_hbox),
"tab-content") == 0) {
2313 GList* _children = gtk_container_get_children(GTK_CONTAINER(tab_hbox));
2314 tab_hbox = _children ? GTK_WIDGET(_children->data) : nullptr;
2315 g_list_free(_children);
2318 if (!GTK_IS_BOX(tab_hbox))
2320 PWARN (
"Unknown widget for tab label %p", tab_widget);
2324 children = gtk_container_get_children(GTK_CONTAINER(tab_hbox));
2325 for (tmp = children; tmp; tmp = g_list_next(tmp))
2327 widget =
static_cast<GtkWidget*
>(tmp->data);
2328 if (GTK_IS_LABEL(widget))
2332 else if (GTK_IS_ENTRY(widget))
2337 g_list_free(children);
2339 LEAVE(
"label %p, entry %p", *label_p, *entry_p);
2340 return (*label_p && *entry_p);
2344 main_window_find_tab_widget (GncMainWindow *window,
2346 GtkWidget **widget_p)
2350 ENTER(
"window %p, page %p, widget %p",
2351 window, page, widget_p);
2352 *widget_p =
nullptr;
2356 LEAVE(
"invalid notebook_page");
2360 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2361 *widget_p = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->
notebook),
2364 LEAVE(
"widget %p", *widget_p);
2370 const gchar *long_name_in)
2372 GtkWidget *tab_widget;
2376 if ((long_name_in ==
nullptr) || (*long_name_in ==
'\0'))
2381 gchar *long_name = g_strstrip (g_strdup (long_name_in));
2385 if (*long_name ==
'\0' || strcmp (long_name, old_long_name) == 0)
2388 LEAVE(
"empty string or name unchanged");
2394 GncMainWindow *window = GNC_MAIN_WINDOW(page->
window);
2398 LEAVE(
"no window widget available");
2403 if (main_window_find_tab_widget (window, page, &tab_widget))
2404 gtk_widget_set_tooltip_text (tab_widget, long_name);
2412 const gchar *name_in)
2414 GncMainWindow *window;
2416 GtkWidget *
label, *entry;
2422 if ((name_in ==
nullptr) || (*name_in ==
'\0'))
2427 name = g_strstrip(g_strdup(name_in));
2433 LEAVE(
"empty string or name unchanged");
2441 window = GNC_MAIN_WINDOW(page->
window);
2445 LEAVE(
"no window widget available");
2449 if (main_window_find_tab_items(window, page, &
label, &entry))
2450 gtk_label_set_text(GTK_LABEL(
label), name);
2453 tw = populate_tab_width_struct ();
2454 gnc_main_window_update_tab_width_one_page (page, tw);
2460 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2461 label = gtk_notebook_get_menu_label (GTK_NOTEBOOK(priv->
notebook),
2463 gtk_label_set_text(GTK_LABEL(
label), name);
2467 gnc_main_window_update_title(window);
2475 const gchar *color_in)
2477 GncMainWindow *window;
2479 GtkWidget *tab_widget;
2481 gchar *color_string =
nullptr;
2482 gboolean want_color = FALSE;
2486 color_string = g_strstrip(g_strdup(color_in));
2488 if (color_string && *color_string !=
'\0')
2492 window = GNC_MAIN_WINDOW(page->
window);
2499 main_window_find_tab_widget (window, page, &tab_widget);
2500 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2502 if (want_color && gdk_rgba_parse(&tab_color, color_string) && priv->
show_color_tabs)
2504 GtkCssProvider *provider = gtk_css_provider_new();
2505 GtkStyleContext *stylectxt;
2506 gchar *col_str, *widget_css;
2508 if (!GTK_IS_EVENT_BOX (tab_widget))
2510 GtkWidget *event_box = gtk_event_box_new ();
2511 g_object_ref (tab_widget);
2512 gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->
notebook),
2514 gtk_container_add (GTK_CONTAINER(event_box), tab_widget);
2515 g_object_unref (tab_widget);
2516 tab_widget = event_box;
2519 stylectxt = gtk_widget_get_style_context (GTK_WIDGET (tab_widget));
2520 col_str = gdk_rgba_to_string (&tab_color);
2521 widget_css = g_strconcat (
"*{\n background-color:", col_str,
";\n}\n",
nullptr);
2523 gtk_css_provider_load_from_data (provider, widget_css, -1,
nullptr);
2524 gtk_style_context_add_provider (stylectxt, GTK_STYLE_PROVIDER (provider),
2525 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
2526 g_object_unref (provider);
2528 g_free (widget_css);
2532 if (GTK_IS_EVENT_BOX (tab_widget))
2534 GtkWidget *tab_hbox = gtk_bin_get_child(GTK_BIN(tab_widget));
2535 g_object_ref (tab_hbox);
2536 gtk_container_remove (GTK_CONTAINER(tab_widget), tab_hbox);
2537 gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->
notebook),
2539 g_object_unref (tab_hbox);
2542 g_free(color_string);
2551 GncMainWindow *window;
2552 GtkWidget *tab_widget;
2553 GtkWidget *image = NULL;
2555 gchar *image_name = NULL;
2556 const gchar *icon_name;
2560 g_return_if_fail (page && page->
window);
2562 if (!GNC_IS_MAIN_WINDOW (page->
window))
2565 window = GNC_MAIN_WINDOW(page->
window);
2568 main_window_find_tab_widget (window, page, &tab_widget);
2572 LEAVE(
"no tab widget");
2576 if (GTK_IS_EVENT_BOX(tab_widget))
2577 tab_widget = gtk_bin_get_child (GTK_BIN(tab_widget));
2579 children = gtk_container_get_children (GTK_CONTAINER(tab_widget));
2581 for (GList *child = children; child; child = g_list_next (child))
2583 GtkWidget *widget =
static_cast<GtkWidget*
>(child->data);
2584 if (GTK_IS_IMAGE(widget))
2587 g_list_free (children);
2591 LEAVE(
"no image to replace");
2595 g_object_get (image,
"icon-name", &image_name, NULL);
2598 icon_name =
"changes-prevent-symbolic";
2600 icon_name = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
2602 if (g_strcmp0 (icon_name, image_name) == 0)
2604 LEAVE(
"page icon the same, no need to replace");
2605 g_free (image_name);
2608 gtk_container_remove (GTK_CONTAINER(tab_widget), image);
2609 image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
2610 gtk_widget_show (image);
2612 gtk_container_add (GTK_CONTAINER(tab_widget), image);
2613 gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
2614 gtk_box_reorder_child (GTK_BOX(tab_widget), image, 0);
2616 g_free (image_name);
2622 gnc_main_window_tab_entry_activate (GtkWidget *entry,
2625 GtkWidget *
label, *entry2;
2627 g_return_if_fail(GTK_IS_ENTRY(entry));
2628 g_return_if_fail(GNC_IS_PLUGIN_PAGE(page));
2631 if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->
window),
2632 page, &
label, &entry2))
2634 LEAVE(
"can't find required widgets");
2640 gtk_widget_hide(entry);
2641 gtk_widget_show(
label);
2647 gnc_main_window_tab_entry_editing_done (GtkWidget *entry,
2651 gnc_main_window_tab_entry_activate(entry, page);
2657 gnc_main_window_tab_entry_focus_out_event (GtkWidget *entry,
2662 gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(entry));
2668 gnc_main_window_tab_entry_key_press_event (GtkWidget *entry,
2672 if (event->keyval == GDK_KEY_Escape)
2674 GtkWidget *
label, *entry2;
2676 g_return_val_if_fail(GTK_IS_ENTRY(entry), FALSE);
2677 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
2680 if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->
window),
2681 page, &
label, &entry2))
2683 LEAVE(
"can't find required widgets");
2687 gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(
label)));
2688 gtk_widget_hide(entry);
2689 gtk_widget_show(
label);
2711 GObjectClass *object_class = G_OBJECT_CLASS (klass);
2712 GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS(klass);
2714 window_type = g_quark_from_static_string (
"gnc-main-window");
2716 object_class->constructed = gnc_main_window_constructed;
2717 object_class->finalize = gnc_main_window_finalize;
2720 gtkwidget_class->destroy = gnc_main_window_destroy;
2733 main_window_signals[PAGE_ADDED] =
2734 g_signal_new (
"page_added",
2735 G_OBJECT_CLASS_TYPE (object_class),
2739 g_cclosure_marshal_VOID__OBJECT,
2753 main_window_signals[PAGE_CHANGED] =
2754 g_signal_new (
"page_changed",
2755 G_OBJECT_CLASS_TYPE (object_class),
2759 g_cclosure_marshal_VOID__OBJECT,
2771 main_window_signals[MENU_CHANGED] =
2772 g_signal_new (
"menu_changed",
2773 G_OBJECT_CLASS_TYPE (object_class),
2777 g_cclosure_marshal_VOID__OBJECT,
2782 GNC_PREF_SHOW_CLOSE_BUTTON,
2783 (gpointer)gnc_main_window_update_tab_close,
2787 (gpointer)gnc_main_window_update_tab_width,
2790 gnc_hook_add_dangler(HOOK_BOOK_SAVED,
2791 (GFunc)gnc_main_window_update_all_titles,
nullptr,
nullptr);
2792 gnc_hook_add_dangler(HOOK_BOOK_OPENED,
2793 (GFunc)gnc_main_window_attach_to_book,
nullptr,
nullptr);
2804 gnc_main_window_init (GncMainWindow *window)
2809 gtk_widget_set_name (GTK_WIDGET(window),
"gnc-id-main-window");
2816 priv->display_item_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
nullptr);
2818 priv->previous_plugin_page_name =
nullptr;
2819 priv->previous_menu_qualifier =
nullptr;
2822 gtk_window_add_accel_group (GTK_WINDOW(window), priv->
accel_group);
2829 (gpointer)gnc_main_window_update_tab_color,
2832 gnc_main_window_setup_window (window);
2842 gnc_main_window_constructed (GObject *obj)
2846 G_OBJECT_CLASS (gnc_main_window_parent_class)->constructed (obj);
2860 gnc_main_window_finalize (GObject *
object)
2862 g_return_if_fail (
object !=
nullptr);
2863 g_return_if_fail (GNC_IS_MAIN_WINDOW (
object));
2865 if (active_windows ==
nullptr)
2872 G_OBJECT_CLASS (gnc_main_window_parent_class)->finalize (
object);
2877 gnc_main_window_remove_prefs (GncMainWindow *window)
2882 (gpointer)gnc_main_window_update_tab_color,
2886 GNC_PREF_SHOW_CLOSE_BUTTON,
2887 (gpointer)gnc_main_window_update_tab_close,
2892 (gpointer)gnc_main_window_update_tab_width,
2896 GNC_PREF_TAB_POSITION_TOP,
2897 (gpointer)gnc_main_window_update_tab_position,
2901 GNC_PREF_TAB_POSITION_BOTTOM,
2902 (gpointer)gnc_main_window_update_tab_position,
2906 GNC_PREF_TAB_POSITION_LEFT,
2907 (gpointer)gnc_main_window_update_tab_position,
2911 GNC_PREF_TAB_POSITION_RIGHT,
2912 (gpointer)gnc_main_window_update_tab_position,
2920 gnc_prefs_set_reg_negative_color_pref_id (0);
2928 gnc_prefs_set_reg_auto_raise_lists_id (0);
2934 gnc_main_window_destroy (GtkWidget *widget)
2936 GncMainWindow *window;
2938 GncPluginManager *manager;
2941 g_return_if_fail (widget !=
nullptr);
2942 g_return_if_fail (GNC_IS_MAIN_WINDOW (widget));
2944 window = GNC_MAIN_WINDOW (widget);
2945 #ifdef MAC_INTEGRATION 2946 auto entry = g_list_find (active_windows, window);
2947 if (entry && (entry->next || entry->prev))
2948 gnc_quartz_set_menu (GNC_MAIN_WINDOW (entry->next ? entry->next->data : entry->prev->data));
2950 active_windows = g_list_remove (active_windows, window);
2953 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2961 if (gnc_window_get_progressbar_window() == GNC_WINDOW(window))
2962 gnc_window_set_progressbar_window(
nullptr);
2963 #ifndef MAC_INTEGRATION 2965 gnc_main_window_update_all_menu_items();
2968 gnc_main_window_remove_prefs (window);
2973 g_hash_table_destroy (priv->display_item_hash);
2978 g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
2979 g_list_free (plugins);
2982 GTK_WIDGET_CLASS (gnc_main_window_parent_class)->destroy (widget);
2987 gnc_main_window_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
2990 GdkModifierType modifiers;
2992 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(widget), FALSE);
2994 priv = GNC_MAIN_WINDOW_GET_PRIVATE(widget);
2996 modifiers = gtk_accelerator_get_default_mod_mask ();
2998 if ((event->state & modifiers) == (GDK_CONTROL_MASK | GDK_MOD1_MASK))
3000 const gchar *account_key = C_ (
"lower case key for short cut to 'Accounts'",
"a");
3001 guint account_keyval = gdk_keyval_from_name (account_key);
3003 if ((account_keyval == event->keyval) || (account_keyval == gdk_keyval_to_lower (event->keyval)))
3007 for (GList *item = priv->
installed_pages; item; item = g_list_next (item))
3011 if (g_strcmp0 (pname,
"GncPluginPageAccountTree") == 0)
3013 gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->
notebook), page);
3019 else if ((GDK_KEY_Menu == event->keyval) || (GDK_KEY_space == event->keyval))
3021 GList *menu = gtk_menu_get_for_attach_widget (GTK_WIDGET(priv->
notebook));
3025 gtk_menu_popup_at_widget (GTK_MENU(menu->data),
3043 auto window{
static_cast<GncMainWindow*
>(g_object_new (GNC_TYPE_MAIN_WINDOW,
nullptr))};
3044 gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
3050 gtk_window_get_size (old_window, &width, &height);
3051 gtk_window_resize (GTK_WINDOW (window), width, height);
3052 if ((gdk_window_get_state((gtk_widget_get_window (GTK_WIDGET(old_window))))
3053 & GDK_WINDOW_STATE_MAXIMIZED) != 0)
3055 gtk_window_maximize (GTK_WINDOW (window));
3058 active_windows = g_list_append (active_windows, window);
3059 gnc_main_window_update_title(window);
3060 window->window_quitting = FALSE;
3061 window->just_plugin_prefs = FALSE;
3062 #ifdef MAC_INTEGRATION 3063 gnc_quartz_set_menu(window);
3065 gnc_main_window_update_all_menu_items();
3070 g_signal_connect (G_OBJECT(window),
"key-press-event",
3071 G_CALLBACK(gnc_main_window_key_press_event),
3082 gnc_main_window_engine_commit_error_callback( gpointer data,
3085 GncMainWindow* window = GNC_MAIN_WINDOW(data);
3087 const gchar *reason = _(
"Unable to save to database.");
3089 reason = _(
"Unable to save to database: Book is marked read-only.");
3090 dialog = gtk_message_dialog_new( GTK_WINDOW(window),
3091 GTK_DIALOG_DESTROY_WITH_PARENT,
3096 gtk_dialog_run(GTK_DIALOG (dialog));
3097 gtk_widget_destroy(dialog);
3119 gnc_main_window_connect (GncMainWindow *window,
3121 GtkWidget *tab_hbox,
3122 GtkWidget *menu_label)
3125 GtkNotebook *notebook;
3126 gint current_position = -1;
3128 page->
window = GTK_WIDGET(window);
3129 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3130 notebook = GTK_NOTEBOOK (priv->
notebook);
3138 gtk_notebook_insert_page_menu (notebook, page->
notebook_page,
3139 tab_hbox, menu_label, current_position);
3140 gtk_notebook_set_tab_reorderable (notebook, page->
notebook_page, TRUE);
3141 gnc_plugin_page_inserted (page);
3143 gtk_notebook_set_current_page (notebook, current_position);
3145 if (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)
3146 (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)(page, GTK_WIDGET(window));
3147 g_signal_emit (window, main_window_signals[PAGE_ADDED], 0, page);
3149 g_signal_connect(G_OBJECT(page->
notebook_page),
"popup-menu",
3151 g_signal_connect_after(G_OBJECT(page->
notebook_page),
"button-press-event",
3170 gnc_main_window_disconnect (GncMainWindow *window,
3174 GtkNotebook *notebook;
3179 g_signal_handlers_disconnect_by_func(G_OBJECT(page->
notebook_page),
3181 g_signal_handlers_disconnect_by_func(G_OBJECT(page->
notebook_page),
3188 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3191 gnc_plugin_page_unselected (page);
3200 notebook = GTK_NOTEBOOK (priv->
notebook);
3206 page_num = gtk_notebook_page_num(notebook, new_page->
notebook_page);
3207 gtk_notebook_set_current_page(notebook, page_num);
3212 while (gtk_events_pending())
3213 gtk_main_iteration();
3218 page_num = gtk_notebook_page_num(notebook, page->
notebook_page);
3219 gtk_notebook_remove_page (notebook, page_num);
3221 if ( gtk_notebook_get_current_page(notebook) == -1)
3227 gnc_main_window_switch_page(notebook,
nullptr, -1, window);
3231 gnc_plugin_page_removed (page);
3233 gnc_window_set_status (GNC_WINDOW(window), page,
nullptr);
3245 GncMainWindow *window;
3247 GtkNotebook *notebook;
3250 window = GNC_MAIN_WINDOW (page->
window);
3251 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3252 notebook = GTK_NOTEBOOK (priv->
notebook);
3253 page_num = gtk_notebook_page_num(notebook, page->
notebook_page);
3254 gtk_notebook_set_current_page (notebook, page_num);
3255 gtk_window_present(GTK_WINDOW(window));
3271 GtkWidget *tab_container, *tab_clickable_area;
3272 GtkWidget *
label, *entry;
3273 const gchar *icon, *text, *color_string, *lab_text;
3278 ENTER(
"window %p, page %p", window, page);
3280 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3281 g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
3284 if (gnc_main_window_page_exists(page))
3294 for (tmp = active_windows; tmp; tmp = g_list_next(tmp))
3296 window = GNC_MAIN_WINDOW(tmp->data);
3297 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3305 gtk_widget_show(GTK_WIDGET(window));
3307 else if ((window ==
nullptr) && active_windows)
3309 window =
static_cast<GncMainWindow*
>(active_windows->data);
3312 page->
window = GTK_WIDGET(window);
3329 icon = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
3331 label = gtk_label_new (lab_text);
3332 g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL,
label);
3334 tw = populate_tab_width_struct ();
3335 gnc_main_window_update_tab_width_one_page (page, tw);
3338 gtk_widget_show (
label);
3340 tab_container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
3345 gtk_widget_set_tooltip_text(tab_container, text);
3349 gtk_widget_set_name (GTK_WIDGET(tab_container),
"gnc-id-account-page-tab-box");
3351 gtk_box_set_homogeneous (GTK_BOX (tab_container), FALSE);
3352 gtk_widget_show (tab_container);
3355 tab_clickable_area = gtk_event_box_new();
3356 gtk_widget_show(tab_clickable_area);
3357 gtk_box_pack_start (GTK_BOX (tab_container), tab_clickable_area, TRUE, TRUE, 0);
3361 GtkWidget *tab_content = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
3362 gtk_widget_set_name(tab_content,
"tab-content");
3363 gtk_container_add(GTK_CONTAINER(tab_clickable_area), tab_content);
3364 gtk_widget_show(tab_content);
3366 if (icon !=
nullptr)
3368 image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
3369 gtk_widget_show (image);
3370 gtk_box_pack_start (GTK_BOX (tab_content), image, FALSE, FALSE, 0);
3371 gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
3372 gtk_box_pack_start (GTK_BOX (tab_content),
label, TRUE, TRUE, 0);
3375 gtk_box_pack_start (GTK_BOX (tab_content),
label, TRUE, TRUE, 0);
3377 entry = gtk_entry_new();
3378 gtk_widget_hide (entry);
3379 gtk_box_pack_start (GTK_BOX (tab_content), entry, TRUE, TRUE, 0);
3380 g_signal_connect(G_OBJECT(entry),
"activate",
3381 G_CALLBACK(gnc_main_window_tab_entry_activate), page);
3382 g_signal_connect(G_OBJECT(entry),
"focus-out-event",
3383 G_CALLBACK(gnc_main_window_tab_entry_focus_out_event),
3385 g_signal_connect(G_OBJECT(entry),
"key-press-event",
3386 G_CALLBACK(gnc_main_window_tab_entry_key_press_event),
3388 g_signal_connect(G_OBJECT(entry),
"editing-done",
3389 G_CALLBACK(gnc_main_window_tab_entry_editing_done),
3393 if (!g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE))
3395 GtkWidget *close_image, *close_button;
3396 GtkRequisition requisition;
3398 close_button = gtk_button_new();
3399 gtk_button_set_relief(GTK_BUTTON(close_button), GTK_RELIEF_NONE);
3400 close_image = gtk_image_new_from_icon_name (
"window-close", GTK_ICON_SIZE_MENU);
3401 gtk_widget_show(close_image);
3402 gtk_widget_get_preferred_size (close_image, &requisition,
nullptr);
3403 gtk_widget_set_size_request(close_button, requisition.width + 4,
3404 requisition.height + 2);
3405 gtk_container_add(GTK_CONTAINER(close_button), close_image);
3407 gtk_widget_show (close_button);
3409 gtk_widget_hide (close_button);
3412 g_signal_connect(G_OBJECT(tab_clickable_area),
"button-press-event",
3413 G_CALLBACK(gnc_tab_clicked_cb), page);
3415 g_signal_connect_swapped (G_OBJECT (close_button),
"clicked",
3418 gtk_box_pack_start (GTK_BOX (tab_container), close_button, FALSE, FALSE, 0);
3419 gtk_widget_set_margin_end (GTK_WIDGET(close_button), 5);
3420 g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON, close_button);
3431 gnc_main_window_connect(window, page, tab_container,
label);
3447 GncMainWindow *window;
3456 if (!GNC_IS_MAIN_WINDOW (page->
window))
3459 window = GNC_MAIN_WINDOW (page->
window);
3462 g_warning(
"Page is not in a window.");
3466 gnc_main_window_disconnect(window, page);
3468 g_object_unref(page);
3471 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3474 if (window->window_quitting)
3480 window->just_plugin_prefs = TRUE;
3481 g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
3482 window->just_plugin_prefs = FALSE;
3483 g_list_free (plugins);
3486 gnc_main_window_remove_prefs (window);
3489 gtk_widget_destroy (GTK_WIDGET(window));
3506 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3518 const gchar *group_name,
3519 GSimpleActionGroup *group)
3521 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3522 g_return_if_fail (group_name !=
nullptr);
3523 g_return_if_fail (G_IS_SIMPLE_ACTION_GROUP(group));
3525 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
3526 G_ACTION_GROUP(group));
3531 update_menu_model (GncMainWindow *window,
const gchar *ui_filename,
3532 const gchar **ui_updates)
3535 GError *error =
nullptr;
3537 GtkBuilder *builder = gtk_builder_new ();
3538 GMenuModel *menu_model_part;
3539 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
3541 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3542 g_return_if_fail (ui_filename !=
nullptr);
3543 g_return_if_fail (ui_updates !=
nullptr);
3545 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3547 gtk_builder_set_translation_domain (builder, PROJECT_NAME);
3548 res_name = g_strconcat (GNUCASH_RESOURCE_PREFIX
"/", ui_filename, NULL);
3550 gtk_builder_add_from_resource (builder, res_name, &error);
3555 g_critical (
"Failed to load, Error %s", error->message);
3556 g_error_free (error);
3560 for (gint i = 0; ui_updates[i]; i++)
3562 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, ui_updates[i]);
3564 gsm->search_action_label =
nullptr;
3565 gsm->search_action_name = ui_updates[i];
3566 gsm->search_action_target =
nullptr;
3569 g_menu_insert_section (G_MENU(gsm->model), gsm->index, NULL, G_MENU_MODEL(menu_model_part));
3571 PERR(
"Could not find '%s' in menu model", ui_updates[i]);
3574 g_object_unref (builder);
3586 const gchar *group_name,
3587 GActionEntry *actions,
3589 const gchar **ui_updates,
3590 const gchar *ui_filename,
3594 GSimpleActionGroup *simple_action_group;
3596 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3597 g_return_if_fail (group_name !=
nullptr);
3598 g_return_if_fail (actions !=
nullptr);
3599 g_return_if_fail (n_actions > 0);
3602 data->window = window;
3603 data->data = user_data;
3605 simple_action_group = g_simple_action_group_new ();
3607 g_action_map_add_action_entries (G_ACTION_MAP(simple_action_group),
3612 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
3613 G_ACTION_GROUP(simple_action_group));
3616 update_menu_model (window, ui_filename, ui_updates);
3627 const gchar *group_name)
3629 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3630 g_return_if_fail (group_name !=
nullptr);
3632 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
nullptr);
3638 GAction *action =
nullptr;
3640 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3641 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3643 action = g_action_map_lookup_action (G_ACTION_MAP(window),
3651 const gchar *group_name,
3654 GAction *action =
nullptr;
3656 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3657 g_return_val_if_fail (group_name !=
nullptr,
nullptr);
3658 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3660 auto action_group = gtk_widget_get_action_group (GTK_WIDGET(window), group_name);
3663 action = g_action_map_lookup_action (G_ACTION_MAP(action_group),
action_name);
3673 GSimpleActionGroup *
3675 const gchar *group_name)
3677 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3678 g_return_val_if_fail (group_name !=
nullptr,
nullptr);
3680 auto action_group = gtk_widget_get_action_group (GTK_WIDGET(window), group_name);
3681 return (GSimpleActionGroup*)action_group;
3689 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3690 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3692 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3701 GtkWidget *menu_item;
3703 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3704 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3706 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3708 menu_item = GTK_WIDGET(g_hash_table_lookup (priv->display_item_hash,
action_name));
3714 g_hash_table_insert (priv->display_item_hash, g_strdup (
action_name), menu_item);
3725 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3727 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3737 const gchar *tooltip)
3740 gboolean found =
false;
3742 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
false);
3743 g_return_val_if_fail (
action_name !=
nullptr,
false);
3744 g_return_val_if_fail (
label !=
nullptr,
false);
3746 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3749 nullptr, _(
label),
nullptr, _(tooltip));
3761 const gchar **action_names,
3766 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3768 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3770 for (gint i = 0; action_names[i]; i++)
3777 PINFO(
"Found menu_item %p with action name '%s', seting vis to '%s'",
3778 menu_item, action_names[i], vis ?
"true" :
"false");
3779 gtk_widget_set_visible (menu_item, vis);
3782 PINFO(
"Did not find menu_item with action name '%s' to set vis '%s'",
3783 action_names[i], vis ?
"true" :
"false");
3787 PINFO(
"Found tool_item %p with action name '%s', seting vis to '%s'",
3788 tool_item, action_names[i], vis ?
"true" :
"false");
3789 gtk_widget_set_visible (tool_item, vis);
3792 PINFO(
"Did not find tool_item with action name '%s' to set vis '%s'",
3793 action_names[i], vis ?
"true" :
"false");
3804 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3805 g_return_if_fail (toolbar_labels !=
nullptr);
3807 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3814 gnc_main_window_update_toolbar (GncMainWindow *window,
GncPluginPage *page,
3815 const gchar *toolbar_qualifier)
3818 GtkBuilder *builder;
3821 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3822 g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
3824 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3830 gchar *toolbar_name;
3833 if (toolbar_qualifier)
3834 toolbar_name = g_strconcat (
"mainwin-toolbar-", toolbar_qualifier,
nullptr);
3836 toolbar_name = g_strdup (
"mainwin-toolbar");
3838 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder, toolbar_name);
3841 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder,
"mainwin-toolbar");
3843 g_object_set (priv->
toolbar,
"toolbar-style", GTK_TOOLBAR_BOTH, NULL);
3845 g_free (toolbar_name);
3853 GVariant *state = g_action_get_state (G_ACTION(action));
3854 gtk_widget_set_visible (priv->
toolbar, g_variant_get_boolean (state));
3855 g_variant_unref (state);
3865 const gchar **ui_updates)
3868 const gchar *plugin_page_actions_group_name;
3869 GtkBuilder *builder;
3870 const gchar *menu_qualifier;
3872 GMenuModel *menu_model_part;
3873 #ifdef MAC_INTEGRATION 3874 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
3876 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3877 g_return_if_fail (page !=
nullptr);
3878 g_return_if_fail (ui_updates !=
nullptr);
3880 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3891 if (!plugin_page_actions_group_name)
3897 if ((g_strcmp0 (priv->previous_plugin_page_name,
3898 plugin_page_actions_group_name) == 0) &&
3899 (g_strcmp0 (priv->previous_menu_qualifier,
3900 menu_qualifier) == 0))
3903 priv->previous_plugin_page_name = plugin_page_actions_group_name;
3904 priv->previous_menu_qualifier = menu_qualifier;
3906 gnc_main_window_update_toolbar (window, page, menu_qualifier);
3909 g_hash_table_remove_all (priv->display_item_hash);
3911 GNC_MENU_ATTRIBUTE_TEMPORARY);
3913 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
3914 for (gint i = 0; ui_updates[i]; i++)
3919 menu_name = g_strconcat (ui_updates[i],
"-", menu_qualifier,
nullptr);
3921 menu_name = g_strdup (ui_updates[i]);
3923 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, menu_name);
3925 if (!menu_model_part)
3926 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, ui_updates[i]);
3928 gsm->search_action_label =
nullptr;
3929 gsm->search_action_name = ui_updates[i];
3930 gsm->search_action_target =
nullptr;
3933 g_menu_insert_section (G_MENU(gsm->model), gsm->index,
3934 nullptr, G_MENU_MODEL(menu_model_part));
3936 PERR(
"Could not find '%s' in menu model", ui_updates[i]);
3946 #ifdef MAC_INTEGRATION 3947 gtkosx_application_sync_menubar (theApp);
3948 g_object_unref (theApp);
3951 g_signal_emit_by_name (window,
"menu_changed", page);
3958 gnc_main_window_update_tab_position (gpointer prefs, gchar *pref, gpointer user_data)
3960 GncMainWindow *window;
3961 GtkPositionType position = GTK_POS_TOP;
3966 g_return_if_fail (GNC_IS_MAIN_WINDOW(user_data));
3968 window = GNC_MAIN_WINDOW(user_data);
3970 ENTER (
"window %p", window);
3979 position = GTK_POS_BOTTOM;
3984 position = GTK_POS_LEFT;
3989 position = GTK_POS_RIGHT;
3993 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3994 gtk_notebook_set_tab_pos (GTK_NOTEBOOK(priv->
notebook), position);
3996 action = g_action_map_lookup_action (G_ACTION_MAP(window),
3997 "ViewTabPositionAction");
3999 g_signal_handlers_block_by_func (G_OBJECT(action),
4000 (gpointer)gnc_main_window_cmd_view_tab_position,
4002 g_action_change_state (G_ACTION(action), g_variant_new_int32 (item));
4003 g_signal_handlers_unblock_by_func (G_OBJECT(action),
4004 (gpointer)gnc_main_window_cmd_view_tab_position,
4007 gnc_main_window_update_tab_width (
nullptr, (
char*)GNC_PREF_TAB_WIDTH,
nullptr);
4016 gnc_main_window_update_edit_actions_sensitivity (GncMainWindow *window, gboolean hide)
4020 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));
4022 gboolean can_copy =
false, can_cut =
false, can_paste =
false;
4024 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4027 if (page && GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)
4029 (GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)(page, hide);
4033 if (GTK_IS_EDITABLE (widget))
4035 gboolean has_selection;
4037 has_selection = gtk_editable_get_selection_bounds
4038 (GTK_EDITABLE (widget),
nullptr,
nullptr);
4040 can_copy = has_selection;
4041 can_cut = has_selection;
4044 else if (GTK_IS_TEXT_VIEW (widget))
4046 gboolean has_selection;
4047 GtkTextBuffer *text_buffer;
4049 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4050 has_selection = gtk_text_buffer_get_selection_bounds
4051 (text_buffer,
nullptr,
nullptr);
4053 can_copy = has_selection;
4054 can_cut = has_selection;
4059 #ifdef ORIGINAL_EPIPHANY_CODE 4061 can_copy = can_cut = can_paste =
true;
4065 can_copy = can_cut = can_paste =
false;
4069 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_copy);
4072 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_cut);
4075 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_paste);
4079 gnc_main_window_enable_edit_actions_sensitivity (GncMainWindow *window)
4084 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4087 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4090 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4095 gnc_main_window_edit_menu_show_cb (GtkWidget *menu,
4096 GncMainWindow *window)
4098 gnc_main_window_update_edit_actions_sensitivity (window, FALSE);
4102 gnc_main_window_edit_menu_hide_cb (GtkWidget *menu,
4103 GncMainWindow *window)
4105 gnc_main_window_enable_edit_actions_sensitivity (window);
4109 gnc_main_window_init_menu_updaters (GncMainWindow *window)
4111 GtkWidget *edit_menu_item, *edit_menu;
4115 edit_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM(edit_menu_item));
4117 g_signal_connect (edit_menu,
"show",
4118 G_CALLBACK(gnc_main_window_edit_menu_show_cb), window);
4119 g_signal_connect (edit_menu,
"hide",
4120 G_CALLBACK(gnc_main_window_edit_menu_hide_cb), window);
4125 gnc_main_window_page_focus_in (GtkWidget *widget, GdkEvent *event,
4128 auto window{
static_cast<GncMainWindow *
>(user_data)};
4131 g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
4136 gnc_main_window_get_redirect (GncMainWindow *window,
const gchar *
action_name)
4139 GAction *action =
nullptr;
4140 const gchar *group_name;
4142 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window),
nullptr);
4143 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
4145 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4159 PINFO(
"Redirect action is %p for action anme '%s' and group_name '%s'",
4165 main_window_realize_cb (GtkWidget *widget, gpointer user_data)
4167 GncMainWindow *window = (GncMainWindow*)user_data;
4174 g_signal_emit_by_name (window,
"menu_changed",
nullptr);
4178 gnc_main_window_setup_window (GncMainWindow *window)
4181 GtkWidget *main_vbox;
4182 GtkBuilder *builder;
4183 GncPluginManager *manager;
4185 GError *error =
nullptr;
4191 g_signal_connect (G_OBJECT (window),
"delete-event",
4192 G_CALLBACK (gnc_main_window_delete_event), window);
4195 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4196 gtk_box_set_homogeneous (GTK_BOX (main_vbox), FALSE);
4197 gtk_widget_show (main_vbox);
4198 gtk_container_add (GTK_CONTAINER (window), main_vbox);
4200 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4201 priv->
menu_dock = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4202 gtk_box_set_homogeneous (GTK_BOX (priv->
menu_dock), FALSE);
4204 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
menu_dock,
4207 priv->
notebook = gtk_notebook_new ();
4208 g_object_set(G_OBJECT(priv->
notebook),
4210 "enable-popup", TRUE,
4213 g_signal_connect (G_OBJECT (priv->
notebook),
"switch-page",
4214 G_CALLBACK (gnc_main_window_switch_page), window);
4215 g_signal_connect (G_OBJECT (priv->
notebook),
"page-reordered",
4216 G_CALLBACK (gnc_main_window_page_reordered), window);
4217 g_signal_connect (G_OBJECT (priv->
notebook),
"focus-in-event",
4218 G_CALLBACK (gnc_main_window_page_focus_in), window);
4219 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
notebook,
4224 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
statusbar,
4228 gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR(priv->
progressbar), TRUE);
4229 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(priv->
progressbar),
" ");
4233 gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(priv->
progressbar),
4236 builder = gtk_builder_new ();
4237 gtk_builder_set_translation_domain (builder, PROJECT_NAME);
4238 gtk_builder_add_from_resource (builder, GNUCASH_RESOURCE_PREFIX
"/gnc-main-window.ui", &error);
4242 g_critical (
"Failed to load, Error %s", error->message);
4243 g_error_free (error);
4247 g_action_map_add_action_entries (G_ACTION_MAP(window),
4252 priv->
menubar_model = (GMenuModel *)gtk_builder_get_object (builder,
"mainwin-menu");
4255 gtk_widget_show (GTK_WIDGET(priv->
menubar));
4257 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder,
"mainwin-toolbar");
4258 g_object_set (priv->
toolbar,
"toolbar-style", GTK_TOOLBAR_BOTH, NULL);
4259 gtk_container_add (GTK_CONTAINER(priv->
menu_dock), GTK_WIDGET(priv->
toolbar));
4260 gtk_widget_show (GTK_WIDGET(priv->
toolbar));
4262 g_object_unref (builder);
4265 initially_insensitive_actions,
4268 always_insensitive_actions,
4274 gtk_widget_insert_action_group (GTK_WIDGET(window),
"mainwin",
4275 G_ACTION_GROUP(window));
4278 GNC_PREF_TAB_POSITION_TOP,
4279 (gpointer)gnc_main_window_update_tab_position,
4282 GNC_PREF_TAB_POSITION_BOTTOM,
4283 (gpointer)gnc_main_window_update_tab_position,
4286 GNC_PREF_TAB_POSITION_LEFT,
4287 (gpointer)gnc_main_window_update_tab_position,
4290 GNC_PREF_TAB_POSITION_RIGHT,
4291 (gpointer)gnc_main_window_update_tab_position,
4293 gnc_main_window_update_tab_position (
nullptr,
nullptr, window);
4295 gnc_main_window_init_menu_updaters (window);
4299 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4302 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4305 if (!gnc_prefs_is_extra_enabled())
4308 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4314 g_list_foreach (plugins, gnc_main_window_add_plugin, window);
4315 g_list_free (plugins);
4317 g_signal_connect (G_OBJECT (manager),
"plugin-added",
4318 G_CALLBACK (gnc_main_window_plugin_added), window);
4319 g_signal_connect (G_OBJECT (manager),
"plugin-removed",
4320 G_CALLBACK (gnc_main_window_plugin_removed), window);
4323 g_signal_connect (G_OBJECT(window),
"realize",
4324 G_CALLBACK(main_window_realize_cb), window);
4329 #ifdef MAC_INTEGRATION 4338 gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data)
4349 gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window)
4352 gnc_main_window_quit (window);
4357 can_activate_cb(GtkWidget *widget, guint signal_id, gpointer data)
4364 gnc_quartz_set_menu (GncMainWindow* window)
4367 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
4368 GtkWidget *item =
nullptr;
4369 GClosure *quit_closure;
4371 gtk_widget_hide (priv->
menubar);
4372 gtk_widget_set_no_show_all (priv->
menubar,
true);
4374 gtkosx_application_set_menu_bar (theApp, GTK_MENU_SHELL(priv->
menubar));
4379 gtk_widget_hide (GTK_WIDGET(item));
4381 quit_closure = g_cclosure_new (G_CALLBACK (gnc_quartz_should_quit),
4383 gtk_accel_group_connect (priv->
accel_group,
'q', GDK_META_MASK,
4384 GTK_ACCEL_MASK, quit_closure);
4391 gtk_widget_hide (item);
4392 gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET(item), 0);
4399 gtk_widget_hide (GTK_WIDGET(item));
4400 gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET(item), 2);
4406 gtkosx_application_set_help_menu (theApp, GTK_MENU_ITEM(item));
4410 gtkosx_application_set_window_menu (theApp, GTK_MENU_ITEM(item));
4412 g_signal_connect (theApp,
"NSApplicationBlockTermination",
4413 G_CALLBACK(gnc_quartz_should_quit), window);
4415 g_signal_connect (priv->
menubar,
"can-activate-accel",
4416 G_CALLBACK (can_activate_cb),
nullptr);
4418 gtkosx_application_set_use_quartz_accelerators (theApp, FALSE);
4419 g_object_unref (theApp);
4421 #endif //MAC_INTEGRATION 4438 gnc_main_window_show_summarybar (GncMainWindow *window, GAction *action)
4443 if (action ==
nullptr)
4444 action = g_action_map_lookup_action (G_ACTION_MAP(window),
4445 "ViewSummaryAction");
4446 if (action ==
nullptr)
4449 state = g_action_get_state (G_ACTION(action));
4451 visible = g_variant_get_boolean (state);
4453 g_variant_unref (state);
4468 gnc_main_window_switch_page (GtkNotebook *notebook,
4469 gpointer *notebook_page,
4471 GncMainWindow *window)
4478 ENTER(
"Notebook %p, page, %p, index %d, window %p",
4479 notebook, notebook_page, pos, window);
4480 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4482 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4486 gnc_plugin_page_unselected (page);
4489 child = gtk_notebook_get_nth_page (notebook, pos);
4501 if (page !=
nullptr)
4505 visible = gnc_main_window_show_summarybar (window,
nullptr);
4509 gnc_plugin_page_selected (page);
4510 gnc_window_update_status (GNC_WINDOW(window), page);
4518 multiple_page_actions,
4521 gnc_main_window_update_title(window);
4522 #ifndef MAC_INTEGRATION 4523 gnc_main_window_update_menu_item(window);
4525 g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
4536 gnc_main_window_page_reordered (GtkNotebook *notebook,
4539 GncMainWindow *window)
4545 ENTER(
"Notebook %p, child %p, index %d, window %p",
4546 notebook, child, pos, window);
4547 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4551 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4557 if (!old_link)
return;
4568 gnc_main_window_plugin_added (GncPlugin *manager,
4570 GncMainWindow *window)
4572 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4573 g_return_if_fail (GNC_IS_PLUGIN (plugin));
4579 gnc_main_window_plugin_removed (GncPlugin *manager,
4581 GncMainWindow *window)
4583 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4584 g_return_if_fail (GNC_IS_PLUGIN (plugin));
4592 gnc_main_window_cmd_redirect (GSimpleAction *simple,
4593 GVariant *parameter,
4596 GncMainWindow *window = (GncMainWindow*)user_data;
4597 GAction *redirect_action;
4599 PINFO(
"Redirect action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4601 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4603 if (redirect_action)
4605 PINFO(
"Found action %p", redirect_action);
4606 g_action_activate (redirect_action,
nullptr);
4612 gnc_main_window_cmd_page_setup (GSimpleAction *simple,
4613 GVariant *parameter,
4616 GncMainWindow *window = (GncMainWindow*)user_data;
4617 GtkWindow *gtk_window;
4619 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
4621 gtk_window = gnc_window_get_gtk_window(GNC_WINDOW(window));
4628 QofBook *book = gnc_get_current_book ();
4629 gboolean use_split_action_for_num_before =
4631 gint use_read_only_threshold_before =
4633 gboolean use_split_action_for_num_after;
4634 gint use_read_only_threshold_after;
4635 gboolean return_val = FALSE;
4636 GList *results =
nullptr, *iter;
4638 if (!options)
return return_val;
4641 for (iter = results; iter; iter = iter->next)
4649 gtk_dialog_run(GTK_DIALOG(dialog));
4650 gtk_widget_destroy(dialog);
4651 g_free (iter->data);
4653 g_list_free (results);
4654 qof_book_begin_edit (book);
4656 use_split_action_for_num_after =
4660 book->cached_num_days_autoreadonly_isvalid = FALSE;
4663 if (use_split_action_for_num_before != use_split_action_for_num_after)
4666 use_split_action_for_num_after);
4669 if (use_read_only_threshold_before != use_read_only_threshold_after)
4672 qof_book_commit_edit (book);
4680 auto options{
static_cast<GncOptionDB *
>(user_data)};
4682 if (!options)
return;
4685 gnc_gui_refresh_all ();
4692 auto options{
static_cast<GncOptionDB *
>(user_data)};
4704 gnc_suspend_gui_refresh ();
4711 GNC_FEATURE_NUM_FIELD_SOURCE);
4713 gnc_book_option_num_field_source_change (num_action);
4714 gnc_resume_gui_refresh ();
4718 show_handler (
const char *class_name, gint component_id,
4719 gpointer user_data, gpointer iter_data)
4726 auto widget = optwin->get_widget();
4727 gtk_window_present(GTK_WINDOW(widget));
4734 auto book = gnc_get_current_book ();
4743 if (gnc_forall_gui_components(DIALOG_BOOK_OPTIONS_CM_CLASS,
4744 show_handler,
nullptr))
4749 (title ? title : _(
"Book Options")),
4750 DIALOG_BOOK_OPTIONS_CM_CLASS, parent);
4751 optionwin->build_contents(options);
4752 optionwin->set_book_help_cb();
4753 optionwin->set_apply_cb(gnc_book_options_dialog_apply_cb,
4755 optionwin->set_close_cb ( gnc_book_options_dialog_close_cb,
4759 return optionwin->get_widget();
4763 gnc_main_window_cmd_file_properties (GSimpleAction *simple,
4764 GVariant *parameter,
4767 GncMainWindow *window = (GncMainWindow*)user_data;
4772 gnc_main_window_cmd_file_close (GSimpleAction *simple,
4773 GVariant *parameter,
4776 GncMainWindow *window = (GncMainWindow*)user_data;
4780 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
4782 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4788 gnc_main_window_cmd_file_quit (GSimpleAction *simple,
4789 GVariant *parameter,
4792 GncMainWindow *window = (GncMainWindow*)user_data;
4796 gnc_main_window_quit(window);
4800 gnc_main_window_cmd_edit_cut (GSimpleAction *simple,
4801 GVariant *parameter,
4804 GncMainWindow *window = (GncMainWindow*)user_data;
4805 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4806 GAction *redirect_action;
4808 PINFO(
"Copy action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4810 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4812 if (redirect_action)
4814 PINFO(
"Found action %p", redirect_action);
4815 g_action_activate (redirect_action,
nullptr);
4819 if (GTK_IS_EDITABLE(widget))
4821 gtk_editable_cut_clipboard (GTK_EDITABLE(widget));
4823 else if (GTK_IS_TEXT_VIEW(widget))
4825 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4826 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(widget),
4827 GDK_SELECTION_CLIPBOARD);
4828 gboolean editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(widget));
4831 gtk_text_buffer_cut_clipboard (text_buffer, clipboard, editable);
4836 gnc_main_window_cmd_edit_copy (GSimpleAction *simple,
4837 GVariant *parameter,
4840 GncMainWindow *window = (GncMainWindow*)user_data;
4841 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4842 GAction *redirect_action;
4844 PINFO(
"Copy action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4846 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4848 if (redirect_action)
4850 PINFO(
"Found action %p", redirect_action);
4851 g_action_activate (redirect_action,
nullptr);
4855 if (GTK_IS_EDITABLE(widget))
4857 gtk_editable_copy_clipboard (GTK_EDITABLE(widget));
4859 else if (GTK_IS_TEXT_VIEW(widget))
4861 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4862 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(widget),
4863 GDK_SELECTION_CLIPBOARD);
4865 gtk_text_buffer_copy_clipboard (text_buffer, clipboard);
4870 gnc_main_window_cmd_edit_paste (GSimpleAction *simple,
4871 GVariant *parameter,
4874 GncMainWindow *window = (GncMainWindow*)user_data;
4875 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4876 GAction *redirect_action;
4878 PINFO(
"Paste action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4880 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4882 if (redirect_action)
4884 PINFO(
"Found action %p", redirect_action);
4885 g_action_activate (redirect_action,
nullptr);
4889 if (GTK_IS_EDITABLE(widget))
4891 gtk_editable_paste_clipboard (GTK_EDITABLE(widget));
4893 else if (GTK_IS_TEXT_VIEW(widget))
4895 auto clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
4899 auto text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4900 auto editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(widget));
4901 gtk_text_buffer_paste_clipboard (text_buffer, clipboard,
nullptr,
4908 gnc_main_window_cmd_edit_preferences (GSimpleAction *simple,
4909 GVariant *parameter,
4912 GncMainWindow *window = (GncMainWindow*)user_data;
4917 gnc_main_window_cmd_view_refresh (GSimpleAction *simple,
4918 GVariant *parameter,
4924 gnc_main_window_cmd_actions_reset_warnings (GSimpleAction *simple,
4925 GVariant *parameter,
4928 GncMainWindow *window = (GncMainWindow*)user_data;
4929 gnc_reset_warnings_dialog(GTK_WINDOW(window));
4933 gnc_main_window_cmd_actions_rename_page (GSimpleAction *simple,
4934 GVariant *parameter,
4937 GncMainWindow *window = (GncMainWindow*)user_data;
4940 GtkWidget *
label, *entry;
4943 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4947 LEAVE(
"No current page");
4951 if (!main_window_find_tab_items(window, page, &
label, &entry))
4953 LEAVE(
"can't find required widgets");
4957 gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(
label)));
4958 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
4959 gtk_widget_hide(
label);
4960 gtk_widget_show(entry);
4961 gtk_widget_grab_focus(entry);
4962 LEAVE(
"opened for editing");
4966 gnc_main_window_cmd_view_toolbar (GSimpleAction *simple,
4967 GVariant *parameter,
4970 GncMainWindow *window = (GncMainWindow*)user_data;
4972 GVariant *state = g_action_get_state (G_ACTION(simple));
4974 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4976 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!g_variant_get_boolean (state)));
4978 if (!g_variant_get_boolean (state))
4979 gtk_widget_show (priv->
toolbar);
4981 gtk_widget_hide (priv->
toolbar);
4983 g_variant_unref (state);
4987 gnc_main_window_cmd_view_summary (GSimpleAction *simple,
4988 GVariant *parameter,
4991 GncMainWindow *window = (GncMainWindow*)user_data;
4996 visible = gnc_main_window_show_summarybar (window, G_ACTION(simple));
4998 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!
visible));
5008 gnc_main_window_cmd_view_statusbar (GSimpleAction *simple,
5009 GVariant *parameter,
5012 GncMainWindow *window = (GncMainWindow*)user_data;
5014 GVariant *state = g_action_get_state (G_ACTION(simple));
5016 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5018 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!g_variant_get_boolean (state)));
5020 if (!g_variant_get_boolean (state))
5025 g_variant_unref (state);
5029 gnc_main_window_cmd_window_new (GSimpleAction *simple,
5033 GncMainWindow *new_window;
5038 gtk_widget_show(GTK_WIDGET(new_window));
5043 gnc_main_window_cmd_window_move_page (GSimpleAction *simple,
5047 GncMainWindow *window = (GncMainWindow*)user_data;
5049 GncMainWindow *new_window;
5051 GtkNotebook *notebook;
5052 GtkWidget *tab_widget, *menu_widget;
5054 ENTER(
"action %p, window %p", simple, window);
5057 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5061 LEAVE(
"invalid page");
5066 LEAVE(
"invalid notebook_page");
5070 #ifndef MAC_INTEGRATION 5072 gnc_info_dialog (GTK_WINDOW(window),
"%s",
5073 _(
"The maximum number of window menu entries reached, no more entries will be added."));
5076 notebook = GTK_NOTEBOOK (priv->
notebook);
5077 tab_widget = gtk_notebook_get_tab_label (notebook, page->
notebook_page);
5078 menu_widget = gtk_notebook_get_menu_label (notebook, page->
notebook_page);
5085 g_object_ref(tab_widget);
5086 g_object_ref(menu_widget);
5088 gnc_main_window_disconnect(window, page);
5092 gtk_widget_show(GTK_WIDGET(new_window));
5095 gnc_main_window_connect (new_window, page, tab_widget, menu_widget);
5099 g_object_unref(menu_widget);
5100 g_object_unref(tab_widget);
5101 g_object_unref(page);
5104 DEBUG(
"Moved page %p from window %p to new window %p",
5105 page, window, new_window);
5106 DEBUG(
"Old window current is %p, new window current is %p",
5109 LEAVE(
"page moved");
5113 gnc_main_window_cmd_view_tab_position (GSimpleAction *simple,
5114 GVariant *parameter,
5117 gint item = g_variant_get_int32 (parameter);
5119 g_action_change_state (G_ACTION(simple), parameter);
5121 if (item < 0 || item > 3)
5124 if (item != 0 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_TOP))
5127 if (item != 1 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_BOTTOM))
5130 if (item != 2 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT))
5133 if (item != 3 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_RIGHT))
5157 #ifndef MAC_INTEGRATION 5159 gnc_main_window_cmd_window_raise (GSimpleAction *simple,
5160 GVariant *parameter,
5163 GncMainWindow *window = (GncMainWindow*)user_data;
5164 GncMainWindow *new_window;
5167 g_return_if_fail (G_IS_SIMPLE_ACTION(simple));
5168 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
5170 item = g_variant_get_int32 (parameter);
5172 ENTER(
"action %p, window %p, item %d", simple, window, item);
5174 g_action_change_state (G_ACTION(simple), parameter);
5176 new_window =
static_cast<GncMainWindow*
>(g_list_nth_data (active_windows, item));
5177 gtk_window_present (GTK_WINDOW(new_window));
5181 g_idle_add ((GSourceFunc)gnc_main_window_update_radio_button, window);
5187 gnc_main_window_cmd_help_tutorial (GSimpleAction *simple,
5191 GncMainWindow *window = (GncMainWindow*)user_data;
5196 gnc_main_window_cmd_help_contents (GSimpleAction *simple,
5200 GncMainWindow *window = (GncMainWindow*)user_data;
5214 get_file (
const gchar *partial)
5216 gchar *filename, *text =
nullptr;
5220 if (filename && g_file_get_contents(filename, &text, &length,
nullptr))
5244 get_file_strsplit (
const gchar *partial)
5246 gchar *text, **lines;
5248 text = get_file(partial);
5252 lines = g_strsplit_set(text,
"\r\n", -1);
5263 url_signal_cb (GtkAboutDialog *dialog, gchar *uri, gpointer data)
5270 link_button_cb (GtkLinkButton *button, gpointer user_data)
5272 const gchar *uri = gtk_link_button_get_uri (button);
5273 gchar *escaped_uri = g_uri_escape_string (uri,
":/.\\",
true);
5275 g_free (escaped_uri);
5280 add_about_paths (GtkDialog *dialog)
5288 PWARN(
"Unable to find AboutDialog 'page_vbox' Widget");
5292 grid = gtk_grid_new ();
5294 for (
const auto& ep : gnc_list_all_paths ())
5296 gchar *env_name = g_strconcat (ep.env_name,
":", NULL);
5297 GtkWidget *
label = gtk_label_new (env_name);
5299 gchar *display_uri = gnc_doclink_get_unescaped_just_uri (uri);
5300 GtkWidget *widget = gtk_link_button_new_with_label (uri, display_uri);
5302 gtk_grid_attach (GTK_GRID(grid),
label, 0, i, 1, 1);
5303 gtk_widget_set_halign (
label, GTK_ALIGN_END);
5304 gtk_grid_attach (GTK_GRID(grid), widget, 1, i, 1, 1);
5305 gtk_widget_set_halign (widget, GTK_ALIGN_START);
5306 gtk_widget_set_margin_top (widget, 0);
5307 gtk_widget_set_margin_bottom (widget, 0);
5311 GtkWidget *mod_lab = gtk_label_new (_(
"(user modifiable)"));
5312 gtk_grid_attach (GTK_GRID(grid), mod_lab, 2, i, 1, 1);
5313 gtk_widget_show (mod_lab);
5315 g_signal_connect (widget,
"activate-link",
5316 G_CALLBACK(link_button_cb), dialog);
5319 g_free (display_uri);
5322 gtk_container_add_with_properties (GTK_CONTAINER(page_vbox), grid,
5323 "position", 1, NULL);
5324 gtk_widget_show_all (grid);
5330 gnc_main_window_cmd_help_about (GSimpleAction *simple,
5334 GncMainWindow *window = (GncMainWindow*)user_data;
5336 gchar *copyright = g_strdup_printf(_(
"Copyright © 1997-%s The GnuCash contributors."),
5338 gchar **authors = get_file_strsplit(
"AUTHORS");
5339 gchar **documenters = get_file_strsplit(
"DOCUMENTERS");
5340 gchar *license = get_file(
"LICENSE");
5341 GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
5342 GdkPixbuf *logo = gtk_icon_theme_load_icon (icon_theme,
5345 GTK_ICON_LOOKUP_USE_BUILTIN,
5347 gchar *version = g_strdup_printf (
"%s: %s\n%s: %s\nFinance::Quote: %s",
5349 _(
"Build ID"), gnc_build_id(),
5353 GtkDialog *dialog = GTK_DIALOG (gtk_about_dialog_new ());
5354 g_object_set (G_OBJECT (dialog),
5356 "documenters", documenters,
5357 "comments", _(
"Accounting for personal and small business finance."),
5358 "copyright", copyright,
5366 "translator-credits", _(
"translator-credits"),
5368 "website", PACKAGE_URL,
5369 "website-label", _(
"Visit the GnuCash website."),
5377 g_strfreev(documenters);
5379 g_strfreev(authors);
5380 g_object_unref (logo);
5381 g_signal_connect (dialog,
"activate-link",
5382 G_CALLBACK (url_signal_cb),
nullptr);
5385 add_about_paths (dialog);
5388 gtk_window_set_resizable(GTK_WINDOW (dialog), TRUE);
5390 gtk_window_set_transient_for (GTK_WINDOW (dialog),
5391 GTK_WINDOW (window));
5392 gtk_dialog_run (dialog);
5393 gtk_widget_destroy (GTK_WIDGET (dialog));
5405 #ifdef MAC_INTEGRATION 5406 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
5408 for (window_iter = active_windows; window_iter !=
nullptr; window_iter = window_iter->next)
5410 gtk_widget_show(GTK_WIDGET(window_iter->data));
5412 #ifdef MAC_INTEGRATION 5413 g_signal_connect(theApp,
"NSApplicationWillTerminate",
5414 G_CALLBACK(gnc_quartz_shutdown),
nullptr);
5415 gtkosx_application_ready(theApp);
5416 g_object_unref (theApp);
5423 GtkWidget *toplevel;
5428 toplevel = gtk_widget_get_toplevel (widget);
5429 if (toplevel && GTK_IS_WINDOW (toplevel))
5430 return GTK_WINDOW (toplevel);
5441 while (toplevel && !GNC_IS_MAIN_WINDOW (toplevel))
5442 toplevel = gtk_window_get_transient_for(toplevel);
5447 for (window = active_windows; window; window = window->next)
5448 if (gtk_window_is_active (GTK_WINDOW (window->data)))
5449 return static_cast<GtkWindow*
>(window->data);
5451 for (window = active_windows; window; window = window->next)
5452 if (gtk_widget_get_mapped (GTK_WIDGET(window->data)))
5453 return static_cast<GtkWindow*>(window->data);
5465 gnc_main_window_get_gtk_window (GncWindow *window)
5467 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window),
nullptr);
5468 return GTK_WINDOW(window);
5478 gnc_main_window_get_statusbar (GncWindow *window_in)
5481 GncMainWindow *window;
5483 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in),
nullptr);
5485 window = GNC_MAIN_WINDOW(window_in);
5486 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5497 gnc_main_window_get_progressbar (GncWindow *window_in)
5500 GncMainWindow *window;
5502 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in),
nullptr);
5504 window = GNC_MAIN_WINDOW(window_in);
5505 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5516 gnc_main_window_get_menubar (GncWindow *window)
5520 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5522 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5533 gnc_main_window_get_toolbar (GncWindow *window)
5537 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5539 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5550 gnc_main_window_get_menubar_model (GncWindow *window)
5554 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5556 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5566 static GtkAccelGroup *
5567 gnc_main_window_get_accel_group (GncWindow *window)
5571 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5573 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5583 gnc_window_main_window_init (GncWindowInterface *iface)
5585 iface->get_gtk_window = gnc_main_window_get_gtk_window;
5586 iface->get_statusbar = gnc_main_window_get_statusbar;
5587 iface->get_progressbar = gnc_main_window_get_progressbar;
5588 iface->get_menubar = gnc_main_window_get_menubar;
5589 iface->get_toolbar = gnc_main_window_get_toolbar;
5590 iface->get_menubar_model = gnc_main_window_get_menubar_model;
5591 iface->get_accel_group = gnc_main_window_get_accel_group;
5603 gncwin = GNC_WINDOW(window);
5604 gnc_window_set_progressbar_window(gncwin);
5623 GtkBuilder *builder;
5624 GMenuModel *menu_model;
5626 const gchar *menu_qualifier;
5627 gchar *popup_menu_name;
5628 GncWindow* gnc_window;
5629 GtkWidget *statusbar;
5631 g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
5633 ENTER(
"page %p, event %p", page, event);
5635 gnc_window = GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window);
5637 statusbar = gnc_window_get_statusbar (gnc_window);
5643 if (!menu_qualifier)
5646 if (builder ==
nullptr)
5648 LEAVE(
"no builder");
5653 popup_menu_name = g_strconcat (
"mainwin-popup-", menu_qualifier,
nullptr);
5655 popup_menu_name = g_strdup (
"mainwin-popup");
5657 menu_model = (GMenuModel *)gtk_builder_get_object (builder, popup_menu_name);
5660 menu_model = (GMenuModel *)gtk_builder_get_object (builder,
"mainwin-popup");
5662 menu = gtk_menu_new_from_model (menu_model);
5673 gtk_menu_attach_to_widget (GTK_MENU(menu), GTK_WIDGET(page->
window),
nullptr);
5674 gtk_menu_popup_at_pointer (GTK_MENU(menu), (GdkEvent *) event);
5676 g_free (popup_menu_name);
5699 ENTER(
"widget %p, page %p", widget, page);
5700 do_popup_menu(page,
nullptr);
5712 GdkEventButton *event,
5715 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
5717 ENTER(
"widget %p, event %p, page %p", whatever, event, page);
5719 if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
5721 do_popup_menu(page, event);
5722 LEAVE(
"menu shown");
5726 LEAVE(
"other click");
5734 for (
auto tmp = active_windows; tmp; tmp = g_list_next(tmp))
5737 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), sensitive);
5746 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5748 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5754 gnc_main_window_just_plugin_prefs (GncMainWindow* window)
5756 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.