[gthumb] added the list tools to the header bar



commit cdaabea3f55c90fa3fa979bdc88afc9a28a2036f
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Mon Oct 21 19:00:53 2013 +0200

    added the list tools to the header bar

 Makefile.am                                        |    3 +-
 .../actions/view-zoom-fit-width-symbolic.svg       |   15 ++-
 extension-resources.mk                             |    7 +
 extensions/bookmarks/Makefile.am                   |   15 +--
 .../bookmarks/{gresource.xml => resources.xml}     |    0
 extensions/image_rotation/actions.c                |   56 +++++----
 extensions/image_rotation/actions.h                |   12 +-
 extensions/image_rotation/callbacks.c              |  117 +++++---------------
 extensions/list_tools/Makefile.am                  |   10 ++-
 extensions/list_tools/actions.c                    |   51 ++++++++
 extensions/list_tools/actions.h                    |    6 +
 extensions/list_tools/callbacks.c                  |  120 ++++++++++++++-----
 extensions/list_tools/data/ui/Makefile.am          |    8 +-
 extensions/list_tools/data/ui/tools-menu.ui        |   18 +++
 extensions/list_tools/dlg-personalize-scripts.c    |    2 +-
 extensions/list_tools/gth-script-editor-dialog.c   |    2 +-
 extensions/list_tools/gth-script.c                 |    2 +-
 extensions/list_tools/list-tools.h                 |   29 +++++
 extensions/list_tools/resources.xml                |    9 ++
 gthumb/gth-browser.c                               |   35 ++++---
 gthumb/gth-browser.h                               |   41 ++++----
 gthumb/gth-menu-manager.c                          |   70 +++++++++++-
 gthumb/gth-menu-manager.h                          |    8 ++
 m4/gthumb.m4                                       |    6 +-
 24 files changed, 422 insertions(+), 220 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 63f1efe..6fe5d71 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,7 +11,8 @@ EXTRA_DIST =                    \
        config.rpath            \
        intltool-merge.in       \
        intltool-update.in      \
-       intltool-extract.in
+       intltool-extract.in     \
+       extension-resources.mk
 
 DISTCLEANFILES =                        \
        po/.intltool-merge-cache        \
diff --git a/data/icons/hicolor/scalable/actions/view-zoom-fit-width-symbolic.svg 
b/data/icons/hicolor/scalable/actions/view-zoom-fit-width-symbolic.svg
index 0eb67b5..23b63fd 100644
--- a/data/icons/hicolor/scalable/actions/view-zoom-fit-width-symbolic.svg
+++ b/data/icons/hicolor/scalable/actions/view-zoom-fit-width-symbolic.svg
@@ -58,9 +58,9 @@
      borderopacity="1.0"
      inkscape:pageopacity="1"
      inkscape:pageshadow="2"
-     inkscape:zoom="11.765977"
-     inkscape:cx="1.9402487"
-     inkscape:cy="13.424149"
+     inkscape:zoom="16"
+     inkscape:cx="-4.8221853"
+     inkscape:cy="10.011072"
      inkscape:document-units="px"
      inkscape:current-layer="layer1"
      showgrid="true"
@@ -106,8 +106,13 @@
      transform="translate(-31.97559,-220.36218)">
     <path
        style="fill:#bebebe;fill-opacity:1;stroke:none"
-       d="M 1.03125 1 L 1.03125 15 L 15.03125 15 L 15.03125 1 L 1.03125 1 z M 3.03125 3 L 5.03125 3 L 
7.03125 3 L 7.03125 5 L 5.03125 5 L 5.03125 11 L 7.03125 11 L 7.03125 13 L 5.03125 13 L 3.03125 13 L 3.03125 
3 z M 9.03125 3 L 11.03125 3 L 13.03125 3 L 13.03125 13 L 11.03125 13 L 9.03125 13 L 9.03125 11 L 11.03125 11 
L 11.03125 5 L 9.03125 5 L 9.03125 3 z "
+       d="m 10.893072,221.30212 0,14 14,0 0,-14 -14,0 z m 2,2 2,0 2,0 0,2 -2,0 0,6 2,0 0,2 -2,0 -2,0 0,-10 z 
m 6,0 2,0 2,0 0,10 -2,0 -2,0 0,-2 2,0 0,-6 -2,0 0,-2 z"
+       id="rect4385"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#bebebe;fill-opacity:1;stroke:none"
+       d="M 1.03125 1 L 1.03125 15 L 15.03125 15 L 15.03125 1 L 1.03125 1 z M 5.4375 5.03125 L 6.4375 
5.03125 L 6.4375 6.03125 C 6.43754 6.28846 6.30812 6.55974 6.125 6.75 L 4.84375 8.03125 L 6.125 9.3125 C 
6.30788 9.50301 6.4375 9.77405 6.4375 10.03125 L 6.4375 11.03125 L 5.4375 11.03125 C 5.12771 11.03125 4.88543 
10.94115 4.6875 10.75 L 2.03125 8.03125 L 4.6875 5.3125 C 4.88538 5.12118 5.1277 5.03125 5.4375 5.03125 z M 
9.59375 5.03125 L 10.59375 5.03125 C 10.90355 5.03125 11.14587 5.12118 11.34375 5.3125 L 14 8.03125 L 
11.34375 10.75 C 11.14582 10.94115 10.90354 11.03125 10.59375 11.03125 L 9.59375 11.03125 L 9.59375 10.03125 
C 9.59375 9.77405 9.72337 9.50301 9.90625 9.3125 L 11.1875 8.03125 L 9.90625 6.75 C 9.72313 6.55974 9.59371 
6.28846 9.59375 6.03125 L 9.59375 5.03125 z "
        transform="translate(31.97559,220.36218)"
-       id="rect4385" />
+       id="rect3002" />
   </g>
 </svg>
diff --git a/extension-resources.mk b/extension-resources.mk
new file mode 100644
index 0000000..00ccb42
--- /dev/null
+++ b/extension-resources.mk
@@ -0,0 +1,7 @@
+# rule to build the resources .c file from the xml file
+
+RESOURCES_DEP = $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir=$(srcdir) 
$(srcdir)/resources.xml)
+resources.c: resources.xml $(RESOURCES_DEP)
+       $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate --c-name gth 
$(srcdir)/resources.xml
+resources.h: resources.xml $(RESOURCES_DEP)
+       $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate --c-name gth 
$(srcdir)/resources.xml
\ No newline at end of file
diff --git a/extensions/bookmarks/Makefile.am b/extensions/bookmarks/Makefile.am
index 3de25c7..61953c6 100644
--- a/extensions/bookmarks/Makefile.am
+++ b/extensions/bookmarks/Makefile.am
@@ -10,15 +10,9 @@ libbookmarks_la_SOURCES =            \
        callbacks.h                     \
        dlg-bookmarks.c                 \
        dlg-bookmarks.h                 \
