From 5e8141e95f5092e53f385dc79168eaa7d9844325 Mon Sep 17 00:00:00 2001 From: David Hampton Date: Sun, 9 Jun 2002 21:43:51 +0000 Subject: [PATCH] First pass at menu rearranging git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@6954 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 31 ++ src/app-file/gnome/gnc-file-history.c | 17 +- src/gnome-utils/gnc-mdi-utils.c | 422 ++++++++++++++++++++++- src/gnome-utils/gnc-mdi-utils.h | 41 +++ src/gnome-utils/gnc-menu-extensions.scm | 2 +- src/gnome/mainwindow-account-tree.c | 6 +- src/gnome/mainwindow-account-tree.h | 2 +- src/gnome/window-acct-tree.c | 361 ++++++++++++++++--- src/gnome/window-main.c | 400 ++++++++++++++++++--- src/report/report-gnome/report-gnome.scm | 4 +- src/report/report-gnome/window-report.c | 26 +- src/scm/main.scm | 4 +- 12 files changed, 1179 insertions(+), 137 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3040bb854..a18e0da722 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2002-06-08 David Hampton + + * src/app-file/gnome/gnc-file-history.c (gnc_history_update_menu): + Move the file history items into a sub-menu of the file menu. + + * src/gnome/window-acct-tree.c: Menu/toolbar items are now + enabled/disabled depending upon whether or not an account is + selected. Integrated the account specific menu into the main + application window menus. + + * src/gnome/window-main.c: Reorganize the menubar in the main + window. Add support for dispatching top level menu items to + functions that operate on contained views (i,e, on a report). + + * src/gnome/window-register.c: Start reorganizing the menubar in + the register window. + + * src/gnome-utils/gnc-mdi-utils.[ch]: Add new functions for + finding/manipulating menu/toolbar items on the fly. Add support + for automatically showing/hiding/enabling/disabling menu/toolbar + items when the view is changed in the MDI window. Add support for + dispatching various main menu items to view specific callback + functions. + + * src/report/report-gnome/window-report.c: Hook into the + dispatching from the main window menubar. + + * src/gnome-utils/gnc-menu-extensions.scm + * src/report/report-gnome/report-gnome.scm: + * src/scm/main.scm: Reorganize menu items. + 2002-06-06 Derek Atkins Create a top-level Business menu item in the main window. You diff --git a/src/app-file/gnome/gnc-file-history.c b/src/app-file/gnome/gnc-file-history.c index 04bd81fc47..277e8017d1 100644 --- a/src/app-file/gnome/gnc-file-history.c +++ b/src/app-file/gnome/gnc-file-history.c @@ -232,8 +232,7 @@ gnc_history_update_menu (GtkWidget * app_w) data = gtk_object_get_data (GTK_OBJECT (app), "gnc_num_history"); num_entries = GPOINTER_TO_INT (data); - gnome_app_remove_menu_range (app, GNOME_MENU_FILE_PATH, - pos, 1 + num_entries); + gnome_app_remove_menu_range (app, path, 0, num_entries); } if (history_list == NULL) @@ -243,17 +242,15 @@ gnc_history_update_menu (GtkWidget * app_w) return; n = g_slist_length (history_list); - /* one separator, plus one for each filename entry, plus one for end */ - menu = g_new (GnomeUIInfo, 2 + n); + /* one for each filename entry, plus one for end */ + menu = g_new (GnomeUIInfo, n + 1); - menu->type = GNOME_APP_UI_SEPARATOR; - - for (i = 1; i <= n; i++) + for (i = 0; i < n; i++) { (menu+i)->type = GNOME_APP_UI_ITEM; /* get the file name */ - file = g_slist_nth_data (history_list, i - 1); + file = g_slist_nth_data (history_list, i); if (file == NULL) file = ""; @@ -273,7 +270,7 @@ gnc_history_update_menu (GtkWidget * app_w) } *q = '\0'; - (menu+i)->label = g_strdup_printf ("_%d. %s", i, name); + (menu+i)->label = g_strdup_printf ("_%d. %s", i+1, name); g_free (name); @@ -295,7 +292,7 @@ gnc_history_update_menu (GtkWidget * app_w) gtk_object_set_data (GTK_OBJECT (app), "gnc_num_history", GINT_TO_POINTER (num_menu_entries)); - for (i = 1; i <= n; i++) + for (i = 0; i < n; i++) g_free ((menu+i)->label); g_free (menu); diff --git a/src/gnome-utils/gnc-mdi-utils.c b/src/gnome-utils/gnc-mdi-utils.c index 2dd284d712..026a6adbfe 100644 --- a/src/gnome-utils/gnc-mdi-utils.c +++ b/src/gnome-utils/gnc-mdi-utils.c @@ -36,7 +36,22 @@ #define GNC_MDI_CM_CLASS "gnc-mdi" static GNCMDIInfo *gnc_mdi_current = NULL; +static gboolean gnc_toolbar_visible = TRUE; +/* + * These strings must match the dispatch enum listed at the start of + * gnc-mdi-utils.h. + * + * Do not internationalize these strings!!! + */ +static gchar * +dispatch_menu_paths[GNC_DISP_LAST] = { + "File/Print", + "Edit/Cut", + "Edit/Copy", + "Edit/Paste", + "View/Refresh" +}; gncUIWidget gnc_ui_get_toplevel (void) @@ -69,6 +84,329 @@ gnc_ui_get_toplevel (void) return NULL; } +gboolean +gnc_mdi_get_toolbar_visibility (void) +{ + return(gnc_toolbar_visible); +} + +void +gnc_mdi_set_toolbar_visibility (gboolean visible) +{ + gnc_toolbar_visible = visible; +} + +/** + * gnc_mdi_widget_show + * + * @par1: The widget to modify. + * @par2: TRUE if the widget should be shown, FALSE if hidden. + * + * This routine is merely a wrapper around gtk_widget_show/hide so + * that those functions can be called on a list of widgets. + */ +void +gnc_mdi_widget_show(gpointer data, gpointer user_data) +{ + g_return_if_fail(data != NULL); + g_return_if_fail(GTK_IS_WIDGET(data)); + + if ((gboolean)user_data) { + gtk_widget_show(GTK_WIDGET(data)); + } else { + gtk_widget_hide(GTK_WIDGET(data)); + } +} + +/** + * gnc_mdi_widget_sensitive + * + * @par1: The widget to modify. + * @par2: The new sensitivity of the widget. + * + * This routine is merely a wrapper around gtk_widget_set_sensitive + * so that functions can be called on a list of widgets. + */ +static void +gnc_mdi_widget_sensitive(gpointer data, gpointer user_data) +{ + g_return_if_fail(data != NULL); + g_return_if_fail(GTK_IS_WIDGET(data)); + + gtk_widget_set_sensitive(GTK_WIDGET(data), (gboolean)user_data); +} + +/** + * gnc_mdi_update_widgets + * + * @par1: A pointer to the child data structure for the GNC child + * being brought to the front (or sent to the back). + * + * @par2: TRUE if this child is being raised to the front of the + * notebook (or to be the topmost window.) + * + * This routine performs all the widget modifications needed to adjust + * the menus and toolbar for a new gnc window. + */ +static void +gnc_mdi_update_widgets(GNCMDIChildInfo *mc, gboolean topmost) +{ + if (mc == NULL) return; /* expected once */ + + g_list_foreach(mc->widgets[GNC_AUTO_SHOW], gnc_mdi_widget_show, + (gpointer)topmost); + g_list_foreach(mc->widgets[GNC_AUTO_HIDE], gnc_mdi_widget_show, + (gpointer)!topmost); + g_list_foreach(mc->widgets[GNC_AUTO_ENABLE], gnc_mdi_widget_sensitive, + (gpointer)topmost); + g_list_foreach(mc->widgets[GNC_AUTO_DISABLE], gnc_mdi_widget_sensitive, + (gpointer)!topmost); +} + +/** + * gnc_mdi_child_find_menu_item + * + * @par1: A pointer to the child data structure for the GNC child + * currently visible. + * + * @par2: A string giving the menu path of the item wanted. This + * string MUST NOT be internationalized. + * + * This routine will search through the menubar looking for a specific + * menu item. It handles internationalizing the string passed to it, + * and pulling apart the string into the components of the menu path. + * + * returns: A pointer to the requested GtkMenuItem, or NULL. + */ +GtkWidget * +gnc_mdi_child_find_menu_item(GNCMDIChildInfo *mc, gchar *path) +{ + GnomeDockItem *di; + GtkWidget *menubar; + GtkWidget *menu; + GtkWidget *menuitem; + int pos; + + if (mc->app == NULL) + return(NULL); + + di = gnome_app_get_dock_item_by_name (mc->app, GNOME_APP_MENUBAR_NAME); + if (di == NULL) + return(NULL); + + menubar = gnome_dock_item_get_child (di); + if (menubar == NULL) + return(NULL); + + menu = gnome_app_find_menu_pos (menubar, path, &pos); + if (menu == NULL) + return(NULL); + + menuitem = (GtkWidget*)g_list_nth_data(GTK_MENU_SHELL(menu)->children, pos-1); + return(menuitem); +} + +/** + * gnc_mdi_child_find_toolbar_item + * + * @par1: A pointer to the child data structure for the GNC child + * currently visible. + * + * @par2: A string giving the name the item wanted. This name MUST + * NOT be internationalized. + * + * This routine will search through the toolbar looking for a specific + * item. It returns the widget that is used to display that item in + * the toolbar. This routine handles internationalizing the string + * passed to it. + * + * returns: A pointer to the requested toolbar item, or NULL. + */ +GtkWidget * +gnc_mdi_child_find_toolbar_item(GNCMDIChildInfo *mc, gchar *name) +{ + GtkToolbar *toolbar; + GtkToolbarChild *child; + gchar *label; + gchar *transl; + int pos; + + g_return_val_if_fail(mc != NULL, NULL); + g_return_val_if_fail(mc->toolbar != NULL, NULL); + + transl = L_(name); + toolbar = GTK_TOOLBAR(mc->toolbar); + for (pos = 0; pos < toolbar->num_children; pos++) { + child = g_list_nth_data(toolbar->children, pos); + if ((child == NULL) || (child->label == NULL) || (child->widget == NULL)) + continue; + gtk_label_get(GTK_LABEL(child->label), &label); + if (strcasecmp(label, transl) == 0) + return(child->widget); + } + return(NULL); +} + +/** + * gnc_mdi_child_auto_menu + * + * @par1: A pointer to the child data structure for the GNC child + * whose menus should be set up for automatic adjustment. + * + * @par2: An enum describing what should be done with this item each + * time this child is brought to the front. Choices are: SHOW, HIDE, + * ENABLE, and DISABLE. + * + * @par3: NULL terminated list of strings corresponding to the menu + * items that should be added to the adjustment list. + * + * This routine searches through the application menu data structures + * to find the specified menu item widgets, and then adds them to a + * list. This list is used for automatic manipulation of the widget + * whenever the gnc child (@param1) becomes the front-most + * window. When the child is no longer the front-most window the + * manipulation is undone. + * + * *** Do not i18n strings passed to this function. The routines + * *** called by this function correctly handle taking menu paths + * *** apart and i18n the individual pieces as they go. Passing i18n + * *** strings will cause this function to fail. + */ +void +gnc_mdi_child_auto_menu(GNCMDIChildInfo *mc, + GNCMDIAutoType type, + gchar *first_path, ...) +{ + GnomeDockItem *di; + GtkWidget *menubar; + GtkWidget *menu; + GtkWidget *menuitem; + va_list args; + gchar *path; + int pos; + + if (mc->app == NULL) + return; + + di = gnome_app_get_dock_item_by_name (mc->app, GNOME_APP_MENUBAR_NAME); + if (di == NULL) + return; + + menubar = gnome_dock_item_get_child (di); + if (menubar == NULL) + return; + + va_start(args, first_path); + for (path = first_path; path != NULL; path = va_arg(args, gchar *)) { + menu = gnome_app_find_menu_pos (menubar, path, &pos); + if (menu == NULL) + continue; + + menuitem = (GtkWidget*)g_list_nth_data(GTK_MENU_SHELL(menu)->children, pos-1); + if (menuitem == NULL) + continue; + + if (g_list_index(mc->widgets[type], menuitem) == -1) + mc->widgets[type] = g_list_append(mc->widgets[type], menuitem); + } + va_end(args); +} + +/** + * gnc_mdi_child_auto_toolbar + * + * @par1: A pointer to the child data structure for the GNC child + * whose toolbar items should be set up for automatic adjustment. + * + * @par2: An enum describing what should be done with this item each + * time this child is brought to the front. Choices are: SHOW, HIDE, + * ENABLE, and DISABLE. + * + * @par3: NULL terminated list of strings corresponding to the toolbar + * items that should be added to the adjustment list. + * + * This routine searches through the application toolbar data structures + * to find the specified toolbar item widgets, and then adds them to a + * list. This list is used for automatic manipulation of the widget + * whenever the gnc child (par1) becomes the front-most window. When + * the child is no longer the front-most window the manipulation is + * undone. + * + * *** Do not i18n strings passed to this function. This is for + * *** consistency with the previous function. This function + * *** correctly handles performing i18n on the strings passed to it. + */ +void +gnc_mdi_child_auto_toolbar(GNCMDIChildInfo *mc, + GNCMDIAutoType type, + gchar *first_path, ...) +{ + GnomeDockItem *di; + GtkToolbar *toolbar; + GtkToolbarChild *child; + GtkWidget *widget = NULL; + gchar *label; + gchar *path, *transl; + va_list args; + int pos; + + if (mc->app == NULL) + return; + + di = gnome_app_get_dock_item_by_name (mc->app, GNOME_APP_TOOLBAR_NAME); + if (di == NULL) + return; + + toolbar = GTK_TOOLBAR(gnome_dock_item_get_child (di)); + if (toolbar == NULL) + return; + + va_start(args, first_path); + for (path = first_path; path != NULL; path = va_arg(args, gchar *)) { + transl = L_(path); + for (pos = 0; pos < toolbar->num_children; pos++) { + child = g_list_nth_data(toolbar->children, pos); + if ((child == NULL) || (child->label == NULL) || (child->widget == NULL)) + continue; + gtk_label_get(GTK_LABEL(child->label), &label); + if (strcasecmp(label, transl) == 0) { + widget = child->widget; + break; + } + } + + if (widget == NULL) + continue; + + if (g_list_index(mc->widgets[type], widget) == -1) + mc->widgets[type] = g_list_append(mc->widgets[type], widget); + } + va_end(args); +} + +/** + * gnc_mdi_show_toolbar + * + * @par1: A pointer to the child data structure for the GNC child + * whose toolbar items should be shown/hidden. + * + * This routine shows or hides the gnome dock item containing the + * toolbar. + */ +void +gnc_mdi_show_toolbar (GNCMDIChildInfo *mc) +{ + GtkWidget *dockitem = GTK_WIDGET(mc->toolbar)->parent; + + if (gnc_toolbar_visible) { + gtk_widget_show(dockitem); + } else { + gtk_widget_hide(dockitem); + if (mc->app) + gtk_widget_queue_resize(mc->app->dock); + } +} + static void gnc_mdi_child_set_title (GNCMDIChildInfo *childwin) { @@ -111,8 +449,6 @@ gnc_mdi_child_set_title (GNCMDIChildInfo *childwin) * * (I'm not sure this routine is ever really called. I tried to find a * set of actions that would trigger it and couldn't.) - * - * Returns: void */ static void gnc_mdi_app_destroyed_cb (GnomeApp * app, gpointer user_data) @@ -176,8 +512,6 @@ gnc_mdi_app_created_cb (GnomeMDI * mdi, GnomeApp * app, gpointer data) * which occurs in the gnc_mdi_destroy function. This function is * basically a subroutine of that function, with a couple of layers of * gtk code between them. - * - * Returns: void */ static void gnc_mdi_destroy_cb (GtkObject * w, gpointer data) @@ -197,16 +531,84 @@ gnc_mdi_destroy_cb (GtkObject * w, gpointer data) g_free (gnc_mdi); } +/** + * gnc_mdi_child_menu_tweaking + * + * @par1: A pointer to the child data structure for the GNC child view + * that has just been created. + * + * This routine adjust the main menubar to reflect which of the + * 'dispatchable' menu items this view has set up callbacks for. It + * also calls a view specific routine which can add menu items to the + * menubar, and calls the main window routine to adjust items in the + * View menu. + */ static void -gnc_mdi_child_changed_cb (GnomeMDI * mdi, GnomeMDIChild * not_used, +gnc_mdi_child_menu_tweaking (GNCMDIChildInfo * mc) +{ + GNCMDIAutoType what; + GNCMDIDispatchType type; + + for (type = GNC_DISP_PRINT; type < GNC_DISP_LAST; type++) { + what = mc->dispatch_callback[type] ? GNC_AUTO_ENABLE : GNC_AUTO_DISABLE; + gnc_mdi_child_auto_menu(mc, what, dispatch_menu_paths[type], NULL); + } + + if (mc->menu_tweaking) + mc->menu_tweaking(mc); + if (mc->gnc_mdi->menu_tweaking) + mc->gnc_mdi->menu_tweaking(mc); +} + +/** + * gnc_mdi_child_menu_tweaking + * + * @par1: A pointer to the child data structure for the GNC child view + * that should be updated. + * + * @par2: The dispatch entry whose data should be set. + * + * @par3: A view specific callback function. + * + * @par4: The data to pass to the view specific callback. + * + * This routine remembers the data for dispatching various top level + * menu items to view specific functions. These are items like the + * print menu item, or the refresh menu item. All this function does + * is record the passed arguments on to the gnc mdi child data + * structure for later use in determining whether or not the menu item + * should be available, and then for use when the menu item is + * selected. + */ +void +gnc_mdi_set_dispatch_cb (GNCMDIChildInfo * mc, GNCMDIDispatchType type, + GtkCallback cb, gpointer data) +{ + g_return_if_fail(mc != NULL); + g_return_if_fail(type < GNC_DISP_LAST); + g_return_if_fail(cb != NULL); + + mc->dispatch_callback[type] = cb; + mc->dispatch_data[type] = data; + +} + +static void +gnc_mdi_child_changed_cb (GnomeMDI * mdi, GnomeMDIChild * prev_child, gpointer data) { - GNCMDIChildInfo * childwin = NULL; + GNCMDIChildInfo * childwin = NULL, *prevwin = NULL; GnomeUIInfo * hintinfo; GtkWidget * oldbar; GnomeApp * new_app = NULL; GnomeDockItemBehavior behavior; + if (prev_child) + { + prevwin = gtk_object_get_user_data (GTK_OBJECT(prev_child)); + gnc_mdi_update_widgets(prevwin, FALSE); + } + if (mdi && mdi->active_child) { childwin = gtk_object_get_user_data (GTK_OBJECT(mdi->active_child)); @@ -226,7 +628,7 @@ gnc_mdi_child_changed_cb (GnomeMDI * mdi, GnomeMDIChild * not_used, { if (oldbar->parent) gtk_widget_hide (GTK_WIDGET(oldbar)->parent); - gtk_widget_show (GTK_WIDGET(childwin->toolbar)->parent); + gnc_mdi_show_toolbar(childwin); } } else if (childwin->app) @@ -253,6 +655,7 @@ gnc_mdi_child_changed_cb (GnomeMDI * mdi, GnomeMDIChild * not_used, gtk_toolbar_set_style (GTK_TOOLBAR(childwin->toolbar), gnc_get_toolbar_style ()); + gnc_mdi_show_toolbar(childwin); } else { @@ -268,6 +671,8 @@ gnc_mdi_child_changed_cb (GnomeMDI * mdi, GnomeMDIChild * not_used, gtk_toolbar_set_style (GTK_TOOLBAR(childwin->toolbar), gnc_get_toolbar_style ()); + gnc_mdi_show_toolbar(childwin); + gnc_mdi_child_menu_tweaking(childwin); } oldbar = gtk_object_get_user_data (GTK_OBJECT(new_app)); @@ -295,6 +700,7 @@ gnc_mdi_child_changed_cb (GnomeMDI * mdi, GnomeMDIChild * not_used, hintinfo = gnome_mdi_get_child_menu_info (new_app); if (hintinfo) gnome_app_install_menu_hints (new_app, hintinfo); + gnc_mdi_update_widgets(childwin, TRUE); } } @@ -565,8 +971,6 @@ gnc_app_set_title (GnomeApp *app) * * This function is called during the destruction of the gnucash gui. * It is called from gnc_gui_destroy() in top-level.c - * - * Returns: void */ void gnc_mdi_destroy (GNCMDIInfo * gnc_mdi) diff --git a/src/gnome-utils/gnc-mdi-utils.h b/src/gnome-utils/gnc-mdi-utils.h index fc336f56da..2748c90596 100644 --- a/src/gnome-utils/gnc-mdi-utils.h +++ b/src/gnome-utils/gnc-mdi-utils.h @@ -32,6 +32,28 @@ typedef struct gnc_mdi_child_info GNCMDIChildInfo; typedef void (*GNCShutdownFunc) (int exit_status); typedef gboolean (*GNCMDICanRestoreCB) (const char * filename); typedef GnomeMDIChild * (*GNCMDIRestoreCB) (const char *config_string); +typedef void (*GNCMDIAutoSetup) (GNCMDIChildInfo *child); + +typedef enum { + GNC_AUTO_SHOW, + GNC_AUTO_HIDE, + GNC_AUTO_ENABLE, + GNC_AUTO_DISABLE, + GNC_AUTO_LAST +} GNCMDIAutoType; + +/* + * If you update this enum, you must also update the list of menu + * paths at the start of gnc-mdi-utils.c. + */ +typedef enum { + GNC_DISP_PRINT, + GNC_DISP_CUT, + GNC_DISP_COPY, + GNC_DISP_PASTE, + GNC_DISP_REFRESH, + GNC_DISP_LAST +} GNCMDIDispatchType; typedef struct { @@ -51,6 +73,7 @@ typedef struct GList * children; GNCShutdownFunc shutdown; + GNCMDIAutoSetup menu_tweaking; GNCMDICanRestoreCB can_restore_cb; GNCMDIRestoreCB restore_cb; @@ -70,6 +93,12 @@ struct gnc_mdi_child_info int component_id; void * user_data; char * title; + + GNCMDIAutoSetup menu_tweaking; + GList * widgets[GNC_AUTO_LAST]; + + GtkCallback dispatch_callback[GNC_DISP_LAST]; + gpointer dispatch_data[GNC_DISP_LAST]; }; @@ -96,4 +125,16 @@ void gnc_mdi_restore (GNCMDIInfo * gnc_mdi, const char * filename); void gnc_mdi_create_child_toolbar (GNCMDIInfo * mi, GNCMDIChildInfo * child); +void gnc_mdi_child_auto_menu(GNCMDIChildInfo *, GNCMDIAutoType, gchar *, ...); +void gnc_mdi_child_auto_toolbar(GNCMDIChildInfo *, GNCMDIAutoType, gchar *, ...); +GtkWidget * gnc_mdi_child_find_menu_item(GNCMDIChildInfo *mc, gchar *path); +GtkWidget * gnc_mdi_child_find_toolbar_item(GNCMDIChildInfo *mc, gchar *name); +void gnc_mdi_set_dispatch_cb (GNCMDIChildInfo * mc, GNCMDIDispatchType type, + GtkCallback cb, gpointer data); +gboolean gnc_mdi_get_toolbar_visibility (void); +void gnc_mdi_set_toolbar_visibility (gboolean visible); +void gnc_mdi_show_toolbar (GNCMDIChildInfo *mc); +void gnc_mdi_widget_show(gpointer data, gpointer user_data); + + #endif diff --git a/src/gnome-utils/gnc-menu-extensions.scm b/src/gnome-utils/gnc-menu-extensions.scm index cba50148db..82d307166a 100644 --- a/src/gnome-utils/gnc-menu-extensions.scm +++ b/src/gnome-utils/gnc-menu-extensions.scm @@ -60,7 +60,7 @@ "Functions to run when the extensions menu is created. Hook args: ()")) (define (gnc:extensions-menu-setup) - (define menu (gnc:make-menu "Extensions" (list "_Settings"))) + (define menu (gnc:make-menu "Extensions" (list "_Tools"))) (gnc:add-extension menu) (gnc:hook-run-danglers gnc:*add-extension-hook*)) diff --git a/src/gnome/mainwindow-account-tree.c b/src/gnome/mainwindow-account-tree.c index 127d374c22..c755d92fc0 100644 --- a/src/gnome/mainwindow-account-tree.c +++ b/src/gnome/mainwindow-account-tree.c @@ -196,17 +196,17 @@ gnc_mainwin_account_tree_get_type () * * * Args: mwac_trec - the mainwindow account tree to attach to * * popup_info - the popup to attach * - * Returns: Nothing * + * Returns: The menu created. * \*******************************************************************************/ -void +GtkWidget * gnc_mainwin_account_tree_attach_popup(GNCMainWinAccountTree *mwac_tree, GnomeUIInfo *popup_info, gpointer user_data) { GtkWidget *popup = gnome_popup_menu_new(popup_info); gnome_popup_menu_attach(popup, GTK_WIDGET(mwac_tree->acc_tree), user_data); - return; + return(popup); } /*******************************************************************************\ diff --git a/src/gnome/mainwindow-account-tree.h b/src/gnome/mainwindow-account-tree.h index 04444b0c7b..b406235471 100644 --- a/src/gnome/mainwindow-account-tree.h +++ b/src/gnome/mainwindow-account-tree.h @@ -63,7 +63,7 @@ struct _GNCMainWinAccountTreeClass guint gnc_mainwin_account_tree_get_type(void); GtkWidget* gnc_mainwin_account_tree_new(void); -void +GtkWidget* gnc_mainwin_account_tree_attach_popup(GNCMainWinAccountTree *tree, GnomeUIInfo *popup_info, gpointer user_data); diff --git a/src/gnome/window-acct-tree.c b/src/gnome/window-acct-tree.c index e701edb8ce..ce8dbce829 100644 --- a/src/gnome/window-acct-tree.c +++ b/src/gnome/window-acct-tree.c @@ -73,6 +73,75 @@ struct GNCAcctTreeWin_p GList * account_sensitives; }; +static void gnc_acct_tree_tweak_menu (GNCMDIChildInfo * mc); + + +/** + * gnc_acct_tree_window_set_sensitives + * + * @par1: A pointer to the data structure holding all the data + * associated with the Account Tree window. + * + * @par2: TRUE to enable the list of widgets, FALSE to disable them. + * + * Run the list of account sensitive widgets and enable/disable all + * the items in the list. + */ +static void +gnc_acct_tree_window_set_sensitives(GNCAcctTreeWin * win, + gboolean sensitive) +{ + g_list_foreach(win->account_sensitives, (GFunc)gtk_widget_set_sensitive, + (gpointer)sensitive); +} + + +/** + * gnc_acct_tree_window_add_sensitive + * + * @par1: A pointer to the data structure holding all the data + * associated with the Account Tree window. + * + * @par2: A pointer to a menu or toolbar item. + * + * Add this widget to the list of items to be enabled/disabled when an + * account is selected in this window. + */ +static void +gnc_acct_tree_window_add_sensitive(GNCAcctTreeWin * win, GtkWidget *widget) +{ + if (widget == NULL) + return; + win->account_sensitives = g_list_append(win->account_sensitives, widget); +} + +/** + * gnc_acct_tree_window_find_popup_item + * + * @par1: A pointer to the data structure holding all the data + * associated with the Account Tree window. + * + * @par2: A pointer to the popup menu for this window. + * + * @par3: The name of the menu item to find. + * + * This routine looks for a particular menu item in a popup menu. If + * found, it adds the menu to the list of items to be enabled/disabled + * when an account is selected in this window. + */ +static void +gnc_acct_tree_window_find_popup_item(GNCAcctTreeWin * win, GtkWidget *popup, + gchar *name) +{ + GtkWidget *menuitem; + gint pos; + + if (gnome_app_find_menu_pos(popup, name, &pos)) { + menuitem = (GtkWidget*)g_list_nth_data(GTK_MENU_SHELL(popup)->children, + pos-1); + gnc_acct_tree_window_add_sensitive(win, menuitem); + } +} /******************************************************************** * ACCOUNT WINDOW FUNCTIONS @@ -150,10 +219,12 @@ gnc_acct_tree_view_refresh (gpointer data) } static GtkWidget * -gnc_acct_tree_view_new(GnomeMDIChild * child, gpointer user_data) { +gnc_acct_tree_view_new(GnomeMDIChild * child, gpointer user_data) +{ GNCMDIInfo * maininfo = user_data; GNCMDIChildInfo * mc = g_new0(GNCMDIChildInfo, 1); GNCAcctTreeWin * win = gnc_acct_tree_window_new(child->name); + GtkWidget * popup; char * name; mc->contents = gnc_acct_tree_window_get_widget(win); @@ -165,6 +236,8 @@ gnc_acct_tree_view_new(GnomeMDIChild * child, gpointer user_data) { mc->user_data = win; mc->title = g_strdup(_("Accounts")); + mc->menu_tweaking = gnc_acct_tree_tweak_menu; + gtk_object_set_user_data(GTK_OBJECT(child), mc); /* set the child name that will get used to save app state */ @@ -189,14 +262,23 @@ gnc_acct_tree_view_new(GnomeMDIChild * child, gpointer user_data) { gnc_acct_tree_window_create_toolbar(win, mc); gnc_mdi_create_child_toolbar(maininfo, mc); - gnc_mainwin_account_tree_attach_popup - (GNC_MAINWIN_ACCOUNT_TREE (win->account_tree), - mc->menu_info->moreinfo, child); - - if(mc->menu_info) { - gnome_mdi_child_set_menu_template(child, mc->menu_info); + if (mc->menu_info) { + popup = gnc_mainwin_account_tree_attach_popup + (GNC_MAINWIN_ACCOUNT_TREE (win->account_tree), + mc->menu_info->moreinfo, child); + gnc_acct_tree_window_find_popup_item(win, popup, "Open Account"); + gnc_acct_tree_window_find_popup_item(win, popup, "Open Subaccounts"); + gnc_acct_tree_window_find_popup_item(win, popup, "Edit Account"); + gnc_acct_tree_window_find_popup_item(win, popup, "Delete Account"); } + /* + * The 'Account' menu used to be created at this point. Its + * functionality has been integrated into the other menus. The + * GnomeUIInfo data structures are still used to create the popup + * menu. + */ + return mc->contents; } @@ -721,7 +803,8 @@ static void gnc_acct_tree_window_toolbar_options_cb(GtkWidget * w, gpointer d); void gnc_acct_tree_window_create_toolbar(GNCAcctTreeWin * win, - GNCMDIChildInfo * child) { + GNCMDIChildInfo * child) +{ GnomeUIInfo toolbar_template[] = { { GNOME_APP_UI_ITEM, @@ -782,57 +865,78 @@ gnc_acct_tree_window_create_toolbar(GNCAcctTreeWin * win, child->toolbar_info = g_memdup (toolbar_template, sizeof(toolbar_template)); } +/* + * The scrub menu is shared by both the code to insert items into the + * main menus, and the code to create the right click popup menu. + */ +static GnomeUIInfo scrubmenu[] = +{ + { + GNOME_APP_UI_ITEM, + N_("Check & Repair A_ccount"), + N_("Check for and repair unbalanced transactions and orphan splits " + "in this account"), + gnc_acct_tree_window_menu_scrub_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("Check & Repair Su_baccounts"), + N_("Check for and repair unbalanced transactions and orphan splits " + "in this account and its subaccounts"), + gnc_acct_tree_window_menu_scrub_sub_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("Check & Repair A_ll"), + N_("Check for and repair unbalanced transactions and orphan splits " + "in all accounts"), + gnc_acct_tree_window_menu_scrub_all_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_END +}; + +/** + * gnc_acct_tree_window_create_menu + * + * @par1: A pointer to the data structure holding all the data + * associated with the Account Tree window. + * + * @par2: A pointer to the GNC MDI child associated with the Account + * Tree window. + * + * This routine creates the menu for the right-click popup menu in the + * account tree window. This same menu was also previously inserted + * into the menu bar and available there. These menu items are now + * separately incorporated into the menus. See + * gnc_acct_tree_tweak_menu(). + */ void gnc_acct_tree_window_create_menu(GNCAcctTreeWin * main_info, - GNCMDIChildInfo * child) { - GnomeUIInfo scrubmenu[] = - { - { - GNOME_APP_UI_ITEM, - N_("Check & Repair A_ccount"), - N_("Check for and repair unbalanced transactions and orphan splits " - "in this account"), - gnc_acct_tree_window_menu_scrub_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("Check & Repair Su_baccounts"), - N_("Check for and repair unbalanced transactions and orphan splits " - "in this account and its subaccounts"), - gnc_acct_tree_window_menu_scrub_sub_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - { - GNOME_APP_UI_ITEM, - N_("Check & Repair A_ll"), - N_("Check for and repair unbalanced transactions and orphan splits " - "in all accounts"), - gnc_acct_tree_window_menu_scrub_all_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, - 0, 0, NULL - }, - GNOMEUIINFO_END - }; + GNCMDIChildInfo * child) +{ GnomeUIInfo * dup_scrub = g_memdup(scrubmenu, sizeof(scrubmenu)); GnomeUIInfo accountsmenu[] = { { GNOME_APP_UI_ITEM, - N_("_Open Account"), + N_("Open Account"), N_("Open the selected account"), - gnc_acct_tree_window_menu_open_cb, NULL, NULL, + gnc_acct_tree_window_menu_open_cb, child->child, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, 'o', GDK_CONTROL_MASK, NULL }, { GNOME_APP_UI_ITEM, - N_("Open S_ubaccounts"), + N_("Open _Subaccounts"), N_("Open the selected account and all its subaccounts"), - gnc_acct_tree_window_menu_open_subs_cb, NULL, NULL, + gnc_acct_tree_window_menu_open_subs_cb, child->child, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, 0, 0, NULL }, @@ -911,17 +1015,6 @@ gnc_acct_tree_window_create_menu(GNCAcctTreeWin * main_info, } -/******************************************************************** - * gnc_acct_tree_window_set_sensitives - * set account-related buttons/menus sensitivities - ********************************************************************/ - -static void -gnc_acct_tree_window_set_sensitives(GNCAcctTreeWin * win, - gboolean sensitive) { - /* FIXME: set sensitivity right. */ -} - static void gnc_acct_tree_window_select_cb(GNCMainWinAccountTree *tree, Account *account, @@ -931,8 +1024,7 @@ gnc_acct_tree_window_select_cb(GNCMainWinAccountTree *tree, account = gnc_mainwin_account_tree_get_current_account(tree); sensitive = (account != NULL); - gnc_acct_tree_window_set_sensitives - (gtk_object_get_user_data(GTK_OBJECT(tree)), sensitive); + gnc_acct_tree_window_set_sensitives(win, sensitive); } @@ -1128,3 +1220,158 @@ gnc_acct_tree_window_toolbar_options_cb(GtkWidget * widget, gpointer data) { } } +/** + * gnc_acct_tree_tweak_menu + * + * @par1: A pointer to the GNC MDI child associated with the Account + * Tree window. + * + * This routine is called when the account tree view is created and + * shown for the first time. It performs a variety of setup functions. + * First, it creates menu items needed for the Account Tree window, + * and inserts them into the main MDI application menus at the correct + * positions. Second, it also sets up certain main menu items to be + * enabled/disabled whenever the account tree view is brought to the + * top. Third, it builds a list of widgets (menu and toolbar items) + * to be enabled/disabled whenever an account is selected in the + * view. + */ +static void +gnc_acct_tree_tweak_menu (GNCMDIChildInfo * mc) +{ + GNCAcctTreeWin * win; + GtkWidget * widget; + GnomeUIInfo fileitems1[] = + { + { + GNOME_APP_UI_ITEM, + N_("_New Account..."), + N_("Create a new account"), + gnc_acct_tree_window_menu_add_account_cb, mc->child, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_ADD, + 0, 0, NULL + }, + GNOMEUIINFO_END + }; + GnomeUIInfo fileitems2[] = + { + { + GNOME_APP_UI_ITEM, + N_("_Open Account"), + N_("Open the selected account"), + gnc_acct_tree_window_menu_open_cb, mc->child, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, + 'o', GDK_CONTROL_MASK, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("Open S_ubaccounts"), + N_("Open the selected account and all its subaccounts"), + gnc_acct_tree_window_menu_open_subs_cb, mc->child, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, + 0, 0, NULL + }, + GNOMEUIINFO_END + }; + + GnomeUIInfo edititems[] = + { + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_ITEM, + N_("_Edit Account"), + N_("Edit the selected account"), + gnc_acct_tree_window_menu_edit_cb, mc->child, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PROP, + 'e', GDK_CONTROL_MASK, NULL + }, + { GNOME_APP_UI_ITEM, + N_("_Delete Account"), + N_("Delete selected account"), + gnc_acct_tree_window_menu_delete_account_cb, + mc->child, + NULL, + GNOME_APP_PIXMAP_STOCK, + GNOME_STOCK_PIXMAP_REMOVE, + 0, 0, NULL + }, + GNOMEUIINFO_END + }; + + GnomeUIInfo * dup_scrub = g_memdup(scrubmenu, sizeof(scrubmenu)); + GnomeUIInfo actionsitems[] = + { + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_ITEM, + N_("_Transfer..."), + N_("Transfer funds from one account to another"), + gnc_acct_tree_window_menu_transfer_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 't', GDK_CONTROL_MASK, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("_Reconcile..."), + N_("Reconcile the selected account"), + gnc_acct_tree_window_menu_reconcile_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 'r', GDK_CONTROL_MASK, NULL + }, + { + GNOME_APP_UI_ITEM, + N_("Stock S_plit..."), + N_("Record a stock split or a stock merger"), + gnc_acct_tree_window_menu_stock_split_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_SUBTREE(N_("_Check & Repair"), dup_scrub), + GNOMEUIINFO_END + }; + + if (mc->app == NULL) + return; + + /* + * This window can be created multiple times, so the code needs to + * check and see if the menus its adding are already present. This + * can't just be code to insure this routine is only called + * once,because the Gnome MDI code may destroy and recreate the + * menus and toolbars. What a pain. + */ + /* Do not i18n these strings!!! */ + if (gnc_mdi_child_find_menu_item(mc, "File/New Account...")) + return; + + /* Do not i18n these strings!!! */ + gnome_app_insert_menus (mc->app, "File/New File", fileitems1); + gnome_app_insert_menus (mc->app, "File/Open...", fileitems2); + gnome_app_insert_menus (mc->app, "Edit/Paste", edititems); + gnome_app_insert_menus (mc->app, "Actions/Scheduled Transactions", + actionsitems); + + win = (GNCAcctTreeWin *)mc->user_data; + gnc_acct_tree_window_add_sensitive(win, fileitems2[0].widget); + gnc_acct_tree_window_add_sensitive(win, fileitems2[1].widget); + gnc_acct_tree_window_add_sensitive(win, edititems[1].widget); + gnc_acct_tree_window_add_sensitive(win, edititems[2].widget); + + /* Do not i18n these strings!!! */ + widget = gnc_mdi_child_find_toolbar_item(mc, "Open"); + gnc_acct_tree_window_add_sensitive(win, widget); + widget = gnc_mdi_child_find_toolbar_item(mc, "Edit"); + gnc_acct_tree_window_add_sensitive(win, widget); + widget = gnc_mdi_child_find_toolbar_item(mc, "Delete"); + gnc_acct_tree_window_add_sensitive(win, widget); + + /* Do not i18n these strings!!! */ + gnc_mdi_child_auto_menu(mc, GNC_AUTO_DISABLE, "File/Close", NULL); + gnc_mdi_child_auto_toolbar(mc, GNC_AUTO_DISABLE, "Close", NULL); + + /* Start with all the 'sensitives' disabled. */ + g_list_foreach(win->account_sensitives, (GFunc)gtk_widget_set_sensitive, + (gpointer)FALSE); +} + diff --git a/src/gnome/window-main.c b/src/gnome/window-main.c index 15729581ff..4f48e5e8ed 100644 --- a/src/gnome/window-main.c +++ b/src/gnome/window-main.c @@ -66,10 +66,41 @@ #include "window-register.h" #include "window-report.h" +static gboolean gnc_show_status_bar = TRUE; +static gboolean gnc_show_summary_bar = TRUE; + static void gnc_main_window_create_menus(GNCMDIInfo * maininfo); static GnomeUIInfo * gnc_main_window_toolbar_prefix (void); static GnomeUIInfo * gnc_main_window_toolbar_suffix (void); + +/** + * gnc_main_window_get_mdi_child + * + * This routine grovels through the mdi data structures and finds the + * GNCMDIChildInfo data structure for the view currently at the top of + * the stack. + * + * returns: A pointer to the GNCMDIChildInfo data structure for the + * current view, or NULL in cast of error. + */ +static GNCMDIChildInfo * +gnc_main_window_get_mdi_child (void) +{ + GNCMDIInfo *main_info; + GnomeMDI *mdi; + + main_info = gnc_mdi_get_current (); + if (!main_info) + return(NULL); + + mdi = main_info->mdi; + if (!mdi || !mdi->active_child) + return(NULL); + + return(gtk_object_get_user_data(GTK_OBJECT(mdi->active_child))); +} + /******************************************************************** * gnc_shutdown * close down gnucash from the C side... @@ -178,7 +209,8 @@ gnc_refresh_main_window_info (void) ********************************************************************/ static GnomeMDIChild * -gnc_main_window_create_child(const gchar * configstring) { +gnc_main_window_create_child(const gchar * configstring) +{ GnomeMDIChild *child; URLType type; char * location; @@ -221,6 +253,144 @@ gnc_main_window_can_restore_cb (const char * filename) GNC_COMMODITY_NS_LEGACY); } +/** + * gnc_acct_tree_tweak_menus + * + * @par1: A pointer to the GNC MDI child associated with the Main + * window. + * + * This routine updates the View window in the main window menubar to + * correctly show the state of the Toolbar, Summarybar and Statusbar. + * The "show xxx" and "Hide xxx" menu items are changed to show what + * can be done to the item in its current state. I.E. If the item is + * hidden, only the "Show xxx" menu item will be visible. This + * routine is called whenever one of the main window parts is hidden + * or shown, or whenever the the mdi view is changed (for safety + * sake). + */ +static void +gnc_main_window_tweak_menus(GNCMDIChildInfo * mc) +{ + GtkWidget *widget; + gboolean toolbar_visibility; + + toolbar_visibility = gnc_mdi_get_toolbar_visibility(); + + widget = gnc_mdi_child_find_menu_item(mc, "View/Show Toolbar"); + gnc_mdi_widget_show(widget, (gpointer)!toolbar_visibility); + widget = gnc_mdi_child_find_menu_item(mc, "View/Hide Toolbar"); + gnc_mdi_widget_show(widget, (gpointer)toolbar_visibility); + + widget = gnc_mdi_child_find_menu_item(mc, "View/Show Status Bar"); + gnc_mdi_widget_show(widget, (gpointer)!gnc_show_status_bar); + widget = gnc_mdi_child_find_menu_item(mc, "View/Hide Status Bar"); + gnc_mdi_widget_show(widget, (gpointer)gnc_show_status_bar); + + widget = gnc_mdi_child_find_menu_item(mc, "View/Show Summary Bar"); + gnc_mdi_widget_show(widget, (gpointer)!gnc_show_summary_bar); + widget = gnc_mdi_child_find_menu_item(mc, "View/Hide Summary Bar"); + gnc_mdi_widget_show(widget, (gpointer)gnc_show_summary_bar); +} + +/** + * gnc_main_window_flip_toolbar_cb + * + * @par1: A pointer to the menu item selected. (ignored) + * @par2: The user data for this menu item. (ignored) + * + * This routine flips the state of the toolbar, hiding it if currently + * visible, and showing it if not. This routine has to grovel through + * the mdi related data structures to find the current child data + * structure (because there are potentially many windows). The + * callback data should point to the right mdi child data structure, + * but doesn't appear to. + */ +static void +gnc_main_window_flip_toolbar_cb(GtkWidget * widget, gpointer data) +{ + GNCMDIChildInfo * mc; + gboolean toolbar_visibility = !gnc_mdi_get_toolbar_visibility(); + + mc = gnc_main_window_get_mdi_child(); + if (!mc) + return; + gnc_mdi_set_toolbar_visibility(toolbar_visibility); + gnc_mdi_show_toolbar(mc); + gnc_main_window_tweak_menus(mc); +} + +/** + * gnc_main_window_flip_status_bar_cb + * + * @par1: A pointer to the menu item selected. (ignored) + * @par2: The user data for this menu item. (ignored) + * + * This routine flips the state of the status bar, hiding it if + * currently visible, and showing it if not. This routine has to + * grovel through the mdi related data structures to find the current + * child data structure (because there are potentially many windows). + * The callback data should point to the right mdi child data + * structure, but doesn't appear to. + */ +static void +gnc_main_window_flip_status_bar_cb(GtkWidget * widget, gpointer data) +{ + GNCMDIChildInfo * mc; + + gnc_show_status_bar = !gnc_show_status_bar; + + mc = gnc_main_window_get_mdi_child(); + if (!mc || !mc->app) + return; + + if (gnc_show_status_bar) { + gtk_widget_show(mc->app->statusbar); + } else { + gtk_widget_hide(mc->app->statusbar); + gtk_widget_queue_resize(mc->app->statusbar->parent); + } + gnc_main_window_tweak_menus(mc); +} + +/** + * gnc_main_window_flip_summary_bar_cb + * + * @par1: A pointer to the menu item selected. (ignored) + * @par2: The user data for this menu item. (ignored) + * + * This routine flips the state of the summary bar, hiding it if + * currently visible, and showing it if not. This routine has to + * grovel through the mdi related data structures to find the current + * child data structure (because there are potentially many windows). + * The callback data should point to the right mdi child data + * structure, but doesn't appear to. + */ +static void +gnc_main_window_flip_summary_bar_cb(GtkWidget * widget, gpointer data) +{ + GNCMDIChildInfo * mc; + GnomeDockItem *summarybar; + guint dc1, dc2, dc3, dc4; + + gnc_show_summary_bar = !gnc_show_summary_bar; + + mc = gnc_main_window_get_mdi_child(); + if (!mc || !mc->app) + return; + + summarybar = gnome_dock_get_item_by_name(GNOME_DOCK(mc->app->dock), + "Summary Bar", + &dc1, &dc2, &dc3, &dc4); + if (!summarybar) return; + + if (gnc_show_summary_bar) + gtk_widget_show(GTK_WIDGET(summarybar)); + else + gtk_widget_hide(GTK_WIDGET(summarybar)); + gnc_main_window_tweak_menus(mc); + gtk_widget_queue_resize(mc->app->dock); +} + /******************************************************************** * gnc_main_window_new() * initialize the Gnome MDI system @@ -247,7 +417,7 @@ gnc_main_window_new (void) /* set up the position where the child menus/toolbars will be * inserted */ gnome_mdi_set_child_menu_path(GNOME_MDI(retval->mdi), - "_Tools"); + "_Edit"); gnome_mdi_set_child_list_path(GNOME_MDI(retval->mdi), "_Windows/"); @@ -256,12 +426,16 @@ gnc_main_window_new (void) GTK_SIGNAL_FUNC(gnc_main_window_app_created_cb), retval); + + /* handle show/hide items in view menu */ + retval->menu_tweaking = gnc_main_window_tweak_menus; + return retval; } /******************************************************************** * menu/toolbar data structures and callbacks - * these are the "templates" that are installed in every toplevel + * these are the "templates" that are installed in every top level * MDI window ********************************************************************/ @@ -347,7 +521,7 @@ gnc_main_window_file_export_cb(GtkWidget * widget, gpointer data) rc = stat (filename, &statbuf); - /* Check for an error that isn't a non-existant file. */ + /* Check for an error that isn't a non-existent file. */ if (rc != 0 && errno != ENOENT) { const char *format = _("You cannot save to that filename.\n\n%s"); @@ -408,6 +582,60 @@ gnc_main_window_file_shutdown_cb(GtkWidget * widget, gpointer data) gnc_shutdown (0); } +/** + * gnc_main_window_dispatch_cb + * + * @par1: A pointer to the menu item selected. (ignored) + * @par2: The user data for this menu item. (ignored) + * + * The main menubar has several items that must react differently + * depending upon what window is in front when they are selected. + * These menus all point to this dispatch routine, which uses the user + * data associated with the menu item to determine which function was + * requested. If then calls the appropriate dispatch function (and + * data) registered for this item and saved in the GNCMDIChildInfo + * data structure. + * + * Again, this routine has to grovel through the mdi related data + * structures to find the current child data structure (because there + * are potentially many windows). The callback data should point to + * the right mdi child data structure, but doesn't appear to. + */ +static void +gnc_main_window_dispatch_cb(GtkWidget * widget, gpointer data) +{ + GNCMDIChildInfo *mc; + GNCMDIDispatchType type; + gpointer *uidata; + + /* How annoying. MDI overrides the user data. Get it the hard way. */ + uidata = gtk_object_get_data(GTK_OBJECT(widget), GNOMEUIINFO_KEY_UIDATA); + type = (GNCMDIDispatchType)GPOINTER_TO_UINT(uidata); + g_return_if_fail(type < GNC_DISP_LAST); + + mc = gnc_main_window_get_mdi_child(); + if (mc && mc->dispatch_callback[type]) + mc->dispatch_callback[type](widget, mc->dispatch_data[type]); +} + +/** + * gnc_main_window_tax_info_cb + * + * @par1: A pointer to the menu item selected. (ignored) + * @par2: The user data for this menu item. (ignored) + * + * Bring up the window for editing tax data. + */ +static void +gnc_main_window_tax_info_cb (GtkWidget * widget, gpointer unused) { + GNCMDIChildInfo * mc; + + mc = gnc_main_window_get_mdi_child(); + if (!mc || !mc->app) + return; + gnc_tax_info_dialog(GTK_WIDGET(mc->app)); +} + static void gnc_main_window_file_close_cb(GtkWidget * widget, gpointer data) { @@ -546,66 +774,140 @@ gnc_main_window_file_new_account_tree_cb(GtkWidget * w, gpointer data) static void gnc_main_window_create_menus(GNCMDIInfo * maininfo) { - static GnomeUIInfo gnc_file_menu_template[] = + static GnomeUIInfo gnc_file_recent_files_submenu_template[] = + { + GNOMEUIINFO_END + }; + + static GnomeUIInfo gnc_file_export_submenu_template[] = { - GNOMEUIINFO_MENU_NEW_ITEM(N_("New _File"), - N_("Create a new file"), - gnc_main_window_file_new_file_cb, NULL), - GNOMEUIINFO_MENU_OPEN_ITEM(gnc_main_window_file_open_cb, NULL), - GNOMEUIINFO_MENU_SAVE_ITEM(gnc_main_window_file_save_cb, NULL), - GNOMEUIINFO_MENU_SAVE_AS_ITEM(gnc_main_window_file_save_as_cb, NULL), { GNOME_APP_UI_ITEM, - N_("Export Accounts..."), + N_("Export _Accounts..."), N_("Export the account hierarchy to a new file"), gnc_main_window_file_export_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL }, - GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_END + }; + + static GnomeUIInfo gnc_file_menu_template[] = + { + GNOMEUIINFO_MENU_NEW_ITEM(N_("_New File"), + N_("Create a new file"), + gnc_main_window_file_new_file_cb, NULL), { GNOME_APP_UI_ITEM, - N_("Import QIF..."), - N_("Import a Quicken QIF file"), - gnc_main_window_file_import_cb, NULL, NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_CONVERT, - 'i', GDK_CONTROL_MASK, NULL - }, - GNOMEUIINFO_SEPARATOR, - { - GNOME_APP_UI_ITEM, - N_("New _Account Tree"), + N_("New Account _Tree"), N_("Open a new account tree view"), gnc_main_window_file_new_account_tree_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL }, GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_MENU_OPEN_ITEM(gnc_main_window_file_open_cb, NULL), { GNOME_APP_UI_ITEM, - N_("Move to New Window"), + N_("Open in a New Window"), N_("Open a new top-level GnuCash window for the current view"), gnc_main_window_file_new_window_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL }, + GNOMEUIINFO_SUBTREE( N_("Open _Recent"), + gnc_file_recent_files_submenu_template ), + GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_MENU_SAVE_ITEM(gnc_main_window_file_save_cb, NULL), + GNOMEUIINFO_MENU_SAVE_AS_ITEM(gnc_main_window_file_save_as_cb, NULL), + GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, - N_("Close _Window"), - N_("Close the current notebook page"), - gnc_main_window_file_close_cb, NULL, NULL, - GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL - }, + N_("_Import QIF..."), + N_("Import a Quicken QIF file"), + gnc_main_window_file_import_cb, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_CONVERT, + 'i', GDK_CONTROL_MASK, NULL + }, + GNOMEUIINFO_SUBTREE( N_("_Export"), + gnc_file_export_submenu_template ), + GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_MENU_PRINT_ITEM(gnc_main_window_dispatch_cb, + GUINT_TO_POINTER(GNC_DISP_PRINT)), + GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_MENU_CLOSE_ITEM(gnc_main_window_file_close_cb, NULL), GNOMEUIINFO_MENU_EXIT_ITEM(gnc_main_window_file_shutdown_cb, NULL), GNOMEUIINFO_END }; - static GnomeUIInfo gnc_settings_menu_template[] = + static GnomeUIInfo gnc_edit_menu_template[] = { - { - GNOME_APP_UI_ITEM, - N_("_Preferences..."), - N_("Open the global preferences dialog"), - gnc_main_window_options_cb, NULL, NULL, - GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PREF, + GNOMEUIINFO_MENU_CUT_ITEM(gnc_main_window_dispatch_cb, + GUINT_TO_POINTER(GNC_DISP_CUT)), + GNOMEUIINFO_MENU_COPY_ITEM(gnc_main_window_dispatch_cb, + GUINT_TO_POINTER(GNC_DISP_COPY)), + GNOMEUIINFO_MENU_PASTE_ITEM(gnc_main_window_dispatch_cb, + GUINT_TO_POINTER(GNC_DISP_PASTE)), + GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_MENU_PREFERENCES_ITEM(gnc_main_window_options_cb, NULL), + { GNOME_APP_UI_ITEM, + N_("Ta_x Options"), + N_("Setup tax information for all income and expense accounts"), + gnc_main_window_tax_info_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_END + }; + + static GnomeUIInfo gnc_view_menu_template[] = + { + { GNOME_APP_UI_ITEM, + N_("_Refresh"), + N_("Refresh this window"), + gnc_main_window_dispatch_cb, GUINT_TO_POINTER(GNC_DISP_REFRESH), NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + { GNOME_APP_UI_ITEM, + N_("Hide _Toolbar"), + N_("Hide the toolbar on this window"), + gnc_main_window_flip_toolbar_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { GNOME_APP_UI_ITEM, + N_("Show _Toolbar"), + N_("Show the toolbar on this window"), + gnc_main_window_flip_toolbar_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { GNOME_APP_UI_ITEM, + N_("Hide _Status Bar"), + N_("Hide the status bar on this window"), + gnc_main_window_flip_status_bar_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { GNOME_APP_UI_ITEM, + N_("Show _Status Bar"), + N_("Show the status bar on this window"), + gnc_main_window_flip_status_bar_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { GNOME_APP_UI_ITEM, + N_("Hide S_ummary Bar"), + N_("Hide the summary bar on this window"), + gnc_main_window_flip_summary_bar_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { GNOME_APP_UI_ITEM, + N_("Show S_ummary Bar"), + N_("Show the summary bar on this window"), + gnc_main_window_flip_summary_bar_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL }, GNOMEUIINFO_END @@ -630,6 +932,12 @@ gnc_main_window_create_menus(GNCMDIInfo * maininfo) GNOMEUIINFO_END }; + static GnomeUIInfo gnc_actions_menu_template[] = + { + GNOMEUIINFO_SUBTREE( N_("Scheduled Transactions"), + gnc_sched_xaction_tools_submenu_template ), + GNOMEUIINFO_END + }; static GnomeUIInfo gnc_tools_menu_template[] = { { @@ -642,17 +950,17 @@ gnc_main_window_create_menus(GNCMDIInfo * maininfo) }, { GNOME_APP_UI_ITEM, - N_("Commodity _Editor"), - N_("View and edit the commodities for stocks and mutual funds"), - gnc_main_window_commodities_cb, NULL, NULL, + N_("_Price Editor"), + N_("View and edit the prices for stocks and mutual funds"), + gnc_main_window_prices_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL }, { GNOME_APP_UI_ITEM, - N_("_Price Editor"), - N_("View and edit the prices for stocks and mutual funds"), - gnc_main_window_prices_cb, NULL, NULL, + N_("Commodity _Editor"), + N_("View and edit the commodities for stocks and mutual funds"), + gnc_main_window_commodities_cb, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL }, @@ -671,8 +979,6 @@ gnc_main_window_create_menus(GNCMDIInfo * maininfo) GNOME_APP_PIXMAP_NONE, NULL, 'f', GDK_CONTROL_MASK, NULL }, - GNOMEUIINFO_SUBTREE( N_("Scheduled Transactions"), - gnc_sched_xaction_tools_submenu_template ), GNOMEUIINFO_END }; @@ -708,8 +1014,10 @@ gnc_main_window_create_menus(GNCMDIInfo * maininfo) static GnomeUIInfo gnc_main_menu_template[] = { GNOMEUIINFO_MENU_FILE_TREE(gnc_file_menu_template), + GNOMEUIINFO_MENU_EDIT_TREE(gnc_edit_menu_template), + GNOMEUIINFO_MENU_VIEW_TREE(gnc_view_menu_template), + GNOMEUIINFO_SUBTREE(N_("_Actions"), gnc_actions_menu_template), GNOMEUIINFO_SUBTREE(N_("_Tools"), gnc_tools_menu_template), - GNOMEUIINFO_SUBTREE(N_("_Settings"), gnc_settings_menu_template), GNOMEUIINFO_SUBTREE(N_("_Windows"), gnc_windows_menu_template), GNOMEUIINFO_MENU_HELP_TREE(gnc_help_menu_template), GNOMEUIINFO_END @@ -718,7 +1026,7 @@ gnc_main_window_create_menus(GNCMDIInfo * maininfo) gnome_mdi_set_menubar_template(GNOME_MDI(maininfo->mdi), gnc_main_menu_template); - gnc_file_history_add_after ("New _Account Tree"); + gnc_file_history_add_after ("Open _Recent/"); } static GnomeUIInfo * diff --git a/src/report/report-gnome/report-gnome.scm b/src/report/report-gnome/report-gnome.scm index e3943bd48c..22d112481b 100644 --- a/src/report/report-gnome/report-gnome.scm +++ b/src/report/report-gnome/report-gnome.scm @@ -79,8 +79,8 @@ (define (gnc:report-menu-setup) ;; since this menu gets added to every child window, we say it - ;; comes after the "_File" menu. - (define menu (gnc:make-menu gnc:menuname-reports (list "_File"))) + ;; comes after the "_Actions" menu. + (define menu (gnc:make-menu gnc:menuname-reports (list "_Actions"))) (define menu-namer (gnc:new-menu-namer)) (define tax-menu (gnc:make-menu gnc:menuname-taxes (list gnc:menuname-reports ""))) diff --git a/src/report/report-gnome/window-report.c b/src/report/report-gnome/window-report.c index a624fdce11..04105d6346 100644 --- a/src/report/report-gnome/window-report.c +++ b/src/report/report-gnome/window-report.c @@ -74,6 +74,9 @@ struct gnc_report_window_s }; +static void gnc_report_window_print_cb(GtkWidget * w, gpointer data); +static void gnc_report_window_reload_cb(GtkWidget * w, gpointer data); + /******************************************************************** * REPORT WINDOW FUNCTIONS * creating/managing report-window mdi children @@ -133,13 +136,20 @@ gnc_report_window_view_destroy(GtkObject * obj, gpointer user_data) g_free(mc); } +static void +gnc_report_window_menu_tweaking (GNCMDIChildInfo * mc) +{ + /* Do not i18n these strings!!! */ +} + /******************************************************************** * report_view_new * create a new report view. ********************************************************************/ static GtkWidget * -gnc_report_window_view_new(GnomeMDIChild * child, gpointer user_data) { +gnc_report_window_view_new(GnomeMDIChild * child, gpointer user_data) +{ GNCMDIInfo * maininfo = user_data; GNCMDIChildInfo * mc = g_new0(GNCMDIChildInfo, 1); gnc_report_window * win = gnc_report_window_new(mc); @@ -153,9 +163,14 @@ gnc_report_window_view_new(GnomeMDIChild * child, gpointer user_data) { mc->user_data = win; mc->child = child; mc->title = g_strdup("Report"); - + mc->menu_tweaking = gnc_report_window_menu_tweaking; gnc_mdi_add_child (maininfo, mc); + /* Override a couple of standard buttons. */ + gnc_mdi_set_dispatch_cb(mc, GNC_DISP_PRINT, + gnc_report_window_print_cb, win); + gnc_mdi_set_dispatch_cb(mc, GNC_DISP_REFRESH, + gnc_report_window_reload_cb, win); type = gnc_html_parse_url(gnc_report_window_get_html(win), child->name, &url_location, &url_label); @@ -504,8 +519,8 @@ gnc_report_window_params_cb(GtkWidget * w, gpointer data) return TRUE; } -static int -gnc_report_window_reload_button_cb(GtkWidget * w, gpointer data) { +static void +gnc_report_window_reload_cb(GtkWidget * unused, gpointer data) { gnc_report_window * report = data; SCM dirty_report = gh_eval_str("gnc:report-set-dirty?!"); @@ -513,7 +528,6 @@ gnc_report_window_reload_button_cb(GtkWidget * w, gpointer data) { gh_call2(dirty_report, report->cur_report, SCM_BOOL_T); gnc_html_reload(report->html); } - return TRUE; } static void @@ -795,7 +809,7 @@ gnc_report_window_create_toolbar(gnc_report_window * win, { GNOME_APP_UI_ITEM, N_("Reload"), N_("Reload the current report"), - gnc_report_window_reload_button_cb, win, + gnc_report_window_reload_cb, win, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_REFRESH, diff --git a/src/scm/main.scm b/src/scm/main.scm index 83acd4a3a8..9ded5e2ebd 100644 --- a/src/scm/main.scm +++ b/src/scm/main.scm @@ -433,9 +433,9 @@ string and 'directories' must be a list of strings." ;; add the menu option to edit style sheets (gnc:add-extension (gnc:make-menu-item - (_ "Style Sheets...") + (_ "_Style Sheets...") (_ "Edit report style sheets.") - (list "_Settings" "") + (list "_Edit" "_Preferences...") (lambda () (gnc:style-sheet-dialog-open))))