summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog143
-rw-r--r--acconfig.h6
-rw-r--r--configure.in6
-rw-r--r--libnautilus-extensions/nautilus-global-preferences.c19
-rw-r--r--libnautilus-extensions/nautilus-global-preferences.h3
-rw-r--r--libnautilus-extensions/nautilus-icon-container.c19
-rw-r--r--libnautilus-extensions/nautilus-icon-text-item.c44
-rw-r--r--libnautilus-extensions/nautilus-medusa-support.c69
-rw-r--r--libnautilus-extensions/nautilus-volume-monitor.c434
-rw-r--r--libnautilus-private/nautilus-global-preferences.c19
-rw-r--r--libnautilus-private/nautilus-global-preferences.h3
-rw-r--r--libnautilus-private/nautilus-icon-container.c19
-rw-r--r--libnautilus-private/nautilus-icon-text-item.c44
-rw-r--r--libnautilus-private/nautilus-medusa-support.c69
-rw-r--r--libnautilus-private/nautilus-volume-monitor.c434
-rw-r--r--libnautilus/nautilus-clipboard-ui.xml29
-rw-r--r--libnautilus/nautilus-clipboard.c33
-rw-r--r--src/file-manager/fm-directory-view.c760
-rw-r--r--src/file-manager/fm-icon-view.c16
-rw-r--r--src/file-manager/nautilus-directory-view-ui.xml28
-rw-r--r--src/nautilus-shell-ui.xml12
21 files changed, 1362 insertions, 847 deletions
diff --git a/ChangeLog b/ChangeLog
index c4b40a6a1..1ad593d58 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,146 @@
+2001-03-22 Darin Adler <darin@eazel.com>
+
+ reviewed by: John Sullivan <sullivan@eazel.com>
+
+ Fix bug 6613 (no way to delete files without using trash) by
+ integrating Maciej's patch to add an optional Delete command (with
+ some fixes to the patch). There may still be some loose ends.
+
+ Fix bug 2206 (No way to move or copy a file to a different
+ directory from keyboard) by implementing Cut, Copy, and Paste for
+ files, in a way that will be familiar to Windows users. The
+ positioning of the new files is not right yet (they inherit their
+ position from the old files), there is no feedback when you have
+ cut some files (Arlo's idea, which I might implement, is to make
+ them translucent to show they are "on the way out") or when you
+ have copied some files, and I think there are some other loose
+ ends.
+
+ Fixed cut, copy, and paste within the file names when you do a
+ rename. This wasn't working at all.
+
+ Got rid of configure-time checks that were looking at the
+ existence of some special system files.
+
+ Fixed a few minor bugs discovered by code inspection.
+
+ * libnautilus-extensions/nautilus-global-preferences.h:
+ * libnautilus-extensions/nautilus-global-preferences.c:
+ (global_preferences_install_descriptions),
+ (global_preferences_install_defaults),
+ (global_preferences_install_visibility),
+ (global_preferences_create_dialog): Add expert preference to add a
+ Delete command that bypasses the Trash.
+ * src/file-manager/nautilus-directory-view-ui.xml: Add Delete, Cut
+ Files, Copy Files, and Paste Files.
+ * src/file-manager/fm-directory-view.c: (confirm_delete_directly),
+ (delete_callback): Add delete code.
+ (bonobo_menu_empty_trash_callback): Get rid of extraneous cast.
+ (fm_directory_view_initialize): Track the delete preference. Set
+ the flags properly to indicate we have our own X window. Add a
+ target so GTK knows that we accept pastes of copied files.
+ (forget_clipboard_contents): Helper for when we are no longer the
+ clipboard owner.
+ (fm_directory_view_destroy): Remove the delete preference
+ callback. Free the clipboard contents.
+ (offset_drop_points): Change so it handles NULL for the list of
+ points.
+ (trash_or_delete_files_common): Remove unneeded parameters.
+ (get_current_event_time): New function, placeholder that just
+ returned GDK_CURRENT_TIME. Perhaps we should get the real event
+ time here for use in clipboard manipulation calls.
+ (copy_or_cut_files): New function. Save the selection for later
+ use in a paste.
+ (copy_files_callback), (cut_files_callback): Call the new
+ copy_or_cut_files function.
+ (paste_files_callback): Do the clipboard convert that results in
+ the paste operation.
+ (real_selection_clear_event): Forget the clipboard contents.
+ (real_selection_get): Convert the selection into the appropriate
+ format and put it on the clipboard.
+ (convert_lines_to_str_list): Helper function for decoding incoming
+ pasted files.
+ (real_selection_received): Handle pasted files by parsing and then
+ triggering a file copy operation.
+ (real_merge_menus): Add verbs for cut, copy, and paste.
+ (enable_delete_changed_callback): Keep track of delete command
+ status in a boolean.
+ (real_update_menus): Show delete command if the preference is on
+ and we are not showing "Delete from Trash". Update names of the
+ Cut and Copy command depending on how many files are selected.
+ Also desensitize them when none are selected.
+ (fm_directory_view_select_file): Initialize an uninitialized field.
+ (fm_directory_view_move_copy_items): Allow relative_item_points to
+ be NULL.
+ (real_realize): Create our own X window.
+ (real_size_allocate): Trick GtkScrolledWindow into doing the right
+ thing despite the fact that we have our own X window.
+ (fm_directory_view_initialize_class): Moved down to the bottom so
+ we don't need so many forward declaractions. Added code to set up
+ some needed atoms and new default handlers.
+
+ * libnautilus-extensions/nautilus-icon-text-item.c:
+ (send_focus_event), (iti_stop_editing), (iti_start_editing): Add
+ code to send the appropriate focus events to the fake off-screen
+ GtkEntry. This makes the clipboard code that tracks focus-related
+ signals work properly with this entry.
+ (iti_event): Tweak the sequence and simplify the code a bit.
+ * libnautilus/nautilus-clipboard.c:
+ (set_paste_sensitive_if_clipboard_contains_data): Add more
+ FIXMEs. This function is very far from useful, and it's not clear
+ that it can be implemented efficiently under X.
+ (nautilus_clipboard_set_up_editable): Get rid of silly
+ "grab_focus" hack that was an attempt to address the problems with
+ the NautilusIconTextItem. The real solution was to do focusing for
+ that item too.
+ (nautilus_clipboard_set_up_editable_in_control): Fix this so it
+ works when called on an editable that is already focused.
+ * src/file-manager/fm-icon-view.c: (renaming_icon_callback): Get
+ rid of "grab_focus" workaround, which wasn't working.
+
+ * acconfig.h:
+ * configure.in:
+ Remove all configure checks that were checking the existence of
+ files.
+ * libnautilus-extensions/nautilus-medusa-support.c:
+ (nautilus_medusa_check_cron_is_enabled): Simplify logic so there's
+ less room for confusion (I did this as a fix for the bug that was
+ reported on the mailing list, but Rebecka checked in the small
+ patch first). Also change it so we don't need a configure-time
+ check for the existence of the process directory and fix it so we
+ won't get a core dump if the file doesn't have a space character
+ in it. Also change the logic so we don't leave the directory open
+ when we do find the cron process.
+ * libnautilus-extensions/nautilus-volume-monitor.c:
+ (nautilus_volume_monitor_initialize_class),
+ (has_removable_mntent_options), (get_removable_volumes),
+ (volume_is_removable), (volume_is_read_only),
+ (mount_volume_get_cdrom_name), (mount_volume_activate_cdda),
+ (mount_volume_activate_cdrom), (build_volume_list_delta),
+ (get_current_mount_list), (mount_lists_are_identical),
+ (verify_current_mount_state), (mount_volume_floppy_add),
+ (get_cdrom_type_solaris), (mount_volume_iso9660_add),
+ (display_mount_status), (close_error_pipe),
+ (nautilus_volume_monitor_mount_unmount_removable),
+ (mount_volume_add_filesystem): Make changes throughout to get rid
+ of dependence on configure-time file checks and do things at
+ runtime instead. Also use typedefs to make less code conditional.
+ Also fix the Solaris CD-ROM code which was casting a GString to
+ a (char *) before, so it used absurd file names, and failed to open
+ and returned FALSE all the time.
+
+ * libnautilus-extensions/nautilus-icon-container.c:
+ (nautilus_icon_container_start_renaming_selected_item): Send the
+ renaming signal before setting up the rest of the icon. This
+ change is not really needed, but it's a better order to do things.
+
+ * libnautilus/nautilus-clipboard-ui.xml: Move tips into the
+ commands instead of the menu items (for style mostly, no practical
+ implications at the moment).
+ * src/nautilus-shell-ui.xml: Remove tips from Cut, Copy, and Paste,
+ since tips from insensitive items aren't used, and if we had tips,
+ we'd put them on the command, not the menu item, anyway.
+
2001-03-22 John Harper <jsh@eazel.com>
Fixed bug 7366 (Smooth text layout cache checks take too long):
diff --git a/acconfig.h b/acconfig.h
index 3f2d8b10a..fc3b04c93 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -25,9 +25,3 @@
#undef bzopen
#undef bzread
#undef bzwrite
-#undef HAVE_DEV
-#undef HAVE_VOL_DEV
-#undef HAVE_VOL
-#undef HAVE_ETC_MNTTAB
-#undef HAVE_PROC_MOUNTS
-#undef HAVE_PROC_PROCESS_FILES
diff --git a/configure.in b/configure.in
index d01ee6940..056378b90 100644
--- a/configure.in
+++ b/configure.in
@@ -158,12 +158,6 @@ Determining mount system properties:
"
AC_CHECK_FUNCS( setmntent endmntent )
AC_CHECK_HEADERS( mntent.h sys/mnttab.h sys/vfstab.h sys/cdio.h )
-AC_CHECK_FILES( /dev, AC_DEFINE(HAVE_DEV))
-AC_CHECK_FILES( /vol/dev, AC_DEFINE(HAVE_VOL_DEV))
-AC_CHECK_FILES( /vol, AC_DEFINE(HAVE_VOL))
-AC_CHECK_FILES( /etc/mnttab, AC_DEFINE(HAVE_ETC_MNTTAB))
-AC_CHECK_FILES( /proc/mounts, AC_DEFINE(HAVE_PROC_MOUNTS))
-AC_CHECK_FILES( /proc/1, AC_DEFINE(HAVE_PROC_PROCESS_FILES))
echo "
"
diff --git a/libnautilus-extensions/nautilus-global-preferences.c b/libnautilus-extensions/nautilus-global-preferences.c
index 14ad7312b..918fadd4f 100644
--- a/libnautilus-extensions/nautilus-global-preferences.c
+++ b/libnautilus-extensions/nautilus-global-preferences.c
@@ -2,7 +2,7 @@
/* nautilus-prefs-dialog.c - Implementation for preferences dialog.
- Copyright (C) 1999, 2000 Eazel, Inc.
+ Copyright (C) 1999, 2000, 2001 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -100,7 +100,10 @@ global_preferences_install_descriptions (void)
_("Open each file or folder in a separate window"));
nautilus_preferences_set_description (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
- _("Ask before emptying the Trash"));
+ _("Ask before emptying the Trash or deleting files"));
+
+ nautilus_preferences_set_description (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ _("Include a Delete command that bypasses Trash"));
nautilus_preferences_set_description (NAUTILUS_PREFERENCES_CLICK_POLICY,
_("Click Behavior"));
@@ -260,6 +263,10 @@ global_preferences_install_defaults (void)
NAUTILUS_USER_LEVEL_NOVICE,
TRUE);
+ nautilus_preferences_default_set_boolean (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ NAUTILUS_USER_LEVEL_NOVICE,
+ FALSE);
+
nautilus_preferences_default_set_integer (NAUTILUS_PREFERENCES_SHOW_TEXT_IN_ICONS,
NAUTILUS_USER_LEVEL_NOVICE,
NAUTILUS_SPEED_TRADEOFF_LOCAL_ONLY);
@@ -426,6 +433,9 @@ global_preferences_install_visibility (void)
nautilus_preferences_set_visible_user_level (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
NAUTILUS_USER_LEVEL_ADVANCED);
+ nautilus_preferences_set_visible_user_level (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ NAUTILUS_USER_LEVEL_ADVANCED);
+
nautilus_preferences_set_visible_user_level (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
NAUTILUS_USER_LEVEL_INTERMEDIATE);
@@ -612,6 +622,11 @@ global_preferences_create_dialog (void)
NAUTILUS_PREFERENCES_CONFIRM_TRASH,
NAUTILUS_PREFERENCE_ITEM_BOOLEAN);
+ nautilus_preferences_pane_add_item_to_nth_group (NAUTILUS_PREFERENCES_PANE (windows_and_desktop_pane),
+ 2,
+ NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ NAUTILUS_PREFERENCE_ITEM_BOOLEAN);
+
/* FIXME: This group clearly doesn't belong in Windows &
* Desktop, but there's no obviously-better place for it and
* it probably doesn't deserve a pane of its own.
diff --git a/libnautilus-extensions/nautilus-global-preferences.h b/libnautilus-extensions/nautilus-global-preferences.h
index ab2452e74..26678f255 100644
--- a/libnautilus-extensions/nautilus-global-preferences.h
+++ b/libnautilus-extensions/nautilus-global-preferences.h
@@ -2,7 +2,7 @@
/* nautilus-global-prefs.h - Nautilus main preferences api.
- Copyright (C) 1999, 2000 Eazel, Inc.
+ Copyright (C) 1999, 2000, 2001 Eazel, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -49,6 +49,7 @@ BEGIN_GNOME_DECLS
/* Trash options */
#define NAUTILUS_PREFERENCES_CONFIRM_TRASH "preferences/confirm_trash"
+#define NAUTILUS_PREFERENCES_ENABLE_DELETE "preferences/enable_delete"
/* Desktop options */
#define NAUTILUS_PREFERENCES_SHOW_DESKTOP "preferences/show_desktop"
diff --git a/libnautilus-extensions/nautilus-icon-container.c b/libnautilus-extensions/nautilus-icon-container.c
index 56c8154dd..32e948611 100644
--- a/libnautilus-extensions/nautilus-icon-container.c
+++ b/libnautilus-extensions/nautilus-icon-container.c
@@ -4862,21 +4862,22 @@ nautilus_icon_container_start_renaming_selected_item (NautilusIconContainer *con
gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (details->rename_widget), &icon_rect.x0, &icon_rect.y0);
gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (details->rename_widget), &icon_rect.x1, &icon_rect.y1);
- nautilus_icon_text_item_configure (
- details->rename_widget,
- (icon_rect.x0 + icon_rect.x1) / 2, /* x_center */
- icon_rect.y1, /* y_top */
- nautilus_icon_canvas_item_get_max_text_width (icon->item), /* max_text_width */
- details->label_font[details->zoom_level], /* font */
- editable_text, /* text */
- FALSE); /* allocate local copy */
+ nautilus_icon_text_item_configure
+ (details->rename_widget,
+ (icon_rect.x0 + icon_rect.x1) / 2, /* x_center */
+ icon_rect.y1, /* y_top */
+ nautilus_icon_canvas_item_get_max_text_width (icon->item), /* max_text_width */
+ details->label_font[details->zoom_level], /* font */
+ editable_text, /* text */
+ FALSE); /* allocate local copy */
nautilus_icon_text_item_start_editing (details->rename_widget);
- nautilus_icon_container_update_icon (container, icon);
gtk_signal_emit (GTK_OBJECT (container),
signals[RENAMING_ICON],
nautilus_icon_text_item_get_renaming_editable (details->rename_widget));
+
+ nautilus_icon_container_update_icon (container, icon);
/* We are in renaming mode */
details->renaming = TRUE;
diff --git a/libnautilus-extensions/nautilus-icon-text-item.c b/libnautilus-extensions/nautilus-icon-text-item.c
index 03d28357a..d1cf5388e 100644
--- a/libnautilus-extensions/nautilus-icon-text-item.c
+++ b/libnautilus-extensions/nautilus-icon-text-item.c
@@ -90,6 +90,36 @@ enum {
};
static guint iti_signals [LAST_SIGNAL] = { 0 };
+static void
+send_focus_event (Iti *iti, gboolean in)
+{
+ ItiPrivate *priv;
+ GtkWidget *widget;
+ gboolean has_focus;
+ GdkEvent fake_event;
+
+ g_assert (in == FALSE || in == TRUE);
+
+ priv = iti->priv;
+ if (priv->entry == NULL) {
+ g_assert (!in);
+ return;
+ }
+
+ widget = GTK_WIDGET (priv->entry);
+ has_focus = GTK_WIDGET_HAS_FOCUS (widget);
+ if (has_focus == in) {
+ return;
+ }
+
+ memset (&fake_event, 0, sizeof (fake_event));
+ fake_event.focus_change.type = GDK_FOCUS_CHANGE;
+ fake_event.focus_change.window = widget->window;
+ fake_event.focus_change.in = in;
+ gtk_widget_event (widget, &fake_event);
+ g_assert (GTK_WIDGET_HAS_FOCUS (widget) == in);
+}
+
/* Stops the editing state of an icon text item */
static void
iti_stop_editing (Iti *iti)
@@ -100,6 +130,8 @@ iti_stop_editing (Iti *iti)
iti->editing = FALSE;
+ send_focus_event (iti, FALSE);
+
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
gtk_signal_emit (GTK_OBJECT (iti), iti_signals[EDITING_STOPPED]);
@@ -232,7 +264,7 @@ iti_start_editing (Iti *iti)
gtk_signal_connect (GTK_OBJECT (priv->entry), "activate",
GTK_SIGNAL_FUNC (iti_entry_activate), iti);
/* Make clipboard functions cause an update the appearance of
- the icon text item iteself, since the clipboard functions
+ the icon text item itself, since the clipboard functions
will change the offscreen entry */
gtk_signal_connect_after (GTK_OBJECT (priv->entry), "changed",
GTK_SIGNAL_FUNC (iti_entry_text_changed_by_clipboard), iti);
@@ -249,6 +281,8 @@ iti_start_editing (Iti *iti)
iti->editing = TRUE;
+ send_focus_event (iti, TRUE);
+
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
gtk_signal_emit (GTK_OBJECT (iti), iti_signals[EDITING_STARTED]);
@@ -1067,13 +1101,13 @@ iti_event (GnomeCanvasItem *item, GdkEvent *event)
} else {
GTK_WIDGET_UNSET_FLAGS (item->canvas, GTK_HAS_FOCUS);
}
-
- if (iti->editing && !event->focus_change.in) {
- iti_edition_accept (iti);
- }
if (iti->editing) {
gtk_widget_event (GTK_WIDGET (priv->entry), event);
+
+ if (!event->focus_change.in) {
+ iti_edition_accept (iti);
+ }
}
return TRUE;
diff --git a/libnautilus-extensions/nautilus-medusa-support.c b/libnautilus-extensions/nautilus-medusa-support.c
index 2ae619fc4..94a079e66 100644
--- a/libnautilus-extensions/nautilus-medusa-support.c
+++ b/libnautilus-extensions/nautilus-medusa-support.c
@@ -25,16 +25,13 @@
*/
#include <config.h>
-#include <glib.h>
-
-#include <string.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <dirent.h>
+#include "nautilus-medusa-support.h"
#include "nautilus-glib-extensions.h"
-#include "nautilus-medusa-support.h"
#include "nautilus-string.h"
+#include <dirent.h>
+#include <stdio.h>
+#include <sys/types.h>
#ifdef HAVE_MEDUSA
#include <libmedusa/medusa-system-state.h>
@@ -85,7 +82,6 @@ nautilus_medusa_add_system_state_changed_callback (NautilusMedusaChangedCallback
NautilusCronStatus
nautilus_medusa_check_cron_is_enabled (void)
{
-#ifdef HAVE_PROC_PROCESS_FILES
DIR *proc_directory;
struct dirent *file;
char *stat_file_name;
@@ -93,6 +89,7 @@ nautilus_medusa_check_cron_is_enabled (void)
char stat_file_data[128];
const char *stat_file_process_name;
int process_number, bytes_read;
+ NautilusCronStatus status;
/* We figure out whether cron is running by reading the proc
directory, and checking for a process named or ending with
@@ -103,37 +100,39 @@ nautilus_medusa_check_cron_is_enabled (void)
return NAUTILUS_CRON_STATUS_UNKNOWN;
}
- file = readdir (proc_directory);
- while (file != NULL) {
+ status = NAUTILUS_CRON_STATUS_UNKNOWN;
+
+ while ((file = readdir (proc_directory)) != NULL) {
/* Process files have numbers */
- if (nautilus_str_to_int (file->d_name,
- &process_number)) {
- stat_file_name = g_strdup_printf ("/proc/%d/stat", process_number);
- stat_file = fopen (stat_file_name, "r");
- g_free (stat_file_name);
-
- if (stat_file == NULL) {
- file = readdir (proc_directory);
- continue;
- }
-
- bytes_read = fread (stat_file_data, sizeof (char), NAUTILUS_N_ELEMENTS (stat_file_data) - 1, stat_file);
- fclose (stat_file);
- stat_file_data[bytes_read] = 0;
-
- stat_file_process_name = strchr (stat_file_data, ' ') + 1;
-
- if (nautilus_str_has_prefix (stat_file_process_name, "(crond)")) {
- return NAUTILUS_CRON_STATUS_ON;
- }
+ if (!nautilus_str_to_int (file->d_name, &process_number)) {
+ continue;
+ }
+ /* Since we've seen at least one process file, we can change our state
+ * from "unknown" to "presumed off until proved otherwise".
+ */
+ status = NAUTILUS_CRON_STATUS_OFF;
+
+ stat_file_name = g_strdup_printf ("/proc/%d/stat", process_number);
+ stat_file = fopen (stat_file_name, "r");
+ g_free (stat_file_name);
+
+ if (stat_file == NULL) {
+ continue;
+ }
+
+ bytes_read = fread (stat_file_data, 1, sizeof (stat_file_data) - 1, stat_file);
+ fclose (stat_file);
+ stat_file_data[bytes_read] = '\0';
+
+ stat_file_process_name = strchr (stat_file_data, ' ');
+
+ if (nautilus_str_has_prefix (stat_file_process_name, " (crond)")) {
+ status = NAUTILUS_CRON_STATUS_ON;
+ break;
}
- file = readdir (proc_directory);
}
closedir (proc_directory);
- return NAUTILUS_CRON_STATUS_OFF;
-#else
- return NAUTILUS_CRON_STATUS_UNKNOWN;
-#endif
+ return status;
}
diff --git a/libnautilus-extensions/nautilus-volume-monitor.c b/libnautilus-extensions/nautilus-volume-monitor.c
index e32254a22..8055b44cd 100644
--- a/libnautilus-extensions/nautilus-volume-monitor.c
+++ b/libnautilus-extensions/nautilus-volume-monitor.c
@@ -2,7 +2,7 @@
/* nautilus-volume-monitor.c - Desktop volume mounting routines.
- Copyright (C) 2000 Eazel, Inc.
+ Copyright (C) 2000, 2001 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -23,8 +23,6 @@
*/
#include <config.h>
-#include <sys/types.h>
-
#include "nautilus-volume-monitor.h"
#include "nautilus-cdrom-extensions.h"
@@ -64,11 +62,13 @@
#ifdef HAVE_MNTENT_H
#include <mntent.h>
+#define MOUNT_TABLE_PATH _PATH_MNTTAB
#endif
#ifdef HAVE_SYS_MNTTAB_H
#define SOLARIS_MNT 1
#include <sys/mnttab.h>
+#define MOUNT_TABLE_PATH "/etc/mnttab"
#endif
#ifdef SOLARIS_MNT
@@ -77,7 +77,16 @@
#define USE_VOLRMMOUNT 0
#endif
+#ifndef MNTOPT_RO
+#define MNTOPT_RO "ro"
+#endif
+
+#ifndef HAVE_SETMNTENT
+#define setmntent(f,m) fopen(f,m)
+#endif
+
#ifdef HAVE_CDDA
+
#define size16 short
#define size32 int
@@ -94,48 +103,17 @@
* due to our strict error checking.
*/
char **broken_header_fix = strerror_tr;
-#endif
-
-#define CHECK_STATUS_INTERVAL 2000
-#ifdef HAVE_ETC_MNTTAB
-#define PATH_PROC_MOUNTS "/etc/mnttab"
-#define PROC_MOUNTS_SEPARATOR "\t"
#endif
-#ifdef HAVE_PROC_MOUNTS
-#define PATH_PROC_MOUNTS "/proc/mounts"
-#define PROC_MOUNTS_SEPARATOR " "
-#endif
+#define CHECK_STATUS_INTERVAL 2000
#define FLOPPY_MOUNT_PATH_PREFIX "/mnt/fd"
-#ifdef HAVE_VOL_DEV
-#define FLOPPY_DEVICE_PATH_PREFIX "/vol/dev/diskette"
-#else
-#define FLOPPY_DEVICE_PATH_PREFIX "/dev/fd"
-#endif
-
#ifdef HAVE_SYS_MNTTAB_H
-#define PATH_MOUNT_TABLE "/etc/mnttab"
-#endif
-
-#ifdef HAVE_MNTENT_H
-#define PATH_MOUNT_TABLE _PATH_MNTTAB
-#endif
-
-#ifdef HAVE_VOL
-# define MNTOPT_NOAUTO "/vol/"
-# else
-# define MNTOPT_NOAUTO "noauto"
-#endif
-
-#ifndef MNTOPT_RO
-# define MNTOPT_RO "ro"
-#endif
-
-#ifndef HAVE_SETMNTENT
-#define setmntent(f,m) fopen(f,m)
+typedef struct mnttab MountTableEntry;
+#else
+typedef struct mntent MountTableEntry;
#endif
struct NautilusVolumeMonitorDetails
@@ -147,6 +125,8 @@ struct NautilusVolumeMonitorDetails
};
static NautilusVolumeMonitor *global_volume_monitor = NULL;
+static const char *floppy_device_path_prefix;
+static const char *noauto_string;
/* The NautilusVolumeMonitor signals. */
@@ -182,7 +162,7 @@ static GList *mount_volume_add_filesystem (NautilusVolume *volume,
static NautilusVolume *create_volume (const char *device_path,
const char *mount_path,
const char *filesystem);
-static NautilusVolume *copy_volume (NautilusVolume *volume);
+static NautilusVolume *copy_volume (NautilusVolume *volume);
static void find_volumes (NautilusVolumeMonitor *monitor);
static void free_mount_list (GList *mount_list);
static GList *get_removable_volumes (void);
@@ -194,7 +174,8 @@ static gboolean locate_audio_cd (void);
#endif
#ifdef SOLARIS_MNT
-static int get_cdrom_type_solaris(char *vol_dev_path, int* fd) ;
+static int get_cdrom_type_solaris (const char *vol_dev_path,
+ int *fd);
#endif
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusVolumeMonitor,
@@ -242,7 +223,19 @@ nautilus_volume_monitor_initialize_class (NautilusVolumeMonitorClass *klass)
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
- gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+ gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+
+ /* Check environment a bit. */
+ if (g_file_exists ("/vol/dev")) {
+ floppy_device_path_prefix = "/vol/dev/diskette/";
+ } else {
+ floppy_device_path_prefix = "/dev/fd/";
+ }
+ if (g_file_exists ("/vol")) {
+ noauto_string = "/vol/";
+ } else {
+ noauto_string = "/dev/fd/";
+ }
}
static void
@@ -330,31 +323,20 @@ nautilus_volume_monitor_get_removable_volumes (NautilusVolumeMonitor *monitor)
}
-#ifdef HAVE_SYS_MNTTAB_H
-
-static gboolean
-has_removable_mntent_options (struct mnttab *ent)
-{
-
-#else
-
static gboolean
-has_removable_mntent_options (struct mntent *ent)
+has_removable_mntent_options (MountTableEntry *ent)
{
-
-#endif /* HAVE_SYS_MNTTAB_H */
-
/* Use "owner" or "user" or "users" as our way of determining a removable volume */
if (hasmntopt (ent, "user") != NULL
|| hasmntopt (ent, "users") != NULL
|| hasmntopt (ent, "owner") != NULL) {
- return TRUE;
+ return TRUE;
}
-#if SOLARIS_MNT && HAVE_VOL
- if (strstr (ent->mnt_special, "/vol/") == ent->mnt_special) {
- return TRUE;
- }
+#ifdef SOLARIS_MNT
+ if (nautilus_str_has_prefix (ent->mnt_special, "/vol/")) {
+ return TRUE;
+ }
#endif
return FALSE;
@@ -372,36 +354,38 @@ get_removable_volumes (void)
{
FILE *file;
GList *volumes;
-#if HAVE_SYS_MNTTAB_H
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-#else
- struct mntent *ent;
-#endif /* HAVE_SYS_MNTTAB_H */
+ MountTableEntry *ent;
NautilusVolume *volume;
+#if HAVE_SYS_MNTTAB_H
+ MountTableEntry ent_storage;
+#endif
volumes = NULL;
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return NULL;
}
#if HAVE_SYS_MNTTAB_H
+ ent = &ent_storage;
while (! getmntent (file, ent)) {
/* On Solaris look for /vol/ for determining a removable volume */
- if (strstr (ent->mnt_special, MNTOPT_NOAUTO) == ent->mnt_special) {
+ if (nautilus_str_has_prefix (ent->mnt_special, noauto_string)) {
volume = create_volume (ent->mnt_special, ent->mnt_mountp, ent->mnt_fstype);
volume->is_removable = TRUE;
- volume->is_read_only = (hasmntopt (ent, MNTOPT_RO) !=NULL);
+ volume->is_read_only = hasmntopt (ent, MNTOPT_RO) != NULL;
+ volumes = mount_volume_add_filesystem (volume, volumes);
+ }
+ }
#else
while ((ent = getmntent (file)) != NULL) {
if (has_removable_mntent_options (ent)) {
volume = create_volume (ent->mnt_fsname, ent->mnt_dir, ent->mnt_type);
-#endif /* HAVE_SYS_MNTTAB_H */
volumes = mount_volume_add_filesystem (volume, volumes);
- }
+ }
}
+#endif /* HAVE_SYS_MNTTAB_H */
fclose (file);
@@ -419,26 +403,24 @@ static gboolean
volume_is_removable (const NautilusVolume *volume)
{
FILE *file;
+ MountTableEntry *ent;
#if HAVE_SYS_MNTTAB_H
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-#else
- struct mntent *ent;
-#endif /* HAVE_SYS_MNTTAB_H */
+ MountTableEntry ent_storage;
+#endif
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return FALSE;
}
/* Search for our device in the fstab */
#if HAVE_SYS_MNTTAB_H
+ MountTableEntry *ent = &ent_storage;
while (!getmntent (file, ent)) {
if (strcmp (volume->device_path, ent->mnt_special) == 0) {
/* On Solaris look for /vol/ for determining
a removable volume */
- if (strstr (ent->mnt_special, MNTOPT_NOAUTO)
- == ent->mnt_special) {
+ if (nautilus_str_has_prefix (ent->mnt_special, noauto_string)) {
fclose (file);
return TRUE;
}
@@ -452,7 +434,6 @@ volume_is_removable (const NautilusVolume *volume)
return TRUE;
}
}
-
#endif /* HAVE_SYS_MNTTAB_H */
fclose (file);
@@ -463,18 +444,19 @@ static gboolean
volume_is_read_only (const NautilusVolume *volume)
{
FILE *file;
+ MountTableEntry *ent;
#if HAVE_SYS_MNTTAB_H
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ MountTableEntry ent_storage;
+
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return FALSE;
}
/* Search for our device in the fstab */
- while (!getmntent (file, ent)) {
+ ent = &ent_storage;
+ while (!getmntent (file, ent)) {
if (strcmp (volume->device_path, ent->mnt_special) == 0) {
if (strstr (ent->mnt_mntopts, MNTOPT_RO) != NULL) {
fclose (file);
@@ -483,9 +465,7 @@ volume_is_read_only (const NautilusVolume *volume)
}
}
#else
- struct mntent *ent;
-
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return FALSE;
}
@@ -629,14 +609,12 @@ mount_volume_get_cdrom_name (NautilusVolume *volume)
{
int fd, disctype;
- #ifdef SOLARIS_MNT
- disctype = get_cdrom_type_solaris(volume->device_path, &fd);
-
- #else
+#if SOLARIS_MNT
+ disctype = get_cdrom_type_solaris (volume->device_path, &fd);
+#else
fd = open (volume->device_path, O_RDONLY|O_NONBLOCK);
disctype = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT);
-
- #endif
+#endif
switch (disctype) {
case CDS_AUDIO:
@@ -672,7 +650,7 @@ mount_volume_activate_cdda (NautilusVolumeMonitor *monitor, NautilusVolume *volu
int fd, disctype;
#ifdef SOLARIS_MNT
- disctype = get_cdrom_type_solaris(volume->device_path, &fd);
+ disctype = get_cdrom_type_solaris (volume->device_path, &fd);
#else
fd = open (volume->device_path, O_RDONLY | O_NONBLOCK);
disctype = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT);
@@ -693,7 +671,7 @@ mount_volume_activate_cdrom (NautilusVolumeMonitor *monitor, NautilusVolume *vol
{
int fd, disctype;
#ifdef SOLARIS_MNT
- disctype = get_cdrom_type_solaris(volume->device_path, &fd);
+ disctype = get_cdrom_type_solaris (volume->device_path, &fd);
#else
fd = open (volume->device_path, O_RDONLY | O_NONBLOCK);
disctype = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT);
@@ -918,19 +896,18 @@ build_volume_list_delta (GList *list_one, GList *list_two)
GList *ptrOne, *ptrTwo;
GList *new_list;
NautilusVolume *volOne, *volTwo, *new_volume;
- int index;
gboolean found_match;
new_list = NULL;
- for (ptrOne = list_one, index = 0; ptrOne != NULL; ptrOne = ptrOne->next, index++) {
+ for (ptrOne = list_one; ptrOne != NULL; ptrOne = ptrOne->next) {
found_match = FALSE;
- volOne = (NautilusVolume *)ptrOne->data;
+ volOne = (NautilusVolume *) ptrOne->data;
for (ptrTwo = list_two; ptrTwo != NULL; ptrTwo = ptrTwo->next) {
- volTwo = (NautilusVolume *)ptrTwo->data;
+ volTwo = (NautilusVolume *) ptrTwo->data;
/* Check and see if mount point from list one is in list two */
if (strcmp (volOne->mount_path, volTwo->mount_path) == 0) {
@@ -958,32 +935,36 @@ get_current_mount_list (void)
FILE *fh;
#ifdef SOLARIS_MNT
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-
- fh = setmntent (PATH_MOUNT_TABLE, "r");
- if (fh == NULL) {
- return NULL;
- }
- while (! getmntent (fh, ent)) {
- volume = create_volume (ent->mnt_special, ent->mnt_mountp, ent->mnt_fstype);
- volume->is_removable = has_removable_mntent_options(ent);
- volume->is_read_only = (hasmntopt (ent, MNTOPT_RO) != NULL);
- current_mounts = mount_volume_add_filesystem (volume, current_mounts);
- }
+ MountTableEntry ent_storage;
+ MountTableEntry *ent = &ent_storage;
+
+ fh = setmntent (MOUNT_TABLE_PATH, "r");
+ if (fh != NULL) {
+ while (! getmntent (fh, ent)) {
+ volume = create_volume (ent->mnt_special, ent->mnt_mountp, ent->mnt_fstype);
+ volume->is_removable = has_removable_mntent_options(ent);
+ volume->is_read_only = hasmntopt (ent, MNTOPT_RO) != NULL;
+ current_mounts = mount_volume_add_filesystem (volume, current_mounts);
+ }
+ }
#else
char line[PATH_MAX * 3];
char device_name[sizeof (line)];
NautilusStringList *list;
char *device_path, *mount_path, *filesystem;
+ const char *separator;
- /* Open /proc/mounts */
- fh = fopen (PATH_PROC_MOUNTS, "r");
+ fh = fopen ("/etc/mnttab", "r");
+ separator = "\t";
+ if (fh == NULL) {
+ fh = fopen ("/proc/mounts", "r");
+ separator = " ";
+ }
g_return_val_if_fail (fh != NULL, NULL);
while (fgets (line, sizeof(line), fh)) {
if (sscanf (line, "%s", device_name) == 1) {
- list = nautilus_string_list_new_from_tokens (line, PROC_MOUNTS_SEPARATOR, FALSE);
+ list = nautilus_string_list_new_from_tokens (line, separator, FALSE);
if (list != NULL) {
/* The string list needs to have at least 3 items per line.
* We need to find at least device path, mount path and file system type.
@@ -1002,9 +983,12 @@ get_current_mount_list (void)
}
}
}
-
#endif /* SOLARIS_MNT */
+ if (fh != NULL) {
+ fclose (fh);
+ }
+
#ifdef HAVE_CDDA
/* CD Audio tricks */
if (locate_audio_cd ()) {
@@ -1014,8 +998,6 @@ get_current_mount_list (void)
}
#endif
- fclose (fh);
-
return current_mounts;
}
@@ -1035,7 +1017,6 @@ update_modifed_volume_name (GList *mount_list, NautilusVolume *volume)
}
}
-
static gboolean
mount_lists_are_identical (GList *list_a, GList *list_b)
{
@@ -1043,7 +1024,6 @@ mount_lists_are_identical (GList *list_a, GList *list_b)
NautilusVolume *volumeOne, *volumeTwo;
for (p = list_a, q = list_b; p != NULL && q != NULL; p = p->next, q = q->next) {
-
volumeOne = p->data;
volumeTwo = q->data;
@@ -1058,17 +1038,7 @@ static void
verify_current_mount_state (NautilusVolumeMonitor *monitor)
{
GList *new_mounts, *old_mounts, *current_mounts;
- GList *saved_mount_list;
- gboolean free_new_mounts;
-
- new_mounts = old_mounts = current_mounts = saved_mount_list = NULL;
-
- /* Free the new mount list only if it is not a copy of the current mount list. */
- if (monitor->details->mounts != NULL) {
- free_new_mounts = TRUE;
- } else {
- free_new_mounts = FALSE;
- }
+ GList *saved_mount_list, *p;
/* Get all current mounts */
current_mounts = get_current_mount_list ();
@@ -1082,17 +1052,9 @@ verify_current_mount_state (NautilusVolumeMonitor *monitor)
return;
}
- /* If saved mounts is NULL, this is the first time we have been here. New mounts
- * are the same as current mounts
- */
- if (monitor->details->mounts == NULL) {
- new_mounts = current_mounts;
- old_mounts = NULL;
- } else {
- /* Create list of new and old mounts */
- new_mounts = build_volume_list_delta (current_mounts, monitor->details->mounts);
- old_mounts = build_volume_list_delta (monitor->details->mounts, current_mounts);
- }
+ /* Create list of new and old mounts */
+ new_mounts = build_volume_list_delta (current_mounts, monitor->details->mounts);
+ old_mounts = build_volume_list_delta (monitor->details->mounts, current_mounts);
/* Stash a copy of the current mount list for updating mount names later. */
saved_mount_list = monitor->details->mounts;
@@ -1101,36 +1063,24 @@ verify_current_mount_state (NautilusVolumeMonitor *monitor)
monitor->details->mounts = current_mounts;
/* Check and see if we have new mounts to add */
- if (new_mounts != NULL) {
- GList *p;
- for (p = new_mounts; p != NULL; p = p->next) {
- mount_volume_activate (monitor, (NautilusVolume *)p->data);
- }
- }
+ for (p = new_mounts; p != NULL; p = p->next) {
+ mount_volume_activate (monitor, (NautilusVolume *)p->data);
+ }
/* Check and see if we have old mounts to remove */
- if (old_mounts != NULL) {
- GList *p;
-
- for (p = old_mounts; p != NULL; p = p->next) {
- /* First we need to update the volume names in this list with modified names in the old list. Names in
- * the old list may have been modifed due to icon name conflicts. The list of old mounts is unable
- * take this into account when it is created
- */
- update_modifed_volume_name (saved_mount_list, (NautilusVolume *)p->data);
-
- /* Deactivate the volume. */
- mount_volume_deactivate (monitor, (NautilusVolume *)p->data);
- }
- free_mount_list (old_mounts);
+ for (p = old_mounts; p != NULL; p = p->next) {
+ /* First we need to update the volume names in this list with modified names in the old list. Names in
+ * the old list may have been modifed due to icon name conflicts. The list of old mounts is unable
+ * take this into account when it is created
+ */
+ update_modifed_volume_name (saved_mount_list, (NautilusVolume *) p->data);
+
+ /* Deactivate the volume. */
+ mount_volume_deactivate (monitor, (NautilusVolume *) p->data);
}
- /* Free the new mount list only if it is not a copy of the current mount list.
- * It will be a copy if there are no previous mounts.
- */
- if (free_new_mounts) {
- free_mount_list (new_mounts);
- }
+ free_mount_list (old_mounts);
+ free_mount_list (new_mounts);
free_mount_list (saved_mount_list);
}
@@ -1148,6 +1098,7 @@ static gboolean
mount_volume_floppy_add (NautilusVolume *volume)
{
volume->type = NAUTILUS_VOLUME_FLOPPY;
+
return TRUE;
}
@@ -1184,43 +1135,49 @@ mount_volume_msdos_add (NautilusVolume *volume)
}
#ifdef SOLARIS_MNT
-static int get_cdrom_type_solaris(char *vol_dev_path, int* fd) {
+static int
+get_cdrom_type_solaris (const char *vol_dev_path, int* fd)
+{
GString *new_dev_path;
struct cdrom_tocentry entry;
- struct cdrom_tochdr header;
- gboolean audio;
-
-/* For ioctl call to work dev_path has to be /vol/dev/rdsk....
- there has to be a nicer way to do this. */
+ struct cdrom_tochdr header;
+ int type;
- new_dev_path = g_string_new(vol_dev_path);
- new_dev_path = g_string_insert_c(new_dev_path, 9, 'r');
-
-
- *fd = open((char *)new_dev_path, O_RDONLY | O_NONBLOCK);
-
- ioctl (*fd, CDROMREADTOCHDR, &header);
- entry.cdte_track = 1;
- entry.cdte_format = CDROM_LBA;
- audio = TRUE;
- while(entry.cdte_track<=header.cdth_trk1 && audio) {
+ /* For ioctl call to work dev_path has to be /vol/dev/rdsk.
+ * There has to be a nicer way to do this.
+ */
+ new_dev_path = g_string_new (vol_dev_path);
+ new_dev_path = g_string_insert_c (new_dev_path, 9, 'r');
+ *fd = open (new_dev_path.str, O_RDONLY | O_NONBLOCK);
+ g_string_free (new_dev_path, TRUE);
- ioctl (*fd, CDROMREADTOCENTRY, &entry);
- if(entry.cdte_ctrl & CDROM_DATA_TRACK)
- audio = FALSE;
- entry.cdte_track++;
+ if (*fd < 0) {
+ return CDS_DATA_1;
}
- g_string_free(new_dev_path, TRUE);
+ if (ioctl (*fd, CDROMREADTOCHDR, &header) == 0) {
+ return CDS_DATA_1;
+ }
- if(audio)
- return(CDS_AUDIO);
+ type = CDS_DATA_1;
+
+ for (entry.cdte_track = 1;
+ entry.cdte_track <= header.cdth_trk1;
+ entry.cdte_track++) {
+ entry.cdte_format = CDROM_LBA;
+ if (ioctl (*fd, CDROMREADTOCENTRY, &entry) == 0) {
+ if (entry.cdte_ctrl & CDROM_DATA_TRACK) {
+ type = CDS_AUDIO;
+ break;
+ }
+ }
+ }
- return(CDS_DATA_1);
+ return type;
}
-#endif
+#endif
static void
cdrom_ioctl_get_info (int fd)
@@ -1233,7 +1190,6 @@ cdrom_ioctl_get_info (int fd)
static gboolean
mount_volume_iso9660_add (NautilusVolume *volume)
{
-
#ifndef SOLARIS_MNT
int fd;
@@ -1249,7 +1205,7 @@ mount_volume_iso9660_add (NautilusVolume *volume)
cdrom_ioctl_get_info (fd);
close (fd);
-#endif /* #ifndef SOLARIS_MNT */
+#endif
volume->type = NAUTILUS_VOLUME_CDROM;
@@ -1376,22 +1332,6 @@ find_volumes (NautilusVolumeMonitor *monitor)
monitor);
}
-#if 0
-void
-nautilus_volume_monitor_each_volume (NautilusVolumeMonitor *monitor,
- NautilusEachVolumeFunction function,
- gpointer context)
-{
- GList *p;
-
- for (p = monitor->details->mounts; p != NULL; p = p->next) {
- if ((* function) ((NautilusVolume *) p->data, context)) {
- break;
- }
- }
-}
-#endif
-
void
nautilus_volume_monitor_each_mounted_volume (NautilusVolumeMonitor *monitor,
NautilusEachVolumeFunction function,
@@ -1434,9 +1374,9 @@ static const char *volrmmount_locations [] = {
};
#define MOUNT_COMMAND volrmmount_locations
-#define MOUNT_SEPERATOR " -i "
+#define MOUNT_SEPARATOR " -i "
#define UMOUNT_COMMAND volrmmount_locations
-#define UMOUNT_SEPERATOR " -e "
+#define UMOUNT_SEPARATOR " -e "
#else
@@ -1453,9 +1393,9 @@ static const char *umount_known_locations [] = {
};
#define MOUNT_COMMAND mount_known_locations
-#define MOUNT_SEPERATOR " "
+#define MOUNT_SEPARATOR " "
#define UMOUNT_COMMAND umount_known_locations
-#define UMOUNT_SEPERATOR " "
+#define UMOUNT_SEPARATOR " "
#endif /* USE_VOLRMMOUNT */
@@ -1503,7 +1443,7 @@ typedef struct {
typedef struct {
char *message;
char *detailed_message;
- char *title;
+ const char *title;
} MountStatusInfo;
@@ -1517,7 +1457,6 @@ display_mount_status (gpointer callback_data)
g_free (info->message);
g_free (info->detailed_message);
- g_free (info->title);
g_free (info);
return FALSE;
@@ -1527,34 +1466,33 @@ static void
close_error_pipe (gboolean mount, const char *mount_path)
{
char *message;
- const char *title;
char detailed_msg[MAX_PIPE_SIZE];
- int length = 0;
+ int length;
gboolean is_floppy;
MountStatusInfo *info;
-
- if (mount) {
- title = _("Mount Error");
- } else {
- title = _("Unmount Error");
+
+ if (old_error < 0) {
+ return;
}
-
- if (old_error >= 0) {
- close (2);
- dup (old_error);
- close (old_error);
-
- do {
- length = read (error_pipe[0], detailed_msg, MAX_PIPE_SIZE);
- } while (length < 0);
-
- if (length >= 0) {
- detailed_msg[length] = 0;
- }
-
- close (error_pipe[0]);
+
+ close (2);
+ dup (old_error);
+ close (old_error);
+
+ /* FIXME: This keeps reading into the same buffer over and
+ * over again and makes no attempt to save bytes from any
+ * calls other than the last read call.
+ */
+ do {
+ length = read (error_pipe[0], detailed_msg, MAX_PIPE_SIZE);
+ } while (length < 0);
+
+ if (length >= 0) {
+ detailed_msg[length] = 0;
}
+ close (error_pipe[0]);
+
/* No output to show */
if (length == 0) {
return;
@@ -1605,13 +1543,11 @@ close_error_pipe (gboolean mount, const char *mount_path)
/* Set up info and pass it to callback to display dialog. We do this because this
routine may be called from a thread */
info = g_new0 (MountStatusInfo, 1);
- info->message = g_strdup (message);
+ info->message = message;
info->detailed_message = g_strdup (detailed_msg);
- info->title = g_strdup (title);
+ info->title = mount ? _("Mount Error") : _("Unmount Error");
gtk_idle_add (display_mount_status, info);
-
- g_free (message);
}
@@ -1667,19 +1603,19 @@ nautilus_volume_monitor_mount_unmount_removable (NautilusVolumeMonitor *monitor,
if (name != NULL) {
name = name + 1;
} else {
- name = mount_point;
+ name = mount_point;
}
#else
name = mount_point;
#endif /* USE_VOLRMMOUNT */
-
+
if (should_mount) {
command = find_command (MOUNT_COMMAND);
- command_string = g_strconcat (command, MOUNT_SEPERATOR, name, NULL);
+ command_string = g_strconcat (command, MOUNT_SEPARATOR, name, NULL);
} else {
command = find_command (UMOUNT_COMMAND);
- command_string = g_strconcat (command, UMOUNT_SEPERATOR, name, NULL);
+ command_string = g_strconcat (command, UMOUNT_SEPARATOR, name, NULL);
}
mount_info = g_new0 (MountThreadInfo, 1);
@@ -1883,7 +1819,7 @@ mount_volume_add_filesystem (NautilusVolume *volume, GList *volume_list)
{
gboolean mounted = FALSE;
- if (nautilus_str_has_prefix (volume->device_path, FLOPPY_DEVICE_PATH_PREFIX)) {
+ if (nautilus_str_has_prefix (volume->device_path, floppy_device_path_prefix)) {
mounted = mount_volume_floppy_add (volume);
} else if (strcmp (volume->filesystem, "affs") == 0) {
mounted = mount_volume_affs_add (volume);
@@ -1931,7 +1867,7 @@ mount_volume_add_filesystem (NautilusVolume *volume, GList *volume_list)
#ifndef SOLARIS_MNT
volume->is_removable = volume_is_removable (volume);
volume->is_read_only = volume_is_read_only (volume);
-#endif /* SOLARIS_MNT */
+#endif
mount_volume_get_name (volume);
volume_list = g_list_append (volume_list, volume);
} else {
diff --git a/libnautilus-private/nautilus-global-preferences.c b/libnautilus-private/nautilus-global-preferences.c
index 14ad7312b..918fadd4f 100644
--- a/libnautilus-private/nautilus-global-preferences.c
+++ b/libnautilus-private/nautilus-global-preferences.c
@@ -2,7 +2,7 @@
/* nautilus-prefs-dialog.c - Implementation for preferences dialog.
- Copyright (C) 1999, 2000 Eazel, Inc.
+ Copyright (C) 1999, 2000, 2001 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -100,7 +100,10 @@ global_preferences_install_descriptions (void)
_("Open each file or folder in a separate window"));
nautilus_preferences_set_description (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
- _("Ask before emptying the Trash"));
+ _("Ask before emptying the Trash or deleting files"));
+
+ nautilus_preferences_set_description (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ _("Include a Delete command that bypasses Trash"));
nautilus_preferences_set_description (NAUTILUS_PREFERENCES_CLICK_POLICY,
_("Click Behavior"));
@@ -260,6 +263,10 @@ global_preferences_install_defaults (void)
NAUTILUS_USER_LEVEL_NOVICE,
TRUE);
+ nautilus_preferences_default_set_boolean (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ NAUTILUS_USER_LEVEL_NOVICE,
+ FALSE);
+
nautilus_preferences_default_set_integer (NAUTILUS_PREFERENCES_SHOW_TEXT_IN_ICONS,
NAUTILUS_USER_LEVEL_NOVICE,
NAUTILUS_SPEED_TRADEOFF_LOCAL_ONLY);
@@ -426,6 +433,9 @@ global_preferences_install_visibility (void)
nautilus_preferences_set_visible_user_level (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
NAUTILUS_USER_LEVEL_ADVANCED);
+ nautilus_preferences_set_visible_user_level (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ NAUTILUS_USER_LEVEL_ADVANCED);
+
nautilus_preferences_set_visible_user_level (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
NAUTILUS_USER_LEVEL_INTERMEDIATE);
@@ -612,6 +622,11 @@ global_preferences_create_dialog (void)
NAUTILUS_PREFERENCES_CONFIRM_TRASH,
NAUTILUS_PREFERENCE_ITEM_BOOLEAN);
+ nautilus_preferences_pane_add_item_to_nth_group (NAUTILUS_PREFERENCES_PANE (windows_and_desktop_pane),
+ 2,
+ NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ NAUTILUS_PREFERENCE_ITEM_BOOLEAN);
+
/* FIXME: This group clearly doesn't belong in Windows &
* Desktop, but there's no obviously-better place for it and
* it probably doesn't deserve a pane of its own.
diff --git a/libnautilus-private/nautilus-global-preferences.h b/libnautilus-private/nautilus-global-preferences.h
index ab2452e74..26678f255 100644
--- a/libnautilus-private/nautilus-global-preferences.h
+++ b/libnautilus-private/nautilus-global-preferences.h
@@ -2,7 +2,7 @@
/* nautilus-global-prefs.h - Nautilus main preferences api.
- Copyright (C) 1999, 2000 Eazel, Inc.
+ Copyright (C) 1999, 2000, 2001 Eazel, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -49,6 +49,7 @@ BEGIN_GNOME_DECLS
/* Trash options */
#define NAUTILUS_PREFERENCES_CONFIRM_TRASH "preferences/confirm_trash"
+#define NAUTILUS_PREFERENCES_ENABLE_DELETE "preferences/enable_delete"
/* Desktop options */
#define NAUTILUS_PREFERENCES_SHOW_DESKTOP "preferences/show_desktop"
diff --git a/libnautilus-private/nautilus-icon-container.c b/libnautilus-private/nautilus-icon-container.c
index 56c8154dd..32e948611 100644
--- a/libnautilus-private/nautilus-icon-container.c
+++ b/libnautilus-private/nautilus-icon-container.c
@@ -4862,21 +4862,22 @@ nautilus_icon_container_start_renaming_selected_item (NautilusIconContainer *con
gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (details->rename_widget), &icon_rect.x0, &icon_rect.y0);
gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (details->rename_widget), &icon_rect.x1, &icon_rect.y1);
- nautilus_icon_text_item_configure (
- details->rename_widget,
- (icon_rect.x0 + icon_rect.x1) / 2, /* x_center */
- icon_rect.y1, /* y_top */
- nautilus_icon_canvas_item_get_max_text_width (icon->item), /* max_text_width */
- details->label_font[details->zoom_level], /* font */
- editable_text, /* text */
- FALSE); /* allocate local copy */
+ nautilus_icon_text_item_configure
+ (details->rename_widget,
+ (icon_rect.x0 + icon_rect.x1) / 2, /* x_center */
+ icon_rect.y1, /* y_top */
+ nautilus_icon_canvas_item_get_max_text_width (icon->item), /* max_text_width */
+ details->label_font[details->zoom_level], /* font */
+ editable_text, /* text */
+ FALSE); /* allocate local copy */
nautilus_icon_text_item_start_editing (details->rename_widget);
- nautilus_icon_container_update_icon (container, icon);
gtk_signal_emit (GTK_OBJECT (container),
signals[RENAMING_ICON],
nautilus_icon_text_item_get_renaming_editable (details->rename_widget));
+
+ nautilus_icon_container_update_icon (container, icon);
/* We are in renaming mode */
details->renaming = TRUE;
diff --git a/libnautilus-private/nautilus-icon-text-item.c b/libnautilus-private/nautilus-icon-text-item.c
index 03d28357a..d1cf5388e 100644
--- a/libnautilus-private/nautilus-icon-text-item.c
+++ b/libnautilus-private/nautilus-icon-text-item.c
@@ -90,6 +90,36 @@ enum {
};
static guint iti_signals [LAST_SIGNAL] = { 0 };
+static void
+send_focus_event (Iti *iti, gboolean in)
+{
+ ItiPrivate *priv;
+ GtkWidget *widget;
+ gboolean has_focus;
+ GdkEvent fake_event;
+
+ g_assert (in == FALSE || in == TRUE);
+
+ priv = iti->priv;
+ if (priv->entry == NULL) {
+ g_assert (!in);
+ return;
+ }
+
+ widget = GTK_WIDGET (priv->entry);
+ has_focus = GTK_WIDGET_HAS_FOCUS (widget);
+ if (has_focus == in) {
+ return;
+ }
+
+ memset (&fake_event, 0, sizeof (fake_event));
+ fake_event.focus_change.type = GDK_FOCUS_CHANGE;
+ fake_event.focus_change.window = widget->window;
+ fake_event.focus_change.in = in;
+ gtk_widget_event (widget, &fake_event);
+ g_assert (GTK_WIDGET_HAS_FOCUS (widget) == in);
+}
+
/* Stops the editing state of an icon text item */
static void
iti_stop_editing (Iti *iti)
@@ -100,6 +130,8 @@ iti_stop_editing (Iti *iti)
iti->editing = FALSE;
+ send_focus_event (iti, FALSE);
+
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
gtk_signal_emit (GTK_OBJECT (iti), iti_signals[EDITING_STOPPED]);
@@ -232,7 +264,7 @@ iti_start_editing (Iti *iti)
gtk_signal_connect (GTK_OBJECT (priv->entry), "activate",
GTK_SIGNAL_FUNC (iti_entry_activate), iti);
/* Make clipboard functions cause an update the appearance of
- the icon text item iteself, since the clipboard functions
+ the icon text item itself, since the clipboard functions
will change the offscreen entry */
gtk_signal_connect_after (GTK_OBJECT (priv->entry), "changed",
GTK_SIGNAL_FUNC (iti_entry_text_changed_by_clipboard), iti);
@@ -249,6 +281,8 @@ iti_start_editing (Iti *iti)
iti->editing = TRUE;
+ send_focus_event (iti, TRUE);
+
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
gtk_signal_emit (GTK_OBJECT (iti), iti_signals[EDITING_STARTED]);
@@ -1067,13 +1101,13 @@ iti_event (GnomeCanvasItem *item, GdkEvent *event)
} else {
GTK_WIDGET_UNSET_FLAGS (item->canvas, GTK_HAS_FOCUS);
}
-
- if (iti->editing && !event->focus_change.in) {
- iti_edition_accept (iti);
- }
if (iti->editing) {
gtk_widget_event (GTK_WIDGET (priv->entry), event);
+
+ if (!event->focus_change.in) {
+ iti_edition_accept (iti);
+ }
}
return TRUE;
diff --git a/libnautilus-private/nautilus-medusa-support.c b/libnautilus-private/nautilus-medusa-support.c
index 2ae619fc4..94a079e66 100644
--- a/libnautilus-private/nautilus-medusa-support.c
+++ b/libnautilus-private/nautilus-medusa-support.c
@@ -25,16 +25,13 @@
*/
#include <config.h>
-#include <glib.h>
-
-#include <string.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <dirent.h>
+#include "nautilus-medusa-support.h"
#include "nautilus-glib-extensions.h"
-#include "nautilus-medusa-support.h"
#include "nautilus-string.h"
+#include <dirent.h>
+#include <stdio.h>
+#include <sys/types.h>
#ifdef HAVE_MEDUSA
#include <libmedusa/medusa-system-state.h>
@@ -85,7 +82,6 @@ nautilus_medusa_add_system_state_changed_callback (NautilusMedusaChangedCallback
NautilusCronStatus
nautilus_medusa_check_cron_is_enabled (void)
{
-#ifdef HAVE_PROC_PROCESS_FILES
DIR *proc_directory;
struct dirent *file;
char *stat_file_name;
@@ -93,6 +89,7 @@ nautilus_medusa_check_cron_is_enabled (void)
char stat_file_data[128];
const char *stat_file_process_name;
int process_number, bytes_read;
+ NautilusCronStatus status;
/* We figure out whether cron is running by reading the proc
directory, and checking for a process named or ending with
@@ -103,37 +100,39 @@ nautilus_medusa_check_cron_is_enabled (void)
return NAUTILUS_CRON_STATUS_UNKNOWN;
}
- file = readdir (proc_directory);
- while (file != NULL) {
+ status = NAUTILUS_CRON_STATUS_UNKNOWN;
+
+ while ((file = readdir (proc_directory)) != NULL) {
/* Process files have numbers */
- if (nautilus_str_to_int (file->d_name,
- &process_number)) {
- stat_file_name = g_strdup_printf ("/proc/%d/stat", process_number);
- stat_file = fopen (stat_file_name, "r");
- g_free (stat_file_name);
-
- if (stat_file == NULL) {
- file = readdir (proc_directory);
- continue;
- }
-
- bytes_read = fread (stat_file_data, sizeof (char), NAUTILUS_N_ELEMENTS (stat_file_data) - 1, stat_file);
- fclose (stat_file);
- stat_file_data[bytes_read] = 0;
-
- stat_file_process_name = strchr (stat_file_data, ' ') + 1;
-
- if (nautilus_str_has_prefix (stat_file_process_name, "(crond)")) {
- return NAUTILUS_CRON_STATUS_ON;
- }
+ if (!nautilus_str_to_int (file->d_name, &process_number)) {
+ continue;
+ }
+ /* Since we've seen at least one process file, we can change our state
+ * from "unknown" to "presumed off until proved otherwise".
+ */
+ status = NAUTILUS_CRON_STATUS_OFF;
+
+ stat_file_name = g_strdup_printf ("/proc/%d/stat", process_number);
+ stat_file = fopen (stat_file_name, "r");
+ g_free (stat_file_name);
+
+ if (stat_file == NULL) {
+ continue;
+ }
+
+ bytes_read = fread (stat_file_data, 1, sizeof (stat_file_data) - 1, stat_file);
+ fclose (stat_file);
+ stat_file_data[bytes_read] = '\0';
+
+ stat_file_process_name = strchr (stat_file_data, ' ');
+
+ if (nautilus_str_has_prefix (stat_file_process_name, " (crond)")) {
+ status = NAUTILUS_CRON_STATUS_ON;
+ break;
}
- file = readdir (proc_directory);
}
closedir (proc_directory);
- return NAUTILUS_CRON_STATUS_OFF;
-#else
- return NAUTILUS_CRON_STATUS_UNKNOWN;
-#endif
+ return status;
}
diff --git a/libnautilus-private/nautilus-volume-monitor.c b/libnautilus-private/nautilus-volume-monitor.c
index e32254a22..8055b44cd 100644
--- a/libnautilus-private/nautilus-volume-monitor.c
+++ b/libnautilus-private/nautilus-volume-monitor.c
@@ -2,7 +2,7 @@
/* nautilus-volume-monitor.c - Desktop volume mounting routines.
- Copyright (C) 2000 Eazel, Inc.
+ Copyright (C) 2000, 2001 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -23,8 +23,6 @@
*/
#include <config.h>
-#include <sys/types.h>
-
#include "nautilus-volume-monitor.h"
#include "nautilus-cdrom-extensions.h"
@@ -64,11 +62,13 @@
#ifdef HAVE_MNTENT_H
#include <mntent.h>
+#define MOUNT_TABLE_PATH _PATH_MNTTAB
#endif
#ifdef HAVE_SYS_MNTTAB_H
#define SOLARIS_MNT 1
#include <sys/mnttab.h>
+#define MOUNT_TABLE_PATH "/etc/mnttab"
#endif
#ifdef SOLARIS_MNT
@@ -77,7 +77,16 @@
#define USE_VOLRMMOUNT 0
#endif
+#ifndef MNTOPT_RO
+#define MNTOPT_RO "ro"
+#endif
+
+#ifndef HAVE_SETMNTENT
+#define setmntent(f,m) fopen(f,m)
+#endif
+
#ifdef HAVE_CDDA
+
#define size16 short
#define size32 int
@@ -94,48 +103,17 @@
* due to our strict error checking.
*/
char **broken_header_fix = strerror_tr;
-#endif
-
-#define CHECK_STATUS_INTERVAL 2000
-#ifdef HAVE_ETC_MNTTAB
-#define PATH_PROC_MOUNTS "/etc/mnttab"
-#define PROC_MOUNTS_SEPARATOR "\t"
#endif
-#ifdef HAVE_PROC_MOUNTS
-#define PATH_PROC_MOUNTS "/proc/mounts"
-#define PROC_MOUNTS_SEPARATOR " "
-#endif
+#define CHECK_STATUS_INTERVAL 2000
#define FLOPPY_MOUNT_PATH_PREFIX "/mnt/fd"
-#ifdef HAVE_VOL_DEV
-#define FLOPPY_DEVICE_PATH_PREFIX "/vol/dev/diskette"
-#else
-#define FLOPPY_DEVICE_PATH_PREFIX "/dev/fd"
-#endif
-
#ifdef HAVE_SYS_MNTTAB_H
-#define PATH_MOUNT_TABLE "/etc/mnttab"
-#endif
-
-#ifdef HAVE_MNTENT_H
-#define PATH_MOUNT_TABLE _PATH_MNTTAB
-#endif
-
-#ifdef HAVE_VOL
-# define MNTOPT_NOAUTO "/vol/"
-# else
-# define MNTOPT_NOAUTO "noauto"
-#endif
-
-#ifndef MNTOPT_RO
-# define MNTOPT_RO "ro"
-#endif
-
-#ifndef HAVE_SETMNTENT
-#define setmntent(f,m) fopen(f,m)
+typedef struct mnttab MountTableEntry;
+#else
+typedef struct mntent MountTableEntry;
#endif
struct NautilusVolumeMonitorDetails
@@ -147,6 +125,8 @@ struct NautilusVolumeMonitorDetails
};
static NautilusVolumeMonitor *global_volume_monitor = NULL;
+static const char *floppy_device_path_prefix;
+static const char *noauto_string;
/* The NautilusVolumeMonitor signals. */
@@ -182,7 +162,7 @@ static GList *mount_volume_add_filesystem (NautilusVolume *volume,
static NautilusVolume *create_volume (const char *device_path,
const char *mount_path,
const char *filesystem);
-static NautilusVolume *copy_volume (NautilusVolume *volume);
+static NautilusVolume *copy_volume (NautilusVolume *volume);
static void find_volumes (NautilusVolumeMonitor *monitor);
static void free_mount_list (GList *mount_list);
static GList *get_removable_volumes (void);
@@ -194,7 +174,8 @@ static gboolean locate_audio_cd (void);
#endif
#ifdef SOLARIS_MNT
-static int get_cdrom_type_solaris(char *vol_dev_path, int* fd) ;
+static int get_cdrom_type_solaris (const char *vol_dev_path,
+ int *fd);
#endif
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusVolumeMonitor,
@@ -242,7 +223,19 @@ nautilus_volume_monitor_initialize_class (NautilusVolumeMonitorClass *klass)
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
- gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+ gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+
+ /* Check environment a bit. */
+ if (g_file_exists ("/vol/dev")) {
+ floppy_device_path_prefix = "/vol/dev/diskette/";
+ } else {
+ floppy_device_path_prefix = "/dev/fd/";
+ }
+ if (g_file_exists ("/vol")) {
+ noauto_string = "/vol/";
+ } else {
+ noauto_string = "/dev/fd/";
+ }
}
static void
@@ -330,31 +323,20 @@ nautilus_volume_monitor_get_removable_volumes (NautilusVolumeMonitor *monitor)
}
-#ifdef HAVE_SYS_MNTTAB_H
-
-static gboolean
-has_removable_mntent_options (struct mnttab *ent)
-{
-
-#else
-
static gboolean
-has_removable_mntent_options (struct mntent *ent)
+has_removable_mntent_options (MountTableEntry *ent)
{
-
-#endif /* HAVE_SYS_MNTTAB_H */
-
/* Use "owner" or "user" or "users" as our way of determining a removable volume */
if (hasmntopt (ent, "user") != NULL
|| hasmntopt (ent, "users") != NULL
|| hasmntopt (ent, "owner") != NULL) {
- return TRUE;
+ return TRUE;
}
-#if SOLARIS_MNT && HAVE_VOL
- if (strstr (ent->mnt_special, "/vol/") == ent->mnt_special) {
- return TRUE;
- }
+#ifdef SOLARIS_MNT
+ if (nautilus_str_has_prefix (ent->mnt_special, "/vol/")) {
+ return TRUE;
+ }
#endif
return FALSE;
@@ -372,36 +354,38 @@ get_removable_volumes (void)
{
FILE *file;
GList *volumes;
-#if HAVE_SYS_MNTTAB_H
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-#else
- struct mntent *ent;
-#endif /* HAVE_SYS_MNTTAB_H */
+ MountTableEntry *ent;
NautilusVolume *volume;
+#if HAVE_SYS_MNTTAB_H
+ MountTableEntry ent_storage;
+#endif
volumes = NULL;
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return NULL;
}
#if HAVE_SYS_MNTTAB_H
+ ent = &ent_storage;
while (! getmntent (file, ent)) {
/* On Solaris look for /vol/ for determining a removable volume */
- if (strstr (ent->mnt_special, MNTOPT_NOAUTO) == ent->mnt_special) {
+ if (nautilus_str_has_prefix (ent->mnt_special, noauto_string)) {
volume = create_volume (ent->mnt_special, ent->mnt_mountp, ent->mnt_fstype);
volume->is_removable = TRUE;
- volume->is_read_only = (hasmntopt (ent, MNTOPT_RO) !=NULL);
+ volume->is_read_only = hasmntopt (ent, MNTOPT_RO) != NULL;
+ volumes = mount_volume_add_filesystem (volume, volumes);
+ }
+ }
#else
while ((ent = getmntent (file)) != NULL) {
if (has_removable_mntent_options (ent)) {
volume = create_volume (ent->mnt_fsname, ent->mnt_dir, ent->mnt_type);
-#endif /* HAVE_SYS_MNTTAB_H */
volumes = mount_volume_add_filesystem (volume, volumes);
- }
+ }
}
+#endif /* HAVE_SYS_MNTTAB_H */
fclose (file);
@@ -419,26 +403,24 @@ static gboolean
volume_is_removable (const NautilusVolume *volume)
{
FILE *file;
+ MountTableEntry *ent;
#if HAVE_SYS_MNTTAB_H
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-#else
- struct mntent *ent;
-#endif /* HAVE_SYS_MNTTAB_H */
+ MountTableEntry ent_storage;
+#endif
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return FALSE;
}
/* Search for our device in the fstab */
#if HAVE_SYS_MNTTAB_H
+ MountTableEntry *ent = &ent_storage;
while (!getmntent (file, ent)) {
if (strcmp (volume->device_path, ent->mnt_special) == 0) {
/* On Solaris look for /vol/ for determining
a removable volume */
- if (strstr (ent->mnt_special, MNTOPT_NOAUTO)
- == ent->mnt_special) {
+ if (nautilus_str_has_prefix (ent->mnt_special, noauto_string)) {
fclose (file);
return TRUE;
}
@@ -452,7 +434,6 @@ volume_is_removable (const NautilusVolume *volume)
return TRUE;
}
}
-
#endif /* HAVE_SYS_MNTTAB_H */
fclose (file);
@@ -463,18 +444,19 @@ static gboolean
volume_is_read_only (const NautilusVolume *volume)
{
FILE *file;
+ MountTableEntry *ent;
#if HAVE_SYS_MNTTAB_H
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ MountTableEntry ent_storage;
+
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return FALSE;
}
/* Search for our device in the fstab */
- while (!getmntent (file, ent)) {
+ ent = &ent_storage;
+ while (!getmntent (file, ent)) {
if (strcmp (volume->device_path, ent->mnt_special) == 0) {
if (strstr (ent->mnt_mntopts, MNTOPT_RO) != NULL) {
fclose (file);
@@ -483,9 +465,7 @@ volume_is_read_only (const NautilusVolume *volume)
}
}
#else
- struct mntent *ent;
-
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return FALSE;
}
@@ -629,14 +609,12 @@ mount_volume_get_cdrom_name (NautilusVolume *volume)
{
int fd, disctype;
- #ifdef SOLARIS_MNT
- disctype = get_cdrom_type_solaris(volume->device_path, &fd);
-
- #else
+#if SOLARIS_MNT
+ disctype = get_cdrom_type_solaris (volume->device_path, &fd);
+#else
fd = open (volume->device_path, O_RDONLY|O_NONBLOCK);
disctype = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT);
-
- #endif
+#endif
switch (disctype) {
case CDS_AUDIO:
@@ -672,7 +650,7 @@ mount_volume_activate_cdda (NautilusVolumeMonitor *monitor, NautilusVolume *volu
int fd, disctype;
#ifdef SOLARIS_MNT
- disctype = get_cdrom_type_solaris(volume->device_path, &fd);
+ disctype = get_cdrom_type_solaris (volume->device_path, &fd);
#else
fd = open (volume->device_path, O_RDONLY | O_NONBLOCK);
disctype = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT);
@@ -693,7 +671,7 @@ mount_volume_activate_cdrom (NautilusVolumeMonitor *monitor, NautilusVolume *vol
{
int fd, disctype;
#ifdef SOLARIS_MNT
- disctype = get_cdrom_type_solaris(volume->device_path, &fd);
+ disctype = get_cdrom_type_solaris (volume->device_path, &fd);
#else
fd = open (volume->device_path, O_RDONLY | O_NONBLOCK);
disctype = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT);
@@ -918,19 +896,18 @@ build_volume_list_delta (GList *list_one, GList *list_two)
GList *ptrOne, *ptrTwo;
GList *new_list;
NautilusVolume *volOne, *volTwo, *new_volume;
- int index;
gboolean found_match;
new_list = NULL;
- for (ptrOne = list_one, index = 0; ptrOne != NULL; ptrOne = ptrOne->next, index++) {
+ for (ptrOne = list_one; ptrOne != NULL; ptrOne = ptrOne->next) {
found_match = FALSE;
- volOne = (NautilusVolume *)ptrOne->data;
+ volOne = (NautilusVolume *) ptrOne->data;
for (ptrTwo = list_two; ptrTwo != NULL; ptrTwo = ptrTwo->next) {
- volTwo = (NautilusVolume *)ptrTwo->data;
+ volTwo = (NautilusVolume *) ptrTwo->data;
/* Check and see if mount point from list one is in list two */
if (strcmp (volOne->mount_path, volTwo->mount_path) == 0) {
@@ -958,32 +935,36 @@ get_current_mount_list (void)
FILE *fh;
#ifdef SOLARIS_MNT
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-
- fh = setmntent (PATH_MOUNT_TABLE, "r");
- if (fh == NULL) {
- return NULL;
- }
- while (! getmntent (fh, ent)) {
- volume = create_volume (ent->mnt_special, ent->mnt_mountp, ent->mnt_fstype);
- volume->is_removable = has_removable_mntent_options(ent);
- volume->is_read_only = (hasmntopt (ent, MNTOPT_RO) != NULL);
- current_mounts = mount_volume_add_filesystem (volume, current_mounts);
- }
+ MountTableEntry ent_storage;
+ MountTableEntry *ent = &ent_storage;
+
+ fh = setmntent (MOUNT_TABLE_PATH, "r");
+ if (fh != NULL) {
+ while (! getmntent (fh, ent)) {
+ volume = create_volume (ent->mnt_special, ent->mnt_mountp, ent->mnt_fstype);
+ volume->is_removable = has_removable_mntent_options(ent);
+ volume->is_read_only = hasmntopt (ent, MNTOPT_RO) != NULL;
+ current_mounts = mount_volume_add_filesystem (volume, current_mounts);
+ }
+ }
#else
char line[PATH_MAX * 3];
char device_name[sizeof (line)];
NautilusStringList *list;
char *device_path, *mount_path, *filesystem;
+ const char *separator;
- /* Open /proc/mounts */
- fh = fopen (PATH_PROC_MOUNTS, "r");
+ fh = fopen ("/etc/mnttab", "r");
+ separator = "\t";
+ if (fh == NULL) {
+ fh = fopen ("/proc/mounts", "r");
+ separator = " ";
+ }
g_return_val_if_fail (fh != NULL, NULL);
while (fgets (line, sizeof(line), fh)) {
if (sscanf (line, "%s", device_name) == 1) {
- list = nautilus_string_list_new_from_tokens (line, PROC_MOUNTS_SEPARATOR, FALSE);
+ list = nautilus_string_list_new_from_tokens (line, separator, FALSE);
if (list != NULL) {
/* The string list needs to have at least 3 items per line.
* We need to find at least device path, mount path and file system type.
@@ -1002,9 +983,12 @@ get_current_mount_list (void)
}
}
}
-
#endif /* SOLARIS_MNT */
+ if (fh != NULL) {
+ fclose (fh);
+ }
+
#ifdef HAVE_CDDA
/* CD Audio tricks */
if (locate_audio_cd ()) {
@@ -1014,8 +998,6 @@ get_current_mount_list (void)
}
#endif
- fclose (fh);
-
return current_mounts;
}
@@ -1035,7 +1017,6 @@ update_modifed_volume_name (GList *mount_list, NautilusVolume *volume)
}
}
-
static gboolean
mount_lists_are_identical (GList *list_a, GList *list_b)
{
@@ -1043,7 +1024,6 @@ mount_lists_are_identical (GList *list_a, GList *list_b)
NautilusVolume *volumeOne, *volumeTwo;
for (p = list_a, q = list_b; p != NULL && q != NULL; p = p->next, q = q->next) {
-
volumeOne = p->data;
volumeTwo = q->data;
@@ -1058,17 +1038,7 @@ static void
verify_current_mount_state (NautilusVolumeMonitor *monitor)
{
GList *new_mounts, *old_mounts, *current_mounts;
- GList *saved_mount_list;
- gboolean free_new_mounts;
-
- new_mounts = old_mounts = current_mounts = saved_mount_list = NULL;
-
- /* Free the new mount list only if it is not a copy of the current mount list. */
- if (monitor->details->mounts != NULL) {
- free_new_mounts = TRUE;
- } else {
- free_new_mounts = FALSE;
- }
+ GList *saved_mount_list, *p;
/* Get all current mounts */
current_mounts = get_current_mount_list ();
@@ -1082,17 +1052,9 @@ verify_current_mount_state (NautilusVolumeMonitor *monitor)
return;
}
- /* If saved mounts is NULL, this is the first time we have been here. New mounts
- * are the same as current mounts
- */
- if (monitor->details->mounts == NULL) {
- new_mounts = current_mounts;
- old_mounts = NULL;
- } else {
- /* Create list of new and old mounts */
- new_mounts = build_volume_list_delta (current_mounts, monitor->details->mounts);
- old_mounts = build_volume_list_delta (monitor->details->mounts, current_mounts);
- }
+ /* Create list of new and old mounts */
+ new_mounts = build_volume_list_delta (current_mounts, monitor->details->mounts);
+ old_mounts = build_volume_list_delta (monitor->details->mounts, current_mounts);
/* Stash a copy of the current mount list for updating mount names later. */
saved_mount_list = monitor->details->mounts;
@@ -1101,36 +1063,24 @@ verify_current_mount_state (NautilusVolumeMonitor *monitor)
monitor->details->mounts = current_mounts;
/* Check and see if we have new mounts to add */
- if (new_mounts != NULL) {
- GList *p;
- for (p = new_mounts; p != NULL; p = p->next) {
- mount_volume_activate (monitor, (NautilusVolume *)p->data);
- }
- }
+ for (p = new_mounts; p != NULL; p = p->next) {
+ mount_volume_activate (monitor, (NautilusVolume *)p->data);
+ }
/* Check and see if we have old mounts to remove */
- if (old_mounts != NULL) {
- GList *p;
-
- for (p = old_mounts; p != NULL; p = p->next) {
- /* First we need to update the volume names in this list with modified names in the old list. Names in
- * the old list may have been modifed due to icon name conflicts. The list of old mounts is unable
- * take this into account when it is created
- */
- update_modifed_volume_name (saved_mount_list, (NautilusVolume *)p->data);
-
- /* Deactivate the volume. */
- mount_volume_deactivate (monitor, (NautilusVolume *)p->data);
- }
- free_mount_list (old_mounts);
+ for (p = old_mounts; p != NULL; p = p->next) {
+ /* First we need to update the volume names in this list with modified names in the old list. Names in
+ * the old list may have been modifed due to icon name conflicts. The list of old mounts is unable
+ * take this into account when it is created
+ */
+ update_modifed_volume_name (saved_mount_list, (NautilusVolume *) p->data);
+
+ /* Deactivate the volume. */
+ mount_volume_deactivate (monitor, (NautilusVolume *) p->data);
}
- /* Free the new mount list only if it is not a copy of the current mount list.
- * It will be a copy if there are no previous mounts.
- */
- if (free_new_mounts) {
- free_mount_list (new_mounts);
- }
+ free_mount_list (old_mounts);
+ free_mount_list (new_mounts);
free_mount_list (saved_mount_list);
}
@@ -1148,6 +1098,7 @@ static gboolean
mount_volume_floppy_add (NautilusVolume *volume)
{
volume->type = NAUTILUS_VOLUME_FLOPPY;
+
return TRUE;
}
@@ -1184,43 +1135,49 @@ mount_volume_msdos_add (NautilusVolume *volume)
}
#ifdef SOLARIS_MNT
-static int get_cdrom_type_solaris(char *vol_dev_path, int* fd) {
+static int
+get_cdrom_type_solaris (const char *vol_dev_path, int* fd)
+{
GString *new_dev_path;
struct cdrom_tocentry entry;
- struct cdrom_tochdr header;
- gboolean audio;
-
-/* For ioctl call to work dev_path has to be /vol/dev/rdsk....
- there has to be a nicer way to do this. */
+ struct cdrom_tochdr header;
+ int type;
- new_dev_path = g_string_new(vol_dev_path);
- new_dev_path = g_string_insert_c(new_dev_path, 9, 'r');
-
-
- *fd = open((char *)new_dev_path, O_RDONLY | O_NONBLOCK);
-
- ioctl (*fd, CDROMREADTOCHDR, &header);
- entry.cdte_track = 1;
- entry.cdte_format = CDROM_LBA;
- audio = TRUE;
- while(entry.cdte_track<=header.cdth_trk1 && audio) {
+ /* For ioctl call to work dev_path has to be /vol/dev/rdsk.
+ * There has to be a nicer way to do this.
+ */
+ new_dev_path = g_string_new (vol_dev_path);
+ new_dev_path = g_string_insert_c (new_dev_path, 9, 'r');
+ *fd = open (new_dev_path.str, O_RDONLY | O_NONBLOCK);
+ g_string_free (new_dev_path, TRUE);
- ioctl (*fd, CDROMREADTOCENTRY, &entry);
- if(entry.cdte_ctrl & CDROM_DATA_TRACK)
- audio = FALSE;
- entry.cdte_track++;
+ if (*fd < 0) {
+ return CDS_DATA_1;
}
- g_string_free(new_dev_path, TRUE);
+ if (ioctl (*fd, CDROMREADTOCHDR, &header) == 0) {
+ return CDS_DATA_1;
+ }
- if(audio)
- return(CDS_AUDIO);
+ type = CDS_DATA_1;
+
+ for (entry.cdte_track = 1;
+ entry.cdte_track <= header.cdth_trk1;
+ entry.cdte_track++) {
+ entry.cdte_format = CDROM_LBA;
+ if (ioctl (*fd, CDROMREADTOCENTRY, &entry) == 0) {
+ if (entry.cdte_ctrl & CDROM_DATA_TRACK) {
+ type = CDS_AUDIO;
+ break;
+ }
+ }
+ }
- return(CDS_DATA_1);
+ return type;
}
-#endif
+#endif
static void
cdrom_ioctl_get_info (int fd)
@@ -1233,7 +1190,6 @@ cdrom_ioctl_get_info (int fd)
static gboolean
mount_volume_iso9660_add (NautilusVolume *volume)
{
-
#ifndef SOLARIS_MNT
int fd;
@@ -1249,7 +1205,7 @@ mount_volume_iso9660_add (NautilusVolume *volume)
cdrom_ioctl_get_info (fd);
close (fd);
-#endif /* #ifndef SOLARIS_MNT */
+#endif
volume->type = NAUTILUS_VOLUME_CDROM;
@@ -1376,22 +1332,6 @@ find_volumes (NautilusVolumeMonitor *monitor)
monitor);
}
-#if 0
-void
-nautilus_volume_monitor_each_volume (NautilusVolumeMonitor *monitor,
- NautilusEachVolumeFunction function,
- gpointer context)
-{
- GList *p;
-
- for (p = monitor->details->mounts; p != NULL; p = p->next) {
- if ((* function) ((NautilusVolume *) p->data, context)) {
- break;
- }
- }
-}
-#endif
-
void
nautilus_volume_monitor_each_mounted_volume (NautilusVolumeMonitor *monitor,
NautilusEachVolumeFunction function,
@@ -1434,9 +1374,9 @@ static const char *volrmmount_locations [] = {
};
#define MOUNT_COMMAND volrmmount_locations
-#define MOUNT_SEPERATOR " -i "
+#define MOUNT_SEPARATOR " -i "
#define UMOUNT_COMMAND volrmmount_locations
-#define UMOUNT_SEPERATOR " -e "
+#define UMOUNT_SEPARATOR " -e "
#else
@@ -1453,9 +1393,9 @@ static const char *umount_known_locations [] = {
};
#define MOUNT_COMMAND mount_known_locations
-#define MOUNT_SEPERATOR " "
+#define MOUNT_SEPARATOR " "
#define UMOUNT_COMMAND umount_known_locations
-#define UMOUNT_SEPERATOR " "
+#define UMOUNT_SEPARATOR " "
#endif /* USE_VOLRMMOUNT */
@@ -1503,7 +1443,7 @@ typedef struct {
typedef struct {
char *message;
char *detailed_message;
- char *title;
+ const char *title;
} MountStatusInfo;
@@ -1517,7 +1457,6 @@ display_mount_status (gpointer callback_data)
g_free (info->message);
g_free (info->detailed_message);
- g_free (info->title);
g_free (info);
return FALSE;
@@ -1527,34 +1466,33 @@ static void
close_error_pipe (gboolean mount, const char *mount_path)
{
char *message;
- const char *title;
char detailed_msg[MAX_PIPE_SIZE];
- int length = 0;
+ int length;
gboolean is_floppy;
MountStatusInfo *info;
-
- if (mount) {
- title = _("Mount Error");
- } else {
- title = _("Unmount Error");
+
+ if (old_error < 0) {
+ return;
}
-
- if (old_error >= 0) {
- close (2);
- dup (old_error);
- close (old_error);
-
- do {
- length = read (error_pipe[0], detailed_msg, MAX_PIPE_SIZE);
- } while (length < 0);
-
- if (length >= 0) {
- detailed_msg[length] = 0;
- }
-
- close (error_pipe[0]);
+
+ close (2);
+ dup (old_error);
+ close (old_error);
+
+ /* FIXME: This keeps reading into the same buffer over and
+ * over again and makes no attempt to save bytes from any
+ * calls other than the last read call.
+ */
+ do {
+ length = read (error_pipe[0], detailed_msg, MAX_PIPE_SIZE);
+ } while (length < 0);
+
+ if (length >= 0) {
+ detailed_msg[length] = 0;
}
+ close (error_pipe[0]);
+
/* No output to show */
if (length == 0) {
return;
@@ -1605,13 +1543,11 @@ close_error_pipe (gboolean mount, const char *mount_path)
/* Set up info and pass it to callback to display dialog. We do this because this
routine may be called from a thread */
info = g_new0 (MountStatusInfo, 1);
- info->message = g_strdup (message);
+ info->message = message;
info->detailed_message = g_strdup (detailed_msg);
- info->title = g_strdup (title);
+ info->title = mount ? _("Mount Error") : _("Unmount Error");
gtk_idle_add (display_mount_status, info);
-
- g_free (message);
}
@@ -1667,19 +1603,19 @@ nautilus_volume_monitor_mount_unmount_removable (NautilusVolumeMonitor *monitor,
if (name != NULL) {
name = name + 1;
} else {
- name = mount_point;
+ name = mount_point;
}
#else
name = mount_point;
#endif /* USE_VOLRMMOUNT */
-
+
if (should_mount) {
command = find_command (MOUNT_COMMAND);
- command_string = g_strconcat (command, MOUNT_SEPERATOR, name, NULL);
+ command_string = g_strconcat (command, MOUNT_SEPARATOR, name, NULL);
} else {
command = find_command (UMOUNT_COMMAND);
- command_string = g_strconcat (command, UMOUNT_SEPERATOR, name, NULL);
+ command_string = g_strconcat (command, UMOUNT_SEPARATOR, name, NULL);
}
mount_info = g_new0 (MountThreadInfo, 1);
@@ -1883,7 +1819,7 @@ mount_volume_add_filesystem (NautilusVolume *volume, GList *volume_list)
{
gboolean mounted = FALSE;
- if (nautilus_str_has_prefix (volume->device_path, FLOPPY_DEVICE_PATH_PREFIX)) {
+ if (nautilus_str_has_prefix (volume->device_path, floppy_device_path_prefix)) {
mounted = mount_volume_floppy_add (volume);
} else if (strcmp (volume->filesystem, "affs") == 0) {
mounted = mount_volume_affs_add (volume);
@@ -1931,7 +1867,7 @@ mount_volume_add_filesystem (NautilusVolume *volume, GList *volume_list)
#ifndef SOLARIS_MNT
volume->is_removable = volume_is_removable (volume);
volume->is_read_only = volume_is_read_only (volume);
-#endif /* SOLARIS_MNT */
+#endif
mount_volume_get_name (volume);
volume_list = g_list_append (volume_list, volume);
} else {
diff --git a/libnautilus/nautilus-clipboard-ui.xml b/libnautilus/nautilus-clipboard-ui.xml
index 431cb2017..b673c5a8f 100644
--- a/libnautilus/nautilus-clipboard-ui.xml
+++ b/libnautilus/nautilus-clipboard-ui.xml
@@ -1,33 +1,43 @@
<Root>
<commands>
- <cmd name="Cut" accel="*Control*x" sensitive="1"/>
- <cmd name="Copy" accel="*Control*c" sensitive="1"/>
- <cmd name="Paste" accel="*Control*v" sensitive="1"/>
- <cmd name="Clear" sensitive="1"/>
- <cmd name="Select All" accel="*Control*a" sensitive="1"/>
+ <cmd name="Cut"
+ _label="Cut Text"
+ accel="*Control*x"
+ _tip="Cut the selected text to the clipboard"/>
+ <cmd name="Copy"
+ _label="Copy Text"
+ accel="*Control*c"
+ _tip="Copy the selected text to the clipboard"/>
+ <cmd name="Paste"
+ _label="Paste Text"
+ _tip="Paste the text stored on the clipboard"
+ accel="*Control*v"/>
+ <cmd name="Clear"
+ _tip="Remove the selected text without putting it on the clipboard"
+ _label="Clear Text"/>
+ <cmd name="Select All"
+ _label="Select All"
+ _tip="Select all the text in a text field"
+ accel="*Control*a"/>
</commands>
<menu>
<submenu name="Edit">
<menuitem name="Cut"
_label="Cut _Text"
- _tip="Cut the selected text to the clipboard"
pixtype="stock" pixname="Cut"
verb="Cut"/>
<menuitem name="Copy"
_label="_Copy Text"
- _tip="Copy the selected text to the clipboard"
pixtype="stock" pixname="Copy"
verb="Copy"/>
<menuitem name="Paste"
_label="_Paste Text"
- _tip="Paste the text stored on the clipboard"
pixtype="stock" pixname="Paste"
verb="Paste"/>
<menuitem name="Clear"
_label="C_lear Text"
- _tip="Remove the selected text without putting it on the clipboard"
pixtype="stock" pixname="Clear"
verb="Clear"/>
<menuitem name="Select All"
@@ -35,4 +45,5 @@
verb="Select All"/>
</submenu>
</menu>
+
</Root>
diff --git a/libnautilus/nautilus-clipboard.c b/libnautilus/nautilus-clipboard.c
index badb92339..d13682281 100644
--- a/libnautilus/nautilus-clipboard.c
+++ b/libnautilus/nautilus-clipboard.c
@@ -205,6 +205,12 @@ set_paste_sensitive_if_clipboard_contains_data (BonoboUIComponent *component)
* process, which may not be the case, and we may still be
* able to paste data.
*/
+ /* FIXME: PRIMARY is wrong here. We are interested in
+ * CLIPBOARD, not PRIMARY.
+ */
+ /* FIXME: This doesn't tell us what kind of data is on the
+ * clipboard, and we only want to be sensitive if it's text.
+ */
clipboard_contains_data =
(gdk_selection_owner_get (GDK_SELECTION_PRIMARY) != NULL);
@@ -350,13 +356,6 @@ focus_changed_callback (GtkWidget *widget,
}
static void
-grab_focus_callback (GtkWidget *widget,
- gpointer data)
-{
- focus_changed_callback (widget, NULL, data);
-}
-
-static void
selection_changed_callback (GtkWidget *widget,
gpointer callback_data)
{
@@ -440,16 +439,13 @@ nautilus_clipboard_set_up_editable (GtkEditable *target,
g_return_if_fail (GTK_IS_EDITABLE (target));
g_return_if_fail (ui_container != CORBA_OBJECT_NIL);
+ target_data = initialize_clipboard_component_with_callback_data
+ (target,
+ ui_container,
+ shares_selection_changes);
- target_data = initialize_clipboard_component_with_callback_data (target,
- ui_container,
- shares_selection_changes);
gtk_signal_connect_after (GTK_OBJECT (target), "focus_in_event",
focus_changed_callback, target_data);
- /* Allow widgets that are already focused when they set up tell the clipboard
- to manually consider them */
- gtk_signal_connect (GTK_OBJECT (target), "grab_focus",
- grab_focus_callback, target_data);
gtk_signal_connect_after (GTK_OBJECT (target), "focus_out_event",
focus_changed_callback, target_data);
@@ -489,7 +485,6 @@ first_focus_callback (GtkWidget *widget,
widget_was_set_up_with_selection_sensitivity (widget));
}
-
static void
control_destroyed_callback (GtkObject *object,
gpointer callback_data)
@@ -506,6 +501,14 @@ nautilus_clipboard_set_up_editable_in_control (GtkEditable *target,
g_return_if_fail (GTK_IS_EDITABLE (target));
g_return_if_fail (BONOBO_IS_CONTROL (control));
+ if (GTK_WIDGET_HAS_FOCUS (target)) {
+ nautilus_clipboard_set_up_editable
+ (target,
+ bonobo_control_get_remote_ui_container (control),
+ shares_selection_changes);
+ return;
+ }
+
/* Use lazy initialization, so that we wait until after
* embedding. At that point, the UI container will be set up,
* but it's not necessarily set up now.
diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c
index fcf0c6641..eeaace714 100644
--- a/src/file-manager/fm-directory-view.c
+++ b/src/file-manager/fm-directory-view.c
@@ -98,11 +98,15 @@
#define FM_DIRECTORY_VIEW_COMMAND_REMOVE_CUSTOM_ICONS "/commands/Remove Custom Icons"
#define FM_DIRECTORY_VIEW_COMMAND_OTHER_APPLICATION "/commands/OtherApplication"
#define FM_DIRECTORY_VIEW_COMMAND_OTHER_VIEWER "/commands/OtherViewer"
+#define FM_DIRECTORY_VIEW_COMMAND_CUT_FILES "/commands/Cut Files"
+#define FM_DIRECTORY_VIEW_COMMAND_COPY_FILES "/commands/Copy Files"
+#define FM_DIRECTORY_VIEW_COMMAND_PASTE_FILES "/commands/Paste Files"
#define FM_DIRECTORY_VIEW_MENU_PATH_OPEN_IN_NEW_WINDOW "/menu/File/Open Placeholder/OpenNew"
#define FM_DIRECTORY_VIEW_MENU_PATH_OPEN_WITH "/menu/File/Open Placeholder/Open With"
#define FM_DIRECTORY_VIEW_MENU_PATH_SCRIPTS "/menu/File/Open Placeholder/Scripts"
#define FM_DIRECTORY_VIEW_MENU_PATH_TRASH "/menu/File/File Items Placeholder/Trash"
+#define FM_DIRECTORY_VIEW_MENU_PATH_DELETE "/menu/File/File Items Placeholder/Delete"
#define FM_DIRECTORY_VIEW_MENU_PATH_EMPTY_TRASH "/menu/File/Global File Items Placeholder/Empty Trash"
#define FM_DIRECTORY_VIEW_MENU_PATH_CREATE_LINK "/menu/File/File Items Placeholder/Create Link"
#define FM_DIRECTORY_VIEW_MENU_PATH_REMOVE_CUSTOM_ICONS "/menu/Edit/Edit Items Placeholder/Remove Custom Icons"
@@ -112,6 +116,9 @@
#define FM_DIRECTORY_VIEW_MENU_PATH_OTHER_VIEWER "/menu/File/Open Placeholder/Open With/OtherViewer"
#define FM_DIRECTORY_VIEW_MENU_PATH_SCRIPTS_PLACEHOLDER "/menu/File/Open Placeholder/Scripts/Scripts Placeholder"
#define FM_DIRECTORY_VIEW_MENU_PATH_SCRIPTS_SEPARATOR "/menu/File/Open Placeholder/Scripts/After Scripts"
+#define FM_DIRECTORY_VIEW_MENU_PATH_CUT_FILES "/menu/Edit/Cut"
+#define FM_DIRECTORY_VIEW_MENU_PATH_COPY_FILES "/menu/Edit/Copy"
+#define FM_DIRECTORY_VIEW_MENU_PATH_PASTE_FILES "/menu/File/Paste"
#define FM_DIRECTORY_VIEW_POPUP_PATH_BACKGROUND "/popups/background"
#define FM_DIRECTORY_VIEW_POPUP_PATH_SELECTION "/popups/selection"
@@ -138,6 +145,11 @@ enum {
static guint signals[LAST_SIGNAL];
+static GdkAtom clipboard_atom;
+static GdkAtom copied_files_atom;
+
+static gboolean show_delete_command;
+
struct FMDirectoryViewDetails
{
NautilusView *nautilus_view;
@@ -190,6 +202,9 @@ struct FMDirectoryViewDetails
NautilusFile *file_monitored_for_open_with;
NautilusDirectory *directory_monitored_for_activation;
+
+ GList *clipboard_contents;
+ gboolean clipboard_contents_were_cut;
};
typedef enum {
@@ -220,31 +235,21 @@ static void fm_directory_view_initialize
static void fm_directory_view_duplicate_selection (FMDirectoryView *view,
GList *files,
GArray *item_locations);
+static gboolean fm_directory_view_confirm_deletion (FMDirectoryView *view,
+ GList *uris,
+ gboolean all);
static void fm_directory_view_create_links_for_files (FMDirectoryView *view,
GList *files,
GArray *item_locations);
static void fm_directory_view_trash_or_delete_files (const GList *files,
FMDirectoryView *view);
-static void fm_directory_view_destroy (GtkObject *object);
static void fm_directory_view_activate_file (FMDirectoryView *view,
NautilusFile *file,
WindowChoice choice);
static void load_directory (FMDirectoryView *view,
NautilusDirectory *directory);
static void fm_directory_view_merge_menus (FMDirectoryView *view);
-static void real_file_limit_reached (FMDirectoryView *view);
-static gboolean real_display_pending_files (FMDirectoryView *view,
- GList **pending_files_added,
- GList **pending_files_changed);
-static void real_load_error (FMDirectoryView *view,
- GnomeVFSResult result);
-static void real_merge_menus (FMDirectoryView *view);
-static void real_update_menus (FMDirectoryView *view);
-static gboolean real_is_read_only (FMDirectoryView *view);
-static gboolean real_supports_creating_files (FMDirectoryView *view);
-static gboolean real_accepts_dragged_files (FMDirectoryView *view);
-static gboolean real_supports_zooming (FMDirectoryView *view);
-static gboolean real_supports_properties (FMDirectoryView *view);
+static char * file_name_from_uri (const char *uri);
static BonoboControl * get_bonobo_control (FMDirectoryView *view);
static void stop_loading_callback (NautilusView *nautilus_view,
FMDirectoryView *directory_view);
@@ -278,9 +283,6 @@ static void unschedule_display_of_pending_files
static void disconnect_model_handlers (FMDirectoryView *view);
static void disconnect_script_handlers (FMDirectoryView *view);
static void filtering_changed_callback (gpointer callback_data);
-static NautilusStringList *real_get_emblem_names_to_exclude (FMDirectoryView *view);
-static void start_renaming_item (FMDirectoryView *view,
- const char *uri);
static void metadata_for_directory_as_file_ready_callback (NautilusFile *file,
gpointer callback_data);
static void metadata_for_files_in_directory_ready_callback (NautilusDirectory *directory,
@@ -312,106 +314,6 @@ NAUTILUS_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, select_all)
NAUTILUS_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, set_selection)
NAUTILUS_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, get_selected_icon_locations)
-static void
-fm_directory_view_initialize_class (FMDirectoryViewClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = GTK_OBJECT_CLASS (klass);
-
- object_class->destroy = fm_directory_view_destroy;
-
- signals[CLEAR] =
- gtk_signal_new ("clear",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (FMDirectoryViewClass, clear),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
- signals[BEGIN_ADDING_FILES] =
- gtk_signal_new ("begin_adding_files",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (FMDirectoryViewClass, begin_adding_files),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
- signals[ADD_FILE] =
- gtk_signal_new ("add_file",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (FMDirectoryViewClass, add_file),
- gtk_marshal_NONE__BOXED,
- GTK_TYPE_NONE, 1, GTK_TYPE_BOXED);
- signals[FILE_CHANGED] =
- gtk_signal_new ("file_changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (FMDirectoryViewClass, file_changed),
- gtk_marshal_NONE__BOXED,
- GTK_TYPE_NONE, 1, GTK_TYPE_BOXED);
- signals[DONE_ADDING_FILES] =
- gtk_signal_new ("done_adding_files",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (FMDirectoryViewClass, done_adding_files),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
- signals[BEGIN_LOADING] =
- gtk_signal_new ("begin_loading",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (FMDirectoryViewClass, begin_loading),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
- signals[END_LOADING] =
- gtk_signal_new ("end_loading",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (FMDirectoryViewClass, end_loading),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
- signals[LOAD_ERROR] =
- gtk_signal_new ("load_error",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (FMDirectoryViewClass, load_error),
- gtk_marshal_NONE__INT,
- GTK_TYPE_NONE, 1, GTK_TYPE_INT);
-
- klass->merge_menus = real_merge_menus;
- klass->update_menus = real_update_menus;
- klass->display_pending_files = real_display_pending_files;
- klass->get_emblem_names_to_exclude = real_get_emblem_names_to_exclude;
- klass->start_renaming_item = start_renaming_item;
- klass->is_read_only = real_is_read_only;
- klass->supports_creating_files = real_supports_creating_files;
- klass->accepts_dragged_files = real_accepts_dragged_files;
- klass->supports_zooming = real_supports_zooming;
- klass->supports_properties = real_supports_properties;
- klass->file_limit_reached = real_file_limit_reached;
- klass->load_error = real_load_error;
- klass->reveal_selection = NULL;
-
- /* Function pointers that subclasses must override */
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, add_file);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, bump_zoom_level);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, zoom_to_level);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, restore_default_zoom_level);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, can_zoom_in);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, can_zoom_out);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, get_background_widget);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, clear);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, file_changed);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, get_selection);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, is_empty);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, select_all);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, set_selection);
- NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, get_selected_icon_locations);
-
- gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
-
-}
-
typedef struct {
GnomeVFSMimeApplication *application;
NautilusFile *file;
@@ -818,6 +720,77 @@ trash_callback (BonoboUIComponent *component, gpointer callback_data, const char
nautilus_file_list_free (selection);
}
+static gboolean
+confirm_delete_directly (FMDirectoryView *view,
+ GList *uris)
+{
+ GnomeDialog *dialog;
+ char *prompt;
+ char *file_name;
+ int uri_count;
+
+ g_assert (FM_IS_DIRECTORY_VIEW (view));
+
+ /* Just Say Yes if the preference says not to confirm. */
+ if (!nautilus_preferences_get_boolean (NAUTILUS_PREFERENCES_CONFIRM_TRASH)) {
+ return TRUE;
+ }
+
+ uri_count = g_list_length (uris);
+ g_assert (uri_count > 0);
+
+ if (uri_count == 1) {
+ file_name = file_name_from_uri ((char *) uris->data);
+ prompt = g_strdup_printf (_("Are you sure you want to permanently delete \"%s\"?"),
+ file_name);
+ g_free (file_name);
+ } else {
+ prompt = g_strdup_printf (_("Are you sure you want to permanently delete "
+ "the %d selected items?"), uri_count);
+ }
+
+ dialog = nautilus_show_yes_no_dialog
+ (prompt,
+ _("Delete?"),
+ _("Delete"),
+ GNOME_STOCK_BUTTON_CANCEL,
+ fm_directory_view_get_containing_window (view));
+
+ g_free (prompt);
+
+ return gnome_dialog_run (dialog) == GNOME_OK;
+}
+
+
+static void
+delete_callback (BonoboUIComponent *component, gpointer callback_data, const char *verb)
+{
+ FMDirectoryView *view;
+ GList *selection;
+ GList *node;
+ GList *file_uris;
+
+ view = FM_DIRECTORY_VIEW (callback_data);
+ selection = fm_directory_view_get_selection (view);
+ if (selection_not_empty_in_menu_callback (view, selection)) {
+
+ file_uris = NULL;
+ for (node = selection; node != NULL; node = node->next) {
+ file_uris = g_list_prepend (file_uris,
+ nautilus_file_get_uri ((NautilusFile *) node->data));
+ }
+
+ if (confirm_delete_directly (view,
+ file_uris)) {
+ nautilus_file_operations_delete (file_uris, GTK_WIDGET (view));
+ }
+
+ nautilus_g_list_free_deep (file_uris);
+ }
+
+ nautilus_file_list_free (selection);
+}
+
static void
duplicate_callback (BonoboUIComponent *component, gpointer callback_data, const char *verb)
{
@@ -891,7 +864,7 @@ bonobo_menu_empty_trash_callback (BonoboUIComponent *component,
{
g_assert (FM_IS_DIRECTORY_VIEW (callback_data));
- nautilus_file_operations_empty_trash (GTK_WIDGET (FM_DIRECTORY_VIEW (callback_data)));
+ nautilus_file_operations_empty_trash (GTK_WIDGET (callback_data));
}
static void
@@ -1127,12 +1100,18 @@ connect_script_handlers (FMDirectoryView *view)
view);
}
-
-
static void
fm_directory_view_initialize (FMDirectoryView *view)
{
view->details = g_new0 (FMDirectoryViewDetails, 1);
+
+ /* We need to have our own X window so that cut, copy, and
+ * paste work. The window is created by our realize method,
+ * but we also have to do this additional set-up here.
+ */
+ GTK_WIDGET_UNSET_FLAGS (view, GTK_NO_WINDOW);
+ gtk_selection_add_target (GTK_WIDGET (view), clipboard_atom,
+ copied_files_atom, 0);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view),
GTK_POLICY_AUTOMATIC,
@@ -1200,58 +1179,49 @@ fm_directory_view_initialize (FMDirectoryView *view)
filtering_changed_callback (view);
- /* Keep track of changes in this pref to filter files accordingly. */
nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
filtering_changed_callback,
view);
-
- /* Keep track of changes in this pref to filter files accordingly. */
nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_SHOW_BACKUP_FILES,
filtering_changed_callback,
view);
-
- /* Keep track of changes in this pref to display menu names correctly. */
nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
schedule_update_menus_callback,
view);
-
- /* Keep track of changes in text attribute names */
+ nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ schedule_update_menus_callback,
+ view);
nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_ICON_CAPTIONS,
text_attribute_names_changed_callback,
view);
-
- /* Keep track of changes in image display policy */
nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_SHOW_IMAGE_FILE_THUMBNAILS,
image_display_policy_changed_callback,
view);
-
- /* Keep track of changes in the font family */
nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_DIRECTORY_VIEW_FONT_FAMILY,
directory_view_font_family_changed_callback,
view);
-
- /* Keep track of changes in the smooth font */
nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_DIRECTORY_VIEW_SMOOTH_FONT,
directory_view_smooth_font_changed_callback,
view);
-
- /* Keep track of changes in clicking policy */
nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_CLICK_POLICY,
click_policy_changed_callback,
view);
-
- /* Keep track of changes in graphics trade offs */
nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_SMOOTH_GRAPHICS_MODE,
smooth_graphics_mode_changed_callback,
view);
-
- /* Keep track of changes in sort order */
nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST,
sort_directories_first_changed_callback,
view);
}
static void
+forget_clipboard_contents (FMDirectoryView *view)
+{
+ nautilus_file_list_free (view->details->clipboard_contents);
+ view->details->clipboard_contents = NULL;
+}
+
+static void
fm_directory_view_destroy (GtkObject *object)
{
FMDirectoryView *view;
@@ -1291,6 +1261,9 @@ fm_directory_view_destroy (GtkObject *object)
nautilus_preferences_remove_callback (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
schedule_update_menus_callback,
view);
+ nautilus_preferences_remove_callback (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ schedule_update_menus_callback,
+ view);
nautilus_preferences_remove_callback (NAUTILUS_PREFERENCES_ICON_CAPTIONS,
text_attribute_names_changed_callback,
view);
@@ -1313,6 +1286,8 @@ fm_directory_view_destroy (GtkObject *object)
sort_directories_first_changed_callback,
view);
+ forget_clipboard_contents (view);
+
g_free (view->details);
NAUTILUS_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object));
@@ -2528,6 +2503,10 @@ offset_drop_points (GArray *relative_item_points,
{
guint index;
+ if (relative_item_points == NULL) {
+ return;
+ }
+
for (index = 0; index < relative_item_points->len; index++) {
g_array_index (relative_item_points, GdkPoint, index).x += x_offset;
g_array_index (relative_item_points, GdkPoint, index).y += y_offset;
@@ -2555,8 +2534,9 @@ fm_directory_view_create_links_for_files (FMDirectoryView *view, GList *files,
/* offset the drop locations a bit so that we don't pile
* up the icons on top of each other
*/
- offset_drop_points (relative_item_points, DUPLICATE_HORIZONTAL_ICON_OFFSET,
- DUPLICATE_VERTICAL_ICON_OFFSET);
+ offset_drop_points (relative_item_points,
+ DUPLICATE_HORIZONTAL_ICON_OFFSET,
+ DUPLICATE_VERTICAL_ICON_OFFSET);
copy_move_done_data = pre_copy_move (view);
nautilus_file_operations_copy_move (uris, relative_item_points, NULL, GDK_ACTION_LINK,
@@ -2585,8 +2565,9 @@ fm_directory_view_duplicate_selection (FMDirectoryView *view, GList *files,
/* offset the drop locations a bit so that we don't pile
* up the icons on top of each other
*/
- offset_drop_points (relative_item_points, DUPLICATE_HORIZONTAL_ICON_OFFSET,
- DUPLICATE_VERTICAL_ICON_OFFSET);
+ offset_drop_points (relative_item_points,
+ DUPLICATE_HORIZONTAL_ICON_OFFSET,
+ DUPLICATE_VERTICAL_ICON_OFFSET);
copy_move_done_data = pre_copy_move (view);
nautilus_file_operations_copy_move (uris, relative_item_points, NULL, GDK_ACTION_COPY,
@@ -2809,13 +2790,13 @@ fm_directory_view_confirm_deletion (FMDirectoryView *view, GList *uris, gboolean
}
}
- dialog = nautilus_show_yes_no_dialog (
- prompt,
- _("Delete Immediately?"),
- _("Delete"),
- GNOME_STOCK_BUTTON_CANCEL,
- fm_directory_view_get_containing_window (view));
-
+ dialog = nautilus_show_yes_no_dialog
+ (prompt,
+ _("Delete Immediately?"),
+ _("Delete"),
+ GNOME_STOCK_BUTTON_CANCEL,
+ fm_directory_view_get_containing_window (view));
+
g_free (prompt);
return gnome_dialog_run (dialog) == GNOME_OK;
@@ -2840,8 +2821,7 @@ confirm_delete_from_trash (FMDirectoryView *view, GList *uris)
g_assert (uri_count > 0);
if (uri_count == 1) {
- file_name = file_name_from_uri ((char *)uris->data);
-
+ file_name = file_name_from_uri ((char *) uris->data);
prompt = g_strdup_printf (_("Are you sure you want to permanently delete \"%s\" "
"from the Trash?"), file_name);
g_free (file_name);
@@ -2867,7 +2847,6 @@ trash_or_delete_files_common (const GList *file_uris,
GArray *relative_item_points,
const char *target_uri,
int copy_action,
- int x, int y,
FMDirectoryView *view)
{
const GList *file_node;
@@ -2944,7 +2923,7 @@ fm_directory_view_trash_or_delete_files (const GList *files,
file_uris = g_list_reverse (file_uris);
trash_or_delete_files_common (file_uris, NULL, NAUTILUS_TRASH_URI,
- GDK_ACTION_MOVE, 0, 0, view);
+ GDK_ACTION_MOVE, view);
nautilus_g_list_free_deep (file_uris);
}
@@ -2999,7 +2978,9 @@ fm_directory_view_new_folder (FMDirectoryView *directory_view)
char *parent_uri;
parent_uri = fm_directory_view_get_uri (directory_view);
- nautilus_file_operations_new_folder (GTK_WIDGET (directory_view), parent_uri, new_folder_done, directory_view);
+ nautilus_file_operations_new_folder (GTK_WIDGET (directory_view),
+ parent_uri,
+ new_folder_done, directory_view);
g_free (parent_uri);
}
@@ -3685,8 +3666,6 @@ open_scripts_folder_callback (BonoboUIComponent *component,
}
}
-
-
static BonoboWindow *
get_bonobo_window (FMDirectoryView *view)
{
@@ -3715,25 +3694,197 @@ create_popup_menu (FMDirectoryView *view, const char *popup_path)
return menu;
}
+static guint
+get_current_event_time (void)
+{
+ /* FIXME: Maybe we should implement this for real? */
+ return GDK_CURRENT_TIME;
+}
+
+static void
+copy_or_cut_files (FMDirectoryView *view,
+ gboolean cut)
+{
+ if (gtk_selection_owner_set (GTK_WIDGET (view),
+ clipboard_atom,
+ get_current_event_time ())) {
+ nautilus_file_list_free (view->details->clipboard_contents);
+ view->details->clipboard_contents
+ = fm_directory_view_get_selection (view);
+ view->details->clipboard_contents_were_cut = cut;
+ }
+}
+
+static void
+copy_files_callback (BonoboUIComponent *component,
+ gpointer callback_data,
+ const char *verb)
+{
+ copy_or_cut_files (callback_data, FALSE);
+}
+
+static void
+cut_files_callback (BonoboUIComponent *component,
+ gpointer callback_data,
+ const char *verb)
+{
+ copy_or_cut_files (callback_data, TRUE);
+}
+
+static void
+paste_files_callback (BonoboUIComponent *component,
+ gpointer callback_data,
+ const char *verb)
+{
+ gtk_selection_convert (GTK_WIDGET (callback_data),
+ clipboard_atom,
+ copied_files_atom,
+ get_current_event_time ());
+}
+
+static gboolean
+real_selection_clear_event (GtkWidget *widget,
+ GdkEventSelection *event)
+{
+ FMDirectoryView *view;
+
+ view = FM_DIRECTORY_VIEW (widget);
+
+ if (!gtk_selection_clear (widget, event)) {
+ return FALSE;
+ }
+
+ forget_clipboard_contents (view);
+ return TRUE;
+}
+
+static void
+real_selection_get (GtkWidget *widget,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
+{
+ FMDirectoryView *view;
+ GString *uris;
+ GList *node;
+ char *uri;
+
+ view = FM_DIRECTORY_VIEW (widget);
+
+ uris = g_string_new (view->details->clipboard_contents_were_cut
+ ? "cut" : "copy");
+
+ for (node = view->details->clipboard_contents;
+ node != NULL; node = node->next) {
+ uri = nautilus_file_get_uri (node->data);
+ g_string_append_c (uris, '\n');
+ g_string_append (uris, uri);
+ g_free (uri);
+ }
+
+ gtk_selection_data_set (selection_data,
+ copied_files_atom,
+ 8,
+ uris->str,
+ uris->len);
+
+ g_string_free (uris, TRUE);
+}
+
+static GList *
+convert_lines_to_str_list (char **lines, gboolean *cut)
+{
+ int i;
+ GList *result;
+
+ if (lines[0] == NULL) {
+ return NULL;
+ }
+
+ if (strcmp (lines[0], "cut") == 0) {
+ *cut = TRUE;
+ } else if (strcmp (lines[0], "copy") == 0) {
+ *cut = FALSE;
+ } else {
+ return NULL;
+ }
+
+ result = NULL;
+ for (i = 1; lines[i] != NULL; i++) {
+ result = g_list_prepend (result, g_strdup (lines[i]));
+ }
+ return g_list_reverse (result);
+}
+
+static void
+real_selection_received (GtkWidget *widget,
+ GtkSelectionData *selection_data,
+ guint time)
+{
+ FMDirectoryView *view;
+ char **lines;
+ gboolean cut;
+ GList *item_uris;
+ char *view_uri;
+
+ view = FM_DIRECTORY_VIEW (widget);
+
+ if (selection_data->type != copied_files_atom
+ || selection_data->length <= 0) {
+ return;
+ }
+
+ /* Not sure why it's legal to assume there's an extra byte
+ * past the end of the selection data that it's safe to write
+ * to. But gtk_editable_selection_received does this, so I
+ * think it is OK.
+ */
+ selection_data->data[selection_data->length] = '\0';
+ lines = g_strsplit (selection_data->data, "\n", 0);
+ item_uris = convert_lines_to_str_list (lines, &cut);
+ g_strfreev (lines);
+ if (item_uris == NULL) {
+ return;
+ }
+
+ view_uri = fm_directory_view_get_uri (view);
+ if (view_uri == NULL) {
+ nautilus_g_list_free_deep (item_uris);
+ return;
+ }
+
+ fm_directory_view_move_copy_items (item_uris, NULL, view_uri,
+ cut ? GDK_ACTION_MOVE : GDK_ACTION_COPY,
+ 0, 0,
+ view);
+
+ nautilus_g_list_free_deep (item_uris);
+ g_free (view_uri);
+}
+
static void
real_merge_menus (FMDirectoryView *view)
{
BonoboUIVerb verbs [] = {
+ BONOBO_UI_VERB ("Copy Files", copy_files_callback),
+ BONOBO_UI_VERB ("Create Link", create_link_callback),
+ BONOBO_UI_VERB ("Cut Files", cut_files_callback),
+ BONOBO_UI_VERB ("Delete", delete_callback),
+ BONOBO_UI_VERB ("Duplicate", duplicate_callback),
+ BONOBO_UI_VERB ("Empty Trash", bonobo_menu_empty_trash_callback),
BONOBO_UI_VERB ("New Folder", new_folder_callback),
+ BONOBO_UI_VERB ("Open Scripts Folder", open_scripts_folder_callback),
BONOBO_UI_VERB ("Open", open_callback),
BONOBO_UI_VERB ("OpenNew", open_in_new_window_callback),
BONOBO_UI_VERB ("OtherApplication", other_application_callback),
BONOBO_UI_VERB ("OtherViewer", other_viewer_callback),
- BONOBO_UI_VERB ("Show Properties", open_properties_window_callback),
- BONOBO_UI_VERB ("Trash", trash_callback),
- BONOBO_UI_VERB ("Duplicate", duplicate_callback),
- BONOBO_UI_VERB ("Create Link", create_link_callback),
- BONOBO_UI_VERB ("Show Trash", show_trash_callback),
- BONOBO_UI_VERB ("Empty Trash", bonobo_menu_empty_trash_callback),
- BONOBO_UI_VERB ("Select All", bonobo_menu_select_all_callback),
+ BONOBO_UI_VERB ("Paste Files", paste_files_callback),
BONOBO_UI_VERB ("Remove Custom Icons", remove_custom_icons_callback),
BONOBO_UI_VERB ("Reset Background", reset_background_callback),
- BONOBO_UI_VERB ("Open Scripts Folder", open_scripts_folder_callback),
+ BONOBO_UI_VERB ("Select All", bonobo_menu_select_all_callback),
+ BONOBO_UI_VERB ("Show Properties", open_properties_window_callback),
+ BONOBO_UI_VERB ("Show Trash", show_trash_callback),
+ BONOBO_UI_VERB ("Trash", trash_callback),
BONOBO_UI_VERB_END
};
@@ -3770,14 +3921,24 @@ confirm_trash_changed_callback (gpointer callback_data)
}
static void
+enable_delete_changed_callback (gpointer callback_data)
+{
+ show_delete_command = nautilus_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_DELETE);
+}
+
+static void
real_update_menus (FMDirectoryView *view)
{
static gboolean confirm_trash_changed_callback_installed = FALSE;
+ static gboolean enable_delete_changed_callback_installed = FALSE;
GList *selection;
gint selection_count;
+ const char *tip, *accelerator, *label;
char *label_with_underscore;
gboolean selection_contains_special_link;
gboolean can_create_files;
+ gboolean can_delete_files;
+ gboolean show_separate_delete_command;
NautilusBackground *background;
selection = fm_directory_view_get_selection (view);
@@ -3793,6 +3954,17 @@ real_update_menus (FMDirectoryView *view)
/* Peek for the first time */
confirm_trash_changed_callback (NULL);
}
+
+ /* Add the callback once for the life of our process */
+ if (!enable_delete_changed_callback_installed) {
+ nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ enable_delete_changed_callback,
+ NULL);
+ enable_delete_changed_callback_installed = TRUE;
+
+ /* Peek for the first time */
+ enable_delete_changed_callback (NULL);
+ }
selection_contains_special_link = special_link_in_selection (view);
can_create_files = fm_directory_view_supports_creating_files (view);
@@ -3833,36 +4005,50 @@ real_update_menus (FMDirectoryView *view)
/* Broken into its own function just for convenience */
reset_bonobo_open_with_menu (view, selection);
-
if (fm_directory_all_selected_items_in_trash (view)) {
- nautilus_bonobo_set_tip (view->details->ui,
- FM_DIRECTORY_VIEW_MENU_PATH_TRASH,
- _("Delete all selected items permanently"));
- nautilus_bonobo_set_accelerator (view->details->ui,
- FM_DIRECTORY_VIEW_MENU_PATH_TRASH,
- "");
- label_with_underscore = g_strdup (confirm_trash
- ? _("Delete from _Trash...")
- : _("Delete from _Trash"));
+ label = confirm_trash ? _("Delete from _Trash...") : _("Delete from _Trash");
+ accelerator = "";
+ tip = _("Delete all selected items permanently");
+ show_separate_delete_command = FALSE;
} else {
- nautilus_bonobo_set_tip (view->details->ui,
- FM_DIRECTORY_VIEW_MENU_PATH_TRASH,
- _("Move all selected items to the Trash"));
- nautilus_bonobo_set_accelerator (view->details->ui,
- FM_DIRECTORY_VIEW_MENU_PATH_TRASH,
- "*Control*t");
- label_with_underscore = g_strdup (_("Move to _Trash"));
+ label = _("Move to _Trash");
+ accelerator = "*Control*t";
+ tip = _("Move all selected items to the Trash");
+ show_separate_delete_command = show_delete_command;
}
+
+ can_delete_files = !fm_directory_view_is_read_only (view)
+ && selection_count != 0
+ && !selection_contains_special_link;
+
nautilus_bonobo_set_label_for_menu_item_and_command
(view->details->ui,
FM_DIRECTORY_VIEW_MENU_PATH_TRASH,
FM_DIRECTORY_VIEW_COMMAND_TRASH,
- label_with_underscore);
+ label);
+ nautilus_bonobo_set_accelerator (view->details->ui,
+ FM_DIRECTORY_VIEW_MENU_PATH_TRASH,
+ accelerator);
+ nautilus_bonobo_set_tip (view->details->ui,
+ FM_DIRECTORY_VIEW_MENU_PATH_TRASH,
+ tip);
nautilus_bonobo_set_sensitive (view->details->ui,
FM_DIRECTORY_VIEW_COMMAND_TRASH,
- !fm_directory_view_is_read_only (view)
- && selection_count != 0
- && !selection_contains_special_link);
+ can_delete_files);
+
+ nautilus_bonobo_set_hidden (view->details->ui,
+ FM_DIRECTORY_VIEW_COMMAND_DELETE,
+ !show_separate_delete_command);
+ if (show_separate_delete_command) {
+ nautilus_bonobo_set_label_for_menu_item_and_command
+ (view->details->ui,
+ FM_DIRECTORY_VIEW_MENU_PATH_DELETE,
+ FM_DIRECTORY_VIEW_COMMAND_DELETE,
+ confirm_trash ? _("Delete...") : _("Delete"));
+ nautilus_bonobo_set_sensitive (view->details->ui,
+ FM_DIRECTORY_VIEW_COMMAND_DELETE,
+ can_delete_files);
+ }
nautilus_bonobo_set_sensitive (view->details->ui,
FM_DIRECTORY_VIEW_COMMAND_DUPLICATE,
@@ -3894,7 +4080,6 @@ real_update_menus (FMDirectoryView *view)
selection_count != 0
&& fm_directory_view_supports_properties (view));
-
nautilus_bonobo_set_label_for_menu_item_and_command
(view->details->ui,
FM_DIRECTORY_VIEW_MENU_PATH_EMPTY_TRASH,
@@ -3922,6 +4107,32 @@ real_update_menus (FMDirectoryView *view)
NAUTILUS_COMMAND_SELECT_ALL,
!fm_directory_view_is_empty (view));
+ nautilus_bonobo_set_label_for_menu_item_and_command
+ (view->details->ui,
+ FM_DIRECTORY_VIEW_MENU_PATH_CUT_FILES,
+ FM_DIRECTORY_VIEW_COMMAND_CUT_FILES,
+ selection_count == 1
+ ? _("Cu_t File")
+ : _("Cu_t Files"));
+ nautilus_bonobo_set_sensitive (view->details->ui,
+ FM_DIRECTORY_VIEW_COMMAND_CUT_FILES,
+ selection_count != 0);
+
+ nautilus_bonobo_set_label_for_menu_item_and_command
+ (view->details->ui,
+ FM_DIRECTORY_VIEW_MENU_PATH_COPY_FILES,
+ FM_DIRECTORY_VIEW_COMMAND_COPY_FILES,
+ selection_count == 1
+ ? _("_Copy File")
+ : _("_Copy Files"));
+ nautilus_bonobo_set_sensitive (view->details->ui,
+ FM_DIRECTORY_VIEW_COMMAND_COPY_FILES,
+ selection_count != 0);
+
+ /* FIXME: Would be nice to set up paste item here based on
+ * contents of CLIPBOARD, but I'm not sure that's possible due
+ * to limitations of X clipboard support.
+ */
bonobo_ui_component_thaw (view->details->ui, NULL);
@@ -3930,7 +4141,6 @@ real_update_menus (FMDirectoryView *view)
if (view->details->scripts_invalid) {
schedule_reset_scripts_menu (view);
}
-
}
/**
@@ -4723,8 +4933,10 @@ static void
fm_directory_view_select_file (FMDirectoryView *view, NautilusFile *file)
{
GList file_list;
+
file_list.data = file;
file_list.next = NULL;
+ file_list.prev = NULL;
fm_directory_view_set_selection (view, &file_list);
}
@@ -4993,8 +5205,9 @@ fm_directory_view_move_copy_items (const GList *item_uris,
int length;
const GList *p;
- g_assert (relative_item_points->len == 0
- || g_list_length ((GList *)item_uris) == relative_item_points->len);
+ g_assert (relative_item_points == NULL
+ || relative_item_points->len == 0
+ || g_list_length ((GList *)item_uris) == relative_item_points->len);
/* add the drop location to the icon offsets */
offset_drop_points (relative_item_points, x, y);
@@ -5035,7 +5248,7 @@ fm_directory_view_move_copy_items (const GList *item_uris,
if (nautilus_uri_is_trash (target_uri)) {
trash_or_delete_files_common (item_uris, relative_item_points,
target_uri, copy_action,
- x, y, view);
+ view);
} else {
nautilus_file_operations_copy_move
(item_uris, relative_item_points,
@@ -5161,3 +5374,168 @@ monitor_file_for_activation (FMDirectoryView *view,
TRUE, TRUE, NULL);
}
}
+
+static void
+real_realize (GtkWidget *widget)
+{
+ GdkWindowAttr attributes;
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+ attributes.x = widget->allocation.x;
+ attributes.y = widget->allocation.y;
+ attributes.width = widget->allocation.width;
+ attributes.height = widget->allocation.height;
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.colormap = gtk_widget_get_colormap (widget);
+ attributes.event_mask = gtk_widget_get_events (widget)
+ | GDK_BUTTON_MOTION_MASK
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_EXPOSURE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK;
+
+ widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes,
+ GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP);
+ gdk_window_set_user_data (widget->window, widget);
+
+ widget->style = gtk_style_attach (widget->style, widget->window);
+}
+
+static void
+real_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkAllocation allocation_to_fool_scrolled_window;
+
+ /* Trick GtkScrolledWindow into working. */
+
+ allocation_to_fool_scrolled_window.x = 0;
+ allocation_to_fool_scrolled_window.y = 0;
+ allocation_to_fool_scrolled_window.width = allocation->width;
+ allocation_to_fool_scrolled_window.height = allocation->height;
+ NAUTILUS_CALL_PARENT (GTK_WIDGET_CLASS, size_allocate,
+ (widget, &allocation_to_fool_scrolled_window));
+
+ /* The rest of this is just identical to what GtkWidget does. */
+ widget->allocation = *allocation;
+ if (GTK_WIDGET_REALIZED (widget)) {
+ gdk_window_move_resize (widget->window,
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+ }
+}
+
+static void
+fm_directory_view_initialize_class (FMDirectoryViewClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->destroy = fm_directory_view_destroy;
+
+ widget_class->realize = real_realize;
+ widget_class->selection_clear_event = real_selection_clear_event;
+ widget_class->selection_get = real_selection_get;
+ widget_class->selection_received = real_selection_received;
+ widget_class->size_allocate = real_size_allocate;
+
+ signals[CLEAR] =
+ gtk_signal_new ("clear",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (FMDirectoryViewClass, clear),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+ signals[BEGIN_ADDING_FILES] =
+ gtk_signal_new ("begin_adding_files",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (FMDirectoryViewClass, begin_adding_files),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+ signals[ADD_FILE] =
+ gtk_signal_new ("add_file",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (FMDirectoryViewClass, add_file),
+ gtk_marshal_NONE__BOXED,
+ GTK_TYPE_NONE, 1, GTK_TYPE_BOXED);
+ signals[FILE_CHANGED] =
+ gtk_signal_new ("file_changed",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (FMDirectoryViewClass, file_changed),
+ gtk_marshal_NONE__BOXED,
+ GTK_TYPE_NONE, 1, GTK_TYPE_BOXED);
+ signals[DONE_ADDING_FILES] =
+ gtk_signal_new ("done_adding_files",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (FMDirectoryViewClass, done_adding_files),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+ signals[BEGIN_LOADING] =
+ gtk_signal_new ("begin_loading",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (FMDirectoryViewClass, begin_loading),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+ signals[END_LOADING] =
+ gtk_signal_new ("end_loading",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (FMDirectoryViewClass, end_loading),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+ signals[LOAD_ERROR] =
+ gtk_signal_new ("load_error",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (FMDirectoryViewClass, load_error),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1, GTK_TYPE_INT);
+
+ klass->merge_menus = real_merge_menus;
+ klass->update_menus = real_update_menus;
+ klass->display_pending_files = real_display_pending_files;
+ klass->get_emblem_names_to_exclude = real_get_emblem_names_to_exclude;
+ klass->start_renaming_item = start_renaming_item;
+ klass->is_read_only = real_is_read_only;
+ klass->supports_creating_files = real_supports_creating_files;
+ klass->accepts_dragged_files = real_accepts_dragged_files;
+ klass->supports_zooming = real_supports_zooming;
+ klass->supports_properties = real_supports_properties;
+ klass->file_limit_reached = real_file_limit_reached;
+ klass->load_error = real_load_error;
+ klass->reveal_selection = NULL;
+
+ /* Function pointers that subclasses must override */
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, add_file);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, bump_zoom_level);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, zoom_to_level);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, restore_default_zoom_level);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, can_zoom_in);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, can_zoom_out);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, get_background_widget);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, clear);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, file_changed);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, get_selection);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, is_empty);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, select_all);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, set_selection);
+ NAUTILUS_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, fm_directory_view, get_selected_icon_locations);
+
+ gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+
+ clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+ copied_files_atom = gdk_atom_intern ("x-special/gnome-copied-files", FALSE);
+}
diff --git a/src/file-manager/fm-icon-view.c b/src/file-manager/fm-icon-view.c
index 9b868564e..85b8c43f6 100644
--- a/src/file-manager/fm-icon-view.c
+++ b/src/file-manager/fm-icon-view.c
@@ -1456,21 +1456,17 @@ icon_container_preview_callback (NautilusIconContainer *container,
static void
renaming_icon_callback (NautilusIconContainer *container,
- gpointer editable_data,
+ GtkEditable *editable,
gpointer callback_data)
{
FMDirectoryView *directory_view;
directory_view = FM_DIRECTORY_VIEW (callback_data);
- nautilus_clipboard_set_up_editable_in_control (GTK_EDITABLE (editable_data),
- fm_directory_view_get_bonobo_control (directory_view),
- TRUE);
- /* Focus the editable in so the clipboard items will get turned on
- while we're renaming; the hack that the nautilus entry is a
- virtual widget prevents this from happening normally */
- gtk_signal_emit_by_name (GTK_OBJECT (editable_data), "grab_focus");
-
+ nautilus_clipboard_set_up_editable_in_control
+ (editable,
+ fm_directory_view_get_bonobo_control (directory_view),
+ TRUE);
}
static int
@@ -1486,7 +1482,7 @@ icon_container_compare_icons_callback (NautilusIconContainer *container,
return nautilus_file_compare_for_sort
(file_a, file_b, icon_view->details->sort->sort_type,
- fm_directory_view_should_sort_directories_first (FM_DIRECTORY_VIEW (icon_view)),
+ fm_directory_view_should_sort_directories_first (FM_DIRECTORY_VIEW (icon_view)),
icon_view->details->sort_reversed);
}
diff --git a/src/file-manager/nautilus-directory-view-ui.xml b/src/file-manager/nautilus-directory-view-ui.xml
index 9cf56b1a3..fe0f3700b 100644
--- a/src/file-manager/nautilus-directory-view-ui.xml
+++ b/src/file-manager/nautilus-directory-view-ui.xml
@@ -3,6 +3,9 @@
<cmd name="Create Link"
_label="Create Link"
_tip="Create a symbolic link for each selected item"/>
+ <cmd name="Delete"
+ _label="Delete"
+ _tip="Delete each selected item, without moving to the Trash"/>
<cmd name="Duplicate"
_label="Duplicate"
_tip="Duplicate each selected item"/>
@@ -33,6 +36,15 @@
<cmd name="Reset Background"
_label="Reset Background"
_tip="Remove any custom pattern or color from the background of this location"/>
+ <cmd name="Cut Files"
+ _label="Cut Files"
+ _tip="Prepare the selected files to be moved with a Paste Files command"/>
+ <cmd name="Copy Files"
+ _label="Copy Files"
+ _tip="Prepare the selected files to be copied with a Paste Files command"/>
+ <cmd name="Paste Files"
+ _label="Paste Files"
+ _tip="Move or copy files previously selected by a Cut Files or Copy Files command"/>
<cmd name="Select All"
_label="Select All Files"
_tip="Select all items in this window"/>
@@ -96,6 +108,9 @@
_label="Move to _Trash"
accel="*Control*t"
verb="Trash"/>
+ <menuitem name="Delete"
+ _label="Delete"
+ verb="Delete"/>
<menuitem name="Duplicate"
_label="_Duplicate"
accel="*Control*d"
@@ -117,6 +132,18 @@
</submenu>
<submenu name="Edit">
+ <menuitem name="Cut"
+ _label="Cu_t Files"
+ accel="*Control*x"
+ verb="Cut Files"/>
+ <menuitem name="Copy"
+ _label="_Copy Files"
+ accel="*Control*c"
+ verb="Copy Files"/>
+ <menuitem name="Paste"
+ _label="_Paste Files"
+ accel="*Control*v"
+ verb="Paste Files"/>
<menuitem name="Select All"
_label="Select _All Files"
accel="*Control*a"
@@ -172,6 +199,7 @@
<placeholder name="File Actions" delimit="top">
<menuitem name="Show Properties" verb="Show Properties"/>
<menuitem name="Trash" verb="Trash"/>
+ <menuitem name="Delete" verb="Delete"/>
<menuitem name="Duplicate" verb="Duplicate"/>
<menuitem name="Create Link" verb="Create Link"/>
</placeholder>
diff --git a/src/nautilus-shell-ui.xml b/src/nautilus-shell-ui.xml
index a1a77c9af..17c9300c4 100644
--- a/src/nautilus-shell-ui.xml
+++ b/src/nautilus-shell-ui.xml
@@ -93,23 +93,19 @@
-->
<menuitem name="Cut"
- _label="Cut _Text"
- _tip="Cut the selected text to the clipboard"
+ _label="Cut _Text"
pixtype="stock" pixname="Cut"
verb="Cut"/>
<menuitem name="Copy"
- _label="_Copy Text"
- _tip="Copy the selected text to the clipboard"
+ _label="_Copy Text"
pixtype="stock" pixname="Copy"
verb="Copy"/>
<menuitem name="Paste"
- _label="_Paste Text"
- _tip="Paste the text stored on the clipboard"
+ _label="_Paste Text"
pixtype="stock" pixname="Paste"
verb="Paste"/>
<menuitem name="Clear"
- _label="C_lear Text"
- _tip="Removes the selected text without putting it on the clipboard"
+ _label="C_lear Text"
verb="Clear"/>
<separator/>