templates patch ...



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



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