+       main.c                          \
        resources.c                     \
-       resources.h                     \
-       main.c
-
-RESOURCES_DEP = $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies --sourcedir=$(srcdir) 
$(srcdir)/gresource.xml)
-resources.c: gresource.xml $(RESOURCES_DEP)
-       $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate --c-name gth 
$(srcdir)/gresource.xml
-resources.h: gresource.xml $(RESOURCES_DEP)
-       $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate --c-name gth 
$(srcdir)/gresource.xml
+       resources.h
 
 libbookmarks_la_CFLAGS = $(GTHUMB_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
 libbookmarks_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
@@ -33,9 +27,10 @@ extensionini_DATA = $(extensionini_in_files:.extension.in.in=.extension)
 @GTHUMB_EXTENSION_RULE@
 
 EXTRA_DIST =                           \
-        $(extensionini_in_files)       \
-        gresource.xml 
+       $(extensionini_in_files)        \
+       resources.xml 
 
 DISTCLEANFILES = $(extensionini_DATA)
 
 -include $(top_srcdir)/git.mk
+-include $(top_srcdir)/extension-resources.mk
diff --git a/extensions/bookmarks/gresource.xml b/extensions/bookmarks/resources.xml
similarity index 100%
rename from extensions/bookmarks/gresource.xml
rename to extensions/bookmarks/resources.xml
diff --git a/extensions/image_rotation/actions.c b/extensions/image_rotation/actions.c
index 00053ff..fb75e33 100644
--- a/extensions/image_rotation/actions.c
+++ b/extensions/image_rotation/actions.c
@@ -28,13 +28,15 @@
 
 
 void
-gth_browser_activate_action_tool_rotate_right (GtkAction  *action,
-                                              GthBrowser *browser)
+gth_browser_activate_rotate_right (GSimpleAction       *action,
+                                  GVariant             *parameter,
+                                  gpointer              user_data)
 {
-       GList   *items;
-       GList   *file_data_list;
-       GList   *file_list;
-       GthTask *task;
+       GthBrowser      *browser = GTH_BROWSER (user_data);
+       GList           *items;
+       GList           *file_data_list;
+       GList           *file_list;
+       GthTask         *task;
 
        items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view 
(browser)));
        file_data_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
@@ -50,13 +52,15 @@ gth_browser_activate_action_tool_rotate_right (GtkAction  *action,
 
 
 void
-gth_browser_activate_action_tool_rotate_left (GtkAction  *action,
-                                             GthBrowser *browser)
+gth_browser_activate_rotate_left (GSimpleAction *action,
+                                 GVariant      *parameter,
+                                 gpointer       user_data)
 {
-       GList   *items;
-       GList   *file_data_list;
-       GList   *file_list;
-       GthTask *task;
+       GthBrowser      *browser = GTH_BROWSER (user_data);
+       GList           *items;
+       GList           *file_data_list;
+       GList           *file_list;
+       GthTask         *task;
 
        items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view 
(browser)));
        file_data_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
@@ -72,13 +76,15 @@ gth_browser_activate_action_tool_rotate_left (GtkAction  *action,
 
 
 void
-gth_browser_activate_action_tool_apply_orientation (GtkAction  *action,
-                                                   GthBrowser *browser)
+gth_browser_activate_apply_orientation (GSimpleAction  *action,
+                                       GVariant        *parameter,
+                                       gpointer         user_data)
 {
-       GList   *items;
-       GList   *file_data_list;
-       GList   *file_list;
-       GthTask *task;
+       GthBrowser      *browser = GTH_BROWSER (user_data);
+       GList           *items;
+       GList           *file_data_list;
+       GList           *file_list;
+       GthTask         *task;
 
        items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view 
(browser)));
        file_data_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
@@ -94,13 +100,15 @@ gth_browser_activate_action_tool_apply_orientation (GtkAction  *action,
 
 
 void
-gth_browser_activate_action_tool_reset_orientation (GtkAction  *action,
-                                                   GthBrowser *browser)
+gth_browser_activate_reset_orientation (GSimpleAction  *action,
+                                       GVariant        *parameter,
+                                       gpointer         user_data)
 {
-       GList   *items;
-       GList   *file_data_list;
-       GList   *file_list;
-       GthTask *task;
+       GthBrowser      *browser = GTH_BROWSER (user_data);
+       GList           *items;
+       GList           *file_data_list;
+       GList           *file_list;
+       GthTask         *task;
 
        items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view 
(browser)));
        file_data_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
diff --git a/extensions/image_rotation/actions.h b/extensions/image_rotation/actions.h
index 2e9c1c6..3543a77 100644
--- a/extensions/image_rotation/actions.h
+++ b/extensions/image_rotation/actions.h
@@ -22,13 +22,11 @@
 #ifndef ACTIONS_H
 #define ACTIONS_H
 
-#include <gtk/gtk.h>
+#include <gthumb.h>
 
-#define DEFINE_ACTION(x) void x (GtkAction *action, gpointer data);
-
-DEFINE_ACTION(gth_browser_activate_action_tool_rotate_right)
-DEFINE_ACTION(gth_browser_activate_action_tool_rotate_left)
-DEFINE_ACTION(gth_browser_activate_action_tool_apply_orientation)
-DEFINE_ACTION(gth_browser_activate_action_tool_reset_orientation)
+DEF_ACTION_CALLBACK (gth_browser_activate_rotate_right)
+DEF_ACTION_CALLBACK (gth_browser_activate_rotate_left)
+DEF_ACTION_CALLBACK (gth_browser_activate_apply_orientation)
+DEF_ACTION_CALLBACK (gth_browser_activate_reset_orientation)
 
 #endif /* ACTIONS_H */
diff --git a/extensions/image_rotation/callbacks.c b/extensions/image_rotation/callbacks.c
index 1c19f90..e0b36fa 100644
--- a/extensions/image_rotation/callbacks.c
+++ b/extensions/image_rotation/callbacks.c
@@ -25,115 +25,54 @@
 #include <glib-object.h>
 #include <gdk/gdkkeysyms.h>
 #include <gthumb.h>
+#include <extensions/list_tools/list-tools.h>
 #include "actions.h"
 
