[gimp] libgimpbase, app: implement File -> Show in File Manager



commit e448cc3173b55029cb02e89ed041362e95b6901b
Author: Michael Natterer <mitch gimp org>
Date:   Mon Feb 16 18:40:26 2015 +0100

    libgimpbase, app: implement File -> Show in File Manager
    
    Add gimp_file_show_in_file_manager() to libgimpbase and a menu item
    in app which shows the image's file (if any) in the file manager.
    
    Implemented calling the org.freedesktop.FileManager1 interface
    and dropped snippets found on stackoverflow for somebody to
    turn into working code for OSX and Windows.

 app/actions/file-actions.c  |   29 +++++++----
 app/actions/file-commands.c |   29 +++++++++++
 app/actions/file-commands.h |   54 +++++++++++----------
 app/widgets/gimphelp-ids.h  |    1 +
 libgimpbase/gimpbase.def    |    1 +
 libgimpbase/gimputils.c     |  114 +++++++++++++++++++++++++++++++++++++++++++
 libgimpbase/gimputils.h     |   76 +++++++++++++++--------------
 menus/image-menu.xml.in     |    4 +-
 8 files changed, 233 insertions(+), 75 deletions(-)
---
diff --git a/app/actions/file-actions.c b/app/actions/file-actions.c
index c66ce6a..027edac 100644
--- a/app/actions/file-actions.c
+++ b/app/actions/file-actions.c
@@ -108,6 +108,12 @@ static const GimpActionEntry file_actions[] =
     G_CALLBACK (file_close_all_cmd_callback),
     GIMP_HELP_FILE_CLOSE_ALL },
 
