Addl fix #444: User-definable toolbar
authorColin Clark <colin.clark@cclark.uk>
Wed, 31 Jul 2019 15:59:11 +0000 (16:59 +0100)
committerColin Clark <colin.clark@cclark.uk>
Wed, 31 Jul 2019 15:59:11 +0000 (16:59 +0100)
https://github.com/BestImageViewer/geeqie/issues/444

The status bar toolbar is now user-definable.

doc/docbook/GuideMainWindowStatusBar.xml
doc/docbook/GuideOptionsToolbar.xml
src/layout.c
src/layout_util.c
src/preferences.c
src/rcfile.c
src/toolbar.c
src/toolbar.h

index 76a5146..d72f8f7 100644 (file)
     <para>This section displays the dimensions (width x height) and file byte size of the image that is active in the image pane. When the format of the file in the image pane can not be determined the dimensions will show as “(0 x 0)”, in addition “(no read permision)” may appear if the file permissions do not allow reading the contents of the file.</para>\r
     <para />\r
   </section>\r
+  <section id="ZoomAndScroll">\r
+    <title>Zoom and Scroll</title>\r
+    <para>The button label displays the current zoom ratio. A ratio of 1:1 is the image's original size. When the left number is larger the image is displayed larger than original size, when the right number is larger the image is displayed smaller.</para>\r
+    <para>A tilde (~) appears within the ratio display when the zoom is set to fit the image within the display area. In this zoom mode the ratio is automatically adjusted, and the displayed ratio may not be the actual ratio because the status bar display rounds the actual value to the nearest tenth (0.1).</para>\r
+    <para />\r
+    <para>Clicking this button permits control of the behavior of the zoom and scroll settings used when changing the displayed image.</para>\r
+    <variablelist>\r
+      <varlistentry>\r
+        <term>\r
+          <guilabel>Zoom to original size</guilabel>\r
+        </term>\r
+        <listitem>\r
+          <para>The new image is set to its original size.</para>\r
+        </listitem>\r
+      </varlistentry>\r
+      <varlistentry>\r
+        <term>\r
+          <guilabel>Fit image to window</guilabel>\r
+        </term>\r
+        <listitem>\r
+          <para>The new image's zoom is changed so that the image will fit within the current view area.</para>\r
+        </listitem>\r
+      </varlistentry>\r
+      <varlistentry>\r
+        <term>\r
+          <guilabel>Leave zoom at previous setting</guilabel>\r
+        </term>\r
+        <listitem>\r
+          <para>The zoom setting is unchanged, the new image will be scaled the same as the previous image.</para>\r
+        </listitem>\r
+      </varlistentry>\r
+    </variablelist>\r
+    <variablelist>\r
+      <varlistentry>\r
+        <term>\r
+          <guilabel>Scroll to top left corner</guilabel>\r
+        </term>\r
+        <listitem>\r
+          <para>The new image is displayed from top left corner.</para>\r
+        </listitem>\r
+      </varlistentry>\r
+      <varlistentry>\r
+        <term>\r
+          <guilabel>Scroll to image center</guilabel>\r
+        </term>\r
+        <listitem>\r
+          <para>The new image is centered</para>\r
+        </listitem>\r
+      </varlistentry>\r
+      <varlistentry>\r
+        <term>\r
+          <guilabel>Keep the region from previous iamge</guilabel>\r
+        </term>\r
+        <listitem>\r
+          <para>The new image is positioned as the previous one, whenever possible.</para>\r
+        </listitem>\r
+      </varlistentry>\r
+    </variablelist>\r
+  </section>\r
   <section id="Buttons">\r
     <title>Buttons</title>\r
-    <para>Statusbar buttons corresponds to selected menu action.</para>\r
+    <para>\r
+      The Status bar toolbar buttons, the defaults are shown below, correspond to selected menu action. The buttons displayed may be changed in the\r
+      <link linkend="GuideOptionsToolbar">Toolbar tab of Preferences.</link>\r
+    </para>\r
     <para />\r