-#define BROWSER_DATA_KEY "image-rotation-browser-data"
-
-
-static const char *fixed_ui_info =
-"<ui>"
-"  <popup name='ListToolsPopup'>"
-"    <placeholder name='Tools'>"
-"      <menuitem name='RotateRight' action='Tool_RotateRight'/>"
-"      <menuitem name='RotateLeft' action='Tool_RotateLeft'/>"
-"      <menuitem name='ApplyOrientation' action='Tool_ApplyOrientation'/>"
-"      <menuitem name='ResetOrientation' action='Tool_ResetOrientation'/>"
-"      <separator />"
-"    </placeholder>"
-"  </popup>"
-"</ui>";
-
-
-static GthActionEntryExt action_entries[] = {
-       { "Tool_RotateRight", "object-rotate-right",
-         N_("Rotate Right"), "<control><alt>R",
-         N_("Rotate the selected images 90° to the right"),
-         GTH_ACTION_FLAG_ALWAYS_SHOW_IMAGE,
-         G_CALLBACK (gth_browser_activate_action_tool_rotate_right) },
-
-       { "Tool_RotateLeft", "object-rotate-left",
-         N_("Rotate Left"), "<control><alt>L",
-         N_("Rotate the selected images 90° to the left"),
-         GTH_ACTION_FLAG_ALWAYS_SHOW_IMAGE,
-         G_CALLBACK (gth_browser_activate_action_tool_rotate_left) },
-
-       { "Tool_ApplyOrientation", NULL,
-         N_("Rotate Physically"), NULL,
-         N_("Rotate the selected images according to the embedded orientation"),
-         0,
-         G_CALLBACK (gth_browser_activate_action_tool_apply_orientation) },
-
-       { "Tool_ResetOrientation", NULL,
-         N_("Reset the EXIF Orientation"), NULL,
-         N_("Reset the embedded orientation without rotating the images"),
-         0,
-         G_CALLBACK (gth_browser_activate_action_tool_reset_orientation) }
-};
-
 
-typedef struct {
-       GtkActionGroup *action_group;
-} BrowserData;
+static const GActionEntry actions[] = {
+       { "rotate-right", gth_browser_activate_rotate_right },
+       { "rotate-left", gth_browser_activate_rotate_left },
+       { "apply-orientation", gth_browser_activate_apply_orientation },
+       { "reset-orientation", gth_browser_activate_reset_orientation }
+};
 
 
-static void
-browser_data_free (BrowserData *data)
-{
-       g_free (data);
-}
+static const GthMenuEntry tools_action_entries[] = {
+       { N_("Rotate Right"), "win.rotate-right", "<control><alt>R", "object-rotate-right-symbolic" },
+       { N_("Rotate Left"), "win.rotate-left", "<control><alt>L", "object-rotate-left-symbolic" },
+       { N_("Rotate Physically"), "win.apply-orientation", NULL },
+       { N_("Reset the EXIF Orientation"), "win.reset-orientation", NULL }
+};
 
 
 void
 ir__gth_browser_construct_cb (GthBrowser *browser)
 {
-       BrowserData *data;
-       GError      *error = NULL;
-
        g_return_if_fail (GTH_IS_BROWSER (browser));
 
-       data = g_new0 (BrowserData, 1);
-       data->action_group = gtk_action_group_new ("Image Rotation Actions");
-       gtk_action_group_set_translation_domain (data->action_group, NULL);
-       _gtk_action_group_add_actions_with_flags (data->action_group,
-                                                 action_entries,
-                                                 G_N_ELEMENTS (action_entries),
-                                                 browser);
-       gtk_ui_manager_insert_action_group (gth_browser_get_ui_manager (browser), data->action_group, 0);
-
-       if (! gtk_ui_manager_add_ui_from_string (gth_browser_get_ui_manager (browser), fixed_ui_info, -1, 
&error)) {
-               g_message ("building menus failed: %s", error->message);
-               g_clear_error (&error);
-       }
-
-       g_object_set_data_full (G_OBJECT (browser), BROWSER_DATA_KEY, data, (GDestroyNotify) 
browser_data_free);
+       g_action_map_add_action_entries (G_ACTION_MAP (browser),
+                                        actions,
+                                        G_N_ELEMENTS (actions),
+                                        browser);
+       gth_menu_manager_append_entries (gth_browser_get_menu_manager (browser, 
GTH_BROWSER_MENU_MANAGER_TOOLS1),
+                                        tools_action_entries,
+                                        G_N_ELEMENTS (tools_action_entries));
 }
 
 
 void
 ir__gth_browser_update_sensitivity_cb (GthBrowser *browser)
 {
-       BrowserData *data;
-       GtkAction   *action;
-       int          n_selected;
-       gboolean     sensitive;
-
-       data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
-       g_return_if_fail (data != NULL);
+       int      n_selected;
+       gboolean sensitive;
 
        n_selected = gth_file_selection_get_n_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view 
(browser)));
        sensitive = n_selected > 0;
 
-       action = gtk_action_group_get_action (data->action_group, "Tool_RotateRight");
-       g_object_set (action, "sensitive", sensitive, NULL);
-
-       action = gtk_action_group_get_action (data->action_group, "Tool_RotateLeft");
-       g_object_set (action, "sensitive", sensitive, NULL);
-
-       action = gtk_action_group_get_action (data->action_group, "Tool_ApplyOrientation");
-       g_object_set (action, "sensitive", sensitive, NULL);
-
-       action = gtk_action_group_get_action (data->action_group, "Tool_ResetOrientation");
-       g_object_set (action, "sensitive", sensitive, NULL);
+       gth_window_enable_action (GTH_WINDOW (browser), "rotate-right", sensitive);
+       gth_window_enable_action (GTH_WINDOW (browser), "rotate-left", sensitive);
+       gth_window_enable_action (GTH_WINDOW (browser), "apply-orientation", sensitive);
+       gth_window_enable_action (GTH_WINDOW (browser), "reset-orientation", sensitive);
 }
 
 
