summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--NEWS5
-rw-r--r--configure.in2
-rw-r--r--libnautilus-private/nautilus-file-utilities.c298
-rw-r--r--libnautilus-private/nautilus-file-utilities.h2
-rw-r--r--libnautilus-private/nautilus-file.c1
-rw-r--r--libnautilus-private/nautilus-signaller.c9
-rw-r--r--src/file-manager/fm-directory-view.c103
8 files changed, 394 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 4af0969fd..1e428c8e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-03-12 Alexander Larsson <alexl@redhat.com>
+
+ * NEWS:
+ Update for release
+
+ * configure.in:
+ Bump version to 2.18.0
+
2007-03-08 Christian Kirbach <Christian.Kirbach@googlemail.com>
* src/network-scheme.desktop.in:
diff --git a/NEWS b/NEWS
index acc26b5e5..088cb57a1 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Major changes in 2.18.0 are:
+* Fix up desktop file categories
+* Some sparse code cleanups
+* Don't make filename column expand
+
Major changes in 2.17.92 are:
* Don't display homedir as "desktop" in pathbar when in home-as-desktop mode
* Use GtkLabel ellipsizing
diff --git a/configure.in b/configure.in
index 7c009c709..47147d645 100644
--- a/configure.in
+++ b/configure.in
@@ -28,7 +28,7 @@ dnl Interface break is not allowed.
m4_define(nautilus_extension_current, 2)
m4_define(nautilus_extension_revision, 0)
-AC_INIT(nautilus, 2.17.93,
+AC_INIT(nautilus, 2.18.0,
[http://bugzilla.gnome.org/enter_bug.cgi?product=nautilus])
dnl ===========================================================================
diff --git a/libnautilus-private/nautilus-file-utilities.c b/libnautilus-private/nautilus-file-utilities.c
index 0473b16e0..ec795281a 100644
--- a/libnautilus-private/nautilus-file-utilities.c
+++ b/libnautilus-private/nautilus-file-utilities.c
@@ -31,6 +31,7 @@
#include "nautilus-metafile.h"
#include "nautilus-file.h"
#include "nautilus-search-directory.h"
+#include "nautilus-signaller.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-string.h>
#include <eel/eel-vfs-extensions.h>
@@ -49,6 +50,10 @@
#define LEGACY_DESKTOP_DIRECTORY_NAME ".gnome-desktop"
#define DEFAULT_DESKTOP_DIRECTORY_MODE (0755)
+static void update_xdg_dir_cache (void);
+static void schedule_user_dirs_changed (void);
+static void desktop_dir_changed (void);
+
char *
nautilus_compute_title_for_uri (const char *text_uri)
@@ -148,15 +153,280 @@ nautilus_get_user_directory (void)
return user_directory;
}
+typedef struct {
+ char *type;
+ char *path;
+ NautilusFile *file;
+} XdgDirEntry;
+
+
+static XdgDirEntry *
+parse_xdg_dirs (const char *config_file)
+{
+ GArray *array;
+ char *config_file_free = NULL;
+ XdgDirEntry dir;
+ char *data;
+ char **lines;
+ char *p, *d;
+ int i;
+ char *type_start, *type_end;
+ char *value, *unescaped;
+ gboolean relative;
+
+ array = g_array_new (TRUE, TRUE, sizeof (XdgDirEntry));
+
+ if (config_file == NULL)
+ {
+ config_file_free = g_build_filename (g_get_user_config_dir (),
+ "user-dirs.dirs", NULL);
+ config_file = (const char *)config_file_free;
+ }
+
+ if (g_file_get_contents (config_file, &data, NULL, NULL))
+ {
+ lines = g_strsplit (data, "\n", 0);
+ g_free (data);
+ for (i = 0; lines[i] != NULL; i++)
+ {
+ p = lines[i];
+ while (g_ascii_isspace (*p))
+ p++;
+
+ if (*p == '#')
+ continue;
+
+ value = strchr (p, '=');
+ if (value == NULL)
+ continue;
+ *value++ = 0;
+
+ g_strchug (g_strchomp (p));
+ if (!g_str_has_prefix (p, "XDG_"))
+ continue;
+ if (!g_str_has_suffix (p, "_DIR"))
+ continue;
+ type_start = p + 4;
+ type_end = p + strlen (p) - 4;
+
+ while (g_ascii_isspace (*value))
+ value++;
+
+ if (*value != '"')
+ continue;
+ value++;
+
+ relative = FALSE;
+ if (g_str_has_prefix (value, "$HOME"))
+ {
+ relative = TRUE;
+ value += 5;
+ while (*value == '/')
+ value++;
+ }
+ else if (*value != '/')
+ continue;
+
+ d = unescaped = g_malloc (strlen (value) + 1);
+ while (*value && *value != '"')
+ {
+ if ((*value == '\\') && (*(value + 1) != 0))
+ value++;
+ *d++ = *value++;
+ }
+ *d = 0;
+
+ *type_end = 0;
+ dir.type = g_strdup (type_start);
+ if (relative)
+ {
+ dir.path = g_build_filename (g_get_home_dir (), unescaped, NULL);
+ g_free (unescaped);
+ }
+ else
+ dir.path = unescaped;
+
+ g_array_append_val (array, dir);
+ }
+
+ g_strfreev (lines);
+ }
+
+ g_free (config_file_free);
+
+ return (XdgDirEntry *)g_array_free (array, FALSE);
+}
+
+static XdgDirEntry *cached_xdg_dirs = NULL;
+static GnomeVFSMonitorHandle *cached_xdg_dirs_handle = NULL;
+
+static void
+xdg_dir_changed (NautilusFile *file,
+ XdgDirEntry *dir)
+{
+ char *file_uri;
+ char *dir_uri;
+ char *path;
+
+ file_uri = nautilus_file_get_uri (file);
+ dir_uri = gnome_vfs_get_uri_from_local_path (dir->path);
+ if (file_uri && dir_uri &&
+ !gnome_vfs_uris_match (dir_uri, file_uri)) {
+ path = gnome_vfs_get_local_path_from_uri (file_uri);
+
+ if (path) {
+ char *argv[5];
+ int i;
+
+ g_free (dir->path);
+ dir->path = path;
+
+ i = 0;
+ argv[i++] = "xdg-user-dirs-update";
+ argv[i++] = "--set";
+ argv[i++] = dir->type;
+ argv[i++] = dir->path;
+ argv[i++] = NULL;
+
+ /* We do this sync, to avoid possible race-conditions
+ if multiple dirs change at the same time. Its
+ blocking the main thread, but these updates should
+ be very rare and very fast. */
+ g_spawn_sync (NULL,
+ argv, NULL,
+ G_SPAWN_SEARCH_PATH |
+ G_SPAWN_STDOUT_TO_DEV_NULL |
+ G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL, NULL,
+ NULL, NULL, NULL, NULL);
+ schedule_user_dirs_changed ();
+ desktop_dir_changed ();
+ }
+ }
+ g_free (file_uri);
+ g_free (dir_uri);
+}
+
+static void
+xdg_dir_cache_changed_cb (GnomeVFSMonitorHandle *handle,
+ const gchar *monitor_uri,
+ const gchar *info_uri,
+ GnomeVFSMonitorEventType event_type,
+ gpointer user_data)
+{
+ if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ||
+ event_type == GNOME_VFS_MONITOR_EVENT_CREATED) {
+ update_xdg_dir_cache ();
+ }
+}
+
+static int user_dirs_changed_tag = 0;
+
+static gboolean
+emit_user_dirs_changed_idle (gpointer data)
+{
+ g_signal_emit_by_name (nautilus_signaller_get_current (),
+ "user_dirs_changed");
+ user_dirs_changed_tag = 0;
+ return FALSE;
+}
+
+static void
+schedule_user_dirs_changed (void)
+{
+ if (user_dirs_changed_tag == 0) {
+ user_dirs_changed_tag = g_idle_add (emit_user_dirs_changed_idle, NULL);
+ }
+}
+
+static void
+update_xdg_dir_cache (void)
+{
+ static gboolean started_monitor = FALSE;
+ char *config_file, *uri;
+ int i;
+
+ if (cached_xdg_dirs) {
+ for (i = 0 ; cached_xdg_dirs[i].type != NULL; i++) {
+ if (cached_xdg_dirs[i].file != NULL) {
+ nautilus_file_monitor_remove (cached_xdg_dirs[i].file,
+ &cached_xdg_dirs[i]);
+ g_signal_handlers_disconnect_by_func (cached_xdg_dirs[i].file,
+ G_CALLBACK (xdg_dir_changed),
+ &cached_xdg_dirs[i]);
+ nautilus_file_unref (cached_xdg_dirs[i].file);
+ }
+ g_free (cached_xdg_dirs[i].type);
+ g_free (cached_xdg_dirs[i].path);
+ }
+ g_free (cached_xdg_dirs);
+
+ schedule_user_dirs_changed ();
+ desktop_dir_changed ();
+ }
+
+ if (!started_monitor) {
+ config_file = g_build_filename (g_get_user_config_dir (),
+ "user-dirs.dirs", NULL);
+ uri = gnome_vfs_get_uri_from_local_path (config_file);
+ gnome_vfs_monitor_add (&cached_xdg_dirs_handle,
+ uri,
+ GNOME_VFS_MONITOR_FILE,
+ xdg_dir_cache_changed_cb,
+ NULL);
+ g_free (uri);
+ g_free (config_file);
+ }
+
+ cached_xdg_dirs = parse_xdg_dirs (NULL);
+
+ for (i = 0 ; cached_xdg_dirs[i].type != NULL; i++) {
+ cached_xdg_dirs[i].file = NULL;
+ if (strcmp (cached_xdg_dirs[i].path, g_get_home_dir ()) != 0) {
+ uri = gnome_vfs_get_uri_from_local_path (cached_xdg_dirs[i].path);
+ cached_xdg_dirs[i].file = nautilus_file_get (uri);
+ nautilus_file_monitor_add (cached_xdg_dirs[i].file,
+ &cached_xdg_dirs[i],
+ NAUTILUS_FILE_ATTRIBUTE_FILE_TYPE);
+ g_signal_connect (cached_xdg_dirs[i].file,
+ "changed", G_CALLBACK (xdg_dir_changed), &cached_xdg_dirs[i]);
+ g_free (uri);
+ }
+ }
+}
+
+char *
+nautilus_get_xdg_dir (const char *type)
+{
+ int i;
+
+ if (cached_xdg_dirs == NULL) {
+ update_xdg_dir_cache ();
+ }
+
+ for (i = 0 ; cached_xdg_dirs != NULL && cached_xdg_dirs[i].type != NULL; i++) {
+ if (strcmp (cached_xdg_dirs[i].type, type) == 0) {
+ return g_strdup (cached_xdg_dirs[i].path);
+ }
+ }
+ if (strcmp ("DESKTOP", type) == 0) {
+ return g_build_filename (g_get_home_dir (), DESKTOP_DIRECTORY_NAME, NULL);
+ }
+ if (strcmp ("TEMPLATES", type) == 0) {
+ return g_build_filename (g_get_home_dir (), "Templates", NULL);
+ }
+
+ return g_strdup (g_get_home_dir ());
+}
+
static char *
get_desktop_path (void)
{
if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR)) {
return g_strdup (g_get_home_dir());
} else {
- return g_build_filename (g_get_home_dir (), DESKTOP_DIRECTORY_NAME, NULL);
+ return nautilus_get_xdg_dir ("DESKTOP");
}
-
}
/**
@@ -231,11 +501,22 @@ nautilus_get_home_directory_uri (void)
}
+gboolean
+nautilus_should_use_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;
+}
+
char *
nautilus_get_templates_directory (void)
{
- return g_build_filename (g_get_home_dir(),
- "Templates", NULL);
+ return nautilus_get_xdg_dir ("TEMPLATES");
}
void
@@ -283,8 +564,9 @@ static char *escaped_desktop_dir_dirname = NULL;
static char *escaped_desktop_dir_filename = NULL;
static gboolean desktop_dir_changed_callback_installed = FALSE;
+
static void
-desktop_dir_changed_callback (gpointer callback_data)
+desktop_dir_changed (void)
{
g_free (escaped_desktop_dir);
g_free (escaped_desktop_dir_filename);
@@ -295,6 +577,12 @@ desktop_dir_changed_callback (gpointer callback_data)
}
static void
+desktop_dir_changed_callback (gpointer callback_data)
+{
+ desktop_dir_changed ();
+}
+
+static void
update_desktop_dir (void)
{
char *uri, *path;
diff --git a/libnautilus-private/nautilus-file-utilities.h b/libnautilus-private/nautilus-file-utilities.h
index 3ca0c648c..d55eed038 100644
--- a/libnautilus-private/nautilus-file-utilities.h
+++ b/libnautilus-private/nautilus-file-utilities.h
@@ -37,6 +37,7 @@ gboolean nautilus_file_name_matches_backup_pattern (const char *name_or_relati
/* These functions all return something something that needs to be
* freed with g_free, is not NULL, and is guaranteed to exist.
*/
+char * nautilus_get_xdg_dir (const char *type);
char * nautilus_get_user_directory (void);
char * nautilus_get_desktop_directory (void);
char * nautilus_get_desktop_directory_uri (void);
@@ -49,6 +50,7 @@ gboolean nautilus_is_home_directory_file_escaped (char *escaped_dirname,
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);
diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c
index af3a8fa71..af661fb56 100644
--- a/libnautilus-private/nautilus-file.c
+++ b/libnautilus-private/nautilus-file.c
@@ -839,7 +839,6 @@ nautilus_file_can_rename (NautilusFile *file)
}
if ((is_desktop_file (file) && !can_rename_desktop_file (file)) ||
- nautilus_file_is_desktop_directory (file) ||
nautilus_file_is_home (file)) {
return FALSE;
}
diff --git a/libnautilus-private/nautilus-signaller.c b/libnautilus-private/nautilus-signaller.c
index 4ae97ed56..a10e27d87 100644
--- a/libnautilus-private/nautilus-signaller.c
+++ b/libnautilus-private/nautilus-signaller.c
@@ -39,6 +39,7 @@ enum {
HISTORY_LIST_CHANGED,
EMBLEMS_CHANGED,
POPUP_MENU_CHANGED,
+ USER_DIRS_CHANGED,
LAST_SIGNAL
};
@@ -94,4 +95,12 @@ nautilus_signaller_class_init (NautilusSignallerClass *class)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ signals[USER_DIRS_CHANGED] =
+ g_signal_new ("user_dirs_changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c
index 83baf2e1c..a9a44afcf 100644
--- a/src/file-manager/fm-directory-view.c
+++ b/src/file-manager/fm-directory-view.c
@@ -151,6 +151,7 @@
#define FM_DIRECTORY_VIEW_POPUP_PATH_LOCATION "/location"
#define MAX_MENU_LEVELS 5
+#define TEMPLATE_LIMIT 30
enum {
ADD_FILE,
@@ -187,9 +188,6 @@ static gboolean confirm_trash_auto_value;
static char *scripts_directory_uri;
static int scripts_directory_uri_length;
-static char *templates_directory_uri;
-static int templates_directory_uri_length;
-
struct FMDirectoryViewDetails
{
NautilusWindowInfo *window;
@@ -389,6 +387,8 @@ static gboolean activate_check_mime_types (FMDirectoryView
NautilusFile *file,
gboolean warn_on_mismatch);
static GdkDragAction ask_link_action (FMDirectoryView *view);
+static void update_templates_directory (FMDirectoryView *view);
+static void user_dirs_changed (FMDirectoryView *view);
static void file_get_volume_and_drive (NautilusFile *file,
GnomeVFSVolume **volume,
@@ -1619,17 +1619,6 @@ set_up_scripts_directory_global (void)
}
static void
-set_up_templates_directory_global (void)
-{
- if (templates_directory_uri != NULL) {
- return;
- }
-
- templates_directory_uri = nautilus_get_templates_directory_uri ();
- templates_directory_uri_length = strlen (templates_directory_uri);
-}
-
-static void
create_scripts_directory (void)
{
char *gnome1_path, *gnome1_uri_str;
@@ -1912,6 +1901,7 @@ fm_directory_view_init (FMDirectoryView *view)
static gboolean setup_autos = FALSE;
NautilusDirectory *scripts_directory;
NautilusDirectory *templates_directory;
+ char *templates_uri;
if (!setup_autos) {
setup_autos = TRUE;
@@ -1940,10 +1930,18 @@ fm_directory_view_init (FMDirectoryView *view)
add_directory_to_scripts_directory_list (view, scripts_directory);
nautilus_directory_unref (scripts_directory);
- set_up_templates_directory_global ();
- templates_directory = nautilus_directory_get (templates_directory_uri);
- add_directory_to_templates_directory_list (view, templates_directory);
- nautilus_directory_unref (templates_directory);
+ if (nautilus_should_use_templates_directory ()) {
+ templates_uri = nautilus_get_templates_directory_uri ();
+ templates_directory = nautilus_directory_get (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",
+ G_CALLBACK (user_dirs_changed),
+ view, G_CONNECT_SWAPPED);
view->details->sort_directories_first =
eel_preferences_get_boolean (NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
@@ -5712,19 +5710,52 @@ add_template_to_templates_menus (FMDirectoryView *directory_view,
g_free (action_name);
}
+static void
+update_templates_directory (FMDirectoryView *view)
+{
+ NautilusDirectory *templates_directory;
+ GList *node, *next;
+ char *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 (templates_uri);
+ g_free (templates_uri);
+ add_directory_to_templates_directory_list (view, templates_directory);
+ nautilus_directory_unref (templates_directory);
+ }
+}
+
+static void
+user_dirs_changed (FMDirectoryView *view)
+{
+ update_templates_directory (view);
+ view->details->templates_invalid = TRUE;
+ schedule_update_menus (view);
+}
static gboolean
-directory_belongs_in_templates_menu (const char *uri)
+directory_belongs_in_templates_menu (const char *templates_directory_uri,
+ const char *uri)
{
int num_levels;
int i;
- if (!eel_str_has_prefix (uri, templates_directory_uri)) {
+ if (templates_directory_uri == NULL) {
+ return FALSE;
+ }
+
+ if (!g_str_has_prefix (uri, templates_directory_uri)) {
return FALSE;
}
num_levels = 0;
- for (i = templates_directory_uri_length; uri[i] != '\0'; i++) {
+ for (i = strlen (templates_directory_uri); uri[i] != '\0'; i++) {
if (uri[i] == '/') {
num_levels++;
}
@@ -5738,7 +5769,9 @@ directory_belongs_in_templates_menu (const char *uri)
}
static gboolean
-update_directory_in_templates_menu (FMDirectoryView *view, NautilusDirectory *directory)
+update_directory_in_templates_menu (FMDirectoryView *view,
+ const char *templates_directory_uri,
+ NautilusDirectory *directory)
{
char *menu_path, *popup_bg_path;
GList *file_list, *filtered, *node;
@@ -5747,9 +5780,13 @@ update_directory_in_templates_menu (FMDirectoryView *view, NautilusDirectory *di
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 + templates_directory_uri_length);
+ escaped_path = escape_action_path (uri + strlen (templates_directory_uri));
g_free (uri);
menu_path = g_strconcat (FM_DIRECTORY_VIEW_MENU_PATH_NEW_DOCUMENTS_PLACEHOLDER,
escaped_path,
@@ -5765,13 +5802,14 @@ update_directory_in_templates_menu (FMDirectoryView *view, NautilusDirectory *di
file_list = nautilus_file_list_sort_by_display_name (filtered);
+ num = 0;
any_templates = FALSE;
- for (node = file_list; node != NULL; node = node->next) {
+ for (node = file_list; num < TEMPLATE_LIMIT && node != NULL; node = node->next, num++) {
file = node->data;
if (nautilus_file_is_directory (file)) {
uri = nautilus_file_get_uri (file);
- if (directory_belongs_in_templates_menu (uri)) {
+ if (directory_belongs_in_templates_menu (templates_directory_uri, uri)) {
dir = nautilus_directory_get (uri);
add_directory_to_templates_directory_list (view, dir);
nautilus_directory_unref (dir);
@@ -5809,6 +5847,13 @@ update_templates_menu (FMDirectoryView *view)
GtkUIManager *ui_manager;
char *uri;
GtkAction *action;
+ char *templates_directory_uri;
+
+ if (nautilus_should_use_templates_directory ()) {
+ templates_directory_uri = nautilus_get_templates_directory_uri ();
+ } else {
+ templates_directory_uri = 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
@@ -5833,9 +5878,11 @@ update_templates_menu (FMDirectoryView *view)
directory = node->data;
uri = nautilus_directory_get_uri (directory);
- if (!directory_belongs_in_templates_menu (uri)) {
+ if (!directory_belongs_in_templates_menu (templates_directory_uri, uri)) {
remove_directory_from_templates_directory_list (view, directory);
- } else if (update_directory_in_templates_menu (view, directory)) {
+ } else if (update_directory_in_templates_menu (view,
+ templates_directory_uri,
+ directory)) {
any_templates = TRUE;
}
g_free (uri);
@@ -5844,6 +5891,8 @@ update_templates_menu (FMDirectoryView *view)
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);
}