-    <section id="ZoomAndScroll">\r
-      <title>Zoom and Scroll</title>\r
-      <para>The button label displays the current zoom ratio. A ratio of 1:1 is the image's original size. When the left number is larger the image is displayed larger than original size, when the right number is larger the image is displayed smaller.</para>\r
-      <para>A tilde (~) appears within the ratio display when the zoom is set to fit the image within the display area. In this zoom mode the ratio is automatically adjusted, and the displayed ratio may not be the actual ratio because the status bar display rounds the actual value to the nearest tenth (0.1).</para>\r
-      <para />\r
-      <para>Clicking this button permits control of the behavior of the zoom and scroll settings used when changing the displayed image.</para>\r
-      <variablelist>\r
-        <varlistentry>\r
-          <term>\r
-            <guilabel>Zoom to original size</guilabel>\r
-          </term>\r
-          <listitem>\r
-            <para>The new image is set to its original size.</para>\r
-          </listitem>\r
-        </varlistentry>\r
-        <varlistentry>\r
-          <term>\r
-            <guilabel>Fit image to window</guilabel>\r
-          </term>\r
-          <listitem>\r
-            <para>The new image's zoom is changed so that the image will fit within the current view area.</para>\r
-          </listitem>\r
-        </varlistentry>\r
-        <varlistentry>\r
-          <term>\r
-            <guilabel>Leave zoom at previous setting</guilabel>\r
-          </term>\r
-          <listitem>\r
-            <para>The zoom setting is unchanged, the new image will be scaled the same as the previous image.</para>\r
-          </listitem>\r
-        </varlistentry>\r
-      </variablelist>\r
-      <variablelist>\r
-        <varlistentry>\r
-          <term>\r
-            <guilabel>Scroll to top left corner</guilabel>\r
-          </term>\r
-          <listitem>\r
-            <para>The new image is displayed from top left corner.</para>\r
-          </listitem>\r
-        </varlistentry>\r
-        <varlistentry>\r
-          <term>\r
-            <guilabel>Scroll to image center</guilabel>\r
-          </term>\r
-          <listitem>\r
-            <para>The new image is centered</para>\r
-          </listitem>\r
-        </varlistentry>\r
-        <varlistentry>\r
-          <term>\r
-            <guilabel>Keep the region from previous iamge</guilabel>\r
-          </term>\r
-          <listitem>\r
-            <para>The new image is positioned as the previous one, whenever possible.</para>\r
-          </listitem>\r
-        </varlistentry>\r
-      </variablelist>\r
-    </section>\r
     <section id="ExifRotate">\r
       <title>Exif rotate</title>\r
       <para>\r
index 95fe2cc..6f9ac54 100644 (file)
@@ -2,7 +2,7 @@
 <section id="GuideOptionsToolbar">\r
   <title>Toolbar</title>\r
   <para>\r
-    This dialogue enables you to change the items displayed on the Toolbar.\r
+    This dialogue enables you to change the items displayed on either the Main Toolbar or the Status Toolbar.\r
     <para />\r
     The initial display shows the current setup. You may re-order these items by right-clicking on any item.\r
     <para />\r
index 2508496..d06ad32 100644 (file)
@@ -2641,6 +2641,7 @@ void layout_write_config(LayoutWindow *lw, GString *outstr, gint indent)
 
        WRITE_SEPARATOR();
        layout_toolbar_write_config(lw, TOOLBAR_MAIN, outstr, indent + 1);
+       layout_toolbar_write_config(lw, TOOLBAR_STATUS, outstr, indent + 1);
 
        WRITE_NL(); WRITE_STRING("</layout>");
 }
index 5c3aa73..a74ca0e 100644 (file)
@@ -2344,10 +2344,6 @@ static const gchar *menu_ui_description =
 "  <toolbar name='ToolBar'>"
 "  </toolbar>"
 "  <toolbar name='StatusBar'>"
-"    <toolitem action='ExifRotate'/>"
-"    <toolitem action='ShowInfoPixel'/>"
-"    <toolitem action='UseColorProfiles'/>"
-"    <toolitem action='SaveMetadata'/>"
 "  </toolbar>"
 "<accelerator action='PrevImageAlt1'/>"
 "<accelerator action='PrevImageAlt2'/>"
@@ -2628,6 +2624,7 @@ static void layout_actions_setup_editors(LayoutWindow *lw)
 void layout_actions_setup(LayoutWindow *lw)
 {
        GError *error;
+       gint i;
 
        DEBUG_1("%s layout_actions_setup: start", get_exec_time());
        if (lw->ui_manager) return;
@@ -2675,8 +2672,12 @@ void layout_actions_setup(LayoutWindow *lw)
                exit(EXIT_FAILURE);
                }
 
-       layout_toolbar_clear(lw, TOOLBAR_MAIN);
-       layout_toolbar_add_default(lw, TOOLBAR_MAIN);
+       DEBUG_1("%s layout_actions_setup: add toolbar", get_exec_time());
+       for (i = 0; i < TOOLBAR_COUNT; i++)
+               {
+               layout_toolbar_clear(lw, i);
+               layout_toolbar_add_default(lw, i);
+               }
 
        DEBUG_1("%s layout_actions_setup: marks", get_exec_time());
        layout_actions_setup_marks(lw);