@@ -145,12 +84,12 @@ ir__gth_browser_file_list_key_press_cb (GthBrowser  *browser,
 
        switch (event->keyval) {
        case GDK_KEY_bracketright:
-               gth_browser_activate_action_tool_rotate_right (NULL, browser);
+               gth_browser_activate_rotate_right (NULL, NULL, browser);
                result = GINT_TO_POINTER (1);
                break;
 
        case GDK_KEY_bracketleft:
-               gth_browser_activate_action_tool_rotate_left (NULL, browser);
+               gth_browser_activate_rotate_left (NULL, NULL, browser);
                result = GINT_TO_POINTER (1);
                break;
 
diff --git a/extensions/list_tools/Makefile.am b/extensions/list_tools/Makefile.am
index 5abffa2..39b646c 100644
--- a/extensions/list_tools/Makefile.am
+++ b/extensions/list_tools/Makefile.am
@@ -18,7 +18,10 @@ liblist_tools_la_SOURCES =           \
        gth-script-file.h               \
        gth-script-task.h               \
        gth-script-task.c               \
-       main.c
+       list-tools.h                    \
+       main.c                          \
+       resources.c                     \
+       resources.h
 
 liblist_tools_la_CFLAGS = $(GTHUMB_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
 liblist_tools_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
@@ -32,8 +35,11 @@ extensionini_DATA = $(extensionini_in_files:.extension.in.in=.extension)
 @GTHUMB_EXTENSION_IN_RULE@
 @GTHUMB_EXTENSION_RULE@
 
-EXTRA_DIST = $(extensionini_in_files) 
+EXTRA_DIST =                           \
+       $(extensionini_in_files)        \
+       resources.xml
 
 DISTCLEANFILES = $(extensionini_DATA)
 
 -include $(top_srcdir)/git.mk
+-include $(top_srcdir)/extension-resources.mk
diff --git a/extensions/list_tools/actions.c b/extensions/list_tools/actions.c
index 055b818..1971127 100644
--- a/extensions/list_tools/actions.c
+++ b/extensions/list_tools/actions.c
@@ -24,6 +24,9 @@
 #include <glib/gi18n.h>
 #include <gthumb.h>
 #include "dlg-personalize-scripts.h"
+#include "gth-script.h"
+#include "gth-script-file.h"
+#include "gth-script-task.h"
 
 
 void
@@ -32,3 +35,51 @@ gth_browser_action_edit_scripts (GtkAction  *action,
 {
        dlg_personalize_scripts (browser);
 }
+
+
+void
+gth_browser_exec_script (GthBrowser *browser,
+                        GthScript  *script)
+{
+       GList *items;
+       GList *file_list;
+
+       items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view 
(browser)));
+       file_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
+       if (file_list != NULL) {
+               GthTask *task;
+
+               task = gth_script_task_new (GTK_WINDOW (browser), script, file_list);
+               gth_browser_exec_task (browser, task, FALSE);
+
+               g_object_unref (task);
+       }
+
+       _g_object_list_unref (file_list);
+       _gtk_tree_path_list_free (items);
+}
+
+
+void
+gth_browser_activate_exec_script (GSimpleAction *action,
+                                 GVariant      *parameter,
+                                 gpointer       user_data)
+{
+       GthBrowser *browser = GTH_BROWSER (user_data);
+       const char *script_id;
+       GthScript  *script;
+
+       script_id = g_variant_get_string (parameter, NULL);
+       script = gth_script_file_get_script (gth_script_file_get (), script_id);
+       if (script != NULL)
+               gth_browser_exec_script (browser, script);
+}
+
+
+void
+gth_browser_activate_personalize_tools (GSimpleAction  *action,
+                                       GVariant        *parameter,
+                                       gpointer         user_data)
+{
+       dlg_personalize_scripts (GTH_BROWSER (user_data));
+}
diff --git a/extensions/list_tools/actions.h b/extensions/list_tools/actions.h
index e9f6e33..408d715 100644
--- a/extensions/list_tools/actions.h
+++ b/extensions/list_tools/actions.h
@@ -23,9 +23,15 @@
 #define ACTIONS_H
 
 #include <gtk/gtk.h>
+#include <gthumb.h>
+#include "gth-script.h"
 
 #define DEFINE_ACTION(x) void x (GtkAction *action, gpointer data);
 
 DEFINE_ACTION(gth_browser_action_edit_scripts)
+DEF_ACTION_CALLBACK (gth_browser_activate_exec_script)
+DEF_ACTION_CALLBACK (gth_browser_activate_personalize_tools)
+
+void   gth_browser_exec_script (GthBrowser *browser, GthScript  *script);
 
 #endif /* ACTIONS_H */
diff --git a/extensions/list_tools/callbacks.c b/extensions/list_tools/callbacks.c
index 0cfec21..68cd546 100644
--- a/extensions/list_tools/callbacks.c
+++ b/extensions/list_tools/callbacks.c
@@ -28,11 +28,18 @@
 #include "callbacks.h"
 #include "gth-script-file.h"
 #include "gth-script-task.h"
+#include "list-tools.h"
 
 
 #define BROWSER_DATA_KEY "list-tools-browser-data"
 
 
+static const GActionEntry actions[] = {
+       { "exec-script", gth_browser_activate_exec_script, "s" },
+       { "personalize-tools", gth_browser_activate_personalize_tools }
+};
+
+
 static const char *fixed_ui_info =
 "<ui>"
 "  <toolbar name='ToolBar'>"
@@ -84,6 +91,7 @@ typedef struct {
        GtkActionGroup *action_group;
        gulong          scripts_changed_id;
        gboolean        menu_initialized;
+       guint           menu_merge_id;
 } BrowserData;
 
 
@@ -164,29 +172,6 @@ list_tools__gth_browser_update_sensitivity_cb (GthBrowser *browser)
 
 
 static void
-exec_script (GthBrowser *browser,
-            GthScript  *script)
-{
-       GList *items;
-       GList *file_list;
-
-       items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view 
(browser)));
-       file_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
-       if (file_list != NULL) {
-               GthTask *task;
-
-               task = gth_script_task_new (GTK_WINDOW (browser), script, file_list);
-               gth_browser_exec_task (browser, task, FALSE);
-
-               g_object_unref (task);
-       }
-
-       _g_object_list_unref (file_list);
-       _gtk_tree_path_list_free (items);
-}
-
-
-static void
 activate_script_menu_item (GtkMenuItem *menuitem,
                           gpointer     user_data)
 {
@@ -195,7 +180,7 @@ activate_script_menu_item (GtkMenuItem *menuitem,
 
        script = gth_script_file_get_script (gth_script_file_get (), g_object_get_data (G_OBJECT (menuitem), 
"script_id"));
        if (script != NULL)
-               exec_script (data->browser, script);
+               gth_browser_exec_script (data->browser, script);
 }
 
 
@@ -203,24 +188,31 @@ static void
 _update_scripts_menu (BrowserData *data,
                      const char  *prefix)
 {
-       GtkWidget *separator1;
-       GtkWidget *separator2;
-       GtkWidget *menu;
-       GList     *script_list;
-       GList     *scan;
-       int        pos;
-       gboolean   script_present = FALSE;
+       GtkWidget       *separator1;
+       GtkWidget       *separator2;
+       GtkWidget       *menu;
+       GthMenuManager  *menu_manager;
+       GList           *script_list;
+       GList           *scan;
+       int              pos;
+       gboolean         script_present = FALSE;
 
        separator1 = get_widget_with_prefix (data, prefix, "/ToolsSeparator");
        separator2 = get_widget_with_prefix (data, prefix, "/Scripts");
        menu = gtk_widget_get_parent (separator1);
        _gtk_container_remove_children (GTK_CONTAINER (menu), separator1, separator2);
 
+       menu_manager = gth_browser_get_menu_manager (data->browser, GTH_BROWSER_MENU_MANAGER_TOOLS3);
+       if (data->menu_merge_id != 0)
+               gth_menu_manager_remove_entries (menu_manager, data->menu_merge_id);
+       data->menu_merge_id = gth_menu_manager_new_merge_id (menu_manager);
+
        script_list = gth_script_file_get_scripts (gth_script_file_get ());
        pos = _gtk_container_get_pos (GTK_CONTAINER (menu), separator2);
        for (scan = script_list; scan; scan = scan->next) {
                GthScript *script = scan->data;
                GtkWidget *menu_item;
+               char      *detailed_action;
 
                if (! gth_script_is_visible (script))
                        continue;
@@ -239,7 +231,16 @@ _update_scripts_menu (BrowserData *data,
                                  G_CALLBACK (activate_script_menu_item),
                                  data);
 
+               detailed_action = g_strdup_printf ("win.exec-script('%s')", gth_script_get_id (script));
+               gth_menu_manager_append_entry (menu_manager,
+                                              data->menu_merge_id,
+                                              gth_script_get_display_name (script),
+                                              detailed_action,
+                                              NULL,
+                                              NULL);
                script_present = TRUE;
+
+               g_free (detailed_action);
        }
 
        separator1 = get_widget_with_prefix (data, prefix, "/ScriptsListSeparator");
@@ -294,6 +295,22 @@ list_tools_show_menu_func (GtkAction *action,
 }
 
 
+static void
+tools_menu_button_toggled_cb (GtkToggleButton *togglebutton,
+                             gpointer         user_data)
+{
+       BrowserData *data = user_data;
+
+       if (! gtk_toggle_button_get_active (togglebutton))
+               return;
+
+       if (! data->menu_initialized) {
+               data->menu_initialized = TRUE;
+               update_scripts_menu (data);
+       }
+}
+
+
 void
 list_tools__gth_browser_construct_cb (GthBrowser *browser)
 {
@@ -303,6 +320,11 @@ list_tools__gth_browser_construct_cb (GthBrowser *browser)
 
        g_return_if_fail (GTH_IS_BROWSER (browser));
 
+       g_action_map_add_action_entries (G_ACTION_MAP (browser),
+                                        actions,
+                                        G_N_ELEMENTS (actions),
+                                        browser);
+
        data = g_new0 (BrowserData, 1);
        data->browser = browser;
        data->action_group = gtk_action_group_new ("List Tools Manager Actions");
@@ -336,6 +358,40 @@ list_tools__gth_browser_construct_cb (GthBrowser *browser)
        }
 
        g_object_set_data_full (G_OBJECT (browser), BROWSER_DATA_KEY, data, (GDestroyNotify) 
browser_data_free);
+
+       {
+               GtkWidget  *button;
+               GtkBuilder *builder;
+               GMenuModel *menu;
+
+               builder = gtk_builder_new_from_resource 
("/org/gnome/gThumb/list_tools/data/ui/tools-menu.ui");
+               gth_browser_add_menu_manager_for_menu (browser, GTH_BROWSER_MENU_MANAGER_TOOLS1, G_MENU 
(gtk_builder_get_object (builder, "tools1")));
+               gth_browser_add_menu_manager_for_menu (browser, GTH_BROWSER_MENU_MANAGER_TOOLS2, G_MENU 
(gtk_builder_get_object (builder, "tools2")));
+               gth_browser_add_menu_manager_for_menu (browser, GTH_BROWSER_MENU_MANAGER_TOOLS3, G_MENU 
(gtk_builder_get_object (builder, "tools3")));
+               menu = G_MENU_MODEL (gtk_builder_get_object (builder, "tools-menu"));
+
+               /* browser tools */
+
+               button = _gtk_menu_button_new_for_header_bar ();
+               g_signal_connect (button, "toggled", G_CALLBACK (tools_menu_button_toggled_cb), data);
+               gtk_widget_set_tooltip_text (button, _("Tools"));
+               gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name 
("system-run-symbolic", GTK_ICON_SIZE_MENU));
+               gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu);
+               gtk_widget_show_all (button);
+               gtk_box_pack_start (GTK_BOX (gth_browser_get_headerbar_section (browser, 
GTH_BROWSER_HEADER_SECTION_BROWSER_TOOLS)), button, FALSE, FALSE, 0);
+
+               /* viewer tools */
+
+               button = _gtk_menu_button_new_for_header_bar ();
+               g_signal_connect (button, "toggled", G_CALLBACK (tools_menu_button_toggled_cb), data);
+               gtk_widget_set_tooltip_text (button, _("Tools"));
+               gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name 
("system-run-symbolic", GTK_ICON_SIZE_MENU));
+               gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu);
+               gtk_widget_show_all (button);
+               gtk_box_pack_start (GTK_BOX (gth_browser_get_headerbar_section (browser, 
GTH_BROWSER_HEADER_SECTION_VIEWER_TOOLS)), button, FALSE, FALSE, 0);
+
+               g_object_unref (builder);
+       }
 }
 
 