+  { "file-show-in-file-manager", "gtk-directory",
+    NC_("file-action", "Show in File Manager"), "<primary><alt>F",
+    NC_("file-action", "Show in File Manager"),
+    G_CALLBACK (file_show_in_file_manager_cmd_callback),
+    GIMP_HELP_FILE_SHOW_IN_FILE_MANAGER },
+
   { "file-quit", "application-exit",
     NC_("file-action", "_Quit"), "<primary>Q",
     NC_("file-action", "Quit the GNU Image Manipulation Program"),
@@ -280,17 +286,18 @@ file_actions_update (GimpActionGroup *group,
 #define SET_SENSITIVE(action,condition) \
         gimp_action_group_set_action_sensitive (group, action, (condition) != 0)
 
-  SET_SENSITIVE ("file-save",            drawable);
-  SET_SENSITIVE ("file-save-as",         drawable);
-  SET_SENSITIVE ("file-save-a-copy",     drawable);
-  SET_SENSITIVE ("file-save-and-close",  drawable);
-  SET_SENSITIVE ("file-revert",          image && (file || source));
-  SET_SENSITIVE ("file-export",          drawable);
-  SET_VISIBLE   ("file-export",          ! show_overwrite);
-  SET_SENSITIVE ("file-overwrite",       show_overwrite);
-  SET_VISIBLE   ("file-overwrite",       show_overwrite);
-  SET_SENSITIVE ("file-export-as",       drawable);
-  SET_SENSITIVE ("file-create-template", image);
+  SET_SENSITIVE ("file-save",                 drawable);
+  SET_SENSITIVE ("file-save-as",              drawable);
+  SET_SENSITIVE ("file-save-a-copy",          drawable);
+  SET_SENSITIVE ("file-save-and-close",       drawable);
+  SET_SENSITIVE ("file-revert",               file || source);
+  SET_SENSITIVE ("file-export",               drawable);
+  SET_VISIBLE   ("file-export",               ! show_overwrite);
+  SET_SENSITIVE ("file-overwrite",            show_overwrite);
+  SET_VISIBLE   ("file-overwrite",            show_overwrite);
+  SET_SENSITIVE ("file-export-as",            drawable);
+  SET_SENSITIVE ("file-create-template",      image);
+  SET_SENSITIVE ("file-show-in-file-manager", file || source || export);
 
   if (export)
     {
diff --git a/app/actions/file-commands.c b/app/actions/file-commands.c
index 598e3f7..13ccb01 100644
--- a/app/actions/file-commands.c
+++ b/app/actions/file-commands.c
@@ -471,6 +471,35 @@ file_close_all_cmd_callback (GtkAction *action,
 }
 
 void
+file_show_in_file_manager_cmd_callback (GtkAction *action,
+                                        gpointer   data)
+{
+  Gimp         *gimp;
+  GimpDisplay  *display;
+  GimpImage    *image;
+  GFile        *file;
+  return_if_no_gimp (gimp, data);
+  return_if_no_display (display, data);
+
+  image = gimp_display_get_image (display);
+
+  file = gimp_image_get_any_file (image);
+
+  if (file)
+    {
+      GError *error = NULL;
+
+      if (! gimp_file_show_in_file_manager (file, &error))
+        {
+          gimp_message (gimp, G_OBJECT (display), GIMP_MESSAGE_ERROR,
+                        _("Can't show file in file manager: %s"),
+                        error->message);
+          g_clear_error (&error);
+        }
+    }
+}
+
+void
 file_quit_cmd_callback (GtkAction *action,
                         gpointer   data)
 {
diff --git a/app/actions/file-commands.h b/app/actions/file-commands.h
index e249eff..5a8a5ed 100644
--- a/app/actions/file-commands.h
+++ b/app/actions/file-commands.h
@@ -19,32 +19,34 @@
 #define __FILE_COMMANDS_H__
 
 
-void   file_open_cmd_callback            (GtkAction   *action,
-                                          gpointer     data);
-void   file_open_as_layers_cmd_callback  (GtkAction   *action,
-                                          gpointer     data);
-void   file_open_location_cmd_callback   (GtkAction   *action,
-                                          gpointer     data);
-void   file_open_recent_cmd_callback     (GtkAction   *action,
-                                          gint         value,
-                                          gpointer     data);
-
-void   file_save_cmd_callback            (GtkAction   *action,
-                                          gint         value,
-                                          gpointer     data);
-void   file_create_template_cmd_callback (GtkAction   *action,
-                                          gpointer     data);
-
-void   file_revert_cmd_callback          (GtkAction   *action,
-                                          gpointer     data);
-void   file_close_all_cmd_callback       (GtkAction   *action,
-                                          gpointer     data);
-void   file_quit_cmd_callback            (GtkAction   *action,
-                                          gpointer     data);
-
-void   file_file_open_dialog             (Gimp        *gimp,
-                                          GFile       *file,
-                                          GtkWidget   *parent);
+void   file_open_cmd_callback                 (GtkAction   *action,
+                                               gpointer     data);
+void   file_open_as_layers_cmd_callback       (GtkAction   *action,
+                                               gpointer     data);
+void   file_open_location_cmd_callback        (GtkAction   *action,
+                                               gpointer     data);
+void   file_open_recent_cmd_callback          (GtkAction   *action,
+                                               gint         value,
+                                               gpointer     data);
+
+void   file_save_cmd_callback                 (GtkAction   *action,
+                                               gint         value,
+                                               gpointer     data);
+void   file_create_template_cmd_callback      (GtkAction   *action,
+                                               gpointer     data);
+
+void   file_revert_cmd_callback               (GtkAction   *action,
+                                               gpointer     data);
+void   file_close_all_cmd_callback            (GtkAction   *action,
+                                               gpointer     data);
+void   file_show_in_file_manager_cmd_callback (GtkAction   *action,
+                                               gpointer     data);
+void   file_quit_cmd_callback                 (GtkAction   *action,
+                                               gpointer     data);
+
+void   file_file_open_dialog                  (Gimp        *gimp,
+                                               GFile       *file,
+                                               GtkWidget   *parent);
 
 
 #endif /* __FILE_COMMANDS_H__ */
diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h
index 6a6e537..0a7dec0 100644
--- a/app/widgets/gimphelp-ids.h
+++ b/app/widgets/gimphelp-ids.h
@@ -41,6 +41,7 @@
 #define GIMP_HELP_FILE_REVERT                     "gimp-file-revert"
 #define GIMP_HELP_FILE_CLOSE                      "gimp-file-close"
 #define GIMP_HELP_FILE_CLOSE_ALL                  "gimp-file-close-all"
+#define GIMP_HELP_FILE_SHOW_IN_FILE_MANAGER       "gimp-file-show-in-file-manager"
 #define GIMP_HELP_FILE_CREATE_TEMPLATE            "gimp-file-save-as-template" /* Update string along with 
gimp-help-2 */
 #define GIMP_HELP_FILE_QUIT                       "gimp-file-quit"
 
diff --git a/libgimpbase/gimpbase.def b/libgimpbase/gimpbase.def
index 4832eee..2e4a20b 100644
--- a/libgimpbase/gimpbase.def
+++ b/libgimpbase/gimpbase.def
@@ -35,6 +35,7 @@ EXPORTS
        gimp_escape_uline
        gimp_file_get_utf8_name
        gimp_file_has_extension
+       gimp_file_show_in_file_manager
        gimp_filename_to_utf8
        gimp_fill_type_get_type
        gimp_flags_get_first_desc
diff --git a/libgimpbase/gimputils.c b/libgimpbase/gimputils.c
index e223292..698dfd8 100644
--- a/libgimpbase/gimputils.c
+++ b/libgimpbase/gimputils.c
@@ -313,6 +313,120 @@ gimp_file_has_extension (GFile       *file,
 }
 
 /**
+ * gimp_file_show_in_file_manager:
+ * @file:  a #GFile
+ * @error: return location for a #GError
+ *
+ * Shows @file in the system file manager.
+ *
+ * Since: GIMP 2.10
+ *
+ * Return value: %TRUE on success, %FALSE otherwise. On %FASLE, @error
+ *               is set.
+ **/
+gboolean
+gimp_file_show_in_file_manager (GFile   *file,
+                                GError **error)
+{
+  g_return_val_if_fail (G_IS_FILE (file), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+#if defined(G_OS_WIN32)
+
+  {
+#if 0
+    /* found on stackoverflow, please turn this into working code...
+     */
+    void BrowseToFile(LPCTSTR filename)
+    {
+      ITEMIDLIST *pidl = ILCreateFromPath (filename);
+      if (pidl)
+        {
+          SHOpenFolderAndSelectItems (pidl, 0, 0, 0);
+          ILFree (pidl);
+        }
+    }
+#endif
+
+    g_set_error_literal (error, G_FILE_ERROR, 0,
+                         "Please implement something in "
+                         "gimp_file_show_in_file_manager().");
+    return FALSE;
+  }
+
+#elif defined(PLATFORM_OSX)
+
+  {
+#if 0
+    /* found on stackoverflow, please turn this into working code...
+     */
+    NSArray *fileURLs = [NSArray arrayWithObjects:fileURL1, /* ... */ nil];
+
+    [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:fileURLs];
+#endif
+
+    g_set_error_literal (error, G_FILE_ERROR, 0,
+                         "Please implement something in "
+                         "gimp_file_show_in_file_manager().");
+    return FALSE;
+  }
+
+#else /* UNIX */
+
+  {
+    GDBusProxy      *proxy;
+    GVariant        *retval;
+    GVariantBuilder *builder;
+    gchar           *uri;
+
+    proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                           G_DBUS_PROXY_FLAGS_NONE,
+                                           NULL,
+                                           "org.freedesktop.FileManager1",
+                                           "/org/freedesktop/FileManager1",
+                                           "org.freedesktop.FileManager1",
+                                           NULL, error);
+
+    if (! proxy)
+      {
+        g_prefix_error (error,
+                        _("Connecting to org.freedesktop.FileManager1 failed: "));
+        return FALSE;
+      }
+
+    uri = g_file_get_uri (file);
+
+    builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
+    g_variant_builder_add (builder, "s", uri);
+
+    g_free (uri);
+
+    retval = g_dbus_proxy_call_sync (proxy,
+                                     "ShowItems",
+                                     g_variant_new ("(ass)",
+                                                    builder,
+                                                    ""),
+                                     G_DBUS_CALL_FLAGS_NONE,
+                                     -1, NULL, error);
+
+    g_variant_builder_unref (builder);
+    g_object_unref (proxy);
+
+    if (! retval)
+      {
+        g_prefix_error (error, _("Calling ShowItems failed: "));
+        return FALSE;
+      }
+
+    g_variant_unref (retval);
+
+    return TRUE;
+  }
+
+#endif
+}
+
+/**
  * gimp_strip_uline:
  * @str: underline infested string (or %NULL)
  *
diff --git a/libgimpbase/gimputils.h b/libgimpbase/gimputils.h
index 4af931a..c7cea29 100644
--- a/libgimpbase/gimputils.h
+++ b/libgimpbase/gimputils.h
@@ -26,48 +26,50 @@
 G_BEGIN_DECLS
 
 
-gchar         * gimp_utf8_strtrim            (const gchar  *str,
-                                              gint          max_chars) G_GNUC_MALLOC;
-gchar         * gimp_any_to_utf8             (const gchar  *str,
-                                              gssize        len,
-                                              const gchar  *warning_format,
-                                              ...) G_GNUC_PRINTF (3, 4) G_GNUC_MALLOC;
-const gchar   * gimp_filename_to_utf8        (const gchar  *filename);
+gchar         * gimp_utf8_strtrim              (const gchar  *str,
+                                                gint          max_chars) G_GNUC_MALLOC;
+gchar         * gimp_any_to_utf8               (const gchar  *str,
+                                                gssize        len,
+                                                const gchar  *warning_format,
+                                                ...) G_GNUC_PRINTF (3, 4) G_GNUC_MALLOC;
+const gchar   * gimp_filename_to_utf8          (const gchar  *filename);
 
-const gchar   * gimp_file_get_utf8_name      (GFile        *file);
-gboolean        gimp_file_has_extension      (GFile        *file,
-                                              const gchar  *extension);
+const gchar   * gimp_file_get_utf8_name        (GFile        *file);
+gboolean        gimp_file_has_extension        (GFile        *file,
+                                                const gchar  *extension);
+gboolean        gimp_file_show_in_file_manager (GFile        *file,
+                                                GError      **error);
 
-gchar         * gimp_strip_uline             (const gchar  *str) G_GNUC_MALLOC;
-gchar         * gimp_escape_uline            (const gchar  *str) G_GNUC_MALLOC;
+gchar         * gimp_strip_uline               (const gchar  *str) G_GNUC_MALLOC;
+gchar         * gimp_escape_uline              (const gchar  *str) G_GNUC_MALLOC;
 
-gchar         * gimp_canonicalize_identifier (const gchar  *identifier) G_GNUC_MALLOC;
+gchar         * gimp_canonicalize_identifier   (const gchar  *identifier) G_GNUC_MALLOC;
 
-GimpEnumDesc  * gimp_enum_get_desc           (GEnumClass   *enum_class,
-                                              gint          value);
-gboolean        gimp_enum_get_value          (GType         enum_type,
-                                              gint          value,
-                                              const gchar **value_name,
-                                              const gchar **value_nick,
-                                              const gchar **value_desc,
-                                              const gchar **value_help);
-const gchar   * gimp_enum_value_get_desc     (GEnumClass   *enum_class,
-                                              GEnumValue   *enum_value);
-const gchar   * gimp_enum_value_get_help     (GEnumClass   *enum_class,
-                                              GEnumValue   *enum_value);
+GimpEnumDesc  * gimp_enum_get_desc             (GEnumClass   *enum_class,
+                                                gint          value);
+gboolean        gimp_enum_get_value            (GType         enum_type,
+                                                gint          value,
+                                                const gchar **value_name,
+                                                const gchar **value_nick,
+                                                const gchar **value_desc,
+                                                const gchar **value_help);
+const gchar   * gimp_enum_value_get_desc       (GEnumClass   *enum_class,
+                                                GEnumValue   *enum_value);
+const gchar   * gimp_enum_value_get_help       (GEnumClass   *enum_class,
+                                                GEnumValue   *enum_value);
 
-GimpFlagsDesc * gimp_flags_get_first_desc    (GFlagsClass  *flags_class,
-                                              guint         value);
-gboolean        gimp_flags_get_first_value   (GType         flags_type,
-                                              guint         value,
-                                              const gchar **value_name,
-                                              const gchar **value_nick,
-                                              const gchar **value_desc,
-                                              const gchar **value_help);
-const gchar   * gimp_flags_value_get_desc    (GFlagsClass  *flags_class,
-                                              GFlagsValue  *flags_value);
-const gchar   * gimp_flags_value_get_help    (GFlagsClass  *flags_class,
-                                              GFlagsValue  *flags_value);
+GimpFlagsDesc * gimp_flags_get_first_desc      (GFlagsClass  *flags_class,
+                                                guint         value);
+gboolean        gimp_flags_get_first_value     (GType         flags_type,
+                                                guint         value,
+                                                const gchar **value_name,
+                                                const gchar **value_nick,
+                                                const gchar **value_desc,
+                                                const gchar **value_help);
+const gchar   * gimp_flags_value_get_desc      (GFlagsClass  *flags_class,
+                                                GFlagsValue  *flags_value);
+const gchar   * gimp_flags_value_get_help      (GFlagsClass  *flags_class,
+                                                GFlagsValue  *flags_value);
 
 
 G_END_DECLS
diff --git a/menus/image-menu.xml.in b/menus/image-menu.xml.in
index 72d951a..7af3915 100644
--- a/menus/image-menu.xml.in
+++ b/menus/image-menu.xml.in
@@ -52,7 +52,9 @@
       <separator />
       <placeholder name="Send" />
       <separator />
-      <placeholder name="Info" />
+      <placeholder name="Info">
+       <menuitem action="file-show-in-file-manager" />
+      </placeholder>
       <separator />
       <menuitem action="view-close" />
       <menuitem action="file-close-all" />


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