@@ -2849,6 +2850,9 @@ void layout_toolbar_add(LayoutWindow *lw, ToolbarType type, const gchar *action)
                case TOOLBAR_MAIN:
                        path = "/ToolBar";
                        break;
+               case TOOLBAR_STATUS:
+                       path = "/StatusBar";
+                       break;
                default:
                        break;
                }
@@ -2933,6 +2937,36 @@ void layout_toolbar_add_default(LayoutWindow *lw, ToolbarType type)
                                layout_toolbar_add(lw, type, "FloatTools");
                                }
                        break;
+               case TOOLBAR_STATUS:
+                       if (layout_window_list)
+                               {
+                               lw_first = layout_window_list->data;
+                               if (lw_first->toolbar_actions[TOOLBAR_MAIN])
+                                       {
+                                       work_action = lw_first->toolbar_actions[type];
+                                       while (work_action)
+                                               {
+                                               gchar *action = work_action->data;
+                                               work_action = work_action->next;
+                                               layout_toolbar_add(lw, type, action);
+                                               }
+                                       }
+                               else
+                                       {
+                                       layout_toolbar_add(lw, type, "ExifRotate");
+                                       layout_toolbar_add(lw, type, "ShowInfoPixel");
+                                       layout_toolbar_add(lw, type, "UseColorProfiles");
+                                       layout_toolbar_add(lw, type, "SaveMetadata");
+                                       }
+                               }
+                       else
+                               {
+                               layout_toolbar_add(lw, type, "ExifRotate");
+                               layout_toolbar_add(lw, type, "ShowInfoPixel");
+                               layout_toolbar_add(lw, type, "UseColorProfiles");
+                               layout_toolbar_add(lw, type, "SaveMetadata");
+                               }
+                       break;
                default:
                        break;
                }
@@ -2950,6 +2984,9 @@ void layout_toolbar_write_config(LayoutWindow *lw, ToolbarType type, GString *ou
                case TOOLBAR_MAIN:
                        name = "toolbar";
                        break;
+               case TOOLBAR_STATUS:
+                       name = "statusbar";
+                       break;
                default:
                        break;
                }
index c3e9329..70a612d 100644 (file)
@@ -465,7 +465,8 @@ static void config_window_apply(void)
 
        if (accel_store) gtk_tree_model_foreach(GTK_TREE_MODEL(accel_store), accel_apply_cb, NULL);
 
-       toolbar_apply();
+       toolbar_apply(TOOLBAR_MAIN);
+       toolbar_apply(TOOLBAR_STATUS);
 }
 
 /*
@@ -3429,8 +3430,8 @@ static void config_tab_accelerators(GtkWidget *notebook)
        gtk_widget_show(button);
 }
 
-/* toolbar tab */
-static void config_tab_toolbar(GtkWidget *notebook)
+/* toolbar main tab */
+static void config_tab_toolbar_main(GtkWidget *notebook)
 {
        GtkWidget *vbox;
        GtkWidget *toolbardata;
@@ -3438,9 +3439,25 @@ static void config_tab_toolbar(GtkWidget *notebook)
 
        lw = layout_window_list->data;
 
-       vbox = scrolled_notebook_page(notebook, _("Toolbar"));
+       vbox = scrolled_notebook_page(notebook, _("Toolbar Main"));
 
-       toolbardata = toolbar_select_new(lw);
+       toolbardata = toolbar_select_new(lw, TOOLBAR_MAIN);
+       gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
+       gtk_widget_show(vbox);
+}
+
+/* toolbar status tab */
+static void config_tab_toolbar_status(GtkWidget *notebook)
+{
+       GtkWidget *vbox;
+       GtkWidget *toolbardata;
+       LayoutWindow *lw;
+
+       lw = layout_window_list->data;
+
+       vbox = scrolled_notebook_page(notebook, _("Toolbar Status"));
+
+       toolbardata = toolbar_select_new(lw, TOOLBAR_STATUS);
        gtk_box_pack_start(GTK_BOX(vbox), toolbardata, TRUE, TRUE, 0);
        gtk_widget_show(vbox);
 }
@@ -3562,7 +3579,8 @@ static void config_window_create(void)
        config_tab_color(notebook);
        config_tab_stereo(notebook);
        config_tab_behavior(notebook);
-       config_tab_toolbar(notebook);
+       config_tab_toolbar_main(notebook);
+       config_tab_toolbar_status(notebook);
 
        hbox = gtk_hbutton_box_new();
        gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