@@ -352,7 +408,7 @@ list_tools__gth_browser_file_list_key_press_cb (GthBrowser  *browser,
                GthScript *script = scan->data;
 
                if (gth_script_get_shortcut (script) == event->keyval) {
-                       exec_script (browser, script);
+                       gth_browser_exec_script (browser, script);
                        result = GINT_TO_POINTER (1);
                        break;
                }
diff --git a/extensions/list_tools/data/ui/Makefile.am b/extensions/list_tools/data/ui/Makefile.am
index a1379a1..72dc5ba 100644
--- a/extensions/list_tools/data/ui/Makefile.am
+++ b/extensions/list_tools/data/ui/Makefile.am
@@ -1,5 +1,7 @@
-uidir = $(pkgdatadir)/ui
-ui_DATA = ask-value.ui personalize-scripts.ui script-editor.ui
-EXTRA_DIST = $(ui_DATA)
+EXTRA_DIST =                   \
+       ask-value.ui            \
+       personalize-scripts.ui  \
+       script-editor.ui        \
+       tools-menu.ui
 
 -include $(top_srcdir)/git.mk
diff --git a/extensions/list_tools/data/ui/tools-menu.ui b/extensions/list_tools/data/ui/tools-menu.ui
new file mode 100644
index 0000000..4a973cc
--- /dev/null
+++ b/extensions/list_tools/data/ui/tools-menu.ui
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="tools-menu">
+    <section id="tools1">
+    </section>
+    <section id="tools2">
+    </section>
+    <section id="tools3">
+    </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">Personalize...</attribute>
+        <attribute name="action">win.personalize-tools</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/extensions/list_tools/dlg-personalize-scripts.c b/extensions/list_tools/dlg-personalize-scripts.c
index e98689c..8cc2b5c 100644
--- a/extensions/list_tools/dlg-personalize-scripts.c
+++ b/extensions/list_tools/dlg-personalize-scripts.c
@@ -541,7 +541,7 @@ dlg_personalize_scripts (GthBrowser *browser)
 
        data = g_new0 (DialogData, 1);
        data->browser = browser;
-       data->builder = _gtk_builder_new_from_file ("personalize-scripts.ui", "list_tools");
+       data->builder = gtk_builder_new_from_resource 
("/org/gnome/gThumb/list_tools/data/ui/personalize-scripts.ui");
 
        /* Get the widgets. */
 
diff --git a/extensions/list_tools/gth-script-editor-dialog.c 
b/extensions/list_tools/gth-script-editor-dialog.c
index 8dae48f..e07cc0d 100644
--- a/extensions/list_tools/gth-script-editor-dialog.c
+++ b/extensions/list_tools/gth-script-editor-dialog.c
@@ -131,7 +131,7 @@ gth_script_editor_dialog_construct (GthScriptEditorDialog *self,
        gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_SAVE, GTK_RESPONSE_OK);
        gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_HELP, GTK_RESPONSE_HELP);
 
