Hi there, Quick review appreciated for a patch to support system templates (from) /usr/share/templates in the same way that KDE does: improving cross-desktop interop, and of course improving our (somewhat lame) "Create Document" template stuff - at least making it easy to configure to do something useful by default. I believe in the past people were happy for me to commit to HEAD, but ;-) times and management change etc. I guess. [ Incidentally - if it is more widely used - should it not be one slot higher up than "Add Launcher" in the right-click context menu ? ] I attach the patch, and a few sample test .desktop files I tested it with [ primed for OpenSUSE admittedly, some tweakage necessary for other apps ]. My URI manipulation stuff is shaky no doubt - input appreciated; and I hate to write new code - eg. the OnlyShowIn thing makes me nervous: why is that not pre-existing & sharable ? [ or is it ? :-]. HTH, Michael. -- michael meeks novell com <><, Pseudo Engineer, itinerant idiot
diff -u -r -x Makefile -x '*.o' -x .libs pristine-nautilus-2.22.2/libnautilus-private/nautilus-file-utilities.c nautilus-2.22.2/libnautilus-private/nautilus-file-utilities.c --- pristine-nautilus-2.22.2/libnautilus-private/nautilus-file-utilities.c 2008-03-29 09:40:43.000000000 +0000 +++ nautilus-2.22.2/libnautilus-private/nautilus-file-utilities.c 2008-06-24 20:47:54.000000000 +0100 @@ -491,38 +491,27 @@ char * nautilus_get_home_directory_uri (void) { - return g_filename_to_uri (g_get_home_dir (), NULL, NULL); + return g_filename_to_uri (g_get_home_dir (), NULL, NULL); } - -gboolean -nautilus_should_use_templates_directory (void) +static char * +nautilus_get_templates_directory (void) { char *dir; - gboolean res; dir = nautilus_get_xdg_dir ("TEMPLATES"); - res = strcmp (dir, g_get_home_dir ()) != 0; - g_free (dir); - return res; + if (strcmp (dir, g_get_home_dir ()) != 0) { + return dir; + } else { + g_free (dir); + return NULL; + } } char * -nautilus_get_templates_directory (void) -{ - return nautilus_get_xdg_dir ("TEMPLATES"); -} - -void -nautilus_create_templates_directory (void) +nautilus_get_system_templates_directory_uri (void) { - char *dir; - - dir = nautilus_get_templates_directory (); - if (!g_file_test (dir, G_FILE_TEST_EXISTS)) { - mkdir (dir, DEFAULT_NAUTILUS_DIRECTORY_MODE); - } - g_free (dir); + return g_filename_to_uri (DATADIR "/templates", NULL, NULL); } char * diff -u -r -x Makefile -x '*.o' -x .libs pristine-nautilus-2.22.2/libnautilus-private/nautilus-file-utilities.h nautilus-2.22.2/libnautilus-private/nautilus-file-utilities.h --- pristine-nautilus-2.22.2/libnautilus-private/nautilus-file-utilities.h 2008-03-29 09:40:43.000000000 +0000 +++ nautilus-2.22.2/libnautilus-private/nautilus-file-utilities.h 2008-06-24 20:47:54.000000000 +0100 @@ -53,10 +53,8 @@ char * nautilus_get_gmc_desktop_directory (void); char * nautilus_get_pixmap_directory (void); -gboolean nautilus_should_use_templates_directory (void); -char * nautilus_get_templates_directory (void); char * nautilus_get_templates_directory_uri (void); -void nautilus_create_templates_directory (void); +char * nautilus_get_system_templates_directory_uri (void); char * nautilus_get_searches_directory (void); diff -u -r -x Makefile -x '*.o' -x .libs pristine-nautilus-2.22.2/src/file-manager/fm-directory-view.c nautilus-2.22.2/src/file-manager/fm-directory-view.c --- pristine-nautilus-2.22.2/src/file-manager/fm-directory-view.c 2008-06-24 17:35:53.000000000 +0100 +++ nautilus-2.22.2/src/file-manager/fm-directory-view.c 2008-06-24 21:51:23.000000000 +0100 @@ -39,6 +39,7 @@ #include "libnautilus-private/nautilus-open-with-dialog.h" #include <libgnome/gnome-url.h> +#include <libgnome/gnome-desktop-item.h> #include <eel/eel-mount-operation.h> #include <eel/eel-background.h> #include <eel/eel-glib-extensions.h> @@ -411,7 +412,7 @@ } ScriptLaunchParameters; typedef struct { - NautilusFile *file; + char *src_uri; FMDirectoryView *directory_view; } CreateTemplateParameters; @@ -547,16 +548,14 @@ } static CreateTemplateParameters * -create_template_parameters_new (NautilusFile *file, - FMDirectoryView *directory_view) +create_template_parameters_new (char *src_uri, FMDirectoryView *directory_view) { CreateTemplateParameters *result; result = g_new0 (CreateTemplateParameters, 1); g_object_ref (directory_view); result->directory_view = directory_view; - nautilus_file_ref (file); - result->file = file; + result->src_uri = src_uri; return result; } @@ -565,7 +564,7 @@ create_templates_parameters_free (CreateTemplateParameters *parameters) { g_object_unref (parameters->directory_view); - nautilus_file_unref (parameters->file); + g_free (parameters->src_uri); g_free (parameters); } @@ -1613,12 +1612,14 @@ } static void -add_directory_to_templates_directory_list (FMDirectoryView *view, - NautilusDirectory *directory) +add_uri_to_templates_directory_list (FMDirectoryView *view, const char *directory_uri) { + NautilusDirectory *directory; + directory = nautilus_directory_get_by_uri (directory_uri); add_directory_to_directory_list (view, directory, &view->details->templates_directory_list, G_CALLBACK (templates_added_or_changed_callback)); + nautilus_directory_unref (directory); } static void @@ -1788,13 +1789,6 @@ add_directory_to_scripts_directory_list (view, scripts_directory); nautilus_directory_unref (scripts_directory); - if (nautilus_should_use_templates_directory ()) { - templates_uri = nautilus_get_templates_directory_uri (); - templates_directory = nautilus_directory_get_by_uri (templates_uri); - g_free (templates_uri); - add_directory_to_templates_directory_list (view, templates_directory); - nautilus_directory_unref (templates_directory); - } update_templates_directory (view); g_signal_connect_object (nautilus_signaller_get_current (), "user_dirs_changed", @@ -3916,14 +3910,13 @@ new_folder_done, data); } -void -fm_directory_view_new_file (FMDirectoryView *directory_view, - const char *parent_uri, - NautilusFile *source) +static void +fm_directory_view_new_file_from_uri (FMDirectoryView *directory_view, + const char *parent_uri, + const char *source_uri) { GdkPoint *pos; NewFolderData *data; - char *source_uri; char *container_uri; container_uri = NULL; @@ -3932,7 +3925,7 @@ g_assert (container_uri != NULL); } - if (source == NULL) { + if (source_uri == NULL) { fm_directory_view_new_file_with_initial_contents (directory_view, parent_uri != NULL ? parent_uri : container_uri, NULL, @@ -3941,23 +3934,35 @@ return; } - g_return_if_fail (nautilus_file_is_local (source)); +/* g_return_if_fail (nautilus_file_is_local (source_uri)); FIXME - only local ? */ pos = context_menu_to_file_operation_position (directory_view); - data = setup_new_folder_data (directory_view); - source_uri = nautilus_file_get_uri (source); - nautilus_file_operations_new_file_from_template (GTK_WIDGET (directory_view), pos, parent_uri != NULL ? parent_uri : container_uri, NULL, source_uri, new_folder_done, data); + g_free (container_uri); +} + +void +fm_directory_view_new_file (FMDirectoryView *directory_view, + const char *parent_uri, + NautilusFile *source) +{ + char *source_uri = NULL; + + if (source != NULL) { + g_return_if_fail (nautilus_file_is_local (source)); + source_uri = nautilus_file_get_uri (source); + } + + fm_directory_view_new_file_from_uri (directory_view, parent_uri, source_uri); g_free (source_uri); - g_free (container_uri); } /* handle the open command */ @@ -5125,16 +5130,71 @@ parameters = callback_data; - fm_directory_view_new_file (parameters->directory_view, NULL, parameters->file); + fm_directory_view_new_file_from_uri (parameters->directory_view, NULL, + parameters->src_uri); } -static void +/* + * Determine the true source of a .desktop template file at + * a given URI - is it really a link to another document we + * should copy; or is it some strange KDE device .desktop + * file ? cf. libkonq/knewmenu.cc + */ +static char * +get_template_source_if_valid (const char *uri, NautilusFile *file) +{ + char *src_file = NULL; + const char *only_show_in; + GnomeDesktopItem *desktop_file; + + desktop_file = gnome_desktop_item_new_from_uri (uri, GNOME_DESKTOP_ITEM_LOAD_ONLY_IF_EXISTS, NULL); + if (!desktop_file) { + g_warning ("Invalid .desktop file '%s'", uri); + return NULL; + } + + only_show_in = gnome_desktop_item_get_string (desktop_file, + GNOME_DESKTOP_ITEM_ONLY_SHOW_IN); + if (!only_show_in || strstr (only_show_in, "GNOME")) { + const char *type; + type = gnome_desktop_item_get_string (desktop_file, GNOME_DESKTOP_ITEM_TYPE); + if (!g_strcasecmp (type, "Link")) { + /* copy the link target not ourselves */ + const char *url_prop; + url_prop = gnome_desktop_item_get_string (desktop_file, + GNOME_DESKTOP_ITEM_URL); + if (url_prop) { + if (!strstr (url_prop, "://")) { /* local path */ + if (url_prop[0] == '/') + src_file = g_filename_to_uri (url_prop, NULL, NULL); + else { /* relative path */ + char * parent_uri; + parent_uri = nautilus_file_get_parent_uri (file); + src_file = g_strconcat (parent_uri, "/", url_prop, NULL); + g_free (parent_uri); + } + } else { + src_file = g_strdup (url_prop); + } + } + } + if (src_file == NULL) { + src_file = g_strdup (uri); + } + } + gnome_desktop_item_unref (desktop_file); + + return src_file; +} + +static gboolean add_template_to_templates_menus (FMDirectoryView *directory_view, NautilusFile *file, const char *menu_path, const char *popup_bg_path) { char *tip, *uri, *name; + char *src_uri; char *dot, *escaped_label; GdkPixbuf *pixbuf; char *action_name; @@ -5142,21 +5202,33 @@ GtkUIManager *ui_manager; GtkAction *action; - name = nautilus_file_get_display_name (file); uri = nautilus_file_get_uri (file); - tip = g_strdup_printf (_("Create Document from template \"%s\""), name); - /* Remove extension */ + /* Remove display name extension */ dot = strrchr (name, '.'); if (dot != NULL) { *dot = 0; } + /* find uri extension */ + dot = strrchr (uri, '.'); + if (dot != NULL && !g_strcasecmp (dot + 1, "desktop")) { + src_uri = get_template_source_if_valid (uri, file); + if (!src_uri) { /* filtered */ + g_free (uri); + g_free (name); + return FALSE; + } + } else { + src_uri = g_strdup (uri); + } + + tip = g_strdup_printf (_("Create Document from template \"%s\""), name); action_name = escape_action_name (uri, "template_"); escaped_label = eel_str_double_underscores (name); - parameters = create_template_parameters_new (file, directory_view); + parameters = create_template_parameters_new (src_uri, directory_view); action = gtk_action_new (action_name, escaped_label, @@ -5202,6 +5274,8 @@ g_free (tip); g_free (uri); g_free (action_name); + + return TRUE; } static void @@ -5209,19 +5283,23 @@ { NautilusDirectory *templates_directory; GList *node, *next; - char *templates_uri; + char *templates_uri, *system_templates_uri; for (node = view->details->templates_directory_list; node != NULL; node = next) { next = node->next; remove_directory_from_templates_directory_list (view, node->data); } - if (nautilus_should_use_templates_directory ()) { - templates_uri = nautilus_get_templates_directory_uri (); - templates_directory = nautilus_directory_get_by_uri (templates_uri); + templates_uri = nautilus_get_templates_directory_uri (); + if (templates_uri != NULL) { + add_uri_to_templates_directory_list (view, templates_uri); g_free (templates_uri); - add_directory_to_templates_directory_list (view, templates_directory); - nautilus_directory_unref (templates_directory); + } + + system_templates_uri = nautilus_get_system_templates_directory_uri (); + if (system_templates_uri != NULL) { + add_uri_to_templates_directory_list (view, system_templates_uri); + g_free (system_templates_uri); } } @@ -5234,22 +5312,24 @@ } static gboolean -directory_belongs_in_templates_menu (const char *templates_directory_uri, - const char *uri) +directory_belongs_in_templates_menu (char **valid_roots, + const char *uri, + char **sub_path) { int num_levels; int i; + const char *prefix = NULL; - if (templates_directory_uri == NULL) { - return FALSE; + for (i = 0; (prefix = valid_roots[i]) != NULL; i++) { + if (g_str_has_prefix (uri, prefix)) + break; } - - if (!g_str_has_prefix (uri, templates_directory_uri)) { + if (!prefix) { return FALSE; } num_levels = 0; - for (i = strlen (templates_directory_uri); uri[i] != '\0'; i++) { + for (i = strlen (prefix); uri[i] != '\0'; i++) { if (uri[i] == '/') { num_levels++; } @@ -5259,29 +5339,31 @@ return FALSE; } + if (sub_path != NULL) { + *sub_path = g_strdup (uri + strlen (prefix)); + } + return TRUE; } static gboolean update_directory_in_templates_menu (FMDirectoryView *view, - const char *templates_directory_uri, + char **valid_roots, + const char *sub_path, NautilusDirectory *directory) { char *menu_path, *popup_bg_path; GList *file_list, *filtered, *node; gboolean any_templates; NautilusFile *file; - NautilusDirectory *dir; char *escaped_path; char *uri; int num; /* We know this directory belongs to the template dir, so it must exist */ - g_assert (templates_directory_uri); - - uri = nautilus_directory_get_uri (directory); - escaped_path = escape_action_path (uri + strlen (templates_directory_uri)); - g_free (uri); + g_assert (valid_roots); + + escaped_path = escape_action_path (sub_path); menu_path = g_strconcat (FM_DIRECTORY_VIEW_MENU_PATH_NEW_DOCUMENTS_PLACEHOLDER, escaped_path, NULL); @@ -5303,10 +5385,8 @@ if (nautilus_file_is_directory (file)) { uri = nautilus_file_get_uri (file); - if (directory_belongs_in_templates_menu (templates_directory_uri, uri)) { - dir = nautilus_directory_get_by_uri (uri); - add_directory_to_templates_directory_list (view, dir); - nautilus_directory_unref (dir); + if (directory_belongs_in_templates_menu (valid_roots, uri, NULL)) { + add_uri_to_templates_directory_list (view, uri); add_submenu_to_directory_menus (view, view->details->templates_action_group, @@ -5317,8 +5397,7 @@ } g_free (uri); } else if (nautilus_file_can_read (file)) { - add_template_to_templates_menus (view, file, menu_path, popup_bg_path); - any_templates = TRUE; + any_templates |= add_template_to_templates_menus (view, file, menu_path, popup_bg_path); } } @@ -5331,7 +5410,6 @@ } - static void update_templates_menu (FMDirectoryView *view) { @@ -5341,13 +5419,12 @@ GtkUIManager *ui_manager; char *uri; GtkAction *action; - char *templates_directory_uri; + char *valid_roots[3]; - if (nautilus_should_use_templates_directory ()) { - templates_directory_uri = nautilus_get_templates_directory_uri (); - } else { - templates_directory_uri = NULL; - } + valid_roots[0] = nautilus_get_system_templates_directory_uri (); + g_assert (valid_roots[0] != NULL); + valid_roots[1] = nautilus_get_templates_directory_uri (); + valid_roots[2] = NULL; /* There is a race condition here. If we don't mark the scripts menu as valid before we begin our task then we can lose template menu updates that @@ -5369,16 +5446,17 @@ sorted_copy = nautilus_directory_list_sort_by_uri (nautilus_directory_list_copy (view->details->templates_directory_list)); for (node = sorted_copy; node != NULL; node = node->next) { + char *sub_path = NULL; directory = node->data; uri = nautilus_directory_get_uri (directory); - if (!directory_belongs_in_templates_menu (templates_directory_uri, uri)) { + if (!directory_belongs_in_templates_menu (valid_roots, uri, &sub_path)) { remove_directory_from_templates_directory_list (view, directory); - } else if (update_directory_in_templates_menu (view, - templates_directory_uri, - directory)) { + } else if (update_directory_in_templates_menu (view, valid_roots, + sub_path, directory)) { any_templates = TRUE; } + g_free (sub_path); g_free (uri); } nautilus_directory_list_free (sorted_copy); @@ -5386,7 +5464,8 @@ action = gtk_action_group_get_action (view->details->dir_action_group, FM_ACTION_NO_TEMPLATES); gtk_action_set_visible (action, !any_templates); - g_free (templates_directory_uri); + g_free (valid_roots[0]); + g_free (valid_roots[1]); } diff -u -r -x Makefile -x '*.o' -x .libs pristine-nautilus-2.22.2/src/file-manager/fm-directory-view.c.orig nautilus-2.22.2/src/file-manager/fm-directory-view.c.orig --- pristine-nautilus-2.22.2/src/file-manager/fm-directory-view.c.orig 2008-04-04 15:53:15.000000000 +0100 +++ nautilus-2.22.2/src/file-manager/fm-directory-view.c.orig 2008-06-24 17:35:53.000000000 +0100 @@ -7347,6 +7347,12 @@ { g_assert (FM_IS_DIRECTORY_VIEW (view)); + if (eel_preferences_get_boolean (NAUTILUS_LOCKDOWN_DISABLE_CONTEXT_MENUS)) { + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_LOCKDOWN, + "Ignoring request to pop up the context menu for the view's selection"); + return; + } + /* Make the context menu items not flash as they update to proper disabled, * etc. states by forcing menus to update now. */ @@ -7376,6 +7382,12 @@ { g_assert (FM_IS_DIRECTORY_VIEW (view)); + if (eel_preferences_get_boolean (NAUTILUS_LOCKDOWN_DISABLE_CONTEXT_MENUS)) { + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_LOCKDOWN, + "Ignoring request to pop up the context menu for the view's background"); + return; + } + /* Make the context menu items not flash as they update to proper disabled, * etc. states by forcing menus to update now. */ @@ -7404,6 +7416,12 @@ { g_assert (FM_IS_DIRECTORY_VIEW (view)); + if (eel_preferences_get_boolean (NAUTILUS_LOCKDOWN_DISABLE_CONTEXT_MENUS)) { + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_LOCKDOWN, + "Ignoring request to pop up the context menu for the view"); + return; + } + /* always update the menu before showing it. Shouldn't be too expensive. */ real_update_location_menu (view); diff -u -r -x Makefile -x '*.o' -x .libs pristine-nautilus-2.22.2/src/nautilus-window-menus.c nautilus-2.22.2/src/nautilus-window-menus.c --- pristine-nautilus-2.22.2/src/nautilus-window-menus.c 2008-03-29 09:40:25.000000000 +0000 +++ nautilus-2.22.2/src/nautilus-window-menus.c 2008-06-24 20:59:40.000000000 +0100 @@ -283,12 +283,12 @@ action_go_to_templates_callback (GtkAction *action, gpointer user_data) { - char *path; + char *uri; GFile *location; - path = nautilus_get_templates_directory (); - location = g_file_new_for_path (path); - g_free (path); + uri = nautilus_get_templates_directory_uri (); + location = g_file_new_for_uri (uri); + g_free (uri); nautilus_window_go_to (NAUTILUS_WINDOW (user_data), location); g_object_unref (location);
Attachment:
GnomeOnlyRelative.desktop
Description: application/desktop
Attachment:
OnlyKDE.desktop
Description: application/desktop
Attachment:
Path.desktop
Description: application/desktop
Attachment:
URL.desktop
Description: application/desktop