index 9e1119f..9484132 100644 (file)
@@ -1306,6 +1306,27 @@ static void options_parse_toolbar(GQParserData *parser_data, GMarkupParseContext
                options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
                }
 }
+
+static void options_parse_statusbar(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
+{
+       LayoutWindow *lw = data;
+       if (g_ascii_strcasecmp(element_name, "toolitem") == 0)
+               {
+               layout_toolbar_add_from_config(lw, TOOLBAR_STATUS, attribute_names, attribute_values);
+               options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+               }
+       else if (g_ascii_strcasecmp(element_name, "clear") == 0)
+               {
+               layout_toolbar_clear(lw, TOOLBAR_STATUS);
+               options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+               }
+       else
+               {
+               log_printf("unexpected in <statusbar>: <%s>\n", element_name);
+               options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+               }
+}
+
 static void options_parse_dialogs(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
 {
        if (g_ascii_strcasecmp(element_name, "window") == 0)
@@ -1348,7 +1369,7 @@ static void options_parse_layout(GQParserData *parser_data, GMarkupParseContext
                }
        else if (g_ascii_strcasecmp(element_name, "statusbar") == 0)
                {
-               options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+               options_parse_func_push(parser_data, options_parse_statusbar, NULL, lw);
                }
        else if (g_ascii_strcasecmp(element_name, "dialogs") == 0)
                {
index 71ac3e2..f4bc115 100644 (file)
@@ -55,7 +55,7 @@ struct _ToolbarButtonData
        gchar *stock_id;
 };
 
-static         ToolbarData *toolbarlist;
+static ToolbarData *toolbarlist[2];
 
 typedef struct _UseableToolbarItems UseableToolbarItems;
 struct _UseableToolbarItems
@@ -123,6 +123,10 @@ static const UseableToolbarItems useable_toolbar_items[] = {
        {"ConnectZoomIn",       N_("Connected Zoom in"), GTK_STOCK_ZOOM_IN},
        {"Grayscale",   N_("Grayscale"), PIXBUF_INLINE_ICON_GRAYSCALE},
        {"OverUnderExposed",    N_("Over Under Exposed"), PIXBUF_INLINE_ICON_EXPOSURE},
+       {"ShowInfoPixel",       N_("Pixel Info"),       GTK_STOCK_COLOR_PICKER},
+       {"ExifRotate",  N_("_Exif rotate"),     GTK_STOCK_ORIENTATION_PORTRAIT},
+       {"UseColorProfiles",    N_("Use color profiles"),       GTK_STOCK_SELECT_COLOR},
+       {"SaveMetadata",        N_("Save metadata"),    GTK_STOCK_SAVE},
        {"HideTools",   N_("Hide file list"), PIXBUF_INLINE_ICON_HIDETOOLS},
        {"SlideShowPause",      N_("Pause slideshow"), GTK_STOCK_MEDIA_PAUSE},
        {"SlideShowFaster",     N_("Slideshow Faster"), GTK_STOCK_FILE},
@@ -424,9 +428,10 @@ static gboolean toolbar_menu_add_cb(GtkWidget *widget, gpointer data)
 
 /**
  * @brief For each layoutwindow, clear toolbar and reload with current selection
+ * @param bar Main or Status toolbar
  * 
  */
-void toolbar_apply()
+void toolbar_apply(ToolbarType bar)
 {
        LayoutWindow *lw;
        GList *work_windows;
@@ -437,16 +442,16 @@ void toolbar_apply()
                {
                lw = work_windows->data;
 
-               layout_toolbar_clear(lw, TOOLBAR_MAIN);
+               layout_toolbar_clear(lw, bar);
 
-               work_toolbar = gtk_container_get_children(GTK_CONTAINER(toolbarlist->vbox));
+               work_toolbar = gtk_container_get_children(GTK_CONTAINER(toolbarlist[bar]->vbox));
                while (work_toolbar)
                        {
                        GtkButton *button = work_toolbar->data;
                        ToolbarButtonData *tbbd;
 
                        tbbd = g_object_get_data(G_OBJECT(button),"toolbarbuttondata");
-                       layout_toolbar_add(lw, TOOLBAR_MAIN, tbbd->name);
+                       layout_toolbar_add(lw, bar, tbbd->name);
 
                        work_toolbar = work_toolbar->next;
                        }
@@ -461,13 +466,14 @@ void toolbar_apply()
  * @brief Load the current toolbar items into the vbox
  * @param lw 
  * @param box The vbox displayed in the preferences Toolbar tab
+ * @param bar Main or Status toolbar
  * 
  * Get the current contents of the toolbar, both menu items
  * and desktop items, and load them into the vbox
  */
-static void toolbarlist_populate(LayoutWindow *lw, GtkBox *box)
+static void toolbarlist_populate(LayoutWindow *lw, GtkBox *box, ToolbarType bar)
 {
-       GList *work = g_list_first(lw->toolbar_actions[TOOLBAR_MAIN]);
+       GList *work = g_list_first(lw->toolbar_actions[bar]);
 
        while (work)
                {
@@ -488,7 +494,7 @@ static void toolbarlist_populate(LayoutWindow *lw, GtkBox *box)
                }
 }
 
-GtkWidget *toolbar_select_new(LayoutWindow *lw)
+GtkWidget *toolbar_select_new(LayoutWindow *lw, ToolbarType bar)
 {
        GtkWidget *scrolled;
        GtkWidget *tbar;
@@ -496,40 +502,40 @@ GtkWidget *toolbar_select_new(LayoutWindow *lw)
 
        if (!lw) return NULL;
 
-       if (!toolbarlist)
+       if (!toolbarlist[bar])
                {
-               toolbarlist = g_new0(ToolbarData, 1);
+               toolbarlist[bar] = g_new0(ToolbarData, 1);
                }
-       toolbarlist->lw = lw;
+       toolbarlist[bar]->lw = lw;
 
-       toolbarlist->widget = gtk_vbox_new(FALSE, PREF_PAD_GAP);
-       gtk_widget_show(toolbarlist->widget);
+       toolbarlist[bar]->widget = gtk_vbox_new(FALSE, PREF_PAD_GAP);
+       gtk_widget_show(toolbarlist[bar]->widget);
 
        scrolled = gtk_scrolled_window_new(NULL, NULL);
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
                                                        GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_NONE);
-       gtk_box_pack_start(GTK_BOX(toolbarlist->widget), scrolled, TRUE, TRUE, 0);
+       gtk_box_pack_start(GTK_BOX(toolbarlist[bar]->widget), scrolled, TRUE, TRUE, 0);
        gtk_widget_show(scrolled);
 
-       toolbarlist->vbox = gtk_vbox_new(FALSE, 0);
-       gtk_widget_show(toolbarlist->vbox);
-       gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), toolbarlist->vbox);
+       toolbarlist[bar]->vbox = gtk_vbox_new(FALSE, 0);
+       gtk_widget_show(toolbarlist[bar]->vbox);
+       gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), toolbarlist[bar]->vbox);
        gtk_viewport_set_shadow_type(GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN(scrolled))),
                                                                                                                                GTK_SHADOW_NONE);
 
        add_box = gtk_vbox_new(FALSE, 0);
        gtk_widget_show(add_box);