-       self->priv->builder = _gtk_builder_new_from_file ("script-editor.ui", "list_tools");
+       self->priv->builder = gtk_builder_new_from_resource 
("/org/gnome/gThumb/list_tools/data/ui/script-editor.ui");
 
        content = _gtk_builder_get_widget (self->priv->builder, "script_editor");
        gtk_container_set_border_width (GTK_CONTAINER (content), 5);
diff --git a/extensions/list_tools/gth-script.c b/extensions/list_tools/gth-script.c
index 74defbf..a265284 100644
--- a/extensions/list_tools/gth-script.c
+++ b/extensions/list_tools/gth-script.c
@@ -618,7 +618,7 @@ ask_value (ReplaceData  *replace_data,
        else
                default_value = "";
 
-       builder = _gtk_builder_new_from_file ("ask-value.ui", "list_tools");
+       builder = gtk_builder_new_from_resource ("/org/gnome/gThumb/list_tools/data/ui/ask-value.ui");
        dialog = _gtk_builder_get_widget (builder, "ask_value_dialog");
        gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (builder, "title_label")), 
gth_script_get_display_name (replace_data->script));
        gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (builder, "filename_label")), 
g_file_info_get_display_name (file_data->info));
diff --git a/extensions/list_tools/list-tools.h b/extensions/list_tools/list-tools.h
new file mode 100644
index 0000000..9172d67
--- /dev/null
+++ b/extensions/list_tools/list-tools.h
@@ -0,0 +1,29 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2013 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIST_TOOLS_H
+#define LIST_TOOLS_H
+
+#define GTH_BROWSER_MENU_MANAGER_TOOLS1 "tools.tools1"
+#define GTH_BROWSER_MENU_MANAGER_TOOLS2 "tools.tools2"
+#define GTH_BROWSER_MENU_MANAGER_TOOLS3 "tools.tools3"
+
+#endif /* LIST_TOOLS_H */
diff --git a/extensions/list_tools/resources.xml b/extensions/list_tools/resources.xml
new file mode 100644
index 0000000..e64c8c6
--- /dev/null
+++ b/extensions/list_tools/resources.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/gnome/gThumb/list_tools">
+    <file compressed="true">data/ui/ask-value.ui</file>
+    <file compressed="true">data/ui/personalize-scripts.ui</file>
+    <file compressed="true">data/ui/script-editor.ui</file>
+    <file compressed="true">data/ui/tools-menu.ui</file>
+  </gresource>
+</gresources>
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index a1827a1..652733f 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -117,7 +117,7 @@ struct _GthBrowserPrivate {
        GtkWidget         *list_extra_widget;
        GtkWidget         *file_properties;
        GtkWidget         *header_sections[GTH_BROWSER_N_HEADER_SECTIONS];
-       GthMenuManager    *menu_managers[GTH_BROWSER_N_MENU_MANAGERS];
+       GHashTable        *menu_managers;
 
        GtkWidget         *thumbnail_list;
 
@@ -2386,10 +2386,8 @@ static void
 gth_browser_finalize (GObject *object)
 {
        GthBrowser *browser = GTH_BROWSER (object);
-       int         i;
 
-       for (i = 0; i < GTH_BROWSER_N_MENU_MANAGERS; i++)
-               _g_object_unref (browser->priv->menu_managers[i]);
+       g_hash_table_destroy (browser->priv->menu_managers);
        browser_state_free (&browser->priv->state);
        _g_object_unref (browser->priv->browser_settings);
        _g_object_unref (browser->priv->messages_settings);
@@ -4001,9 +3999,7 @@ gth_browser_init (GthBrowser *browser)
        browser->priv->messages_settings = g_settings_new (GTHUMB_MESSAGES_SCHEMA);
        browser->priv->desktop_interface_settings = g_settings_new (GNOME_DESKTOP_INTERFACE_SCHEMA);
        browser->priv->file_properties_on_the_right = g_settings_get_boolean 
(browser->priv->browser_settings, PREF_BROWSER_PROPERTIES_ON_THE_RIGHT);
-
-       for (i = 0; i < GTH_BROWSER_N_MENU_MANAGERS; i++)
-               browser->priv->menu_managers[i] = NULL;
+       browser->priv->menu_managers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, 
g_object_unref);
 
        browser_state_init (&browser->priv->state);
 
@@ -4225,8 +4221,8 @@ gth_browser_init (GthBrowser *browser)
                        gtk_widget_show_all (button);
                        gtk_header_bar_pack_end (GTK_HEADER_BAR (header_bar), button);
 
-                       browser->priv->menu_managers[GTH_BROWSER_MENU_MANAGER_GEARS] = gth_menu_manager_new 
(G_MENU (menu));
-                       browser->priv->menu_managers[GTH_BROWSER_MENU_MANAGER_GEARS_FOLDER_ACTIONS] = 
gth_menu_manager_new (G_MENU (gtk_builder_get_object (builder, "folder-actions")));
+                       gth_browser_add_menu_manager_for_menu (browser, GTH_BROWSER_MENU_MANAGER_GEARS, 
G_MENU (menu));
+                       gth_browser_add_menu_manager_for_menu (browser, 
GTH_BROWSER_MENU_MANAGER_GEARS_FOLDER_ACTIONS, G_MENU (gtk_builder_get_object (builder, "folder-actions")));
 
                        _gtk_window_add_accelerators_from_menu ((GTK_WINDOW (browser)), menu);
 
@@ -4252,13 +4248,13 @@ gth_browser_init (GthBrowser *browser)
                                                   "go-up-symbolic",
                                                   _("Go up one level"),
                                                   "win.go-up",
-                                                  "<alt>Up");
+                                                  "<alt>Up");*/
                gth_browser_add_header_bar_button (browser,
                                                   GTH_BROWSER_HEADER_SECTION_BROWSER_LOCATIONS,
                                                   "user-home-symbolic",
                                                   NULL,
                                                   "win.go-home",
-                                                  "<alt>Home"); FIXME */
+                                                  "<alt>Home");
 
                /* history menu button */
 
