diff --git a/ChangeLog b/ChangeLog index 0430363..ec482c1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,17 +2,27 @@ Iterim milestones These private versions, the version numbering bumps just denote that a development milestone is achieved +0.8.0 (25 oct 2006): + * INTERNAL: Changed the use of lstat() and realpath() to GnomeVFS versions + * BUGFIX: Resolve realpaths correctly for paths with non-ascii characters + or spaces + * FEATURE: Support for multiple file selections, entries for the symbolic + links in the selected set are added to the context menu + * BUGFIX: Don't use urlencoded urls for the working dir of the spawned + nautilus + * INTERNAL: Use '.' as cwd of the spawned nautilus + 0.7.9 (24 oct 2006): - * Show the symbolic link's name (unresolved) in context menu and + * FEATURE: Show the symbolic link's name (unresolved) in context menu and description 0.7.0 (24 oct 2006): - * Added support for background items (context menu on opened symlinks) + * FEATURE: Added support for background items (context menu on opened symlinks) * BUGFIX: Corrected translation typos * BUGFIX: Corrected includes only working in DEBUG/NON-DEBUG mode 0.6.0 (24 oct 2006): - * Added support for i18n, updated build-dependancies accordingly + * FEATURE: Added support for i18n, updated build-dependancies accordingly 0.5.2 (24 oct 2006): * INTERNAL: Corrected includes and function declarations diff --git a/Makefile.am b/Makefile.am index 7a9b5bf..95198e6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ SUBDIRS = po src # This doesn't work as expected libdir = @libdir@/nautilus/extensions-1.0 -#EXTRA_DIST = dist +EXTRA_DIST = dist po/nautilus-follow-symlink.pot # Extra files to get rid of when distcleaning DISTCLEANFILES = \ diff --git a/configure.in b/configure.in index d8aed15..fd681b4 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,6 @@ AC_INIT(src/follow-symlink.c) -AM_INIT_AUTOMAKE(libnautilus-follow-symlink, "0.7.9") +AM_INIT_AUTOMAKE(libnautilus-follow-symlink, "0.8.0") AC_CONFIG_HEADER(src/config.h) dnl default FLAGS @@ -28,7 +28,7 @@ AM_GLIB_GNU_GETTEXT dnl defines STDC_HEADERS if ANSI-compliant headers are present AC_HEADER_STDC dnl Xref: http://www.seul.org/docs/autotut/#libtool -AC_CHECK_HEADERS(sys/stat.h,,AC_MSG_ERROR([required header file missing])) +#AC_CHECK_HEADERS(sys/stat.h,,AC_MSG_ERROR([required header file missing])) # glib-2.0: ensure it's present dnl and set GLIB_CFLAGS and GLIB_LIBS diff --git a/debian/changelog b/debian/changelog index 9f84514..50c53bd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +nautilus-follow-symlink (0.8.0-out.1) unstable; urgency=low + + * New upstream release + + -- Toni Corvera Wed, 25 Oct 2006 05:03:23 +0200 + nautilus-follow-symlink (0.7.9-out.1) unstable; urgency=low * New upstream release diff --git a/dist b/dist index 20e3a5a..5d08355 100755 --- a/dist +++ b/dist @@ -16,6 +16,25 @@ gen: autoheader automake --add-missing --foreign +help: + @echo "This file is used to aid in the setup of the build" + @echo "environment, there are the following available targets" + @echo "(use ./dist TARGET):" + @echo " gen (default) Create the required structure" + @echo " clean Remove the files created by gen and by the build process" + @echo " update-po Update the language files with new translation or moved " + @echo " string locations (note it also updates the meta-timestamp)" + @echo " so it can get funny issuing this command when using CVS/SVN" + @echo " regen 'clean' then 'gen'" + @echo " help This very message" + + +update-po: + cd po && intltool-update -p + cd po && for file in *.po ; do \ + intltool-update --dist `basename $$file .po` ; \ + done + regen: clean gen clean: diff --git a/po/ca.po b/po/ca.po index c431e32..98dc73e 100644 --- a/po/ca.po +++ b/po/ca.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libnautilus-follow-symlink\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-10-24 22:55+0200\n" +"POT-Creation-Date: 2006-10-25 05:22+0200\n" "PO-Revision-Date: 2006-10-24 22:59+0200\n" "Last-Translator: Toni Corvera \n" "Language-Team: Catalan \n" @@ -15,22 +15,22 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../src/follow-symlink.c:159 +#: ../src/follow-symlink.c:188 #, c-format msgid "Follow symbolic _link '%s'" msgstr "Segueix l'en_llaç simbòlic '%s'" -#: ../src/follow-symlink.c:160 +#: ../src/follow-symlink.c:189 #, c-format msgid "Open the directory pointed by the symbolic link '%s'" msgstr "Obre el directori apuntat per l'enllaç simbòlic '%s'" -#: ../src/follow-symlink.c:169 +#: ../src/follow-symlink.c:198 #, c-format msgid "Open real path of '%s'" msgstr "Obre la ruta real de '%s'" -#: ../src/follow-symlink.c:170 +#: ../src/follow-symlink.c:199 #, c-format msgid "Open the real path of the folder pointed by '%s'" msgstr "Obre el directori apuntat per '%s'" diff --git a/po/es.po b/po/es.po index e1abdcc..b33ca43 100644 --- a/po/es.po +++ b/po/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: libnautilus-follow-symlink\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-10-24 22:55+0200\n" +"POT-Creation-Date: 2006-10-25 05:22+0200\n" "PO-Revision-Date: 2006-10-24 23:00+0200\n" "Last-Translator: Toni Corvera \n" "Language-Team: Spanish \n" @@ -17,23 +17,22 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../src/follow-symlink.c:159 +#: ../src/follow-symlink.c:188 #, c-format msgid "Follow symbolic _link '%s'" msgstr "Seguir en_lace simbólico '%s'" -#: ../src/follow-symlink.c:160 +#: ../src/follow-symlink.c:189 #, c-format msgid "Open the directory pointed by the symbolic link '%s'" -msgstr "" -"Abrir el directorio apuntado por el enlace simbólico '%s'" +msgstr "Abrir el directorio apuntado por el enlace simbólico '%s'" -#: ../src/follow-symlink.c:169 +#: ../src/follow-symlink.c:198 #, c-format msgid "Open real path of '%s'" msgstr "Abrir la ruta real de '%s'" -#: ../src/follow-symlink.c:170 +#: ../src/follow-symlink.c:199 #, c-format msgid "Open the real path of the folder pointed by '%s'" msgstr "Abrir el directoro apuntado por '%s'" diff --git a/po/nautilus-follow-symlink.pot b/po/nautilus-follow-symlink.pot deleted file mode 100644 index 71602b1..0000000 --- a/po/nautilus-follow-symlink.pot +++ /dev/null @@ -1,33 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-10-24 21:27+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../src/follow-symlink.c:156 -msgid "Follow symbolic _link" -msgstr "" - -#: ../src/follow-symlink.c:157 -msgid "Open the directory pointed by the currently selected symbolic link" -msgstr "" - -#: ../src/follow-symlink.c:160 -msgid "Open real path" -msgstr "" - -#: ../src/follow-symlink.c:161 -msgid "Open the real path of the folder pointed by this symbolic link" -msgstr "" diff --git a/src/common.h b/src/common.h index 66364b4..008039b 100644 --- a/src/common.h +++ b/src/common.h @@ -19,8 +19,20 @@ #include "config.h" #endif // HAVE_CONFIG_H -#ifndef __inline__ +#if !defined(__inline) #define __inline +#elif defined(_DEBUG) + #undef __inline + #define __inline +#endif + +#if !defined(__fsl_unused) + // Xref: http://rlove.org/log/2005102601 + #if __GNUC__ >= 3 + #define __fsl_unused __attribute__ ((unused)) + #else + #define __fsl_unused + #endif #endif #ifdef _DEBUG @@ -49,12 +61,14 @@ #define FSL_LOG(str) if (DEBUG_ON_()) g_printf("%s\n", (str)); /* Display a formatted message with one string argument */ #define FSL_LOG1(str1, str2) if (DEBUG_ON_()) g_printf("%s %s\n", (str1), (str2)); + #define FSL_LOG_SPRINTF1(s1, s2) if (DEBUG_ON_()) g_printf((s1), (s2)); #else /* Debugging facilities disabled */ #define TRACE() #define FSL_LOG(a) #define FSL_LOG1(a,b) #define FSL_DEBUG_INIT() + #define FSL_LOG_SPRINTF1(a,b) #endif #endif /* FOLLOW_SYMLINK_COMMON_H */ diff --git a/src/follow-symlink.c b/src/follow-symlink.c index 5f911ad..a3b3ce5 100644 --- a/src/follow-symlink.c +++ b/src/follow-symlink.c @@ -1,7 +1,7 @@ #include "follow-symlink.h" // Offset at char 7 to remove file:// -static const unsigned short URI_OFFSET = 7 * sizeof(gchar); +//static const unsigned short URI_OFFSET = 7 * sizeof(gchar); static const size_t PATH_LENGTH_BYTES = sizeof(gchar) * (PATH_MAX + 1); extern int errno; @@ -21,7 +21,8 @@ void fsl_extension_menu_provider_iface_init(NautilusMenuProviderIface *iface) */ GList * fsl_get_items_impl(GtkWidget * window, NautilusFileInfo * file_info, - gboolean is_file_item) + gboolean is_file_item, + GList * input) { TRACE(); @@ -29,6 +30,7 @@ GList * fsl_get_items_impl(GtkWidget * window, // Only file uris { + // TODO: what about GnomeVFSFileInfo's is_local ? gchar * uri_scheme = nautilus_file_info_get_uri_scheme(file_info); if (strcmp(uri_scheme, "file") != 0) { FSL_LOG( "Not file scheme" ); @@ -39,24 +41,24 @@ GList * fsl_get_items_impl(GtkWidget * window, // We know the file is either a directory or a symlink to a directory // TODO: Has glib/gnome any better/faster alternatives? - { - struct stat file_stat; - // Note ..._get_name doesn't give the full path - const gchar * const file_name = nautilus_file_info_get_uri(file_info) + URI_OFFSET; - lstat(file_name, &file_stat); - if (! S_ISLNK(file_stat.st_mode)) { - FSL_LOG1( "Not S_ISLNK:", file_name ); - return NULL; - } + GnomeVFSFileInfo * gfi = nautilus_file_info_get_vfs_file_info(file_info); + + /* TODO: In which situations might the flags field be invalid? + * Hence, can the older stat version be dumped safely? + */ + g_assert( (gfi->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_FLAGS) > 0 ); + + if ( (gfi->flags & GNOME_VFS_FILE_FLAGS_SYMLINK) == 0 ) { + FSL_LOG1("GnomeVFS Flags: ! SYMLINK: ", nautilus_file_info_get_uri(file_info)); + return NULL; } item = fsl_menu_item_new(gtk_widget_get_screen(window), is_file_item, nautilus_file_info_get_name(file_info)); - g_signal_connect(item, "activate", G_CALLBACK(fsl_callback), - file_info); + g_signal_connect(item, "activate", G_CALLBACK(fsl_callback), file_info); - return g_list_append(NULL, item); + return g_list_append(input, item); } GList * @@ -69,7 +71,20 @@ fsl_get_background_items(NautilusMenuProvider * provider, if (NULL == current_folder) { // XXX: Does this ever happen? FSL_LOG( "No folder selected" ); } - return fsl_get_items_impl(window, current_folder, FALSE); + return fsl_get_items_impl(window, current_folder, FALSE, NULL); +} + + +gboolean file_is_directory (gpointer file_data) +{ + TRACE(); + + /* + * Apparently type is never GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK and symlinks + * are resolved to the target type + */ + const GnomeVFSFileInfo * const gfi = nautilus_file_info_get_vfs_file_info(file_data); + return gfi->type == GNOME_VFS_FILE_TYPE_DIRECTORY; } /* Bind to menu if needed */ @@ -82,24 +97,46 @@ fsl_get_file_items (NautilusMenuProvider * provider, // Number of files = g_list_length(files) // Directory = nautilus_file_info_is_directory(files->data) - - if (NULL==files || g_list_length(files) != 1) { - FSL_LOG( (NULL==files) ? "No file" : "More than one file" ); - return NULL; - } - - GnomeVFSFileInfo * gfi = nautilus_file_info_get_vfs_file_info(files->data); - /* - * Aparently type is never GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK and symlinks - * are resolved to the target type - */ - if (gfi->type != GNOME_VFS_FILE_TYPE_DIRECTORY) { - FSL_LOG( "Not directory" ); + if (NULL == files) { + FSL_LOG("No file selected"); return NULL; } - return fsl_get_items_impl(window, files->data, TRUE); + if (g_list_length(files) == 1) { + if (!file_is_directory(files->data)) { + FSL_LOG("File is not a directory"); + return NULL; + } + return fsl_get_items_impl(window, files->data, TRUE, NULL); + } + + // More than one selected file + assert( g_list_length(files) > 1 ); + + FSL_LOG( "More than one file selected" ); + + GList * items = NULL; + + for (int i=0; i - */ - if (NULL == realpath(link_name, target)) { - g_printf("ERROR in realpath(): %s\n", strerror(errno)); - g_assert( FALSE ); - } + const GnomeVFSFileInfo * gfi = nautilus_file_info_get_vfs_file_info(file_info); + // See /usr/include/gnome-vfs-2.0/libgnomevfs/gnome-vfs-file-info.h, + // this one is the "realpath()" (3), also it isn0t urlencoded + const gchar const * target = gfi->symlink_name; const gchar const * BASE_CMD = "nautilus --no-desktop --no-default-window '%s'"; gchar * command_line = g_malloc( sizeof(gchar) * ( strlen(BASE_CMD) + strlen(target) + 1 ) ); @@ -129,7 +159,12 @@ void fsl_callback (NautilusMenuItem * item, NautilusFileInfo * file_info) g_printf("nautilus-follow-symlink: Spawning nautilus with\n '%s'\n", command_line); - g_spawn_async( nautilus_file_info_get_parent_uri(file_info) + URI_OFFSET, + const gchar * cwd = "."; + // FIXME: const gchar * cwd = nautilus_file_info_get_parent_uri(file_info) + URI_OFFSET; + // TODO: does the cwd used for spawn have any side-effect ? + FSL_LOG_SPRINTF1 ("\tusing pwd=%s\n", cwd ); + + g_spawn_async( cwd, argv, NULL, G_SPAWN_SEARCH_PATH, @@ -138,7 +173,6 @@ void fsl_callback (NautilusMenuItem * item, NautilusFileInfo * file_info) g_free(command_line); g_strfreev(argv); } - /* Create the new menu item */ NautilusMenuItem * fsl_menu_item_new(GdkScreen *screen, gboolean is_file_item, const gchar * base_name) @@ -171,8 +205,16 @@ fsl_menu_item_new(GdkScreen *screen, gboolean is_file_item, const gchar * base_n g_sprintf(tooltip, fmt_tooltip, base_name); } + // Trial and error shows that the menu item name must be different + // when various are to be shown, and also that the name should always be + // the same for a given file + static const gchar * ITEM_NAME_FMT = "FsymlinkExtension::follow_symlink_%s"; + // TODO: Check g_alloca() error conditions + gchar * unique_name = g_alloca(strlen(ITEM_NAME_FMT) + strlen(base_name)); // 10 = strlen("4294967296")); + g_sprintf(unique_name, ITEM_NAME_FMT, base_name); // (name, label, tip, icon) - ret = nautilus_menu_item_new("FsymlinkExtension::follow_symlink", + ret = nautilus_menu_item_new(//"FsymlinkExtension::follow_symlink", + unique_name, name, tooltip, NULL); g_free(name); g_free(tooltip); diff --git a/src/follow-symlink.h b/src/follow-symlink.h index 3612041..a914cc2 100644 --- a/src/follow-symlink.h +++ b/src/follow-symlink.h @@ -11,10 +11,9 @@ #include #include -#include #include /* errno (3) */ -#include /* realpath() (3) */ #include /* strlen(), strerror() (3) */ +#include /* Static Prototypes */ @@ -24,10 +23,12 @@ static GList * fsl_get_file_items(NautilusMenuProvider *, GtkWidget *, GList *); static GList * fsl_get_background_items(NautilusMenuProvider *, GtkWidget *, NautilusFileInfo *); -static GList * fsl_get_items_impl(GtkWidget *, NautilusFileInfo *, gboolean); +static __inline GList * fsl_get_items_impl(GtkWidget *, NautilusFileInfo *, gboolean,GList*); static NautilusMenuItem * fsl_menu_item_new(GdkScreen *, gboolean, const gchar *); +static __inline gboolean file_is_directory(gpointer); + /* Exported Prototypes * Here the namespace is a bit more explicit just in case */