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);
209 static void gnc_main_window_init_menu_updaters (
GncMainWindow *window);
253 const gchar *previous_plugin_page_name;
254 const gchar *previous_menu_qualifier;
259 GHashTable *display_item_hash;
265 G_IMPLEMENT_INTERFACE (GNC_TYPE_WINDOW,
266 gnc_window_main_window_init))
268 #define GNC_MAIN_WINDOW_GET_PRIVATE(o) \ 269 ((GncMainWindowPrivate*)gnc_main_window_get_instance_private((GncMainWindow*)o)) 273 static guint main_window_signals[LAST_SIGNAL] = { 0 };
279 static GActionEntry gnc_menu_actions [] =
281 {
"FilePageSetupAction", gnc_main_window_cmd_page_setup,
nullptr,
nullptr,
nullptr },
282 {
"FilePropertiesAction", gnc_main_window_cmd_file_properties,
nullptr,
nullptr,
nullptr },
283 {
"FileCloseAction", gnc_main_window_cmd_file_close,
nullptr,
nullptr,
nullptr },
284 {
"FilePrintAction", gnc_main_window_cmd_redirect,
nullptr,
nullptr,
nullptr },
285 {
"FileQuitAction", gnc_main_window_cmd_file_quit,
nullptr,
nullptr,
nullptr },
287 {
"EditCutAction", gnc_main_window_cmd_edit_cut,
nullptr,
nullptr,
nullptr },
288 {
"EditCopyAction", gnc_main_window_cmd_edit_copy,
nullptr,
nullptr,
nullptr },
289 {
"EditPasteAction", gnc_main_window_cmd_edit_paste,
nullptr,
nullptr,
nullptr },
290 {
"EditPreferencesAction", gnc_main_window_cmd_edit_preferences,
nullptr,
nullptr,
nullptr },
292 {
"ActionsForgetWarningsAction", gnc_main_window_cmd_actions_reset_warnings,
nullptr,
nullptr,
nullptr },
293 {
"ActionsRenamePageAction", gnc_main_window_cmd_actions_rename_page,
nullptr,
nullptr,
nullptr },
295 {
"TransactionAction",
nullptr,
nullptr,
nullptr,
nullptr },
297 {
"ViewSortByAction",
nullptr,
nullptr,
nullptr,
nullptr },
298 {
"ViewFilterByAction",
nullptr,
nullptr,
nullptr,
nullptr },
299 {
"ViewRefreshAction", gnc_main_window_cmd_view_refresh,
nullptr,
nullptr,
nullptr },
300 {
"ViewToolbarAction", gnc_main_window_cmd_view_toolbar,
nullptr,
"true",
nullptr },
301 {
"ViewSummaryAction", gnc_main_window_cmd_view_summary,
nullptr,
"true",
nullptr },
302 {
"ViewStatusbarAction", gnc_main_window_cmd_view_statusbar,
nullptr,
"true",
nullptr },
303 {
"ViewTabPositionAction", gnc_main_window_cmd_view_tab_position,
"i",
"@i 0",
nullptr },
305 {
"ScheduledAction",
nullptr,
nullptr,
nullptr,
nullptr },
307 {
"ExtensionsAction",
nullptr,
nullptr,
nullptr,
nullptr },
309 {
"WindowNewAction", gnc_main_window_cmd_window_new,
nullptr,
nullptr,
nullptr },
310 {
"WindowMovePageAction", gnc_main_window_cmd_window_move_page,
nullptr,
nullptr,
nullptr },
311 #ifndef MAC_INTEGRATION 312 {
"WindowAction", gnc_main_window_cmd_window_raise,
"i",
"@i 0",
nullptr },
314 {
"HelpTutorialAction", gnc_main_window_cmd_help_tutorial,
nullptr,
nullptr,
nullptr },
315 {
"HelpContentsAction", gnc_main_window_cmd_help_contents,
nullptr,
nullptr,
nullptr },
316 {
"HelpAboutAction", gnc_main_window_cmd_help_about,
nullptr,
nullptr,
nullptr },
319 static guint gnc_menu_n_actions = G_N_ELEMENTS(gnc_menu_actions);
325 static const gchar *always_insensitive_actions[] =
335 static const gchar *initially_insensitive_actions[] =
346 static const gchar *always_hidden_actions[] =
349 "ViewFilterByAction",
356 static const gchar *immutable_page_actions[] =
365 static const gchar *multiple_page_actions[] =
367 "WindowMovePageAction",
375 #define WINDOW_COUNT "WindowCount" 376 #define WINDOW_STRING "Window %d" 377 #define WINDOW_GEOMETRY "WindowGeometry" 378 #define WINDOW_POSITION "WindowPosition" 379 #define WINDOW_MAXIMIZED "WindowMaximized" 380 #define TOOLBAR_VISIBLE "ToolbarVisible" 381 #define STATUSBAR_VISIBLE "StatusbarVisible" 382 #define SUMMARYBAR_VISIBLE "SummarybarVisible" 383 #define WINDOW_FIRSTPAGE "FirstPage" 384 #define WINDOW_PAGECOUNT "PageCount" 385 #define WINDOW_PAGEORDER "PageOrder" 386 #define PAGE_TYPE "PageType" 387 #define PAGE_NAME "PageName" 388 #define PAGE_STRING "Page %d" 393 const gchar *group_name;
414 for (
auto w = active_windows; w; w = g_list_next(w))
417 auto priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
418 for (
auto p = priv->installed_pages; p; p = g_list_next(p))
448 gchar *page_group, *page_type =
nullptr, *name =
nullptr;
449 const gchar *class_type;
450 GError *error =
nullptr;
452 ENTER(
"window %p, data %p (key file %p, window %d, page start %d, page num %d)",
453 window, data, data->key_file, data->window_num, data->page_offset,
456 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
457 page_group = g_strdup_printf(PAGE_STRING,
458 data->page_offset + data->page_num);
459 page_type = g_key_file_get_string(data->key_file, page_group,
463 g_warning(
"error reading group %s key %s: %s",
464 page_group, PAGE_TYPE, error->message);
473 class_type = GNC_PLUGIN_PAGE_GET_CLASS(page)->plugin_name;
474 if (strcmp(page_type, class_type) != 0)
476 g_warning(
"error: page types don't match: state %s, existing page %s",
477 page_type, class_type);
485 data->key_file, page_group);
489 if (page->
window ==
nullptr)
496 name = g_key_file_get_string(data->key_file, page_group,
500 g_warning(
"error reading group %s key %s: %s",
501 page_group, PAGE_NAME, error->message);
506 DEBUG(
"updating page name for %p to %s.", page, name);
521 return (page ?
true :
false);
525 intersects_some_monitor(
const GdkRectangle& rect)
527 auto display = gdk_display_get_default();
531 int n = gdk_display_get_n_monitors(display);
532 for (
int i = 0; i < n; ++i)
534 auto monitor = gdk_display_get_monitor(display, i);
535 GdkRectangle monitor_geometry;
536 gdk_monitor_get_geometry(monitor, &monitor_geometry);
537 DEBUG(
"Monitor %d: position (%d,%d), size %dx%d\n", i,
538 monitor_geometry.x, monitor_geometry.y,
539 monitor_geometry.width, monitor_geometry.height);
540 if (gdk_rectangle_intersect(&rect, &monitor_geometry,
nullptr))
551 GError *error =
nullptr;
552 gint *geom = g_key_file_get_integer_list(data->key_file, window_group,
553 WINDOW_GEOMETRY, &length, &error);
556 g_warning(
"error reading group %s key %s: %s",
557 window_group, WINDOW_GEOMETRY, error->message);
561 else if (length != 2)
563 g_warning(
"invalid number of values for group %s key %s",
564 window_group, WINDOW_GEOMETRY);
568 gtk_window_resize(GTK_WINDOW(window), geom[0], geom[1]);
569 DEBUG(
"window (%p) size %dx%d", window, geom[0], geom[1]);
574 gint *pos = g_key_file_get_integer_list(data->key_file, window_group,
575 WINDOW_POSITION, &length, &error);
578 g_warning(
"error reading group %s key %s: %s",
579 window_group, WINDOW_POSITION, error->message);
583 else if (length != 2)
585 g_warning(
"invalid number of values for group %s key %s",
586 window_group, WINDOW_POSITION);
592 GdkRectangle geometry{pos[0], pos[1], geom ? geom[0] : 1, geom ? geom[1] : 1};
593 if (intersects_some_monitor(geometry))
595 gtk_window_move(GTK_WINDOW(window), geometry.x, geometry.y);
596 auto priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
597 priv->
pos[0] = geometry.x;
598 priv->
pos[1] = geometry.y;
599 DEBUG(
"window (%p) position (%d,%d)", window, geometry.x, geometry.y);
603 DEBUG(
"position (%d,%d), size %dx%d is offscreen; will not move",
604 geometry.x, geometry.y, geometry.width, geometry.height);
610 gboolean max = g_key_file_get_boolean(data->key_file, window_group,
611 WINDOW_MAXIMIZED, &error);
614 g_warning(
"error reading group %s key %s: %s",
615 window_group, WINDOW_MAXIMIZED, error->message);
621 gtk_window_maximize(GTK_WINDOW(window));
640 gsize page_start, page_count, i;
641 GError *error =
nullptr;
642 GSList *added_page_offsets =
nullptr;
646 ENTER(
"window %p, data %p (key file %p, window %d)",
647 window, data, data->key_file, data->window_num);
648 gchar *window_group = g_strdup_printf(WINDOW_STRING, data->window_num + 1);
657 if (!g_key_file_has_group (data->key_file, window_group) ||
658 !g_key_file_has_key (data->key_file, window_group, WINDOW_PAGECOUNT, &error))
663 PINFO (
"saved state had an empty first main window\n" 664 "an account hierarchy page was added automatically to avoid confusion");
667 PINFO (
"saved state had an empty main window, skipping restore");
674 page_count = g_key_file_get_integer(data->key_file,
675 window_group, WINDOW_PAGECOUNT, &error);
678 g_warning(
"error reading group %s key %s: %s",
679 window_group, WINDOW_PAGECOUNT, error->message);
688 page_start = g_key_file_get_integer(data->key_file,
689 window_group, WINDOW_FIRSTPAGE, &error);
692 g_warning(
"error reading group %s key %s: %s",
693 window_group, WINDOW_FIRSTPAGE, error->message);
698 if (window ==
nullptr)
700 DEBUG(
"Window %d doesn't exist. Creating new window.", data->window_num);
701 DEBUG(
"active_windows %p.", active_windows);
703 DEBUG(
"first window %p.", active_windows->data);
708 set_window_geometry(window, data, window_group);
710 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
719 GVariant *state = g_action_get_state (G_ACTION(action));
720 gboolean visible = g_variant_get_boolean (state);
721 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
722 TOOLBAR_VISIBLE, &error);
726 g_warning (
"error reading group %s key %s: %s",
727 window_group, TOOLBAR_VISIBLE, error->message);
728 g_error_free (error);
731 else if (visible != desired_visibility)
733 g_action_activate (action,
nullptr);
735 g_variant_unref (state);
741 GVariant *state = g_action_get_state (G_ACTION(action));
742 gboolean visible = g_variant_get_boolean (state);
743 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
744 SUMMARYBAR_VISIBLE, &error);
748 g_warning (
"error reading group %s key %s: %s",
749 window_group, SUMMARYBAR_VISIBLE, error->message);
750 g_error_free (error);
753 else if (visible != desired_visibility)
755 g_action_activate (action,
nullptr);
757 g_variant_unref (state);
763 GVariant *state = g_action_get_state (G_ACTION(action));
764 gboolean visible = g_variant_get_boolean (state);
765 gboolean desired_visibility = g_key_file_get_boolean (data->key_file, window_group,
766 STATUSBAR_VISIBLE, &error);
770 g_warning (
"error reading group %s key %s: %s",
771 window_group, STATUSBAR_VISIBLE, error->message);
772 g_error_free (error);
775 else if (visible != desired_visibility)
777 g_action_activate (action,
nullptr);
779 g_variant_unref (state);
783 for (i = 0; i < page_count; i++)
785 data->page_offset = page_start;
787 gboolean page_added = gnc_main_window_restore_page (window, data);
789 added_page_offsets = g_slist_append (added_page_offsets, GINT_TO_POINTER(offset));
795 while (gtk_events_pending ())
796 gtk_main_iteration ();
802 order = g_key_file_get_integer_list (data->key_file, window_group,
803 WINDOW_PAGEORDER, &length, &error);
806 g_warning(
"error reading group %s key %s: %s",
807 window_group, WINDOW_PAGEORDER, error->message);
811 else if (length != page_count)
813 g_warning(
"%s key %s length %" G_GSIZE_FORMAT
" differs from window page count %" G_GSIZE_FORMAT,
814 window_group, WINDOW_PAGEORDER, length, page_count);
822 for (i = 0; i < length; i++)
824 gint offset = GPOINTER_TO_INT(g_slist_nth_data (added_page_offsets, order[i] - 1));
825 gpointer page = g_list_nth_data (priv->
installed_pages, order[i] - 1 - offset);
831 gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->
notebook),
832 order[0] - 1 - offset);
834 g_signal_emit_by_name (window,
"page_changed",
842 LEAVE(
"window %p", window);
844 g_slist_free (added_page_offsets);
847 g_free(window_group);
849 gtk_widget_show (GTK_WIDGET(window));
855 gint i, window_count;
856 GError *error =
nullptr;
861 data.key_file = (GKeyFile *) keyfile;
862 window_count = g_key_file_get_integer(data.key_file, STATE_FILE_TOP,
863 WINDOW_COUNT, &error);
866 g_warning(
"error reading group %s key %s: %s",
867 STATE_FILE_TOP, WINDOW_COUNT, error->message);
869 LEAVE(
"can't read count");
875 gnc_set_busy_cursor (
nullptr, TRUE);
876 for (i = 0; i < window_count; i++)
879 auto window{
static_cast<GncMainWindow*
>(g_list_nth_data(active_windows,
881 gnc_main_window_restore_window(window, &data);
883 gnc_unset_busy_cursor (
nullptr);
885 statusbar_notification_lastmodified();
895 DEBUG(
"no saved state file");
897 window =
static_cast<GncMainWindow*
>(g_list_nth_data(active_windows, 0));
898 gtk_widget_show (GTK_WIDGET(window));
900 "gnc-plugin-account-tree-actions",
901 "ViewAccountTreeAction");
902 g_action_activate (action,
nullptr);
918 const gchar *plugin_name, *page_name;
920 ENTER(
"page %p, data %p (key file %p, window %d, page %d)",
921 page, data, data->key_file, data->window_num, data->page_num);
924 if (!plugin_name || !page_name)
926 LEAVE(
"not saving invalid page");
929 page_group = g_strdup_printf(PAGE_STRING, data->page_num++);
930 g_key_file_set_string(data->key_file, page_group, PAGE_TYPE, plugin_name);
931 g_key_file_set_string(data->key_file, page_group, PAGE_NAME, page_name);
952 gint i, num_pages, coords[4], *order;
953 gboolean maximized, minimized, visible =
true;
957 ENTER(
"window %p, data %p (key file %p, window %d)",
958 window, data, data->key_file, data->window_num);
959 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
962 num_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->
notebook));
965 LEAVE(
"empty window %p", window);
970 window_group = g_strdup_printf(WINDOW_STRING, data->window_num++);
971 g_key_file_set_integer(data->key_file, window_group,
972 WINDOW_PAGECOUNT, num_pages);
973 g_key_file_set_integer(data->key_file, window_group,
974 WINDOW_FIRSTPAGE, data->page_num);
979 order =
static_cast<int*
>(g_malloc(
sizeof(gint) * num_pages));
980 for (i = 0; i < num_pages; i++)
982 gpointer page = g_list_nth_data(priv->
usage_order, i);
985 g_key_file_set_integer_list(data->key_file, window_group,
986 WINDOW_PAGEORDER, order, num_pages);
990 gtk_window_get_position(GTK_WINDOW(window), &coords[0], &coords[1]);
991 gtk_window_get_size(GTK_WINDOW(window), &coords[2], &coords[3]);
992 maximized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
993 & GDK_WINDOW_STATE_MAXIMIZED) != 0;
994 minimized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
995 & GDK_WINDOW_STATE_ICONIFIED) != 0;
999 gint *pos = priv->
pos;
1000 g_key_file_set_integer_list(data->key_file, window_group,
1001 WINDOW_POSITION, &pos[0], 2);
1002 DEBUG(
"window minimized (%p) position (%d,%d)", window, pos[0], pos[1]);
1005 g_key_file_set_integer_list(data->key_file, window_group,
1006 WINDOW_POSITION, &coords[0], 2);
1007 g_key_file_set_integer_list(data->key_file, window_group,
1008 WINDOW_GEOMETRY, &coords[2], 2);
1009 g_key_file_set_boolean(data->key_file, window_group,
1010 WINDOW_MAXIMIZED, maximized);
1011 DEBUG(
"window (%p) position (%d,%d), size %dx%d, %s", window, coords[0], coords[1],
1012 coords[2], coords[3],
1013 maximized ?
"maximized" :
"not maximized");
1019 GVariant *state = g_action_get_state (G_ACTION(action));
1020 visible = g_variant_get_boolean (state);
1021 g_variant_unref (state);
1023 g_key_file_set_boolean (data->key_file, window_group,
1024 TOOLBAR_VISIBLE, visible);
1028 GVariant *state = g_action_get_state (G_ACTION(action));
1029 visible = g_variant_get_boolean (state);
1030 g_variant_unref (state);
1032 g_key_file_set_boolean (data->key_file, window_group,
1033 SUMMARYBAR_VISIBLE, visible);
1037 GVariant *state = g_action_get_state (G_ACTION(action));
1038 visible = g_variant_get_boolean (state);
1039 g_variant_unref (state);
1041 g_key_file_set_boolean (data->key_file, window_group,
1042 STATUSBAR_VISIBLE, visible);
1045 g_list_foreach (priv->
installed_pages, (GFunc)gnc_main_window_save_page, data);
1047 g_free(window_group);
1048 LEAVE(
"window %p", window);
1057 data.key_file = keyfile;
1058 data.window_num = 1;
1061 g_key_file_set_integer(data.key_file,
1062 STATE_FILE_TOP, WINDOW_COUNT,
1063 g_list_length(active_windows));
1065 g_list_foreach(active_windows, (GFunc)gnc_main_window_save_window, &data);
1075 g_return_val_if_fail(GNC_IS_MAIN_WINDOW(window), TRUE);
1077 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1092 const GList *windows, *item;
1095 for (item = windows; item; item = g_list_next(item))
1102 if (gnc_gui_refresh_suspended ())
1104 gnc_warning_dialog (
nullptr,
"%s",
"An operation is still running, wait for it to complete before quitting.");
1127 for (walker = active_windows; walker; walker = g_list_next(walker))
1130 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1139 static gboolean auto_save_countdown (GtkWidget *dialog)
1142 gchar *timeoutstr =
nullptr;
1145 if (!GTK_IS_DIALOG (dialog))
1149 label = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
"count-down-label"));
1150 if (!GTK_IS_LABEL (label))
1156 DEBUG (
"Counting down: %d seconds", secs_to_save);
1158 timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
1159 gtk_label_set_text (GTK_LABEL (label), timeoutstr);
1160 g_free (timeoutstr);
1165 gtk_dialog_response (GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
1184 gnc_main_window_prompt_for_save (GtkWidget *window)
1186 QofSession *session;
1188 GtkWidget *dialog, *msg_area, *label;
1190 const gchar *filename, *tmp;
1191 const gchar *title = _(
"Save changes to file %s before closing?");
1193 const gchar *message_hours =
1194 _(
"If you don't save, changes from the past %d hours and %d minutes will be discarded.");
1195 const gchar *message_days =
1196 _(
"If you don't save, changes from the past %d days and %d hours will be discarded.");
1198 gint minutes, hours, days;
1199 guint timer_source = 0;
1200 if (!gnc_current_session_exist())
1202 session = gnc_get_current_session();
1206 filename = qof_session_get_url(session);
1207 if (!strlen (filename))
1208 filename = _(
"<unknown>");
1209 if ((tmp = strrchr(filename,
'/')) !=
nullptr)
1213 gnc_autosave_remove_timer(book);
1215 dialog = gtk_message_dialog_new(GTK_WINDOW(window),
1217 GTK_MESSAGE_WARNING,
1222 minutes = (
gnc_time (
nullptr) - oldest_change) / 60 + 1;
1223 hours = minutes / 60;
1224 minutes = minutes % 60;
1229 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1230 message_days, days, hours);
1234 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1235 message_hours, hours, minutes);
1239 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1240 ngettext(
"If you don't save, changes from the past %d minute will be discarded.",
1241 "If you don't save, changes from the past %d minutes will be discarded.",
1244 gtk_dialog_add_buttons(GTK_DIALOG(dialog),
1245 _(
"Close _Without Saving"), GTK_RESPONSE_CLOSE,
1246 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
1247 _(
"_Save"), GTK_RESPONSE_APPLY,
1249 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
1256 gchar *timeoutstr =
nullptr;
1258 secs_to_save =
gnc_prefs_get_int (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_CLOSE_WAIT_TIME);
1259 timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
1260 label = GTK_WIDGET(gtk_label_new (timeoutstr));
1261 g_free (timeoutstr);
1262 gtk_widget_show (label);
1264 msg_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG(dialog));
1265 gtk_box_pack_end (GTK_BOX(msg_area), label, TRUE, TRUE, 0);
1266 g_object_set (G_OBJECT (label),
"xalign", 0.0,
nullptr);
1268 g_object_set_data (G_OBJECT (dialog),
"count-down-label", label);
1269 timer_source = g_timeout_add_seconds (1, (GSourceFunc)auto_save_countdown, dialog);
1272 response = gtk_dialog_run (GTK_DIALOG (dialog));
1274 g_source_remove (timer_source);
1275 gtk_widget_destroy(dialog);
1279 case GTK_RESPONSE_APPLY:
1280 gnc_file_save (GTK_WINDOW (window));
1283 case GTK_RESPONSE_CLOSE:
1294 gnc_main_window_add_plugin (gpointer plugin,
1297 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
1298 g_return_if_fail (GNC_IS_PLUGIN (plugin));
1302 GNC_MAIN_WINDOW (window),
1308 gnc_main_window_remove_plugin (gpointer plugin,
1311 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
1312 g_return_if_fail (GNC_IS_PLUGIN (plugin));
1316 GNC_MAIN_WINDOW (window),
1323 gnc_main_window_timed_quit (gpointer dummy)
1325 if (gnc_file_save_in_progress())
1335 QofSession *session;
1336 gboolean needs_save, do_shutdown = TRUE;
1337 if (gnc_current_session_exist())
1339 session = gnc_get_current_session();
1342 !gnc_file_save_in_progress();
1343 do_shutdown = !needs_save ||
1345 !gnc_main_window_prompt_for_save(GTK_WIDGET(window)));
1355 for (w = active_windows; w; w = next)
1360 next = g_list_next (w);
1362 window->window_quitting = TRUE;
1364 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1368 gtk_widget_destroy (GTK_WIDGET(window));
1371 gnc_main_window_remove_prefs (window);
1372 g_timeout_add(250, gnc_main_window_timed_quit,
nullptr);
1379 gnc_main_window_delete_event (GtkWidget *window,
1383 static gboolean already_dead = FALSE;
1392 gchar *message = _(
"This window is closing and will not be restored.");
1394 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
1395 GTK_DIALOG_DESTROY_WITH_PARENT,
1396 GTK_MESSAGE_QUESTION,
1398 "%s", _(
"Close Window?"));
1399 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
1402 gtk_dialog_add_buttons (GTK_DIALOG(dialog),
1403 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
1404 _(
"_OK"), GTK_RESPONSE_YES,
1406 gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_YES);
1407 response = gnc_dialog_run (GTK_DIALOG(dialog), GNC_PREF_WARN_CLOSING_WINDOW_QUESTION);
1408 gtk_widget_destroy (dialog);
1410 if (response == GTK_RESPONSE_CANCEL)
1423 already_dead = gnc_main_window_quit(GNC_MAIN_WINDOW(window));
1449 gpointer user_data, gpointer event_data)
1457 g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
1462 if (event_type != QOF_EVENT_DESTROY)
1465 ENTER(
"entity %p, event %d, window %p, event data %p",
1466 entity, event_type, user_data, event_data);
1467 window = GNC_MAIN_WINDOW(user_data);
1468 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1475 next = g_list_next(item);
1476 page = GNC_PLUGIN_PAGE(item->data);
1481 if (GTK_IS_WIDGET(window) && window->window_quitting)
1482 gtk_widget_destroy (GTK_WIDGET(window));
1511 gchar *filename =
nullptr;
1512 const gchar *uri =
nullptr;
1513 const gchar *dirty =
"";
1514 const gchar *readonly_text =
nullptr;
1518 if (gnc_current_session_exist())
1520 uri = qof_session_get_url (gnc_get_current_session ());
1521 book = gnc_get_current_book();
1528 readonly_text = _(
"(read-only)");
1531 readonly = (readonly_text !=
nullptr)
1532 ? g_strdup_printf(
" %s", readonly_text)
1535 if (!uri || g_strcmp0 (uri,
"") == 0)
1536 filename = g_strdup(_(
"Unsaved Book"));
1544 filename = g_path_get_basename ( path );
1555 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1561 title = g_strdup_printf(
"%s%s%s - %s - GnuCash", dirty, filename, readonly,
1566 title = g_strdup_printf(
"%s%s%s - GnuCash", dirty, filename, readonly);
1570 g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE);
1572 immutable_page_actions,
1575 g_signal_emit_by_name (window,
"page_changed", page);
1597 title = gnc_main_window_generate_title(window);
1598 gtk_window_set_title(GTK_WINDOW(window), title);
1603 gnc_main_window_update_all_titles (
void)
1605 g_list_foreach(active_windows,
1606 (GFunc)gnc_main_window_update_title,
1611 gnc_main_window_book_dirty_cb (QofBook *book,
1615 gnc_main_window_update_all_titles();
1618 gnc_autosave_dirty_handler(book, dirty);
1622 gnc_main_window_attach_to_book (QofSession *session)
1626 g_return_if_fail(session);
1630 gnc_main_window_update_all_titles();
1631 #ifndef MAC_INTEGRATION 1632 gnc_main_window_update_all_menu_items();
1636 static guint gnc_statusbar_notification_messageid = 0;
1638 #ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL 1641 static gboolean statusbar_notification_off(gpointer user_data_unused)
1645 if (gnc_statusbar_notification_messageid == 0)
1650 GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
1651 gtk_statusbar_remove(GTK_STATUSBAR(statusbar), 0, gnc_statusbar_notification_messageid);
1652 gnc_statusbar_notification_messageid = 0;
1656 g_warning(
"oops, no GncMainWindow obtained\n");
1660 #endif // STATUSBAR_NOTIFICATION_AUTOREMOVAL 1664 static gchar *generate_statusbar_lastmodified_message()
1666 gchar *message =
nullptr;
1667 const gchar *uri =
nullptr;
1669 if (gnc_current_session_exist())
1671 uri = qof_session_get_url (gnc_get_current_session ());
1674 if (!(uri && strlen (uri)))
1682 gchar *filename = g_path_get_basename ( filepath );
1683 GFile *file = g_file_new_for_uri (uri);
1684 GFileInfo *info = g_file_query_info (file,
1685 G_FILE_ATTRIBUTE_TIME_MODIFIED,
1686 G_FILE_QUERY_INFO_NONE,
1689 if (info && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
1692 struct stat statbuf;
1693 int r = stat(filepath, &statbuf);
1702 _(
"Last modified on %a, %b %d, %Y at %I:%M %p"));
1705 message = g_strdup_printf(_(
"File %s opened. %s"),
1706 filename, time_string);
1711 g_warning(
"Unable to read mtime for file %s\n", filepath);
1717 g_object_unref (info);
1718 g_object_unref (file);
1727 statusbar_notification_lastmodified()
1731 GtkWidget *widget =
nullptr;
1732 for (iter = active_windows; iter && !(widget && GNC_IS_MAIN_WINDOW(widget));
1733 iter = g_list_next(iter))
1735 widget =
static_cast<GtkWidget*
>(iter->data);
1737 if (widget && GNC_IS_MAIN_WINDOW(widget))
1741 GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
1743 gchar *msg = generate_statusbar_lastmodified_message();
1746 gnc_statusbar_notification_messageid = gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);
1750 #ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL 1753 g_timeout_add(10 * 1000, statusbar_notification_off,
nullptr);
1758 g_warning(
"uh oh, no GNC_IS_MAIN_WINDOW\n");
1780 #ifndef MAC_INTEGRATION 1795 gnc_main_window_update_one_menu_action (
GncMainWindow *window,
1799 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
1803 ENTER(
"window %p, action %s, label %s, index %d, visible %d", window,
1804 data->action_name, data->label, data->index, data->visible);
1806 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
1808 gsm->search_action_label =
nullptr;
1809 gsm->search_action_name =
"WindowsPlaceholder1";
1810 gsm->search_action_target =
nullptr;
1814 LEAVE(
"Could not find placeholder 'WindowsPlaceholder1' for windows entries");
1819 pos = gsm->index + data->index + 1;
1823 if (pos < g_menu_model_get_n_items (gsm->model))
1824 g_menu_remove (G_MENU(gsm->model), pos);
1831 item = g_menu_item_new (data->label,
"mainwin.WindowAction");
1832 g_menu_item_set_attribute (item, G_MENU_ATTRIBUTE_TARGET,
"i", data->index);
1834 if (pos < g_menu_model_get_n_items (gsm->model))
1835 g_menu_remove (G_MENU(gsm->model), pos);
1836 g_menu_insert_item (G_MENU(gsm->model), pos, item);
1837 g_object_unref (item);
1861 ENTER(
"window %p", window);
1864 index = g_list_index (active_windows, window);
1872 action = g_action_map_lookup_action (G_ACTION_MAP(window),
1877 g_signal_handlers_block_by_func (G_OBJECT(action),
1878 (gpointer)gnc_main_window_cmd_window_raise,
1881 DEBUG(
"blocked signal on action %p, window %p", action, window);
1882 g_action_change_state (G_ACTION(action), g_variant_new_int32 (index));
1884 g_signal_handlers_unblock_by_func (G_OBJECT(action),
1885 (gpointer)gnc_main_window_cmd_window_raise,
1906 gchar **strings, *title, *expanded;
1909 ENTER(
"window %p", window);
1911 index = g_list_index (active_windows, window);
1920 title = gnc_main_window_generate_title (window);
1921 strings = g_strsplit (title,
"_", 0);
1923 expanded = g_strjoinv (
"__", strings);
1926 data.label = g_strdup_printf (
"_%" G_GSIZE_FORMAT
" %s", (
index + 1) % 10, expanded);
1931 data.label = expanded;
1933 g_strfreev (strings);
1935 data.visible = TRUE;
1936 data.action_name = g_strdup_printf (
"Window%" G_GSIZE_FORMAT
"Action",
index);
1939 g_list_foreach (active_windows,
1940 (GFunc)gnc_main_window_update_one_menu_action,
1943 g_free (data.action_name);
1944 g_free (data.label);
1958 #ifndef MAC_INTEGRATION 1960 gnc_main_window_update_all_menu_items (
void)
1966 g_list_foreach (active_windows,
1967 (GFunc)gnc_main_window_update_menu_item,
1970 g_list_foreach (active_windows,
1971 (GFunc)gnc_main_window_update_radio_button,
1975 data.visible = FALSE;
1980 data.action_name = g_strdup_printf (
"Window%dAction", data.index);
1981 data.label = g_strdup_printf (
"mywin%" G_GSIZE_FORMAT, i % 10);
1983 g_list_foreach (active_windows,
1984 (GFunc)gnc_main_window_update_one_menu_action,
1987 g_free (data.action_name);
1988 g_free (data.label);
2006 gnc_main_window_update_tab_close_one_page (
GncPluginPage *page,
2009 auto new_value{
static_cast<gboolean*
>(user_data)};
2010 ENTER(
"page %p, visible %d", page, *new_value);
2011 auto close_button{
static_cast<GtkWidget*
>(g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON))};
2014 LEAVE(
"no close button");
2019 gtk_widget_show (close_button);
2021 gtk_widget_hide (close_button);
2039 gnc_main_window_update_tab_close (gpointer prefs, gchar *pref, gpointer user_data)
2044 new_value =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SHOW_CLOSE_BUTTON);
2046 gnc_main_window_update_tab_close_one_page,
2061 gnc_main_window_update_tab_color_one_page (
GncPluginPage *page,
2064 const gchar *color_string;
2066 ENTER(
"page %p", page);
2084 gnc_main_window_update_tab_color (gpointer gsettings, gchar *pref, gpointer user_data)
2087 g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
2089 auto priv{GNC_MAIN_WINDOW_GET_PRIVATE(window)};
2090 if (g_strcmp0 (GNC_PREF_TAB_COLOR, pref) == 0)
2103 gboolean tabs_left_right;
2107 populate_tab_width_struct (
void)
2113 tw->tabs_left_right =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT) ||
2141 gnc_main_window_set_tab_ellipsize (GtkWidget *
label, gint tab_width, gboolean tab_left_right)
2143 const gchar *lab_text = gtk_label_get_text (GTK_LABEL(
label));
2147 gint text_length = g_utf8_strlen (lab_text, -1);
2148 if (text_length < tab_width)
2151 gtk_label_set_width_chars (GTK_LABEL(
label), tab_width);
2153 gtk_label_set_width_chars (GTK_LABEL(
label), text_length);
2155 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_NONE);
2159 gtk_label_set_width_chars (GTK_LABEL(
label), tab_width);
2160 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_MIDDLE);
2165 gtk_label_set_width_chars (GTK_LABEL(
label), 15);
2166 gtk_label_set_ellipsize (GTK_LABEL(
label), PANGO_ELLIPSIZE_NONE);
2182 gnc_main_window_update_tab_width_one_page (
GncPluginPage *page,
2185 auto tw{
static_cast<TabWidth*
>(user_data)};
2187 ENTER(
"page %p, tab width %d, tabs on left or right %d",
2188 page, tw->tab_width, tw->tabs_left_right);
2190 auto label{
static_cast<GtkWidget *
>(g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL))};
2196 gnc_main_window_set_tab_ellipsize (
label, tw->tab_width, tw->tabs_left_right);
2214 gnc_main_window_update_tab_width (gpointer prefs, gchar *pref, gpointer user_data)
2220 tw = populate_tab_width_struct ();
2235 GtkWidget **label_p,
2236 GtkWidget **entry_p)
2239 GtkWidget *tab_hbox, *widget, *tab_widget;
2240 GList *children, *tmp;
2242 ENTER(
"window %p, page %p, label_p %p, entry_p %p",
2243 window, page, label_p, entry_p);
2244 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2245 *label_p = *entry_p =
nullptr;
2249 LEAVE(
"invalid notebook_page");
2253 tab_widget = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->
notebook),
2255 if (GTK_IS_EVENT_BOX (tab_widget))
2256 tab_hbox = gtk_bin_get_child(GTK_BIN(tab_widget));
2257 else if (GTK_IS_BOX (tab_widget))
2258 tab_hbox = tab_widget;
2261 PWARN (
"Unknown widget for tab label %p", tab_widget);
2265 children = gtk_container_get_children(GTK_CONTAINER(tab_hbox));
2266 for (tmp = children; tmp; tmp = g_list_next(tmp))
2268 widget =
static_cast<GtkWidget*
>(tmp->data);
2269 if (GTK_IS_LABEL(widget))
2273 else if (GTK_IS_ENTRY(widget))
2278 g_list_free(children);
2280 LEAVE(
"label %p, entry %p", *label_p, *entry_p);
2281 return (*label_p && *entry_p);
2287 GtkWidget **widget_p)
2291 ENTER(
"window %p, page %p, widget %p",
2292 window, page, widget_p);
2293 *widget_p =
nullptr;
2297 LEAVE(
"invalid notebook_page");
2301 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2302 *widget_p = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->
notebook),
2305 LEAVE(
"widget %p", *widget_p);
2311 const gchar *long_name_in)
2313 GtkWidget *tab_widget;
2317 if ((long_name_in ==
nullptr) || (*long_name_in ==
'\0'))
2322 gchar *long_name = g_strstrip (g_strdup (long_name_in));
2326 if (*long_name ==
'\0' || strcmp (long_name, old_long_name) == 0)
2329 LEAVE(
"empty string or name unchanged");
2339 LEAVE(
"no window widget available");
2344 if (main_window_find_tab_widget (window, page, &tab_widget))
2345 gtk_widget_set_tooltip_text (tab_widget, long_name);
2353 const gchar *name_in)
2357 GtkWidget *
label, *entry;
2363 if ((name_in ==
nullptr) || (*name_in ==
'\0'))
2368 name = g_strstrip(g_strdup(name_in));
2374 LEAVE(
"empty string or name unchanged");
2382 window = GNC_MAIN_WINDOW(page->
window);
2386 LEAVE(
"no window widget available");
2390 if (main_window_find_tab_items(window, page, &
label, &entry))
2391 gtk_label_set_text(GTK_LABEL(
label), name);
2394 tw = populate_tab_width_struct ();
2395 gnc_main_window_update_tab_width_one_page (page, tw);
2401 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2402 label = gtk_notebook_get_menu_label (GTK_NOTEBOOK(priv->
notebook),
2404 gtk_label_set_text(GTK_LABEL(
label), name);
2408 gnc_main_window_update_title(window);
2416 const gchar *color_in)
2420 GtkWidget *tab_widget;
2422 gchar *color_string =
nullptr;
2423 gboolean want_color = FALSE;
2427 color_string = g_strstrip(g_strdup(color_in));
2429 if (color_string && *color_string !=
'\0')
2433 window = GNC_MAIN_WINDOW(page->
window);
2440 main_window_find_tab_widget (window, page, &tab_widget);
2441 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2443 if (want_color && gdk_rgba_parse(&tab_color, color_string) && priv->
show_color_tabs)
2445 GtkCssProvider *provider = gtk_css_provider_new();
2446 GtkStyleContext *stylectxt;
2447 gchar *col_str, *widget_css;
2449 if (!GTK_IS_EVENT_BOX (tab_widget))
2451 GtkWidget *event_box = gtk_event_box_new ();
2452 g_object_ref (tab_widget);
2453 gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->
notebook),
2455 gtk_container_add (GTK_CONTAINER(event_box), tab_widget);
2456 g_object_unref (tab_widget);
2457 tab_widget = event_box;
2460 stylectxt = gtk_widget_get_style_context (GTK_WIDGET (tab_widget));
2461 col_str = gdk_rgba_to_string (&tab_color);
2462 widget_css = g_strconcat (
"*{\n background-color:", col_str,
";\n}\n",
nullptr);
2464 gtk_css_provider_load_from_data (provider, widget_css, -1,
nullptr);
2465 gtk_style_context_add_provider (stylectxt, GTK_STYLE_PROVIDER (provider),
2466 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
2467 g_object_unref (provider);
2469 g_free (widget_css);
2473 if (GTK_IS_EVENT_BOX (tab_widget))
2475 GtkWidget *tab_hbox = gtk_bin_get_child(GTK_BIN(tab_widget));
2476 g_object_ref (tab_hbox);
2477 gtk_container_remove (GTK_CONTAINER(tab_widget), tab_hbox);
2478 gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->
notebook),
2480 g_object_unref (tab_hbox);
2483 g_free(color_string);
2493 GtkWidget *tab_widget;
2494 GtkWidget *image = NULL;
2496 gchar *image_name = NULL;
2497 const gchar *icon_name;
2501 g_return_if_fail (page && page->
window);
2503 if (!GNC_IS_MAIN_WINDOW (page->
window))
2506 window = GNC_MAIN_WINDOW(page->
window);
2509 main_window_find_tab_widget (window, page, &tab_widget);
2513 LEAVE(
"no tab widget");
2517 if (GTK_IS_EVENT_BOX(tab_widget))
2518 tab_widget = gtk_bin_get_child (GTK_BIN(tab_widget));
2520 children = gtk_container_get_children (GTK_CONTAINER(tab_widget));
2522 for (GList *child = children; child; child = g_list_next (child))
2524 GtkWidget *widget =
static_cast<GtkWidget*
>(child->data);
2525 if (GTK_IS_IMAGE(widget))
2528 g_list_free (children);
2532 LEAVE(
"no image to replace");
2536 g_object_get (image,
"icon-name", &image_name, NULL);
2539 icon_name =
"changes-prevent-symbolic";
2541 icon_name = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
2543 if (g_strcmp0 (icon_name, image_name) == 0)
2545 LEAVE(
"page icon the same, no need to replace");
2546 g_free (image_name);
2549 gtk_container_remove (GTK_CONTAINER(tab_widget), image);
2550 image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
2551 gtk_widget_show (image);
2553 gtk_container_add (GTK_CONTAINER(tab_widget), image);
2554 gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
2555 gtk_box_reorder_child (GTK_BOX(tab_widget), image, 0);
2557 g_free (image_name);
2563 gnc_main_window_tab_entry_activate (GtkWidget *entry,
2566 GtkWidget *
label, *entry2;
2568 g_return_if_fail(GTK_IS_ENTRY(entry));
2569 g_return_if_fail(GNC_IS_PLUGIN_PAGE(page));
2572 if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->
window),
2573 page, &
label, &entry2))
2575 LEAVE(
"can't find required widgets");
2581 gtk_widget_hide(entry);
2582 gtk_widget_show(
label);
2588 gnc_main_window_tab_entry_editing_done (GtkWidget *entry,
2592 gnc_main_window_tab_entry_activate(entry, page);
2598 gnc_main_window_tab_entry_focus_out_event (GtkWidget *entry,
2603 gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(entry));
2609 gnc_main_window_tab_entry_key_press_event (GtkWidget *entry,
2613 if (event->keyval == GDK_KEY_Escape)
2615 GtkWidget *
label, *entry2;
2617 g_return_val_if_fail(GTK_IS_ENTRY(entry), FALSE);
2618 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
2621 if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->
window),
2622 page, &
label, &entry2))
2624 LEAVE(
"can't find required widgets");
2628 gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(
label)));
2629 gtk_widget_hide(entry);
2630 gtk_widget_show(
label);
2652 GObjectClass *object_class = G_OBJECT_CLASS (klass);
2653 GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS(klass);
2655 window_type = g_quark_from_static_string (
"gnc-main-window");
2657 object_class->constructed = gnc_main_window_constructed;
2658 object_class->finalize = gnc_main_window_finalize;
2661 gtkwidget_class->destroy = gnc_main_window_destroy;
2674 main_window_signals[PAGE_ADDED] =
2675 g_signal_new (
"page_added",
2676 G_OBJECT_CLASS_TYPE (object_class),
2680 g_cclosure_marshal_VOID__OBJECT,
2694 main_window_signals[PAGE_CHANGED] =
2695 g_signal_new (
"page_changed",
2696 G_OBJECT_CLASS_TYPE (object_class),
2700 g_cclosure_marshal_VOID__OBJECT,
2712 main_window_signals[MENU_CHANGED] =
2713 g_signal_new (
"menu_changed",
2714 G_OBJECT_CLASS_TYPE (object_class),
2718 g_cclosure_marshal_VOID__OBJECT,
2723 GNC_PREF_SHOW_CLOSE_BUTTON,
2724 (gpointer)gnc_main_window_update_tab_close,
2728 (gpointer)gnc_main_window_update_tab_width,
2731 gnc_hook_add_dangler(HOOK_BOOK_SAVED,
2732 (GFunc)gnc_main_window_update_all_titles,
nullptr,
nullptr);
2733 gnc_hook_add_dangler(HOOK_BOOK_OPENED,
2734 (GFunc)gnc_main_window_attach_to_book,
nullptr,
nullptr);
2750 gtk_widget_set_name (GTK_WIDGET(window),
"gnc-id-main-window");
2757 priv->display_item_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
nullptr);
2759 priv->previous_plugin_page_name =
nullptr;
2760 priv->previous_menu_qualifier =
nullptr;
2763 gtk_window_add_accel_group (GTK_WINDOW(window), priv->
accel_group);
2770 (gpointer)gnc_main_window_update_tab_color,
2773 gnc_main_window_setup_window (window);
2783 gnc_main_window_constructed (GObject *obj)
2787 G_OBJECT_CLASS (gnc_main_window_parent_class)->constructed (obj);
2801 gnc_main_window_finalize (GObject *
object)
2803 g_return_if_fail (
object !=
nullptr);
2804 g_return_if_fail (GNC_IS_MAIN_WINDOW (
object));
2806 if (active_windows ==
nullptr)
2813 G_OBJECT_CLASS (gnc_main_window_parent_class)->finalize (
object);
2823 (gpointer)gnc_main_window_update_tab_color,
2827 GNC_PREF_SHOW_CLOSE_BUTTON,
2828 (gpointer)gnc_main_window_update_tab_close,
2833 (gpointer)gnc_main_window_update_tab_width,
2837 GNC_PREF_TAB_POSITION_TOP,
2838 (gpointer)gnc_main_window_update_tab_position,
2842 GNC_PREF_TAB_POSITION_BOTTOM,
2843 (gpointer)gnc_main_window_update_tab_position,
2847 GNC_PREF_TAB_POSITION_LEFT,
2848 (gpointer)gnc_main_window_update_tab_position,
2852 GNC_PREF_TAB_POSITION_RIGHT,
2853 (gpointer)gnc_main_window_update_tab_position,
2861 gnc_prefs_set_reg_negative_color_pref_id (0);
2869 gnc_prefs_set_reg_auto_raise_lists_id (0);
2875 gnc_main_window_destroy (GtkWidget *widget)
2879 GncPluginManager *manager;
2882 g_return_if_fail (widget !=
nullptr);
2883 g_return_if_fail (GNC_IS_MAIN_WINDOW (widget));
2885 window = GNC_MAIN_WINDOW (widget);
2886 #ifdef MAC_INTEGRATION 2887 auto entry = g_list_find (active_windows, window);
2888 if (entry && (entry->next || entry->prev))
2889 gnc_quartz_set_menu (GNC_MAIN_WINDOW (entry->next ? entry->next->data : entry->prev->data));
2891 active_windows = g_list_remove (active_windows, window);
2894 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
2902 if (gnc_window_get_progressbar_window() == GNC_WINDOW(window))
2903 gnc_window_set_progressbar_window(
nullptr);
2904 #ifndef MAC_INTEGRATION 2906 gnc_main_window_update_all_menu_items();
2909 gnc_main_window_remove_prefs (window);
2914 g_hash_table_destroy (priv->display_item_hash);
2919 g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
2920 g_list_free (plugins);
2923 GTK_WIDGET_CLASS (gnc_main_window_parent_class)->destroy (widget);
2928 gnc_main_window_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
2931 GdkModifierType modifiers;
2933 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(widget), FALSE);
2935 priv = GNC_MAIN_WINDOW_GET_PRIVATE(widget);
2937 modifiers = gtk_accelerator_get_default_mod_mask ();
2939 if ((event->state & modifiers) == (GDK_CONTROL_MASK | GDK_MOD1_MASK))
2941 const gchar *account_key = C_ (
"lower case key for short cut to 'Accounts'",
"a");
2942 guint account_keyval = gdk_keyval_from_name (account_key);
2944 if ((account_keyval == event->keyval) || (account_keyval == gdk_keyval_to_lower (event->keyval)))
2948 for (GList *item = priv->
installed_pages; item; item = g_list_next (item))
2952 if (g_strcmp0 (pname,
"GncPluginPageAccountTree") == 0)
2954 gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->
notebook), page);
2960 else if ((GDK_KEY_Menu == event->keyval) || (GDK_KEY_space == event->keyval))
2962 GList *menu = gtk_menu_get_for_attach_widget (GTK_WIDGET(priv->
notebook));
2966 gtk_menu_popup_at_widget (GTK_MENU(menu->data),
2984 auto window{
static_cast<GncMainWindow*
>(g_object_new (GNC_TYPE_MAIN_WINDOW,
nullptr))};
2985 gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
2991 gtk_window_get_size (old_window, &width, &height);
2992 gtk_window_resize (GTK_WINDOW (window), width, height);
2993 if ((gdk_window_get_state((gtk_widget_get_window (GTK_WIDGET(old_window))))
2994 & GDK_WINDOW_STATE_MAXIMIZED) != 0)
2996 gtk_window_maximize (GTK_WINDOW (window));
2999 active_windows = g_list_append (active_windows, window);
3000 gnc_main_window_update_title(window);
3001 window->window_quitting = FALSE;
3002 window->just_plugin_prefs = FALSE;
3003 #ifdef MAC_INTEGRATION 3004 gnc_quartz_set_menu(window);
3006 gnc_main_window_update_all_menu_items();
3011 g_signal_connect (G_OBJECT(window),
"key-press-event",
3012 G_CALLBACK(gnc_main_window_key_press_event),
3023 gnc_main_window_engine_commit_error_callback( gpointer data,
3028 const gchar *reason = _(
"Unable to save to database.");
3030 reason = _(
"Unable to save to database: Book is marked read-only.");
3031 dialog = gtk_message_dialog_new( GTK_WINDOW(window),
3032 GTK_DIALOG_DESTROY_WITH_PARENT,
3037 gtk_dialog_run(GTK_DIALOG (dialog));
3038 gtk_widget_destroy(dialog);
3062 GtkWidget *tab_hbox,
3063 GtkWidget *menu_label)
3066 GtkNotebook *notebook;
3067 gint current_position = -1;
3069 page->
window = GTK_WIDGET(window);
3070 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3071 notebook = GTK_NOTEBOOK (priv->
notebook);
3079 gtk_notebook_insert_page_menu (notebook, page->
notebook_page,
3080 tab_hbox, menu_label, current_position);
3081 gtk_notebook_set_tab_reorderable (notebook, page->
notebook_page, TRUE);
3082 gnc_plugin_page_inserted (page);
3084 gtk_notebook_set_current_page (notebook, current_position);
3086 if (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)
3087 (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)(page, GTK_WIDGET(window));
3088 g_signal_emit (window, main_window_signals[PAGE_ADDED], 0, page);
3090 g_signal_connect(G_OBJECT(page->
notebook_page),
"popup-menu",
3092 g_signal_connect_after(G_OBJECT(page->
notebook_page),
"button-press-event",
3115 GtkNotebook *notebook;
3120 g_signal_handlers_disconnect_by_func(G_OBJECT(page->
notebook_page),
3122 g_signal_handlers_disconnect_by_func(G_OBJECT(page->
notebook_page),
3129 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3132 gnc_plugin_page_unselected (page);
3141 notebook = GTK_NOTEBOOK (priv->
notebook);
3147 page_num = gtk_notebook_page_num(notebook, new_page->
notebook_page);
3148 gtk_notebook_set_current_page(notebook, page_num);
3153 while (gtk_events_pending())
3154 gtk_main_iteration();
3159 page_num = gtk_notebook_page_num(notebook, page->
notebook_page);
3160 gtk_notebook_remove_page (notebook, page_num);
3162 if ( gtk_notebook_get_current_page(notebook) == -1)
3168 gnc_main_window_switch_page(notebook,
nullptr, -1, window);
3172 gnc_plugin_page_removed (page);
3174 gnc_window_set_status (GNC_WINDOW(window), page,
nullptr);
3188 GtkNotebook *notebook;
3191 window = GNC_MAIN_WINDOW (page->
window);
3192 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3193 notebook = GTK_NOTEBOOK (priv->
notebook);
3194 page_num = gtk_notebook_page_num(notebook, page->
notebook_page);
3195 gtk_notebook_set_current_page (notebook, page_num);
3196 gtk_window_present(GTK_WINDOW(window));
3212 GtkWidget *tab_hbox;
3213 GtkWidget *
label, *entry;
3214 const gchar *icon, *text, *color_string, *lab_text;
3219 ENTER(
"window %p, page %p", window, page);
3221 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3222 g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
3225 if (gnc_main_window_page_exists(page))
3235 for (tmp = active_windows; tmp; tmp = g_list_next(tmp))
3237 window = GNC_MAIN_WINDOW(tmp->data);
3238 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3246 gtk_widget_show(GTK_WIDGET(window));
3248 else if ((window ==
nullptr) && active_windows)
3253 page->
window = GTK_WIDGET(window);
3261 icon = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
3263 label = gtk_label_new (lab_text);
3264 g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL,
label);
3266 tw = populate_tab_width_struct ();
3267 gnc_main_window_update_tab_width_one_page (page, tw);
3270 gtk_widget_show (
label);
3272 tab_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
3275 gtk_widget_set_name (GTK_WIDGET(tab_hbox),
"gnc-id-account-page-tab-box");
3277 gtk_box_set_homogeneous (GTK_BOX (tab_hbox), FALSE);
3278 gtk_widget_show (tab_hbox);
3280 if (icon !=
nullptr)
3282 image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
3283 gtk_widget_show (image);
3284 gtk_box_pack_start (GTK_BOX (tab_hbox), image, FALSE, FALSE, 0);
3285 gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
3286 gtk_box_pack_start (GTK_BOX (tab_hbox),
label, TRUE, TRUE, 0);
3289 gtk_box_pack_start (GTK_BOX (tab_hbox),
label, TRUE, TRUE, 0);
3294 gtk_widget_set_tooltip_text(tab_hbox, text);
3297 entry = gtk_entry_new();
3298 gtk_widget_hide (entry);
3299 gtk_box_pack_start (GTK_BOX (tab_hbox), entry, TRUE, TRUE, 0);
3300 g_signal_connect(G_OBJECT(entry),
"activate",
3301 G_CALLBACK(gnc_main_window_tab_entry_activate), page);
3302 g_signal_connect(G_OBJECT(entry),
"focus-out-event",
3303 G_CALLBACK(gnc_main_window_tab_entry_focus_out_event),
3305 g_signal_connect(G_OBJECT(entry),
"key-press-event",
3306 G_CALLBACK(gnc_main_window_tab_entry_key_press_event),
3308 g_signal_connect(G_OBJECT(entry),
"editing-done",
3309 G_CALLBACK(gnc_main_window_tab_entry_editing_done),
3313 if (!g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE))
3315 GtkWidget *close_image, *close_button;
3316 GtkRequisition requisition;
3318 close_button = gtk_button_new();
3319 gtk_button_set_relief(GTK_BUTTON(close_button), GTK_RELIEF_NONE);
3320 close_image = gtk_image_new_from_icon_name (
"window-close", GTK_ICON_SIZE_MENU);
3321 gtk_widget_show(close_image);
3322 gtk_widget_get_preferred_size (close_image, &requisition,
nullptr);
3323 gtk_widget_set_size_request(close_button, requisition.width + 4,
3324 requisition.height + 2);
3325 gtk_container_add(GTK_CONTAINER(close_button), close_image);
3327 gtk_widget_show (close_button);
3329 gtk_widget_hide (close_button);
3331 g_signal_connect_swapped (G_OBJECT (close_button),
"clicked",
3334 gtk_box_pack_start (GTK_BOX (tab_hbox), close_button, FALSE, FALSE, 0);
3335 gtk_widget_set_margin_end (GTK_WIDGET(close_button), 5);
3336 g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON, close_button);
3347 gnc_main_window_connect(window, page, tab_hbox,
label);
3372 if (!GNC_IS_MAIN_WINDOW (page->
window))
3375 window = GNC_MAIN_WINDOW (page->
window);
3378 g_warning(
"Page is not in a window.");
3382 gnc_main_window_disconnect(window, page);
3384 g_object_unref(page);
3387 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3390 if (window->window_quitting)
3396 window->just_plugin_prefs = TRUE;
3397 g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
3398 window->just_plugin_prefs = FALSE;
3399 g_list_free (plugins);
3402 gnc_main_window_remove_prefs (window);
3405 gtk_widget_destroy (GTK_WIDGET(window));
3422 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3434 const gchar *group_name,
3435 GSimpleActionGroup *group)
3437 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3438 g_return_if_fail (group_name !=
nullptr);
3439 g_return_if_fail (G_IS_SIMPLE_ACTION_GROUP(group));
3441 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
3442 G_ACTION_GROUP(group));
3447 update_menu_model (
GncMainWindow *window,
const gchar *ui_filename,
3448 const gchar **ui_updates)
3451 GError *error =
nullptr;
3453 GtkBuilder *builder = gtk_builder_new ();
3454 GMenuModel *menu_model_part;
3455 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
3457 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3458 g_return_if_fail (ui_filename !=
nullptr);
3459 g_return_if_fail (ui_updates !=
nullptr);
3461 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3463 gtk_builder_set_translation_domain (builder, PROJECT_NAME);
3464 res_name = g_strconcat (GNUCASH_RESOURCE_PREFIX
"/", ui_filename, NULL);
3466 gtk_builder_add_from_resource (builder, res_name, &error);
3471 g_critical (
"Failed to load, Error %s", error->message);
3472 g_error_free (error);
3476 for (gint i = 0; ui_updates[i]; i++)
3478 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, ui_updates[i]);
3480 gsm->search_action_label =
nullptr;
3481 gsm->search_action_name = ui_updates[i];
3482 gsm->search_action_target =
nullptr;
3485 g_menu_insert_section (G_MENU(gsm->model), gsm->index, NULL, G_MENU_MODEL(menu_model_part));
3487 PERR(
"Could not find '%s' in menu model", ui_updates[i]);
3490 g_object_unref (builder);
3502 const gchar *group_name,
3503 GActionEntry *actions,
3505 const gchar **ui_updates,
3506 const gchar *ui_filename,
3510 GSimpleActionGroup *simple_action_group;
3512 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3513 g_return_if_fail (group_name !=
nullptr);
3514 g_return_if_fail (actions !=
nullptr);
3515 g_return_if_fail (n_actions > 0);
3518 data->window = window;
3519 data->data = user_data;
3521 simple_action_group = g_simple_action_group_new ();
3523 g_action_map_add_action_entries (G_ACTION_MAP(simple_action_group),
3528 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
3529 G_ACTION_GROUP(simple_action_group));
3532 update_menu_model (window, ui_filename, ui_updates);
3543 const gchar *group_name)
3545 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
3546 g_return_if_fail (group_name !=
nullptr);
3548 gtk_widget_insert_action_group (GTK_WIDGET(window), group_name,
nullptr);
3554 GAction *action =
nullptr;
3556 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3557 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3559 action = g_action_map_lookup_action (G_ACTION_MAP(window),
3567 const gchar *group_name,
3570 GAction *action =
nullptr;
3572 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3573 g_return_val_if_fail (group_name !=
nullptr,
nullptr);
3574 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3576 auto action_group = gtk_widget_get_action_group (GTK_WIDGET(window), group_name);
3579 action = g_action_map_lookup_action (G_ACTION_MAP(action_group),
action_name);
3589 GSimpleActionGroup *
3591 const gchar *group_name)
3593 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3594 g_return_val_if_fail (group_name !=
nullptr,
nullptr);
3596 auto action_group = gtk_widget_get_action_group (GTK_WIDGET(window), group_name);
3597 return (GSimpleActionGroup*)action_group;
3605 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3606 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3608 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3617 GtkWidget *menu_item;
3619 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
3620 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
3622 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3624 menu_item = GTK_WIDGET(g_hash_table_lookup (priv->display_item_hash,
action_name));
3630 g_hash_table_insert (priv->display_item_hash, g_strdup (
action_name), menu_item);
3641 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3643 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3653 const gchar *tooltip)
3656 gboolean found =
false;
3658 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
false);
3659 g_return_val_if_fail (
action_name !=
nullptr,
false);
3660 g_return_val_if_fail (
label !=
nullptr,
false);
3662 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3665 nullptr, _(
label),
nullptr, _(tooltip));
3677 const gchar **action_names,
3682 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3684 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3686 for (gint i = 0; action_names[i]; i++)
3693 PINFO(
"Found menu_item %p with action name '%s', seting vis to '%s'",
3694 menu_item, action_names[i], vis ?
"true" :
"false");
3695 gtk_widget_set_visible (menu_item, vis);
3698 PINFO(
"Did not find menu_item with action name '%s' to set vis '%s'",
3699 action_names[i], vis ?
"true" :
"false");
3703 PINFO(
"Found tool_item %p with action name '%s', seting vis to '%s'",
3704 tool_item, action_names[i], vis ?
"true" :
"false");
3705 gtk_widget_set_visible (tool_item, vis);
3708 PINFO(
"Did not find tool_item with action name '%s' to set vis '%s'",
3709 action_names[i], vis ?
"true" :
"false");
3720 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3721 g_return_if_fail (toolbar_labels !=
nullptr);
3723 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3731 const gchar *toolbar_qualifier)
3734 GtkBuilder *builder;
3737 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3738 g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
3740 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3746 gchar *toolbar_name;
3749 if (toolbar_qualifier)
3750 toolbar_name = g_strconcat (
"mainwin-toolbar-", toolbar_qualifier,
nullptr);
3752 toolbar_name = g_strdup (
"mainwin-toolbar");
3754 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder, toolbar_name);
3757 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder,
"mainwin-toolbar");
3759 g_object_set (priv->
toolbar,
"toolbar-style", GTK_TOOLBAR_BOTH, NULL);
3761 g_free (toolbar_name);
3769 GVariant *state = g_action_get_state (G_ACTION(action));
3770 gtk_widget_set_visible (priv->
toolbar, g_variant_get_boolean (state));
3771 g_variant_unref (state);
3781 const gchar **ui_updates)
3784 const gchar *plugin_page_actions_group_name;
3785 GtkBuilder *builder;
3786 const gchar *menu_qualifier;
3788 GMenuModel *menu_model_part;
3789 #ifdef MAC_INTEGRATION 3790 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
3792 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
3793 g_return_if_fail (page !=
nullptr);
3794 g_return_if_fail (ui_updates !=
nullptr);
3796 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3807 if (!plugin_page_actions_group_name)
3813 if ((g_strcmp0 (priv->previous_plugin_page_name,
3814 plugin_page_actions_group_name) == 0) &&
3815 (g_strcmp0 (priv->previous_menu_qualifier,
3816 menu_qualifier) == 0))
3819 priv->previous_plugin_page_name = plugin_page_actions_group_name;
3820 priv->previous_menu_qualifier = menu_qualifier;
3822 gnc_main_window_update_toolbar (window, page, menu_qualifier);
3825 g_hash_table_remove_all (priv->display_item_hash);
3827 GNC_MENU_ATTRIBUTE_TEMPORARY);
3829 GncMenuModelSearch *gsm = g_new0 (GncMenuModelSearch, 1);
3830 for (gint i = 0; ui_updates[i]; i++)
3835 menu_name = g_strconcat (ui_updates[i],
"-", menu_qualifier,
nullptr);
3837 menu_name = g_strdup (ui_updates[i]);
3839 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, menu_name);
3841 if (!menu_model_part)
3842 menu_model_part = (GMenuModel *)gtk_builder_get_object (builder, ui_updates[i]);
3844 gsm->search_action_label =
nullptr;
3845 gsm->search_action_name = ui_updates[i];
3846 gsm->search_action_target =
nullptr;
3849 g_menu_insert_section (G_MENU(gsm->model), gsm->index,
3850 nullptr, G_MENU_MODEL(menu_model_part));
3852 PERR(
"Could not find '%s' in menu model", ui_updates[i]);
3862 #ifdef MAC_INTEGRATION 3863 gtkosx_application_sync_menubar (theApp);
3864 g_object_unref (theApp);
3867 g_signal_emit_by_name (window,
"menu_changed", page);
3874 gnc_main_window_update_tab_position (gpointer prefs, gchar *pref, gpointer user_data)
3877 GtkPositionType position = GTK_POS_TOP;
3882 g_return_if_fail (GNC_IS_MAIN_WINDOW(user_data));
3884 window = GNC_MAIN_WINDOW(user_data);
3886 ENTER (
"window %p", window);
3895 position = GTK_POS_BOTTOM;
3900 position = GTK_POS_LEFT;
3905 position = GTK_POS_RIGHT;
3909 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3910 gtk_notebook_set_tab_pos (GTK_NOTEBOOK(priv->
notebook), position);
3912 action = g_action_map_lookup_action (G_ACTION_MAP(window),
3913 "ViewTabPositionAction");
3915 g_signal_handlers_block_by_func (G_OBJECT(action),
3916 (gpointer)gnc_main_window_cmd_view_tab_position,
3918 g_action_change_state (G_ACTION(action), g_variant_new_int32 (item));
3919 g_signal_handlers_unblock_by_func (G_OBJECT(action),
3920 (gpointer)gnc_main_window_cmd_view_tab_position,
3923 gnc_main_window_update_tab_width (
nullptr, (
char*)GNC_PREF_TAB_WIDTH,
nullptr);
3932 gnc_main_window_update_edit_actions_sensitivity (
GncMainWindow *window, gboolean hide)
3936 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));
3938 gboolean can_copy =
false, can_cut =
false, can_paste =
false;
3940 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
3943 if (page && GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)
3945 (GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)(page, hide);
3949 if (GTK_IS_EDITABLE (widget))
3951 gboolean has_selection;
3953 has_selection = gtk_editable_get_selection_bounds
3954 (GTK_EDITABLE (widget),
nullptr,
nullptr);
3956 can_copy = has_selection;
3957 can_cut = has_selection;
3960 else if (GTK_IS_TEXT_VIEW (widget))
3962 gboolean has_selection;
3963 GtkTextBuffer *text_buffer;
3965 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
3966 has_selection = gtk_text_buffer_get_selection_bounds
3967 (text_buffer,
nullptr,
nullptr);
3969 can_copy = has_selection;
3970 can_cut = has_selection;
3975 #ifdef ORIGINAL_EPIPHANY_CODE 3977 can_copy = can_cut = can_paste =
true;
3981 can_copy = can_cut = can_paste =
false;
3985 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_copy);
3988 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_cut);
3991 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), can_paste);
3995 gnc_main_window_enable_edit_actions_sensitivity (
GncMainWindow *window)
4000 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4003 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4006 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
4011 gnc_main_window_edit_menu_show_cb (GtkWidget *menu,
4014 gnc_main_window_update_edit_actions_sensitivity (window, FALSE);
4018 gnc_main_window_edit_menu_hide_cb (GtkWidget *menu,
4021 gnc_main_window_enable_edit_actions_sensitivity (window);
4027 GtkWidget *edit_menu_item, *edit_menu;
4031 edit_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM(edit_menu_item));
4033 g_signal_connect (edit_menu,
"show",
4034 G_CALLBACK(gnc_main_window_edit_menu_show_cb), window);
4035 g_signal_connect (edit_menu,
"hide",
4036 G_CALLBACK(gnc_main_window_edit_menu_hide_cb), window);
4041 gnc_main_window_page_focus_in (GtkWidget *widget, GdkEvent *event,
4047 g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
4055 GAction *action =
nullptr;
4056 const gchar *group_name;
4058 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window),
nullptr);
4059 g_return_val_if_fail (
action_name !=
nullptr,
nullptr);
4061 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4075 PINFO(
"Redirect action is %p for action anme '%s' and group_name '%s'",
4081 main_window_realize_cb (GtkWidget *widget, gpointer user_data)
4090 g_signal_emit_by_name (window,
"menu_changed",
nullptr);
4097 GtkWidget *main_vbox;
4098 GtkBuilder *builder;
4099 GncPluginManager *manager;
4101 GError *error =
nullptr;
4107 g_signal_connect (G_OBJECT (window),
"delete-event",
4108 G_CALLBACK (gnc_main_window_delete_event), window);
4111 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4112 gtk_box_set_homogeneous (GTK_BOX (main_vbox), FALSE);
4113 gtk_widget_show (main_vbox);
4114 gtk_container_add (GTK_CONTAINER (window), main_vbox);
4116 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4117 priv->
menu_dock = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4118 gtk_box_set_homogeneous (GTK_BOX (priv->
menu_dock), FALSE);
4120 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
menu_dock,
4123 priv->
notebook = gtk_notebook_new ();
4124 g_object_set(G_OBJECT(priv->
notebook),
4126 "enable-popup", TRUE,
4129 g_signal_connect (G_OBJECT (priv->
notebook),
"switch-page",
4130 G_CALLBACK (gnc_main_window_switch_page), window);
4131 g_signal_connect (G_OBJECT (priv->
notebook),
"page-reordered",
4132 G_CALLBACK (gnc_main_window_page_reordered), window);
4133 g_signal_connect (G_OBJECT (priv->
notebook),
"focus-in-event",
4134 G_CALLBACK (gnc_main_window_page_focus_in), window);
4135 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
notebook,
4140 gtk_box_pack_start (GTK_BOX (main_vbox), priv->
statusbar,
4144 gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR(priv->
progressbar), TRUE);
4145 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(priv->
progressbar),
" ");
4149 gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(priv->
progressbar),
4152 builder = gtk_builder_new ();
4153 gtk_builder_set_translation_domain (builder, PROJECT_NAME);
4154 gtk_builder_add_from_resource (builder, GNUCASH_RESOURCE_PREFIX
"/gnc-main-window.ui", &error);
4158 g_critical (
"Failed to load, Error %s", error->message);
4159 g_error_free (error);
4163 g_action_map_add_action_entries (G_ACTION_MAP(window),
4168 priv->
menubar_model = (GMenuModel *)gtk_builder_get_object (builder,
"mainwin-menu");
4171 gtk_widget_show (GTK_WIDGET(priv->
menubar));
4173 priv->
toolbar = (GtkWidget *)gtk_builder_get_object (builder,
"mainwin-toolbar");
4174 g_object_set (priv->
toolbar,
"toolbar-style", GTK_TOOLBAR_BOTH, NULL);
4175 gtk_container_add (GTK_CONTAINER(priv->
menu_dock), GTK_WIDGET(priv->
toolbar));
4176 gtk_widget_show (GTK_WIDGET(priv->
toolbar));
4178 g_object_unref (builder);
4181 initially_insensitive_actions,
4184 always_insensitive_actions,
4190 gtk_widget_insert_action_group (GTK_WIDGET(window),
"mainwin",
4191 G_ACTION_GROUP(window));
4194 GNC_PREF_TAB_POSITION_TOP,
4195 (gpointer)gnc_main_window_update_tab_position,
4198 GNC_PREF_TAB_POSITION_BOTTOM,
4199 (gpointer)gnc_main_window_update_tab_position,
4202 GNC_PREF_TAB_POSITION_LEFT,
4203 (gpointer)gnc_main_window_update_tab_position,
4206 GNC_PREF_TAB_POSITION_RIGHT,
4207 (gpointer)gnc_main_window_update_tab_position,
4209 gnc_main_window_update_tab_position (
nullptr,
nullptr, window);
4211 gnc_main_window_init_menu_updaters (window);
4215 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4218 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4221 if (!gnc_prefs_is_extra_enabled())
4224 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
4230 g_list_foreach (plugins, gnc_main_window_add_plugin, window);
4231 g_list_free (plugins);
4233 g_signal_connect (G_OBJECT (manager),
"plugin-added",
4234 G_CALLBACK (gnc_main_window_plugin_added), window);
4235 g_signal_connect (G_OBJECT (manager),
"plugin-removed",
4236 G_CALLBACK (gnc_main_window_plugin_removed), window);
4239 g_signal_connect (G_OBJECT(window),
"realize",
4240 G_CALLBACK(main_window_realize_cb), window);
4245 #ifdef MAC_INTEGRATION 4254 gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data)
4265 gnc_quartz_should_quit (GtkosxApplication *theApp,
GncMainWindow *window)
4268 gnc_main_window_quit (window);
4273 can_activate_cb(GtkWidget *widget, guint signal_id, gpointer data)
4283 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
4284 GtkWidget *item =
nullptr;
4285 GClosure *quit_closure;
4287 gtk_widget_hide (priv->
menubar);
4288 gtk_widget_set_no_show_all (priv->
menubar,
true);
4290 gtkosx_application_set_menu_bar (theApp, GTK_MENU_SHELL(priv->
menubar));
4295 gtk_widget_hide (GTK_WIDGET(item));
4297 quit_closure = g_cclosure_new (G_CALLBACK (gnc_quartz_should_quit),
4299 gtk_accel_group_connect (priv->
accel_group,
'q', GDK_META_MASK,
4300 GTK_ACCEL_MASK, quit_closure);
4307 gtk_widget_hide (item);
4308 gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET(item), 0);
4315 gtk_widget_hide (GTK_WIDGET(item));
4316 gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET(item), 2);
4322 gtkosx_application_set_help_menu (theApp, GTK_MENU_ITEM(item));
4326 gtkosx_application_set_window_menu (theApp, GTK_MENU_ITEM(item));
4328 g_signal_connect (theApp,
"NSApplicationBlockTermination",
4329 G_CALLBACK(gnc_quartz_should_quit), window);
4331 g_signal_connect (priv->
menubar,
"can-activate-accel",
4332 G_CALLBACK (can_activate_cb),
nullptr);
4334 gtkosx_application_set_use_quartz_accelerators (theApp, FALSE);
4335 g_object_unref (theApp);
4337 #endif //MAC_INTEGRATION 4354 gnc_main_window_show_summarybar (
GncMainWindow *window, GAction *action)
4359 if (action ==
nullptr)
4360 action = g_action_map_lookup_action (G_ACTION_MAP(window),
4361 "ViewSummaryAction");
4362 if (action ==
nullptr)
4365 state = g_action_get_state (G_ACTION(action));
4367 visible = g_variant_get_boolean (state);
4369 g_variant_unref (state);
4384 gnc_main_window_switch_page (GtkNotebook *notebook,
4385 gpointer *notebook_page,
4394 ENTER(
"Notebook %p, page, %p, index %d, window %p",
4395 notebook, notebook_page, pos, window);
4396 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4398 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4402 gnc_plugin_page_unselected (page);
4405 child = gtk_notebook_get_nth_page (notebook, pos);
4417 if (page !=
nullptr)
4421 visible = gnc_main_window_show_summarybar (window,
nullptr);
4425 gnc_plugin_page_selected (page);
4426 gnc_window_update_status (GNC_WINDOW(window), page);
4434 multiple_page_actions,
4437 gnc_main_window_update_title(window);
4438 #ifndef MAC_INTEGRATION 4439 gnc_main_window_update_menu_item(window);
4441 g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
4452 gnc_main_window_page_reordered (GtkNotebook *notebook,
4461 ENTER(
"Notebook %p, child %p, index %d, window %p",
4462 notebook, child, pos, window);
4463 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4467 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4473 if (!old_link)
return;
4484 gnc_main_window_plugin_added (GncPlugin *manager,
4488 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4489 g_return_if_fail (GNC_IS_PLUGIN (plugin));
4495 gnc_main_window_plugin_removed (GncPlugin *manager,
4499 g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
4500 g_return_if_fail (GNC_IS_PLUGIN (plugin));
4508 gnc_main_window_cmd_redirect (GSimpleAction *simple,
4509 GVariant *parameter,
4513 GAction *redirect_action;
4515 PINFO(
"Redirect action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4517 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4519 if (redirect_action)
4521 PINFO(
"Found action %p", redirect_action);
4522 g_action_activate (redirect_action,
nullptr);
4528 gnc_main_window_cmd_page_setup (GSimpleAction *simple,
4529 GVariant *parameter,
4533 GtkWindow *gtk_window;
4535 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
4537 gtk_window = gnc_window_get_gtk_window(GNC_WINDOW(window));
4544 QofBook *book = gnc_get_current_book ();
4545 gboolean use_split_action_for_num_before =
4547 gint use_read_only_threshold_before =
4549 gboolean use_split_action_for_num_after;
4550 gint use_read_only_threshold_after;
4551 gboolean return_val = FALSE;
4552 GList *results =
nullptr, *iter;
4554 if (!options)
return return_val;
4557 for (iter = results; iter; iter = iter->next)
4565 gtk_dialog_run(GTK_DIALOG(dialog));
4566 gtk_widget_destroy(dialog);
4567 g_free (iter->data);
4569 g_list_free (results);
4570 qof_book_begin_edit (book);
4572 use_split_action_for_num_after =
4576 book->cached_num_days_autoreadonly_isvalid = FALSE;
4579 if (use_split_action_for_num_before != use_split_action_for_num_after)
4582 use_split_action_for_num_after);
4585 if (use_read_only_threshold_before != use_read_only_threshold_after)
4588 qof_book_commit_edit (book);
4596 auto options{
static_cast<GncOptionDB *
>(user_data)};
4598 if (!options)
return;
4601 gnc_gui_refresh_all ();
4608 auto options{
static_cast<GncOptionDB *
>(user_data)};
4620 gnc_suspend_gui_refresh ();
4627 GNC_FEATURE_NUM_FIELD_SOURCE);
4629 gnc_book_option_num_field_source_change (num_action);
4630 gnc_resume_gui_refresh ();
4634 show_handler (
const char *class_name, gint component_id,
4635 gpointer user_data, gpointer iter_data)
4642 auto widget = optwin->get_widget();
4643 gtk_window_present(GTK_WINDOW(widget));
4650 auto book = gnc_get_current_book ();
4659 if (gnc_forall_gui_components(DIALOG_BOOK_OPTIONS_CM_CLASS,
4660 show_handler,
nullptr))
4665 (title ? title : _(
"Book Options")),
4666 DIALOG_BOOK_OPTIONS_CM_CLASS, parent);
4667 optionwin->build_contents(options);
4668 optionwin->set_book_help_cb();
4669 optionwin->set_apply_cb(gnc_book_options_dialog_apply_cb,
4671 optionwin->set_close_cb ( gnc_book_options_dialog_close_cb,
4675 return optionwin->get_widget();
4679 gnc_main_window_cmd_file_properties (GSimpleAction *simple,
4680 GVariant *parameter,
4688 gnc_main_window_cmd_file_close (GSimpleAction *simple,
4689 GVariant *parameter,
4696 g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
4698 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4704 gnc_main_window_cmd_file_quit (GSimpleAction *simple,
4705 GVariant *parameter,
4712 gnc_main_window_quit(window);
4716 gnc_main_window_cmd_edit_cut (GSimpleAction *simple,
4717 GVariant *parameter,
4721 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4722 GAction *redirect_action;
4724 PINFO(
"Copy action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4726 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4728 if (redirect_action)
4730 PINFO(
"Found action %p", redirect_action);
4731 g_action_activate (redirect_action,
nullptr);
4735 if (GTK_IS_EDITABLE(widget))
4737 gtk_editable_cut_clipboard (GTK_EDITABLE(widget));
4739 else if (GTK_IS_TEXT_VIEW(widget))
4741 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4742 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(widget),
4743 GDK_SELECTION_CLIPBOARD);
4744 gboolean editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(widget));
4747 gtk_text_buffer_cut_clipboard (text_buffer, clipboard, editable);
4752 gnc_main_window_cmd_edit_copy (GSimpleAction *simple,
4753 GVariant *parameter,
4757 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4758 GAction *redirect_action;
4760 PINFO(
"Copy action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4762 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4764 if (redirect_action)
4766 PINFO(
"Found action %p", redirect_action);
4767 g_action_activate (redirect_action,
nullptr);
4771 if (GTK_IS_EDITABLE(widget))
4773 gtk_editable_copy_clipboard (GTK_EDITABLE(widget));
4775 else if (GTK_IS_TEXT_VIEW(widget))
4777 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4778 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(widget),
4779 GDK_SELECTION_CLIPBOARD);
4781 gtk_text_buffer_copy_clipboard (text_buffer, clipboard);
4786 gnc_main_window_cmd_edit_paste (GSimpleAction *simple,
4787 GVariant *parameter,
4791 GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW(window));
4792 GAction *redirect_action;
4794 PINFO(
"Paste action_is %p, name is '%s'", simple, g_action_get_name (G_ACTION(simple)));
4796 redirect_action = gnc_main_window_get_redirect (window, g_action_get_name (G_ACTION(simple)));
4798 if (redirect_action)
4800 PINFO(
"Found action %p", redirect_action);
4801 g_action_activate (redirect_action,
nullptr);
4805 if (GTK_IS_EDITABLE(widget))
4807 gtk_editable_paste_clipboard (GTK_EDITABLE(widget));
4809 else if (GTK_IS_TEXT_VIEW(widget))
4811 auto clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
4815 auto text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
4816 auto editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(widget));
4817 gtk_text_buffer_paste_clipboard (text_buffer, clipboard,
nullptr,
4824 gnc_main_window_cmd_edit_preferences (GSimpleAction *simple,
4825 GVariant *parameter,
4833 gnc_main_window_cmd_view_refresh (GSimpleAction *simple,
4834 GVariant *parameter,
4840 gnc_main_window_cmd_actions_reset_warnings (GSimpleAction *simple,
4841 GVariant *parameter,
4845 gnc_reset_warnings_dialog(GTK_WINDOW(window));
4849 gnc_main_window_cmd_actions_rename_page (GSimpleAction *simple,
4850 GVariant *parameter,
4856 GtkWidget *
label, *entry;
4859 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4863 LEAVE(
"No current page");
4867 if (!main_window_find_tab_items(window, page, &
label, &entry))
4869 LEAVE(
"can't find required widgets");
4873 gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(
label)));
4874 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
4875 gtk_widget_hide(
label);
4876 gtk_widget_show(entry);
4877 gtk_widget_grab_focus(entry);
4878 LEAVE(
"opened for editing");
4882 gnc_main_window_cmd_view_toolbar (GSimpleAction *simple,
4883 GVariant *parameter,
4888 GVariant *state = g_action_get_state (G_ACTION(simple));
4890 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4892 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!g_variant_get_boolean (state)));
4894 if (!g_variant_get_boolean (state))
4895 gtk_widget_show (priv->
toolbar);
4897 gtk_widget_hide (priv->
toolbar);
4899 g_variant_unref (state);
4903 gnc_main_window_cmd_view_summary (GSimpleAction *simple,
4904 GVariant *parameter,
4912 visible = gnc_main_window_show_summarybar (window, G_ACTION(simple));
4914 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!
visible));
4924 gnc_main_window_cmd_view_statusbar (GSimpleAction *simple,
4925 GVariant *parameter,
4930 GVariant *state = g_action_get_state (G_ACTION(simple));
4932 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4934 g_action_change_state (G_ACTION(simple), g_variant_new_boolean (!g_variant_get_boolean (state)));
4936 if (!g_variant_get_boolean (state))
4941 g_variant_unref (state);
4945 gnc_main_window_cmd_window_new (GSimpleAction *simple,
4954 gtk_widget_show(GTK_WIDGET(new_window));
4959 gnc_main_window_cmd_window_move_page (GSimpleAction *simple,
4967 GtkNotebook *notebook;
4968 GtkWidget *tab_widget, *menu_widget;
4970 ENTER(
"action %p, window %p", simple, window);
4973 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
4977 LEAVE(
"invalid page");
4982 LEAVE(
"invalid notebook_page");
4986 #ifndef MAC_INTEGRATION 4988 gnc_info_dialog (GTK_WINDOW(window),
"%s",
4989 _(
"The maximum number of window menu entries reached, no more entries will be added."));
4992 notebook = GTK_NOTEBOOK (priv->
notebook);
4993 tab_widget = gtk_notebook_get_tab_label (notebook, page->
notebook_page);
4994 menu_widget = gtk_notebook_get_menu_label (notebook, page->
notebook_page);
5001 g_object_ref(tab_widget);
5002 g_object_ref(menu_widget);
5004 gnc_main_window_disconnect(window, page);
5008 gtk_widget_show(GTK_WIDGET(new_window));
5011 gnc_main_window_connect (new_window, page, tab_widget, menu_widget);
5015 g_object_unref(menu_widget);
5016 g_object_unref(tab_widget);
5017 g_object_unref(page);
5020 DEBUG(
"Moved page %p from window %p to new window %p",
5021 page, window, new_window);
5022 DEBUG(
"Old window current is %p, new window current is %p",
5025 LEAVE(
"page moved");
5029 gnc_main_window_cmd_view_tab_position (GSimpleAction *simple,
5030 GVariant *parameter,
5033 gint item = g_variant_get_int32 (parameter);
5035 g_action_change_state (G_ACTION(simple), parameter);
5037 if (item < 0 || item > 3)
5040 if (item != 0 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_TOP))
5043 if (item != 1 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_BOTTOM))
5046 if (item != 2 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT))
5049 if (item != 3 &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_RIGHT))
5073 #ifndef MAC_INTEGRATION 5075 gnc_main_window_cmd_window_raise (GSimpleAction *simple,
5076 GVariant *parameter,
5083 g_return_if_fail (G_IS_SIMPLE_ACTION(simple));
5084 g_return_if_fail (GNC_IS_MAIN_WINDOW(window));
5086 item = g_variant_get_int32 (parameter);
5088 ENTER(
"action %p, window %p, item %d", simple, window, item);
5090 g_action_change_state (G_ACTION(simple), parameter);
5092 new_window =
static_cast<GncMainWindow*
>(g_list_nth_data (active_windows, item));
5093 gtk_window_present (GTK_WINDOW(new_window));
5097 g_idle_add ((GSourceFunc)gnc_main_window_update_radio_button, window);
5103 gnc_main_window_cmd_help_tutorial (GSimpleAction *simple,
5112 gnc_main_window_cmd_help_contents (GSimpleAction *simple,
5130 get_file (
const gchar *partial)
5132 gchar *filename, *text =
nullptr;
5136 if (filename && g_file_get_contents(filename, &text, &length,
nullptr))
5160 get_file_strsplit (
const gchar *partial)
5162 gchar *text, **lines;
5164 text = get_file(partial);
5168 lines = g_strsplit_set(text,
"\r\n", -1);
5179 url_signal_cb (GtkAboutDialog *dialog, gchar *uri, gpointer data)
5186 link_button_cb (GtkLinkButton *button, gpointer user_data)
5188 const gchar *uri = gtk_link_button_get_uri (button);
5189 gchar *escaped_uri = g_uri_escape_string (uri,
":/.\\",
true);
5191 g_free (escaped_uri);
5196 add_about_paths (GtkDialog *dialog)
5204 PWARN(
"Unable to find AboutDialog 'page_vbox' Widget");
5208 grid = gtk_grid_new ();
5210 for (
const auto& ep : gnc_list_all_paths ())
5212 gchar *env_name = g_strconcat (ep.env_name,
":", NULL);
5213 GtkWidget *
label = gtk_label_new (env_name);
5215 gchar *display_uri = gnc_doclink_get_unescaped_just_uri (uri);
5216 GtkWidget *widget = gtk_link_button_new_with_label (uri, display_uri);
5218 gtk_grid_attach (GTK_GRID(grid),
label, 0, i, 1, 1);
5219 gtk_widget_set_halign (
label, GTK_ALIGN_END);
5220 gtk_grid_attach (GTK_GRID(grid), widget, 1, i, 1, 1);
5221 gtk_widget_set_halign (widget, GTK_ALIGN_START);
5222 gtk_widget_set_margin_top (widget, 0);
5223 gtk_widget_set_margin_bottom (widget, 0);
5227 GtkWidget *mod_lab = gtk_label_new (_(
"(user modifiable)"));
5228 gtk_grid_attach (GTK_GRID(grid), mod_lab, 2, i, 1, 1);
5229 gtk_widget_show (mod_lab);
5231 g_signal_connect (widget,
"activate-link",
5232 G_CALLBACK(link_button_cb), dialog);
5235 g_free (display_uri);
5238 gtk_container_add_with_properties (GTK_CONTAINER(page_vbox), grid,
5239 "position", 1, NULL);
5240 gtk_widget_show_all (grid);
5246 gnc_main_window_cmd_help_about (GSimpleAction *simple,
5252 gchar *copyright = g_strdup_printf(_(
"Copyright © 1997-%s The GnuCash contributors."),
5254 gchar **authors = get_file_strsplit(
"AUTHORS");
5255 gchar **documenters = get_file_strsplit(
"DOCUMENTERS");
5256 gchar *license = get_file(
"LICENSE");
5257 GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
5258 GdkPixbuf *logo = gtk_icon_theme_load_icon (icon_theme,
5261 GTK_ICON_LOOKUP_USE_BUILTIN,
5263 gchar *version = g_strdup_printf (
"%s: %s\n%s: %s\nFinance::Quote: %s",
5265 _(
"Build ID"), gnc_build_id(),
5269 GtkDialog *dialog = GTK_DIALOG (gtk_about_dialog_new ());
5270 g_object_set (G_OBJECT (dialog),
5272 "documenters", documenters,
5273 "comments", _(
"Accounting for personal and small business finance."),
5274 "copyright", copyright,
5282 "translator-credits", _(
"translator-credits"),
5284 "website", PACKAGE_URL,
5285 "website-label", _(
"Visit the GnuCash website."),
5293 g_strfreev(documenters);
5295 g_strfreev(authors);
5296 g_object_unref (logo);
5297 g_signal_connect (dialog,
"activate-link",
5298 G_CALLBACK (url_signal_cb),
nullptr);
5301 add_about_paths (dialog);
5304 gtk_window_set_resizable(GTK_WINDOW (dialog), TRUE);
5306 gtk_window_set_transient_for (GTK_WINDOW (dialog),
5307 GTK_WINDOW (window));
5308 gtk_dialog_run (dialog);
5309 gtk_widget_destroy (GTK_WIDGET (dialog));
5321 #ifdef MAC_INTEGRATION 5322 auto theApp{
static_cast<GtkosxApplication *
>(g_object_new(GTKOSX_TYPE_APPLICATION,
nullptr))};
5324 for (window_iter = active_windows; window_iter !=
nullptr; window_iter = window_iter->next)
5326 gtk_widget_show(GTK_WIDGET(window_iter->data));
5328 #ifdef MAC_INTEGRATION 5329 g_signal_connect(theApp,
"NSApplicationWillTerminate",
5330 G_CALLBACK(gnc_quartz_shutdown),
nullptr);
5331 gtkosx_application_ready(theApp);
5332 g_object_unref (theApp);
5339 GtkWidget *toplevel;
5344 toplevel = gtk_widget_get_toplevel (widget);
5345 if (toplevel && GTK_IS_WINDOW (toplevel))
5346 return GTK_WINDOW (toplevel);
5357 while (toplevel && !GNC_IS_MAIN_WINDOW (toplevel))
5358 toplevel = gtk_window_get_transient_for(toplevel);
5363 for (window = active_windows; window; window = window->next)
5364 if (gtk_window_is_active (GTK_WINDOW (window->data)))
5365 return static_cast<GtkWindow*
>(window->data);
5367 for (window = active_windows; window; window = window->next)
5368 if (gtk_widget_get_mapped (GTK_WIDGET(window->data)))
5369 return static_cast<GtkWindow*>(window->data);
5381 gnc_main_window_get_gtk_window (GncWindow *window)
5383 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window),
nullptr);
5384 return GTK_WINDOW(window);
5394 gnc_main_window_get_statusbar (GncWindow *window_in)
5399 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in),
nullptr);
5401 window = GNC_MAIN_WINDOW(window_in);
5402 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5413 gnc_main_window_get_progressbar (GncWindow *window_in)
5418 g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in),
nullptr);
5420 window = GNC_MAIN_WINDOW(window_in);
5421 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5432 gnc_main_window_get_menubar (GncWindow *window)
5436 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5438 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5449 gnc_main_window_get_toolbar (GncWindow *window)
5453 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5455 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5466 gnc_main_window_get_menubar_model (GncWindow *window)
5470 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5472 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5482 static GtkAccelGroup *
5483 gnc_main_window_get_accel_group (GncWindow *window)
5487 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5489 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
5499 gnc_window_main_window_init (GncWindowInterface *iface)
5501 iface->get_gtk_window = gnc_main_window_get_gtk_window;
5502 iface->get_statusbar = gnc_main_window_get_statusbar;
5503 iface->get_progressbar = gnc_main_window_get_progressbar;
5504 iface->get_menubar = gnc_main_window_get_menubar;
5505 iface->get_toolbar = gnc_main_window_get_toolbar;
5506 iface->get_menubar_model = gnc_main_window_get_menubar_model;
5507 iface->get_accel_group = gnc_main_window_get_accel_group;
5519 gncwin = GNC_WINDOW(window);
5520 gnc_window_set_progressbar_window(gncwin);
5539 GtkBuilder *builder;
5540 GMenuModel *menu_model;
5542 const gchar *menu_qualifier;
5543 gchar *popup_menu_name;
5544 GncWindow* gnc_window;
5545 GtkWidget *statusbar;
5547 g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
5549 ENTER(
"page %p, event %p", page, event);
5551 gnc_window = GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window);
5553 statusbar = gnc_window_get_statusbar (gnc_window);
5559 if (!menu_qualifier)
5562 if (builder ==
nullptr)
5564 LEAVE(
"no builder");
5569 popup_menu_name = g_strconcat (
"mainwin-popup-", menu_qualifier,
nullptr);
5571 popup_menu_name = g_strdup (
"mainwin-popup");
5573 menu_model = (GMenuModel *)gtk_builder_get_object (builder, popup_menu_name);
5576 menu_model = (GMenuModel *)gtk_builder_get_object (builder,
"mainwin-popup");
5578 menu = gtk_menu_new_from_model (menu_model);
5589 gtk_menu_attach_to_widget (GTK_MENU(menu), GTK_WIDGET(page->
window),
nullptr);
5590 gtk_menu_popup_at_pointer (GTK_MENU(menu), (GdkEvent *) event);
5592 g_free (popup_menu_name);
5615 ENTER(
"widget %p, page %p", widget, page);
5616 do_popup_menu(page,
nullptr);
5628 GdkEventButton *event,
5631 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
5633 ENTER(
"widget %p, event %p, page %p", whatever, event, page);
5635 if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
5637 do_popup_menu(page, event);
5638 LEAVE(
"menu shown");
5642 LEAVE(
"other click");
5650 for (
auto tmp = active_windows; tmp; tmp = g_list_next(tmp))
5653 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), sensitive);
5662 g_return_val_if_fail (GNC_IS_MAIN_WINDOW(window),
nullptr);
5664 priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
Holds all of the options for a book, report, or stylesheet, organized by GncOptionSections.
void gnc_preferences_dialog(GtkWindow *parent)
This function creates the preferences dialog and presents it to the user.
GncPluginPage * gnc_plugin_page_recreate_page(GtkWidget *window, const gchar *page_type, GKeyFile *key_file, const gchar *page_group)
This function looks up a specific plugin type by name, and then calls a plugin specific function to c...
GtkWidget * statusbar
A pointer to the status bar at the bottom edge of the window.
Functions to load, save and get gui state.
void gnc_menubar_model_remove_items_with_attrib(GMenuModel *menu_model, const gchar *attrib)
Remove GMenuModel entries based on having an attribute value equal to attrib, it does not matter what...
gboolean gnc_plugin_page_has_books(GncPluginPage *page)
Query a page to see if it has a reference to any book.
gboolean gnc_plugin_page_get_use_new_window(GncPluginPage *page)
Retrieve the "use new window" setting associated with this page.
void gnc_option_db_clean(GncOptionDB *odb)
Reset all ui_items to the option value.
gboolean gnc_plugin_page_finish_pending(GncPluginPage *page)
Tell a page to finish any outstanding activities.
void gnc_main_window_restore_all_windows(const GKeyFile *keyfile)
Restore the persistent state of all windows.
void gnc_main_window_update_menu_and_toolbar(GncMainWindow *window, GncPluginPage *page, const gchar **ui_updates)
Update the main window menu with the placeholders listed in ui_updates and load the page specific too...
void qof_book_load_options(QofBook *book, GncOptionLoad load_cb, GncOptionDB *odb)
Load a GncOptionsDB from KVP data.
void gnc_plugin_page_destroy_widget(GncPluginPage *plugin_page)
Destroy the display widget that corresponds to this plugin.
GtkAccelGroup * accel_group
The accelerator group for the window.
The instance data structure for a content plugin.
void qof_book_set_dirty_cb(QofBook *book, QofBookDirtyCB cb, gpointer user_data)
Set the function to call when a book transitions from clean to dirty, or vice versa.
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
gboolean gnc_main_window_button_press_cb(GtkWidget *whatever, GdkEventButton *event, GncPluginPage *page)
Callback function invoked when the user clicks in the content of any Gnucash window.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Register a callback that gets triggered when the given preference changes.
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
utility functions for the GnuCash UI
#define PINFO(format, args...)
Print an informational note.
void gnc_main_window_set_vis_of_items_by_action(GncMainWindow *window, const gchar **action_names, gboolean vis)
Show or hide menu and toolbar items based on a NULL terminated list of action names.
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.
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.
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.
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.
The instance data structure for a main window object.
void gnc_main_window_restore_default_state(GncMainWindow *window)
Restore the persistent state of one window to a sane default.
The class data structure for a main window object.
File path resolution utility functions.
gboolean gnc_main_window_all_finish_pending(void)
Tell all pages in all windows to finish any outstanding activities.
void gnc_option_db_book_options(GncOptionDB *odb)
Register the standard option set for a QofBook.
gint gnc_list_length_cmp(const GList *list, size_t len)
Scans the GList elements the minimum number of iterations required to test it against a specified siz...
void gnc_main_window_manual_merge_actions(GncMainWindow *window, const gchar *group_name, GSimpleActionGroup *group)
Manually add a set of actions to the specified window.
void main_window_update_page_name(GncPluginPage *page, const gchar *name_in)
Update the name of the page in the main window.
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.