diff --git a/src/gnome-utils/glade/preferences.glade b/src/gnome-utils/glade/preferences.glade
index beed29e24b..21f8747c94 100644
--- a/src/gnome-utils/glade/preferences.glade
+++ b/src/gnome-utils/glade/preferences.glade
@@ -3457,7 +3457,7 @@
6
True
- 19
+ 20
4
False
0
@@ -3478,7 +3478,7 @@
0
- 1
+ 4
8
9
12
@@ -3503,7 +3503,7 @@
0
- 1
+ 4
7
8
12
@@ -3528,7 +3528,7 @@
0
- 1
+ 4
6
7
12
@@ -3553,7 +3553,7 @@
0
- 1
+ 4
5
6
12
@@ -3578,7 +3578,7 @@
0
- 1
+ 4
4
5
12
@@ -3607,7 +3607,7 @@
0
- 1
+ 4
3
4
fill
@@ -3635,7 +3635,7 @@
0
- 1
+ 4
0
1
fill
@@ -3685,7 +3685,7 @@
0
- 1
+ 4
1
2
12
@@ -3708,7 +3708,7 @@
0
- 1
+ 4
12
13
12
@@ -3738,8 +3738,8 @@
0
1
- 13
- 14
+ 14
+ 15
fill
@@ -3765,9 +3765,9 @@
0
- 1
- 14
- 15
+ 4
+ 15
+ 16
fill
@@ -3788,9 +3788,9 @@
0
- 1
- 15
- 16
+ 4
+ 16
+ 17
12
fill
@@ -3813,9 +3813,9 @@
0
- 1
- 16
- 17
+ 4
+ 17
+ 18
12
fill
@@ -3838,9 +3838,9 @@
0
- 1
- 17
- 18
+ 4
+ 18
+ 19
12
fill
@@ -3863,9 +3863,9 @@
0
- 1
- 18
- 19
+ 4
+ 19
+ 20
12
fill
@@ -3903,7 +3903,7 @@
True
- <b>Close Button</b>
+ <b>Tabs</b>
False
True
GTK_JUSTIFY_LEFT
@@ -3920,7 +3920,7 @@
0
- 1
+ 4
10
11
fill
@@ -3943,7 +3943,7 @@
0
- 1
+ 4
11
12
12
@@ -3951,6 +3951,108 @@
+
+
+
+ True
+ 0.5
+ 0.5
+ 1
+ 1
+ 0
+ 0
+ 12
+ 0
+
+
+
+ True
+ _Width:
+ True
+ False
+ GTK_JUSTIFY_LEFT
+ False
+ False
+ 0.5
+ 0.5
+ 0
+ 0
+ PANGO_ELLIPSIZE_NONE
+ -1
+ False
+ 0
+
+
+
+
+ 0
+ 1
+ 13
+ 14
+ fill
+ fill
+
+
+
+
+
+ True
+ False
+ 0
+
+
+
+ True
+ True
+ 1
+ 0
+ True
+ GTK_UPDATE_ALWAYS
+ False
+ False
+ 30 1 100 1 10 10
+
+
+ 0
+ False
+ True
+
+
+
+
+
+ True
+ characters
+ False
+ False
+ GTK_JUSTIFY_LEFT
+ False
+ False
+ 0.5
+ 0.5
+ 3
+ 0
+ PANGO_ELLIPSIZE_NONE
+ -1
+ False
+ 0
+
+
+ 0
+ False
+ False
+
+
+
+
+ 1
+ 2
+ 13
+ 14
+ fill
+ fill
+
+
False
diff --git a/src/gnome-utils/gnc-main-window.c b/src/gnome-utils/gnc-main-window.c
index c6d45ee99b..77dd085137 100644
--- a/src/gnome-utils/gnc-main-window.c
+++ b/src/gnome-utils/gnc-main-window.c
@@ -79,10 +79,12 @@ enum {
#define PLUGIN_PAGE_LABEL "plugin-page"
#define PLUGIN_PAGE_CLOSE_BUTTON "close-button"
+#define PLUGIN_PAGE_TAB_LABEL "label"
#define KEY_SHOW_CLOSE_BUTTON "tab_close_buttons"
#define KEY_TAB_NEXT_RECENT "tab_next_recent"
#define KEY_TAB_POSITION "tab_position"
+#define KEY_TAB_WIDTH "tab_width"
#define GNC_MAIN_WINDOW_NAME "GncMainWindow"
@@ -392,6 +394,11 @@ static const gchar *multiple_page_actions[] = {
};
+/* This data structure holds the tooltops for all notebook tabs.
+ * Typically these are used to provide the full path of a register
+ * page. */
+static GtkTooltips *tips = NULL;
+
/************************************************************
* *
************************************************************/
@@ -419,6 +426,29 @@ typedef struct {
} GncMainWindowSaveData;
+/* Iterator function to walk all pages in all windows, calling the
+ * specified function for each page. */
+void
+gnc_main_window_foreach_page (GncMainWindowPageFunc fn, gpointer user_data)
+{
+ GncMainWindowPrivate *priv;
+ GncMainWindow *window;
+ GncPluginPage *page;
+ GList *w, *p;
+
+ ENTER(" ");
+ for (w = active_windows; w; w = g_list_next(w)) {
+ window = w->data;
+ priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+ for (p = priv->installed_pages; p; p = g_list_next(p)) {
+ page = p->data;
+ fn(page, user_data);
+ }
+ }
+ LEAVE(" ");
+}
+
+
/** Restore a single page to a window. This function calls a page
* specific function to create the actual page. It then handles all
* the common tasks such as insuring the page is installed into a
@@ -1445,9 +1475,10 @@ gnc_main_window_update_all_menu_items (void)
* or not the close button should be visible.
*/
static void
-gnc_main_window_update_tabs_one_page (GncPluginPage *page,
- gboolean *new_value)
+gnc_main_window_update_tab_close_one_page (GncPluginPage *page,
+ gpointer user_data)
{
+ gboolean *new_value = user_data;
GtkWidget * close_button;
ENTER("page %p, visible %d", page, *new_value);
@@ -1465,35 +1496,9 @@ gnc_main_window_update_tabs_one_page (GncPluginPage *page,
}
-/** Show/hide the close box on all pages in a given window. This
- * function calls the gnc_main_window_update_tabs_one_page() for each
- * page in the window.
- *
- * @internal
- *
- * @param window The GncMainWindow whose notebook tabs should be
- * updated.
- *
- * @param new_value A pointer to the boolean that indicates whether
- * or not the close button should be visible.
- */
-static void
-gnc_main_window_update_tabs_one_window (GncMainWindow *window, gboolean *new_value)
-{
- GncMainWindowPrivate *priv;
-
- ENTER("window %p, visible %d", window, *new_value);
- priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
- g_list_foreach(priv->installed_pages,
- (GFunc)gnc_main_window_update_tabs_one_page,
- new_value);
- LEAVE(" ");
-}
-
-
-/** Show/hide the close box on all pages in all windows. This
- * function calls the gnc_main_window_update_tabs_one_window() for
- * each open window in the application.
+/** Show/hide the close box on all pages in all windows. This function
+ * calls gnc_main_window_update_tab_close() for each plugin page in the
+ * application.
*
* @internal
*
@@ -1503,14 +1508,76 @@ gnc_main_window_update_tabs_one_window (GncMainWindow *window, gboolean *new_val
* @param user_data Unused.
*/
static void
-gnc_main_window_update_tabs (GConfEntry *entry, gpointer user_data)
+gnc_main_window_update_tab_close (GConfEntry *entry, gpointer user_data)
{
gboolean new_value;
ENTER(" ");
new_value = gconf_value_get_bool(entry->value);
- g_list_foreach(active_windows,
- (GFunc)gnc_main_window_update_tabs_one_window,
+ gnc_main_window_foreach_page(
+ gnc_main_window_update_tab_close_one_page,
+ &new_value);
+ LEAVE(" ");
+}
+
+
+/** Update the width of the label in the tab of a notebook page. This
+ * function adjusts both the width and the ellipsize mode so that the tab
+ * label looks correct. The special check for a zero value handles the
+ * case where a user hasn't set a tab width and the gconf default isn't
+ * detected.
+ *
+ * @internal
+ *
+ * @param page The GncPluginPage whose notebook tab should be updated.
+ *
+ * @param new_value The new width of the label in the tab.
+ */
+static void
+gnc_main_window_update_tab_width_one_page (GncPluginPage *page,
+ gpointer user_data)
+{
+ gint *new_value = user_data;
+ GtkWidget *label;
+
+ ENTER("page %p, visible %d", page, *new_value);
+ label = g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL);
+ if (!label) {
+ LEAVE("no label");
+ return;
+ }
+
+ if (*new_value != 0) {
+ gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_MIDDLE);
+ gtk_label_set_max_width_chars(GTK_LABEL(label), *new_value);
+ } else {
+ gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_NONE);
+ gtk_label_set_max_width_chars(GTK_LABEL(label), 100);
+ }
+ LEAVE(" ");
+}
+
+
+/** Update the tab label width in all pages in all windows. This function
+ * calls gnc_main_window_update_tab_width() for each plugin page in the
+ * application.
+ *
+ * @internal
+ *
+ * @param entry A pointer to the GConfEntry which describes the new
+ * size of the tab label width.
+ *
+ * @param user_data Unused.
+ */
+static void
+gnc_main_window_update_tab_width (GConfEntry *entry, gpointer user_data)
+{
+ gint new_value;
+
+ ENTER(" ");
+ new_value = gconf_value_get_float(entry->value);
+ gnc_main_window_foreach_page(
+ gnc_main_window_update_tab_width_one_page,
&new_value);
LEAVE(" ");
}
@@ -1538,8 +1605,8 @@ main_window_find_tab_items (GncMainWindow *window,
children = gtk_container_get_children(GTK_CONTAINER(tab_hbox));
for (tmp = children; tmp; tmp = g_list_next(tmp)) {
widget = tmp->data;
- if (GTK_IS_LABEL(widget)) {
- *label_p = widget;
+ if (GTK_IS_EVENT_BOX(widget)) {
+ *label_p = gtk_bin_get_child(GTK_BIN(widget));
} else if (GTK_IS_ENTRY(widget)) {
*entry_p = widget;
}
@@ -1771,12 +1838,17 @@ gnc_main_window_class_init (GncMainWindowClass *klass)
G_TYPE_OBJECT);
gnc_gconf_general_register_cb (KEY_SHOW_CLOSE_BUTTON,
- gnc_main_window_update_tabs,
+ gnc_main_window_update_tab_close,
+ NULL);
+ gnc_gconf_general_register_cb (KEY_TAB_WIDTH,
+ gnc_main_window_update_tab_width,
NULL);
gnc_hook_add_dangler(HOOK_BOOK_SAVED,
(GFunc)gnc_main_window_update_all_titles, NULL);
gnc_hook_add_dangler(HOOK_BOOK_OPENED,
(GFunc)gnc_main_window_attach_to_book, NULL);
+
+ tips = gtk_tooltips_new();
}
@@ -2070,10 +2142,11 @@ gnc_main_window_open_page (GncMainWindow *window,
{
GncMainWindowPrivate *priv;
GtkWidget *tab_hbox;
- GtkWidget *label, *entry;
- const gchar *icon;
+ GtkWidget *label, *entry, *event_box;
+ const gchar *icon, *text;
GtkWidget *image;
GList *tmp;
+ gint width;
ENTER("window %p, page %p", window, page);
@@ -2112,9 +2185,15 @@ gnc_main_window_open_page (GncMainWindow *window,
/*
* The page tab.
*/
+ width = gnc_gconf_get_float(GCONF_GENERAL, KEY_TAB_WIDTH, NULL);
icon = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
label = gtk_label_new (gnc_plugin_page_get_page_name(page));
+ if (width != 0) {
+ gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_MIDDLE);
+ gtk_label_set_max_width_chars(GTK_LABEL(label), width);
+ }
gtk_widget_show (label);
+ g_object_set_data(G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL, label);
tab_hbox = gtk_hbox_new (FALSE, 6);
gtk_widget_show (tab_hbox);
@@ -2125,8 +2204,17 @@ gnc_main_window_open_page (GncMainWindow *window,
gtk_box_pack_start (GTK_BOX (tab_hbox), image, FALSE, FALSE, 0);
}
- gtk_box_pack_start (GTK_BOX (tab_hbox), label, TRUE, TRUE, 0);
-
+ event_box = gtk_event_box_new();
+ gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box), FALSE);
+ gtk_widget_show(event_box);
+ gtk_container_add(GTK_CONTAINER(event_box), label);
+ gtk_box_pack_start (GTK_BOX (tab_hbox), event_box, TRUE, TRUE, 0);
+
+ text = gnc_plugin_page_get_page_long_name(page);
+ if (text) {
+ gtk_tooltips_set_tip(tips, event_box, text, NULL);
+ }
+
entry = gtk_entry_new();
gtk_widget_hide (entry);
gtk_box_pack_start (GTK_BOX (tab_hbox), entry, TRUE, TRUE, 0);
diff --git a/src/gnome-utils/gnc-main-window.h b/src/gnome-utils/gnc-main-window.h
index cfd2486669..44789cd7a3 100644
--- a/src/gnome-utils/gnc-main-window.h
+++ b/src/gnome-utils/gnc-main-window.h
@@ -76,6 +76,7 @@ typedef struct {
} GncMainWindowActionData;
typedef void (*GncMainWindowFunc) (GncMainWindow *window, GncPluginPage *page);
+typedef void (*GncMainWindowPageFunc) (GncPluginPage *page, gpointer user_data);
/* function prototypes */
@@ -127,6 +128,17 @@ void gnc_main_window_open_page (GncMainWindow *window,
void gnc_main_window_close_page (GncPluginPage *page);
+/* Iterator function to walk all pages in all windows, calling the
+ * specified function for each page.
+ *
+ * @param entry A pointer to the function to be called.
+ *
+ * @param user_data A data pointer passed to each call of the function.
+ */
+void gnc_main_window_foreach_page (GncMainWindowPageFunc fn,
+ gpointer user_data);
+
+
/** Retrieve a pointer to the page that is currently at the front of
* the specified window. Any plugin that needs to manipulate its
* menus based upon the currently selected menu page should connect
diff --git a/src/gnome-utils/gnc-plugin-page.c b/src/gnome-utils/gnc-plugin-page.c
index f57a2c0b1a..7789135e91 100644
--- a/src/gnome-utils/gnc-plugin-page.c
+++ b/src/gnome-utils/gnc-plugin-page.c
@@ -95,6 +95,7 @@ typedef struct _GncPluginPagePrivate
gboolean use_new_window;
gchar *page_name;
+ gchar *page_long_name;
gchar *uri;
gchar *statusbar_text;
} GncPluginPagePrivate;
@@ -769,6 +770,38 @@ gnc_plugin_page_set_page_name (GncPluginPage *page, const gchar *name)
}
+/* Retrieve the long name of this page. This is the string used in
+ * the tooltip that is attached to the pate name in the notebook
+ * tab. */
+const gchar *
+gnc_plugin_page_get_page_long_name (GncPluginPage *page)
+{
+ GncPluginPagePrivate *priv;
+
+ g_return_val_if_fail (GNC_IS_PLUGIN_PAGE (page), NULL);
+
+ priv = GNC_PLUGIN_PAGE_GET_PRIVATE(page);
+ return priv->page_long_name;
+}
+
+
+/* Set the long name of this page. This is the string used in the
+ * tooltip that is attached to the pate name in the notebook tab. */
+void
+gnc_plugin_page_set_page_long_name (GncPluginPage *page, const gchar *name)
+{
+ GncPluginPagePrivate *priv;
+ GncPluginPageClass *klass;
+
+ g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
+
+ priv = GNC_PLUGIN_PAGE_GET_PRIVATE(page);
+ if (priv->page_long_name)
+ g_free(priv->page_long_name);
+ priv->page_long_name = g_strdup(name);
+}
+
+
/* Retrieve the Uniform Resource Identifier for this page. */
const gchar *
gnc_plugin_page_get_uri (GncPluginPage *page)
diff --git a/src/gnome-utils/gnc-plugin-page.h b/src/gnome-utils/gnc-plugin-page.h
index c5eda12427..8f0ac9536c 100644
--- a/src/gnome-utils/gnc-plugin-page.h
+++ b/src/gnome-utils/gnc-plugin-page.h
@@ -350,6 +350,28 @@ const gchar *gnc_plugin_page_get_page_name (GncPluginPage *page);
void gnc_plugin_page_set_page_name (GncPluginPage *page, const char *name);
+/** Retrieve the long name of this page. This is the string used in
+ * the tooltip that is attached to the pate name in the notebook
+ * tab.
+ *
+ * @param page The page whose name should be retrieved.
+ *
+ * @return The page's name. This string is owned by the page and
+ * should not be freed by the caller.
+ */
+const gchar *gnc_plugin_page_get_page_long_name (GncPluginPage *page);
+
+
+/** Set the long name of this page. This is the string used in the
+ * tooltip that is attached to the pate name in the notebook tab.
+ *
+ * @param page The page whose name should be set.
+ *
+ * @param name The new string for the name.
+ */
+void gnc_plugin_page_set_page_long_name (GncPluginPage *page, const char *name);
+
+
/** Retrieve the Uniform Resource Identifier for this page.
*
* @param page The page whose URI should be retrieved.
diff --git a/src/gnome/gnc-plugin-page-register.c b/src/gnome/gnc-plugin-page-register.c
index b80180c76c..4802e9e6de 100644
--- a/src/gnome/gnc-plugin-page-register.c
+++ b/src/gnome/gnc-plugin-page-register.c
@@ -95,6 +95,7 @@ static void gnc_plugin_page_register_update_edit_menu (GncPluginPage *page, gboo
static gboolean gnc_plugin_page_register_finish_pending (GncPluginPage *page);
static gchar *gnc_plugin_page_register_get_tab_name (GncPluginPage *plugin_page);
+static gchar *gnc_plugin_page_register_get_long_name (GncPluginPage *plugin_page);
/* Callbacks for the "Sort By" dialog */
void gnc_plugin_page_register_sort_button_cb(GtkToggleButton *button, GncPluginPageRegister *page);
@@ -454,6 +455,10 @@ gnc_plugin_page_register_new_common (GNCLedgerDisplay *ledger)
gnc_plugin_page_set_page_name(plugin_page, label);
g_free(label);
+ label = gnc_plugin_page_register_get_long_name(plugin_page);
+ gnc_plugin_page_set_page_long_name(plugin_page, label);
+ g_free(label);
+
q = gnc_ledger_display_get_query (ledger);
book_list = qof_query_get_books (q);
for (item = book_list; item; item = g_list_next(item))
@@ -1154,6 +1159,37 @@ gnc_plugin_page_register_get_tab_name (GncPluginPage *plugin_page)
return g_strdup(_("unknown"));
}
+static gchar *
+gnc_plugin_page_register_get_long_name (GncPluginPage *plugin_page)
+{
+ GncPluginPageRegisterPrivate *priv;
+ GNCLedgerDisplayType ledger_type;
+ GNCLedgerDisplay *ld;
+ SplitRegister *reg;
+ Account *leader;
+
+ g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER (plugin_page), _("unknown"));
+
+ priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
+ ld = priv->ledger;
+ reg = gnc_ledger_display_get_split_register (ld);
+ ledger_type = gnc_ledger_display_type (ld);
+ leader = gnc_ledger_display_leader (ld);
+
+ switch (ledger_type) {
+ case LD_SINGLE:
+ return g_strdup(xaccAccountGetFullName (leader));
+
+ case LD_SUBACCOUNT:
+ return g_strdup_printf("%s+", xaccAccountGetFullName (leader));
+
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
/************************************************************/
/* "Sort By" Dialog */
/************************************************************/
diff --git a/src/gnome/schemas/apps_gnucash_general.schemas.in b/src/gnome/schemas/apps_gnucash_general.schemas.in
index 5e3d6d219c..3a120eb59b 100644
--- a/src/gnome/schemas/apps_gnucash_general.schemas.in
+++ b/src/gnome/schemas/apps_gnucash_general.schemas.in
@@ -184,6 +184,23 @@
+
+ /schemas/apps/gnucash/general/tab_width
+ /apps/gnucash/general/tab_width
+ gnucash
+ float
+ 30.0
+
+ Width of notebook tabs
+
+ This key specifies the maximum width of notebook tabs.
+ If the text in the tab is longer than this value (the test
+ is approximate) then the tab label will have the middle cut
+ and replaced with an ellipsis.
+
+
+
+
/schemas/apps/gnucash/general/currency_choice
/apps/gnucash/general/currency_choice