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