@@ -4267,7 +4263,7 @@ gth_browser_init (GthBrowser *browser)
 
                        builder = _gtk_builder_new_from_resource ("history-menu.ui");
                        button = _gtk_menu_button_new_for_header_bar ();
-                       gtk_widget_set_tooltip_text (button, _("Visited Locations"));
+                       gtk_widget_set_tooltip_text (button, _("History"));
                        gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name 
("document-open-recent-symbolic", GTK_ICON_SIZE_MENU));
 
                        browser->priv->history_menu = G_MENU (gtk_builder_get_object (builder, 
"visited-locations"));
@@ -4989,11 +4985,20 @@ gth_browser_add_header_bar_toggle_button (GthBrowser                    *browser,
 }
 
 
+void
+gth_browser_add_menu_manager_for_menu (GthBrowser *browser,
+                                      const char *menu_id,
+                                      GMenu      *menu)
+{
+       g_hash_table_insert (browser->priv->menu_managers, g_strdup (menu_id), gth_menu_manager_new (menu));
+}
+
+
 GthMenuManager *
-gth_browser_get_menu_manager (GthBrowser               *browser,
-                             GthBrowserMenuManager      manager)
+gth_browser_get_menu_manager (GthBrowser *browser,
+                             const char *menu_id)
 {
-       return browser->priv->menu_managers[manager];
+       return g_hash_table_lookup (browser->priv->menu_managers, menu_id);
 }
 
 
diff --git a/gthumb/gth-browser.h b/gthumb/gth-browser.h
index 71415c3..91b6048 100644
--- a/gthumb/gth-browser.h
+++ b/gthumb/gth-browser.h
@@ -32,6 +32,9 @@
 
 G_BEGIN_DECLS
 
+#define GTH_BROWSER_MENU_MANAGER_GEARS                 "gears"
+#define GTH_BROWSER_MENU_MANAGER_GEARS_FOLDER_ACTIONS  "folder-actions"
+
 #define GTH_TYPE_BROWSER              (gth_browser_get_type ())
 #define GTH_BROWSER(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_BROWSER, GthBrowser))
 #define GTH_BROWSER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_BROWSER_TYPE, GthBrowserClass))
@@ -66,12 +69,6 @@ typedef enum { /*< skip >*/
        GTH_BROWSER_N_HEADER_SECTIONS
 } GthBrowserHeaderSection;
 
-typedef enum { /*< skip >*/
-       GTH_BROWSER_MENU_MANAGER_GEARS,
-       GTH_BROWSER_MENU_MANAGER_GEARS_FOLDER_ACTIONS,
-       GTH_BROWSER_N_MENU_MANAGERS
-} GthBrowserMenuManager;
-
 typedef enum {
        GTH_ACTION_GO_TO,
        GTH_ACTION_GO_BACK,
@@ -132,21 +129,23 @@ GtkWidget *      gth_browser_get_statusbar          (GthBrowser       *browser);
 GtkWidget *      gth_browser_get_filterbar          (GthBrowser       *browser);
 GtkWidget *      gth_browser_get_headerbar_section  (GthBrowser                        *browser,
                                                     GthBrowserHeaderSection     section);
-GtkWidget *     gth_browser_add_header_bar_button  (GthBrowser                 *browser,
-                                                    GthBrowserHeaderSection     section,
-                                                    const char                 *icon_name,
-                                                    const char                 *tooltip,
-                                                    const char                 *action_name,
-                                                    const char                 *accelerator);
-GtkWidget * gth_browser_add_header_bar_toggle_button    (GthBrowser                    *browser,
-                                                         GthBrowserHeaderSection        section,
-                                                         const char                    *icon_name,
-                                                         const char                    *tooltip,
-                                                         const char                    *action_name,
-                                                         const char                    *accelerator);
-GthMenuManager * gth_browser_get_menu_manager       (GthBrowser       *browser,
-                                                    GthBrowserMenuManager
-                                                                      manager);
+GtkWidget *     gth_browser_add_header_bar_button      (GthBrowser                     *browser,
+                                                        GthBrowserHeaderSection         section,
+                                                        const char                     *icon_name,
+                                                        const char                     *tooltip,
+                                                        const char                     *action_name,
+                                                        const char                     *accelerator);
+GtkWidget *gth_browser_add_header_bar_toggle_button    (GthBrowser                     *browser,
+                                                        GthBrowserHeaderSection         section,
+                                                        const char                     *icon_name,
+                                                        const char                     *tooltip,
+                                                        const char                     *action_name,
+                                                        const char                     *accelerator);
+void            gth_browser_add_menu_manager_for_menu  (GthBrowser                     *browser,
+                                                        const char                     *menu_id,
+                                                        GMenu                          *menu);
+GthMenuManager * gth_browser_get_menu_manager          (GthBrowser                     *browser,
+                                                        const char                     *menu_id);
 GtkWidget *      gth_browser_get_file_list          (GthBrowser       *browser);
 GtkWidget *      gth_browser_get_file_list_view     (GthBrowser       *browser);
 GtkWidget *      gth_browser_get_thumbnail_list     (GthBrowser       *browser);
diff --git a/gthumb/gth-menu-manager.c b/gthumb/gth-menu-manager.c
index a4afd6a..dc86761 100644
--- a/gthumb/gth-menu-manager.c
+++ b/gthumb/gth-menu-manager.c
@@ -43,6 +43,15 @@ G_DEFINE_TYPE (GthMenuManager, gth_menu_manager, G_TYPE_OBJECT)
 
 
 static void
+free_items_list (gpointer key,
+                gpointer value,
+                gpointer user_data)
+{
+       _g_string_list_free (value);
+}
+
+
+static void
 gth_menu_manager_finalize (GObject *object)
 {
        GthMenuManager *self;
@@ -50,6 +59,7 @@ gth_menu_manager_finalize (GObject *object)
        self = GTH_MENU_MANAGER (object);
 
        _g_object_unref (self->priv->menu);
+       g_hash_table_foreach (self->priv->items, free_items_list, NULL);
        g_hash_table_destroy (self->priv->items);
 
        G_OBJECT_CLASS (gth_menu_manager_parent_class)->finalize (object);
@@ -126,7 +136,7 @@ static void
 gth_menu_manager_init (GthMenuManager *self)
 {
        self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_MENU_MANAGER, GthMenuManagerPrivate);
-       self->priv->items = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) 
_g_string_list_free);
+       self->priv->items = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
        self->priv->last_id = 1;
        self->priv->menu = NULL;
 }