-       gtk_box_pack_end(GTK_BOX(toolbarlist->widget), add_box, FALSE, FALSE, 0);
+       gtk_box_pack_end(GTK_BOX(toolbarlist[bar]->widget), add_box, FALSE, FALSE, 0);
        tbar = pref_toolbar_new(add_box, GTK_TOOLBAR_ICONS);
-       toolbarlist->add_button = pref_toolbar_button(tbar, GTK_STOCK_ADD, "NULL", FALSE,
+       toolbarlist[bar]->add_button = pref_toolbar_button(tbar, GTK_STOCK_ADD, "NULL", FALSE,
                                                                                        _("Add Toolbar Item"),
-                                                                                       G_CALLBACK(toolbar_menu_add_cb), toolbarlist);
-       gtk_widget_show(toolbarlist->add_button);
+                                                                                       G_CALLBACK(toolbar_menu_add_cb), toolbarlist[bar]);
+       gtk_widget_show(toolbarlist[bar]->add_button);
 
-       toolbarlist_populate(lw,GTK_BOX(toolbarlist->vbox));
+       toolbarlist_populate(lw,GTK_BOX(toolbarlist[bar]->vbox), bar);
 
-       return toolbarlist->widget;
+       return toolbarlist[bar]->widget;
 }
 
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
index a86099e..703d847 100644 (file)
@@ -22,8 +22,8 @@
 #ifndef TOOLBAR_H
 #define TOOLBAR_H
 
-GtkWidget *toolbar_select_new(LayoutWindow *lw);
-void toolbar_apply();
+GtkWidget *toolbar_select_new(LayoutWindow *lw, ToolbarType bar);
+void toolbar_apply(ToolbarType bar);
 #endif
 
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */