[easytag] Add Nautilus actions extension



commit 145685dbdc6c5ab6654600b908c272a3829863bb
Author: Victor A. Santos <victoraur santos gmail com>
Date:   Wed Jun 11 13:01:56 2014 -0300

    Add Nautilus actions extension
    
    Include a context menu item for opening directories, and one for opening
    supported files, in a Nautilus extension.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=731493

 Makefile.am                           |   25 +++
 configure.ac                          |   29 +++
 nautilus-extension/easytag-module.c   |   42 +++++
 nautilus-extension/nautilus-easytag.c |  302 +++++++++++++++++++++++++++++++++
 nautilus-extension/nautilus-easytag.h |   48 +++++
 po/POTFILES.in                        |    1 +
 6 files changed, 447 insertions(+), 0 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 1f58f47..33cbab7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -154,6 +154,31 @@ easytag-win32-installer.nsi: easytag-win32-installer.nsi.in Makefile
                -e "s|\ PACKAGE_VERSION\@|$(PACKAGE_VERSION)|" \
                -e "s|\ PREFIX\@|$(prefix)|" $< > $@
 
+if ENABLE_NAUTILUS_ACTIONS
+nautilus_extensiondir = $(NAUTILUS_EXTENSION_DIR)
+
+nautilus_extension_LTLIBRARIES = \
+       libnautilus-easytag.la
+
+libnautilus_easytag_la_SOURCES = \
+       nautilus-extension/easytag-module.c \
+       nautilus-extension/nautilus-easytag.c \
+       nautilus-extension/nautilus-easytag.h
+
+libnautilus_easytag_la_CPPFLAGS = \
+       -I$(top_srcdir) \
+       -I$(top_builddir) \
+       $(DEPRECATED_CPPFLAGS) \
+       -DLOCALEDIR=\"$(localedir)\" \
+       $(NAUTILUS_CFLAGS)
+
+libnautilus_easytag_la_LDFLAGS = \
+       -module -avoid-version -no-undefined
+
+libnautilus_easytag_la_LIBADD = \
+       $(NAUTILUS_LIBS)
+endif
+
 # Create a directory stamp in the build dir. Used to workaround the case where
 # a pattern rule is used for a target with a path that does not ordinarily
 # exist in the build dir.
diff --git a/configure.ac b/configure.ac
index 535cebf..847bc15 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,6 +19,12 @@ AM_MAINTAINER_MODE([enable])
 AM_SILENT_RULES([yes])
 
 dnl -------------------------------
+dnl Init Libtool
+dnl -------------------------------
+LT_PREREQ([2.2])
+LT_INIT([disable-static])
+
+dnl -------------------------------
 dnl Translation files.
 dnl -------------------------------
 IT_PROG_INTLTOOL([0.50.0])
@@ -136,6 +142,10 @@ AC_ARG_ENABLE([mp4],
 AC_ARG_ENABLE([wavpack],
               [AS_HELP_STRING([--disable-wavpack], [Disable support for Wavpack files (default=auto)])])
 
+AC_ARG_ENABLE([nautilus_actions],
+              [AS_HELP_STRING([--disable-nautilus-actions], [do not build the nautilus context menu actions 
(default=auto)])])
+
+
 
 dnl -------------------------------
 dnl Checks for libraries.
@@ -288,6 +298,24 @@ AS_IF([test "x$have_wavpack" != "xno"],
        AS_IF([test "x$enable_wavpack" = "xyes"],
              [AC_MSG_ERROR([Wavpack support requested but required dependencies ($WAVPACK_DEPS) not 
found])])])
 
+dnl ################################################
+dnl # Nautilus
+dnl ################################################
+NAUTILUS_DEPS="libnautilus-extension gio-unix-2.0"
+AS_IF([test "x$enable_nautilus_actions" != "xno"],
+      [PKG_CHECK_EXISTS([$NAUTILUS_DEPS], [have_libnautilus_extension=yes], 
[have_libnautilus_extension=no])],
+      [have_libnautilus_extension=no])
+
+AS_IF([test "x$have_libnautilus_extension" = "xno"],
+      [NAUTILUS_DEPS=""
+       AS_IF([test "x$enable_nautilus_actions" = "xyes"],
+             [AC_MSG_ERROR([Nautilus Actions build requested but required dependencies ($NAUTILUS_DEPS) not 
found])])],
+      [PKG_CHECK_MODULES([NAUTILUS], [$NAUTILUS_DEPS])
+       NAUTILUS_EXTENSION_DIR=`$PKG_CONFIG --variable=extensiondir libnautilus-extension`
+       AC_SUBST([NAUTILUS_EXTENSION_DIR], [$NAUTILUS_EXTENSION_DIR])])
+
+AM_CONDITIONAL([ENABLE_NAUTILUS_ACTIONS], [test x"$have_libnautilus_extension" != x"no"])
+
 dnl Check the pkg-config dependencies
 GIO_DEPS="gio-2.0 >= 2.32.0" dnl For g_file_new_tmp()
 PKG_CHECK_MODULES([EASYTAG], [$GIO_DEPS $GTK_DEPS $OPUS_DEPS $OGG_DEPS $SPEEX_DEPS $FLAC_DEPS $ID3TAG_DEPS 
$TAGLIB_DEPS $WAVPACK_DEPS])
@@ -394,6 +422,7 @@ echo FLAC file support .......: $have_flac
 echo MP4 file support ........: $have_taglib
 echo WavPack support .........: $have_wavpack
 echo NLS/gettext .............: $USE_NLS
+echo Nautilus actions ........: $have_libnautilus_extension
 echo Tests during make check .: $testing_utilities
 echo Install prefix ..........: $prefix
 echo 
diff --git a/nautilus-extension/easytag-module.c b/nautilus-extension/easytag-module.c
new file mode 100644
index 0000000..15c82a1
--- /dev/null
+++ b/nautilus-extension/easytag-module.c
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (C) 2014 Victor A. Santos <victoraur santos gmail com>
+ *
+ *  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 3 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/>.
+ */
+
+#include <libnautilus-extension/nautilus-extension-types.h>
+#include <libnautilus-extension/nautilus-column-provider.h>
+#include "nautilus-easytag.h"
+
+void
+nautilus_module_initialize (GTypeModule *module)
+{
+    nautilus_easytag_register_type (module);
+}
+
+void
+nautilus_module_shutdown (void)
+{
+}
+
+void
+nautilus_module_list_types (const GType **types,
+                            int *num_types)
+{
+    static GType type_list[1];
+  
+    type_list[0] = NAUTILUS_TYPE_EASYTAG;
+    *types = type_list;
+    *num_types = 1;
+}
diff --git a/nautilus-extension/nautilus-easytag.c b/nautilus-extension/nautilus-easytag.c
new file mode 100644
index 0000000..0583613
--- /dev/null
+++ b/nautilus-extension/nautilus-easytag.c
@@ -0,0 +1,302 @@
+/*
+ *  Copyright (C) 2014 Victor A. Santos <victoraur santos gmail com>
+ *
+ *  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 3 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/>.
+ */
+
+#include "config.h"
+
+#include "nautilus-easytag.h"
+
+#include <string.h>
+#include <gio/gio.h>
+#include <gio/gdesktopappinfo.h>
+#include <glib/gi18n-lib.h>
+#include <libnautilus-extension/nautilus-extension-types.h>
+#include <libnautilus-extension/nautilus-file-info.h>
+#include <libnautilus-extension/nautilus-menu-provider.h>
+
+static GObjectClass *parent_class;
+
+void
+on_open_in_easytag (NautilusMenuItem *item,
+                    gpointer data)
+{
+    NautilusFileInfo    *dir;
+    GList               *uris = NULL;
+    GdkDisplay          *display = gdk_display_get_default ();
+    GDesktopAppInfo     *appinfo;
+    GdkAppLaunchContext *context;
+
+    dir = g_object_get_data (G_OBJECT (item), "dir");
+
+    appinfo = g_desktop_app_info_new ("easytag.desktop");
+
+    if (appinfo)
+    {
+        uris = g_list_append (uris, nautilus_file_info_get_uri (dir));
+
+        context = gdk_display_get_app_launch_context (display);
+
+        g_app_info_launch_uris (G_APP_INFO (appinfo), uris,
+                                G_APP_LAUNCH_CONTEXT (context), NULL);
+    }
+}
+
+void
+on_open_with_easytag (NautilusMenuItem *item,
+                      gpointer data)
+{
+    GList               *files, *scan;
+    GList               *uris = NULL;
+    GdkDisplay          *display = gdk_display_get_default ();
+    GDesktopAppInfo     *appinfo;
+    GdkAppLaunchContext *context;
+
+    files = g_object_get_data (G_OBJECT (item), "files");
+
+    appinfo = g_desktop_app_info_new ("easytag.desktop");
+
+    if (appinfo)
+    {
+        for (scan = files; scan; scan = scan->next)
+        {
+            uris = g_list_append (uris,
+                                  nautilus_file_info_get_uri (scan->data));
+        }
+
+        context = gdk_display_get_app_launch_context (display);
+
+        g_app_info_launch_uris (G_APP_INFO (appinfo), uris,
+                                G_APP_LAUNCH_CONTEXT (context), NULL);
+    }
+}
+
+static struct
+{
+    gchar *mime_type;
+    gboolean is_directory;
+    gboolean is_file;
+} easytag_mime_types[] =
+{
+    { "inode/directory", TRUE, FALSE },
+    { "audio/x-mp3", FALSE, TRUE },
+    { "audio/x-mpeg", FALSE, TRUE },
+    { "audio/mpeg", FALSE, TRUE },
+    { "application/ogg", FALSE, TRUE },
+    { "audio/x-vorbis+ogg", FALSE, TRUE },
+    { "audio/x-flac", FALSE, TRUE },
+    { "audio/x-musepack", FALSE, TRUE },
+    { "audio/x-ape", FALSE, TRUE },
+    { "audio/x-speex+ogg", FALSE, TRUE },
+    { "audio/x-opus+ogg", FALSE, TRUE },
+    { NULL, FALSE }
+};
+
+typedef struct
+{
+    gboolean is_directory;
+    gboolean is_file;
+} FileMimeInfo;
+
+static FileMimeInfo
+get_file_mime_info (NautilusFileInfo *file)
+{
+    FileMimeInfo file_mime_info;
+    gsize i;
+
+    file_mime_info.is_directory = FALSE;
+    file_mime_info.is_file = FALSE;
+
+    for (i = 0; easytag_mime_types[i].mime_type != NULL; i++)
+    {
+        if (nautilus_file_info_is_mime_type (file,
+                                             easytag_mime_types[i].mime_type))
+        {
+            file_mime_info.is_directory = easytag_mime_types[i].is_directory;
+            file_mime_info.is_file = easytag_mime_types[i].is_file;
+
+            return file_mime_info;
+        }
+    }
+
+    return file_mime_info;
+}
+
+static gboolean
+unsupported_scheme (NautilusFileInfo *file)
+{
+    gboolean result = FALSE;
+    GFile *location;
+    gchar *scheme;
+
+    location = nautilus_file_info_get_location (file);
+    scheme = g_file_get_uri_scheme (location);
+
+    if (scheme != NULL)
+    {
+        const gchar *unsupported[] = { "trash", "computer", NULL };
+        gsize i;
+
+        for (i = 0; unsupported[i] != NULL; i++)
+        {
+            if (strcmp (scheme, unsupported[i]) == 0)
+            {
+                result = TRUE;
+            }
+        }
+    }
+
+    g_free (scheme);
+    g_object_unref (location);
+
+    return result;
+}
+
+static GList *
+nautilus_easytag_get_file_items (NautilusMenuProvider *provider,
+                                 GtkWidget *window,
+                                 GList *files)
+{
+    GList *items = NULL;
+    GList *scan;
+    gboolean one_item;
+    gboolean  one_directory = TRUE;
+    gboolean  all_files = TRUE;
+
+    if (files == NULL)
+    {
+        return NULL;
+    }
+
+    if (unsupported_scheme ((NautilusFileInfo *)files->data))
+    {
+        return NULL;
+    }
+
+    for (scan = files; scan; scan = scan->next)
+    {
+        NautilusFileInfo *file = scan->data;
+        FileMimeInfo file_mime_info;
+
+        file_mime_info = get_file_mime_info (file);
+
+        if (all_files && !file_mime_info.is_file)
+        {
+            all_files = FALSE;
+        }
+
+        if (one_directory && !file_mime_info.is_directory)
+        {
+            one_directory = FALSE;
+        }
+    }
+
+    one_item = (files != NULL) && (files->next == NULL);
+
+    if (one_directory && one_item)
+    {
+        NautilusMenuItem *item;
+
+        item = nautilus_menu_item_new ("NautilusEasyTag::open_directory",
+                                       _("Open in EasyTAG"),
+                                       _("Open the current selected directory in EasyTAG"),
+                                       "easytag");
+        g_signal_connect (item,
+                          "activate",
+                          G_CALLBACK (on_open_in_easytag),
+                          provider);
+        g_object_set_data (G_OBJECT (item),
+                           "dir",
+                           files->data);
+
+        items = g_list_append (items, item);
+    }
+    else if (all_files)
+    {
+        NautilusMenuItem *item;
+
+        item = nautilus_menu_item_new ("NautilusEasyTag::open_files",
+                                       _("Open with EasyTAG"),
+                                       _("Open selected files in EasyTAG"),
+                                       "easytag");
+        g_signal_connect (item,
+                          "activate",
+                          G_CALLBACK (on_open_with_easytag),
+                          provider);
+        g_object_set_data_full (G_OBJECT (item),
+                                "files",
+                                nautilus_file_info_list_copy (files),
+                                (GDestroyNotify) nautilus_file_info_list_free);
+
+        items = g_list_append (items, item);
+    }
+
+    return items;
+}
+
+static void
+nautilus_easytag_menu_provider_iface_init (NautilusMenuProviderIface *iface)
+{
+    iface->get_file_items = nautilus_easytag_get_file_items;
+}
+
+static void
+nautilus_easytag_instance_init (NautilusEasyTag *fr)
+{
+}
+
+static void
+nautilus_easytag_class_init (NautilusEasyTagClass *class)
+{
+    parent_class = g_type_class_peek_parent (class);
+}
+
+GType easytag_type = 0;
+
+GType nautilus_easytag_get_type ()
+{
+    return easytag_type;
+}
+
+void nautilus_easytag_register_type (GTypeModule *module)
+{
+    static const GTypeInfo info = {
+        sizeof (NautilusEasyTagClass),
+        (GBaseInitFunc) NULL,
+        (GBaseFinalizeFunc) NULL,
+        (GClassInitFunc) nautilus_easytag_class_init,
+        NULL,
+        NULL,
+        sizeof (NautilusEasyTag),
+        0,
+        (GInstanceInitFunc) nautilus_easytag_instance_init,
+    };
+
+    static const GInterfaceInfo menu_provider_iface_info = {
+        (GInterfaceInitFunc) nautilus_easytag_menu_provider_iface_init,
+        NULL,
+        NULL
+    };
+
+    easytag_type = g_type_module_register_type (module,
+                                                G_TYPE_OBJECT,
+                                                "NautilusEasyTag",
+                                                &info, 0);
+
+    g_type_module_add_interface (module,
+                                 easytag_type,
+                                 NAUTILUS_TYPE_MENU_PROVIDER,
+                                 &menu_provider_iface_info);
+}
diff --git a/nautilus-extension/nautilus-easytag.h b/nautilus-extension/nautilus-easytag.h
new file mode 100644
index 0000000..8200619
--- /dev/null
+++ b/nautilus-extension/nautilus-easytag.h
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (C) 2014 Victor A. Santos <victoraur santos gmail com>
+ *
+ *  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 3 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 NAUTILUS_EASYTAG_H_
+#define NAUTILUS_EASYTAG_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_EASYTAG (nautilus_easytag_get_type ())
+#define NAUTILUS_EASYTAG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NAUTILUS_TYPE_EASYTAG, NautilusEasyTag))
+#define NAUTILUS_IS_EASYTAG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NAUTILUS_TYPE_EASYTAG))
+
+typedef struct _NautilusEasyTag NautilusEasyTag;
+typedef struct _NautilusEasyTagClass NautilusEasyTagClass;
+
+struct _NautilusEasyTag
+{
+    GObject parent;
+};
+
+struct _NautilusEasyTagClass
+{
+    GObjectClass parent_class;
+};
+
+GType nautilus_easytag_get_type (void);
+void  nautilus_easytag_register_type (GTypeModule *module);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_EASYTAG_H_ */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 90110cd..7e82b97 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,5 +1,6 @@
 data/easytag.appdata.xml.in
 data/easytag.desktop.in
+nautilus-extension/nautilus-easytag.c
 src/about.c
 src/ape_tag.c
 src/application.c


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