@@ -139,6 +149,30 @@ gth_menu_manager_new (GMenu *menu)
 }
 
 
+static GMenuItem *
+create_menu_item (const char *label,
+                 const char *detailed_action,
+                 const char *accel,
+                 const char *icon_name)
+{
+       GMenuItem *item;
+
+       item = g_menu_item_new (label,detailed_action);
+       if (accel != NULL)
+               g_menu_item_set_attribute (item, "accel", "s", accel, NULL);
+       if (icon_name != NULL) {
+               GIcon *icon;
+
+               icon = g_themed_icon_new (icon_name);
+               g_menu_item_set_icon (item, icon);
+
+               g_object_unref (icon);
+       }
+
+       return item;
+}
+
+
 guint
 gth_menu_manager_append_entries (GthMenuManager     *menu_manager,
                                 const GthMenuEntry *entries,
@@ -148,15 +182,13 @@ gth_menu_manager_append_entries (GthMenuManager     *menu_manager,
        GList *items;
        int    i;
 
-       merge_id = menu_manager->priv->last_id++;
+       merge_id = gth_menu_manager_new_merge_id (menu_manager);
        items = NULL;
        for (i = 0; i < n_entries; i++) {
                const GthMenuEntry *entry = entries + i;
                GMenuItem          *item;
 
-               item = g_menu_item_new (_(entry->label), entry->detailed_action);
-               if (entry->accel != NULL)
-                       g_menu_item_set_attribute (item, "accel", "s", entry->accel, NULL);
+               item = create_menu_item (_(entry->label), entry->detailed_action, entry->accel, 
entry->icon_name);
                g_menu_append_item (menu_manager->priv->menu, item);
 
                items = g_list_prepend (items, g_strdup (entry->detailed_action));
@@ -216,5 +248,33 @@ gth_menu_manager_remove_entries (GthMenuManager     *menu_manager,
                        g_menu_remove (menu_manager->priv->menu, pos);
        }
 
+       _g_string_list_free (items);
        g_hash_table_remove (menu_manager->priv->items, GINT_TO_POINTER (merge_id));
 }
+
+
+guint
+gth_menu_manager_new_merge_id (GthMenuManager *menu_manager)
+{
+       return menu_manager->priv->last_id++;
+}
+
+
+void
+gth_menu_manager_append_entry (GthMenuManager          *menu_manager,
+                              guint             merge_id,
+                              const char       *label,
+                              const char       *detailed_action,
+                              const char       *accel,
+                              const char       *icon_name)
+{
+       GMenuItem *item;
+       GList     *items;
+
+       item = create_menu_item (label, detailed_action, accel, icon_name);
+       g_menu_append_item (menu_manager->priv->menu, item);
+
+       items = g_hash_table_lookup (menu_manager->priv->items, GINT_TO_POINTER (merge_id));
+       items = g_list_append (items, g_strdup (detailed_action));
+       g_hash_table_insert (menu_manager->priv->items, GINT_TO_POINTER (merge_id), items);
+}
diff --git a/gthumb/gth-menu-manager.h b/gthumb/gth-menu-manager.h
index 26a926f..e79125c 100644
--- a/gthumb/gth-menu-manager.h
+++ b/gthumb/gth-menu-manager.h
@@ -37,6 +37,7 @@ typedef struct {
        const char *label;
        const char *detailed_action;
        const char *accel;
+       const char *icon_name;
 } GthMenuEntry;
 
 typedef struct _GthMenuManager         GthMenuManager;
@@ -61,6 +62,13 @@ guint                        gth_menu_manager_append_entries         (GthMenuManager       
  *menu_manager,
                                                                 int                     n_entries);
 void                   gth_menu_manager_remove_entries         (GthMenuManager         *menu_manager,
                                                                 guint                   merge_id);
+guint                  gth_menu_manager_new_merge_id           (GthMenuManager         *menu_manager);
+void                   gth_menu_manager_append_entry           (GthMenuManager         *menu_manager,
+                                                                guint                   merge_id,
+                                                                const char             *label,
+                                                                const char             *detailed_action,
+                                                                const char             *accel,
+                                                                const char             *icon_name);
 
 G_END_DECLS
 
diff --git a/m4/gthumb.m4 b/m4/gthumb.m4
index 4782323..119f294 100644
--- a/m4/gthumb.m4
+++ b/m4/gthumb.m4
@@ -34,7 +34,7 @@ ifelse([$1], [], [AC_MSG_ERROR([Required gthumb API version not supplied])], [])
 _gthumb_api_version=$1
 
 AC_MSG_CHECKING([whether gthumb-$_gthumb_api_version is available])
-PKG_CHECK_EXISTS([gthumb-$_gthumb_api_version], [result=yes],[result=no]) 
+PKG_CHECK_EXISTS([gthumb-$_gthumb_api_version], [result=yes],[result=no])
 AC_MSG_RESULT([$result])
 
 if test $result = "no" ; then
@@ -65,7 +65,7 @@ dnl set the GTHUMB_EXTENSIONS_DIR variable
 GTHUMB_EXTENSIONS_DIR="`$PKG_CONFIG --variable=extensionsdir gthumb-$_gthumb_api_version`"
 AC_SUBST([GTHUMB_EXTENSIONS_DIR])
 
-GTHUMB_EXTENSION_RULES
+AC_SUBST([GTHUMB_EXTENSION_RULES])
 
 ])
 
@@ -81,4 +81,4 @@ AC_SUBST(GTHUMB_EXTENSION_RULE)
 GTHUMB_EXTENSION_IN_RULE='%.extension.in: %.extension.in.in $(extension_LTLIBRARIES) ; sed -e 
"s|%LIBRARY%|`. ./$(extension_LTLIBRARIES) && echo $$dlname`|" -e "s|%VERSION%|$(VERSION)|" -e 
"s|%GTHUMB_API_VERSION%|$(GTHUMB_API_VERSION)|" $< > [$]@'
 AC_SUBST(GTHUMB_EXTENSION_IN_RULE)
 
-])
\ No newline at end of file
+])



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]