summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am8
-rw-r--r--src/nautilus-canvas-view-container.c6
-rw-r--r--src/nautilus-canvas-view.c268
-rw-r--r--src/nautilus-canvas-view.h8
-rw-r--r--src/nautilus-desktop-canvas-view.c54
-rw-r--r--src/nautilus-desktop-canvas-view.h2
-rw-r--r--src/nautilus-empty-view.c140
-rw-r--r--src/nautilus-empty-view.h8
-rw-r--r--src/nautilus-files-view-context-menus.xml (renamed from src/nautilus-view-context-menus.xml)0
-rw-r--r--src/nautilus-files-view-dnd.c547
-rw-r--r--src/nautilus-files-view-dnd.h68
-rw-r--r--src/nautilus-files-view.c8147
-rw-r--r--src/nautilus-files-view.h401
-rw-r--r--src/nautilus-list-view.c250
-rw-r--r--src/nautilus-list-view.h8
-rw-r--r--src/nautilus-trash-bar.c16
-rw-r--r--src/nautilus-trash-bar.h4
-rw-r--r--src/nautilus-view-dnd.c546
-rw-r--r--src/nautilus-view-dnd.h68
-rw-r--r--src/nautilus-view.c8113
-rw-r--r--src/nautilus-view.h401
-rw-r--r--src/nautilus-window-slot-dnd.c10
-rw-r--r--src/nautilus-window-slot.c70
-rw-r--r--src/nautilus-window-slot.h8
-rw-r--r--src/nautilus-window.h2
-rw-r--r--src/nautilus.gresource.xml2
26 files changed, 9595 insertions, 9560 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7de649b7d..fddb7676f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -165,6 +165,10 @@ nautilus_SOURCES = \
nautilus-error-reporting.h \
nautilus-file-management-properties.c \
nautilus-file-management-properties.h \
+ nautilus-files-view.c \
+ nautilus-files-view.h \
+ nautilus-files-view-dnd.c \
+ nautilus-files-view-dnd.h \
nautilus-floating-bar.c \
nautilus-floating-bar.h \
nautilus-freedesktop-dbus.c \
@@ -205,10 +209,6 @@ nautilus_SOURCES = \
nautilus-toolbar.h \
nautilus-trash-bar.c \
nautilus-trash-bar.h \
- nautilus-view.c \
- nautilus-view.h \
- nautilus-view-dnd.c \
- nautilus-view-dnd.h \
nautilus-window-slot.c \
nautilus-window-slot.h \
nautilus-window-slot-dnd.c \
diff --git a/src/nautilus-canvas-view-container.c b/src/nautilus-canvas-view-container.c
index 141daef21..e9779bb56 100644
--- a/src/nautilus-canvas-view-container.c
+++ b/src/nautilus-canvas-view-container.c
@@ -346,13 +346,13 @@ fm_desktop_canvas_container_icons_compare (NautilusCanvasContainer *container,
{
NautilusFile *file_a;
NautilusFile *file_b;
- NautilusView *directory_view;
+ NautilusFilesView *directory_view;
SortCategory category_a, category_b;
file_a = (NautilusFile *) data_a;
file_b = (NautilusFile *) data_b;
- directory_view = NAUTILUS_VIEW (NAUTILUS_CANVAS_VIEW_CONTAINER (container)->view);
+ directory_view = NAUTILUS_FILES_VIEW (NAUTILUS_CANVAS_VIEW_CONTAINER (container)->view);
g_return_val_if_fail (directory_view != NULL, 0);
category_a = get_sort_category (file_a);
@@ -361,7 +361,7 @@ fm_desktop_canvas_container_icons_compare (NautilusCanvasContainer *container,
if (category_a == category_b) {
return nautilus_file_compare_for_sort
(file_a, file_b, NAUTILUS_FILE_SORT_BY_DISPLAY_NAME,
- nautilus_view_should_sort_directories_first (directory_view),
+ nautilus_files_view_should_sort_directories_first (directory_view),
FALSE);
}
diff --git a/src/nautilus-canvas-view.c b/src/nautilus-canvas-view.c
index d1f3ec397..81cc2d80c 100644
--- a/src/nautilus-canvas-view.c
+++ b/src/nautilus-canvas-view.c
@@ -28,7 +28,7 @@
#include "nautilus-canvas-view-container.h"
#include "nautilus-desktop-canvas-view.h"
#include "nautilus-error-reporting.h"
-#include "nautilus-view-dnd.h"
+#include "nautilus-files-view-dnd.h"
#include "nautilus-toolbar.h"
#include <stdlib.h>
@@ -158,7 +158,7 @@ static void nautilus_canvas_view_set_directory_sort_by (N
const char *sort_by);
static void nautilus_canvas_view_update_click_mode (NautilusCanvasView *canvas_view);
static gboolean nautilus_canvas_view_supports_scaling (NautilusCanvasView *canvas_view);
-static void nautilus_canvas_view_reveal_selection (NautilusView *view);
+static void nautilus_canvas_view_reveal_selection (NautilusFilesView *view);
static const SortCriterion *get_sort_criterion_by_sort_type (NautilusFileSortType sort_type);
static gboolean set_sort_reversed (NautilusCanvasView *canvas_view,
gboolean new_value,
@@ -166,9 +166,9 @@ static gboolean set_sort_reversed (NautilusC
static void switch_to_manual_layout (NautilusCanvasView *view);
static NautilusFileSortType get_default_sort_order (NautilusFile *file,
gboolean *reversed);
-static void nautilus_canvas_view_clear (NautilusView *view);
+static void nautilus_canvas_view_clear (NautilusFilesView *view);
-G_DEFINE_TYPE (NautilusCanvasView, nautilus_canvas_view, NAUTILUS_TYPE_VIEW);
+G_DEFINE_TYPE (NautilusCanvasView, nautilus_canvas_view, NAUTILUS_TYPE_FILES_VIEW);
static void
nautilus_canvas_view_destroy (GtkWidget *object)
@@ -177,7 +177,7 @@ nautilus_canvas_view_destroy (GtkWidget *object)
canvas_view = NAUTILUS_CANVAS_VIEW (object);
- nautilus_canvas_view_clear (NAUTILUS_VIEW (object));
+ nautilus_canvas_view_clear (NAUTILUS_FILES_VIEW (object));
if (canvas_view->details->react_to_canvas_change_idle_id != 0) {
g_source_remove (canvas_view->details->react_to_canvas_change_idle_id);
@@ -273,7 +273,7 @@ real_set_sort_criterion (NautilusCanvasView *canvas_view,
{
NautilusFile *file;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (canvas_view));
if (clear) {
nautilus_file_set_metadata (file,
@@ -350,7 +350,7 @@ unref_cover (NautilusCanvasIconData *data, gpointer callback_data)
}
static void
-nautilus_canvas_view_clear (NautilusView *view)
+nautilus_canvas_view_clear (NautilusFilesView *view)
{
NautilusCanvasContainer *canvas_container;
GSList *file_list;
@@ -370,26 +370,26 @@ nautilus_canvas_view_clear (NautilusView *view)
}
static void
-nautilus_canvas_view_remove_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
+nautilus_canvas_view_remove_file (NautilusFilesView *view, NautilusFile *file, NautilusDirectory *directory)
{
NautilusCanvasView *canvas_view;
- /* This used to assert that 'directory == nautilus_view_get_model (view)', but that
+ /* This used to assert that 'directory == nautilus_files_view_get_model (view)', but that
* resulted in a lot of crash reports (bug #352592). I don't see how that trace happens.
* It seems that somehow we get a files_changed event sent to the view from a directory
* that isn't the model, but the code disables the monitor and signal callback handlers when
* changing directories. Maybe we can get some more information when this happens.
* Further discussion in bug #368178.
*/
- if (directory != nautilus_view_get_model (view)) {
+ if (directory != nautilus_files_view_get_model (view)) {
char *file_uri, *dir_uri, *model_uri;
file_uri = nautilus_file_get_uri (file);
dir_uri = nautilus_directory_get_uri (directory);
- model_uri = nautilus_directory_get_uri (nautilus_view_get_model (view));
+ model_uri = nautilus_directory_get_uri (nautilus_files_view_get_model (view));
g_warning ("nautilus_canvas_view_remove_file() - directory not canvas view model, shouldn't happen.\n"
"file: %p:%s, dir: %p:%s, model: %p:%s, view loading: %d\n"
"If you see this, please add this info to http://bugzilla.gnome.org/show_bug.cgi?id=368178",
- file, file_uri, directory, dir_uri, nautilus_view_get_model (view), model_uri, nautilus_view_get_loading (view));
+ file, file_uri, directory, dir_uri, nautilus_files_view_get_model (view), model_uri, nautilus_files_view_get_loading (view));
g_free (file_uri);
g_free (dir_uri);
g_free (model_uri);
@@ -404,18 +404,18 @@ nautilus_canvas_view_remove_file (NautilusView *view, NautilusFile *file, Nautil
}
static void
-nautilus_canvas_view_add_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
+nautilus_canvas_view_add_file (NautilusFilesView *view, NautilusFile *file, NautilusDirectory *directory)
{
NautilusCanvasView *canvas_view;
NautilusCanvasContainer *canvas_container;
- g_assert (directory == nautilus_view_get_model (view));
+ g_assert (directory == nautilus_files_view_get_model (view));
canvas_view = NAUTILUS_CANVAS_VIEW (view);
canvas_container = get_canvas_container (canvas_view);
/* Reset scroll region for the first canvas added when loading a directory. */
- if (nautilus_view_get_loading (view) && nautilus_canvas_container_is_empty (canvas_container)) {
+ if (nautilus_files_view_get_loading (view) && nautilus_canvas_container_is_empty (canvas_container)) {
nautilus_canvas_container_reset_scroll_region (canvas_container);
}
@@ -426,11 +426,11 @@ nautilus_canvas_view_add_file (NautilusView *view, NautilusFile *file, NautilusD
}
static void
-nautilus_canvas_view_file_changed (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
+nautilus_canvas_view_file_changed (NautilusFilesView *view, NautilusFile *file, NautilusDirectory *directory)
{
NautilusCanvasView *canvas_view;
- g_assert (directory == nautilus_view_get_model (view));
+ g_assert (directory == nautilus_files_view_get_model (view));
g_return_if_fail (view != NULL);
canvas_view = NAUTILUS_CANVAS_VIEW (view);
@@ -642,7 +642,7 @@ set_sort_reversed (NautilusCanvasView *canvas_view,
if (set_metadata) {
/* Store the new sort setting. */
- nautilus_canvas_view_set_directory_sort_reversed (canvas_view, nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view)), new_value);
+ nautilus_canvas_view_set_directory_sort_reversed (canvas_view, nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (canvas_view)), new_value);
}
return TRUE;
@@ -702,7 +702,7 @@ get_default_zoom_level (NautilusCanvasView *canvas_view)
}
static void
-nautilus_canvas_view_begin_loading (NautilusView *view)
+nautilus_canvas_view_begin_loading (NautilusFilesView *view)
{
NautilusCanvasView *canvas_view;
GtkWidget *canvas_container;
@@ -712,7 +712,7 @@ nautilus_canvas_view_begin_loading (NautilusView *view)
g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
canvas_view = NAUTILUS_CANVAS_VIEW (view);
- file = nautilus_view_get_directory_as_file (view);
+ file = nautilus_files_view_get_directory_as_file (view);
uri = nautilus_file_get_uri (file);
canvas_container = GTK_WIDGET (get_canvas_container (canvas_view));
@@ -745,8 +745,8 @@ nautilus_canvas_view_begin_loading (NautilusView *view)
/* We could changed to the trash directory or to searching, and then we
* need to update the menus */
- nautilus_view_update_context_menus(view);
- nautilus_view_update_toolbar_menus(view);
+ nautilus_files_view_update_context_menus(view);
+ nautilus_files_view_update_toolbar_menus(view);
}
static void
@@ -766,7 +766,7 @@ canvas_view_notify_clipboard_info (NautilusClipboardMonitor *monitor,
}
static void
-nautilus_canvas_view_end_loading (NautilusView *view,
+nautilus_canvas_view_end_loading (NautilusFilesView *view,
gboolean all_files_seen)
{
NautilusCanvasView *canvas_view;
@@ -786,7 +786,7 @@ nautilus_canvas_view_end_loading (NautilusView *view,
}
static NautilusCanvasZoomLevel
-nautilus_canvas_view_get_zoom_level (NautilusView *view)
+nautilus_canvas_view_get_zoom_level (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), NAUTILUS_CANVAS_ZOOM_LEVEL_STANDARD);
@@ -794,7 +794,7 @@ nautilus_canvas_view_get_zoom_level (NautilusView *view)
}
static void
-nautilus_canvas_view_zoom_to_level (NautilusView *view,
+nautilus_canvas_view_zoom_to_level (NautilusFilesView *view,
gint new_level)
{
NautilusCanvasView *canvas_view;
@@ -810,19 +810,19 @@ nautilus_canvas_view_zoom_to_level (NautilusView *view,
return;
nautilus_canvas_container_set_zoom_level (canvas_container, new_level);
- g_action_group_change_action_state (nautilus_view_get_action_group (view),
+ g_action_group_change_action_state (nautilus_files_view_get_action_group (view),
"zoom-to-level", g_variant_new_int32 (new_level));
- nautilus_view_update_toolbar_menus (view);
+ nautilus_files_view_update_toolbar_menus (view);
}
static void
-nautilus_canvas_view_bump_zoom_level (NautilusView *view, int zoom_increment)
+nautilus_canvas_view_bump_zoom_level (NautilusFilesView *view, int zoom_increment)
{
NautilusCanvasZoomLevel new_level;
g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
- if (!nautilus_view_supports_zooming (view)) {
+ if (!nautilus_files_view_supports_zooming (view)) {
return;
}
@@ -835,7 +835,7 @@ nautilus_canvas_view_bump_zoom_level (NautilusView *view, int zoom_increment)
}
static void
-nautilus_canvas_view_restore_default_zoom_level (NautilusView *view)
+nautilus_canvas_view_restore_default_zoom_level (NautilusFilesView *view)
{
NautilusCanvasView *canvas_view;
@@ -847,7 +847,7 @@ nautilus_canvas_view_restore_default_zoom_level (NautilusView *view)
}
static gboolean
-nautilus_canvas_view_can_zoom_in (NautilusView *view)
+nautilus_canvas_view_can_zoom_in (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), FALSE);
@@ -856,7 +856,7 @@ nautilus_canvas_view_can_zoom_in (NautilusView *view)
}
static gboolean
-nautilus_canvas_view_can_zoom_out (NautilusView *view)
+nautilus_canvas_view_can_zoom_out (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), FALSE);
@@ -865,7 +865,7 @@ nautilus_canvas_view_can_zoom_out (NautilusView *view)
}
static gboolean
-nautilus_canvas_view_is_empty (NautilusView *view)
+nautilus_canvas_view_is_empty (NautilusFilesView *view)
{
g_assert (NAUTILUS_IS_CANVAS_VIEW (view));
@@ -874,7 +874,7 @@ nautilus_canvas_view_is_empty (NautilusView *view)
}
static GList *
-nautilus_canvas_view_get_selection (NautilusView *view)
+nautilus_canvas_view_get_selection (NautilusFilesView *view)
{
GList *list;
@@ -898,7 +898,7 @@ action_reversed_order (GSimpleAction *action,
reversed_order = g_variant_get_boolean (state);
if (set_sort_reversed (user_data, reversed_order, TRUE)) {
nautilus_canvas_container_sort (get_canvas_container (user_data));
- nautilus_canvas_view_reveal_selection (NAUTILUS_VIEW (user_data));
+ nautilus_canvas_view_reveal_selection (NAUTILUS_FILES_VIEW (user_data));
}
g_simple_action_set_state (action, state);
@@ -914,7 +914,7 @@ action_keep_aligned (GSimpleAction *action,
gboolean keep_aligned;
canvas_view = NAUTILUS_CANVAS_VIEW (user_data);
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (canvas_view));
keep_aligned = g_variant_get_boolean (state);
nautilus_canvas_view_set_directory_keep_aligned (canvas_view,
@@ -949,7 +949,7 @@ action_sort_order_changed (GSimpleAction *action,
set_sort_criterion (user_data, sort_criterion, TRUE);
nautilus_canvas_container_sort (get_canvas_container (user_data));
- nautilus_canvas_view_reveal_selection (NAUTILUS_VIEW (user_data));
+ nautilus_canvas_view_reveal_selection (NAUTILUS_FILES_VIEW (user_data));
}
g_simple_action_set_state (action, value);
@@ -960,12 +960,12 @@ action_zoom_to_level (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
- NautilusView *view;
+ NautilusFilesView *view;
NautilusCanvasZoomLevel zoom_level;
- g_assert (NAUTILUS_IS_VIEW (user_data));
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
- view = NAUTILUS_VIEW (user_data);
+ view = NAUTILUS_FILES_VIEW (user_data);
zoom_level = g_variant_get_int32 (state);
nautilus_canvas_view_zoom_to_level (view, zoom_level);
@@ -979,7 +979,7 @@ static void
switch_to_manual_layout (NautilusCanvasView *canvas_view)
{
if (!nautilus_canvas_view_using_auto_layout (canvas_view) ||
- !nautilus_view_is_editable (NAUTILUS_VIEW (canvas_view))) {
+ !nautilus_files_view_is_editable (NAUTILUS_FILES_VIEW (canvas_view))) {
return;
}
@@ -998,7 +998,7 @@ layout_changed_callback (NautilusCanvasContainer *container,
g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
g_assert (container == get_canvas_container (canvas_view));
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (canvas_view));
if (file != NULL) {
nautilus_canvas_view_set_directory_auto_layout
@@ -1009,9 +1009,9 @@ layout_changed_callback (NautilusCanvasContainer *container,
}
static gboolean
-nautilus_canvas_view_can_rename_file (NautilusView *view, NautilusFile *file)
+nautilus_canvas_view_can_rename_file (NautilusFilesView *view, NautilusFile *file)
{
- return NAUTILUS_VIEW_CLASS(nautilus_canvas_view_parent_class)->can_rename_file (view, file);
+ return NAUTILUS_FILES_VIEW_CLASS(nautilus_canvas_view_parent_class)->can_rename_file (view, file);
}
const GActionEntry canvas_view_entries[] = {
@@ -1031,7 +1031,7 @@ update_sort_action_state_hint (NautilusCanvasView *canvas_view)
GVariant *state_hint;
gint idx;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (canvas_view));
g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
for (idx = 0; idx < G_N_ELEMENTS (sort_criteria); idx++) {
@@ -1042,7 +1042,7 @@ update_sort_action_state_hint (NautilusCanvasView *canvas_view)
state_hint = g_variant_builder_end (&builder);
- action_group = nautilus_view_get_action_group (NAUTILUS_VIEW (canvas_view));
+ action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (canvas_view));
action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "sort");
g_simple_action_set_state_hint (G_SIMPLE_ACTION (action), state_hint);
@@ -1050,11 +1050,11 @@ update_sort_action_state_hint (NautilusCanvasView *canvas_view)
}
static gboolean
-showing_recent_directory (NautilusView *view)
+showing_recent_directory (NautilusFilesView *view)
{
NautilusFile *file;
- file = nautilus_view_get_directory_as_file (view);
+ file = nautilus_files_view_get_directory_as_file (view);
if (file != NULL) {
return nautilus_file_is_in_recent (file);
}
@@ -1062,11 +1062,11 @@ showing_recent_directory (NautilusView *view)
}
static gboolean
-showing_search_directory (NautilusView *view)
+showing_search_directory (NautilusFilesView *view)
{
NautilusFile *file;
- file = nautilus_view_get_directory_as_file (view);
+ file = nautilus_files_view_get_directory_as_file (view);
if (file != NULL) {
return nautilus_file_is_in_search (file);
}
@@ -1074,7 +1074,7 @@ showing_search_directory (NautilusView *view)
}
static void
-nautilus_canvas_view_update_actions_state (NautilusView *view)
+nautilus_canvas_view_update_actions_state (NautilusFilesView *view)
{
GActionGroup *view_action_group;
GAction *action;
@@ -1083,9 +1083,9 @@ nautilus_canvas_view_update_actions_state (NautilusView *view)
canvas_view = NAUTILUS_CANVAS_VIEW (view);
- NAUTILUS_VIEW_CLASS (nautilus_canvas_view_parent_class)->update_actions_state (view);
+ NAUTILUS_FILES_VIEW_CLASS (nautilus_canvas_view_parent_class)->update_actions_state (view);
- view_action_group = nautilus_view_get_action_group (view);
+ view_action_group = nautilus_files_view_get_action_group (view);
if (nautilus_canvas_view_supports_auto_layout (canvas_view)) {
GVariant *sort_state;
GVariant *reversed_state;
@@ -1134,7 +1134,7 @@ nautilus_canvas_view_update_actions_state (NautilusView *view)
}
static void
-nautilus_canvas_view_select_all (NautilusView *view)
+nautilus_canvas_view_select_all (NautilusFilesView *view)
{
NautilusCanvasContainer *canvas_container;
@@ -1145,7 +1145,7 @@ nautilus_canvas_view_select_all (NautilusView *view)
}
static void
-nautilus_canvas_view_select_first (NautilusView *view)
+nautilus_canvas_view_select_first (NautilusFilesView *view)
{
NautilusCanvasContainer *canvas_container;
@@ -1156,13 +1156,13 @@ nautilus_canvas_view_select_first (NautilusView *view)
}
static void
-nautilus_canvas_view_reveal_selection (NautilusView *view)
+nautilus_canvas_view_reveal_selection (NautilusFilesView *view)
{
GList *selection;
g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
- selection = nautilus_view_get_selection (view);
+ selection = nautilus_files_view_get_selection (view);
/* Make sure at least one of the selected items is scrolled into view */
if (selection != NULL) {
@@ -1175,7 +1175,7 @@ nautilus_canvas_view_reveal_selection (NautilusView *view)
}
static GdkRectangle*
-nautilus_canvas_view_compute_rename_popover_relative_to (NautilusView *view)
+nautilus_canvas_view_compute_rename_popover_relative_to (NautilusFilesView *view)
{
GArray *bounding_boxes;
GdkRectangle *bounding_box;
@@ -1187,7 +1187,7 @@ nautilus_canvas_view_compute_rename_popover_relative_to (NautilusView *view)
bounding_boxes = nautilus_canvas_container_get_selected_icons_bounding_box (canvas_container);
/* We only allow renaming one item at once */
bounding_box = &g_array_index (bounding_boxes, GdkRectangle, 0);
- parent_container = nautilus_view_get_content_widget (view);
+ parent_container = nautilus_files_view_get_content_widget (view);
vadjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (parent_container));
hadjustment = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (parent_container));
@@ -1200,7 +1200,7 @@ nautilus_canvas_view_compute_rename_popover_relative_to (NautilusView *view)
}
static GArray *
-nautilus_canvas_view_get_selected_icon_locations (NautilusView *view)
+nautilus_canvas_view_get_selected_icon_locations (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), NULL);
@@ -1210,7 +1210,7 @@ nautilus_canvas_view_get_selected_icon_locations (NautilusView *view)
static void
-nautilus_canvas_view_set_selection (NautilusView *view, GList *selection)
+nautilus_canvas_view_set_selection (NautilusFilesView *view, GList *selection)
{
g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
@@ -1219,7 +1219,7 @@ nautilus_canvas_view_set_selection (NautilusView *view, GList *selection)
}
static void
-nautilus_canvas_view_invert_selection (NautilusView *view)
+nautilus_canvas_view_invert_selection (NautilusFilesView *view)
{
g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
@@ -1228,7 +1228,7 @@ nautilus_canvas_view_invert_selection (NautilusView *view)
}
static gboolean
-nautilus_canvas_view_using_manual_layout (NautilusView *view)
+nautilus_canvas_view_using_manual_layout (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), FALSE);
@@ -1236,7 +1236,7 @@ nautilus_canvas_view_using_manual_layout (NautilusView *view)
}
static void
-nautilus_canvas_view_widget_to_file_operation_position (NautilusView *view,
+nautilus_canvas_view_widget_to_file_operation_position (NautilusFilesView *view,
GdkPoint *position)
{
g_assert (NAUTILUS_IS_CANVAS_VIEW (view));
@@ -1253,7 +1253,7 @@ canvas_container_activate_callback (NautilusCanvasContainer *container,
g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
g_assert (container == get_canvas_container (canvas_view));
- nautilus_view_activate_files (NAUTILUS_VIEW (canvas_view),
+ nautilus_files_view_activate_files (NAUTILUS_FILES_VIEW (canvas_view),
file_list,
0, TRUE);
}
@@ -1267,7 +1267,7 @@ canvas_container_activate_previewer_callback (NautilusCanvasContainer *container
g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
g_assert (container == get_canvas_container (canvas_view));
- nautilus_view_preview_files (NAUTILUS_VIEW (canvas_view),
+ nautilus_files_view_preview_files (NAUTILUS_FILES_VIEW (canvas_view),
file_list, locations);
}
@@ -1332,7 +1332,7 @@ canvas_container_activate_alternate_callback (NautilusCanvasContainer *container
DEBUG ("Activate alternate, open in tab %d, close behind %d, new window %d\n",
open_in_tab, close_behind, open_in_window);
- nautilus_view_activate_files (NAUTILUS_VIEW (canvas_view),
+ nautilus_files_view_activate_files (NAUTILUS_FILES_VIEW (canvas_view),
file_list,
flags,
TRUE);
@@ -1345,7 +1345,7 @@ band_select_started_callback (NautilusCanvasContainer *container,
g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
g_assert (container == get_canvas_container (canvas_view));
- nautilus_view_start_batching_selection_changes (NAUTILUS_VIEW (canvas_view));
+ nautilus_files_view_start_batching_selection_changes (NAUTILUS_FILES_VIEW (canvas_view));
}
static void
@@ -1355,7 +1355,7 @@ band_select_ended_callback (NautilusCanvasContainer *container,
g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
g_assert (container == get_canvas_container (canvas_view));
- nautilus_view_stop_batching_selection_changes (NAUTILUS_VIEW (canvas_view));
+ nautilus_files_view_stop_batching_selection_changes (NAUTILUS_FILES_VIEW (canvas_view));
}
int
@@ -1366,12 +1366,12 @@ nautilus_canvas_view_compare_files (NautilusCanvasView *canvas_view,
return nautilus_file_compare_for_sort
(a, b, canvas_view->details->sort->sort_type,
/* Use type-unsafe cast for performance */
- nautilus_view_should_sort_directories_first ((NautilusView *)canvas_view),
+ nautilus_files_view_should_sort_directories_first ((NautilusFilesView *)canvas_view),
canvas_view->details->sort_reversed);
}
static int
-compare_files (NautilusView *canvas_view,
+compare_files (NautilusFilesView *canvas_view,
NautilusFile *a,
NautilusFile *b)
{
@@ -1385,7 +1385,7 @@ selection_changed_callback (NautilusCanvasContainer *container,
g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
g_assert (container == get_canvas_container (canvas_view));
- nautilus_view_notify_selection_changed (NAUTILUS_VIEW (canvas_view));
+ nautilus_files_view_notify_selection_changed (NAUTILUS_FILES_VIEW (canvas_view));
}
static void
@@ -1396,7 +1396,7 @@ canvas_container_context_click_selection_callback (NautilusCanvasContainer *cont
g_assert (NAUTILUS_IS_CANVAS_CONTAINER (container));
g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
- nautilus_view_pop_up_selection_context_menu (NAUTILUS_VIEW (canvas_view), event);
+ nautilus_files_view_pop_up_selection_context_menu (NAUTILUS_FILES_VIEW (canvas_view), event);
}
static void
@@ -1407,7 +1407,7 @@ canvas_container_context_click_background_callback (NautilusCanvasContainer *con
g_assert (NAUTILUS_IS_CANVAS_CONTAINER (container));
g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
- nautilus_view_pop_up_background_context_menu (NAUTILUS_VIEW (canvas_view), event);
+ nautilus_files_view_pop_up_background_context_menu (NAUTILUS_FILES_VIEW (canvas_view), event);
}
static void
@@ -1478,7 +1478,7 @@ get_icon_drop_target_uri_callback (NautilusCanvasContainer *container,
/* Preferences changed callbacks */
static void
-nautilus_canvas_view_click_policy_changed (NautilusView *directory_view)
+nautilus_canvas_view_click_policy_changed (NautilusFilesView *directory_view)
{
g_assert (NAUTILUS_IS_CANVAS_VIEW (directory_view));
@@ -1517,7 +1517,7 @@ default_sort_order_changed_callback (gpointer callback_data)
canvas_view = NAUTILUS_CANVAS_VIEW (callback_data);
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (canvas_view));
sort_name = nautilus_canvas_view_get_directory_sort_by (canvas_view, file);
set_sort_criterion (canvas_view, get_sort_criterion_by_metadata_text (sort_name), FALSE);
g_free (sort_name);
@@ -1539,7 +1539,7 @@ default_sort_in_reverse_order_changed_callback (gpointer callback_data)
canvas_view = NAUTILUS_CANVAS_VIEW (callback_data);
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (canvas_view));
set_sort_reversed (canvas_view, nautilus_canvas_view_get_directory_sort_reversed (canvas_view, file), FALSE);
canvas_container = get_canvas_container (canvas_view);
g_return_if_fail (NAUTILUS_IS_CANVAS_CONTAINER (canvas_container));
@@ -1548,7 +1548,7 @@ default_sort_in_reverse_order_changed_callback (gpointer callback_data)
}
static void
-nautilus_canvas_view_sort_directories_first_changed (NautilusView *directory_view)
+nautilus_canvas_view_sort_directories_first_changed (NautilusFilesView *directory_view)
{
NautilusCanvasView *canvas_view;
@@ -1564,16 +1564,16 @@ static gboolean
canvas_view_can_accept_item (NautilusCanvasContainer *container,
NautilusFile *target_item,
const char *item_uri,
- NautilusView *view)
+ NautilusFilesView *view)
{
return nautilus_drag_can_accept_item (target_item, item_uri);
}
static char *
canvas_view_get_container_uri (NautilusCanvasContainer *container,
- NautilusView *view)
+ NautilusFilesView *view)
{
- return nautilus_view_get_uri (view);
+ return nautilus_files_view_get_uri (view);
}
static void
@@ -1583,12 +1583,12 @@ canvas_view_move_copy_items (NautilusCanvasContainer *container,
const char *target_dir,
int copy_action,
int x, int y,
- NautilusView *view)
+ NautilusFilesView *view)
{
nautilus_clipboard_clear_if_colliding_uris (GTK_WIDGET (view),
item_uris,
- nautilus_view_get_copied_files_atom (view));
- nautilus_view_move_copy_items (view, item_uris, relative_item_points, target_dir,
+ nautilus_files_view_get_copied_files_atom (view));
+ nautilus_files_view_move_copy_items (view, item_uris, relative_item_points, target_dir,
copy_action, x, y);
}
@@ -1617,7 +1617,7 @@ get_stored_layout_timestamp (NautilusCanvasContainer *container,
NautilusDirectory *directory;
if (icon_data == NULL) {
- directory = nautilus_view_get_model (NAUTILUS_VIEW (view));
+ directory = nautilus_files_view_get_model (NAUTILUS_FILES_VIEW (view));
if (directory == NULL) {
return FALSE;
}
@@ -1644,7 +1644,7 @@ store_layout_timestamp (NautilusCanvasContainer *container,
NautilusDirectory *directory;
if (icon_data == NULL) {
- directory = nautilus_view_get_model (NAUTILUS_VIEW (view));
+ directory = nautilus_files_view_get_model (NAUTILUS_FILES_VIEW (view));
if (directory == NULL) {
return FALSE;
}
@@ -1669,7 +1669,7 @@ create_canvas_container (NautilusCanvasView *canvas_view)
NautilusCanvasContainer *canvas_container;
GtkWidget *content_widget;
- content_widget = nautilus_view_get_content_widget (NAUTILUS_VIEW (canvas_view));
+ content_widget = nautilus_files_view_get_content_widget (NAUTILUS_FILES_VIEW (canvas_view));
canvas_container = nautilus_canvas_view_container_new (canvas_view);
canvas_view->details->canvas_container = GTK_WIDGET (canvas_container);
g_object_add_weak_pointer (G_OBJECT (canvas_container),
@@ -1713,10 +1713,10 @@ create_canvas_container (NautilusCanvasView *canvas_view)
g_signal_connect_object (canvas_container, "layout-changed",
G_CALLBACK (layout_changed_callback), canvas_view, 0);
g_signal_connect_object (canvas_container, "icon-stretch-started",
- G_CALLBACK (nautilus_view_update_context_menus), canvas_view,
+ G_CALLBACK (nautilus_files_view_update_context_menus), canvas_view,
G_CONNECT_SWAPPED);
g_signal_connect_object (canvas_container, "icon-stretch-ended",
- G_CALLBACK (nautilus_view_update_context_menus), canvas_view,
+ G_CALLBACK (nautilus_files_view_update_context_menus), canvas_view,
G_CONNECT_SWAPPED);
g_signal_connect_object (canvas_container, "get-stored-layout-timestamp",
@@ -1742,7 +1742,7 @@ canvas_view_handle_netscape_url (NautilusCanvasContainer *container, const char
const char *target_uri,
GdkDragAction action, int x, int y, NautilusCanvasView *view)
{
- nautilus_view_handle_netscape_url_drop (NAUTILUS_VIEW (view),
+ nautilus_files_view_handle_netscape_url_drop (NAUTILUS_FILES_VIEW (view),
encoded_url, target_uri, action, x, y);
}
@@ -1751,7 +1751,7 @@ canvas_view_handle_uri_list (NautilusCanvasContainer *container, const char *ite
const char *target_uri,
GdkDragAction action, int x, int y, NautilusCanvasView *view)
{
- nautilus_view_handle_uri_list_drop (NAUTILUS_VIEW (view),
+ nautilus_files_view_handle_uri_list_drop (NAUTILUS_FILES_VIEW (view),
item_uris, target_uri, action, x, y);
}
@@ -1760,7 +1760,7 @@ canvas_view_handle_text (NautilusCanvasContainer *container, const char *text,
const char *target_uri,
GdkDragAction action, int x, int y, NautilusCanvasView *view)
{
- nautilus_view_handle_text_drop (NAUTILUS_VIEW (view),
+ nautilus_files_view_handle_text_drop (NAUTILUS_FILES_VIEW (view),
text, target_uri, action, x, y);
}
@@ -1769,7 +1769,7 @@ canvas_view_handle_raw (NautilusCanvasContainer *container, const char *raw_data
int length, const char *target_uri, const char *direct_save_uri,
GdkDragAction action, int x, int y, NautilusCanvasView *view)
{
- nautilus_view_handle_raw_drop (NAUTILUS_VIEW (view),
+ nautilus_files_view_handle_raw_drop (NAUTILUS_FILES_VIEW (view),
raw_data, length, target_uri, direct_save_uri, action, x, y);
}
@@ -1778,11 +1778,11 @@ canvas_view_handle_hover (NautilusCanvasContainer *container,
const char *target_uri,
NautilusCanvasView *view)
{
- nautilus_view_handle_hover (NAUTILUS_VIEW (view), target_uri);
+ nautilus_files_view_handle_hover (NAUTILUS_FILES_VIEW (view), target_uri);
}
static char *
-canvas_view_get_first_visible_file (NautilusView *view)
+canvas_view_get_first_visible_file (NautilusFilesView *view)
{
NautilusFile *file;
NautilusCanvasView *canvas_view;
@@ -1799,7 +1799,7 @@ canvas_view_get_first_visible_file (NautilusView *view)
}
static void
-canvas_view_scroll_to_file (NautilusView *view,
+canvas_view_scroll_to_file (NautilusFilesView *view,
const char *uri)
{
NautilusFile *file;
@@ -1820,7 +1820,7 @@ canvas_view_scroll_to_file (NautilusView *view,
}
static const char *
-nautilus_canvas_view_get_id (NautilusView *view)
+nautilus_canvas_view_get_id (NautilusFilesView *view)
{
return NAUTILUS_CANVAS_VIEW_ID;
}
@@ -1883,7 +1883,7 @@ nautilus_canvas_view_finalize (GObject *object)
}
static GIcon*
-nautilus_canvas_view_get_icon (NautilusView *view)
+nautilus_canvas_view_get_icon (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), NULL);
@@ -1893,10 +1893,10 @@ nautilus_canvas_view_get_icon (NautilusView *view)
static void
nautilus_canvas_view_class_init (NautilusCanvasViewClass *klass)
{
- NautilusViewClass *nautilus_view_class;
+ NautilusFilesViewClass *nautilus_files_view_class;
GObjectClass *oclass;
- nautilus_view_class = NAUTILUS_VIEW_CLASS (klass);
+ nautilus_files_view_class = NAUTILUS_FILES_VIEW_CLASS (klass);
oclass = G_OBJECT_CLASS (klass);
oclass->set_property = nautilus_canvas_view_set_property;
@@ -1904,37 +1904,37 @@ nautilus_canvas_view_class_init (NautilusCanvasViewClass *klass)
GTK_WIDGET_CLASS (klass)->destroy = nautilus_canvas_view_destroy;
- nautilus_view_class->add_file = nautilus_canvas_view_add_file;
- nautilus_view_class->begin_loading = nautilus_canvas_view_begin_loading;
- nautilus_view_class->bump_zoom_level = nautilus_canvas_view_bump_zoom_level;
- nautilus_view_class->can_rename_file = nautilus_canvas_view_can_rename_file;
- nautilus_view_class->can_zoom_in = nautilus_canvas_view_can_zoom_in;
- nautilus_view_class->can_zoom_out = nautilus_canvas_view_can_zoom_out;
- nautilus_view_class->clear = nautilus_canvas_view_clear;
- nautilus_view_class->end_loading = nautilus_canvas_view_end_loading;
- nautilus_view_class->file_changed = nautilus_canvas_view_file_changed;
- nautilus_view_class->get_selected_icon_locations = nautilus_canvas_view_get_selected_icon_locations;
- nautilus_view_class->compute_rename_popover_relative_to = nautilus_canvas_view_compute_rename_popover_relative_to;
- nautilus_view_class->get_selection = nautilus_canvas_view_get_selection;
- nautilus_view_class->get_selection_for_file_transfer = nautilus_canvas_view_get_selection;
- nautilus_view_class->is_empty = nautilus_canvas_view_is_empty;
- nautilus_view_class->remove_file = nautilus_canvas_view_remove_file;
- nautilus_view_class->restore_default_zoom_level = nautilus_canvas_view_restore_default_zoom_level;
- nautilus_view_class->reveal_selection = nautilus_canvas_view_reveal_selection;
- nautilus_view_class->select_all = nautilus_canvas_view_select_all;
- nautilus_view_class->select_first = nautilus_canvas_view_select_first;
- nautilus_view_class->set_selection = nautilus_canvas_view_set_selection;
- nautilus_view_class->invert_selection = nautilus_canvas_view_invert_selection;
- nautilus_view_class->compare_files = compare_files;
- nautilus_view_class->click_policy_changed = nautilus_canvas_view_click_policy_changed;
- nautilus_view_class->update_actions_state = nautilus_canvas_view_update_actions_state;
- nautilus_view_class->sort_directories_first_changed = nautilus_canvas_view_sort_directories_first_changed;
- nautilus_view_class->using_manual_layout = nautilus_canvas_view_using_manual_layout;
- nautilus_view_class->widget_to_file_operation_position = nautilus_canvas_view_widget_to_file_operation_position;
- nautilus_view_class->get_view_id = nautilus_canvas_view_get_id;
- nautilus_view_class->get_first_visible_file = canvas_view_get_first_visible_file;
- nautilus_view_class->scroll_to_file = canvas_view_scroll_to_file;
- nautilus_view_class->get_icon = nautilus_canvas_view_get_icon;
+ nautilus_files_view_class->add_file = nautilus_canvas_view_add_file;
+ nautilus_files_view_class->begin_loading = nautilus_canvas_view_begin_loading;
+ nautilus_files_view_class->bump_zoom_level = nautilus_canvas_view_bump_zoom_level;
+ nautilus_files_view_class->can_rename_file = nautilus_canvas_view_can_rename_file;
+ nautilus_files_view_class->can_zoom_in = nautilus_canvas_view_can_zoom_in;
+ nautilus_files_view_class->can_zoom_out = nautilus_canvas_view_can_zoom_out;
+ nautilus_files_view_class->clear = nautilus_canvas_view_clear;
+ nautilus_files_view_class->end_loading = nautilus_canvas_view_end_loading;
+ nautilus_files_view_class->file_changed = nautilus_canvas_view_file_changed;
+ nautilus_files_view_class->get_selected_icon_locations = nautilus_canvas_view_get_selected_icon_locations;
+ nautilus_files_view_class->compute_rename_popover_relative_to = nautilus_canvas_view_compute_rename_popover_relative_to;
+ nautilus_files_view_class->get_selection = nautilus_canvas_view_get_selection;
+ nautilus_files_view_class->get_selection_for_file_transfer = nautilus_canvas_view_get_selection;
+ nautilus_files_view_class->is_empty = nautilus_canvas_view_is_empty;
+ nautilus_files_view_class->remove_file = nautilus_canvas_view_remove_file;
+ nautilus_files_view_class->restore_default_zoom_level = nautilus_canvas_view_restore_default_zoom_level;
+ nautilus_files_view_class->reveal_selection = nautilus_canvas_view_reveal_selection;
+ nautilus_files_view_class->select_all = nautilus_canvas_view_select_all;
+ nautilus_files_view_class->select_first = nautilus_canvas_view_select_first;
+ nautilus_files_view_class->set_selection = nautilus_canvas_view_set_selection;
+ nautilus_files_view_class->invert_selection = nautilus_canvas_view_invert_selection;
+ nautilus_files_view_class->compare_files = compare_files;
+ nautilus_files_view_class->click_policy_changed = nautilus_canvas_view_click_policy_changed;
+ nautilus_files_view_class->update_actions_state = nautilus_canvas_view_update_actions_state;
+ nautilus_files_view_class->sort_directories_first_changed = nautilus_canvas_view_sort_directories_first_changed;
+ nautilus_files_view_class->using_manual_layout = nautilus_canvas_view_using_manual_layout;
+ nautilus_files_view_class->widget_to_file_operation_position = nautilus_canvas_view_widget_to_file_operation_position;
+ nautilus_files_view_class->get_view_id = nautilus_canvas_view_get_id;
+ nautilus_files_view_class->get_first_visible_file = canvas_view_get_first_visible_file;
+ nautilus_files_view_class->scroll_to_file = canvas_view_scroll_to_file;
+ nautilus_files_view_class->get_icon = nautilus_canvas_view_get_icon;
properties[PROP_SUPPORTS_AUTO_LAYOUT] =
g_param_spec_boolean ("supports-auto-layout",
@@ -2014,17 +2014,17 @@ nautilus_canvas_view_init (NautilusCanvasView *canvas_view)
"clipboard-info",
G_CALLBACK (canvas_view_notify_clipboard_info), canvas_view);
- view_action_group = nautilus_view_get_action_group (NAUTILUS_VIEW (canvas_view));
+ view_action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (canvas_view));
g_action_map_add_action_entries (G_ACTION_MAP (view_action_group),
canvas_view_entries,
G_N_ELEMENTS (canvas_view_entries),
canvas_view);
/* Keep the action synced with the actual value, so the toolbar can poll it */
- g_action_group_change_action_state (nautilus_view_get_action_group (NAUTILUS_VIEW (canvas_view)),
+ g_action_group_change_action_state (nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (canvas_view)),
"zoom-to-level", g_variant_new_int32 (get_default_zoom_level (canvas_view)));
}
-NautilusView *
+NautilusFilesView *
nautilus_canvas_view_new (NautilusWindowSlot *slot)
{
return g_object_new (NAUTILUS_TYPE_CANVAS_VIEW,
diff --git a/src/nautilus-canvas-view.h b/src/nautilus-canvas-view.h
index e2b77edf9..994b51f31 100644
--- a/src/nautilus-canvas-view.h
+++ b/src/nautilus-canvas-view.h
@@ -25,7 +25,7 @@
#ifndef NAUTILUS_CANVAS_VIEW_H
#define NAUTILUS_CANVAS_VIEW_H
-#include "nautilus-view.h"
+#include "nautilus-files-view.h"
#include "libnautilus-private/nautilus-canvas-container.h"
typedef struct NautilusCanvasView NautilusCanvasView;
@@ -46,12 +46,12 @@ typedef struct NautilusCanvasViewClass NautilusCanvasViewClass;
typedef struct NautilusCanvasViewDetails NautilusCanvasViewDetails;
struct NautilusCanvasView {
- NautilusView parent;
+ NautilusFilesView parent;
NautilusCanvasViewDetails *details;
};
struct NautilusCanvasViewClass {
- NautilusViewClass parent_class;
+ NautilusFilesViewClass parent_class;
};
/* GObject support */
@@ -63,7 +63,7 @@ void nautilus_canvas_view_filter_by_screen (NautilusCanvasView *canvas_view,
gboolean filter);
void nautilus_canvas_view_clean_up_by_name (NautilusCanvasView *canvas_view);
-NautilusView * nautilus_canvas_view_new (NautilusWindowSlot *slot);
+NautilusFilesView * nautilus_canvas_view_new (NautilusWindowSlot *slot);
NautilusCanvasContainer * nautilus_canvas_view_get_canvas_container (NautilusCanvasView *view);
diff --git a/src/nautilus-desktop-canvas-view.c b/src/nautilus-desktop-canvas-view.c
index 6890743ce..49910b027 100644
--- a/src/nautilus-desktop-canvas-view.c
+++ b/src/nautilus-desktop-canvas-view.c
@@ -29,7 +29,7 @@
#include "nautilus-desktop-canvas-view.h"
#include "nautilus-canvas-view-container.h"
-#include "nautilus-view.h"
+#include "nautilus-files-view.h"
#include <X11/Xatom.h>
#include <gtk/gtk.h>
@@ -74,7 +74,7 @@ struct NautilusDesktopCanvasViewDetails
};
static void default_zoom_level_changed (gpointer user_data);
-static void real_update_context_menus (NautilusView *view);
+static void real_update_context_menus (NautilusFilesView *view);
static void nautilus_desktop_canvas_view_update_canvas_container_fonts (NautilusDesktopCanvasView *view);
static void font_changed_callback (gpointer callback_data);
@@ -227,7 +227,7 @@ desktop_canvas_view_property_filter (GdkXEvent *gdk_xevent,
}
static const char *
-real_get_id (NautilusView *view)
+real_get_id (NautilusFilesView *view)
{
return NAUTILUS_DESKTOP_CANVAS_VIEW_ID;
}
@@ -252,14 +252,14 @@ nautilus_desktop_canvas_view_dispose (GObject *object)
font_changed_callback,
canvas_view);
g_signal_handlers_disconnect_by_func (gnome_lockdown_preferences,
- nautilus_view_update_context_menus,
+ nautilus_files_view_update_context_menus,
canvas_view);
G_OBJECT_CLASS (nautilus_desktop_canvas_view_parent_class)->dispose (object);
}
static void
-nautilus_desktop_canvas_view_end_loading (NautilusView *view,
+nautilus_desktop_canvas_view_end_loading (NautilusFilesView *view,
gboolean all_files_seen)
{
gboolean needs_reorganization;
@@ -269,12 +269,12 @@ nautilus_desktop_canvas_view_end_loading (NautilusView *view,
gchar *current_icon_size_string;
NautilusFile *file;
- NAUTILUS_VIEW_CLASS (nautilus_desktop_canvas_view_parent_class)->end_loading (view, all_files_seen);
+ NAUTILUS_FILES_VIEW_CLASS (nautilus_desktop_canvas_view_parent_class)->end_loading (view, all_files_seen);
if (!all_files_seen)
return;
- file = nautilus_view_get_directory_as_file (view);
+ file = nautilus_files_view_get_directory_as_file (view);
g_return_if_fail (file != NULL);
stored_size_icon = nautilus_file_get_metadata (file, NAUTILUS_METADATA_KEY_DESKTOP_ICON_SIZE, NULL);
@@ -297,9 +297,9 @@ nautilus_desktop_canvas_view_end_loading (NautilusView *view,
static void
nautilus_desktop_canvas_view_class_init (NautilusDesktopCanvasViewClass *class)
{
- NautilusViewClass *vclass;
+ NautilusFilesViewClass *vclass;
- vclass = NAUTILUS_VIEW_CLASS (class);
+ vclass = NAUTILUS_FILES_VIEW_CLASS (class);
G_OBJECT_CLASS (class)->dispose = nautilus_desktop_canvas_view_dispose;
@@ -387,7 +387,7 @@ default_zoom_level_changed (gpointer user_data)
gchar *new_icon_size_string;
desktop_canvas_view = NAUTILUS_DESKTOP_CANVAS_VIEW (user_data);
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (user_data));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (user_data));
new_level = get_default_zoom_level ();
new_icon_size = nautilus_canvas_container_get_icon_size_for_zoom_level (new_level);
new_icon_size_string = g_strdup_printf ("%d", new_icon_size);
@@ -421,7 +421,7 @@ do_desktop_rescan (gpointer data)
desktop_canvas_view->details->pending_rescan = TRUE;
nautilus_directory_force_reload
- (nautilus_view_get_model (NAUTILUS_VIEW (desktop_canvas_view)));
+ (nautilus_files_view_get_model (NAUTILUS_FILES_VIEW (desktop_canvas_view)));
return TRUE;
}
@@ -448,7 +448,7 @@ static void
delayed_init (NautilusDesktopCanvasView *desktop_canvas_view)
{
/* Keep track of the load time. */
- g_signal_connect_object (nautilus_view_get_model (NAUTILUS_VIEW (desktop_canvas_view)),
+ g_signal_connect_object (nautilus_files_view_get_model (NAUTILUS_FILES_VIEW (desktop_canvas_view)),
"done-loading",
G_CALLBACK (done_loading), desktop_canvas_view, 0);
@@ -550,7 +550,7 @@ action_change_background (GSimpleAction *action,
{
const gchar *control_center_cmd, *params;
- g_assert (NAUTILUS_VIEW (user_data));
+ g_assert (NAUTILUS_FILES_VIEW (user_data));
control_center_cmd = get_control_center_command (&params);
if (control_center_cmd == NULL) {
@@ -568,7 +568,7 @@ action_empty_trash (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
- g_assert (NAUTILUS_IS_VIEW (user_data));
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
nautilus_file_operations_empty_trash (GTK_WIDGET (user_data));
}
@@ -599,7 +599,7 @@ action_organize_desktop_by_name (GSimpleAction *action,
}
static gboolean
-trash_link_is_selection (NautilusView *view)
+trash_link_is_selection (NautilusFilesView *view)
{
GList *selection;
NautilusDesktopLink *link;
@@ -607,7 +607,7 @@ trash_link_is_selection (NautilusView *view)
result = FALSE;
- selection = nautilus_view_get_selection (view);
+ selection = nautilus_files_view_get_selection (view);
if ((g_list_length (selection) == 1) &&
NAUTILUS_IS_DESKTOP_ICON_FILE (selection->data)) {
@@ -636,7 +636,7 @@ const GActionEntry desktop_view_entries[] = {
};
static void
-real_update_context_menus (NautilusView *view)
+real_update_context_menus (NautilusFilesView *view)
{
NautilusCanvasContainer *canvas_container;
NautilusDesktopCanvasView *desktop_view;
@@ -646,9 +646,9 @@ real_update_context_menus (NautilusView *view)
g_assert (NAUTILUS_IS_DESKTOP_CANVAS_VIEW (view));
- NAUTILUS_VIEW_CLASS (nautilus_desktop_canvas_view_parent_class)->update_context_menus (view);
+ NAUTILUS_FILES_VIEW_CLASS (nautilus_desktop_canvas_view_parent_class)->update_context_menus (view);
- view_action_group = nautilus_view_get_action_group (view);
+ view_action_group = nautilus_files_view_get_action_group (view);
desktop_view = NAUTILUS_DESKTOP_CANVAS_VIEW (view);
action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "empty-trash");
@@ -664,7 +664,7 @@ real_update_context_menus (NautilusView *view)
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE);
/* Stretch */
- selection_count = nautilus_view_get_selection_count (view);
+ selection_count = nautilus_files_view_get_selection_count (view);
canvas_container = get_canvas_container (desktop_view);
action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "stretch");
@@ -723,10 +723,10 @@ nautilus_desktop_canvas_view_init (NautilusDesktopCanvasView *desktop_canvas_vie
gtk_adjustment_set_value (hadj, 0);
gtk_adjustment_set_value (vadj, 0);
- nautilus_view_ignore_hidden_file_preferences
- (NAUTILUS_VIEW (desktop_canvas_view));
+ nautilus_files_view_ignore_hidden_file_preferences
+ (NAUTILUS_FILES_VIEW (desktop_canvas_view));
- nautilus_view_set_show_foreign (NAUTILUS_VIEW (desktop_canvas_view),
+ nautilus_files_view_set_show_foreign (NAUTILUS_FILES_VIEW (desktop_canvas_view),
FALSE);
g_signal_connect_object (canvas_container, "realize",
@@ -752,18 +752,18 @@ nautilus_desktop_canvas_view_init (NautilusDesktopCanvasView *desktop_canvas_vie
g_signal_connect_swapped (gnome_lockdown_preferences,
"changed::" NAUTILUS_PREFERENCES_LOCKDOWN_COMMAND_LINE,
- G_CALLBACK (nautilus_view_update_context_menus),
+ G_CALLBACK (nautilus_files_view_update_context_menus),
desktop_canvas_view);
- view_action_group = nautilus_view_get_action_group (NAUTILUS_VIEW (desktop_canvas_view));
+ view_action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (desktop_canvas_view));
g_action_map_add_action_entries (G_ACTION_MAP (view_action_group),
desktop_view_entries,
G_N_ELEMENTS (desktop_view_entries),
- NAUTILUS_VIEW (desktop_canvas_view));
+ NAUTILUS_FILES_VIEW (desktop_canvas_view));
}
-NautilusView *
+NautilusFilesView *
nautilus_desktop_canvas_view_new (NautilusWindowSlot *slot)
{
return g_object_new (NAUTILUS_TYPE_DESKTOP_CANVAS_VIEW,
diff --git a/src/nautilus-desktop-canvas-view.h b/src/nautilus-desktop-canvas-view.h
index 8d0c4a470..0c9d0dd6d 100644
--- a/src/nautilus-desktop-canvas-view.h
+++ b/src/nautilus-desktop-canvas-view.h
@@ -50,6 +50,6 @@ typedef struct {
/* GObject support */
GType nautilus_desktop_canvas_view_get_type (void);
-NautilusView * nautilus_desktop_canvas_view_new (NautilusWindowSlot *slot);
+NautilusFilesView * nautilus_desktop_canvas_view_new (NautilusWindowSlot *slot);
#endif /* NAUTILUS_DESKTOP_CANVAS_VIEW_H */
diff --git a/src/nautilus-empty-view.c b/src/nautilus-empty-view.c
index 5ece1c4bf..f87351d3c 100644
--- a/src/nautilus-empty-view.c
+++ b/src/nautilus-empty-view.c
@@ -25,7 +25,7 @@
#include "nautilus-empty-view.h"
-#include "nautilus-view.h"
+#include "nautilus-files-view.h"
#include <string.h>
#include <libnautilus-private/nautilus-file-utilities.h>
@@ -35,15 +35,15 @@ struct NautilusEmptyViewDetails {
int number_of_files;
};
-static GList *nautilus_empty_view_get_selection (NautilusView *view);
-static GList *nautilus_empty_view_get_selection_for_file_transfer (NautilusView *view);
-static void nautilus_empty_view_scroll_to_file (NautilusView *view,
+static GList *nautilus_empty_view_get_selection (NautilusFilesView *view);
+static GList *nautilus_empty_view_get_selection_for_file_transfer (NautilusFilesView *view);
+static void nautilus_empty_view_scroll_to_file (NautilusFilesView *view,
const char *uri);
-G_DEFINE_TYPE (NautilusEmptyView, nautilus_empty_view, NAUTILUS_TYPE_VIEW)
+G_DEFINE_TYPE (NautilusEmptyView, nautilus_empty_view, NAUTILUS_TYPE_FILES_VIEW)
static void
-nautilus_empty_view_add_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
+nautilus_empty_view_add_file (NautilusFilesView *view, NautilusFile *file, NautilusDirectory *directory)
{
static GTimer *timer = NULL;
static gdouble cumu = 0, elaps;
@@ -66,122 +66,122 @@ nautilus_empty_view_add_file (NautilusView *view, NautilusFile *file, NautilusDi
static void
-nautilus_empty_view_begin_loading (NautilusView *view)
+nautilus_empty_view_begin_loading (NautilusFilesView *view)
{
}
static void
-nautilus_empty_view_clear (NautilusView *view)
+nautilus_empty_view_clear (NautilusFilesView *view)
{
}
static void
-nautilus_empty_view_file_changed (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
+nautilus_empty_view_file_changed (NautilusFilesView *view, NautilusFile *file, NautilusDirectory *directory)
{
}
static GList *
-nautilus_empty_view_get_selection (NautilusView *view)
+nautilus_empty_view_get_selection (NautilusFilesView *view)
{
return NULL;
}
static GList *
-nautilus_empty_view_get_selection_for_file_transfer (NautilusView *view)
+nautilus_empty_view_get_selection_for_file_transfer (NautilusFilesView *view)
{
return NULL;
}
static gboolean
-nautilus_empty_view_is_empty (NautilusView *view)
+nautilus_empty_view_is_empty (NautilusFilesView *view)
{
return NAUTILUS_EMPTY_VIEW (view)->details->number_of_files == 0;
}
static void
-nautilus_empty_view_end_file_changes (NautilusView *view)
+nautilus_empty_view_end_file_changes (NautilusFilesView *view)
{
}
static void
-nautilus_empty_view_remove_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
+nautilus_empty_view_remove_file (NautilusFilesView *view, NautilusFile *file, NautilusDirectory *directory)
{
NAUTILUS_EMPTY_VIEW (view)->details->number_of_files--;
g_assert (NAUTILUS_EMPTY_VIEW (view)->details->number_of_files >= 0);
}
static void
-nautilus_empty_view_set_selection (NautilusView *view, GList *selection)
+nautilus_empty_view_set_selection (NautilusFilesView *view, GList *selection)
{
- nautilus_view_notify_selection_changed (view);
+ nautilus_files_view_notify_selection_changed (view);
}
static void
-nautilus_empty_view_select_all (NautilusView *view)
+nautilus_empty_view_select_all (NautilusFilesView *view)
{
}
static void
-nautilus_empty_view_reveal_selection (NautilusView *view)
+nautilus_empty_view_reveal_selection (NautilusFilesView *view)
{
}
static void
-nautilus_empty_view_merge_menus (NautilusView *view)
+nautilus_empty_view_merge_menus (NautilusFilesView *view)
{
- NAUTILUS_VIEW_CLASS (nautilus_empty_view_parent_class)->merge_menus (view);
+ NAUTILUS_FILES_VIEW_CLASS (nautilus_empty_view_parent_class)->merge_menus (view);
}
static void
-nautilus_empty_view_update_menus (NautilusView *view)
+nautilus_empty_view_update_menus (NautilusFilesView *view)
{
- NAUTILUS_VIEW_CLASS (nautilus_empty_view_parent_class)->update_menus (view);
+ NAUTILUS_FILES_VIEW_CLASS (nautilus_empty_view_parent_class)->update_menus (view);
}
static void
-nautilus_empty_view_bump_zoom_level (NautilusView *view, int zoom_increment)
+nautilus_empty_view_bump_zoom_level (NautilusFilesView *view, int zoom_increment)
{
}
static NautilusCanvasZoomLevel
-nautilus_empty_view_get_zoom_level (NautilusView *view)
+nautilus_empty_view_get_zoom_level (NautilusFilesView *view)
{
return NAUTILUS_CANVAS_ZOOM_LEVEL_STANDARD;
}
static void
-nautilus_empty_view_zoom_to_level (NautilusView *view,
+nautilus_empty_view_zoom_to_level (NautilusFilesView *view,
NautilusCanvasZoomLevel zoom_level)
{
}
static void
-nautilus_empty_view_restore_default_zoom_level (NautilusView *view)
+nautilus_empty_view_restore_default_zoom_level (NautilusFilesView *view)
{
}
static gboolean
-nautilus_empty_view_can_zoom_in (NautilusView *view)
+nautilus_empty_view_can_zoom_in (NautilusFilesView *view)
{
return FALSE;
}
static gboolean
-nautilus_empty_view_can_zoom_out (NautilusView *view)
+nautilus_empty_view_can_zoom_out (NautilusFilesView *view)
{
return FALSE;
}
static void
-nautilus_empty_view_click_policy_changed (NautilusView *directory_view)
+nautilus_empty_view_click_policy_changed (NautilusFilesView *directory_view)
{
}
static int
-nautilus_empty_view_compare_files (NautilusView *view, NautilusFile *file1, NautilusFile *file2)
+nautilus_empty_view_compare_files (NautilusFilesView *view, NautilusFile *file1, NautilusFile *file2)
{
if (file1 < file2) {
return -1;
@@ -195,42 +195,42 @@ nautilus_empty_view_compare_files (NautilusView *view, NautilusFile *file1, Naut
}
static gboolean
-nautilus_empty_view_using_manual_layout (NautilusView *view)
+nautilus_empty_view_using_manual_layout (NautilusFilesView *view)
{
return FALSE;
}
static void
-nautilus_empty_view_end_loading (NautilusView *view,
+nautilus_empty_view_end_loading (NautilusFilesView *view,
gboolean all_files_seen)
{
}
static char *
-nautilus_empty_view_get_first_visible_file (NautilusView *view)
+nautilus_empty_view_get_first_visible_file (NautilusFilesView *view)
{
return NULL;
}
static void
-nautilus_empty_view_scroll_to_file (NautilusView *view,
+nautilus_empty_view_scroll_to_file (NautilusFilesView *view,
const char *uri)
{
}
static void
-nautilus_empty_view_sort_directories_first_changed (NautilusView *view)
+nautilus_empty_view_sort_directories_first_changed (NautilusFilesView *view)
{
}
static const char *
-nautilus_empty_view_get_id (NautilusView *view)
+nautilus_empty_view_get_id (NautilusFilesView *view)
{
return NAUTILUS_EMPTY_VIEW_ID;
}
static GIcon*
-nautilus_empty_view_get_icon (NautilusView *view)
+nautilus_empty_view_get_icon (NautilusFilesView *view)
{
return NULL;
}
@@ -238,41 +238,41 @@ nautilus_empty_view_get_icon (NautilusView *view)
static void
nautilus_empty_view_class_init (NautilusEmptyViewClass *class)
{
- NautilusViewClass *nautilus_view_class;
+ NautilusFilesViewClass *nautilus_files_view_class;
g_type_class_add_private (class, sizeof (NautilusEmptyViewDetails));
- nautilus_view_class = NAUTILUS_VIEW_CLASS (class);
-
- nautilus_view_class->add_file = nautilus_empty_view_add_file;
- nautilus_view_class->begin_loading = nautilus_empty_view_begin_loading;
- nautilus_view_class->bump_zoom_level = nautilus_empty_view_bump_zoom_level;
- nautilus_view_class->can_zoom_in = nautilus_empty_view_can_zoom_in;
- nautilus_view_class->can_zoom_out = nautilus_empty_view_can_zoom_out;
- nautilus_view_class->click_policy_changed = nautilus_empty_view_click_policy_changed;
- nautilus_view_class->clear = nautilus_empty_view_clear;
- nautilus_view_class->file_changed = nautilus_empty_view_file_changed;
- nautilus_view_class->get_selection = nautilus_empty_view_get_selection;
- nautilus_view_class->get_selection_for_file_transfer = nautilus_empty_view_get_selection_for_file_transfer;
- nautilus_view_class->is_empty = nautilus_empty_view_is_empty;
- nautilus_view_class->remove_file = nautilus_empty_view_remove_file;
- nautilus_view_class->merge_menus = nautilus_empty_view_merge_menus;
- nautilus_view_class->update_menus = nautilus_empty_view_update_menus;
- nautilus_view_class->restore_default_zoom_level = nautilus_empty_view_restore_default_zoom_level;
- nautilus_view_class->reveal_selection = nautilus_empty_view_reveal_selection;
- nautilus_view_class->select_all = nautilus_empty_view_select_all;
- nautilus_view_class->set_selection = nautilus_empty_view_set_selection;
- nautilus_view_class->compare_files = nautilus_empty_view_compare_files;
- nautilus_view_class->sort_directories_first_changed = nautilus_empty_view_sort_directories_first_changed;
- nautilus_view_class->get_zoom_level = nautilus_empty_view_get_zoom_level;
- nautilus_view_class->zoom_to_level = nautilus_empty_view_zoom_to_level;
- nautilus_view_class->end_file_changes = nautilus_empty_view_end_file_changes;
- nautilus_view_class->using_manual_layout = nautilus_empty_view_using_manual_layout;
- nautilus_view_class->end_loading = nautilus_empty_view_end_loading;
- nautilus_view_class->get_view_id = nautilus_empty_view_get_id;
- nautilus_view_class->get_first_visible_file = nautilus_empty_view_get_first_visible_file;
- nautilus_view_class->scroll_to_file = nautilus_empty_view_scroll_to_file;
- nautilus_view_class->get_icon = nautilus_empty_view_get_icon;
+ nautilus_files_view_class = NAUTILUS_FILES_VIEW_CLASS (class);
+
+ nautilus_files_view_class->add_file = nautilus_empty_view_add_file;
+ nautilus_files_view_class->begin_loading = nautilus_empty_view_begin_loading;
+ nautilus_files_view_class->bump_zoom_level = nautilus_empty_view_bump_zoom_level;
+ nautilus_files_view_class->can_zoom_in = nautilus_empty_view_can_zoom_in;
+ nautilus_files_view_class->can_zoom_out = nautilus_empty_view_can_zoom_out;
+ nautilus_files_view_class->click_policy_changed = nautilus_empty_view_click_policy_changed;
+ nautilus_files_view_class->clear = nautilus_empty_view_clear;
+ nautilus_files_view_class->file_changed = nautilus_empty_view_file_changed;
+ nautilus_files_view_class->get_selection = nautilus_empty_view_get_selection;
+ nautilus_files_view_class->get_selection_for_file_transfer = nautilus_empty_view_get_selection_for_file_transfer;
+ nautilus_files_view_class->is_empty = nautilus_empty_view_is_empty;
+ nautilus_files_view_class->remove_file = nautilus_empty_view_remove_file;
+ nautilus_files_view_class->merge_menus = nautilus_empty_view_merge_menus;
+ nautilus_files_view_class->update_menus = nautilus_empty_view_update_menus;
+ nautilus_files_view_class->restore_default_zoom_level = nautilus_empty_view_restore_default_zoom_level;
+ nautilus_files_view_class->reveal_selection = nautilus_empty_view_reveal_selection;
+ nautilus_files_view_class->select_all = nautilus_empty_view_select_all;
+ nautilus_files_view_class->set_selection = nautilus_empty_view_set_selection;
+ nautilus_files_view_class->compare_files = nautilus_empty_view_compare_files;
+ nautilus_files_view_class->sort_directories_first_changed = nautilus_empty_view_sort_directories_first_changed;
+ nautilus_files_view_class->get_zoom_level = nautilus_empty_view_get_zoom_level;
+ nautilus_files_view_class->zoom_to_level = nautilus_empty_view_zoom_to_level;
+ nautilus_files_view_class->end_file_changes = nautilus_empty_view_end_file_changes;
+ nautilus_files_view_class->using_manual_layout = nautilus_empty_view_using_manual_layout;
+ nautilus_files_view_class->end_loading = nautilus_empty_view_end_loading;
+ nautilus_files_view_class->get_view_id = nautilus_empty_view_get_id;
+ nautilus_files_view_class->get_first_visible_file = nautilus_empty_view_get_first_visible_file;
+ nautilus_files_view_class->scroll_to_file = nautilus_empty_view_scroll_to_file;
+ nautilus_files_view_class->get_icon = nautilus_empty_view_get_icon;
}
static void
@@ -282,7 +282,7 @@ nautilus_empty_view_init (NautilusEmptyView *empty_view)
NautilusEmptyViewDetails);
}
-NautilusView *
+NautilusFilesView *
nautilus_empty_view_new (NautilusWindowSlot *slot)
{
return g_object_new (NAUTILUS_TYPE_EMPTY_VIEW,
diff --git a/src/nautilus-empty-view.h b/src/nautilus-empty-view.h
index 56ff4e99d..a8c573bb5 100644
--- a/src/nautilus-empty-view.h
+++ b/src/nautilus-empty-view.h
@@ -24,7 +24,7 @@
#ifndef NAUTILUS_EMPTY_VIEW_H
#define NAUTILUS_EMPTY_VIEW_H
-#include "nautilus-view.h"
+#include "nautilus-files-view.h"
#define NAUTILUS_TYPE_EMPTY_VIEW nautilus_empty_view_get_type()
#define NAUTILUS_EMPTY_VIEW(obj) \
@@ -41,15 +41,15 @@
typedef struct NautilusEmptyViewDetails NautilusEmptyViewDetails;
typedef struct {
- NautilusView parent_instance;
+ NautilusFilesView parent_instance;
NautilusEmptyViewDetails *details;
} NautilusEmptyView;
typedef struct {
- NautilusViewClass parent_class;
+ NautilusFilesViewClass parent_class;
} NautilusEmptyViewClass;
GType nautilus_empty_view_get_type (void);
-NautilusView * nautilus_empty_view_new (NautilusWindowSlot *slot);
+NautilusFilesView * nautilus_empty_view_new (NautilusWindowSlot *slot);
#endif /* NAUTILUS_EMPTY_VIEW_H */
diff --git a/src/nautilus-view-context-menus.xml b/src/nautilus-files-view-context-menus.xml
index df91fb87a..df91fb87a 100644
--- a/src/nautilus-view-context-menus.xml
+++ b/src/nautilus-files-view-context-menus.xml
diff --git a/src/nautilus-files-view-dnd.c b/src/nautilus-files-view-dnd.c
new file mode 100644
index 000000000..90c5b469c
--- /dev/null
+++ b/src/nautilus-files-view-dnd.c
@@ -0,0 +1,547 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/*
+ * nautilus-view-dnd.c: DnD helpers for NautilusFilesView
+ *
+ * Copyright (C) 1999, 2000 Free Software Foundaton
+ * Copyright (C) 2000, 2001 Eazel, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ettore Perazzoli
+ * Darin Adler <darin@bentspoon.com>
+ * John Sullivan <sullivan@eazel.com>
+ * Pavel Cisler <pavel@eazel.com>
+ */
+
+#include <config.h>
+
+#include "nautilus-files-view-dnd.h"
+
+#include "nautilus-files-view.h"
+
+#include <eel/eel-stock-dialogs.h>
+#include <eel/eel-string.h>
+
+#include <glib/gi18n.h>
+
+#include <libnautilus-private/nautilus-clipboard.h>
+#include <libnautilus-private/nautilus-dnd.h>
+
+#define GET_ANCESTOR(obj) \
+ GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (obj), GTK_TYPE_WINDOW))
+
+static inline void
+view_widget_to_file_operation_position (NautilusFilesView *view,
+ GdkPoint *position)
+{
+ NautilusFilesViewClass *class = NAUTILUS_FILES_VIEW_GET_CLASS (view);
+
+ if (class->widget_to_file_operation_position != NULL) {
+ class->widget_to_file_operation_position (view, position);
+ }
+}
+
+static void
+view_widget_to_file_operation_position_xy (NautilusFilesView *view,
+ int *x,
+ int *y)
+{
+ GdkPoint position;
+
+ position.x = *x;
+ position.y = *y;
+ view_widget_to_file_operation_position (view, &position);
+ *x = position.x;
+ *y = position.y;
+}
+
+typedef struct {
+ NautilusFilesView *view;
+ char *link_name;
+ char *target_uri;
+ char *url;
+ GdkPoint point;
+} NetscapeUrlDropLink;
+
+static void
+revert_slashes (char *string)
+{
+ while (*string != 0) {
+ if (*string == '/') {
+ *string = '\\';
+ }
+ string++;
+ }
+}
+
+static void
+handle_netscape_url_drop_link_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ NetscapeUrlDropLink *data = user_data;
+ char *link_name = data->link_name;
+ char *link_display_name;
+ gint screen_num;
+ GFileInfo *info;
+ char *icon_name = NULL;
+ GdkScreen *screen;
+
+ info = g_file_query_info_finish (G_FILE (source_object),
+ res, NULL);
+
+ if (info != NULL) {
+ GIcon *icon;
+ const char * const *names;
+
+ icon = g_file_info_get_icon (info);
+
+ if (G_IS_THEMED_ICON (icon)) {
+ names = g_themed_icon_get_names (G_THEMED_ICON (icon));
+ icon_name = g_strdup (names[0]);
+ }
+
+ g_object_unref (info);
+ }
+
+ if (icon_name == NULL) {
+ icon_name = g_strdup ("text-html");
+ }
+
+ link_display_name = g_strdup_printf (_("Link to %s"), link_name);
+
+ /* The filename can't contain slashes, strip em.
+ (the basename of http://foo/ is http://foo/) */
+ revert_slashes (link_name);
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (data->view));
+ screen_num = gdk_screen_get_number (screen);
+
+ nautilus_link_local_create (data->target_uri,
+ link_name,
+ link_display_name,
+ icon_name,
+ data->url,
+ &data->point,
+ screen_num,
+ TRUE);
+
+ g_free (link_display_name);
+ g_free (icon_name);
+
+ g_free (data->url);
+ g_free (data->link_name);
+ g_free (data->target_uri);
+
+ g_object_unref (data->view);
+ g_slice_free (NetscapeUrlDropLink, data);
+}
+
+void
+nautilus_files_view_handle_netscape_url_drop (NautilusFilesView *view,
+ const char *encoded_url,
+ const char *target_uri,
+ GdkDragAction action,
+ int x,
+ int y)
+{
+ char *url, *title;
+ char *link_name;
+ GArray *points;
+ char **bits;
+ GList *uri_list = NULL;
+ GFile *f;
+
+ f = g_file_new_for_uri (target_uri);
+
+ if (!g_file_is_native (f)) {
+ eel_show_warning_dialog (_("Drag and drop is not supported."),
+ _("Drag and drop is only supported on local file systems."),
+ GET_ANCESTOR (view));
+ g_object_unref (f);
+ return;
+ }
+
+ g_object_unref (f);
+
+ /* _NETSCAPE_URL_ works like this: $URL\n$TITLE */
+ bits = g_strsplit (encoded_url, "\n", 0);
+ switch (g_strv_length (bits)) {
+ case 0:
+ g_strfreev (bits);
+ return;
+ case 1:
+ url = bits[0];
+ title = NULL;
+ break;
+ default:
+ url = bits[0];
+ title = bits[1];
+ }
+
+ f = g_file_new_for_uri (url);
+
+ view_widget_to_file_operation_position_xy (view, &x, &y);
+
+ /* We don't support GDK_ACTION_ASK or GDK_ACTION_PRIVATE
+ * and we don't support combinations either. */
+ if ((action != GDK_ACTION_DEFAULT) &&
+ (action != GDK_ACTION_COPY) &&
+ (action != GDK_ACTION_MOVE) &&
+ (action != GDK_ACTION_LINK)) {
+ eel_show_warning_dialog (_("Drag and drop is not supported."),
+ _("An invalid drag type was used."),
+ GET_ANCESTOR (view));
+ return;
+ }
+
+ if (action == GDK_ACTION_LINK) {
+ if (g_strcmp0 (title, NULL) == 0) {
+ link_name = g_file_get_basename (f);
+ } else {
+ link_name = g_strdup (title);
+ }
+
+ if (g_strcmp0 (link_name, NULL) != 0) {
+ NetscapeUrlDropLink *data;
+
+ data = g_slice_new0 (NetscapeUrlDropLink);
+ data->link_name = link_name;
+ data->point.x = x;
+ data->point.y = y;
+ data->view = g_object_ref (view);
+ data->target_uri = g_strdup (target_uri);
+ data->url = g_strdup (url);
+
+ g_file_query_info_async (f,
+ G_FILE_ATTRIBUTE_STANDARD_ICON,
+ 0, 0, NULL,
+ handle_netscape_url_drop_link_cb,
+ data);
+ }
+ } else {
+ GdkPoint tmp_point = { 0, 0 };
+
+ /* pass in a 1-item array of icon positions, relative to x, y */
+ points = g_array_new (FALSE, TRUE, sizeof (GdkPoint));
+ g_array_append_val (points, tmp_point);
+
+ uri_list = g_list_append (uri_list, url);
+
+ nautilus_files_view_move_copy_items (view, uri_list, points,
+ target_uri,
+ action, x, y);
+
+ g_list_free (uri_list);
+ g_array_free (points, TRUE);
+ }
+
+ g_object_unref (f);
+ g_strfreev (bits);
+}
+
+void
+nautilus_files_view_handle_uri_list_drop (NautilusFilesView *view,
+ const char *item_uris,
+ const char *target_uri,
+ GdkDragAction action,
+ int x,
+ int y)
+{
+ gchar **uri_list;
+ GList *real_uri_list = NULL;
+ char *container_uri;
+ int n_uris, i;
+ GArray *points;
+
+ if (item_uris == NULL) {
+ return;
+ }
+
+ container_uri = NULL;
+ if (target_uri == NULL) {
+ container_uri = nautilus_files_view_get_backing_uri (view);
+ g_assert (container_uri != NULL);
+ }
+
+ if (action == GDK_ACTION_ASK) {
+ action = nautilus_drag_drop_action_ask
+ (GTK_WIDGET (view),
+ GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
+ if (action == 0) {
+ g_free (container_uri);
+ return;
+ }
+ }
+
+ /* We don't support GDK_ACTION_ASK or GDK_ACTION_PRIVATE
+ * and we don't support combinations either. */
+ if ((action != GDK_ACTION_DEFAULT) &&
+ (action != GDK_ACTION_COPY) &&
+ (action != GDK_ACTION_MOVE) &&
+ (action != GDK_ACTION_LINK)) {
+ eel_show_warning_dialog (_("Drag and drop is not supported."),
+ _("An invalid drag type was used."),
+ GET_ANCESTOR (view));
+ g_free (container_uri);
+ return;
+ }
+
+ n_uris = 0;
+ uri_list = g_uri_list_extract_uris (item_uris);
+ for (i = 0; uri_list[i] != NULL; i++) {
+ real_uri_list = g_list_append (real_uri_list, uri_list[i]);
+ n_uris++;
+ }
+ g_free (uri_list);
+
+ /* do nothing if no real uris are left */
+ if (n_uris == 0) {
+ g_free (container_uri);
+ return;
+ }
+
+ if (n_uris == 1) {
+ GdkPoint tmp_point = { 0, 0 };
+
+ /* pass in a 1-item array of icon positions, relative to x, y */
+ points = g_array_new (FALSE, TRUE, sizeof (GdkPoint));
+ g_array_append_val (points, tmp_point);
+ } else {
+ points = NULL;
+ }
+
+ view_widget_to_file_operation_position_xy (view, &x, &y);
+
+ nautilus_files_view_move_copy_items (view, real_uri_list, points,
+ target_uri != NULL ? target_uri : container_uri,
+ action, x, y);
+
+ g_list_free_full (real_uri_list, g_free);
+
+ if (points != NULL)
+ g_array_free (points, TRUE);
+
+ g_free (container_uri);
+}
+
+#define MAX_LEN_FILENAME 128
+#define MIN_LEN_FILENAME 10
+
+static char *
+get_drop_filename (const char *text)
+{
+ char *filename;
+ char trimmed[MAX_LEN_FILENAME];
+ int i;
+ int last_word = -1;
+ int last_sentence = -1;
+ int last_nonspace = -1;
+ int num_attrs;
+ PangoLogAttr *attrs;
+ gchar *current_char;
+
+ num_attrs = MIN (g_utf8_strlen (text, -1), MAX_LEN_FILENAME) + 1;
+ attrs = g_new (PangoLogAttr, num_attrs);
+ g_utf8_strncpy (trimmed, text, num_attrs - 1);
+ pango_get_log_attrs (trimmed, -1, -1, pango_language_get_default (), attrs, num_attrs);
+
+ /* since the end of the text will always match a word boundary don't include it */
+ for (i = 0; (i < num_attrs - 1); i++) {
+ if (!attrs[i].is_white)
+ last_nonspace = i;
+ if (attrs[i].is_sentence_end)
+ last_sentence = last_nonspace;
+ if (attrs[i].is_word_boundary)
+ last_word = last_nonspace;
+ }
+ g_free (attrs);
+
+ if (last_sentence > 0)
+ i = last_sentence;
+ else
+ i = last_word;
+
+ if (i > MIN_LEN_FILENAME) {
+ char basename[MAX_LEN_FILENAME];
+ g_utf8_strncpy (basename, trimmed, i);
+ filename = g_strdup_printf ("%s.txt", basename);
+ } else {
+ /* Translator: This is the filename used for when you dnd text to a directory */
+ filename = g_strdup (_("Dropped Text.txt"));
+ }
+
+ /* Remove any invalid characters */
+ for (current_char = filename;
+ *current_char;
+ current_char = g_utf8_next_char (current_char)) {
+ if ( G_IS_DIR_SEPARATOR ( g_utf8_get_char (current_char))) {
+ *current_char = '-';
+ }
+ }
+
+ return filename;
+}
+
+void
+nautilus_files_view_handle_text_drop (NautilusFilesView *view,
+ const char *text,
+ const char *target_uri,
+ GdkDragAction action,
+ int x,
+ int y)
+{
+ int length;
+ char *container_uri;
+ GdkPoint pos;
+ char *filename;
+
+ if (text == NULL) {
+ return;
+ }
+
+ g_return_if_fail (action == GDK_ACTION_COPY);
+
+ container_uri = NULL;
+ if (target_uri == NULL) {
+ container_uri = nautilus_files_view_get_backing_uri (view);
+ g_assert (container_uri != NULL);
+ }
+
+ length = strlen (text);
+
+ pos.x = x;
+ pos.y = y;
+ view_widget_to_file_operation_position (view, &pos);
+
+ /* try to get text to use as a filename */
+ filename = get_drop_filename (text);
+
+ nautilus_files_view_new_file_with_initial_contents (view,
+ target_uri != NULL ? target_uri : container_uri,
+ filename,
+ text,
+ length,
+ &pos);
+ g_free (filename);
+ g_free (container_uri);
+}
+
+void
+nautilus_files_view_handle_raw_drop (NautilusFilesView *view,
+ const char *raw_data,
+ int length,
+ const char *target_uri,
+ const char *direct_save_uri,
+ GdkDragAction action,
+ int x,
+ int y)
+{
+ char *container_uri, *filename;
+ GFile *direct_save_full;
+ GdkPoint pos;
+
+ if (raw_data == NULL) {
+ return;
+ }
+
+ g_return_if_fail (action == GDK_ACTION_COPY);
+
+ container_uri = NULL;
+ if (target_uri == NULL) {
+ container_uri = nautilus_files_view_get_backing_uri (view);
+ g_assert (container_uri != NULL);
+ }
+
+ pos.x = x;
+ pos.y = y;
+ view_widget_to_file_operation_position (view, &pos);
+
+ filename = NULL;
+ if (direct_save_uri != NULL) {
+ direct_save_full = g_file_new_for_uri (direct_save_uri);
+ filename = g_file_get_basename (direct_save_full);
+ }
+ if (filename == NULL) {
+ /* Translator: This is the filename used for when you dnd raw
+ * data to a directory, if the source didn't supply a name.
+ */
+ filename = g_strdup (_("dropped data"));
+ }
+
+ nautilus_files_view_new_file_with_initial_contents (
+ view, target_uri != NULL ? target_uri : container_uri,
+ filename, raw_data, length, &pos);
+
+ g_free (container_uri);
+ g_free (filename);
+}
+
+void
+nautilus_files_view_drop_proxy_received_uris (NautilusFilesView *view,
+ const GList *source_uri_list,
+ const char *target_uri,
+ GdkDragAction action)
+{
+ char *container_uri;
+
+ container_uri = NULL;
+ if (target_uri == NULL) {
+ container_uri = nautilus_files_view_get_backing_uri (view);
+ g_assert (container_uri != NULL);
+ }
+
+ if (action == GDK_ACTION_ASK) {
+ action = nautilus_drag_drop_action_ask
+ (GTK_WIDGET (view),
+ GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
+ if (action == 0) {
+ return;
+ }
+ }
+
+ nautilus_clipboard_clear_if_colliding_uris (GTK_WIDGET (view),
+ source_uri_list,
+ nautilus_files_view_get_copied_files_atom (view));
+
+ nautilus_files_view_move_copy_items (view, source_uri_list, NULL,
+ target_uri != NULL ? target_uri : container_uri,
+ action, 0, 0);
+
+ g_free (container_uri);
+}
+
+void
+nautilus_files_view_handle_hover (NautilusFilesView *view,
+ const char *target_uri)
+{
+ NautilusWindowSlot *slot;
+ GFile *location;
+ GFile *current_location;
+ NautilusFile *target_file;
+ gboolean target_is_dir;
+
+ slot = nautilus_files_view_get_nautilus_window_slot (view);
+
+ location = g_file_new_for_uri (target_uri);
+ target_file = nautilus_file_get_existing (location);
+ target_is_dir = nautilus_file_get_file_type (target_file) == G_FILE_TYPE_DIRECTORY;
+ current_location = nautilus_window_slot_get_location (slot);
+ if (target_is_dir && ! (current_location != NULL && g_file_equal(location, current_location))) {
+ nautilus_window_slot_open_location (slot, location, 0);
+ }
+ g_object_unref (location);
+ nautilus_file_unref (target_file);
+}
diff --git a/src/nautilus-files-view-dnd.h b/src/nautilus-files-view-dnd.h
new file mode 100644
index 000000000..1f123582b
--- /dev/null
+++ b/src/nautilus-files-view-dnd.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/*
+ * nautilus-view-dnd.h: DnD helpers for NautilusFilesView
+ *
+ * Copyright (C) 1999, 2000 Free Software Foundaton
+ * Copyright (C) 2000, 2001 Eazel, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ettore Perazzoli
+ * Darin Adler <darin@bentspoon.com>
+ * John Sullivan <sullivan@eazel.com>
+ * Pavel Cisler <pavel@eazel.com>
+ */
+
+#ifndef __NAUTILUS_FILES_VIEW_DND_H__
+#define __NAUTILUS_FILES_VIEW_DND_H__
+
+#include "nautilus-files-view.h"
+
+void nautilus_files_view_handle_netscape_url_drop (NautilusFilesView *view,
+ const char *encoded_url,
+ const char *target_uri,
+ GdkDragAction action,
+ int x,
+ int y);
+void nautilus_files_view_handle_uri_list_drop (NautilusFilesView *view,
+ const char *item_uris,
+ const char *target_uri,
+ GdkDragAction action,
+ int x,
+ int y);
+void nautilus_files_view_handle_text_drop (NautilusFilesView *view,
+ const char *text,
+ const char *target_uri,
+ GdkDragAction action,
+ int x,
+ int y);
+void nautilus_files_view_handle_raw_drop (NautilusFilesView *view,
+ const char *raw_data,
+ int length,
+ const char *target_uri,
+ const char *direct_save_uri,
+ GdkDragAction action,
+ int x,
+ int y);
+void nautilus_files_view_handle_hover (NautilusFilesView *view,
+ const char *target_uri);
+
+void nautilus_files_view_drop_proxy_received_uris (NautilusFilesView *view,
+ const GList *uris,
+ const char *target_location,
+ GdkDragAction action);
+
+
+#endif /* __NAUTILUS_FILES_VIEW_DND_H__ */
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
new file mode 100644
index 000000000..a6c5c7510
--- /dev/null
+++ b/src/nautilus-files-view.c
@@ -0,0 +1,8147 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* nautilus-files-view.c
+ *
+ * Copyright (C) 1999, 2000 Free Software Foundation
+ * Copyright (C) 2000, 2001 Eazel, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ettore Perazzoli,
+ * John Sullivan <sullivan@eazel.com>,
+ * Darin Adler <darin@bentspoon.com>,
+ * Pavel Cisler <pavel@eazel.com>,
+ * David Emory Watson <dwatson@cs.ucr.edu>
+ */
+
+#include <config.h>
+
+#include "nautilus-files-view.h"
+
+#include "nautilus-application.h"
+#include "nautilus-desktop-canvas-view.h"
+#include "nautilus-error-reporting.h"
+#include "nautilus-floating-bar.h"
+#include "nautilus-list-view.h"
+#include "nautilus-mime-actions.h"
+#include "nautilus-previewer.h"
+#include "nautilus-properties-window.h"
+#include "nautilus-window.h"
+#include "nautilus-toolbar.h"
+
+#if ENABLE_EMPTY_VIEW
+#include "nautilus-empty-view.h"
+#endif
+
+#ifdef HAVE_X11_XF86KEYSYM_H
+#include <X11/XF86keysym.h>
+#endif
+
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+#include <math.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <eel/eel-glib-extensions.h>
+#include <eel/eel-gnome-extensions.h>
+#include <eel/eel-gtk-extensions.h>
+#include <eel/eel-stock-dialogs.h>
+#include <eel/eel-string.h>
+#include <eel/eel-vfs-extensions.h>
+
+#include <libnautilus-extension/nautilus-menu-provider.h>
+#include <libnautilus-private/nautilus-clipboard.h>
+#include <libnautilus-private/nautilus-clipboard-monitor.h>
+#include <libnautilus-private/nautilus-desktop-icon-file.h>
+#include <libnautilus-private/nautilus-desktop-directory.h>
+#include <libnautilus-private/nautilus-search-directory.h>
+#include <libnautilus-private/nautilus-directory.h>
+#include <libnautilus-private/nautilus-dnd.h>
+#include <libnautilus-private/nautilus-file-attributes.h>
+#include <libnautilus-private/nautilus-file-changes-queue.h>
+#include <libnautilus-private/nautilus-file-dnd.h>
+#include <libnautilus-private/nautilus-file-operations.h>
+#include <libnautilus-private/nautilus-file-utilities.h>
+#include <libnautilus-private/nautilus-file-private.h>
+#include <libnautilus-private/nautilus-global-preferences.h>
+#include <libnautilus-private/nautilus-link.h>
+#include <libnautilus-private/nautilus-metadata.h>
+#include <libnautilus-private/nautilus-recent.h>
+#include <libnautilus-private/nautilus-module.h>
+#include <libnautilus-private/nautilus-profile.h>
+#include <libnautilus-private/nautilus-program-choosing.h>
+#include <libnautilus-private/nautilus-trash-monitor.h>
+#include <libnautilus-private/nautilus-ui-utilities.h>
+#include <libnautilus-private/nautilus-signaller.h>
+#include <libnautilus-private/nautilus-icon-names.h>
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <gdesktop-enums.h>
+
+#define DEBUG_FLAG NAUTILUS_DEBUG_DIRECTORY_VIEW
+#include <libnautilus-private/nautilus-debug.h>
+
+/* Minimum starting update inverval */
+#define UPDATE_INTERVAL_MIN 100
+/* Maximum update interval */
+#define UPDATE_INTERVAL_MAX 2000
+/* Amount of miliseconds the update interval is increased */
+#define UPDATE_INTERVAL_INC 250
+/* Interval at which the update interval is increased */
+#define UPDATE_INTERVAL_TIMEOUT_INTERVAL 250
+/* Milliseconds that have to pass without a change to reset the update interval */
+#define UPDATE_INTERVAL_RESET 1000
+
+#define SILENT_WINDOW_OPEN_LIMIT 5
+
+#define DUPLICATE_HORIZONTAL_ICON_OFFSET 70
+#define DUPLICATE_VERTICAL_ICON_OFFSET 30
+
+#define MAX_QUEUED_UPDATES 500
+
+#define MAX_MENU_LEVELS 5
+#define TEMPLATE_LIMIT 30
+
+/* Delay to show the duplicated label when creating a folder */
+#define FILE_NAME_DUPLICATED_LABEL_TIMEOUT 500
+
+/* Delay to show the Loading... floating bar */
+#define FLOATING_BAR_LOADING_DELAY 500 /* ms */
+
+enum {
+ ADD_FILE,
+ BEGIN_FILE_CHANGES,
+ BEGIN_LOADING,
+ CLEAR,
+ END_FILE_CHANGES,
+ END_LOADING,
+ FILE_CHANGED,
+ MOVE_COPY_ITEMS,
+ REMOVE_FILE,
+ SELECTION_CHANGED,
+ TRASH,
+ DELETE,
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_WINDOW_SLOT = 1,
+ PROP_SUPPORTS_ZOOMING,
+ PROP_ICON,
+ PROP_VIEW_WIDGET,
+ NUM_PROPERTIES
+};
+
+static guint signals[LAST_SIGNAL];
+static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
+
+static GdkAtom copied_files_atom;
+
+static char *scripts_directory_uri = NULL;
+static int scripts_directory_uri_length;
+
+struct NautilusFilesViewDetails
+{
+ NautilusWindowSlot *slot;
+ NautilusDirectory *model;
+ NautilusFile *directory_as_file;
+ guint dir_merge_id;
+
+ gint duplicated_label_timeout_id;
+ GtkWidget *rename_file_popover;
+
+ gboolean supports_zooming;
+
+ GList *scripts_directory_list;
+ GList *templates_directory_list;
+
+ guint display_selection_idle_id;
+ guint update_context_menus_timeout_id;
+ guint update_status_idle_id;
+ guint reveal_selection_idle_id;
+
+ guint display_pending_source_id;
+ guint changes_timeout_id;
+
+ guint update_interval;
+ guint64 last_queued;
+
+ guint files_added_handler_id;
+ guint files_changed_handler_id;
+ guint load_error_handler_id;
+ guint done_loading_handler_id;
+ guint file_changed_handler_id;
+
+ GList *new_added_files;
+ GList *new_changed_files;
+
+ GHashTable *non_ready_files;
+
+ GList *old_added_files;
+ GList *old_changed_files;
+
+ GList *pending_selection;
+
+ /* whether we are in the active slot */
+ gboolean active;
+
+ /* loading indicates whether this view has begun loading a directory.
+ * This flag should need not be set inside subclasses. NautilusFilesView automatically
+ * sets 'loading' to TRUE before it begins loading a directory's contents and to FALSE
+ * after it finishes loading the directory and its view.
+ */
+ gboolean loading;
+ gboolean templates_present;
+ gboolean scripts_present;
+
+ gboolean sort_directories_first;
+
+ gboolean show_foreign_files;
+ gboolean show_hidden_files;
+ gboolean ignore_hidden_file_preferences;
+
+ gboolean batching_selection_level;
+ gboolean selection_changed_while_batched;
+
+ gboolean selection_was_removed;
+
+ gboolean metadata_for_directory_as_file_pending;
+ gboolean metadata_for_files_in_directory_pending;
+
+ GList *subdirectory_list;
+
+ GdkPoint context_menu_position;
+
+ GMenu *selection_menu;
+ GMenu *background_menu;
+
+ GActionGroup *view_action_group;
+
+ GtkWidget *scrolled_window;
+
+ /* Empty states */
+ GtkWidget *folder_is_empty_widget;
+ GtkWidget *no_search_results_widget;
+
+ /* Floating bar */
+ guint floating_bar_set_status_timeout_id;
+ guint floating_bar_loading_timeout_id;
+ GtkWidget *floating_bar;
+
+ /* View menu */
+ GtkWidget *view_menu_widget;
+ GtkWidget *view_icon;
+ GtkWidget *sort_menu;
+ GtkWidget *sort_trash_time;
+ GtkWidget *sort_search_relevance;
+ GtkWidget *visible_columns;
+ GtkWidget *stop;
+ GtkWidget *reload;
+ GtkAdjustment *zoom_adjustment;
+ GtkWidget *zoom_level_scale;
+
+ gulong stop_signal_handler;
+ gulong reload_signal_handler;
+};
+
+typedef struct {
+ NautilusFile *file;
+ NautilusDirectory *directory;
+} FileAndDirectory;
+
+/* forward declarations */
+
+static gboolean display_selection_info_idle_callback (gpointer data);
+static void trash_or_delete_files (GtkWindow *parent_window,
+ const GList *files,
+ NautilusFilesView *view);
+static void load_directory (NautilusFilesView *view,
+ NautilusDirectory *directory);
+static void clipboard_changed_callback (NautilusClipboardMonitor *monitor,
+ NautilusFilesView *view);
+static void open_one_in_new_window (gpointer data,
+ gpointer callback_data);
+static void schedule_update_context_menus (NautilusFilesView *view);
+static void remove_update_context_menus_timeout_callback (NautilusFilesView *view);
+static void schedule_update_status (NautilusFilesView *view);
+static void remove_update_status_idle_callback (NautilusFilesView *view);
+static void reset_update_interval (NautilusFilesView *view);
+static void schedule_idle_display_of_pending_files (NautilusFilesView *view);
+static void unschedule_display_of_pending_files (NautilusFilesView *view);
+static void disconnect_model_handlers (NautilusFilesView *view);
+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,
+ GList *files,
+ gpointer callback_data);
+static void nautilus_files_view_trash_state_changed_callback (NautilusTrashMonitor *trash,
+ gboolean state,
+ gpointer callback_data);
+static void nautilus_files_view_select_file (NautilusFilesView *view,
+ NautilusFile *file);
+
+static void update_templates_directory (NautilusFilesView *view);
+
+static void check_empty_states (NautilusFilesView *view);
+
+G_DEFINE_TYPE (NautilusFilesView, nautilus_files_view, GTK_TYPE_OVERLAY);
+
+static const struct {
+ unsigned int keyval;
+ const char *action;
+} extra_view_keybindings [] = {
+#ifdef HAVE_X11_XF86KEYSYM_H
+ /* View actions */
+ { XF86XK_ZoomIn, "zoom-in" },
+ { XF86XK_ZoomOut, "zoom-out" },
+
+#endif
+};
+
+static void
+check_empty_states (NautilusFilesView *view)
+{
+ GList *files;
+ GList *filtered;
+ gboolean show_hidden_files;
+
+ gtk_widget_hide (view->details->no_search_results_widget);
+ gtk_widget_hide (view->details->folder_is_empty_widget);
+ if (!view->details->loading && view->details->model) {
+ files = nautilus_directory_get_file_list (view->details->model);
+ show_hidden_files = g_settings_get_boolean (gtk_filechooser_preferences,
+ NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES);
+ filtered = nautilus_file_list_filter_hidden (files, show_hidden_files);
+ if (g_list_length (filtered) == 0) {
+ if (nautilus_files_view_is_search (view)) {
+ gtk_widget_show (view->details->no_search_results_widget);
+ } else {
+ gtk_widget_show (view->details->folder_is_empty_widget);
+ }
+ }
+ nautilus_file_list_unref (filtered);
+ nautilus_file_list_unref (files);
+ }
+}
+
+/*
+ * Floating Bar code
+ */
+static void
+remove_loading_floating_bar (NautilusFilesView *view)
+{
+ if (view->details->floating_bar_loading_timeout_id != 0) {
+ g_source_remove (view->details->floating_bar_loading_timeout_id);
+ view->details->floating_bar_loading_timeout_id = 0;
+ }
+
+ gtk_widget_hide (view->details->floating_bar);
+ nautilus_floating_bar_cleanup_actions (NAUTILUS_FLOATING_BAR (view->details->floating_bar));
+}
+
+static void
+real_setup_loading_floating_bar (NautilusFilesView *view)
+{
+ gboolean disable_chrome;
+
+ g_object_get (nautilus_files_view_get_window (view),
+ "disable-chrome", &disable_chrome,
+ NULL);
+
+ if (disable_chrome) {
+ gtk_widget_hide (view->details->floating_bar);
+ return;
+ }
+
+ nautilus_floating_bar_cleanup_actions (NAUTILUS_FLOATING_BAR (view->details->floating_bar));
+ nautilus_floating_bar_set_primary_label (NAUTILUS_FLOATING_BAR (view->details->floating_bar),
+ nautilus_files_view_is_search (view) ? _("Searching…") : _("Loading…"));
+ nautilus_floating_bar_set_details_label (NAUTILUS_FLOATING_BAR (view->details->floating_bar), NULL);
+ nautilus_floating_bar_set_show_spinner (NAUTILUS_FLOATING_BAR (view->details->floating_bar), view->details->loading);
+ nautilus_floating_bar_add_action (NAUTILUS_FLOATING_BAR (view->details->floating_bar),
+ "process-stop-symbolic",
+ NAUTILUS_FLOATING_BAR_ACTION_ID_STOP);
+
+ gtk_widget_set_halign (view->details->floating_bar, GTK_ALIGN_END);
+ gtk_widget_show (view->details->floating_bar);
+}
+
+static gboolean
+setup_loading_floating_bar_timeout_cb (gpointer user_data)
+{
+ NautilusFilesView *view = user_data;
+
+ view->details->floating_bar_loading_timeout_id = 0;
+ real_setup_loading_floating_bar (view);
+
+ return FALSE;
+}
+
+static void
+setup_loading_floating_bar (NautilusFilesView *view)
+{
+ /* setup loading overlay */
+ if (view->details->floating_bar_set_status_timeout_id != 0) {
+ g_source_remove (view->details->floating_bar_set_status_timeout_id);
+ view->details->floating_bar_set_status_timeout_id = 0;
+ }
+
+ if (view->details->floating_bar_loading_timeout_id != 0) {
+ g_source_remove (view->details->floating_bar_loading_timeout_id);
+ view->details->floating_bar_loading_timeout_id = 0;
+ }
+
+ view->details->floating_bar_loading_timeout_id =
+ g_timeout_add (FLOATING_BAR_LOADING_DELAY, setup_loading_floating_bar_timeout_cb, view);
+}
+
+static void
+floating_bar_action_cb (NautilusFloatingBar *floating_bar,
+ gint action,
+ NautilusFilesView *view)
+{
+ if (action == NAUTILUS_FLOATING_BAR_ACTION_ID_STOP) {
+ remove_loading_floating_bar (view);
+ nautilus_window_slot_stop_loading (view->details->slot);
+ }
+}
+
+static void
+real_floating_bar_set_short_status (NautilusFilesView *view,
+ const gchar *primary_status,
+ const gchar *detail_status)
+{
+ gboolean disable_chrome;
+
+ nautilus_floating_bar_cleanup_actions (NAUTILUS_FLOATING_BAR (view->details->floating_bar));
+ nautilus_floating_bar_set_show_spinner (NAUTILUS_FLOATING_BAR (view->details->floating_bar), view->details->loading);
+
+ g_object_get (nautilus_files_view_get_window (view),
+ "disable-chrome", &disable_chrome,
+ NULL);
+
+ if ((primary_status == NULL && detail_status == NULL) || disable_chrome) {
+ gtk_widget_hide (view->details->floating_bar);
+ return;
+ }
+
+ nautilus_floating_bar_set_labels (NAUTILUS_FLOATING_BAR (view->details->floating_bar),
+ primary_status,
+ detail_status);
+
+ gtk_widget_show (view->details->floating_bar);
+}
+
+typedef struct {
+ gchar *primary_status;
+ gchar *detail_status;
+ NautilusFilesView *view;
+} FloatingBarSetStatusData;
+
+static void
+floating_bar_set_status_data_free (gpointer data)
+{
+ FloatingBarSetStatusData *status_data = data;
+
+ g_free (status_data->primary_status);
+ g_free (status_data->detail_status);
+
+ g_slice_free (FloatingBarSetStatusData, data);
+}
+
+static gboolean
+floating_bar_set_status_timeout_cb (gpointer data)
+{
+ FloatingBarSetStatusData *status_data = data;
+
+ status_data->view->details->floating_bar_set_status_timeout_id = 0;
+ real_floating_bar_set_short_status (status_data->view,
+ status_data->primary_status,
+ status_data->detail_status);
+
+ return FALSE;
+}
+
+static void
+set_floating_bar_status (NautilusFilesView *view,
+ const gchar *primary_status,
+ const gchar *detail_status)
+{
+ GtkSettings *settings;
+ gint double_click_time;
+ FloatingBarSetStatusData *status_data;
+
+ if (view->details->floating_bar_set_status_timeout_id != 0) {
+ g_source_remove (view->details->floating_bar_set_status_timeout_id);
+ view->details->floating_bar_set_status_timeout_id = 0;
+ }
+
+ settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (view)));
+ g_object_get (settings,
+ "gtk-double-click-time", &double_click_time,
+ NULL);
+
+ status_data = g_slice_new0 (FloatingBarSetStatusData);
+ status_data->primary_status = g_strdup (primary_status);
+ status_data->detail_status = g_strdup (detail_status);
+ status_data->view = view;
+
+ /* waiting for half of the double-click-time before setting
+ * the status seems to be a good approximation of not setting it
+ * too often and not delaying the statusbar too much.
+ */
+ view->details->floating_bar_set_status_timeout_id =
+ g_timeout_add_full (G_PRIORITY_DEFAULT,
+ (guint) (double_click_time / 2),
+ floating_bar_set_status_timeout_cb,
+ status_data,
+ floating_bar_set_status_data_free);
+}
+
+static char *
+real_get_backing_uri (NautilusFilesView *view)
+{
+ NautilusDirectory *directory;
+ char *uri;
+
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+
+ if (view->details->model == NULL) {
+ return NULL;
+ }
+
+ directory = view->details->model;
+
+ if (NAUTILUS_IS_DESKTOP_DIRECTORY (directory)) {
+ directory = nautilus_desktop_directory_get_real_directory (NAUTILUS_DESKTOP_DIRECTORY (directory));
+ } else {
+ nautilus_directory_ref (directory);
+ }
+
+ uri = nautilus_directory_get_uri (directory);
+
+ nautilus_directory_unref (directory);
+
+ return uri;
+}
+
+/**
+ *
+ * nautilus_files_view_get_backing_uri:
+ *
+ * Returns the URI for the target location of new directory, new file, new
+ * link and paste operations.
+ */
+
+char *
+nautilus_files_view_get_backing_uri (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_backing_uri (view);
+}
+
+/**
+ * nautilus_files_view_select_all:
+ *
+ * select all the items in the view
+ *
+ **/
+static void
+nautilus_files_view_select_all (NautilusFilesView *view)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->select_all (view);
+}
+
+static void
+nautilus_files_view_select_first (NautilusFilesView *view)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->select_first (view);
+}
+
+static void
+nautilus_files_view_call_set_selection (NautilusFilesView *view, GList *selection)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->set_selection (view, selection);
+}
+
+static GList *
+nautilus_files_view_get_selection_for_file_transfer (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_selection_for_file_transfer (view);
+}
+
+static void
+nautilus_files_view_invert_selection (NautilusFilesView *view)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->invert_selection (view);
+}
+
+/**
+ * nautilus_files_view_reveal_selection:
+ *
+ * Scroll as necessary to reveal the selected items.
+ **/
+static void
+nautilus_files_view_reveal_selection (NautilusFilesView *view)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->reveal_selection (view);
+}
+
+static gboolean
+nautilus_files_view_using_manual_layout (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), FALSE);
+
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->using_manual_layout (view);
+}
+
+/**
+ * nautilus_files_view_get_icon:
+ * @view: a #NautilusFilesView
+ *
+ * Retrieves the #GIcon that represents @view.
+ *
+ * Returns: (transfer none): the #Gicon that represents @view
+ */
+GIcon*
+nautilus_files_view_get_icon (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_icon (view);
+}
+
+/**
+ * nautilus_files_view_get_view_widget:
+ * @view: a #NautilusFilesView
+ *
+ * Retrieves the view menu, as a #GtkWidget. If it's %NULL,
+ * the button renders insensitive.
+ *
+ * Returns: (transfer none): a #GtkWidget for the view menu
+ */
+GtkWidget*
+nautilus_files_view_get_view_widget (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+
+ return view->details->view_menu_widget;
+}
+
+/**
+ * nautilus_files_view_can_rename_file
+ *
+ * Determine whether a file can be renamed.
+ * @file: A NautilusFile
+ *
+ * Return value: TRUE if @file can be renamed, FALSE otherwise.
+ *
+ **/
+static gboolean
+nautilus_files_view_can_rename_file (NautilusFilesView *view,
+ NautilusFile *file)
+{
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->can_rename_file (view, file);
+}
+
+static gboolean
+nautilus_files_view_is_read_only (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), FALSE);
+
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->is_read_only (view);
+}
+
+static gboolean
+showing_trash_directory (NautilusFilesView *view)
+{
+ NautilusFile *file;
+
+ file = nautilus_files_view_get_directory_as_file (view);
+ if (file != NULL) {
+ return nautilus_file_is_in_trash (file);
+ }
+ return FALSE;
+}
+
+static gboolean
+showing_network_directory (NautilusFilesView *view)
+{
+ NautilusFile *file;
+
+ file = nautilus_files_view_get_directory_as_file (view);
+ if (file != NULL) {
+ return nautilus_file_is_in_network (file);
+ }
+ return FALSE;
+}
+
+static gboolean
+showing_recent_directory (NautilusFilesView *view)
+{
+ NautilusFile *file;
+
+ file = nautilus_files_view_get_directory_as_file (view);
+ if (file != NULL) {
+ return nautilus_file_is_in_recent (file);
+ }
+ return FALSE;
+}
+
+static gboolean
+nautilus_files_view_supports_creating_files (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), FALSE);
+
+ return !nautilus_files_view_is_read_only (view)
+ && !showing_trash_directory (view)
+ && !showing_recent_directory (view);
+}
+
+static gboolean
+nautilus_files_view_is_empty (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), FALSE);
+
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->is_empty (view);
+}
+
+/**
+ * nautilus_files_view_bump_zoom_level:
+ *
+ * bump the current zoom level by invoking the relevant subclass through the slot
+ *
+ **/
+void
+nautilus_files_view_bump_zoom_level (NautilusFilesView *view,
+ int zoom_increment)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ if (!nautilus_files_view_supports_zooming (view)) {
+ return;
+ }
+
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->bump_zoom_level (view, zoom_increment);
+}
+
+/**
+ * nautilus_files_view_can_zoom_in:
+ *
+ * Determine whether the view can be zoomed any closer.
+ * @view: The zoomable NautilusFilesView.
+ *
+ * Return value: TRUE if @view can be zoomed any closer, FALSE otherwise.
+ *
+ **/
+gboolean
+nautilus_files_view_can_zoom_in (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), FALSE);
+
+ if (!nautilus_files_view_supports_zooming (view)) {
+ return FALSE;
+ }
+
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->can_zoom_in (view);
+}
+
+/**
+ * nautilus_files_view_can_zoom_out:
+ *
+ * Determine whether the view can be zoomed any further away.
+ * @view: The zoomable NautilusFilesView.
+ *
+ * Return value: TRUE if @view can be zoomed any further away, FALSE otherwise.
+ *
+ **/
+gboolean
+nautilus_files_view_can_zoom_out (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), FALSE);
+
+ if (!nautilus_files_view_supports_zooming (view)) {
+ return FALSE;
+ }
+
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->can_zoom_out (view);
+}
+
+gboolean
+nautilus_files_view_supports_zooming (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), FALSE);
+
+ return view->details->supports_zooming;
+}
+
+/**
+ * nautilus_files_view_restore_default_zoom_level:
+ *
+ * restore to the default zoom level by invoking the relevant subclass through the slot
+ *
+ **/
+void
+nautilus_files_view_restore_default_zoom_level (NautilusFilesView *view)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ if (!nautilus_files_view_supports_zooming (view)) {
+ return;
+ }
+
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->restore_default_zoom_level (view);
+}
+
+gboolean
+nautilus_files_view_is_search (NautilusFilesView *view)
+{
+ if (!view->details->model)
+ return FALSE;
+
+ return NAUTILUS_IS_SEARCH_DIRECTORY (view->details->model);
+}
+
+const char *
+nautilus_files_view_get_view_id (NautilusFilesView *view)
+{
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_view_id (view);
+}
+
+char *
+nautilus_files_view_get_first_visible_file (NautilusFilesView *view)
+{
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_first_visible_file (view);
+}
+
+void
+nautilus_files_view_scroll_to_file (NautilusFilesView *view,
+ const char *uri)
+{
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->scroll_to_file (view, uri);
+}
+
+/**
+ * nautilus_files_view_get_selection:
+ *
+ * Get a list of NautilusFile pointers that represents the
+ * currently-selected items in this view. Subclasses must override
+ * the signal handler for the 'get_selection' signal. Callers are
+ * responsible for g_free-ing the list (but not its data).
+ * @view: NautilusFilesView whose selected items are of interest.
+ *
+ * Return value: GList of NautilusFile pointers representing the selection.
+ *
+ **/
+GList *
+nautilus_files_view_get_selection (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_selection (view);
+}
+
+typedef struct {
+ NautilusFile *file;
+ NautilusFilesView *directory_view;
+} ScriptLaunchParameters;
+
+typedef struct {
+ NautilusFile *file;
+ NautilusFilesView *directory_view;
+} CreateTemplateParameters;
+
+static GList *
+file_and_directory_list_to_files (GList *fad_list)
+{
+ GList *res, *l;
+ FileAndDirectory *fad;
+
+ res = NULL;
+ for (l = fad_list; l != NULL; l = l->next) {
+ fad = l->data;
+ res = g_list_prepend (res, nautilus_file_ref (fad->file));
+ }
+ return g_list_reverse (res);
+}
+
+
+static GList *
+file_and_directory_list_from_files (NautilusDirectory *directory,
+ GList *files)
+{
+ GList *res, *l;
+ FileAndDirectory *fad;
+
+ res = NULL;
+ for (l = files; l != NULL; l = l->next) {
+ fad = g_new0 (FileAndDirectory, 1);
+ fad->directory = nautilus_directory_ref (directory);
+ fad->file = nautilus_file_ref (l->data);
+ res = g_list_prepend (res, fad);
+ }
+ return g_list_reverse (res);
+}
+
+static void
+file_and_directory_free (FileAndDirectory *fad)
+{
+ nautilus_directory_unref (fad->directory);
+ nautilus_file_unref (fad->file);
+ g_free (fad);
+}
+
+
+static void
+file_and_directory_list_free (GList *list)
+{
+ GList *l;
+
+ for (l = list; l != NULL; l = l->next) {
+ file_and_directory_free (l->data);
+ }
+
+ g_list_free (list);
+}
+
+static gboolean
+file_and_directory_equal (gconstpointer v1,
+ gconstpointer v2)
+{
+ const FileAndDirectory *fad1, *fad2;
+ fad1 = v1;
+ fad2 = v2;
+
+ return (fad1->file == fad2->file &&
+ fad1->directory == fad2->directory);
+}
+
+static guint
+file_and_directory_hash (gconstpointer v)
+{
+ const FileAndDirectory *fad;
+
+ fad = v;
+ return GPOINTER_TO_UINT (fad->file) ^ GPOINTER_TO_UINT (fad->directory);
+}
+
+static ScriptLaunchParameters *
+script_launch_parameters_new (NautilusFile *file,
+ NautilusFilesView *directory_view)
+{
+ ScriptLaunchParameters *result;
+
+ result = g_new0 (ScriptLaunchParameters, 1);
+ g_object_ref (directory_view);
+ result->directory_view = directory_view;
+ nautilus_file_ref (file);
+ result->file = file;
+
+ return result;
+}
+
+static void
+script_launch_parameters_free (ScriptLaunchParameters *parameters)
+{
+ g_object_unref (parameters->directory_view);
+ nautilus_file_unref (parameters->file);
+ g_free (parameters);
+}
+
+static CreateTemplateParameters *
+create_template_parameters_new (NautilusFile *file,
+ NautilusFilesView *directory_view)
+{
+ CreateTemplateParameters *result;
+
+ result = g_new0 (CreateTemplateParameters, 1);
+ g_object_ref (directory_view);
+ result->directory_view = directory_view;
+ nautilus_file_ref (file);
+ result->file = file;
+
+ return result;
+}
+
+static void
+create_templates_parameters_free (CreateTemplateParameters *parameters)
+{
+ g_object_unref (parameters->directory_view);
+ nautilus_file_unref (parameters->file);
+ g_free (parameters);
+}
+
+NautilusWindow *
+nautilus_files_view_get_window (NautilusFilesView *view)
+{
+ return nautilus_window_slot_get_window (view->details->slot);
+}
+
+NautilusWindowSlot *
+nautilus_files_view_get_nautilus_window_slot (NautilusFilesView *view)
+{
+ g_assert (view->details->slot != NULL);
+
+ return view->details->slot;
+}
+
+/* Returns the GtkWindow that this directory view occupies, or NULL
+ * if at the moment this directory view is not in a GtkWindow or the
+ * GtkWindow cannot be determined. Primarily used for parenting dialogs.
+ */
+static GtkWindow *
+nautilus_files_view_get_containing_window (NautilusFilesView *view)
+{
+ GtkWidget *window;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ window = gtk_widget_get_ancestor (GTK_WIDGET (view), GTK_TYPE_WINDOW);
+ if (window == NULL) {
+ return NULL;
+ }
+
+ return GTK_WINDOW (window);
+}
+
+static gboolean
+nautilus_files_view_confirm_multiple (GtkWindow *parent_window,
+ int count,
+ gboolean tabs)
+{
+ GtkDialog *dialog;
+ char *prompt;
+ char *detail;
+ int response;
+
+ if (count <= SILENT_WINDOW_OPEN_LIMIT) {
+ return TRUE;
+ }
+
+ prompt = _("Are you sure you want to open all files?");
+ if (tabs) {
+ detail = g_strdup_printf (ngettext("This will open %'d separate tab.",
+ "This will open %'d separate tabs.", count), count);
+ } else {
+ detail = g_strdup_printf (ngettext("This will open %'d separate window.",
+ "This will open %'d separate windows.", count), count);
+ }
+ dialog = eel_show_yes_no_dialog (prompt, detail,
+ _("_OK"), _("_Cancel"),
+ parent_window);
+ g_free (detail);
+
+ response = gtk_dialog_run (dialog);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ return response == GTK_RESPONSE_YES;
+}
+
+static gboolean
+selection_not_empty_in_menu_callback (NautilusFilesView *view,
+ GList *selection)
+{
+ if (selection != NULL) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static char *
+get_view_directory (NautilusFilesView *view)
+{
+ char *uri, *path;
+ GFile *f;
+
+ uri = nautilus_directory_get_uri (view->details->model);
+ if (eel_uri_is_desktop (uri)) {
+ g_free (uri);
+ uri = nautilus_get_desktop_directory_uri ();
+
+ }
+ f = g_file_new_for_uri (uri);
+ path = g_file_get_path (f);
+ g_object_unref (f);
+ g_free (uri);
+
+ return path;
+}
+
+void
+nautilus_files_view_preview_files (NautilusFilesView *view,
+ GList *files,
+ GArray *locations)
+{
+ gchar *uri;
+ guint xid;
+ GtkWidget *toplevel;
+
+ uri = nautilus_file_get_uri (files->data);
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view));
+
+ xid = gdk_x11_window_get_xid (gtk_widget_get_window (toplevel));
+ nautilus_previewer_call_show_file (uri, xid, TRUE);
+
+ g_free (uri);
+}
+
+void
+nautilus_files_view_activate_selection (NautilusFilesView *view)
+{
+ GList *selection;
+
+ selection = nautilus_files_view_get_selection (view);
+ nautilus_files_view_activate_files (view,
+ selection,
+ 0,
+ TRUE);
+ nautilus_file_list_free (selection);
+}
+
+void
+nautilus_files_view_activate_files (NautilusFilesView *view,
+ GList *files,
+ NautilusWindowOpenFlags flags,
+ gboolean confirm_multiple)
+{
+ char *path;
+
+ path = get_view_directory (view);
+ nautilus_mime_activate_files (nautilus_files_view_get_containing_window (view),
+ view->details->slot,
+ files,
+ path,
+ flags,
+ confirm_multiple);
+
+ g_free (path);
+}
+
+static void
+nautilus_files_view_activate_file (NautilusFilesView *view,
+ NautilusFile *file,
+ NautilusWindowOpenFlags flags)
+{
+ char *path;
+
+ path = get_view_directory (view);
+ nautilus_mime_activate_file (nautilus_files_view_get_containing_window (view),
+ view->details->slot,
+ file,
+ path,
+ flags);
+
+ g_free (path);
+}
+
+static void
+action_open_with_default_application (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ nautilus_files_view_activate_selection (view);
+}
+static void
+action_open_file_and_close_window (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ GList *selection;
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection (view);
+ nautilus_files_view_activate_files (view,
+ selection,
+ NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND,
+ TRUE);
+ nautilus_file_list_free (selection);
+}
+
+static void
+got_it_clicked (GtkDialog *dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ g_settings_set_boolean (nautilus_preferences,
+ NAUTILUS_PREFERENCES_SHOW_MOVE_TO_TRASH_SHORTCUT_CHANGED_DIALOG,
+ FALSE);
+}
+
+static void
+action_show_move_to_trash_shortcut_changed_dialog (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ GtkWindow *dialog;
+ GtkBuilder *builder;
+ gboolean show_dialog_preference;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ show_dialog_preference = g_settings_get_boolean (nautilus_preferences,
+ NAUTILUS_PREFERENCES_SHOW_MOVE_TO_TRASH_SHORTCUT_CHANGED_DIALOG);
+ if (show_dialog_preference) {
+ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-move-to-trash-shortcut-changed.ui");
+ dialog = GTK_WINDOW (gtk_builder_get_object (builder, "move_to_trash_shortcut_changed_dialog"));
+
+ gtk_window_set_transient_for (dialog, GTK_WINDOW (nautilus_files_view_get_window (view)));
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (got_it_clicked),
+ view);
+
+ gtk_widget_show (GTK_WIDGET (dialog));
+ gtk_dialog_run(GTK_DIALOG (dialog));
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ g_object_unref (builder);
+ }
+}
+static void
+action_open_item_location (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ GList *selection;
+ NautilusFile *item;
+ GFile *activation_location;
+ NautilusFile *activation_file;
+ NautilusFile *location;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ selection = nautilus_files_view_get_selection (view);
+
+ if (!selection)
+ return;
+
+ item = NAUTILUS_FILE (selection->data);
+ activation_location = nautilus_file_get_activation_location (item);
+ activation_file = nautilus_file_get (activation_location);
+ location = nautilus_file_get_parent (activation_file);
+
+ nautilus_files_view_activate_file (view, location, 0);
+
+ nautilus_file_unref (location);
+ nautilus_file_unref (activation_file);
+ g_object_unref (activation_location);
+ nautilus_file_list_free (selection);
+}
+
+static void
+action_open_item_new_tab (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ GList *selection;
+ GtkWindow *window;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ selection = nautilus_files_view_get_selection (view);
+
+ window = nautilus_files_view_get_containing_window (view);
+
+ if (nautilus_files_view_confirm_multiple (window, g_list_length (selection), TRUE)) {
+ nautilus_files_view_activate_files (view,
+ selection,
+ NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB,
+ FALSE);
+ }
+
+ nautilus_file_list_free (selection);
+}
+
+static void
+app_chooser_dialog_response_cb (GtkDialog *dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ GtkWindow *parent_window;
+ GList *files;
+ GAppInfo *info;
+
+ parent_window = user_data;
+ files = g_object_get_data (G_OBJECT (dialog), "directory-view:files");
+
+ if (response_id != GTK_RESPONSE_OK)
+ goto out;
+
+ info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (dialog));
+
+ g_signal_emit_by_name (nautilus_signaller_get_current (), "mime-data-changed");
+
+ nautilus_launch_application (info, files, parent_window);
+
+ g_object_unref (info);
+out:
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+choose_program (NautilusFilesView *view,
+ GList *files)
+{
+ GtkWidget *dialog;
+ gchar *mime_type;
+ GtkWindow *parent_window;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ mime_type = nautilus_file_get_mime_type (files->data);
+ parent_window = nautilus_files_view_get_containing_window (view);
+
+ dialog = gtk_app_chooser_dialog_new_for_content_type (parent_window,
+ GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT |
+ GTK_DIALOG_USE_HEADER_BAR,
+ mime_type);
+ g_object_set_data_full (G_OBJECT (dialog),
+ "directory-view:files",
+ files,
+ (GDestroyNotify) nautilus_file_list_free);
+ gtk_widget_show (dialog);
+
+ g_signal_connect_object (dialog, "response",
+ G_CALLBACK (app_chooser_dialog_response_cb),
+ parent_window, 0);
+}
+
+static void
+open_with_other_program (NautilusFilesView *view)
+{
+ GList *selection;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ selection = nautilus_files_view_get_selection (view);
+ choose_program (view, selection);
+}
+
+static void
+action_open_with_other_application (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ open_with_other_program (NAUTILUS_FILES_VIEW (user_data));
+}
+
+static void
+trash_or_delete_selected_files (NautilusFilesView *view)
+{
+ GList *selection;
+
+ /* This might be rapidly called multiple times for the same selection
+ * when using keybindings. So we remember if the current selection
+ * was already removed (but the view doesn't know about it yet).
+ */
+ if (!view->details->selection_was_removed) {
+ selection = nautilus_files_view_get_selection_for_file_transfer (view);
+ trash_or_delete_files (nautilus_files_view_get_containing_window (view),
+ selection,
+ view);
+ nautilus_file_list_free (selection);
+ view->details->selection_was_removed = TRUE;
+ }
+}
+
+static void
+action_move_to_trash (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ trash_or_delete_selected_files (NAUTILUS_FILES_VIEW (user_data));
+}
+
+static void
+action_remove_from_recent (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ /* TODO:implement a set of functions for this, is very confusing to
+ * call trash_or_delete_file to remove from recent, even if it does like
+ * that not deleting/moving the files to trash */
+ trash_or_delete_selected_files (NAUTILUS_FILES_VIEW (user_data));
+}
+
+static void
+delete_selected_files (NautilusFilesView *view)
+{
+ GList *selection;
+ GList *node;
+ GList *locations;
+
+ selection = nautilus_files_view_get_selection_for_file_transfer (view);
+ if (selection == NULL) {
+ return;
+ }
+
+ locations = NULL;
+ for (node = selection; node != NULL; node = node->next) {
+ locations = g_list_prepend (locations,
+ nautilus_file_get_location ((NautilusFile *) node->data));
+ }
+ locations = g_list_reverse (locations);
+
+ nautilus_file_operations_delete (locations, nautilus_files_view_get_containing_window (view), NULL, NULL);
+
+ g_list_free_full (locations, g_object_unref);
+ nautilus_file_list_free (selection);
+}
+
+static void
+action_delete (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ delete_selected_files (NAUTILUS_FILES_VIEW (user_data));
+}
+
+static void
+action_restore_from_trash (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ GList *selection;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection_for_file_transfer (view);
+ nautilus_restore_files_from_trash (selection,
+ nautilus_files_view_get_containing_window (view));
+
+ nautilus_file_list_free (selection);
+
+}
+
+static void
+action_select_all (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ nautilus_files_view_select_all (view);
+}
+
+static void
+action_invert_selection (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ nautilus_files_view_invert_selection (user_data);
+}
+
+static void
+pattern_select_response_cb (GtkWidget *dialog,
+ int response,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ NautilusDirectory *directory;
+ GtkWidget *entry;
+ GList *selection;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ switch (response) {
+ case GTK_RESPONSE_OK :
+ entry = g_object_get_data (G_OBJECT (dialog), "entry");
+ directory = nautilus_files_view_get_model (view);
+ selection = nautilus_directory_match_pattern (directory,
+ gtk_entry_get_text (GTK_ENTRY (entry)));
+
+ if (selection) {
+ nautilus_files_view_call_set_selection (view, selection);
+ nautilus_file_list_free (selection);
+
+ nautilus_files_view_reveal_selection(view);
+ }
+ /* fall through */
+ case GTK_RESPONSE_NONE :
+ case GTK_RESPONSE_DELETE_EVENT :
+ case GTK_RESPONSE_CANCEL :
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ break;
+ default :
+ g_assert_not_reached ();
+ }
+}
+
+static void
+select_pattern (NautilusFilesView *view)
+{
+ GtkWidget *dialog;
+ GtkWidget *label;
+ GtkWidget *example;
+ GtkWidget *grid;
+ GtkWidget *entry;
+ char *example_pattern;
+
+ dialog = gtk_dialog_new_with_buttons (_("Select Items Matching"),
+ nautilus_files_view_get_containing_window (view),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR,
+ _("_Cancel"),
+ GTK_RESPONSE_CANCEL,
+ _("_Select"),
+ GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog),
+ GTK_RESPONSE_OK);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 2);
+
+ label = gtk_label_new_with_mnemonic (_("_Pattern:"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+
+ example = gtk_label_new (NULL);
+ gtk_widget_set_halign (example, GTK_ALIGN_START);
+ example_pattern = g_strdup_printf ("%s<i>%s</i> ",
+ _("Examples: "),
+ "*.png, file\?\?.txt, pict*.\?\?\?");
+ gtk_label_set_markup (GTK_LABEL (example), example_pattern);
+ g_free (example_pattern);
+
+ entry = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
+ gtk_widget_set_hexpand (entry, TRUE);
+
+ grid = gtk_grid_new ();
+ g_object_set (grid,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ "border-width", 6,
+ "row-spacing", 6,
+ "column-spacing", 12,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (grid), label);
+ gtk_grid_attach_next_to (GTK_GRID (grid), entry, label,
+ GTK_POS_RIGHT, 1, 1);
+ gtk_grid_attach_next_to (GTK_GRID (grid), example, entry,
+ GTK_POS_BOTTOM, 1, 1);
+
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+ gtk_widget_show_all (grid);
+ gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), grid);
+ g_object_set_data (G_OBJECT (dialog), "entry", entry);
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (pattern_select_response_cb),
+ view);
+ gtk_widget_show_all (dialog);
+}
+
+static void
+action_select_pattern (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ select_pattern(user_data);
+}
+
+static void
+zoom_level_changed (GtkRange *range,
+ NautilusFilesView *view)
+{
+ g_action_group_change_action_state (view->details->view_action_group,
+ "zoom-to-level",
+ g_variant_new_int32 (gtk_range_get_value (range)));
+}
+
+static void
+reveal_newly_added_folder (NautilusFilesView *view,
+ NautilusFile *new_file,
+ NautilusDirectory *directory,
+ GFile *target_location)
+{
+ GFile *location;
+
+ location = nautilus_file_get_location (new_file);
+ if (g_file_equal (location, target_location)) {
+ g_signal_handlers_disconnect_by_func (view,
+ G_CALLBACK (reveal_newly_added_folder),
+ (void *) target_location);
+ nautilus_files_view_select_file (view, new_file);
+ }
+ g_object_unref (location);
+}
+
+typedef struct {
+ NautilusFilesView *directory_view;
+ GHashTable *added_locations;
+ GList *selection;
+} NewFolderData;
+
+typedef struct {
+ NautilusFilesView *directory_view;
+ GHashTable *to_remove_locations;
+ NautilusFile *new_folder;
+} NewFolderSelectionData;
+
+static void
+track_newly_added_locations (NautilusFilesView *view,
+ NautilusFile *new_file,
+ NautilusDirectory *directory,
+ gpointer user_data)
+{
+ NewFolderData *data;
+
+ data = user_data;
+
+ g_hash_table_insert (data->added_locations, nautilus_file_get_location (new_file), NULL);
+}
+
+static void
+new_folder_done (GFile *new_folder,
+ gboolean success,
+ gpointer user_data)
+{
+ NautilusFilesView *directory_view;
+ NautilusFile *file;
+ char screen_string[32];
+ GdkScreen *screen;
+ NewFolderData *data;
+
+ data = (NewFolderData *)user_data;
+
+ directory_view = data->directory_view;
+
+ if (directory_view == NULL) {
+ goto fail;
+ }
+
+ g_signal_handlers_disconnect_by_func (directory_view,
+ G_CALLBACK (track_newly_added_locations),
+ (void *) data);
+
+ if (new_folder == NULL) {
+ goto fail;
+ }
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (directory_view));
+ g_snprintf (screen_string, sizeof (screen_string), "%d", gdk_screen_get_number (screen));
+
+
+ file = nautilus_file_get (new_folder);
+ nautilus_file_set_metadata
+ (file, NAUTILUS_METADATA_KEY_SCREEN,
+ NULL,
+ screen_string);
+
+ if (data->selection != NULL) {
+ NewFolderSelectionData *sdata;
+ GList *uris, *l;
+ char *target_uri;
+
+ sdata = g_new (NewFolderSelectionData, 1);
+ sdata->directory_view = directory_view;
+ sdata->to_remove_locations = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
+ g_object_unref, NULL);
+ sdata->new_folder = g_object_ref (file);
+
+ uris = NULL;
+ for (l = data->selection; l != NULL; l = l->next) {
+ GFile *old_location;
+ GFile *new_location;
+ char *basename;
+
+ uris = g_list_prepend (uris, nautilus_file_get_uri ((NautilusFile *) l->data));
+
+ old_location = nautilus_file_get_location (l->data);
+ basename = g_file_get_basename (old_location);
+ new_location = g_file_resolve_relative_path (new_folder, basename);
+ g_hash_table_insert (sdata->to_remove_locations, new_location, NULL);
+ g_free (basename);
+ g_object_unref (old_location);
+ }
+ uris = g_list_reverse (uris);
+
+ target_uri = nautilus_file_get_uri (file);
+
+ nautilus_files_view_move_copy_items (directory_view,
+ uris,
+ NULL,
+ target_uri,
+ GDK_ACTION_MOVE,
+ 0, 0);
+ g_list_free_full (uris, g_free);
+ g_free (target_uri);
+ } else {
+ if (g_hash_table_lookup_extended (data->added_locations, new_folder, NULL, NULL)) {
+ /* The file was already added */
+ nautilus_files_view_select_file (directory_view, file);
+ } else {
+ /* We need to run after the default handler adds the folder we want to
+ * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
+ * must use connect_after.
+ */
+ g_signal_connect_data (directory_view,
+ "add-file",
+ G_CALLBACK (reveal_newly_added_folder),
+ g_object_ref (new_folder),
+ (GClosureNotify)g_object_unref,
+ G_CONNECT_AFTER);
+ }
+ }
+
+ nautilus_file_unref (file);
+
+ fail:
+ g_hash_table_destroy (data->added_locations);
+
+ if (data->directory_view != NULL) {
+ g_object_remove_weak_pointer (G_OBJECT (data->directory_view),
+ (gpointer *) &data->directory_view);
+ }
+
+ nautilus_file_list_free (data->selection);
+ g_free (data);
+}
+
+
+static NewFolderData *
+new_folder_data_new (NautilusFilesView *directory_view,
+ gboolean with_selection)
+{
+ NewFolderData *data;
+
+ data = g_new (NewFolderData, 1);
+ data->directory_view = directory_view;
+ data->added_locations = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
+ g_object_unref, NULL);
+ if (with_selection) {
+ data->selection = nautilus_files_view_get_selection_for_file_transfer (directory_view);
+ } else {
+ data->selection = NULL;
+ }
+ g_object_add_weak_pointer (G_OBJECT (data->directory_view),
+ (gpointer *) &data->directory_view);
+
+ return data;
+}
+
+static GdkPoint *
+context_menu_to_file_operation_position (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+
+ if (nautilus_files_view_using_manual_layout (view)
+ && view->details->context_menu_position.x >= 0
+ && view->details->context_menu_position.y >= 0) {
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->widget_to_file_operation_position
+ (view, &view->details->context_menu_position);
+ return &view->details->context_menu_position;
+ } else {
+ return NULL;
+ }
+}
+
+typedef struct {
+ NautilusFilesView *view;
+ GtkWidget *widget;
+ GtkWidget *error_label;
+ GtkWidget *name_entry;
+ GtkWidget *activate_button;
+ gboolean target_is_folder;
+ NautilusFile *target_file;
+ gboolean duplicated_is_folder;
+ void (*on_name_accepted) (gpointer data);
+ /* For create folder only */
+ gboolean with_selection;
+} FileNameWidgetData;
+
+static gboolean
+duplicated_file_label_show (FileNameWidgetData *data)
+{
+ if (data->duplicated_is_folder)
+ gtk_label_set_label (GTK_LABEL (data->error_label), _("A folder with that name already exists."));
+ else
+ gtk_label_set_label (GTK_LABEL (data->error_label), _("A file with that name already exists."));
+
+ data->view->details->duplicated_label_timeout_id = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
+static gchar*
+validate_file_name (const gchar *name,
+ gboolean is_folder)
+{
+ gchar *error_message = NULL;
+
+ if (strstr (name, "/") != NULL) {
+ if (is_folder)
+ error_message = _("Folder names cannot contain “/”.");
+ else
+ error_message = _("Files names cannot contain “/”.");
+ } else if (strcmp (name, ".") == 0){
+ if (is_folder)
+ error_message = _("A folder can not be called “.”.");
+ else
+ error_message = _("A file can not be called “.”.");
+ } else if (strcmp (name, "..") == 0){
+ if (is_folder)
+ error_message = _("A folder can not be called “..”.");
+ else
+ error_message = _("A file can not be called “..”.");
+ }
+
+ return error_message;
+}
+
+static void
+file_name_widget_entry_on_changed (gpointer user_data)
+{
+ FileNameWidgetData *data;
+ NautilusFile *existing_file;
+ gchar *name;
+ gchar *error_message;
+ gboolean valid_name;
+ gboolean duplicated;
+
+ data = (FileNameWidgetData *) user_data;
+ name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry))));
+ error_message = validate_file_name (name, TRUE);
+ gtk_label_set_label (GTK_LABEL (data->error_label), error_message);
+
+ existing_file = nautilus_directory_get_file_by_name (data->view->details->model, name);
+
+ valid_name = strlen (name) > 0 && error_message == NULL;
+ /* If there is a target file and the name is the same, we don't show it
+ * as duplicated. This is the case for renaming. */
+ duplicated = existing_file != NULL &&
+ (data->target_file == NULL ||
+ nautilus_file_compare_display_name (data->target_file, name) != 0);
+ gtk_widget_set_sensitive (data->activate_button, valid_name && !duplicated);
+
+ if (data->view->details->duplicated_label_timeout_id > 0) {
+ g_source_remove (data->view->details->duplicated_label_timeout_id);
+ data->view->details->duplicated_label_timeout_id = 0;
+ }
+
+ /* Report duplicated file only if not other message shown (for instance,
+ * folders like "." or ".." will always exists, but we consider it as an
+ * error, not as a duplicated file or if the name is the same as the file
+ * we are renaming also don't report as a duplicated */
+ if (duplicated && valid_name) {
+ data->duplicated_is_folder = nautilus_file_is_directory (existing_file);
+ data->view->details->duplicated_label_timeout_id =
+ g_timeout_add (FILE_NAME_DUPLICATED_LABEL_TIMEOUT,
+ (GSourceFunc)duplicated_file_label_show,
+ data);
+ }
+
+ if (existing_file != NULL)
+ nautilus_file_unref (existing_file);
+
+ g_free (name);
+}
+
+static void
+create_folder_dialog_on_response (GtkDialog *dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ FileNameWidgetData *widget_data;
+
+ widget_data = (FileNameWidgetData *) user_data;
+
+ if (response_id == GTK_RESPONSE_OK) {
+ NewFolderData *data;
+ GdkPoint *pos;
+ char *parent_uri;
+ gchar *name;
+
+ data = new_folder_data_new (widget_data->view, widget_data->with_selection);
+
+ name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (widget_data->name_entry))));
+ g_signal_connect_data (widget_data->view,
+ "add-file",
+ G_CALLBACK (track_newly_added_locations),
+ data,
+ (GClosureNotify)NULL,
+ G_CONNECT_AFTER);
+
+ pos = context_menu_to_file_operation_position (widget_data->view);
+
+ parent_uri = nautilus_files_view_get_backing_uri (widget_data->view);
+ nautilus_file_operations_new_folder (GTK_WIDGET (widget_data->view),
+ pos, parent_uri, name,
+ new_folder_done, data);
+
+ g_free (parent_uri);
+ g_free (name);
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_free (user_data);
+}
+
+
+static void
+create_folder_on_name_accepted (gpointer user_data)
+{
+ FileNameWidgetData *data;
+
+ data = (FileNameWidgetData *) user_data;
+ gtk_dialog_response (GTK_DIALOG (data->widget),
+ GTK_RESPONSE_OK);
+}
+
+static void
+rename_file_on_name_accepted (gpointer user_data)
+{
+ FileNameWidgetData *data;
+ gchar *name;
+
+ data = (FileNameWidgetData *) user_data;
+
+ name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry))));
+ nautilus_rename_file (data->target_file, name, NULL, NULL);
+
+ nautilus_files_view_select_file (data->view, data->target_file);
+ nautilus_files_view_reveal_selection (data->view);
+
+ gtk_widget_hide (data->widget);
+
+ g_free (name);
+}
+
+static void
+file_name_widget_on_activate (gpointer user_data)
+{
+ FileNameWidgetData *data;
+ NautilusFile *existing_file;
+ gchar *name;
+ gchar *error_message;
+ gboolean valid_name;
+ gboolean duplicated;
+
+ data = (FileNameWidgetData *) user_data;
+ name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry))));
+ existing_file = nautilus_directory_get_file_by_name (data->view->details->model, name);
+ error_message = validate_file_name (name, TRUE);
+ valid_name = strlen (name) > 0 && error_message == NULL;
+ duplicated = existing_file != NULL &&
+ (data->target_file == NULL ||
+ nautilus_file_compare_display_name (data->target_file, name) != 0);
+
+ if (data->view->details->duplicated_label_timeout_id > 0) {
+ g_source_remove (data->view->details->duplicated_label_timeout_id);
+ data->view->details->duplicated_label_timeout_id = 0;
+ }
+
+ if (valid_name && !duplicated) {
+ data->on_name_accepted ((gpointer) data);
+ } else {
+ /* Report duplicated file only if not other message shown (for instance,
+ * folders like "." or ".." will always exists, but we consider it as an
+ * error, not as a duplicated file) */
+ if (existing_file != NULL && valid_name) {
+ data->duplicated_is_folder = nautilus_file_is_directory (existing_file);
+ /* Show it inmediatily since the user tried to trigger the action */
+ duplicated_file_label_show (data);
+ }
+ }
+
+ if (existing_file != NULL)
+ nautilus_file_unref (existing_file);
+
+}
+
+static void
+rename_file_popover_on_closed (GtkPopover *popover,
+ gpointer user_data)
+{
+ FileNameWidgetData *widget_data;
+
+ widget_data = (FileNameWidgetData *) user_data;
+ widget_data->view->details->rename_file_popover = NULL;
+ g_free (widget_data);
+}
+
+static GdkRectangle*
+nautilus_files_view_compute_rename_popover_relative_to (NautilusFilesView *view)
+{
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->compute_rename_popover_relative_to (view);
+}
+
+static void
+nautilus_files_view_rename_file_popover_new (NautilusFilesView *view,
+ NautilusFile *target_file)
+{
+ FileNameWidgetData *widget_data;
+ GtkWidget *label_file_name;
+ GtkBuilder *builder;
+ gint start_offset, end_offset;
+ GdkRectangle *relative_to;
+
+ if (view->details->rename_file_popover != NULL)
+ return;
+
+ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-rename-file-popover.ui");
+ label_file_name = GTK_WIDGET (gtk_builder_get_object (builder, "name_label"));
+
+ widget_data = g_new (FileNameWidgetData, 1);
+ widget_data->view = view;
+ widget_data->on_name_accepted = rename_file_on_name_accepted;
+ widget_data->widget = GTK_WIDGET (gtk_builder_get_object (builder, "rename_file_popover"));
+ widget_data->activate_button = GTK_WIDGET (gtk_builder_get_object (builder, "rename_button"));
+ widget_data->error_label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
+ widget_data->name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
+ widget_data->target_is_folder = nautilus_file_is_directory (target_file);
+ widget_data->target_file = target_file;
+
+ view->details->rename_file_popover = widget_data->widget;
+
+ /* Connect signals */
+ gtk_builder_add_callback_symbols (builder,
+ "file_name_widget_entry_on_changed",
+ G_CALLBACK (file_name_widget_entry_on_changed),
+ "file_name_widget_on_activate",
+ G_CALLBACK (file_name_widget_on_activate),
+ "rename_file_popover_on_closed",
+ G_CALLBACK (rename_file_popover_on_closed),
+ "rename_file_popover_on_unmap",
+ G_CALLBACK (gtk_widget_destroy),
+ NULL);
+
+ gtk_builder_connect_signals (builder, widget_data);
+
+ if (widget_data->target_is_folder)
+ gtk_label_set_text (GTK_LABEL (label_file_name), _("Folder name"));
+ else
+ gtk_label_set_text (GTK_LABEL (label_file_name), _("File name"));
+ gtk_entry_set_text (GTK_ENTRY (widget_data->name_entry), nautilus_file_get_name (target_file));
+
+ relative_to = nautilus_files_view_compute_rename_popover_relative_to (view);
+ gtk_popover_set_default_widget (GTK_POPOVER (widget_data->widget),
+ widget_data->activate_button);
+ gtk_popover_set_pointing_to (GTK_POPOVER (widget_data->widget), relative_to);
+ gtk_popover_set_relative_to (GTK_POPOVER (widget_data->widget),
+ GTK_WIDGET (view));
+ gtk_widget_show (widget_data->widget);
+ gtk_widget_grab_focus (widget_data->widget);
+
+ /* Select the name part withouth the file extension */
+ eel_filename_get_rename_region (nautilus_file_get_name (target_file),
+ &start_offset, &end_offset);
+ gtk_editable_select_region (GTK_EDITABLE (widget_data->name_entry),
+ start_offset, end_offset);
+
+ /* Update the rename button status */
+ file_name_widget_entry_on_changed (widget_data);
+
+
+ g_object_unref (builder);
+}
+
+static void
+nautilus_files_view_new_folder_dialog_new (NautilusFilesView *view,
+ gboolean with_selection)
+{
+ FileNameWidgetData *widget_data;
+ GtkWidget *label_file_name;
+ GtkBuilder *builder;
+
+ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-create-folder-dialog.ui");
+ label_file_name = GTK_WIDGET (gtk_builder_get_object (builder, "name_label"));
+
+ widget_data = g_new (FileNameWidgetData, 1);
+ widget_data->view = view;
+ widget_data->on_name_accepted = create_folder_on_name_accepted;
+ widget_data->widget = GTK_WIDGET (gtk_builder_get_object (builder, "create_folder_dialog"));
+ widget_data->activate_button = GTK_WIDGET (gtk_builder_get_object (builder, "ok_button"));
+ widget_data->error_label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
+ widget_data->name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
+ widget_data->target_is_folder = TRUE;
+ widget_data->target_file = NULL;
+ widget_data->with_selection = with_selection;
+
+ gtk_window_set_transient_for (GTK_WINDOW (widget_data->widget),
+ GTK_WINDOW (nautilus_files_view_get_window (view)));
+
+ /* Connect signals */
+ gtk_builder_add_callback_symbols (builder,
+ "file_name_widget_entry_on_changed",
+ G_CALLBACK (file_name_widget_entry_on_changed),
+ "file_name_widget_on_activate",
+ G_CALLBACK (file_name_widget_on_activate),
+ "create_folder_dialog_on_response",
+ G_CALLBACK (create_folder_dialog_on_response),
+ NULL);
+
+ gtk_builder_connect_signals (builder, widget_data);
+ gtk_button_set_label (GTK_BUTTON (widget_data->activate_button),
+ _("Create"));
+ gtk_label_set_text (GTK_LABEL (label_file_name), _("Folder name"));
+ gtk_window_set_title (GTK_WINDOW (widget_data->widget), _("New Folder"));
+
+ gtk_widget_show_all (widget_data->widget);
+ /* Update the ok button status */
+ file_name_widget_entry_on_changed (widget_data);
+
+ g_object_unref (builder);
+}
+
+static void
+nautilus_files_view_new_folder (NautilusFilesView *directory_view,
+ gboolean with_selection)
+{
+ nautilus_files_view_new_folder_dialog_new (directory_view, with_selection);
+}
+
+static NewFolderData *
+setup_new_folder_data (NautilusFilesView *directory_view)
+{
+ NewFolderData *data;
+
+ data = new_folder_data_new (directory_view, FALSE);
+
+ g_signal_connect_data (directory_view,
+ "add-file",
+ G_CALLBACK (track_newly_added_locations),
+ data,
+ (GClosureNotify)NULL,
+ G_CONNECT_AFTER);
+
+ return data;
+}
+
+void
+nautilus_files_view_new_file_with_initial_contents (NautilusFilesView *view,
+ const char *parent_uri,
+ const char *filename,
+ const char *initial_contents,
+ int length,
+ GdkPoint *pos)
+{
+ NewFolderData *data;
+
+ g_assert (parent_uri != NULL);
+
+ data = setup_new_folder_data (view);
+
+ if (pos == NULL) {
+ pos = context_menu_to_file_operation_position (view);
+ }
+
+ nautilus_file_operations_new_file (GTK_WIDGET (view),
+ pos, parent_uri, filename,
+ initial_contents, length,
+ new_folder_done, data);
+}
+
+static void
+nautilus_files_view_new_file (NautilusFilesView *directory_view,
+ const char *parent_uri,
+ NautilusFile *source)
+{
+ GdkPoint *pos;
+ NewFolderData *data;
+ char *source_uri;
+ char *container_uri;
+
+ container_uri = NULL;
+ if (parent_uri == NULL) {
+ container_uri = nautilus_files_view_get_backing_uri (directory_view);
+ g_assert (container_uri != NULL);
+ }
+
+ if (source == NULL) {
+ nautilus_files_view_new_file_with_initial_contents (directory_view,
+ parent_uri != NULL ? parent_uri : container_uri,
+ NULL,
+ NULL,
+ 0,
+ NULL);
+ g_free (container_uri);
+ return;
+ }
+
+ g_return_if_fail (nautilus_file_is_local (source));
+
+ pos = context_menu_to_file_operation_position (directory_view);
+
+ data = setup_new_folder_data (directory_view);
+
+ source_uri = nautilus_file_get_uri (source);
+
+ nautilus_file_operations_new_file_from_template (GTK_WIDGET (directory_view),
+ pos,
+ parent_uri != NULL ? parent_uri : container_uri,
+ NULL,
+ source_uri,
+ new_folder_done, data);
+
+ g_free (source_uri);
+ g_free (container_uri);
+}
+
+static void
+action_new_folder (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ nautilus_files_view_new_folder (NAUTILUS_FILES_VIEW (user_data), FALSE);
+}
+
+static void
+action_new_folder_with_selection (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ nautilus_files_view_new_folder (NAUTILUS_FILES_VIEW (user_data), TRUE);
+}
+
+static void
+action_properties (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ GList *selection;
+ GList *files;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ selection = nautilus_files_view_get_selection (view);
+ if (g_list_length (selection) == 0) {
+ if (view->details->directory_as_file != NULL) {
+ files = g_list_append (NULL, nautilus_file_ref (view->details->directory_as_file));
+
+ nautilus_properties_window_present (files, GTK_WIDGET (view), NULL);
+
+ nautilus_file_list_free (files);
+ }
+ } else {
+ nautilus_properties_window_present (selection, GTK_WIDGET (view), NULL);
+ }
+ nautilus_file_list_free (selection);
+}
+
+static void
+nautilus_files_view_set_show_hidden_files (NautilusFilesView *view,
+ gboolean show_hidden)
+{
+ if (view->details->ignore_hidden_file_preferences) {
+ return;
+ }
+
+ if (show_hidden != view->details->show_hidden_files) {
+ view->details->show_hidden_files = show_hidden;
+
+ g_settings_set_boolean (gtk_filechooser_preferences,
+ NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
+ show_hidden);
+
+ if (view->details->model != NULL) {
+ load_directory (view, view->details->model);
+ }
+ }
+}
+
+static void
+action_show_hidden_files (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ gboolean show_hidden;
+ NautilusFilesView *view;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ show_hidden = g_variant_get_boolean (state);
+
+ nautilus_files_view_set_show_hidden_files (view, show_hidden);
+
+ g_simple_action_set_state (action, state);
+}
+
+static void
+action_zoom_in (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ nautilus_files_view_bump_zoom_level (view, 1);
+}
+
+static void
+action_zoom_out (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ nautilus_files_view_bump_zoom_level (view, -1);
+}
+
+static void
+action_zoom_default (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ nautilus_files_view_restore_default_zoom_level (user_data);
+}
+
+static void
+action_open_item_new_window (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ GtkWindow *window;
+ GList *selection;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ selection = nautilus_files_view_get_selection (view);
+ window = GTK_WINDOW (nautilus_files_view_get_containing_window (view));
+
+ if (nautilus_files_view_confirm_multiple (window, g_list_length (selection), TRUE)) {
+ g_list_foreach (selection, open_one_in_new_window, view);
+ }
+
+ nautilus_file_list_free (selection);
+}
+
+static void
+paste_clipboard_data (NautilusFilesView *view,
+ GtkSelectionData *selection_data,
+ char *destination_uri)
+{
+ gboolean cut;
+ GList *item_uris;
+
+ cut = FALSE;
+ item_uris = nautilus_clipboard_get_uri_list_from_selection_data (selection_data, &cut,
+ copied_files_atom);
+
+ if (item_uris != NULL && destination_uri != NULL) {
+ nautilus_files_view_move_copy_items (view, item_uris, NULL, destination_uri,
+ cut ? GDK_ACTION_MOVE : GDK_ACTION_COPY,
+ 0, 0);
+
+ /* If items are cut then remove from clipboard */
+ if (cut) {
+ gtk_clipboard_clear (nautilus_clipboard_get (GTK_WIDGET (view)));
+ }
+
+ g_list_free_full (item_uris, g_free);
+ }
+}
+
+static void
+paste_clipboard_received_callback (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer data)
+{
+ NautilusFilesView *view;
+ char *view_uri;
+
+ view = NAUTILUS_FILES_VIEW (data);
+
+ view_uri = nautilus_files_view_get_backing_uri (view);
+
+ if (view->details->slot != NULL) {
+ paste_clipboard_data (view, selection_data, view_uri);
+ }
+
+ g_free (view_uri);
+
+ g_object_unref (view);
+}
+
+static void
+action_paste_files (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ g_object_ref (view);
+ gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
+ copied_files_atom,
+ paste_clipboard_received_callback,
+ view);
+}
+
+static void
+click_policy_changed_callback (gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->click_policy_changed (view);
+}
+
+gboolean
+nautilus_files_view_should_sort_directories_first (NautilusFilesView *view)
+{
+ return view->details->sort_directories_first;
+}
+
+static void
+sort_directories_first_changed_callback (gpointer callback_data)
+{
+ NautilusFilesView *view;
+ gboolean preference_value;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ preference_value =
+ g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
+
+ if (preference_value != view->details->sort_directories_first) {
+ view->details->sort_directories_first = preference_value;
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->sort_directories_first_changed (view);
+ }
+}
+
+static void
+show_hidden_files_changed_callback (gpointer callback_data)
+{
+ NautilusFilesView *view;
+ gboolean preference_value;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ preference_value =
+ g_settings_get_boolean (gtk_filechooser_preferences, NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES);
+
+ nautilus_files_view_set_show_hidden_files (view, preference_value);
+}
+
+static gboolean
+set_up_scripts_directory_global (void)
+{
+ char *old_scripts_directory_path;
+ char *scripts_directory_path;
+ const char *override;
+
+ if (scripts_directory_uri != NULL) {
+ return TRUE;
+ }
+
+ scripts_directory_path = nautilus_get_scripts_directory_path ();
+
+ override = g_getenv ("GNOME22_USER_DIR");
+
+ if (override) {
+ old_scripts_directory_path = g_build_filename (override,
+ "nautilus-scripts",
+ NULL);
+ } else {
+ old_scripts_directory_path = g_build_filename (g_get_home_dir (),
+ ".gnome2",
+ "nautilus-scripts",
+ NULL);
+ }
+
+ if (g_file_test (old_scripts_directory_path, G_FILE_TEST_IS_DIR)
+ && !g_file_test (scripts_directory_path, G_FILE_TEST_EXISTS)) {
+ char *updated;
+ const char *message;
+
+ /* test if we already attempted to migrate first */
+ updated = g_build_filename (old_scripts_directory_path, "DEPRECATED-DIRECTORY", NULL);
+ message = _("Nautilus 3.6 deprecated this directory and tried migrating "
+ "this configuration to ~/.local/share/nautilus");
+ if (!g_file_test (updated, G_FILE_TEST_EXISTS)) {
+ char *parent_dir;
+
+ parent_dir = g_path_get_dirname (scripts_directory_path);
+ if (g_mkdir_with_parents (parent_dir, 0700) == 0) {
+ int fd, res;
+
+ /* rename() works fine if the destination directory is
+ * empty.
+ */
+ res = g_rename (old_scripts_directory_path, scripts_directory_path);
+ if (res == -1) {
+ fd = g_creat (updated, 0600);
+ if (fd != -1) {
+ res = write (fd, message, strlen (message));
+ close (fd);
+ }
+ }
+ }
+ g_free (parent_dir);
+ }
+
+ g_free (updated);
+ }
+
+ if (g_mkdir_with_parents (scripts_directory_path, 0700) == 0) {
+ scripts_directory_uri = g_filename_to_uri (scripts_directory_path, NULL, NULL);
+ scripts_directory_uri_length = strlen (scripts_directory_uri);
+ }
+
+ g_free (scripts_directory_path);
+ g_free (old_scripts_directory_path);
+
+ return (scripts_directory_uri != NULL) ? TRUE : FALSE;
+}
+
+static void
+scripts_added_or_changed_callback (NautilusDirectory *directory,
+ GList *files,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ if (view->details->active) {
+ schedule_update_context_menus (view);
+ }
+}
+
+static void
+templates_added_or_changed_callback (NautilusDirectory *directory,
+ GList *files,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ if (view->details->active) {
+ schedule_update_context_menus (view);
+ }
+}
+
+static void
+add_directory_to_directory_list (NautilusFilesView *view,
+ NautilusDirectory *directory,
+ GList **directory_list,
+ GCallback changed_callback)
+{
+ NautilusFileAttributes attributes;
+
+ if (g_list_find (*directory_list, directory) == NULL) {
+ nautilus_directory_ref (directory);
+
+ attributes =
+ NAUTILUS_FILE_ATTRIBUTES_FOR_ICON |
+ NAUTILUS_FILE_ATTRIBUTE_INFO |
+ NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT;
+
+ nautilus_directory_file_monitor_add (directory, directory_list,
+ FALSE, attributes,
+ (NautilusDirectoryCallback)changed_callback, view);
+
+ g_signal_connect_object (directory, "files-added",
+ G_CALLBACK (changed_callback), view, 0);
+ g_signal_connect_object (directory, "files-changed",
+ G_CALLBACK (changed_callback), view, 0);
+
+ *directory_list = g_list_append (*directory_list, directory);
+ }
+}
+
+static void
+remove_directory_from_directory_list (NautilusFilesView *view,
+ NautilusDirectory *directory,
+ GList **directory_list,
+ GCallback changed_callback)
+{
+ *directory_list = g_list_remove (*directory_list, directory);
+
+ g_signal_handlers_disconnect_by_func (directory,
+ G_CALLBACK (changed_callback),
+ view);
+
+ nautilus_directory_file_monitor_remove (directory, directory_list);
+
+ nautilus_directory_unref (directory);
+}
+
+
+static void
+add_directory_to_scripts_directory_list (NautilusFilesView *view,
+ NautilusDirectory *directory)
+{
+ add_directory_to_directory_list (view, directory,
+ &view->details->scripts_directory_list,
+ G_CALLBACK (scripts_added_or_changed_callback));
+}
+
+static void
+remove_directory_from_scripts_directory_list (NautilusFilesView *view,
+ NautilusDirectory *directory)
+{
+ remove_directory_from_directory_list (view, directory,
+ &view->details->scripts_directory_list,
+ G_CALLBACK (scripts_added_or_changed_callback));
+}
+
+static void
+add_directory_to_templates_directory_list (NautilusFilesView *view,
+ NautilusDirectory *directory)
+{
+ add_directory_to_directory_list (view, directory,
+ &view->details->templates_directory_list,
+ G_CALLBACK (templates_added_or_changed_callback));
+}
+
+static void
+remove_directory_from_templates_directory_list (NautilusFilesView *view,
+ NautilusDirectory *directory)
+{
+ remove_directory_from_directory_list (view, directory,
+ &view->details->templates_directory_list,
+ G_CALLBACK (templates_added_or_changed_callback));
+}
+
+static void
+slot_active (NautilusWindowSlot *slot,
+ NautilusFilesView *view)
+{
+ if (view->details->active) {
+ return;
+ }
+
+ view->details->active = TRUE;
+
+ /* Avoid updating the toolbar withouth making sure the toolbar
+ * zoom slider has the correct adjustment that changes when the
+ * view mode changes
+ */
+ nautilus_window_slot_sync_view_mode (slot);
+ nautilus_files_view_update_context_menus(view);
+ nautilus_files_view_update_toolbar_menus (view);
+
+ schedule_update_context_menus (view);
+
+ gtk_widget_insert_action_group (GTK_WIDGET (nautilus_files_view_get_window (view)),
+ "view",
+ G_ACTION_GROUP (view->details->view_action_group));
+}
+
+static void
+slot_inactive (NautilusWindowSlot *slot,
+ NautilusFilesView *view)
+{
+ if (!view->details->active) {
+ return;
+ }
+
+ view->details->active = FALSE;
+
+ remove_update_context_menus_timeout_callback (view);
+ gtk_widget_insert_action_group (GTK_WIDGET (nautilus_files_view_get_window (view)),
+ "view",
+ NULL);
+}
+
+static void
+nautilus_files_view_grab_focus (GtkWidget *widget)
+{
+ /* focus the child of the scrolled window if it exists */
+ NautilusFilesView *view;
+ GtkWidget *child;
+
+ view = NAUTILUS_FILES_VIEW (widget);
+ child = gtk_bin_get_child (GTK_BIN (view->details->scrolled_window));
+
+ GTK_WIDGET_CLASS (nautilus_files_view_parent_class)->grab_focus (widget);
+
+ if (child) {
+ gtk_widget_grab_focus (GTK_WIDGET (child));
+ }
+}
+
+int
+nautilus_files_view_get_selection_count (NautilusFilesView *view)
+{
+ /* FIXME: This could be faster if we special cased it in subclasses */
+ GList *files;
+ int len;
+
+ files = nautilus_files_view_get_selection (NAUTILUS_FILES_VIEW (view));
+ len = g_list_length (files);
+ nautilus_file_list_free (files);
+
+ return len;
+}
+
+void
+nautilus_files_view_set_selection (NautilusFilesView *nautilus_files_view,
+ GList *selection)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (nautilus_files_view);
+
+ if (!view->details->loading) {
+ /* If we aren't still loading, set the selection right now,
+ * and reveal the new selection.
+ */
+ nautilus_files_view_call_set_selection (view, selection);
+ nautilus_files_view_reveal_selection (view);
+ } else {
+ /* If we are still loading, set the list of pending URIs instead.
+ * done_loading() will eventually select the pending URIs and reveal them.
+ */
+ g_list_free_full (view->details->pending_selection, g_object_unref);
+ view->details->pending_selection =
+ g_list_copy_deep (selection, (GCopyFunc) g_object_ref, NULL);
+ }
+}
+
+static char *
+get_bulk_rename_tool ()
+{
+ char *bulk_rename_tool;
+ g_settings_get (nautilus_preferences, NAUTILUS_PREFERENCES_BULK_RENAME_TOOL, "^ay", &bulk_rename_tool);
+ return g_strstrip (bulk_rename_tool);
+}
+
+static gboolean
+have_bulk_rename_tool ()
+{
+ char *bulk_rename_tool;
+ gboolean have_tool;
+
+ bulk_rename_tool = get_bulk_rename_tool ();
+ have_tool = ((bulk_rename_tool != NULL) && (*bulk_rename_tool != '\0'));
+ g_free (bulk_rename_tool);
+ return have_tool;
+}
+
+static void
+nautilus_files_view_destroy (GtkWidget *object)
+{
+ NautilusFilesView *view;
+ GList *node, *next;
+
+ view = NAUTILUS_FILES_VIEW (object);
+
+ nautilus_files_view_stop_loading (view);
+
+ for (node = view->details->scripts_directory_list; node != NULL; node = next) {
+ next = node->next;
+ remove_directory_from_scripts_directory_list (view, node->data);
+ }
+
+ for (node = view->details->templates_directory_list; node != NULL; node = next) {
+ next = node->next;
+ remove_directory_from_templates_directory_list (view, node->data);
+ }
+
+ while (view->details->subdirectory_list != NULL) {
+ nautilus_files_view_remove_subdirectory (view,
+ view->details->subdirectory_list->data);
+ }
+
+ remove_update_context_menus_timeout_callback (view);
+ remove_update_status_idle_callback (view);
+
+ if (view->details->display_selection_idle_id != 0) {
+ g_source_remove (view->details->display_selection_idle_id);
+ view->details->display_selection_idle_id = 0;
+ }
+
+ if (view->details->reveal_selection_idle_id != 0) {
+ g_source_remove (view->details->reveal_selection_idle_id);
+ view->details->reveal_selection_idle_id = 0;
+ }
+
+ if (view->details->floating_bar_set_status_timeout_id != 0) {
+ g_source_remove (view->details->floating_bar_set_status_timeout_id);
+ view->details->floating_bar_set_status_timeout_id = 0;
+ }
+
+ if (view->details->floating_bar_loading_timeout_id != 0) {
+ g_source_remove (view->details->floating_bar_loading_timeout_id);
+ view->details->floating_bar_loading_timeout_id = 0;
+ }
+
+
+ if (view->details->directory_as_file) {
+ nautilus_file_unref (view->details->directory_as_file);
+ view->details->directory_as_file = NULL;
+ }
+
+ /* We don't own the slot, so no unref */
+ view->details->slot = NULL;
+
+ GTK_WIDGET_CLASS (nautilus_files_view_parent_class)->destroy (object);
+}
+
+static void
+nautilus_files_view_finalize (GObject *object)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (object);
+
+ g_signal_handlers_disconnect_by_func (nautilus_preferences,
+ schedule_update_context_menus, view);
+ g_signal_handlers_disconnect_by_func (nautilus_preferences,
+ click_policy_changed_callback, view);
+ g_signal_handlers_disconnect_by_func (nautilus_preferences,
+ sort_directories_first_changed_callback, view);
+ g_signal_handlers_disconnect_by_func (gtk_filechooser_preferences,
+ show_hidden_files_changed_callback, view);
+ g_signal_handlers_disconnect_by_func (nautilus_window_state,
+ nautilus_files_view_display_selection_info, view);
+
+ g_signal_handlers_disconnect_by_func (gnome_lockdown_preferences,
+ schedule_update_context_menus, view);
+
+ g_hash_table_destroy (view->details->non_ready_files);
+
+ if (view->details->rename_file_popover != NULL) {
+ gtk_popover_set_relative_to (GTK_POPOVER (view->details->rename_file_popover),
+ NULL);
+ }
+
+ G_OBJECT_CLASS (nautilus_files_view_parent_class)->finalize (object);
+}
+
+/**
+ * nautilus_files_view_display_selection_info:
+ *
+ * Display information about the current selection, and notify the view frame of the changed selection.
+ * @view: NautilusFilesView for which to display selection info.
+ *
+ **/
+void
+nautilus_files_view_display_selection_info (NautilusFilesView *view)
+{
+ GList *selection;
+ goffset non_folder_size;
+ gboolean non_folder_size_known;
+ guint non_folder_count, folder_count, folder_item_count;
+ gboolean folder_item_count_known;
+ guint file_item_count;
+ GList *p;
+ char *first_item_name;
+ char *non_folder_count_str;
+ char *non_folder_item_count_str;
+ char *folder_count_str;
+ char *folder_item_count_str;
+ char *primary_status;
+ char *detail_status;
+ NautilusFile *file;
+
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ selection = nautilus_files_view_get_selection (view);
+
+ folder_item_count_known = TRUE;
+ folder_count = 0;
+ folder_item_count = 0;
+ non_folder_count = 0;
+ non_folder_size_known = FALSE;
+ non_folder_size = 0;
+ first_item_name = NULL;
+ folder_count_str = NULL;
+ folder_item_count_str = NULL;
+ non_folder_count_str = NULL;
+ non_folder_item_count_str = NULL;
+
+ for (p = selection; p != NULL; p = p->next) {
+ file = p->data;
+ if (nautilus_file_is_directory (file)) {
+ folder_count++;
+ if (nautilus_file_get_directory_item_count (file, &file_item_count, NULL)) {
+ folder_item_count += file_item_count;
+ } else {
+ folder_item_count_known = FALSE;
+ }
+ } else {
+ non_folder_count++;
+ if (!nautilus_file_can_get_size (file)) {
+ non_folder_size_known = TRUE;
+ non_folder_size += nautilus_file_get_size (file);
+ }
+ }
+
+ if (first_item_name == NULL) {
+ first_item_name = nautilus_file_get_display_name (file);
+ }
+ }
+
+ nautilus_file_list_free (selection);
+
+ /* Break out cases for localization's sake. But note that there are still pieces
+ * being assembled in a particular order, which may be a problem for some localizers.
+ */
+
+ if (folder_count != 0) {
+ if (folder_count == 1 && non_folder_count == 0) {
+ folder_count_str = g_strdup_printf (_("“%s” selected"), first_item_name);
+ } else {
+ folder_count_str = g_strdup_printf (ngettext("%'d folder selected",
+ "%'d folders selected",
+ folder_count),
+ folder_count);
+ }
+
+ if (folder_count == 1) {
+ if (!folder_item_count_known) {
+ folder_item_count_str = g_strdup ("");
+ } else {
+ folder_item_count_str = g_strdup_printf (ngettext("(containing %'d item)",
+ "(containing %'d items)",
+ folder_item_count),
+ folder_item_count);
+ }
+ }
+ else {
+ if (!folder_item_count_known) {
+ folder_item_count_str = g_strdup ("");
+ } else {
+ /* translators: this is preceded with a string of form 'N folders' (N more than 1) */
+ folder_item_count_str = g_strdup_printf (ngettext("(containing a total of %'d item)",
+ "(containing a total of %'d items)",
+ folder_item_count),
+ folder_item_count);
+ }
+
+ }
+ }
+
+ if (non_folder_count != 0) {
+ if (folder_count == 0) {
+ if (non_folder_count == 1) {
+ non_folder_count_str = g_strdup_printf (_("“%s” selected"),
+ first_item_name);
+ } else {
+ non_folder_count_str = g_strdup_printf (ngettext("%'d item selected",
+ "%'d items selected",
+ non_folder_count),
+ non_folder_count);
+ }
+ } else {
+ /* Folders selected also, use "other" terminology */
+ non_folder_count_str = g_strdup_printf (ngettext("%'d other item selected",
+ "%'d other items selected",
+ non_folder_count),
+ non_folder_count);
+ }
+
+ if (non_folder_size_known) {
+ char *size_string;
+
+ size_string = g_format_size (non_folder_size);
+ /* This is marked for translation in case a localiser
+ * needs to use something other than parentheses. The
+ * the message in parentheses is the size of the selected items.
+ */
+ non_folder_item_count_str = g_strdup_printf (_("(%s)"), size_string);
+ g_free (size_string);
+ } else {
+ non_folder_item_count_str = g_strdup ("");
+ }
+ }
+
+ if (folder_count == 0 && non_folder_count == 0) {
+ primary_status = NULL;
+ detail_status = NULL;
+ } else if (folder_count == 0) {
+ primary_status = g_strdup (non_folder_count_str);
+ detail_status = g_strdup (non_folder_item_count_str);
+ } else if (non_folder_count == 0) {
+ primary_status = g_strdup (folder_count_str);
+ detail_status = g_strdup (folder_item_count_str);
+ } else {
+ /* This is marked for translation in case a localizer
+ * needs to change ", " to something else. The comma
+ * is between the message about the number of folders
+ * and the number of items in those folders and the
+ * message about the number of other items and the
+ * total size of those items.
+ */
+ primary_status = g_strdup_printf (_("%s %s, %s %s"),
+ folder_count_str,
+ folder_item_count_str,
+ non_folder_count_str,
+ non_folder_item_count_str);
+ detail_status = NULL;
+ }
+
+ g_free (first_item_name);
+ g_free (folder_count_str);
+ g_free (folder_item_count_str);
+ g_free (non_folder_count_str);
+ g_free (non_folder_item_count_str);
+
+ set_floating_bar_status (view, primary_status, detail_status);
+
+ g_free (primary_status);
+ g_free (detail_status);
+}
+
+static void
+nautilus_files_view_send_selection_change (NautilusFilesView *view)
+{
+ g_signal_emit (view, signals[SELECTION_CHANGED], 0);
+}
+
+void
+nautilus_files_view_load_location (NautilusFilesView *nautilus_files_view,
+ GFile *location)
+{
+ NautilusDirectory *directory;
+
+ nautilus_profile_start (NULL);
+ directory = nautilus_directory_get (location);
+ load_directory (nautilus_files_view, directory);
+ nautilus_directory_unref (directory);
+ nautilus_profile_end (NULL);
+}
+
+static gboolean
+reveal_selection_idle_callback (gpointer data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (data);
+
+ view->details->reveal_selection_idle_id = 0;
+ nautilus_files_view_reveal_selection (view);
+
+ return FALSE;
+}
+
+static void
+done_loading (NautilusFilesView *view,
+ gboolean all_files_seen)
+{
+ GList *selection;
+ gboolean do_reveal = FALSE;
+
+ if (!view->details->loading) {
+ return;
+ }
+
+ nautilus_profile_start (NULL);
+
+ /* This can be called during destruction, in which case we set the model
+ * as NULL. */
+ if (view->details->model != NULL) {
+ nautilus_files_view_update_toolbar_menus (view);
+ remove_loading_floating_bar (view);
+ schedule_update_context_menus (view);
+ schedule_update_status (view);
+ reset_update_interval (view);
+
+ selection = view->details->pending_selection;
+
+ if (nautilus_files_view_is_search (view) && all_files_seen) {
+ nautilus_files_view_select_first (view);
+ do_reveal = TRUE;
+ } else if (selection != NULL && all_files_seen) {
+ view->details->pending_selection = NULL;
+
+ nautilus_files_view_call_set_selection (view, selection);
+ g_list_free_full (selection, g_object_unref);
+ do_reveal = TRUE;
+ }
+
+ if (do_reveal) {
+ if (NAUTILUS_IS_LIST_VIEW (view)) {
+ /* HACK: We should be able to directly call reveal_selection here,
+ * but at this point the GtkTreeView hasn't allocated the new nodes
+ * yet, and it has a bug in the scroll calculation dealing with this
+ * special case. It would always make the selection the top row, even
+ * if no scrolling would be neccessary to reveal it. So we let it
+ * allocate before revealing.
+ */
+ if (view->details->reveal_selection_idle_id != 0) {
+ g_source_remove (view->details->reveal_selection_idle_id);
+ }
+ view->details->reveal_selection_idle_id =
+ g_idle_add (reveal_selection_idle_callback, view);
+ } else {
+ nautilus_files_view_reveal_selection (view);
+ }
+ }
+ nautilus_files_view_display_selection_info (view);
+ }
+
+ view->details->loading = FALSE;
+ g_signal_emit (view, signals[END_LOADING], 0, all_files_seen);
+
+ check_empty_states (view);
+
+ nautilus_profile_end (NULL);
+}
+
+
+typedef struct {
+ GHashTable *debuting_files;
+ GList *added_files;
+} DebutingFilesData;
+
+static void
+debuting_files_data_free (DebutingFilesData *data)
+{
+ g_hash_table_unref (data->debuting_files);
+ nautilus_file_list_free (data->added_files);
+ g_free (data);
+}
+
+/* This signal handler watch for the arrival of the icons created
+ * as the result of a file operation. Once the last one is detected
+ * it selects and reveals them all.
+ */
+static void
+debuting_files_add_file_callback (NautilusFilesView *view,
+ NautilusFile *new_file,
+ NautilusDirectory *directory,
+ DebutingFilesData *data)
+{
+ GFile *location;
+
+ nautilus_profile_start (NULL);
+
+ location = nautilus_file_get_location (new_file);
+
+ if (g_hash_table_remove (data->debuting_files, location)) {
+ nautilus_file_ref (new_file);
+ data->added_files = g_list_prepend (data->added_files, new_file);
+
+ if (g_hash_table_size (data->debuting_files) == 0) {
+ nautilus_files_view_call_set_selection (view, data->added_files);
+ nautilus_files_view_reveal_selection (view);
+ g_signal_handlers_disconnect_by_func (view,
+ G_CALLBACK (debuting_files_add_file_callback),
+ data);
+ }
+ }
+
+ nautilus_profile_end (NULL);
+
+ g_object_unref (location);
+}
+
+typedef struct {
+ GList *added_files;
+ NautilusFilesView *directory_view;
+} CopyMoveDoneData;
+
+static void
+copy_move_done_data_free (CopyMoveDoneData *data)
+{
+ g_assert (data != NULL);
+
+ if (data->directory_view != NULL) {
+ g_object_remove_weak_pointer (G_OBJECT (data->directory_view),
+ (gpointer *) &data->directory_view);
+ }
+
+ nautilus_file_list_free (data->added_files);
+ g_free (data);
+}
+
+static void
+pre_copy_move_add_file_callback (NautilusFilesView *view,
+ NautilusFile *new_file,
+ NautilusDirectory *directory,
+ CopyMoveDoneData *data)
+{
+ nautilus_file_ref (new_file);
+ data->added_files = g_list_prepend (data->added_files, new_file);
+}
+
+/* This needs to be called prior to nautilus_file_operations_copy_move.
+ * It hooks up a signal handler to catch any icons that get added before
+ * the copy_done_callback is invoked. The return value should be passed
+ * as the data for uri_copy_move_done_callback.
+ */
+static CopyMoveDoneData *
+pre_copy_move (NautilusFilesView *directory_view)
+{
+ CopyMoveDoneData *copy_move_done_data;
+
+ copy_move_done_data = g_new0 (CopyMoveDoneData, 1);
+ copy_move_done_data->directory_view = directory_view;
+
+ g_object_add_weak_pointer (G_OBJECT (copy_move_done_data->directory_view),
+ (gpointer *) &copy_move_done_data->directory_view);
+
+ /* We need to run after the default handler adds the folder we want to
+ * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
+ * must use connect_after.
+ */
+ g_signal_connect (directory_view, "add-file",
+ G_CALLBACK (pre_copy_move_add_file_callback), copy_move_done_data);
+
+ return copy_move_done_data;
+}
+
+/* This function is used to pull out any debuting uris that were added
+ * and (as a side effect) remove them from the debuting uri hash table.
+ */
+static gboolean
+copy_move_done_partition_func (gpointer data,
+ gpointer callback_data)
+{
+ GFile *location;
+ gboolean result;
+
+ location = nautilus_file_get_location (NAUTILUS_FILE (data));
+ result = g_hash_table_remove ((GHashTable *) callback_data, location);
+ g_object_unref (location);
+
+ return result;
+}
+
+static gboolean
+remove_not_really_moved_files (gpointer key,
+ gpointer value,
+ gpointer callback_data)
+{
+ GList **added_files;
+ GFile *loc;
+
+ loc = key;
+
+ if (GPOINTER_TO_INT (value)) {
+ return FALSE;
+ }
+
+ added_files = callback_data;
+ *added_files = g_list_prepend (*added_files,
+ nautilus_file_get (loc));
+ return TRUE;
+}
+
+/* When this function is invoked, the file operation is over, but all
+ * the icons may not have been added to the directory view yet, so
+ * we can't select them yet.
+ *
+ * We're passed a hash table of the uri's to look out for, we hook
+ * up a signal handler to await their arrival.
+ */
+static void
+copy_move_done_callback (GHashTable *debuting_files,
+ gboolean success,
+ gpointer data)
+{
+ NautilusFilesView *directory_view;
+ CopyMoveDoneData *copy_move_done_data;
+ DebutingFilesData *debuting_files_data;
+
+ copy_move_done_data = (CopyMoveDoneData *) data;
+ directory_view = copy_move_done_data->directory_view;
+
+ if (directory_view != NULL) {
+ g_assert (NAUTILUS_IS_FILES_VIEW (directory_view));
+
+ debuting_files_data = g_new (DebutingFilesData, 1);
+ debuting_files_data->debuting_files = g_hash_table_ref (debuting_files);
+ debuting_files_data->added_files = eel_g_list_partition
+ (copy_move_done_data->added_files,
+ copy_move_done_partition_func,
+ debuting_files,
+ &copy_move_done_data->added_files);
+
+ /* We're passed the same data used by pre_copy_move_add_file_callback, so disconnecting
+ * it will free data. We've already siphoned off the added_files we need, and stashed the
+ * directory_view pointer.
+ */
+ g_signal_handlers_disconnect_by_func (directory_view,
+ G_CALLBACK (pre_copy_move_add_file_callback),
+ data);
+
+ /* Any items in the debuting_files hash table that have
+ * "FALSE" as their value aren't really being copied
+ * or moved, so we can't wait for an add_file signal
+ * to come in for those.
+ */
+ g_hash_table_foreach_remove (debuting_files,
+ remove_not_really_moved_files,
+ &debuting_files_data->added_files);
+
+ if (g_hash_table_size (debuting_files) == 0) {
+ /* on the off-chance that all the icons have already been added */
+ if (debuting_files_data->added_files != NULL) {
+ nautilus_files_view_call_set_selection (directory_view,
+ debuting_files_data->added_files);
+ nautilus_files_view_reveal_selection (directory_view);
+ }
+ debuting_files_data_free (debuting_files_data);
+ } else {
+ /* We need to run after the default handler adds the folder we want to
+ * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
+ * must use connect_after.
+ */
+ g_signal_connect_data (directory_view,
+ "add-file",
+ G_CALLBACK (debuting_files_add_file_callback),
+ debuting_files_data,
+ (GClosureNotify) debuting_files_data_free,
+ G_CONNECT_AFTER);
+ }
+ /* Schedule menu update for undo items */
+ schedule_update_context_menus (directory_view);
+ }
+
+ copy_move_done_data_free (copy_move_done_data);
+}
+
+static gboolean
+view_file_still_belongs (NautilusFilesView *view,
+ NautilusFile *file,
+ NautilusDirectory *directory)
+{
+ if (view->details->model != directory &&
+ g_list_find (view->details->subdirectory_list, directory) == NULL) {
+ return FALSE;
+ }
+
+ return nautilus_directory_contains_file (directory, file);
+}
+
+static gboolean
+still_should_show_file (NautilusFilesView *view,
+ NautilusFile *file,
+ NautilusDirectory *directory)
+{
+ return nautilus_files_view_should_show_file (view, file) &&
+ view_file_still_belongs (view, file, directory);
+}
+
+static gboolean
+ready_to_load (NautilusFile *file)
+{
+ return nautilus_file_check_if_ready (file,
+ NAUTILUS_FILE_ATTRIBUTES_FOR_ICON);
+}
+
+static int
+compare_files_cover (gconstpointer a,
+ gconstpointer b,
+ gpointer callback_data)
+{
+ const FileAndDirectory *fad1, *fad2;
+ NautilusFilesView *view;
+
+ view = callback_data;
+ fad1 = a; fad2 = b;
+
+ if (fad1->directory < fad2->directory) {
+ return -1;
+ } else if (fad1->directory > fad2->directory) {
+ return 1;
+ } else {
+ return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->compare_files (view, fad1->file, fad2->file);
+ }
+}
+static void
+sort_files (NautilusFilesView *view,
+ GList **list)
+{
+ *list = g_list_sort_with_data (*list, compare_files_cover, view);
+
+}
+
+/* Go through all the new added and changed files.
+ * Put any that are not ready to load in the non_ready_files hash table.
+ * Add all the rest to the old_added_files and old_changed_files lists.
+ * Sort the old_*_files lists if anything was added to them.
+ */
+static void
+process_new_files (NautilusFilesView *view)
+{
+ GList *new_added_files, *new_changed_files, *old_added_files, *old_changed_files;
+ GHashTable *non_ready_files;
+ GList *node, *next;
+ FileAndDirectory *pending;
+ gboolean in_non_ready;
+
+ new_added_files = view->details->new_added_files;
+ view->details->new_added_files = NULL;
+ new_changed_files = view->details->new_changed_files;
+ view->details->new_changed_files = NULL;
+
+ non_ready_files = view->details->non_ready_files;
+
+ old_added_files = view->details->old_added_files;
+ old_changed_files = view->details->old_changed_files;
+
+ /* Newly added files go into the old_added_files list if they're
+ * ready, and into the hash table if they're not.
+ */
+ for (node = new_added_files; node != NULL; node = next) {
+ next = node->next;
+ pending = (FileAndDirectory *)node->data;
+ in_non_ready = g_hash_table_lookup (non_ready_files, pending) != NULL;
+ if (nautilus_files_view_should_show_file (view, pending->file)) {
+ if (ready_to_load (pending->file)) {
+ if (in_non_ready) {
+ g_hash_table_remove (non_ready_files, pending);
+ }
+ new_added_files = g_list_delete_link (new_added_files, node);
+ old_added_files = g_list_prepend (old_added_files, pending);
+ } else {
+ if (!in_non_ready) {
+ new_added_files = g_list_delete_link (new_added_files, node);
+ g_hash_table_insert (non_ready_files, pending, pending);
+ }
+ }
+ }
+ }
+ file_and_directory_list_free (new_added_files);
+
+ /* Newly changed files go into the old_added_files list if they're ready
+ * and were seen non-ready in the past, into the old_changed_files list
+ * if they are read and were not seen non-ready in the past, and into
+ * the hash table if they're not ready.
+ */
+ for (node = new_changed_files; node != NULL; node = next) {
+ next = node->next;
+ pending = (FileAndDirectory *)node->data;
+ if (!still_should_show_file (view, pending->file, pending->directory) || ready_to_load (pending->file)) {
+ if (g_hash_table_lookup (non_ready_files, pending) != NULL) {
+ g_hash_table_remove (non_ready_files, pending);
+ if (still_should_show_file (view, pending->file, pending->directory)) {
+ new_changed_files = g_list_delete_link (new_changed_files, node);
+ old_added_files = g_list_prepend (old_added_files, pending);
+ }
+ } else if (nautilus_files_view_should_show_file (view, pending->file)) {
+ new_changed_files = g_list_delete_link (new_changed_files, node);
+ old_changed_files = g_list_prepend (old_changed_files, pending);
+ }
+ }
+ }
+ file_and_directory_list_free (new_changed_files);
+
+ /* If any files were added to old_added_files, then resort it. */
+ if (old_added_files != view->details->old_added_files) {
+ view->details->old_added_files = old_added_files;
+ sort_files (view, &view->details->old_added_files);
+ }
+
+ /* Resort old_changed_files too, since file attributes
+ * relevant to sorting could have changed.
+ */
+ if (old_changed_files != view->details->old_changed_files) {
+ view->details->old_changed_files = old_changed_files;
+ sort_files (view, &view->details->old_changed_files);
+ }
+
+}
+
+static void
+process_old_files (NautilusFilesView *view)
+{
+ GList *files_added, *files_changed, *node;
+ FileAndDirectory *pending;
+ GList *selection, *files;
+ gboolean send_selection_change;
+
+ files_added = view->details->old_added_files;
+ files_changed = view->details->old_changed_files;
+
+ send_selection_change = FALSE;
+
+ if (files_added != NULL || files_changed != NULL) {
+ g_signal_emit (view, signals[BEGIN_FILE_CHANGES], 0);
+
+ for (node = files_added; node != NULL; node = node->next) {
+ pending = node->data;
+ g_signal_emit (view,
+ signals[ADD_FILE], 0, pending->file, pending->directory);
+ }
+
+ for (node = files_changed; node != NULL; node = node->next) {
+ pending = node->data;
+ g_signal_emit (view,
+ signals[still_should_show_file (view, pending->file, pending->directory)
+ ? FILE_CHANGED : REMOVE_FILE], 0,
+ pending->file, pending->directory);
+ }
+
+ g_signal_emit (view, signals[END_FILE_CHANGES], 0);
+ check_empty_states (view);
+
+ if (files_changed != NULL) {
+ selection = nautilus_files_view_get_selection (view);
+ files = file_and_directory_list_to_files (files_changed);
+ send_selection_change = eel_g_lists_sort_and_check_for_intersection
+ (&files, &selection);
+ nautilus_file_list_free (files);
+ nautilus_file_list_free (selection);
+ }
+
+ file_and_directory_list_free (view->details->old_added_files);
+ view->details->old_added_files = NULL;
+
+ file_and_directory_list_free (view->details->old_changed_files);
+ view->details->old_changed_files = NULL;
+ }
+
+ if (send_selection_change) {
+ /* Send a selection change since some file names could
+ * have changed.
+ */
+ nautilus_files_view_send_selection_change (view);
+ }
+}
+
+static void
+display_pending_files (NautilusFilesView *view)
+{
+ process_new_files (view);
+ process_old_files (view);
+
+ if (view->details->model != NULL
+ && nautilus_directory_are_all_files_seen (view->details->model)
+ && g_hash_table_size (view->details->non_ready_files) == 0) {
+ done_loading (view, TRUE);
+ }
+}
+
+static gboolean
+display_selection_info_idle_callback (gpointer data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (data);
+
+ g_object_ref (G_OBJECT (view));
+
+ view->details->display_selection_idle_id = 0;
+ nautilus_files_view_display_selection_info (view);
+ nautilus_files_view_send_selection_change (view);
+
+ g_object_unref (G_OBJECT (view));
+
+ return FALSE;
+}
+
+static void
+remove_update_context_menus_timeout_callback (NautilusFilesView *view)
+{
+ if (view->details->update_context_menus_timeout_id != 0) {
+ g_source_remove (view->details->update_context_menus_timeout_id);
+ view->details->update_context_menus_timeout_id = 0;
+ }
+}
+
+static void
+update_context_menus_if_pending (NautilusFilesView *view)
+{
+ remove_update_context_menus_timeout_callback (view);
+
+ nautilus_files_view_update_context_menus(view);
+}
+
+static gboolean
+update_context_menus_timeout_callback (gpointer data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (data);
+
+ g_object_ref (G_OBJECT (view));
+
+ view->details->update_context_menus_timeout_id = 0;
+ nautilus_files_view_update_context_menus(view);
+
+ g_object_unref (G_OBJECT (view));
+
+ return FALSE;
+}
+
+static gboolean
+display_pending_callback (gpointer data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (data);
+
+ g_object_ref (G_OBJECT (view));
+
+ view->details->display_pending_source_id = 0;
+
+ display_pending_files (view);
+
+ g_object_unref (G_OBJECT (view));
+
+ return FALSE;
+}
+
+static void
+schedule_idle_display_of_pending_files (NautilusFilesView *view)
+{
+ /* Get rid of a pending source as it might be a timeout */
+ unschedule_display_of_pending_files (view);
+
+ /* We want higher priority than the idle that handles the relayout
+ to avoid a resort on each add. But we still want to allow repaints
+ and other hight prio events while we have pending files to show. */
+ view->details->display_pending_source_id =
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE - 20,
+ display_pending_callback, view, NULL);
+}
+
+static void
+schedule_timeout_display_of_pending_files (NautilusFilesView *view,
+ guint interval)
+{
+ /* No need to schedule an update if there's already one pending. */
+ if (view->details->display_pending_source_id != 0) {
+ return;
+ }
+
+ view->details->display_pending_source_id =
+ g_timeout_add (interval, display_pending_callback, view);
+}
+
+static void
+unschedule_display_of_pending_files (NautilusFilesView *view)
+{
+ /* Get rid of source if it's active. */
+ if (view->details->display_pending_source_id != 0) {
+ g_source_remove (view->details->display_pending_source_id);
+ view->details->display_pending_source_id = 0;
+ }
+}
+
+static void
+queue_pending_files (NautilusFilesView *view,
+ NautilusDirectory *directory,
+ GList *files,
+ GList **pending_list)
+{
+ if (files == NULL) {
+ return;
+ }
+
+ *pending_list = g_list_concat (file_and_directory_list_from_files (directory, files),
+ *pending_list);
+
+ if (! view->details->loading || nautilus_directory_are_all_files_seen (directory)) {
+ schedule_timeout_display_of_pending_files (view, view->details->update_interval);
+ }
+}
+
+static void
+remove_changes_timeout_callback (NautilusFilesView *view)
+{
+ if (view->details->changes_timeout_id != 0) {
+ g_source_remove (view->details->changes_timeout_id);
+ view->details->changes_timeout_id = 0;
+ }
+}
+
+static void
+reset_update_interval (NautilusFilesView *view)
+{
+ view->details->update_interval = UPDATE_INTERVAL_MIN;
+ remove_changes_timeout_callback (view);
+ /* Reschedule a pending timeout to idle */
+ if (view->details->display_pending_source_id != 0) {
+ schedule_idle_display_of_pending_files (view);
+ }
+}
+
+static gboolean
+changes_timeout_callback (gpointer data)
+{
+ gint64 now;
+ gint64 time_delta;
+ gboolean ret;
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (data);
+
+ g_object_ref (G_OBJECT (view));
+
+ now = g_get_monotonic_time ();
+ time_delta = now - view->details->last_queued;
+
+ if (time_delta < UPDATE_INTERVAL_RESET*1000) {
+ if (view->details->update_interval < UPDATE_INTERVAL_MAX &&
+ view->details->loading) {
+ /* Increase */
+ view->details->update_interval += UPDATE_INTERVAL_INC;
+ }
+ ret = TRUE;
+ } else {
+ /* Reset */
+ reset_update_interval (view);
+ ret = FALSE;
+ }
+
+ g_object_unref (G_OBJECT (view));
+
+ return ret;
+}
+
+static void
+schedule_changes (NautilusFilesView *view)
+{
+ /* Remember when the change was queued */
+ view->details->last_queued = g_get_monotonic_time ();
+
+ /* No need to schedule if there are already changes pending or during loading */
+ if (view->details->changes_timeout_id != 0 ||
+ view->details->loading) {
+ return;
+ }
+
+ view->details->changes_timeout_id =
+ g_timeout_add (UPDATE_INTERVAL_TIMEOUT_INTERVAL, changes_timeout_callback, view);
+}
+
+static void
+files_added_callback (NautilusDirectory *directory,
+ GList *files,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+ GtkWindow *window;
+ char *uri;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ nautilus_profile_start (NULL);
+
+ window = nautilus_files_view_get_containing_window (view);
+ uri = nautilus_files_view_get_uri (view);
+ DEBUG_FILES (files, "Files added in window %p: %s",
+ window, uri ? uri : "(no directory)");
+ g_free (uri);
+
+ schedule_changes (view);
+
+ queue_pending_files (view, directory, files, &view->details->new_added_files);
+
+ /* The number of items could have changed */
+ schedule_update_status (view);
+
+ nautilus_profile_end (NULL);
+}
+
+static void
+files_changed_callback (NautilusDirectory *directory,
+ GList *files,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+ GtkWindow *window;
+ char *uri;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ window = nautilus_files_view_get_containing_window (view);
+ uri = nautilus_files_view_get_uri (view);
+ DEBUG_FILES (files, "Files changed in window %p: %s",
+ window, uri ? uri : "(no directory)");
+ g_free (uri);
+
+ schedule_changes (view);
+
+ queue_pending_files (view, directory, files, &view->details->new_changed_files);
+
+ /* The free space or the number of items could have changed */
+ schedule_update_status (view);
+
+ /* A change in MIME type could affect the Open with menu, for
+ * one thing, so we need to update menus when files change.
+ */
+ schedule_update_context_menus (view);
+}
+
+static void
+done_loading_callback (NautilusDirectory *directory,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ nautilus_profile_start (NULL);
+ process_new_files (view);
+ if (g_hash_table_size (view->details->non_ready_files) == 0) {
+ /* Unschedule a pending update and schedule a new one with the minimal
+ * update interval. This gives the view a short chance at gathering the
+ * (cached) deep counts.
+ */
+ unschedule_display_of_pending_files (view);
+ schedule_timeout_display_of_pending_files (view, UPDATE_INTERVAL_MIN);
+
+ remove_loading_floating_bar (view);
+ }
+ nautilus_profile_end (NULL);
+}
+
+static void
+load_error_callback (NautilusDirectory *directory,
+ GError *error,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ /* FIXME: By doing a stop, we discard some pending files. Is
+ * that OK?
+ */
+ nautilus_files_view_stop_loading (view);
+
+ nautilus_report_error_loading_directory
+ (nautilus_files_view_get_directory_as_file (view),
+ error,
+ nautilus_files_view_get_containing_window (view));
+}
+
+void
+nautilus_files_view_add_subdirectory (NautilusFilesView *view,
+ NautilusDirectory *directory)
+{
+ NautilusFileAttributes attributes;
+
+ g_assert (!g_list_find (view->details->subdirectory_list, directory));
+
+ nautilus_directory_ref (directory);
+
+ attributes =
+ NAUTILUS_FILE_ATTRIBUTES_FOR_ICON |
+ NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
+ NAUTILUS_FILE_ATTRIBUTE_INFO |
+ NAUTILUS_FILE_ATTRIBUTE_LINK_INFO |
+ NAUTILUS_FILE_ATTRIBUTE_MOUNT |
+ NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO;
+
+ nautilus_directory_file_monitor_add (directory,
+ &view->details->model,
+ view->details->show_hidden_files,
+ attributes,
+ files_added_callback, view);
+
+ g_signal_connect
+ (directory, "files-added",
+ G_CALLBACK (files_added_callback), view);
+ g_signal_connect
+ (directory, "files-changed",
+ G_CALLBACK (files_changed_callback), view);
+
+ view->details->subdirectory_list = g_list_prepend (
+ view->details->subdirectory_list, directory);
+}
+
+void
+nautilus_files_view_remove_subdirectory (NautilusFilesView *view,
+ NautilusDirectory *directory)
+{
+ g_assert (g_list_find (view->details->subdirectory_list, directory));
+
+ view->details->subdirectory_list = g_list_remove (
+ view->details->subdirectory_list, directory);
+
+ g_signal_handlers_disconnect_by_func (directory,
+ G_CALLBACK (files_added_callback),
+ view);
+ g_signal_handlers_disconnect_by_func (directory,
+ G_CALLBACK (files_changed_callback),
+ view);
+
+ nautilus_directory_file_monitor_remove (directory, &view->details->model);
+
+ nautilus_directory_unref (directory);
+}
+
+/**
+ * nautilus_files_view_get_loading:
+ * @view: an #NautilusFilesView.
+ *
+ * Return value: #gboolean inicating whether @view is currently loaded.
+ *
+ **/
+gboolean
+nautilus_files_view_get_loading (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), FALSE);
+
+ return view->details->loading;
+}
+
+/**
+ * nautilus_files_view_get_model:
+ *
+ * Get the model for this NautilusFilesView.
+ * @view: NautilusFilesView of interest.
+ *
+ * Return value: NautilusDirectory for this view.
+ *
+ **/
+NautilusDirectory *
+nautilus_files_view_get_model (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+
+ return view->details->model;
+}
+
+GtkWidget*
+nautilus_files_view_get_content_widget (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+
+ return view->details->scrolled_window;
+}
+
+GdkAtom
+nautilus_files_view_get_copied_files_atom (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), GDK_NONE);
+
+ return copied_files_atom;
+}
+
+static void
+offset_drop_points (GArray *relative_item_points,
+ int x_offset,
+ int y_offset)
+{
+ 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;
+ }
+}
+
+/* special_link_in_selection
+ *
+ * Return TRUE if one of our special links is in the selection.
+ * Special links include the following:
+ * NAUTILUS_DESKTOP_LINK_TRASH, NAUTILUS_DESKTOP_LINK_HOME, NAUTILUS_DESKTOP_LINK_MOUNT
+ */
+
+static gboolean
+special_link_in_selection (GList *selection)
+{
+ gboolean saw_link;
+ GList *node;
+ NautilusFile *file;
+
+ saw_link = FALSE;
+
+ for (node = selection; node != NULL; node = node->next) {
+ file = NAUTILUS_FILE (node->data);
+
+ saw_link = NAUTILUS_IS_DESKTOP_ICON_FILE (file);
+
+ if (saw_link) {
+ break;
+ }
+ }
+
+ return saw_link;
+}
+
+/* desktop_or_home_dir_in_selection
+ *
+ * Return TRUE if either the desktop or the home directory is in the selection.
+ */
+
+static gboolean
+desktop_or_home_dir_in_selection (GList *selection)
+{
+ gboolean saw_desktop_or_home_dir;
+ GList *node;
+ NautilusFile *file;
+
+ saw_desktop_or_home_dir = FALSE;
+
+ for (node = selection; node != NULL; node = node->next) {
+ file = NAUTILUS_FILE (node->data);
+
+ saw_desktop_or_home_dir =
+ nautilus_file_is_home (file)
+ || nautilus_file_is_desktop_directory (file);
+
+ if (saw_desktop_or_home_dir) {
+ break;
+ }
+ }
+
+ return saw_desktop_or_home_dir;
+}
+
+static void
+trash_or_delete_done_cb (GHashTable *debuting_uris,
+ gboolean user_cancel,
+ NautilusFilesView *view)
+{
+ if (user_cancel) {
+ view->details->selection_was_removed = FALSE;
+ }
+}
+
+static void
+trash_or_delete_files (GtkWindow *parent_window,
+ const GList *files,
+ NautilusFilesView *view)
+{
+ GList *locations;
+ const GList *node;
+
+ locations = NULL;
+ for (node = files; node != NULL; node = node->next) {
+ locations = g_list_prepend (locations,
+ nautilus_file_get_location ((NautilusFile *) node->data));
+ }
+
+ locations = g_list_reverse (locations);
+
+ nautilus_file_operations_trash_or_delete (locations,
+ parent_window,
+ (NautilusDeleteCallback) trash_or_delete_done_cb,
+ view);
+ g_list_free_full (locations, g_object_unref);
+}
+
+static gboolean
+can_rename_file (NautilusFilesView *view,
+ NautilusFile *file)
+{
+ return nautilus_file_can_rename (file);
+}
+
+static void
+open_one_in_new_window (gpointer data,
+ gpointer callback_data)
+{
+ g_assert (NAUTILUS_IS_FILE (data));
+ g_assert (NAUTILUS_IS_FILES_VIEW (callback_data));
+
+ nautilus_files_view_activate_file (NAUTILUS_FILES_VIEW (callback_data),
+ NAUTILUS_FILE (data),
+ NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
+}
+
+static void
+update_context_menu_position_from_event (NautilusFilesView *view,
+ GdkEventButton *event)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ if (event != NULL) {
+ view->details->context_menu_position.x = event->x;
+ view->details->context_menu_position.y = event->y;
+ } else {
+ view->details->context_menu_position.x = -1;
+ view->details->context_menu_position.y = -1;
+ }
+}
+
+NautilusFile *
+nautilus_files_view_get_directory_as_file (NautilusFilesView *view)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ return view->details->directory_as_file;
+}
+
+static GdkPixbuf *
+get_menu_icon_for_file (NautilusFile *file,
+ GtkWidget *widget)
+{
+ NautilusIconInfo *info;
+ GdkPixbuf *pixbuf;
+ int size, scale;
+
+ size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
+ scale = gtk_widget_get_scale_factor (widget);
+
+ info = nautilus_file_get_icon (file, size, scale, 0);
+ pixbuf = nautilus_icon_info_get_pixbuf_nodefault_at_size (info, size);
+ g_object_unref (info);
+
+ return pixbuf;
+}
+
+static GList *
+get_extension_selection_menu_items (NautilusFilesView *view)
+{
+ NautilusWindow *window;
+ GList *items;
+ GList *providers;
+ GList *l;
+ GList *selection;
+
+ window = nautilus_files_view_get_window (view);
+ selection = nautilus_files_view_get_selection (view);
+ providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
+ items = NULL;
+
+ for (l = providers; l != NULL; l = l->next) {
+ NautilusMenuProvider *provider;
+ GList *file_items;
+
+ provider = NAUTILUS_MENU_PROVIDER (l->data);
+ file_items = nautilus_menu_provider_get_file_items (provider,
+ GTK_WIDGET (window),
+ selection);
+ items = g_list_concat (items, file_items);
+ }
+
+ nautilus_module_extension_list_free (providers);
+
+ return items;
+}
+
+static GList *
+get_extension_background_menu_items (NautilusFilesView *view)
+{
+ NautilusWindow *window;
+ NautilusFile *file;
+ GList *items;
+ GList *providers;
+ GList *l;
+
+ window = nautilus_files_view_get_window (view);
+ providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
+ file = nautilus_window_slot_get_file (view->details->slot);
+ items = NULL;
+
+ for (l = providers; l != NULL; l = l->next) {
+ NautilusMenuProvider *provider;
+ GList *file_items;
+
+ provider = NAUTILUS_MENU_PROVIDER (l->data);
+ file_items = nautilus_menu_provider_get_background_items (provider,
+ GTK_WIDGET (window),
+ file);
+ items = g_list_concat (items, file_items);
+ }
+
+ nautilus_module_extension_list_free (providers);
+
+ return items;
+}
+
+static void
+extension_action_callback (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusMenuItem *item = user_data;
+ nautilus_menu_item_activate (item);
+}
+
+static void
+add_extension_action (NautilusFilesView *view,
+ NautilusMenuItem *item,
+ const char *action_name)
+{
+ gboolean sensitive;
+ GSimpleAction *action;
+
+ g_object_get (item,
+ "sensitive", &sensitive,
+ NULL);
+
+ action = g_simple_action_new (action_name, NULL);
+ g_signal_connect_data (action, "activate",
+ G_CALLBACK (extension_action_callback),
+ g_object_ref (item),
+ (GClosureNotify) g_object_unref, 0);
+
+ g_action_map_add_action (G_ACTION_MAP (view->details->view_action_group),
+ G_ACTION (action));
+ g_simple_action_set_enabled (action, sensitive);
+
+ g_object_unref (action);
+}
+
+static GMenu *
+build_menu_for_extension_menu_items (NautilusFilesView *view,
+ const gchar *extension_prefix,
+ GList *menu_items)
+{
+ GList *l;
+ GMenu *gmenu;
+ gint idx = 0;
+
+ gmenu = g_menu_new ();
+
+ for (l = menu_items; l; l = l->next) {
+ NautilusMenuItem *item;
+ NautilusMenu *menu;
+ GMenuItem *menu_item;
+ char *name, *label;
+ char *extension_id, *prefix, *parsed_name, *detailed_action_name;
+
+ item = NAUTILUS_MENU_ITEM (l->data);
+
+ g_object_get (item,
+ "label", &label,
+ "menu", &menu,
+ "name", &name,
+ NULL);
+
+ extension_id = g_strdup_printf ("%s_%d", extension_prefix, idx);
+ prefix = g_strdup_printf ("extension_%s_", extension_id);
+ parsed_name = nautilus_escape_action_name (name, prefix);
+ add_extension_action (view, item, parsed_name);
+
+ detailed_action_name = g_strconcat ("view.", parsed_name, NULL);
+ menu_item = g_menu_item_new (label, detailed_action_name);
+
+ if (menu != NULL) {
+ GList *children;
+ GMenu *children_menu;
+
+ children = nautilus_menu_get_items (menu);
+ children_menu = build_menu_for_extension_menu_items (view, extension_id, children);
+ g_menu_item_set_submenu (menu_item, G_MENU_MODEL (children_menu));
+
+ nautilus_menu_item_list_free (children);
+ g_object_unref (children_menu);
+ }
+
+ g_menu_append_item (gmenu, menu_item);
+ idx++;
+
+ g_free (extension_id);
+ g_free (parsed_name);
+ g_free (prefix);
+ g_free (detailed_action_name);
+ g_free (name);
+ g_free (label);
+ g_object_unref (menu_item);
+ }
+
+ return gmenu;
+}
+
+static void
+add_extension_menu_items (NautilusFilesView *view,
+ const gchar *extension_prefix,
+ GList *menu_items,
+ GMenu *insertion_menu)
+{
+ GMenu *menu;
+
+ menu = build_menu_for_extension_menu_items (view, extension_prefix, menu_items);
+ nautilus_gmenu_merge (insertion_menu,
+ menu,
+ "extensions",
+ FALSE);
+
+ g_object_unref (menu);
+}
+
+static void
+update_extensions_menus (NautilusFilesView *view)
+{
+ GList *selection_items, *background_items;
+
+ selection_items = get_extension_selection_menu_items (view);
+ if (selection_items != NULL) {
+ add_extension_menu_items (view,
+ "selection",
+ selection_items,
+ view->details->selection_menu);
+ nautilus_menu_item_list_free (selection_items);
+ }
+
+ background_items = get_extension_background_menu_items (view);
+ if (background_items != NULL) {
+ add_extension_menu_items (view,
+ "background",
+ background_items,
+ view->details->background_menu);
+ nautilus_menu_item_list_free (background_items);
+ }
+}
+
+static char *
+change_to_view_directory (NautilusFilesView *view)
+{
+ char *path;
+ char *old_path;
+
+ old_path = g_get_current_dir ();
+
+ path = get_view_directory (view);
+
+ /* FIXME: What to do about non-local directories? */
+ if (path != NULL) {
+ g_chdir (path);
+ }
+
+ g_free (path);
+
+ return old_path;
+}
+
+static char **
+get_file_names_as_parameter_array (GList *selection,
+ NautilusDirectory *model)
+{
+ NautilusFile *file;
+ char **parameters;
+ GList *node;
+ GFile *file_location;
+ GFile *model_location;
+ int i;
+
+ if (model == NULL) {
+ return NULL;
+ }
+
+ parameters = g_new (char *, g_list_length (selection) + 1);
+
+ model_location = nautilus_directory_get_location (model);
+
+ for (node = selection, i = 0; node != NULL; node = node->next, i++) {
+ file = NAUTILUS_FILE (node->data);
+
+ if (!nautilus_file_is_local (file)) {
+ parameters[i] = NULL;
+ g_strfreev (parameters);
+ return NULL;
+ }
+
+ file_location = nautilus_file_get_location (NAUTILUS_FILE (node->data));
+ parameters[i] = g_file_get_relative_path (model_location, file_location);
+ if (parameters[i] == NULL) {
+ parameters[i] = g_file_get_path (file_location);
+ }
+ g_object_unref (file_location);
+ }
+
+ g_object_unref (model_location);
+
+ parameters[i] = NULL;
+ return parameters;
+}
+
+static char *
+get_file_paths_or_uris_as_newline_delimited_string (GList *selection,
+ gboolean get_paths)
+{
+ char *path;
+ char *uri;
+ char *result;
+ NautilusDesktopLink *link;
+ GString *expanding_string;
+ GList *node;
+ GFile *location;
+
+ expanding_string = g_string_new ("");
+ for (node = selection; node != NULL; node = node->next) {
+ uri = NULL;
+ if (NAUTILUS_IS_DESKTOP_ICON_FILE (node->data)) {
+ link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (node->data));
+ if (link != NULL) {
+ location = nautilus_desktop_link_get_activation_location (link);
+ uri = g_file_get_uri (location);
+ g_object_unref (location);
+ g_object_unref (G_OBJECT (link));
+ }
+ } else {
+ uri = nautilus_file_get_uri (NAUTILUS_FILE (node->data));
+ }
+ if (uri == NULL) {
+ continue;
+ }
+
+ if (get_paths) {
+ path = g_filename_from_uri (uri, NULL, NULL);
+ if (path != NULL) {
+ g_string_append (expanding_string, path);
+ g_free (path);
+ g_string_append (expanding_string, "\n");
+ }
+ } else {
+ g_string_append (expanding_string, uri);
+ g_string_append (expanding_string, "\n");
+ }
+ g_free (uri);
+ }
+
+ result = expanding_string->str;
+ g_string_free (expanding_string, FALSE);
+
+ return result;
+}
+
+static char *
+get_file_paths_as_newline_delimited_string (GList *selection)
+{
+ return get_file_paths_or_uris_as_newline_delimited_string (selection, TRUE);
+}
+
+static char *
+get_file_uris_as_newline_delimited_string (GList *selection)
+{
+ return get_file_paths_or_uris_as_newline_delimited_string (selection, FALSE);
+}
+
+/* returns newly allocated strings for setting the environment variables */
+static void
+get_strings_for_environment_variables (NautilusFilesView *view,
+ GList *selected_files,
+ char **file_paths,
+ char **uris,
+ char **uri)
+{
+ char *directory_uri;
+
+ /* We need to check that the directory uri starts with "file:" since
+ * nautilus_directory_is_local returns FALSE for nfs.
+ */
+ directory_uri = nautilus_directory_get_uri (view->details->model);
+ if (g_str_has_prefix (directory_uri, "file:") ||
+ eel_uri_is_desktop (directory_uri) ||
+ eel_uri_is_trash (directory_uri)) {
+ *file_paths = get_file_paths_as_newline_delimited_string (selected_files);
+ } else {
+ *file_paths = g_strdup ("");
+ }
+ g_free (directory_uri);
+
+ *uris = get_file_uris_as_newline_delimited_string (selected_files);
+
+ *uri = nautilus_directory_get_uri (view->details->model);
+ if (eel_uri_is_desktop (*uri)) {
+ g_free (*uri);
+ *uri = nautilus_get_desktop_directory_uri ();
+ }
+}
+
+/*
+ * Set up some environment variables that scripts can use
+ * to take advantage of the current Nautilus state.
+ */
+static void
+set_script_environment_variables (NautilusFilesView *view,
+ GList *selected_files)
+{
+ char *file_paths;
+ char *uris;
+ char *uri;
+ char *geometry_string;
+
+ get_strings_for_environment_variables (view, selected_files,
+ &file_paths, &uris, &uri);
+
+ g_setenv ("NAUTILUS_SCRIPT_SELECTED_FILE_PATHS", file_paths, TRUE);
+ g_free (file_paths);
+
+ g_setenv ("NAUTILUS_SCRIPT_SELECTED_URIS", uris, TRUE);
+ g_free (uris);
+
+ g_setenv ("NAUTILUS_SCRIPT_CURRENT_URI", uri, TRUE);
+ g_free (uri);
+
+ geometry_string = eel_gtk_window_get_geometry_string
+ (GTK_WINDOW (nautilus_files_view_get_containing_window (view)));
+ g_setenv ("NAUTILUS_SCRIPT_WINDOW_GEOMETRY", geometry_string, TRUE);
+ g_free (geometry_string);
+}
+
+/* Unset all the special script environment variables. */
+static void
+unset_script_environment_variables (void)
+{
+ g_unsetenv ("NAUTILUS_SCRIPT_SELECTED_FILE_PATHS");
+ g_unsetenv ("NAUTILUS_SCRIPT_SELECTED_URIS");
+ g_unsetenv ("NAUTILUS_SCRIPT_CURRENT_URI");
+ g_unsetenv ("NAUTILUS_SCRIPT_WINDOW_GEOMETRY");
+}
+
+static void
+run_script (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ ScriptLaunchParameters *launch_parameters;
+ GdkScreen *screen;
+ GList *selected_files;
+ char *file_uri;
+ char *local_file_path;
+ char *quoted_path;
+ char *old_working_dir;
+ char **parameters;
+
+ launch_parameters = (ScriptLaunchParameters *) user_data;
+
+ file_uri = nautilus_file_get_uri (launch_parameters->file);
+ local_file_path = g_filename_from_uri (file_uri, NULL, NULL);
+ g_assert (local_file_path != NULL);
+ g_free (file_uri);
+
+ quoted_path = g_shell_quote (local_file_path);
+ g_free (local_file_path);
+
+ old_working_dir = change_to_view_directory (launch_parameters->directory_view);
+
+ selected_files = nautilus_files_view_get_selection (launch_parameters->directory_view);
+ set_script_environment_variables (launch_parameters->directory_view, selected_files);
+
+ parameters = get_file_names_as_parameter_array (selected_files,
+ launch_parameters->directory_view->details->model);
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (launch_parameters->directory_view));
+
+ DEBUG ("run_script, script_path=“%s” (omitting script parameters)",
+ local_file_path);
+
+ nautilus_launch_application_from_command_array (screen, quoted_path, FALSE,
+ (const char * const *) parameters);
+ g_strfreev (parameters);
+
+ nautilus_file_list_free (selected_files);
+ unset_script_environment_variables ();
+ g_chdir (old_working_dir);
+ g_free (old_working_dir);
+ g_free (quoted_path);
+}
+
+static void
+add_script_to_scripts_menus (NautilusFilesView *view,
+ NautilusFile *file,
+ GMenu *menu)
+{
+ gchar *name;
+ GdkPixbuf *mimetype_icon;
+ gchar *action_name, *detailed_action_name;
+ ScriptLaunchParameters *launch_parameters;
+ GAction *action;
+ GMenuItem *menu_item;
+
+ launch_parameters = script_launch_parameters_new (file, view);
+
+ name = nautilus_file_get_display_name (file);
+ action_name = nautilus_escape_action_name (name, "script_");
+
+ action = G_ACTION (g_simple_action_new (action_name, NULL));
+
+ g_signal_connect_data (action, "activate",
+ G_CALLBACK (run_script),
+ launch_parameters,
+ (GClosureNotify)script_launch_parameters_free, 0);
+
+ g_action_map_add_action (G_ACTION_MAP (view->details->view_action_group), action);
+
+ g_object_unref (action);
+
+ detailed_action_name = g_strconcat ("view.", action_name, NULL);
+ menu_item = g_menu_item_new (name, detailed_action_name);
+
+ mimetype_icon = get_menu_icon_for_file (file, GTK_WIDGET (view));
+ if (mimetype_icon != NULL) {
+ g_menu_item_set_icon (menu_item, G_ICON (mimetype_icon));
+ g_object_unref (mimetype_icon);
+ }
+
+ g_menu_append_item (menu, menu_item);
+
+ g_free (name);
+ g_free (action_name);
+ g_free (detailed_action_name);
+ g_object_unref (menu_item);
+}
+
+static gboolean
+directory_belongs_in_scripts_menu (const char *uri)
+{
+ int num_levels;
+ int i;
+
+ if (!g_str_has_prefix (uri, scripts_directory_uri)) {
+ return FALSE;
+ }
+
+ num_levels = 0;
+ for (i = scripts_directory_uri_length; uri[i] != '\0'; i++) {
+ if (uri[i] == '/') {
+ num_levels++;
+ }
+ }
+
+ if (num_levels > MAX_MENU_LEVELS) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static GMenu *
+update_directory_in_scripts_menu (NautilusFilesView *view,
+ NautilusDirectory *directory)
+{
+ GList *file_list, *filtered, *node;
+ GMenu *menu, *children_menu;
+ GMenuItem *menu_item;
+ gboolean any_scripts;
+ NautilusFile *file;
+ NautilusDirectory *dir;
+ char *uri;
+ gchar *file_name;
+ int num;
+
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+
+ file_list = nautilus_directory_get_file_list (directory);
+ filtered = nautilus_file_list_filter_hidden (file_list, FALSE);
+ nautilus_file_list_free (file_list);
+ menu = g_menu_new ();
+
+ file_list = nautilus_file_list_sort_by_display_name (filtered);
+
+ num = 0;
+ any_scripts = FALSE;
+ for (node = file_list; num < TEMPLATE_LIMIT && node != NULL; node = node->next, num++) {
+ file = node->data;
+ if (nautilus_file_is_directory (file)) {
+ uri = nautilus_file_get_uri (file);
+ if (directory_belongs_in_scripts_menu (uri)) {
+ dir = nautilus_directory_get_by_uri (uri);
+ add_directory_to_scripts_directory_list (view, dir);
+
+ children_menu = update_directory_in_scripts_menu (view, dir);
+
+ if (children_menu != NULL) {
+ file_name = nautilus_file_get_display_name (file);
+ menu_item = g_menu_item_new_submenu (file_name,
+ G_MENU_MODEL (children_menu));
+ g_menu_append_item (menu, menu_item);
+ any_scripts = TRUE;
+ g_object_unref (menu_item);
+ g_object_unref (children_menu);
+ g_free (file_name);
+ }
+
+ nautilus_directory_unref (dir);
+ }
+ g_free (uri);
+ } else if (nautilus_file_is_launchable (file)) {
+ add_script_to_scripts_menus (view, file, menu);
+ any_scripts = TRUE;
+ }
+ }
+
+ nautilus_file_list_free (file_list);
+
+ if (!any_scripts) {
+ g_object_unref (menu);
+ menu = NULL;
+ }
+
+ return menu;
+}
+
+
+
+static void
+update_scripts_menu (NautilusFilesView *view)
+{
+ GList *sorted_copy, *node;
+ NautilusDirectory *directory;
+ GMenu *submenu;
+ char *uri;
+
+ sorted_copy = nautilus_directory_list_sort_by_uri
+ (nautilus_directory_list_copy (view->details->scripts_directory_list));
+
+ for (node = sorted_copy; node != NULL; node = node->next) {
+ directory = node->data;
+
+ uri = nautilus_directory_get_uri (directory);
+ if (!directory_belongs_in_scripts_menu (uri)) {
+ remove_directory_from_scripts_directory_list (view, directory);
+ }
+ g_free (uri);
+ }
+ nautilus_directory_list_free (sorted_copy);
+
+ directory = nautilus_directory_get_by_uri (scripts_directory_uri);
+ submenu = update_directory_in_scripts_menu (view, directory);
+ if (submenu != NULL) {
+ nautilus_gmenu_merge (view->details->selection_menu,
+ submenu,
+ "scripts-submenu",
+ TRUE);
+ g_object_unref (submenu);
+ }
+
+ view->details->scripts_present = submenu != NULL;
+}
+
+static void
+create_template (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+
+ CreateTemplateParameters *parameters;
+
+ parameters = user_data;
+
+ nautilus_files_view_new_file (parameters->directory_view, NULL, parameters->file);
+}
+
+static void
+add_template_to_templates_menus (NautilusFilesView *view,
+ NautilusFile *file,
+ GMenu *menu)
+{
+ char *tmp, *uri, *name;
+ GdkPixbuf *mimetype_icon;
+ char *action_name, *detailed_action_name;
+ CreateTemplateParameters *parameters;
+ GAction *action;
+ GMenuItem *menu_item;
+
+ tmp = nautilus_file_get_display_name (file);
+ name = eel_filename_strip_extension (tmp);
+ g_free (tmp);
+
+ uri = nautilus_file_get_uri (file);
+ action_name = nautilus_escape_action_name (uri, "template_");
+ action = G_ACTION (g_simple_action_new (action_name, NULL));
+ parameters = create_template_parameters_new (file, view);
+
+ g_signal_connect_data (action, "activate",
+ G_CALLBACK (create_template),
+ parameters,
+ (GClosureNotify)create_templates_parameters_free, 0);
+
+ g_action_map_add_action (G_ACTION_MAP (view->details->view_action_group), action);
+
+ detailed_action_name = g_strconcat ("view.", action_name, NULL);
+ menu_item = g_menu_item_new (name, detailed_action_name);
+
+ mimetype_icon = get_menu_icon_for_file (file, GTK_WIDGET (view));
+ if (mimetype_icon != NULL) {
+ g_menu_item_set_icon (menu_item, G_ICON (mimetype_icon));
+ g_object_unref (mimetype_icon);
+ }
+
+ g_menu_append_item (menu, menu_item);
+
+ g_free (name);
+ g_free (uri);
+ g_free (action_name);
+ g_free (detailed_action_name);
+ g_object_unref (action);
+ g_object_unref (menu_item);
+}
+
+static void
+update_templates_directory (NautilusFilesView *view)
+{
+ NautilusDirectory *templates_directory;
+ GList *node, *next;
+ char *templates_uri;
+
+ for (node = view->details->templates_directory_list; node != NULL; node = next) {
+ next = node->next;
+ remove_directory_from_templates_directory_list (view, node->data);
+ }
+
+ if (nautilus_should_use_templates_directory ()) {
+ templates_uri = nautilus_get_templates_directory_uri ();
+ templates_directory = nautilus_directory_get_by_uri (templates_uri);
+ g_free (templates_uri);
+ add_directory_to_templates_directory_list (view, templates_directory);
+ nautilus_directory_unref (templates_directory);
+ }
+}
+
+static gboolean
+directory_belongs_in_templates_menu (const char *templates_directory_uri,
+ const char *uri)
+{
+ int num_levels;
+ int i;
+
+ if (templates_directory_uri == NULL) {
+ return FALSE;
+ }
+
+ if (!g_str_has_prefix (uri, templates_directory_uri)) {
+ return FALSE;
+ }
+
+ num_levels = 0;
+ for (i = strlen (templates_directory_uri); uri[i] != '\0'; i++) {
+ if (uri[i] == '/') {
+ num_levels++;
+ }
+ }
+
+ if (num_levels > MAX_MENU_LEVELS) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static GMenu *
+update_directory_in_templates_menu (NautilusFilesView *view,
+ NautilusDirectory *directory)
+{
+ GList *file_list, *filtered, *node;
+ GMenu *menu, *children_menu;
+ GMenuItem *menu_item;
+ gboolean any_templates;
+ NautilusFile *file;
+ NautilusDirectory *dir;
+ char *uri;
+ char *templates_directory_uri;
+ int num;
+
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+
+ file_list = nautilus_directory_get_file_list (directory);
+ filtered = nautilus_file_list_filter_hidden (file_list, FALSE);
+ nautilus_file_list_free (file_list);
+ templates_directory_uri = nautilus_get_templates_directory_uri ();
+ menu = g_menu_new ();
+
+ file_list = nautilus_file_list_sort_by_display_name (filtered);
+
+ num = 0;
+ any_templates = FALSE;
+ for (node = file_list; num < TEMPLATE_LIMIT && node != NULL; node = node->next, num++) {
+ file = node->data;
+ if (nautilus_file_is_directory (file)) {
+ uri = nautilus_file_get_uri (file);
+ if (directory_belongs_in_templates_menu (templates_directory_uri, uri)) {
+ dir = nautilus_directory_get_by_uri (uri);
+ add_directory_to_templates_directory_list (view, dir);
+
+ children_menu = update_directory_in_templates_menu (view, dir);
+
+ if (children_menu != NULL) {
+ menu_item = g_menu_item_new_submenu (nautilus_file_get_display_name (file),
+ G_MENU_MODEL (children_menu));
+ g_menu_append_item (menu, menu_item);
+ any_templates = TRUE;
+ g_object_unref (menu_item);
+ g_object_unref (children_menu);
+ }
+
+ nautilus_directory_unref (dir);
+ }
+ g_free (uri);
+ } else if (nautilus_file_can_read (file)) {
+ add_template_to_templates_menus (view, file, menu);
+ any_templates = TRUE;
+ }
+ }
+
+ nautilus_file_list_free (file_list);
+ g_free (templates_directory_uri);
+
+ if (!any_templates) {
+ g_object_unref (menu);
+ menu = NULL;
+ }
+
+ return menu;
+}
+
+
+
+static void
+update_templates_menu (NautilusFilesView *view)
+{
+ GList *sorted_copy, *node;
+ NautilusDirectory *directory;
+ GMenu *submenu;
+ char *uri;
+ char *templates_directory_uri;
+
+ if (nautilus_should_use_templates_directory ()) {
+ templates_directory_uri = nautilus_get_templates_directory_uri ();
+ } else {
+ view->details->templates_present = FALSE;
+ return;
+ }
+
+
+ sorted_copy = nautilus_directory_list_sort_by_uri
+ (nautilus_directory_list_copy (view->details->templates_directory_list));
+
+ for (node = sorted_copy; node != NULL; node = node->next) {
+ directory = node->data;
+
+ uri = nautilus_directory_get_uri (directory);
+ if (!directory_belongs_in_templates_menu (templates_directory_uri, uri)) {
+ remove_directory_from_templates_directory_list (view, directory);
+ }
+ g_free (uri);
+ }
+ nautilus_directory_list_free (sorted_copy);
+
+ directory = nautilus_directory_get_by_uri (templates_directory_uri);
+ submenu = update_directory_in_templates_menu (view, directory);
+ if (submenu != NULL) {
+ nautilus_gmenu_merge (view->details->background_menu,
+ submenu,
+ "templates-submenu",
+ FALSE);
+ g_object_unref (submenu);
+ }
+
+ view->details->templates_present = submenu != NULL;
+
+ g_free (templates_directory_uri);
+}
+
+
+static void
+action_open_scripts_folder (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ static GFile *location = NULL;
+
+ if (location == NULL) {
+ location = g_file_new_for_uri (scripts_directory_uri);
+ }
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ nautilus_window_slot_open_location (view->details->slot, location, 0);
+}
+
+typedef struct _CopyCallbackData {
+ NautilusFilesView *view;
+ GtkFileChooser *chooser;
+ GHashTable *locations;
+ GList *selection;
+ gboolean is_move;
+} CopyCallbackData;
+
+static void
+add_bookmark_for_uri (CopyCallbackData *data,
+ const char *uri)
+{
+ GError *error = NULL;
+ int count;
+
+ count = GPOINTER_TO_INT (g_hash_table_lookup (data->locations, uri));
+ if (count == 0) {
+ gtk_file_chooser_add_shortcut_folder_uri (data->chooser,
+ uri,
+ &error);
+ if (error != NULL) {
+ DEBUG ("Unable to add location '%s' to file selector: %s", uri, error->message);
+ g_clear_error (&error);
+ }
+ }
+ g_hash_table_replace (data->locations, g_strdup (uri), GINT_TO_POINTER (count + 1));
+}
+
+static void
+remove_bookmark_for_uri (CopyCallbackData *data,
+ const char *uri)
+{
+ GError *error = NULL;
+ int count;
+
+ count = GPOINTER_TO_INT (g_hash_table_lookup (data->locations, uri));
+ if (count == 1) {
+ gtk_file_chooser_remove_shortcut_folder_uri (data->chooser,
+ uri,
+ &error);
+ if (error != NULL) {
+ DEBUG ("Unable to remove location '%s' to file selector: %s", uri, error->message);
+ g_clear_error (&error);
+ }
+ g_hash_table_remove (data->locations, uri);
+ } else {
+ g_hash_table_replace (data->locations, g_strdup (uri), GINT_TO_POINTER (count - 1));
+ }
+}
+
+static void
+add_bookmarks_for_window_slot (CopyCallbackData *data,
+ NautilusWindowSlot *slot)
+{
+ char *uri;
+
+ uri = nautilus_window_slot_get_location_uri (slot);
+ if (uri != NULL) {
+ add_bookmark_for_uri (data, uri);
+ }
+ g_free (uri);
+}
+
+static void
+remove_bookmarks_for_window_slot (CopyCallbackData *data,
+ NautilusWindowSlot *slot)
+{
+ char *uri;
+
+ uri = nautilus_window_slot_get_location_uri (slot);
+ if (uri != NULL) {
+ remove_bookmark_for_uri (data, uri);
+ }
+ g_free (uri);
+}
+
+static void
+on_slot_location_changed (NautilusWindowSlot *slot,
+ const char *from,
+ const char *to,
+ CopyCallbackData *data)
+{
+ if (from != NULL) {
+ remove_bookmark_for_uri (data, from);
+ }
+
+ if (to != NULL) {
+ add_bookmark_for_uri (data, to);
+ }
+}
+
+static void
+on_slot_added (NautilusWindow *window,
+ NautilusWindowSlot *slot,
+ CopyCallbackData *data)
+{
+ add_bookmarks_for_window_slot (data, slot);
+ g_signal_connect (slot, "location-changed", G_CALLBACK (on_slot_location_changed), data);
+}
+
+static void
+on_slot_removed (NautilusWindow *window,
+ NautilusWindowSlot *slot,
+ CopyCallbackData *data)
+{
+ remove_bookmarks_for_window_slot (data, slot);
+ g_signal_handlers_disconnect_by_func (slot,
+ G_CALLBACK (on_slot_location_changed),
+ data);
+}
+
+static void
+add_bookmarks_for_window (CopyCallbackData *data,
+ NautilusWindow *window)
+{
+ GList *s;
+ GList *slots;
+
+ slots = nautilus_window_get_slots (window);
+ for (s = slots; s != NULL; s = s->next) {
+ NautilusWindowSlot *slot = s->data;
+ add_bookmarks_for_window_slot (data, slot);
+ g_signal_connect (slot, "location-changed", G_CALLBACK (on_slot_location_changed), data);
+ }
+ g_signal_connect (window, "slot-added", G_CALLBACK (on_slot_added), data);
+ g_signal_connect (window, "slot-removed", G_CALLBACK (on_slot_removed), data);
+}
+
+static void
+remove_bookmarks_for_window (CopyCallbackData *data,
+ NautilusWindow *window)
+{
+ GList *s;
+ GList *slots;
+
+ slots = nautilus_window_get_slots (window);
+ for (s = slots; s != NULL; s = s->next) {
+ NautilusWindowSlot *slot = s->data;
+ remove_bookmarks_for_window_slot (data, slot);
+ g_signal_handlers_disconnect_by_func (slot,
+ G_CALLBACK (on_slot_location_changed),
+ data);
+ }
+ g_signal_handlers_disconnect_by_func (window,
+ G_CALLBACK (on_slot_added),
+ data);
+ g_signal_handlers_disconnect_by_func (window,
+ G_CALLBACK (on_slot_removed),
+ data);
+}
+
+static void
+on_app_window_added (GtkApplication *application,
+ GtkWindow *window,
+ CopyCallbackData *data)
+{
+ add_bookmarks_for_window (data, NAUTILUS_WINDOW (window));
+}
+
+static void
+on_app_window_removed (GtkApplication *application,
+ GtkWindow *window,
+ CopyCallbackData *data)
+{
+ remove_bookmarks_for_window (data, NAUTILUS_WINDOW (window));
+}
+
+static void
+copy_data_free (CopyCallbackData *data)
+{
+ NautilusApplication *application;
+ GList *windows;
+ GList *w;
+
+ application = NAUTILUS_APPLICATION (g_application_get_default ());
+ g_signal_handlers_disconnect_by_func (application,
+ G_CALLBACK (on_app_window_added),
+ data);
+ g_signal_handlers_disconnect_by_func (application,
+ G_CALLBACK (on_app_window_removed),
+ data);
+
+ windows = nautilus_application_get_windows (application);
+ for (w = windows; w != NULL; w = w->next) {
+ NautilusWindow *window = w->data;
+ GList *slots;
+ GList *s;
+
+ slots = nautilus_window_get_slots (window);
+ for (s = slots; s != NULL; s = s->next) {
+ NautilusWindowSlot *slot = s->data;
+ g_signal_handlers_disconnect_by_func (slot, G_CALLBACK (on_slot_location_changed), data);
+ }
+ g_signal_handlers_disconnect_by_func (window, G_CALLBACK (on_slot_added), data);
+ g_signal_handlers_disconnect_by_func (window, G_CALLBACK (on_slot_removed), data);
+ }
+
+ nautilus_file_list_free (data->selection);
+ g_hash_table_destroy (data->locations);
+ g_free (data);
+}
+
+static gboolean
+uri_is_parent_of_selection (GList *selection,
+ const char *uri)
+{
+ gboolean found;
+ GList *l;
+ GFile *file;
+
+ found = FALSE;
+
+ file = g_file_new_for_uri (uri);
+ for (l = selection; !found && l != NULL; l = l->next) {
+ GFile *parent;
+ parent = nautilus_file_get_parent_location (l->data);
+ found = g_file_equal (file, parent);
+ g_object_unref (parent);
+ }
+ g_object_unref (file);
+ return found;
+}
+
+static void
+on_destination_dialog_folder_changed (GtkFileChooser *chooser,
+ gpointer user_data)
+{
+ CopyCallbackData *copy_data = user_data;
+ char *uri;
+ gboolean found;
+
+ uri = gtk_file_chooser_get_current_folder_uri (chooser);
+ found = uri_is_parent_of_selection (copy_data->selection, uri);
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser), GTK_RESPONSE_OK, !found);
+ g_free (uri);
+}
+
+static void
+on_destination_dialog_response (GtkDialog *dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ CopyCallbackData *copy_data = user_data;
+
+ if (response_id == GTK_RESPONSE_OK) {
+ char *target_uri;
+ GList *uris, *l;
+
+ target_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+
+ uris = NULL;
+ for (l = copy_data->selection; l != NULL; l = l->next) {
+ uris = g_list_prepend (uris,
+ nautilus_file_get_uri ((NautilusFile *) l->data));
+ }
+ uris = g_list_reverse (uris);
+
+ nautilus_files_view_move_copy_items (copy_data->view, uris, NULL, target_uri,
+ copy_data->is_move ? GDK_ACTION_MOVE : GDK_ACTION_COPY,
+ 0, 0);
+
+ g_list_free_full (uris, g_free);
+ g_free (target_uri);
+ }
+
+ copy_data_free (copy_data);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static gboolean
+destination_dialog_filter_cb (const GtkFileFilterInfo *filter_info,
+ gpointer user_data)
+{
+ GList *selection = user_data;
+ GList *l;
+
+ for (l = selection; l != NULL; l = l->next) {
+ char *uri;
+ uri = nautilus_file_get_uri (l->data);
+ if (strcmp (uri, filter_info->uri) == 0) {
+ g_free (uri);
+ return FALSE;
+ }
+ g_free (uri);
+ }
+
+ return TRUE;
+}
+
+static GList *
+get_selected_folders (GList *selection)
+{
+ GList *folders;
+ GList *l;
+
+ folders = NULL;
+ for (l = selection; l != NULL; l = l->next) {
+ if (nautilus_file_is_directory (l->data))
+ folders = g_list_prepend (folders, nautilus_file_ref (l->data));
+ }
+ return g_list_reverse (folders);
+}
+
+static void
+add_window_location_bookmarks (CopyCallbackData *data)
+{
+ NautilusApplication *application;
+ GList *windows;
+ GList *w;
+
+ application = NAUTILUS_APPLICATION (g_application_get_default ());
+ windows = nautilus_application_get_windows (application);
+ g_signal_connect (application, "window-added", G_CALLBACK (on_app_window_added), data);
+ g_signal_connect (application, "window-removed", G_CALLBACK (on_app_window_removed), data);
+
+ for (w = windows; w != NULL; w = w->next) {
+ NautilusWindow *window = w->data;
+ add_bookmarks_for_window (data, window);
+ }
+}
+
+static void
+copy_or_move_selection (NautilusFilesView *view,
+ gboolean is_move)
+{
+ GtkWidget *dialog;
+ char *uri;
+ CopyCallbackData *copy_data;
+ GList *selection;
+ const gchar *title;
+
+ if (is_move) {
+ title = _("Select Move Destination");
+ } else {
+ title = _("Select Copy Destination");
+ }
+
+ selection = nautilus_files_view_get_selection_for_file_transfer (view);
+
+ dialog = gtk_file_chooser_dialog_new (title,
+ GTK_WINDOW (nautilus_files_view_get_window (view)),
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("_Select"), GTK_RESPONSE_OK,
+ NULL);
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ copy_data = g_new0 (CopyCallbackData, 1);
+ copy_data->view = view;
+ copy_data->selection = selection;
+ copy_data->is_move = is_move;
+ copy_data->chooser = GTK_FILE_CHOOSER (dialog);
+ copy_data->locations = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ add_window_location_bookmarks (copy_data);
+
+ if (selection != NULL) {
+ GtkFileFilter *filter;
+ GList *folders;
+
+ folders = get_selected_folders (selection);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_add_custom (filter,
+ GTK_FILE_FILTER_URI,
+ destination_dialog_filter_cb,
+ folders,
+ (GDestroyNotify)nautilus_file_list_free);
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
+ }
+
+ uri = nautilus_directory_get_uri (view->details->model);
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), uri);
+ g_free (uri);
+ g_signal_connect (dialog, "current-folder-changed",
+ G_CALLBACK (on_destination_dialog_folder_changed),
+ copy_data);
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (on_destination_dialog_response),
+ copy_data);
+
+ gtk_widget_show_all (dialog);
+}
+
+static void
+copy_or_cut_files (NautilusFilesView *view,
+ GList *clipboard_contents,
+ gboolean cut)
+{
+ NautilusClipboardInfo info;
+ GtkTargetList *target_list;
+ GtkTargetEntry *targets;
+ int n_targets;
+
+ info.files = clipboard_contents;
+ info.cut = cut;
+
+ target_list = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add (target_list, copied_files_atom, 0, 0);
+ gtk_target_list_add_uri_targets (target_list, 0);
+ gtk_target_list_add_text_targets (target_list, 0);
+
+ targets = gtk_target_table_new_from_list (target_list, &n_targets);
+ gtk_target_list_unref (target_list);
+
+ gtk_clipboard_set_with_data (nautilus_clipboard_get (GTK_WIDGET (view)),
+ targets, n_targets,
+ nautilus_get_clipboard_callback, nautilus_clear_clipboard_callback,
+ NULL);
+ gtk_target_table_free (targets, n_targets);
+
+ nautilus_clipboard_monitor_set_clipboard_info (nautilus_clipboard_monitor_get (), &info);
+}
+
+static void
+action_copy (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ GList *selection;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection_for_file_transfer (view);
+ copy_or_cut_files (view, selection, FALSE);
+ nautilus_file_list_free (selection);
+}
+
+static void
+action_cut (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ GList *selection;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection_for_file_transfer (view);
+ copy_or_cut_files (view, selection, TRUE);
+ nautilus_file_list_free (selection);
+}
+
+static void
+action_copy_to (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ copy_or_move_selection (view, FALSE);
+}
+
+static void
+action_move_to (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ copy_or_move_selection (view, TRUE);
+}
+
+typedef struct {
+ NautilusFilesView *view;
+ NautilusFile *target;
+} PasteIntoData;
+
+static void
+paste_into_clipboard_received_callback (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer callback_data)
+{
+ PasteIntoData *data;
+ NautilusFilesView *view;
+ char *directory_uri;
+
+ data = (PasteIntoData *) callback_data;
+
+ view = NAUTILUS_FILES_VIEW (data->view);
+
+ if (view->details->slot != NULL) {
+ directory_uri = nautilus_file_get_activation_uri (data->target);
+
+ paste_clipboard_data (view, selection_data, directory_uri);
+
+ g_free (directory_uri);
+ }
+
+ g_object_unref (view);
+ nautilus_file_unref (data->target);
+ g_free (data);
+}
+
+static void
+paste_into (NautilusFilesView *view,
+ NautilusFile *target)
+{
+ PasteIntoData *data;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+ g_assert (NAUTILUS_IS_FILE (target));
+
+ data = g_new (PasteIntoData, 1);
+
+ data->view = g_object_ref (view);
+ data->target = nautilus_file_ref (target);
+
+ gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
+ copied_files_atom,
+ paste_into_clipboard_received_callback,
+ data);
+}
+
+static void
+action_paste_files_into (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ GList *selection;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ selection = nautilus_files_view_get_selection (view);
+ if (selection != NULL) {
+ paste_into (view, NAUTILUS_FILE (selection->data));
+ nautilus_file_list_free (selection);
+ }
+
+}
+
+static void
+invoke_external_bulk_rename_utility (NautilusFilesView *view,
+ GList *selection)
+{
+ GString *cmd;
+ char *parameter;
+ char *quoted_parameter;
+ char *bulk_rename_tool;
+ GList *walk;
+ NautilusFile *file;
+
+ /* assemble command line */
+ bulk_rename_tool = get_bulk_rename_tool ();
+ cmd = g_string_new (bulk_rename_tool);
+ g_free (bulk_rename_tool);
+ for (walk = selection; walk; walk = walk->next) {
+ file = walk->data;
+ parameter = nautilus_file_get_uri (file);
+ quoted_parameter = g_shell_quote (parameter);
+ g_free (parameter);
+ cmd = g_string_append (cmd, " ");
+ cmd = g_string_append (cmd, quoted_parameter);
+ g_free (quoted_parameter);
+ }
+
+ /* spawning and error handling */
+ nautilus_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (view)),
+ cmd->str, FALSE, NULL);
+ g_string_free (cmd, TRUE);
+}
+
+static void
+real_action_rename (NautilusFilesView *view,
+ gboolean select_all)
+{
+ NautilusFile *file;
+ GList *selection;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ selection = nautilus_files_view_get_selection (view);
+
+ if (selection_not_empty_in_menu_callback (view, selection)) {
+ /* If there is more than one file selected, invoke a batch renamer */
+ if (selection->next != NULL) {
+ if (have_bulk_rename_tool ()) {
+ invoke_external_bulk_rename_utility (view, selection);
+ }
+ } else {
+ file = NAUTILUS_FILE (selection->data);
+ if (!select_all) {
+ /* directories don't have a file extension, so
+ * they are always pre-selected as a whole */
+ select_all = nautilus_file_is_directory (file);
+ }
+ nautilus_files_view_rename_file_popover_new (view, file);
+ }
+ }
+
+ nautilus_file_list_free (selection);
+}
+
+static void
+action_rename (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ real_action_rename (NAUTILUS_FILES_VIEW (user_data), FALSE);
+}
+
+#define BG_KEY_PRIMARY_COLOR "primary-color"
+#define BG_KEY_SECONDARY_COLOR "secondary-color"
+#define BG_KEY_COLOR_TYPE "color-shading-type"
+#define BG_KEY_PICTURE_PLACEMENT "picture-options"
+#define BG_KEY_PICTURE_URI "picture-uri"
+
+static void
+set_uri_as_wallpaper (const char *uri)
+{
+ GSettings *settings;
+
+ settings = gnome_background_preferences;
+
+ g_settings_delay (settings);
+
+ if (uri == NULL)
+ uri = "";
+
+ g_settings_set_string (settings, BG_KEY_PICTURE_URI, uri);
+ g_settings_set_string (settings, BG_KEY_PRIMARY_COLOR, "#000000");
+ g_settings_set_string (settings, BG_KEY_SECONDARY_COLOR, "#000000");
+ g_settings_set_enum (settings, BG_KEY_COLOR_TYPE, G_DESKTOP_BACKGROUND_SHADING_SOLID);
+ g_settings_set_enum (settings, BG_KEY_PICTURE_PLACEMENT, G_DESKTOP_BACKGROUND_STYLE_ZOOM);
+
+ /* Apply changes atomically. */
+ g_settings_apply (settings);
+}
+
+static void
+wallpaper_copy_done_callback (GHashTable *debuting_files,
+ gboolean success,
+ gpointer data)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init (&iter, debuting_files);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ char *uri;
+ uri = g_file_get_uri (G_FILE (key));
+ set_uri_as_wallpaper (uri);
+ g_free (uri);
+ break;
+ }
+}
+
+static gboolean
+can_set_wallpaper (GList *selection)
+{
+ NautilusFile *file;
+
+ if (g_list_length (selection) != 1) {
+ return FALSE;
+ }
+
+ file = NAUTILUS_FILE (selection->data);
+ if (!nautilus_file_is_mime_type (file, "image/*")) {
+ return FALSE;
+ }
+
+ /* FIXME: check file size? */
+
+ return TRUE;
+}
+
+static void
+action_set_as_wallpaper (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ GList *selection;
+
+ /* Copy the item to Pictures/Wallpaper since it may be
+ remote. Then set it as the current wallpaper. */
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+ selection = nautilus_files_view_get_selection (user_data);
+
+ if (can_set_wallpaper (selection)
+ && selection_not_empty_in_menu_callback (user_data, selection)) {
+ NautilusFile *file;
+ char *target_uri;
+ GList *uris;
+ GFile *parent;
+ GFile *target;
+
+ file = NAUTILUS_FILE (selection->data);
+
+ parent = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_PICTURES));
+ target = g_file_get_child (parent, "Wallpapers");
+ g_object_unref (parent);
+ g_file_make_directory_with_parents (target, NULL, NULL);
+ target_uri = g_file_get_uri (target);
+ g_object_unref (target);
+ uris = g_list_prepend (NULL, nautilus_file_get_uri (file));
+ nautilus_file_operations_copy_move (uris,
+ NULL,
+ target_uri,
+ GDK_ACTION_COPY,
+ GTK_WIDGET (user_data),
+ wallpaper_copy_done_callback,
+ NULL);
+ g_free (target_uri);
+ g_list_free_full (uris, g_free);
+ }
+
+ nautilus_file_list_free (selection);
+}
+
+static void
+file_mount_callback (NautilusFile *file,
+ GFile *result_location,
+ GError *error,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ if (error != NULL &&
+ (error->domain != G_IO_ERROR ||
+ (error->code != G_IO_ERROR_CANCELLED &&
+ error->code != G_IO_ERROR_FAILED_HANDLED &&
+ error->code != G_IO_ERROR_ALREADY_MOUNTED))) {
+ char *text;
+ char *name;
+ name = nautilus_file_get_display_name (file);
+ /* Translators: %s is a file name formatted for display */
+ text = g_strdup_printf (_("Unable to access “%s”"), name);
+ eel_show_error_dialog (text, error->message,
+ GTK_WINDOW (nautilus_files_view_get_window (view)));
+ g_free (text);
+ g_free (name);
+ }
+}
+
+static void
+file_unmount_callback (NautilusFile *file,
+ GFile *result_location,
+ GError *error,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+ g_object_unref (view);
+
+ if (error != NULL &&
+ (error->domain != G_IO_ERROR ||
+ (error->code != G_IO_ERROR_CANCELLED &&
+ error->code != G_IO_ERROR_FAILED_HANDLED))) {
+ char *text;
+ char *name;
+ name = nautilus_file_get_display_name (file);
+ /* Translators: %s is a file name formatted for display */
+ text = g_strdup_printf (_("Unable to remove “%s”"), name);
+ eel_show_error_dialog (text, error->message,
+ GTK_WINDOW (nautilus_files_view_get_window (view)));
+ g_free (text);
+ g_free (name);
+ }
+}
+
+static void
+file_eject_callback (NautilusFile *file,
+ GFile *result_location,
+ GError *error,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+ g_object_unref (view);
+
+ if (error != NULL &&
+ (error->domain != G_IO_ERROR ||
+ (error->code != G_IO_ERROR_CANCELLED &&
+ error->code != G_IO_ERROR_FAILED_HANDLED))) {
+ char *text;
+ char *name;
+ name = nautilus_file_get_display_name (file);
+ /* Translators: %s is a file name formatted for display */
+ text = g_strdup_printf (_("Unable to eject “%s”"), name);
+ eel_show_error_dialog (text, error->message,
+ GTK_WINDOW (nautilus_files_view_get_window (view)));
+ g_free (text);
+ g_free (name);
+ }
+}
+
+static void
+file_stop_callback (NautilusFile *file,
+ GFile *result_location,
+ GError *error,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ if (error != NULL &&
+ (error->domain != G_IO_ERROR ||
+ (error->code != G_IO_ERROR_CANCELLED &&
+ error->code != G_IO_ERROR_FAILED_HANDLED))) {
+ eel_show_error_dialog (_("Unable to stop drive"),
+ error->message,
+ GTK_WINDOW (nautilus_files_view_get_window (view)));
+ }
+}
+
+static void
+action_mount_volume (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFile *file;
+ GList *selection, *l;
+ NautilusFilesView *view;
+ GMountOperation *mount_op;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection (view);
+ for (l = selection; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ if (nautilus_file_can_mount (file)) {
+ mount_op = gtk_mount_operation_new (nautilus_files_view_get_containing_window (view));
+ g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
+ nautilus_file_mount (file, mount_op, NULL,
+ file_mount_callback,
+ view);
+ g_object_unref (mount_op);
+ }
+ }
+ nautilus_file_list_free (selection);
+}
+
+static void
+action_unmount_volume (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFile *file;
+ GList *selection, *l;
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection (view);
+
+ for (l = selection; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+ if (nautilus_file_can_unmount (file)) {
+ GMountOperation *mount_op;
+ mount_op = gtk_mount_operation_new (nautilus_files_view_get_containing_window (view));
+ nautilus_file_unmount (file, mount_op, NULL,
+ file_unmount_callback, g_object_ref (view));
+ g_object_unref (mount_op);
+ }
+ }
+ nautilus_file_list_free (selection);
+}
+
+static void
+action_eject_volume (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFile *file;
+ GList *selection, *l;
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection (view);
+ for (l = selection; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ if (nautilus_file_can_eject (file)) {
+ GMountOperation *mount_op;
+ mount_op = gtk_mount_operation_new (nautilus_files_view_get_containing_window (view));
+ nautilus_file_eject (file, mount_op, NULL,
+ file_eject_callback, g_object_ref (view));
+ g_object_unref (mount_op);
+ }
+ }
+ nautilus_file_list_free (selection);
+}
+
+static void
+file_start_callback (NautilusFile *file,
+ GFile *result_location,
+ GError *error,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (callback_data);
+
+ if (error != NULL &&
+ (error->domain != G_IO_ERROR ||
+ (error->code != G_IO_ERROR_CANCELLED &&
+ error->code != G_IO_ERROR_FAILED_HANDLED &&
+ error->code != G_IO_ERROR_ALREADY_MOUNTED))) {
+ char *text;
+ char *name;
+ name = nautilus_file_get_display_name (file);
+ /* Translators: %s is a file name formatted for display */
+ text = g_strdup_printf (_("Unable to start “%s”"), name);
+ eel_show_error_dialog (text, error->message,
+ GTK_WINDOW (nautilus_files_view_get_window (view)));
+ g_free (text);
+ g_free (name);
+ }
+}
+
+static void
+action_start_volume (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFile *file;
+ GList *selection, *l;
+ NautilusFilesView *view;
+ GMountOperation *mount_op;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection (view);
+ for (l = selection; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ if (nautilus_file_can_start (file) || nautilus_file_can_start_degraded (file)) {
+ mount_op = gtk_mount_operation_new (nautilus_files_view_get_containing_window (view));
+ nautilus_file_start (file, mount_op, NULL,
+ file_start_callback, view);
+ g_object_unref (mount_op);
+ }
+ }
+ nautilus_file_list_free (selection);
+}
+
+static void
+action_stop_volume (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFile *file;
+ GList *selection, *l;
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection (view);
+ for (l = selection; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ if (nautilus_file_can_stop (file)) {
+ GMountOperation *mount_op;
+ mount_op = gtk_mount_operation_new (nautilus_files_view_get_containing_window (view));
+ nautilus_file_stop (file, mount_op, NULL,
+ file_stop_callback, view);
+ g_object_unref (mount_op);
+ }
+ }
+ nautilus_file_list_free (selection);
+}
+
+static void
+action_detect_media (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ NautilusFile *file;
+ GList *selection, *l;
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+
+ selection = nautilus_files_view_get_selection (view);
+ for (l = selection; l != NULL; l = l->next) {
+ file = NAUTILUS_FILE (l->data);
+
+ if (nautilus_file_can_poll_for_media (file) && !nautilus_file_is_media_check_automatic (file)) {
+ nautilus_file_poll_for_media (file);
+ }
+ }
+ nautilus_file_list_free (selection);
+}
+
+const GActionEntry view_entries[] = {
+ /* Toolbar menu */
+ { "zoom-in", action_zoom_in },
+ { "zoom-out", action_zoom_out },
+ { "zoom-default", action_zoom_default },
+ { "show-hidden-files", NULL, NULL, "true", action_show_hidden_files },
+ /* Background menu */
+ { "new-folder", action_new_folder },
+ { "select-all", action_select_all },
+ { "paste", action_paste_files },
+ { "new-document" },
+ /* Selection menu */
+ { "scripts" },
+ { "new-folder-with-selection", action_new_folder_with_selection },
+ { "open-scripts-folder", action_open_scripts_folder },
+ { "open-item-location", action_open_item_location },
+ { "open-with-default-application", action_open_with_default_application },
+ { "open-with-other-application", action_open_with_other_application },
+ { "open-item-new-window", action_open_item_new_window },
+ { "open-item-new-tab", action_open_item_new_tab },
+ { "cut", action_cut},
+ { "copy", action_copy},
+ { "move-to", action_move_to},
+ { "copy-to", action_copy_to},
+ { "move-to-trash", action_move_to_trash},
+ { "delete-from-trash", action_delete },
+ /* We separate the shortcut and the menu item since we want the shortcut
+ * to always be available, but we don't want the menu item shown if not
+ * completely necesary. Since the visibility of the menu item is based on
+ * the action enability, we need to split the actions for the menu and the
+ * shortcut. */
+ { "delete-permanently-shortcut", action_delete },
+ { "delete-permanently-menu-item", action_delete },
+ { "remove-from-recent", action_remove_from_recent },
+ { "restore-from-trash", action_restore_from_trash},
+ { "paste-into", action_paste_files_into },
+ { "rename", action_rename},
+ { "properties", action_properties},
+ { "set-as-wallpaper", action_set_as_wallpaper },
+ { "mount-volume", action_mount_volume },
+ { "unmount-volume", action_unmount_volume },
+ { "eject-volume", action_eject_volume },
+ { "start-volume", action_start_volume },
+ { "stop-volume", action_stop_volume },
+ { "detect-media", action_detect_media },
+ /* Only accesible by shorcuts */
+ { "select-pattern", action_select_pattern },
+ { "invert-selection", action_invert_selection },
+ { "open-file-and-close-window", action_open_file_and_close_window },
+ /* Warning dialog for the change of the shorcut to move to trash */
+ { "show-move-to-trash-shortcut-changed-dialog", action_show_move_to_trash_shortcut_changed_dialog }
+};
+
+static gboolean
+can_paste_into_file (NautilusFile *file)
+{
+ if (nautilus_file_is_directory (file) &&
+ nautilus_file_can_write (file)) {
+ return TRUE;
+ }
+ if (nautilus_file_has_activation_uri (file)) {
+ GFile *location;
+ NautilusFile *activation_file;
+ gboolean res;
+
+ location = nautilus_file_get_activation_location (file);
+ activation_file = nautilus_file_get (location);
+ g_object_unref (location);
+
+ /* The target location might not have data for it read yet,
+ and we can't want to do sync I/O, so treat the unknown
+ case as can-write */
+ res = (nautilus_file_get_file_type (activation_file) == G_FILE_TYPE_UNKNOWN) ||
+ (nautilus_file_get_file_type (activation_file) == G_FILE_TYPE_DIRECTORY &&
+ nautilus_file_can_write (activation_file));
+
+ nautilus_file_unref (activation_file);
+
+ return res;
+ }
+
+ return FALSE;
+}
+
+static void
+clipboard_targets_received (GtkClipboard *clipboard,
+ GdkAtom *targets,
+ int n_targets,
+ gpointer user_data)
+{
+ NautilusFilesView *view;
+ gboolean can_paste;
+ int i;
+ GAction *action;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ can_paste = FALSE;
+
+ if (view->details->slot == NULL ||
+ !view->details->active) {
+ /* We've been destroyed or became inactive since call */
+ g_object_unref (view);
+ return;
+ }
+
+ if (targets) {
+ for (i = 0; i < n_targets; i++) {
+ if (targets[i] == copied_files_atom) {
+ can_paste = TRUE;
+ }
+ }
+ }
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view->details->view_action_group),
+ "paste");
+ /* Take into account if the action was previously disabled for other reasons,
+ * like the directory not being writabble */
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_paste && g_action_get_enabled (action));
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view->details->view_action_group),
+ "paste-into");
+
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_paste && g_action_get_enabled (action));
+
+ g_object_unref (view);
+}
+
+static void
+file_should_show_foreach (NautilusFile *file,
+ gboolean *show_mount,
+ gboolean *show_unmount,
+ gboolean *show_eject,
+ gboolean *show_start,
+ gboolean *show_stop,
+ gboolean *show_poll,
+ GDriveStartStopType *start_stop_type)
+{
+ *show_mount = FALSE;
+ *show_unmount = FALSE;
+ *show_eject = FALSE;
+ *show_start = FALSE;
+ *show_stop = FALSE;
+ *show_poll = FALSE;
+
+ if (nautilus_file_can_eject (file)) {
+ *show_eject = TRUE;
+ }
+
+ if (nautilus_file_can_mount (file)) {
+ *show_mount = TRUE;
+ }
+
+ if (nautilus_file_can_start (file) || nautilus_file_can_start_degraded (file)) {
+ *show_start = TRUE;
+ }
+
+ if (nautilus_file_can_stop (file)) {
+ *show_stop = TRUE;
+ }
+
+ /* Dot not show both Unmount and Eject/Safe Removal; too confusing to
+ * have too many menu entries */
+ if (nautilus_file_can_unmount (file) && !*show_eject && !*show_stop) {
+ *show_unmount = TRUE;
+ }
+
+ if (nautilus_file_can_poll_for_media (file) && !nautilus_file_is_media_check_automatic (file)) {
+ *show_poll = TRUE;
+ }
+
+ *start_stop_type = nautilus_file_get_start_stop_type (file);
+}
+
+static gboolean
+can_restore_from_trash (GList *files)
+{
+ NautilusFile *original_file;
+ NautilusFile *original_dir;
+ GHashTable *original_dirs_hash;
+ GList *original_dirs;
+ gboolean can_restore;
+
+ original_file = NULL;
+ original_dir = NULL;
+ original_dirs = NULL;
+ original_dirs_hash = NULL;
+
+ if (files != NULL) {
+ if (g_list_length (files) == 1) {
+ original_file = nautilus_file_get_trash_original_file (files->data);
+ } else {
+ original_dirs_hash = nautilus_trashed_files_get_original_directories (files, NULL);
+ if (original_dirs_hash != NULL) {
+ original_dirs = g_hash_table_get_keys (original_dirs_hash);
+ if (g_list_length (original_dirs) == 1) {
+ original_dir = nautilus_file_ref (NAUTILUS_FILE (original_dirs->data));
+ }
+ }
+ }
+ }
+
+ can_restore = original_file != NULL || original_dirs != NULL;
+
+ nautilus_file_unref (original_file);
+ nautilus_file_unref (original_dir);
+ g_list_free (original_dirs);
+
+ if (original_dirs_hash != NULL) {
+ g_hash_table_destroy (original_dirs_hash);
+ }
+ return can_restore;
+}
+
+static void
+clipboard_changed_callback (NautilusClipboardMonitor *monitor,
+ NautilusFilesView *view)
+{
+ /* Update paste menu item */
+ nautilus_files_view_update_context_menus (view);
+}
+
+static gboolean
+can_delete_all (GList *files)
+{
+ NautilusFile *file;
+ GList *l;
+
+ for (l = files; l != NULL; l = l->next) {
+ file = l->data;
+ if (!nautilus_file_can_delete (file)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static gboolean
+can_trash_all (GList *files)
+{
+ NautilusFile *file;
+ GList *l;
+
+ for (l = files; l != NULL; l = l->next) {
+ file = l->data;
+ if (!nautilus_file_can_trash (file)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static gboolean
+all_in_trash (GList *files)
+{
+ NautilusFile *file;
+ GList *l;
+
+ for (l = files; l != NULL; l = l->next) {
+ file = l->data;
+ if (!nautilus_file_is_in_trash (file)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+GActionGroup *
+nautilus_files_view_get_action_group (NautilusFilesView *view)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ return view->details->view_action_group;
+}
+
+static void
+real_update_actions_state (NautilusFilesView *view)
+{
+ GList *selection, *l;
+ NautilusFile *file;
+ gint selection_count;
+ gboolean selection_contains_special_link;
+ gboolean selection_contains_desktop_or_home_dir;
+ gboolean selection_contains_recent;
+ gboolean selection_contains_search;
+ gboolean selection_all_in_trash;
+ gboolean selection_is_read_only;
+ gboolean can_create_files;
+ gboolean can_delete_files;
+ gboolean can_move_files;
+ gboolean can_trash_files;
+ gboolean can_copy_files;
+ gboolean can_paste_files_into;
+ gboolean show_app, show_run;
+ gboolean item_opens_in_view;
+ gboolean is_read_only;
+ GAction *action;
+ GAppInfo *app;
+ gboolean show_properties;
+ GActionGroup *view_action_group;
+ gboolean show_mount;
+ gboolean show_unmount;
+ gboolean show_eject;
+ gboolean show_start;
+ gboolean show_stop;
+ gboolean show_detect_media;
+ GDriveStartStopType start_stop_type;
+
+ view_action_group = view->details->view_action_group;
+
+ selection = nautilus_files_view_get_selection (view);
+ selection_count = g_list_length (selection);
+ selection_contains_special_link = special_link_in_selection (selection);
+ selection_contains_desktop_or_home_dir = desktop_or_home_dir_in_selection (selection);
+ selection_contains_recent = showing_recent_directory (view);
+ selection_contains_search = nautilus_files_view_is_search (view);
+ selection_is_read_only = selection_count == 1 &&
+ (!nautilus_file_can_write (NAUTILUS_FILE (selection->data)) &&
+ !nautilus_file_has_activation_uri (NAUTILUS_FILE (selection->data)));
+ selection_all_in_trash = all_in_trash (selection);
+
+ is_read_only = nautilus_files_view_is_read_only (view);
+ can_create_files = nautilus_files_view_supports_creating_files (view);
+ can_delete_files =
+ can_delete_all (selection) &&
+ selection_count != 0 &&
+ !selection_contains_special_link &&
+ !selection_contains_desktop_or_home_dir;
+ can_trash_files =
+ can_trash_all (selection) &&
+ selection_count != 0 &&
+ !selection_contains_special_link &&
+ !selection_contains_desktop_or_home_dir;
+ can_copy_files = selection_count != 0
+ && !selection_contains_special_link;
+ can_move_files = can_delete_files && !selection_contains_recent;
+ can_paste_files_into = (!selection_contains_recent &&
+ selection_count == 1 &&
+ can_paste_into_file (NAUTILUS_FILE (selection->data)));
+ show_properties = !showing_network_directory (view) &&
+ (!NAUTILUS_IS_DESKTOP_CANVAS_VIEW (view) || selection_count > 0);
+
+ /* Right click actions */
+ /* Selection menu actions */
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "new-folder-with-selection");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_create_files && can_delete_files && (selection_count > 1) && !selection_contains_recent);
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "rename");
+ if (selection_count > 1) {
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ have_bulk_rename_tool ());
+ } else {
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ selection_count == 1 &&
+ nautilus_files_view_can_rename_file (view, selection->data));
+ }
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "open-item-location");
+
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ selection_count == 1 &&
+ (selection_contains_recent || selection_contains_search));
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "new-folder");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_create_files);
+
+
+ selection = nautilus_files_view_get_selection (view);
+ selection_count = g_list_length (selection);
+
+ show_app = show_run = item_opens_in_view = selection_count != 0;
+
+ for (l = selection; l != NULL; l = l->next) {
+ NautilusFile *file;
+
+ file = NAUTILUS_FILE (selection->data);
+
+ if (!nautilus_mime_file_opens_in_external_app (file)) {
+ show_app = FALSE;
+ }
+
+ if (!nautilus_mime_file_launches (file)) {
+ show_run = FALSE;
+ }
+
+ if (!nautilus_mime_file_opens_in_view (file)) {
+ item_opens_in_view = FALSE;
+ }
+
+ if (!show_app && !show_run && !item_opens_in_view) {
+ break;
+ }
+ }
+
+ /* Open With <App> menu item */
+ app = NULL;
+ if (show_app) {
+ app = nautilus_mime_get_default_application_for_files (selection);
+ }
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "open-with-default-application");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), selection_count != 0);
+
+ /* Allow to select a different application to open the item */
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "open-with-other-application");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ app != NULL ||
+ (selection_count > 0 &&
+ nautilus_file_is_directory (NAUTILUS_FILE (selection->data))));
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "open-item-new-tab");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), item_opens_in_view);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "open-item-new-window");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), item_opens_in_view);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "set-as-wallpaper");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_set_wallpaper (selection));
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "restore-from-trash");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_restore_from_trash (selection));
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "move-to-trash");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_trash_files);
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "delete-from-trash");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_delete_files && selection_all_in_trash);
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "delete-permanently-shortcut");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_delete_files);
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "delete-permanently-menu-item");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_delete_files && !can_trash_files &&
+ !selection_all_in_trash && !selection_contains_recent);
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "remove-from-recent");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ selection_contains_recent && selection_count > 0);
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "cut");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_move_files && !selection_contains_recent);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "copy");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_copy_files);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "copy-to");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_copy_files);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "move-to");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_move_files && !selection_contains_recent);
+
+ /* Drive menu */
+ show_mount = show_unmount = show_eject = show_start = show_stop = show_detect_media = FALSE;
+ for (l = selection; l != NULL && (show_mount || show_unmount
+ || show_eject
+ || show_start || show_stop
+ || show_detect_media);
+ l = l->next) {
+ gboolean show_mount_one;
+ gboolean show_unmount_one;
+ gboolean show_eject_one;
+ gboolean show_start_one;
+ gboolean show_stop_one;
+ gboolean show_detect_media_one;
+
+ file = NAUTILUS_FILE (l->data);
+ file_should_show_foreach (file,
+ &show_mount_one,
+ &show_unmount_one,
+ &show_eject_one,
+ &show_start_one,
+ &show_stop_one,
+ &show_detect_media_one,
+ &start_stop_type);
+
+ show_mount &= show_mount_one;
+ show_unmount &= show_unmount_one;
+ show_eject &= show_eject_one;
+ show_start &= show_start_one;
+ show_stop &= show_stop_one;
+ show_detect_media &= show_detect_media_one;
+ }
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "mount-volume");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ show_mount);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "unmount-volume");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ show_unmount);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "eject-volume");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ show_eject);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "start-volume");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ show_start);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "stop-volume");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ show_stop);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "detect-media");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ show_detect_media);
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "scripts");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ view->details->scripts_present);
+
+ /* Background menu actions */
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "new-folder");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_create_files);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "paste");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ !is_read_only && !selection_contains_recent);
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "paste-into");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ !selection_is_read_only && !selection_contains_recent &&
+ can_paste_files_into);
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "properties");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ show_properties);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "new-document");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ can_create_files &&
+ !selection_contains_recent &&
+ view->details->templates_present);
+
+ /* Ask the clipboard */
+ g_object_ref (view); /* Need to keep the object alive until we get the reply */
+ gtk_clipboard_request_targets (nautilus_clipboard_get (GTK_WIDGET (view)),
+ clipboard_targets_received,
+ view);
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "select-all");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ !nautilus_files_view_is_empty (view));
+
+ /* Toolbar menu actions */
+ g_action_group_change_action_state (view_action_group,
+ "show-hidden-files",
+ g_variant_new_boolean (view->details->show_hidden_files));
+
+ /* Zoom */
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "zoom-in");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ nautilus_files_view_can_zoom_in (view));
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "zoom-out");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ nautilus_files_view_can_zoom_out (view));
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+ "zoom-default");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ nautilus_files_view_supports_zooming (view));
+}
+
+/* Convenience function to be called when updating menus,
+ * so children can subclass it and it will be called when
+ * they chain up to the parent in update_context_menus
+ * or update_toolbar_menus
+ */
+void
+nautilus_files_view_update_actions_state (NautilusFilesView *view)
+{
+ g_assert(NAUTILUS_IS_FILES_VIEW (view));
+
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->update_actions_state (view);
+}
+
+static void
+update_selection_menu (NautilusFilesView *view)
+{
+ GList *selection, *l;
+ NautilusFile *file;
+ gint selection_count;
+ gboolean show_app, show_run;
+ gboolean item_opens_in_view;
+ gchar *item_label;
+ GAppInfo *app;
+ GIcon *app_icon;
+ GMenuItem *menu_item;
+ gboolean show_mount;
+ gboolean show_unmount;
+ gboolean show_eject;
+ gboolean show_start;
+ gboolean show_stop;
+ gboolean show_detect_media;
+ GDriveStartStopType start_stop_type;
+
+ selection = nautilus_files_view_get_selection (view);
+ selection_count = g_list_length (selection);
+
+ show_mount = (selection != NULL);
+ show_unmount = (selection != NULL);
+ show_eject = (selection != NULL);
+ show_start = (selection != NULL && selection_count == 1);
+ show_stop = (selection != NULL && selection_count == 1);
+ show_detect_media = (selection != NULL && selection_count == 1);
+ start_stop_type = G_DRIVE_START_STOP_TYPE_UNKNOWN;
+ item_label = g_strdup_printf (ngettext ("New Folder with Selection (%'d Item)",
+ "New Folder with Selection (%'d Items)",
+ selection_count),
+ selection_count);
+ menu_item = g_menu_item_new (item_label, "view.new-folder-with-selection");
+ g_menu_item_set_attribute (menu_item, "hidden-when", "s", "action-disabled");
+ nautilus_gmenu_add_item_in_submodel (view->details->selection_menu,
+ menu_item,
+ "new-folder-with-selection-section",
+ FALSE);
+ g_object_unref (menu_item);
+ g_free (item_label);
+
+ /* Open With <App> menu item */
+ show_app = show_run = item_opens_in_view = selection_count != 0;
+ for (l = selection; l != NULL; l = l->next) {
+ NautilusFile *file;
+
+ file = NAUTILUS_FILE (selection->data);
+
+ if (!nautilus_mime_file_opens_in_external_app (file)) {
+ show_app = FALSE;
+ }
+
+ if (!nautilus_mime_file_launches (file)) {
+ show_run = FALSE;
+ }
+
+ if (!nautilus_mime_file_opens_in_view (file)) {
+ item_opens_in_view = FALSE;
+ }
+
+ if (!show_app && !show_run && !item_opens_in_view) {
+ break;
+ }
+ }
+
+ item_label = NULL;
+ app = NULL;
+ app_icon = NULL;
+ if (show_app) {
+ app = nautilus_mime_get_default_application_for_files (selection);
+ }
+
+ char *escaped_app;
+
+ if (app != NULL) {
+ escaped_app = eel_str_double_underscores (g_app_info_get_name (app));
+ item_label = g_strdup_printf (_("Open With %s"), escaped_app);
+
+ app_icon = g_app_info_get_icon (app);
+ if (app_icon != NULL) {
+ g_object_ref (app_icon);
+ }
+ g_free (escaped_app);
+ g_object_unref (app);
+ } else if (show_run) {
+ item_label = g_strdup (_("Run"));
+ } else {
+ item_label = g_strdup (_("Open"));
+ }
+
+ menu_item = g_menu_item_new (item_label, "view.open-with-default-application");
+ if (app_icon != NULL)
+ g_menu_item_set_icon (menu_item, app_icon);
+
+ nautilus_gmenu_add_item_in_submodel (view->details->selection_menu,
+ menu_item,
+ "open-with-default-application-section",
+ FALSE);
+
+ g_free (item_label);
+ g_object_unref (menu_item);
+
+ /* Drives */
+ for (l = selection; l != NULL && (show_mount || show_unmount
+ || show_eject
+ || show_start || show_stop
+ || show_detect_media);
+ l = l->next) {
+ gboolean show_mount_one;
+ gboolean show_unmount_one;
+ gboolean show_eject_one;
+ gboolean show_start_one;
+ gboolean show_stop_one;
+ gboolean show_detect_media_one;
+
+ file = NAUTILUS_FILE (l->data);
+ file_should_show_foreach (file,
+ &show_mount_one,
+ &show_unmount_one,
+ &show_eject_one,
+ &show_start_one,
+ &show_stop_one,
+ &show_detect_media_one,
+ &start_stop_type);
+
+ show_mount &= show_mount_one;
+ show_unmount &= show_unmount_one;
+ show_eject &= show_eject_one;
+ show_start &= show_start_one;
+ show_stop &= show_stop_one;
+ show_detect_media &= show_detect_media_one;
+ }
+
+ if (show_start) {
+ switch (start_stop_type) {
+ default:
+ case G_DRIVE_START_STOP_TYPE_UNKNOWN:
+ case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
+ item_label = _("_Start");
+ break;
+ case G_DRIVE_START_STOP_TYPE_NETWORK:
+ item_label = _("_Connect");
+ break;
+ case G_DRIVE_START_STOP_TYPE_MULTIDISK:
+ item_label = _("_Start Multi-disk Drive");
+ break;
+ case G_DRIVE_START_STOP_TYPE_PASSWORD:
+ item_label = _("U_nlock Drive");
+ break;
+ }
+
+ menu_item = g_menu_item_new (item_label, "view.start-volume");
+ nautilus_gmenu_add_item_in_submodel (view->details->selection_menu,
+ menu_item,
+ "drive-section",
+ FALSE);
+ g_object_unref (menu_item);
+ }
+
+ if (show_stop) {
+ switch (start_stop_type) {
+ default:
+ case G_DRIVE_START_STOP_TYPE_UNKNOWN:
+ item_label = _("Stop Drive");
+ break;
+ case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
+ item_label = _("_Safely Remove Drive");
+ break;
+ case G_DRIVE_START_STOP_TYPE_NETWORK:
+ item_label = _("_Disconnect");
+ break;
+ case G_DRIVE_START_STOP_TYPE_MULTIDISK:
+ item_label = _("_Stop Multi-disk Drive");
+ break;
+ case G_DRIVE_START_STOP_TYPE_PASSWORD:
+ item_label = _("_Lock Drive");
+ break;
+ }
+
+ menu_item = g_menu_item_new (item_label, "view.stop-volume");
+ nautilus_gmenu_add_item_in_submodel (view->details->selection_menu,
+ menu_item,
+ "drive-section",
+ FALSE);
+ g_object_unref (menu_item);
+ }
+
+ update_scripts_menu (view);
+}
+
+static void
+update_background_menu (NautilusFilesView *view)
+{
+
+ if (nautilus_files_view_supports_creating_files (view) &&
+ !showing_recent_directory (view))
+ update_templates_menu (view);
+}
+
+static void
+real_update_context_menus (NautilusFilesView *view)
+{
+ g_clear_object (&view->details->background_menu);
+ g_clear_object (&view->details->selection_menu);
+
+ GtkBuilder *builder;
+ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-files-view-context-menus.xml");
+ view->details->background_menu = g_object_ref (G_MENU (gtk_builder_get_object (builder, "background-menu")));
+ view->details->selection_menu = g_object_ref (G_MENU (gtk_builder_get_object (builder, "selection-menu")));
+ g_object_unref (builder);
+
+ update_selection_menu (view);
+ update_background_menu (view);
+ update_extensions_menus (view);
+
+ nautilus_files_view_update_actions_state (view);
+}
+
+/* Convenience function to reset the context menus owned by the view and update
+ * them with the current state.
+ * Children can subclass it and add items on the menu after chaining up to the
+ * parent, so menus are already reseted.
+ * It will also update the actions state, which will also update children
+ * actions state if the children subclass nautilus_files_view_update_actions_state
+ */
+void
+nautilus_files_view_update_context_menus (NautilusFilesView *view)
+{
+ g_assert(NAUTILUS_IS_FILES_VIEW (view));
+
+ NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->update_context_menus (view);
+}
+
+static void
+nautilus_files_view_reset_view_menu (NautilusFilesView *view)
+{
+ GActionGroup *view_action_group;
+ GVariant *variant;
+ GVariantIter iter;
+ gboolean show_sort_trash, show_sort_search, show_sort_access, show_sort_modification, enable_sort;
+ const gchar *hint;
+
+ view_action_group = nautilus_files_view_get_action_group (view);
+
+ gtk_widget_set_visible (view->details->visible_columns,
+ g_action_group_has_action (view_action_group, "visible-columns"));
+
+ enable_sort = g_action_group_get_action_enabled (view_action_group, "sort");
+ show_sort_trash = show_sort_search = show_sort_modification = show_sort_access = FALSE;
+ gtk_widget_set_visible (view->details->sort_menu, enable_sort);
+
+ if (enable_sort) {
+ variant = g_action_group_get_action_state_hint (view_action_group, "sort");
+ g_variant_iter_init (&iter, variant);
+
+ while (g_variant_iter_next (&iter, "&s", &hint)) {
+ if (g_strcmp0 (hint, "trash-time") == 0)
+ show_sort_trash = TRUE;
+ if (g_strcmp0 (hint, "search-relevance") == 0)
+ show_sort_search = TRUE;
+ }
+
+ g_variant_unref (variant);
+ }
+
+ gtk_widget_set_visible (view->details->sort_trash_time, show_sort_trash);
+ gtk_widget_set_visible (view->details->sort_search_relevance, show_sort_search);
+
+ variant = g_action_group_get_action_state (view_action_group, "zoom-to-level");
+ gtk_adjustment_set_value (view->details->zoom_adjustment,
+ g_variant_get_int32 (variant));
+ g_variant_unref (variant);
+}
+
+/* Convenience function to reset the menus owned by the view but managed on
+ * the toolbar, and update them with the current state.
+ * It will also update the actions state, which will also update children
+ * actions state if the children subclass nautilus_files_view_update_actions_state
+ */
+void
+nautilus_files_view_update_toolbar_menus (NautilusFilesView *view)
+{
+ NautilusWindow *window;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ /* Don't update after destroy (#349551),
+ * or if we are not active.
+ */
+ if (view->details->slot == NULL ||
+ !view->details->active) {
+ return;
+ }
+ window = nautilus_files_view_get_window (view);
+ nautilus_window_reset_menus (window);
+
+ nautilus_files_view_reset_view_menu (view);
+ nautilus_files_view_update_actions_state (view);
+}
+
+/**
+ * nautilus_files_view_pop_up_selection_context_menu
+ *
+ * Pop up a context menu appropriate to the selected items.
+ * @view: NautilusFilesView of interest.
+ * @event: The event that triggered this context menu.
+ *
+ **/
+void
+nautilus_files_view_pop_up_selection_context_menu (NautilusFilesView *view,
+ GdkEventButton *event)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ /* Make the context menu items not flash as they update to proper disabled,
+ * etc. states by forcing menus to update now.
+ */
+ update_context_menus_if_pending (view);
+
+ update_context_menu_position_from_event (view, event);
+
+ nautilus_pop_up_context_menu (GTK_WIDGET (view), view->details->selection_menu, event);
+}
+
+/**
+ * nautilus_files_view_pop_up_background_context_menu
+ *
+ * Pop up a context menu appropriate to the view globally at the last right click location.
+ * @view: NautilusFilesView of interest.
+ *
+ **/
+void
+nautilus_files_view_pop_up_background_context_menu (NautilusFilesView *view,
+ GdkEventButton *event)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ /* Make the context menu items not flash as they update to proper disabled,
+ * etc. states by forcing menus to update now.
+ */
+ update_context_menus_if_pending (view);
+
+ update_context_menu_position_from_event (view, event);
+
+ nautilus_pop_up_context_menu (GTK_WIDGET (view), view->details->background_menu, event);
+}
+
+static void
+schedule_update_context_menus (NautilusFilesView *view)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ /* Don't schedule updates after destroy (#349551),
+ * or if we are not active.
+ */
+ if (view->details->slot == NULL ||
+ !view->details->active) {
+ return;
+ }
+
+ /* Schedule a menu update with the current update interval */
+ if (view->details->update_context_menus_timeout_id == 0) {
+ view->details->update_context_menus_timeout_id
+ = g_timeout_add (view->details->update_interval, update_context_menus_timeout_callback, view);
+ }
+}
+
+static void
+remove_update_status_idle_callback (NautilusFilesView *view)
+{
+ if (view->details->update_status_idle_id != 0) {
+ g_source_remove (view->details->update_status_idle_id);
+ view->details->update_status_idle_id = 0;
+ }
+}
+
+static gboolean
+update_status_idle_callback (gpointer data)
+{
+ NautilusFilesView *view;
+
+ view = NAUTILUS_FILES_VIEW (data);
+ nautilus_files_view_display_selection_info (view);
+ view->details->update_status_idle_id = 0;
+ return FALSE;
+}
+
+static void
+schedule_update_status (NautilusFilesView *view)
+{
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ /* Make sure we haven't already destroyed it */
+ if (view->details->slot == NULL) {
+ return;
+ }
+
+ if (view->details->loading) {
+ /* Don't update status bar while loading the dir */
+ return;
+ }
+
+ if (view->details->update_status_idle_id == 0) {
+ view->details->update_status_idle_id =
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE - 20,
+ update_status_idle_callback, view, NULL);
+ }
+}
+
+/**
+ * nautilus_files_view_notify_selection_changed:
+ *
+ * Notify this view that the selection has changed. This is normally
+ * called only by subclasses.
+ * @view: NautilusFilesView whose selection has changed.
+ *
+ **/
+void
+nautilus_files_view_notify_selection_changed (NautilusFilesView *view)
+{
+ GtkWindow *window;
+ GList *selection;
+
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ selection = nautilus_files_view_get_selection (view);
+ window = nautilus_files_view_get_containing_window (view);
+ DEBUG_FILES (selection, "Selection changed in window %p", window);
+ nautilus_file_list_free (selection);
+
+ view->details->selection_was_removed = FALSE;
+
+ /* Schedule a display of the new selection. */
+ if (view->details->display_selection_idle_id == 0) {
+ view->details->display_selection_idle_id
+ = g_idle_add (display_selection_info_idle_callback,
+ view);
+ }
+
+ if (view->details->batching_selection_level != 0) {
+ view->details->selection_changed_while_batched = TRUE;
+ } else {
+ /* Here is the work we do only when we're not
+ * batching selection changes. In other words, it's the slower
+ * stuff that we don't want to slow down selection techniques
+ * such as rubberband-selecting in icon view.
+ */
+
+ /* Schedule an update of menu item states to match selection */
+ schedule_update_context_menus (view);
+ }
+}
+
+static void
+file_changed_callback (NautilusFile *file,
+ gpointer callback_data)
+{
+ NautilusFilesView *view = NAUTILUS_FILES_VIEW (callback_data);
+
+ schedule_changes (view);
+
+ schedule_update_context_menus (view);
+ schedule_update_status (view);
+}
+
+/**
+ * load_directory:
+ *
+ * Switch the displayed location to a new uri. If the uri is not valid,
+ * the location will not be switched; user feedback will be provided instead.
+ * @view: NautilusFilesView whose location will be changed.
+ * @uri: A string representing the uri to switch to.
+ *
+ **/
+static void
+load_directory (NautilusFilesView *view,
+ NautilusDirectory *directory)
+{
+ NautilusDirectory *old_directory;
+ NautilusFile *old_file;
+ NautilusFileAttributes attributes;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
+
+ nautilus_profile_start (NULL);
+
+ nautilus_files_view_stop_loading (view);
+ g_signal_emit (view, signals[CLEAR], 0);
+
+ view->details->loading = TRUE;
+
+ setup_loading_floating_bar (view);
+
+ /* Update menus when directory is empty, before going to new
+ * location, so they won't have any false lingering knowledge
+ * of old selection.
+ */
+ schedule_update_context_menus (view);
+
+ while (view->details->subdirectory_list != NULL) {
+ nautilus_files_view_remove_subdirectory (view,
+ view->details->subdirectory_list->data);
+ }
+
+ old_directory = view->details->model;
+
+ nautilus_directory_ref (directory);
+ view->details->model = directory;
+ nautilus_directory_unref (old_directory);
+
+ old_file = view->details->directory_as_file;
+ view->details->directory_as_file =
+ nautilus_directory_get_corresponding_file (directory);
+ nautilus_file_unref (old_file);
+
+ /* FIXME bugzilla.gnome.org 45062: In theory, we also need to monitor metadata here (as
+ * well as doing a call when ready), in case external forces
+ * change the directory's file metadata.
+ */
+ attributes =
+ NAUTILUS_FILE_ATTRIBUTE_INFO |
+ NAUTILUS_FILE_ATTRIBUTE_MOUNT |
+ NAUTILUS_FILE_ATTRIBUTE_FILESYSTEM_INFO;
+ view->details->metadata_for_directory_as_file_pending = TRUE;
+ view->details->metadata_for_files_in_directory_pending = TRUE;
+ nautilus_file_call_when_ready
+ (view->details->directory_as_file,
+ attributes,
+ metadata_for_directory_as_file_ready_callback, view);
+ nautilus_directory_call_when_ready
+ (view->details->model,
+ attributes,
+ FALSE,
+ metadata_for_files_in_directory_ready_callback, view);
+
+ /* If capabilities change, then we need to update the menus
+ * because of New Folder, and relative emblems.
+ */
+ attributes =
+ NAUTILUS_FILE_ATTRIBUTE_INFO |
+ NAUTILUS_FILE_ATTRIBUTE_FILESYSTEM_INFO;
+ nautilus_file_monitor_add (view->details->directory_as_file,
+ &view->details->directory_as_file,
+ attributes);
+
+ view->details->file_changed_handler_id = g_signal_connect
+ (view->details->directory_as_file, "changed",
+ G_CALLBACK (file_changed_callback), view);
+
+ nautilus_profile_end (NULL);
+}
+
+static void
+finish_loading (NautilusFilesView *view)
+{
+ NautilusFileAttributes attributes;
+
+ nautilus_profile_start (NULL);
+
+ /* Tell interested parties that we've begun loading this directory now.
+ * Subclasses use this to know that the new metadata is now available.
+ */
+ nautilus_profile_start ("BEGIN_LOADING");
+ g_signal_emit (view, signals[BEGIN_LOADING], 0);
+ nautilus_profile_end ("BEGIN_LOADING");
+
+ check_empty_states (view);
+
+ if (nautilus_directory_are_all_files_seen (view->details->model)) {
+ /* Unschedule a pending update and schedule a new one with the minimal
+ * update interval. This gives the view a short chance at gathering the
+ * (cached) deep counts.
+ */
+ unschedule_display_of_pending_files (view);
+ schedule_timeout_display_of_pending_files (view, UPDATE_INTERVAL_MIN);
+ }
+
+ /* Start loading. */
+
+ /* Connect handlers to learn about loading progress. */
+ view->details->done_loading_handler_id = g_signal_connect
+ (view->details->model, "done-loading",
+ G_CALLBACK (done_loading_callback), view);
+ view->details->load_error_handler_id = g_signal_connect
+ (view->details->model, "load-error",
+ G_CALLBACK (load_error_callback), view);
+
+ /* Monitor the things needed to get the right icon. Also
+ * monitor a directory's item count because the "size"
+ * attribute is based on that, and the file's metadata
+ * and possible custom name.
+ */
+ attributes =
+ NAUTILUS_FILE_ATTRIBUTES_FOR_ICON |
+ NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
+ NAUTILUS_FILE_ATTRIBUTE_INFO |
+ NAUTILUS_FILE_ATTRIBUTE_LINK_INFO |
+ NAUTILUS_FILE_ATTRIBUTE_MOUNT |
+ NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO;
+
+ nautilus_directory_file_monitor_add (view->details->model,
+ &view->details->model,
+ view->details->show_hidden_files,
+ attributes,
+ files_added_callback, view);
+
+ view->details->files_added_handler_id = g_signal_connect
+ (view->details->model, "files-added",
+ G_CALLBACK (files_added_callback), view);
+ view->details->files_changed_handler_id = g_signal_connect
+ (view->details->model, "files-changed",
+ G_CALLBACK (files_changed_callback), view);
+
+ nautilus_profile_end (NULL);
+}
+
+static void
+finish_loading_if_all_metadata_loaded (NautilusFilesView *view)
+{
+ if (!view->details->metadata_for_directory_as_file_pending &&
+ !view->details->metadata_for_files_in_directory_pending) {
+ finish_loading (view);
+ }
+}
+
+static void
+metadata_for_directory_as_file_ready_callback (NautilusFile *file,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = callback_data;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+ g_assert (view->details->directory_as_file == file);
+ g_assert (view->details->metadata_for_directory_as_file_pending);
+
+ nautilus_profile_start (NULL);
+
+ view->details->metadata_for_directory_as_file_pending = FALSE;
+
+ finish_loading_if_all_metadata_loaded (view);
+ nautilus_profile_end (NULL);
+}
+
+static void
+metadata_for_files_in_directory_ready_callback (NautilusDirectory *directory,
+ GList *files,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = callback_data;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+ g_assert (view->details->model == directory);
+ g_assert (view->details->metadata_for_files_in_directory_pending);
+
+ nautilus_profile_start (NULL);
+
+ view->details->metadata_for_files_in_directory_pending = FALSE;
+
+ finish_loading_if_all_metadata_loaded (view);
+ nautilus_profile_end (NULL);
+}
+
+static void
+disconnect_handler (GObject *object,
+ guint *id)
+{
+ if (*id != 0) {
+ g_signal_handler_disconnect (object, *id);
+ *id = 0;
+ }
+}
+
+static void
+disconnect_directory_handler (NautilusFilesView *view,
+ guint *id)
+{
+ disconnect_handler (G_OBJECT (view->details->model), id);
+}
+
+static void
+disconnect_directory_as_file_handler (NautilusFilesView *view,
+ guint *id)
+{
+ disconnect_handler (G_OBJECT (view->details->directory_as_file), id);
+}
+
+static void
+disconnect_model_handlers (NautilusFilesView *view)
+{
+ if (view->details->model == NULL) {
+ return;
+ }
+ disconnect_directory_handler (view, &view->details->files_added_handler_id);
+ disconnect_directory_handler (view, &view->details->files_changed_handler_id);
+ disconnect_directory_handler (view, &view->details->done_loading_handler_id);
+ disconnect_directory_handler (view, &view->details->load_error_handler_id);
+ disconnect_directory_as_file_handler (view, &view->details->file_changed_handler_id);
+ nautilus_file_cancel_call_when_ready (view->details->directory_as_file,
+ metadata_for_directory_as_file_ready_callback,
+ view);
+ nautilus_directory_cancel_callback (view->details->model,
+ metadata_for_files_in_directory_ready_callback,
+ view);
+ nautilus_directory_file_monitor_remove (view->details->model,
+ &view->details->model);
+ nautilus_file_monitor_remove (view->details->directory_as_file,
+ &view->details->directory_as_file);
+}
+
+static void
+nautilus_files_view_select_file (NautilusFilesView *view,
+ NautilusFile *file)
+{
+ GList file_list;
+
+ file_list.data = file;
+ file_list.next = NULL;
+ file_list.prev = NULL;
+ nautilus_files_view_call_set_selection (view, &file_list);
+}
+
+static gboolean
+remove_all (gpointer key,
+ gpointer value,
+ gpointer callback_data)
+{
+ return TRUE;
+}
+
+/**
+ * nautilus_files_view_stop_loading:
+ *
+ * Stop the current ongoing process, such as switching to a new uri.
+ * @view: NautilusFilesView in question.
+ *
+ **/
+void
+nautilus_files_view_stop_loading (NautilusFilesView *view)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ disconnect_model_handlers (view);
+ if (view->details->model) {
+ nautilus_directory_unref (view->details->model);
+ view->details->model = NULL;
+ }
+ unschedule_display_of_pending_files (view);
+ reset_update_interval (view);
+
+ /* Free extra undisplayed files */
+ file_and_directory_list_free (view->details->new_added_files);
+ view->details->new_added_files = NULL;
+
+ file_and_directory_list_free (view->details->new_changed_files);
+ view->details->new_changed_files = NULL;
+
+ g_hash_table_foreach_remove (view->details->non_ready_files, remove_all, NULL);
+
+ file_and_directory_list_free (view->details->old_added_files);
+ view->details->old_added_files = NULL;
+
+ file_and_directory_list_free (view->details->old_changed_files);
+ view->details->old_changed_files = NULL;
+
+ g_list_free_full (view->details->pending_selection, g_object_unref);
+ view->details->pending_selection = NULL;
+
+ done_loading (view, FALSE);
+}
+
+gboolean
+nautilus_files_view_is_editable (NautilusFilesView *view)
+{
+ NautilusDirectory *directory;
+
+ directory = nautilus_files_view_get_model (view);
+
+ if (directory != NULL) {
+ return nautilus_directory_is_editable (directory);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+real_is_read_only (NautilusFilesView *view)
+{
+ NautilusFile *file;
+
+ if (!nautilus_files_view_is_editable (view)) {
+ return TRUE;
+ }
+
+ file = nautilus_files_view_get_directory_as_file (view);
+ if (file != NULL) {
+ return !nautilus_file_can_write (file);
+ }
+ return FALSE;
+}
+
+/**
+ * nautilus_files_view_should_show_file
+ *
+ * Returns whether or not this file should be displayed based on
+ * current filtering options.
+ */
+gboolean
+nautilus_files_view_should_show_file (NautilusFilesView *view,
+ NautilusFile *file)
+{
+ return nautilus_file_should_show (file,
+ view->details->show_hidden_files,
+ view->details->show_foreign_files);
+}
+
+static gboolean
+real_using_manual_layout (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), FALSE);
+
+ return FALSE;
+}
+
+void
+nautilus_files_view_ignore_hidden_file_preferences (NautilusFilesView *view)
+{
+ g_return_if_fail (view->details->model == NULL);
+
+ if (view->details->ignore_hidden_file_preferences) {
+ return;
+ }
+
+ view->details->show_hidden_files = FALSE;
+ view->details->ignore_hidden_file_preferences = TRUE;
+}
+
+void
+nautilus_files_view_set_show_foreign (NautilusFilesView *view,
+ gboolean show_foreign)
+{
+ view->details->show_foreign_files = show_foreign;
+}
+
+char *
+nautilus_files_view_get_uri (NautilusFilesView *view)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
+ if (view->details->model == NULL) {
+ return NULL;
+ }
+ return nautilus_directory_get_uri (view->details->model);
+}
+
+void
+nautilus_files_view_move_copy_items (NautilusFilesView *view,
+ const GList *item_uris,
+ GArray *relative_item_points,
+ const char *target_uri,
+ int copy_action,
+ int x,
+ int y)
+{
+ NautilusFile *target_file;
+
+ 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);
+
+ target_file = nautilus_file_get_existing_by_uri (target_uri);
+ /* special-case "command:" here instead of starting a move/copy */
+ if (target_file != NULL && nautilus_file_is_launcher (target_file)) {
+ nautilus_file_unref (target_file);
+ nautilus_launch_desktop_file (
+ gtk_widget_get_screen (GTK_WIDGET (view)),
+ target_uri, item_uris,
+ nautilus_files_view_get_containing_window (view));
+ return;
+ } else if (copy_action == GDK_ACTION_COPY &&
+ nautilus_is_file_roller_installed () &&
+ target_file != NULL &&
+ nautilus_file_is_archive (target_file)) {
+ char *command, *quoted_uri, *tmp;
+ const GList *l;
+ GdkScreen *screen;
+
+ /* Handle dropping onto a file-roller archiver file, instead of starting a move/copy */
+
+ nautilus_file_unref (target_file);
+
+ quoted_uri = g_shell_quote (target_uri);
+ command = g_strconcat ("file-roller -a ", quoted_uri, NULL);
+ g_free (quoted_uri);
+
+ for (l = item_uris; l != NULL; l = l->next) {
+ quoted_uri = g_shell_quote ((char *) l->data);
+
+ tmp = g_strconcat (command, " ", quoted_uri, NULL);
+ g_free (command);
+ command = tmp;
+
+ g_free (quoted_uri);
+ }
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (view));
+ if (screen == NULL) {
+ screen = gdk_screen_get_default ();
+ }
+
+ nautilus_launch_application_from_command (screen, command, FALSE, NULL);
+ g_free (command);
+
+ return;
+ }
+ nautilus_file_unref (target_file);
+
+ nautilus_file_operations_copy_move
+ (item_uris, relative_item_points,
+ target_uri, copy_action, GTK_WIDGET (view),
+ copy_move_done_callback, pre_copy_move (view));
+}
+
+static void
+nautilus_files_view_trash_state_changed_callback (NautilusTrashMonitor *trash_monitor,
+ gboolean state,
+ gpointer callback_data)
+{
+ NautilusFilesView *view;
+
+ view = (NautilusFilesView *) callback_data;
+ g_assert (NAUTILUS_IS_FILES_VIEW (view));
+
+ schedule_update_context_menus (view);
+}
+
+void
+nautilus_files_view_start_batching_selection_changes (NautilusFilesView *view)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+
+ ++view->details->batching_selection_level;
+ view->details->selection_changed_while_batched = FALSE;
+}
+
+void
+nautilus_files_view_stop_batching_selection_changes (NautilusFilesView *view)
+{
+ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
+ g_return_if_fail (view->details->batching_selection_level > 0);
+
+ if (--view->details->batching_selection_level == 0) {
+ if (view->details->selection_changed_while_batched) {
+ nautilus_files_view_notify_selection_changed (view);
+ }
+ }
+}
+
+static GArray *
+real_get_selected_icon_locations (NautilusFilesView *view)
+{
+ /* By default, just return an empty list. */
+ return g_array_new (FALSE, TRUE, sizeof (GdkPoint));
+}
+
+static void
+nautilus_files_view_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ NautilusFilesView *view = NAUTILUS_FILES_VIEW (object);
+
+ switch (prop_id) {
+ case PROP_ICON:
+ g_value_set_object (value, nautilus_files_view_get_icon (view));
+ break;
+
+ case PROP_VIEW_WIDGET:
+ g_value_set_object (value, nautilus_files_view_get_view_widget (view));
+ break;
+
+ default:
+ g_assert_not_reached ();
+
+ }
+}
+
+static void
+nautilus_files_view_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ NautilusFilesView *directory_view;
+ NautilusWindowSlot *slot;
+
+ directory_view = NAUTILUS_FILES_VIEW (object);
+
+ switch (prop_id) {
+ case PROP_WINDOW_SLOT:
+ g_assert (directory_view->details->slot == NULL);
+
+ slot = NAUTILUS_WINDOW_SLOT (g_value_get_object (value));
+ directory_view->details->slot = slot;
+
+ g_signal_connect_object (directory_view->details->slot,
+ "active", G_CALLBACK (slot_active),
+ directory_view, 0);
+ g_signal_connect_object (directory_view->details->slot,
+ "inactive", G_CALLBACK (slot_inactive),
+ directory_view, 0);
+ break;
+ case PROP_SUPPORTS_ZOOMING:
+ directory_view->details->supports_zooming = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+gboolean
+nautilus_files_view_handle_scroll_event (NautilusFilesView *directory_view,
+ GdkEventScroll *event)
+{
+ static gdouble total_delta_y = 0;
+ gdouble delta_x, delta_y;
+
+ if (event->state & GDK_CONTROL_MASK) {
+ switch (event->direction) {
+ case GDK_SCROLL_UP:
+ /* Zoom In */
+ nautilus_files_view_bump_zoom_level (directory_view, 1);
+ return TRUE;
+
+ case GDK_SCROLL_DOWN:
+ /* Zoom Out */
+ nautilus_files_view_bump_zoom_level (directory_view, -1);
+ return TRUE;
+
+ case GDK_SCROLL_SMOOTH:
+ gdk_event_get_scroll_deltas ((const GdkEvent *) event,
+ &delta_x, &delta_y);
+
+ /* try to emulate a normal scrolling event by summing deltas */
+ total_delta_y += delta_y;
+
+ if (total_delta_y >= 1) {
+ total_delta_y = 0;
+ /* emulate scroll down */
+ nautilus_files_view_bump_zoom_level (directory_view, -1);
+ return TRUE;
+ } else if (total_delta_y <= - 1) {
+ total_delta_y = 0;
+ /* emulate scroll up */
+ nautilus_files_view_bump_zoom_level (directory_view, 1);
+ return TRUE;
+ } else {
+ /* eat event */
+ return TRUE;
+ }
+
+ case GDK_SCROLL_LEFT:
+ case GDK_SCROLL_RIGHT:
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ return FALSE;
+}
+
+/* handle Shift+Scroll, which will cause a zoom-in/out */
+static gboolean
+nautilus_files_view_scroll_event (GtkWidget *widget,
+ GdkEventScroll *event)
+{
+ NautilusFilesView *directory_view;
+
+ directory_view = NAUTILUS_FILES_VIEW (widget);
+ if (nautilus_files_view_handle_scroll_event (directory_view, event)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void
+action_reload_enabled_changed (GActionGroup *action_group,
+ gchar *action_name,
+ gboolean enabled,
+ NautilusFilesView *view)
+{
+ gtk_widget_set_visible (view->details->reload, enabled);
+}
+
+static void
+action_stop_enabled_changed (GActionGroup *action_group,
+ gchar *action_name,
+ gboolean enabled,
+ NautilusFilesView *view)
+{
+ gtk_widget_set_visible (view->details->stop, enabled);
+}
+
+static void
+nautilus_files_view_parent_set (GtkWidget *widget,
+ GtkWidget *old_parent)
+{
+ NautilusWindow *window;
+ NautilusFilesView *view;
+ GtkWidget *parent;
+
+ view = NAUTILUS_FILES_VIEW (widget);
+
+ parent = gtk_widget_get_parent (widget);
+ window = nautilus_files_view_get_window (view);
+ g_assert (parent == NULL || old_parent == NULL);
+
+ if (GTK_WIDGET_CLASS (nautilus_files_view_parent_class)->parent_set != NULL) {
+ GTK_WIDGET_CLASS (nautilus_files_view_parent_class)->parent_set (widget, old_parent);
+ }
+
+ if (view->details->stop_signal_handler > 0) {
+ g_signal_handler_disconnect (window, view->details->stop_signal_handler);
+ view->details->stop_signal_handler = 0;
+ }
+
+ if (view->details->reload_signal_handler > 0) {
+ g_signal_handler_disconnect (window, view->details->reload_signal_handler);
+ view->details->reload_signal_handler = 0;
+ }
+
+ if (parent != NULL) {
+ g_assert (old_parent == NULL);
+
+ if (view->details->slot == nautilus_window_get_active_slot (window)) {
+ view->details->active = TRUE;
+ gtk_widget_insert_action_group (GTK_WIDGET (nautilus_files_view_get_window (view)),
+ "view",
+ G_ACTION_GROUP (view->details->view_action_group));
+ }
+
+ view->details->stop_signal_handler =
+ g_signal_connect (window,
+ "action-enabled-changed::stop",
+ G_CALLBACK (action_stop_enabled_changed),
+ view);
+ view->details->reload_signal_handler =
+ g_signal_connect (window,
+ "action-enabled-changed::reload",
+ G_CALLBACK (action_reload_enabled_changed),
+ view);
+ } else {
+ remove_update_context_menus_timeout_callback (view);
+ gtk_widget_insert_action_group (GTK_WIDGET (nautilus_files_view_get_window (view)),
+ "view",
+ NULL);
+ }
+}
+
+static gboolean
+nautilus_files_view_key_press_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ NautilusFilesView *view;
+ gint i;
+
+ view = NAUTILUS_FILES_VIEW (widget);
+
+ for (i = 0; i < G_N_ELEMENTS (extra_view_keybindings); i++) {
+ if (extra_view_keybindings[i].keyval == event->keyval) {
+ GAction *action;
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (view->details->view_action_group),
+ extra_view_keybindings[i].action);
+
+ if (g_action_get_enabled (action)) {
+ g_action_activate (action, NULL);
+ return GDK_EVENT_STOP;
+ }
+
+ break;
+ }
+ }
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+static void
+nautilus_files_view_class_init (NautilusFilesViewClass *klass)
+{
+ GObjectClass *oclass;
+ GtkWidgetClass *widget_class;
+
+ widget_class = GTK_WIDGET_CLASS (klass);
+ oclass = G_OBJECT_CLASS (klass);
+
+ oclass->finalize = nautilus_files_view_finalize;
+ oclass->get_property = nautilus_files_view_get_property;
+ oclass->set_property = nautilus_files_view_set_property;
+
+ widget_class->destroy = nautilus_files_view_destroy;
+ widget_class->key_press_event = nautilus_files_view_key_press_event;
+ widget_class->scroll_event = nautilus_files_view_scroll_event;
+ widget_class->parent_set = nautilus_files_view_parent_set;
+ widget_class->grab_focus = nautilus_files_view_grab_focus;
+
+ g_type_class_add_private (klass, sizeof (NautilusFilesViewDetails));
+
+ signals[ADD_FILE] =
+ g_signal_new ("add-file",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NautilusFilesViewClass, add_file),
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 2, NAUTILUS_TYPE_FILE, NAUTILUS_TYPE_DIRECTORY);
+ signals[BEGIN_FILE_CHANGES] =
+ g_signal_new ("begin-file-changes",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NautilusFilesViewClass, begin_file_changes),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[BEGIN_LOADING] =
+ g_signal_new ("begin-loading",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NautilusFilesViewClass, begin_loading),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[CLEAR] =
+ g_signal_new ("clear",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NautilusFilesViewClass, clear),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[END_FILE_CHANGES] =
+ g_signal_new ("end-file-changes",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NautilusFilesViewClass, end_file_changes),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[END_LOADING] =
+ g_signal_new ("end-loading",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NautilusFilesViewClass, end_loading),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+ signals[FILE_CHANGED] =
+ g_signal_new ("file-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NautilusFilesViewClass, file_changed),
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 2, NAUTILUS_TYPE_FILE, NAUTILUS_TYPE_DIRECTORY);
+ signals[REMOVE_FILE] =
+ g_signal_new ("remove-file",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NautilusFilesViewClass, remove_file),
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 2, NAUTILUS_TYPE_FILE, NAUTILUS_TYPE_DIRECTORY);
+ signals[SELECTION_CHANGED] =
+ g_signal_new ("selection-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ klass->get_selected_icon_locations = real_get_selected_icon_locations;
+ klass->is_read_only = real_is_read_only;
+ klass->can_rename_file = can_rename_file;
+ klass->get_backing_uri = real_get_backing_uri;
+ klass->using_manual_layout = real_using_manual_layout;
+ klass->get_window = nautilus_files_view_get_window;
+ klass->update_context_menus = real_update_context_menus;
+ klass->update_actions_state = real_update_actions_state;
+
+ copied_files_atom = gdk_atom_intern ("x-special/gnome-copied-files", FALSE);
+
+ properties[PROP_WINDOW_SLOT] =
+ g_param_spec_object ("window-slot",
+ "Window Slot",
+ "The parent window slot reference",
+ NAUTILUS_TYPE_WINDOW_SLOT,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY);
+ properties[PROP_SUPPORTS_ZOOMING] =
+ g_param_spec_boolean ("supports-zooming",
+ "Supports zooming",
+ "Whether the view supports zooming",
+ TRUE,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+ properties[PROP_ICON] =
+ g_param_spec_object ("icon",
+ "Icon",
+ "The icon that represents the view",
+ G_TYPE_ICON,
+ G_PARAM_READABLE);
+
+ properties[PROP_VIEW_WIDGET] =
+ g_param_spec_object ("view-widget",
+ "View widget",
+ "The view's widget that will appear under the view menu button",
+ GTK_TYPE_WIDGET,
+ G_PARAM_READABLE);
+
+ g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
+}
+
+static void
+nautilus_files_view_init (NautilusFilesView *view)
+{
+ GtkBuilder *builder;
+ AtkObject *atk_object;
+ NautilusDirectory *scripts_directory;
+ NautilusDirectory *templates_directory;
+ gchar *templates_uri;
+ GApplication *app;
+ const gchar *open_accels[] = {
+ "<control>o",
+ "<alt>Down",
+ NULL
+ };
+
+ nautilus_profile_start (NULL);
+
+ view->details = G_TYPE_INSTANCE_GET_PRIVATE (view, NAUTILUS_TYPE_FILES_VIEW,
+ NautilusFilesViewDetails);
+
+ /* NautilusFloatingBar listen to its parent's 'enter-notify-event' signal
+ * and GtkOverlay doesn't have it enabled by default, so we have to add them
+ * here.
+ */
+ gtk_widget_add_events (GTK_WIDGET (view),
+ GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
+
+ /* View menu */
+ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-toolbar-view-menu.xml");
+ view->details->view_menu_widget = g_object_ref (gtk_builder_get_object (builder, "view_menu_widget"));
+ view->details->zoom_level_scale = GTK_WIDGET (gtk_builder_get_object (builder, "zoom_level_scale"));
+ view->details->zoom_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "zoom_adjustment"));
+
+ view->details->sort_menu = GTK_WIDGET (gtk_builder_get_object (builder, "sort_menu"));
+ view->details->sort_trash_time = GTK_WIDGET (gtk_builder_get_object (builder, "sort_trash_time"));
+ view->details->sort_search_relevance = GTK_WIDGET (gtk_builder_get_object (builder, "sort_search_relevance"));
+ view->details->visible_columns = GTK_WIDGET (gtk_builder_get_object (builder, "visible_columns"));
+ view->details->reload = GTK_WIDGET (gtk_builder_get_object (builder, "reload"));
+ view->details->stop = GTK_WIDGET (gtk_builder_get_object (builder, "stop"));
+
+ g_signal_connect (view->details->zoom_level_scale, "value-changed",
+ G_CALLBACK (zoom_level_changed), view);
+
+ g_object_unref (builder);
+
+ /* Scrolled Window */
+ view->details->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view->details->scrolled_window),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_widget_show (view->details->scrolled_window);
+
+ g_signal_connect_swapped (view->details->scrolled_window,
+ "scroll-event",
+ G_CALLBACK (nautilus_files_view_scroll_event),
+ view);
+
+ gtk_container_add (GTK_CONTAINER (view), view->details->scrolled_window);
+
+ /* Empty states */
+ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-no-search-results.ui");
+ view->details->no_search_results_widget = GTK_WIDGET (gtk_builder_get_object (builder, "no_search_results"));
+ gtk_overlay_add_overlay (GTK_OVERLAY (view), view->details->no_search_results_widget);
+ g_object_unref (builder);
+
+ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-folder-is-empty.ui");
+ view->details->folder_is_empty_widget = GTK_WIDGET (gtk_builder_get_object (builder, "folder_is_empty"));
+ gtk_overlay_add_overlay (GTK_OVERLAY (view), view->details->folder_is_empty_widget);
+ g_object_unref (builder);
+
+ /* Floating bar */
+ view->details->floating_bar = nautilus_floating_bar_new (NULL, NULL, FALSE);
+ gtk_widget_set_halign (view->details->floating_bar, GTK_ALIGN_END);
+ gtk_widget_set_valign (view->details->floating_bar, GTK_ALIGN_END);
+ gtk_overlay_add_overlay (GTK_OVERLAY (view), view->details->floating_bar);
+
+ g_signal_connect (view->details->floating_bar,
+ "action",
+ G_CALLBACK (floating_bar_action_cb),
+ view);
+
+ /* Default to true; desktop-icon-view sets to false */
+ view->details->show_foreign_files = TRUE;
+
+ view->details->non_ready_files =
+ g_hash_table_new_full (file_and_directory_hash,
+ file_and_directory_equal,
+ (GDestroyNotify)file_and_directory_free,
+ NULL);
+
+ gtk_style_context_set_junction_sides (gtk_widget_get_style_context (GTK_WIDGET (view)),
+ GTK_JUNCTION_TOP | GTK_JUNCTION_LEFT);
+
+ if (set_up_scripts_directory_global ()) {
+ scripts_directory = nautilus_directory_get_by_uri (scripts_directory_uri);
+ add_directory_to_scripts_directory_list (view, scripts_directory);
+ nautilus_directory_unref (scripts_directory);
+ } else {
+ g_warning ("Ignoring scripts directory, it may be a broken link\n");
+ }
+
+ if (nautilus_should_use_templates_directory ()) {
+ templates_uri = nautilus_get_templates_directory_uri ();
+ templates_directory = nautilus_directory_get_by_uri (templates_uri);
+ g_free (templates_uri);
+ add_directory_to_templates_directory_list (view, templates_directory);
+ nautilus_directory_unref (templates_directory);
+ }
+ update_templates_directory (view);
+
+ view->details->sort_directories_first =
+ g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
+ view->details->show_hidden_files =
+ g_settings_get_boolean (gtk_filechooser_preferences, NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES);
+
+ g_signal_connect_object (nautilus_trash_monitor_get (), "trash-state-changed",
+ G_CALLBACK (nautilus_files_view_trash_state_changed_callback), view, 0);
+
+ /* React to clipboard changes */
+ g_signal_connect_object (nautilus_clipboard_monitor_get (), "clipboard-changed",
+ G_CALLBACK (clipboard_changed_callback), view, 0);
+
+ /* Register to menu provider extension signal managing menu updates */
+ g_signal_connect_object (nautilus_signaller_get_current (), "popup-menu-changed",
+ G_CALLBACK (schedule_update_context_menus), view, G_CONNECT_SWAPPED);
+
+ gtk_widget_show (GTK_WIDGET (view));
+
+ g_signal_connect_swapped (nautilus_preferences,
+ "changed::" NAUTILUS_PREFERENCES_CLICK_POLICY,
+ G_CALLBACK (click_policy_changed_callback),
+ view);
+ g_signal_connect_swapped (nautilus_preferences,
+ "changed::" NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST,
+ G_CALLBACK (sort_directories_first_changed_callback), view);
+ g_signal_connect_swapped (gtk_filechooser_preferences,
+ "changed::" NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
+ G_CALLBACK (show_hidden_files_changed_callback), view);
+ g_signal_connect_swapped (gnome_lockdown_preferences,
+ "changed::" NAUTILUS_PREFERENCES_LOCKDOWN_COMMAND_LINE,
+ G_CALLBACK (schedule_update_context_menus), view);
+
+ /* Accessibility */
+ atk_object = gtk_widget_get_accessible (GTK_WIDGET (view));
+ atk_object_set_name (atk_object, _("Content View"));
+ atk_object_set_description (atk_object, _("View of the current folder"));
+
+ view->details->view_action_group = G_ACTION_GROUP (g_simple_action_group_new ());
+ g_action_map_add_action_entries (G_ACTION_MAP (view->details->view_action_group),
+ view_entries,
+ G_N_ELEMENTS (view_entries),
+ view);
+ gtk_widget_insert_action_group (GTK_WIDGET (view),
+ "view",
+ G_ACTION_GROUP (view->details->view_action_group));
+ app = g_application_get_default ();
+
+ /* Toolbar menu */
+ nautilus_application_add_accelerator (app, "view.zoom-in", "<control>plus");
+ nautilus_application_add_accelerator (app, "view.zoom-out", "<control>minus");
+ nautilus_application_add_accelerator (app, "view.show-hidden-files", "<control>h");
+ /* Background menu */
+ nautilus_application_add_accelerator (app, "view.select-all", "<control>a");
+ nautilus_application_add_accelerator (app, "view.paste", "<control>v");
+ /* Selection menu */
+ gtk_application_set_accels_for_action (GTK_APPLICATION (app),
+ "view.open-with-default-application", open_accels);
+ nautilus_application_add_accelerator (app, "view.open-item-new-tab", "<shift><control>t");
+ nautilus_application_add_accelerator (app, "view.open-item-new-window", "<shift><control>w");
+ nautilus_application_add_accelerator (app, "view.move-to-trash", "Delete");
+ nautilus_application_add_accelerator (app, "view.delete-from-trash", "Delete");
+ nautilus_application_add_accelerator (app, "view.delete-permanently-shortcut", "<shift>Delete");
+ nautilus_application_add_accelerator (app, "view.properties", "<control>i");
+ nautilus_application_add_accelerator (app, "view.open-item-location", "<control><alt>o");
+ nautilus_application_add_accelerator (app, "view.rename", "F2");
+ nautilus_application_add_accelerator (app, "view.cut", "<control>x");
+ nautilus_application_add_accelerator (app, "view.copy", "<control>c");
+ nautilus_application_add_accelerator (app, "view.new-folder", "<control><shift>n");
+ /* Only accesible by shorcuts */
+ nautilus_application_add_accelerator (app, "view.select-pattern", "<control>s");
+ nautilus_application_add_accelerator (app, "view.zoom-default", "<control>0");
+ nautilus_application_add_accelerator (app, "view.invert-selection", "<shift><control>i");
+ nautilus_application_add_accelerator (app, "view.open-file-and-close-window", "<control><shift>Down");
+
+ /* Show a warning dialog to inform the user that the shorcut for move to trash
+ * changed */
+ nautilus_application_add_accelerator (app, "view.show-move-to-trash-shortcut-changed-dialog", "<control>Delete");
+
+ nautilus_profile_end (NULL);
+}
+
+NautilusFilesView *
+nautilus_files_view_new (const gchar *id,
+ NautilusWindowSlot *slot)
+{
+ NautilusFilesView *view = NULL;
+
+ if (g_strcmp0 (id, NAUTILUS_CANVAS_VIEW_ID) == 0) {
+ view = nautilus_canvas_view_new (slot);
+ } else if (g_strcmp0 (id, NAUTILUS_LIST_VIEW_ID) == 0) {
+ view = nautilus_list_view_new (slot);
+ } else if (g_strcmp0 (id, NAUTILUS_DESKTOP_CANVAS_VIEW_ID) == 0) {
+ view = nautilus_desktop_canvas_view_new (slot);
+ }
+#if ENABLE_EMPTY_VIEW
+ else if (g_strcmp0 (id, NAUTILUS_EMPTY_VIEW_ID) == 0) {
+ view = nautilus_empty_view_new (slot);
+ }
+#endif
+
+ if (view == NULL) {
+ g_critical ("Unknown view type ID: %s", id);
+ } else if (g_object_is_floating (view)) {
+ g_object_ref_sink (view);
+ }
+
+ return view;
+}
diff --git a/src/nautilus-files-view.h b/src/nautilus-files-view.h
new file mode 100644
index 000000000..606a054c6
--- /dev/null
+++ b/src/nautilus-files-view.h
@@ -0,0 +1,401 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* nautilus-view.h
+ *
+ * Copyright (C) 1999, 2000 Free Software Foundaton
+ * Copyright (C) 2000, 2001 Eazel, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ettore Perazzoli
+ * Darin Adler <darin@bentspoon.com>
+ * John Sullivan <sullivan@eazel.com>
+ * Pavel Cisler <pavel@eazel.com>
+ */
+
+#ifndef NAUTILUS_FILES_VIEW_H
+#define NAUTILUS_FILES_VIEW_H
+
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+#include <libnautilus-private/nautilus-directory.h>
+#include <libnautilus-private/nautilus-file.h>
+#include <libnautilus-private/nautilus-link.h>
+
+typedef struct NautilusFilesView NautilusFilesView;
+typedef struct NautilusFilesViewClass NautilusFilesViewClass;
+
+#include "nautilus-window.h"
+#include "nautilus-window-slot.h"
+
+#if ENABLE_EMPTY_VIEW
+#define NAUTILUS_EMPTY_VIEW_ID "OAFIID:Nautilus_File_Manager_Empty_View"
+#endif
+
+#define NAUTILUS_CANVAS_VIEW_ID "OAFIID:Nautilus_File_Manager_Canvas_View"
+#define NAUTILUS_DESKTOP_CANVAS_VIEW_ID "OAFIID:Nautilus_File_Manager_Desktop_Canvas_View"
+#define NAUTILUS_LIST_VIEW_ID "OAFIID:Nautilus_File_Manager_List_View"
+
+#define NAUTILUS_TYPE_FILES_VIEW nautilus_files_view_get_type()
+#define NAUTILUS_FILES_VIEW(obj)\
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_FILES_VIEW, NautilusFilesView))
+#define NAUTILUS_FILES_VIEW_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_FILES_VIEW, NautilusFilesViewClass))
+#define NAUTILUS_IS_FILES_VIEW(obj)\
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_FILES_VIEW))
+#define NAUTILUS_IS_FILES_VIEW_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_FILES_VIEW))
+#define NAUTILUS_FILES_VIEW_GET_CLASS(obj)\
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_FILES_VIEW, NautilusFilesViewClass))
+
+typedef struct NautilusFilesViewDetails NautilusFilesViewDetails;
+
+struct NautilusFilesView {
+ GtkOverlay parent;
+
+ NautilusFilesViewDetails *details;
+};
+
+struct NautilusFilesViewClass {
+ GtkOverlayClass parent_class;
+
+ /* The 'clear' signal is emitted to empty the view of its contents.
+ * It must be replaced by each subclass.
+ */
+ void (* clear) (NautilusFilesView *view);
+
+ /* The 'begin_file_changes' signal is emitted before a set of files
+ * are added to the view. It can be replaced by a subclass to do any
+ * necessary preparation for a set of new files. The default
+ * implementation does nothing.
+ */
+ void (* begin_file_changes) (NautilusFilesView *view);
+
+ /* The 'add_file' signal is emitted to add one file to the view.
+ * It must be replaced by each subclass.
+ */
+ void (* add_file) (NautilusFilesView *view,
+ NautilusFile *file,
+ NautilusDirectory *directory);
+ void (* remove_file) (NautilusFilesView *view,
+ NautilusFile *file,
+ NautilusDirectory *directory);
+
+ /* The 'file_changed' signal is emitted to signal a change in a file,
+ * including the file being removed.
+ * It must be replaced by each subclass.
+ */
+ void (* file_changed) (NautilusFilesView *view,
+ NautilusFile *file,
+ NautilusDirectory *directory);
+
+ /* The 'end_file_changes' signal is emitted after a set of files
+ * are added to the view. It can be replaced by a subclass to do any
+ * necessary cleanup (typically, cleanup for code in begin_file_changes).
+ * The default implementation does nothing.
+ */
+ void (* end_file_changes) (NautilusFilesView *view);
+
+ /* The 'begin_loading' signal is emitted before any of the contents
+ * of a directory are added to the view. It can be replaced by a
+ * subclass to do any necessary preparation to start dealing with a
+ * new directory. The default implementation does nothing.
+ */
+ void (* begin_loading) (NautilusFilesView *view);
+
+ /* The 'end_loading' signal is emitted after all of the contents
+ * of a directory are added to the view. It can be replaced by a
+ * subclass to do any necessary clean-up. The default implementation
+ * does nothing.
+ *
+ * If all_files_seen is true, the handler may assume that
+ * no load error ocurred, and all files of the underlying
+ * directory were loaded.
+ *
+ * Otherwise, end_loading was emitted due to cancellation,
+ * which usually means that not all files are available.
+ */
+ void (* end_loading) (NautilusFilesView *view,
+ gboolean all_files_seen);
+
+ /* Function pointers that don't have corresponding signals */
+
+ /* get_backing uri is a function pointer for subclasses to
+ * override. Subclasses may replace it with a function that
+ * returns the URI for the location where to create new folders,
+ * files, links and paste the clipboard to.
+ */
+
+ char * (* get_backing_uri) (NautilusFilesView *view);
+
+ /* get_selection is not a signal; it is just a function pointer for
+ * subclasses to replace (override). Subclasses must replace it
+ * with a function that returns a newly-allocated GList of
+ * NautilusFile pointers.
+ */
+ GList * (* get_selection) (NautilusFilesView *view);
+
+ /* get_selection_for_file_transfer is a function pointer for
+ * subclasses to replace (override). Subclasses must replace it
+ * with a function that returns a newly-allocated GList of
+ * NautilusFile pointers. The difference from get_selection is
+ * that any files in the selection that also has a parent folder
+ * in the selection is not included.
+ */
+ GList * (* get_selection_for_file_transfer)(NautilusFilesView *view);
+
+ /* select_all is a function pointer that subclasses must override to
+ * select all of the items in the view */
+ void (* select_all) (NautilusFilesView *view);
+
+ /* select_first is a function pointer that subclasses must override to
+ * select the first item in the view */
+ void (* select_first) (NautilusFilesView *view);
+
+ /* set_selection is a function pointer that subclasses must
+ * override to select the specified items (and unselect all
+ * others). The argument is a list of NautilusFiles. */
+
+ void (* set_selection) (NautilusFilesView *view,
+ GList *selection);
+
+ /* invert_selection is a function pointer that subclasses must
+ * override to invert selection. */
+
+ void (* invert_selection) (NautilusFilesView *view);
+
+ /* Return an array of locations of selected icons in their view. */
+ GArray * (* get_selected_icon_locations) (NautilusFilesView *view);
+
+ /* bump_zoom_level is a function pointer that subclasses must override
+ * to change the zoom level of an object. */
+ void (* bump_zoom_level) (NautilusFilesView *view,
+ int zoom_increment);
+
+ /* restore_default_zoom_level is a function pointer that subclasses must override
+ * to restore the zoom level of an object to a default setting. */
+ void (* restore_default_zoom_level) (NautilusFilesView *view);
+
+ /* can_zoom_in is a function pointer that subclasses must override to
+ * return whether the view is at maximum size (furthest-in zoom level) */
+ gboolean (* can_zoom_in) (NautilusFilesView *view);
+
+ /* can_zoom_out is a function pointer that subclasses must override to
+ * return whether the view is at minimum size (furthest-out zoom level) */
+ gboolean (* can_zoom_out) (NautilusFilesView *view);
+
+ /* reveal_selection is a function pointer that subclasses may
+ * override to make sure the selected items are sufficiently
+ * apparent to the user (e.g., scrolled into view). By default,
+ * this does nothing.
+ */
+ void (* reveal_selection) (NautilusFilesView *view);
+
+ /* merge_menus is a function pointer that subclasses can override to
+ * add their own menu items to the window's menu bar.
+ * If overridden, subclasses must call parent class's function.
+ */
+ void (* merge_menus) (NautilusFilesView *view);
+ void (* unmerge_menus) (NautilusFilesView *view);
+
+ /* update_menus is a function pointer that subclasses can override to
+ * update the sensitivity or wording of menu items in the menu bar.
+ * It is called (at least) whenever the selection changes. If overridden,
+ * subclasses must call parent class's function.
+ */
+ void (* update_context_menus) (NautilusFilesView *view);
+
+ void (* update_actions_state) (NautilusFilesView *view);
+
+ /* sort_files is a function pointer that subclasses can override
+ * to provide a sorting order to determine which files should be
+ * presented when only a partial list is provided.
+ */
+ int (* compare_files) (NautilusFilesView *view,
+ NautilusFile *a,
+ NautilusFile *b);
+
+ /* using_manual_layout is a function pointer that subclasses may
+ * override to control whether or not items can be freely positioned
+ * on the user-visible area.
+ * Note that this value is not guaranteed to be constant within the
+ * view's lifecycle. */
+ gboolean (* using_manual_layout) (NautilusFilesView *view);
+
+ /* is_read_only is a function pointer that subclasses may
+ * override to control whether or not the user is allowed to
+ * change the contents of the currently viewed directory. The
+ * default implementation checks the permissions of the
+ * directory.
+ */
+ gboolean (* is_read_only) (NautilusFilesView *view);
+
+ /* is_empty is a function pointer that subclasses must
+ * override to report whether the view contains any items.
+ */
+ gboolean (* is_empty) (NautilusFilesView *view);
+
+ gboolean (* can_rename_file) (NautilusFilesView *view,
+ NautilusFile *file);
+
+ /* convert *point from widget's coordinate system to a coordinate
+ * system used for specifying file operation positions, which is view-specific.
+ *
+ * This is used by the the icon view, which converts the screen position to a zoom
+ * level-independent coordinate system.
+ */
+ void (* widget_to_file_operation_position) (NautilusFilesView *view,
+ GdkPoint *position);
+
+ /* Preference change callbacks, overriden by icon and list views.
+ * Icon and list views respond by synchronizing to the new preference
+ * values and forcing an update if appropriate.
+ */
+ void (* click_policy_changed) (NautilusFilesView *view);
+ void (* sort_directories_first_changed) (NautilusFilesView *view);
+
+ /* Get the id string for this view. Its a constant string, not memory managed */
+ const char * (* get_view_id) (NautilusFilesView *view);
+
+ /* Return the uri of the first visible file */
+ char * (* get_first_visible_file) (NautilusFilesView *view);
+ /* Scroll the view so that the file specified by the uri is at the top
+ of the view */
+ void (* scroll_to_file) (NautilusFilesView *view,
+ const char *uri);
+
+ NautilusWindow * (*get_window) (NautilusFilesView *view);
+
+ GdkRectangle * (*compute_rename_popover_relative_to) (NautilusFilesView *view);
+
+ GIcon * (* get_icon) (NautilusFilesView *view);
+};
+
+/* GObject support */
+GType nautilus_files_view_get_type (void);
+
+NautilusFilesView * nautilus_files_view_new (const gchar *id,
+ NautilusWindowSlot *slot);
+
+/* Functions callable from the user interface and elsewhere. */
+NautilusWindowSlot *nautilus_files_view_get_nautilus_window_slot (NautilusFilesView *view);
+char * nautilus_files_view_get_uri (NautilusFilesView *view);
+
+void nautilus_files_view_display_selection_info (NautilusFilesView *view);
+
+GdkAtom nautilus_files_view_get_copied_files_atom (NautilusFilesView *view);
+
+/* Wrappers for signal emitters. These are normally called
+ * only by NautilusFilesView itself. They have corresponding signals
+ * that observers might want to connect with.
+ */
+gboolean nautilus_files_view_get_loading (NautilusFilesView *view);
+
+/* Hooks for subclasses to call. These are normally called only by
+ * NautilusFilesView and its subclasses
+ */
+void nautilus_files_view_activate_files (NautilusFilesView *view,
+ GList *files,
+ NautilusWindowOpenFlags flags,
+ gboolean confirm_multiple);
+void nautilus_files_view_preview_files (NautilusFilesView *view,
+ GList *files,
+ GArray *locations);
+void nautilus_files_view_start_batching_selection_changes (NautilusFilesView *view);
+void nautilus_files_view_stop_batching_selection_changes (NautilusFilesView *view);
+void nautilus_files_view_notify_selection_changed (NautilusFilesView *view);
+NautilusDirectory *nautilus_files_view_get_model (NautilusFilesView *view);
+NautilusFile *nautilus_files_view_get_directory_as_file (NautilusFilesView *view);
+void nautilus_files_view_pop_up_background_context_menu (NautilusFilesView *view,
+ GdkEventButton *event);
+void nautilus_files_view_pop_up_selection_context_menu (NautilusFilesView *view,
+ GdkEventButton *event);
+gboolean nautilus_files_view_should_show_file (NautilusFilesView *view,
+ NautilusFile *file);
+gboolean nautilus_files_view_should_sort_directories_first (NautilusFilesView *view);
+void nautilus_files_view_ignore_hidden_file_preferences (NautilusFilesView *view);
+void nautilus_files_view_set_show_foreign (NautilusFilesView *view,
+ gboolean show_foreign);
+gboolean nautilus_files_view_handle_scroll_event (NautilusFilesView *view,
+ GdkEventScroll *event);
+
+void nautilus_files_view_add_subdirectory (NautilusFilesView *view,
+ NautilusDirectory *directory);
+void nautilus_files_view_remove_subdirectory (NautilusFilesView *view,
+ NautilusDirectory *directory);
+
+gboolean nautilus_files_view_is_editable (NautilusFilesView *view);
+NautilusWindow * nautilus_files_view_get_window (NautilusFilesView *view);
+
+/* NautilusFilesView methods */
+const char * nautilus_files_view_get_view_id (NautilusFilesView *view);
+
+/* file operations */
+char * nautilus_files_view_get_backing_uri (NautilusFilesView *view);
+void nautilus_files_view_move_copy_items (NautilusFilesView *view,
+ const GList *item_uris,
+ GArray *relative_item_points,
+ const char *target_uri,
+ int copy_action,
+ int x,
+ int y);
+void nautilus_files_view_new_file_with_initial_contents (NautilusFilesView *view,
+ const char *parent_uri,
+ const char *filename,
+ const char *initial_contents,
+ int length,
+ GdkPoint *pos);
+
+/* selection handling */
+void nautilus_files_view_activate_selection (NautilusFilesView *view);
+int nautilus_files_view_get_selection_count (NautilusFilesView *view);
+GList * nautilus_files_view_get_selection (NautilusFilesView *view);
+void nautilus_files_view_set_selection (NautilusFilesView *view,
+ GList *selection);
+
+
+void nautilus_files_view_load_location (NautilusFilesView *view,
+ GFile *location);
+void nautilus_files_view_stop_loading (NautilusFilesView *view);
+
+char * nautilus_files_view_get_first_visible_file (NautilusFilesView *view);
+void nautilus_files_view_scroll_to_file (NautilusFilesView *view,
+ const char *uri);
+char * nautilus_files_view_get_title (NautilusFilesView *view);
+gboolean nautilus_files_view_supports_zooming (NautilusFilesView *view);
+void nautilus_files_view_bump_zoom_level (NautilusFilesView *view,
+ int zoom_increment);
+void nautilus_files_view_zoom_to_level (NautilusFilesView *view,
+ gint level);
+void nautilus_files_view_restore_default_zoom_level (NautilusFilesView *view);
+gboolean nautilus_files_view_can_zoom_in (NautilusFilesView *view);
+gboolean nautilus_files_view_can_zoom_out (NautilusFilesView *view);
+void nautilus_files_view_update_menus (NautilusFilesView *view);
+
+void nautilus_files_view_update_context_menus (NautilusFilesView *view);
+void nautilus_files_view_update_toolbar_menus (NautilusFilesView *view);
+void nautilus_files_view_update_actions_state (NautilusFilesView *view);
+
+void nautilus_files_view_action_show_hidden_files (NautilusFilesView *view,
+ gboolean show_hidden);
+
+GActionGroup * nautilus_files_view_get_action_group (NautilusFilesView *view);
+GtkWidget* nautilus_files_view_get_content_widget (NautilusFilesView *view);
+gboolean nautilus_files_view_is_search (NautilusFilesView *view);
+
+GIcon* nautilus_files_view_get_icon (NautilusFilesView *view);
+
+GtkWidget* nautilus_files_view_get_view_widget (NautilusFilesView *view);
+
+#endif /* NAUTILUS_FILES_VIEW_H */
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index 3beff6626..195a6e3aa 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -29,7 +29,7 @@
#include "nautilus-list-model.h"
#include "nautilus-error-reporting.h"
-#include "nautilus-view-dnd.h"
+#include "nautilus-files-view-dnd.h"
#include "nautilus-toolbar.h"
#include <string.h>
@@ -126,8 +126,8 @@ static GdkCursor * hand_cursor = NULL;
static GtkTargetList * source_target_list = NULL;
-static GList *nautilus_list_view_get_selection (NautilusView *view);
-static GList *nautilus_list_view_get_selection_for_file_transfer (NautilusView *view);
+static GList *nautilus_list_view_get_selection (NautilusFilesView *view);
+static GList *nautilus_list_view_get_selection_for_file_transfer (NautilusFilesView *view);
static void nautilus_list_view_set_zoom_level (NautilusListView *view,
NautilusListZoomLevel new_level);
static void nautilus_list_view_scroll_to_file (NautilusListView *view,
@@ -142,7 +142,7 @@ static char **get_column_order (NautilusListVi
static char **get_default_column_order (NautilusListView *list_view);
-G_DEFINE_TYPE (NautilusListView, nautilus_list_view, NAUTILUS_TYPE_VIEW);
+G_DEFINE_TYPE (NautilusListView, nautilus_list_view, NAUTILUS_TYPE_FILES_VIEW);
static const char * default_search_visible_columns[] = {
"name", "size", "where", NULL
@@ -195,11 +195,11 @@ get_default_sort_order (NautilusFile *file, gboolean *reversed)
static void
list_selection_changed_callback (GtkTreeSelection *selection, gpointer user_data)
{
- NautilusView *view;
+ NautilusFilesView *view;
- view = NAUTILUS_VIEW (user_data);
+ view = NAUTILUS_FILES_VIEW (user_data);
- nautilus_view_notify_selection_changed (view);
+ nautilus_files_view_notify_selection_changed (view);
}
/* Move these to eel? */
@@ -236,10 +236,10 @@ preview_selected_items (NautilusListView *view)
{
GList *file_list;
- file_list = nautilus_list_view_get_selection (NAUTILUS_VIEW (view));
+ file_list = nautilus_list_view_get_selection (NAUTILUS_FILES_VIEW (view));
if (file_list != NULL) {
- nautilus_view_preview_files (NAUTILUS_VIEW (view),
+ nautilus_files_view_preview_files (NAUTILUS_FILES_VIEW (view),
file_list, NULL);
nautilus_file_list_free (file_list);
}
@@ -250,8 +250,8 @@ activate_selected_items (NautilusListView *view)
{
GList *file_list;
- file_list = nautilus_list_view_get_selection (NAUTILUS_VIEW (view));
- nautilus_view_activate_files (NAUTILUS_VIEW (view),
+ file_list = nautilus_list_view_get_selection (NAUTILUS_FILES_VIEW (view));
+ nautilus_files_view_activate_files (NAUTILUS_FILES_VIEW (view),
file_list,
0, TRUE);
nautilus_file_list_free (file_list);
@@ -278,9 +278,9 @@ activate_selected_items_alternate (NautilusListView *view,
nautilus_file_ref (file);
file_list = g_list_prepend (NULL, file);
} else {
- file_list = nautilus_list_view_get_selection (NAUTILUS_VIEW (view));
+ file_list = nautilus_list_view_get_selection (NAUTILUS_FILES_VIEW (view));
}
- nautilus_view_activate_files (NAUTILUS_VIEW (view),
+ nautilus_files_view_activate_files (NAUTILUS_FILES_VIEW (view),
file_list,
flags,
TRUE);
@@ -612,9 +612,9 @@ static void
do_popup_menu (GtkWidget *widget, NautilusListView *view, GdkEventButton *event)
{
if (tree_view_has_selection (GTK_TREE_VIEW (widget))) {
- nautilus_view_pop_up_selection_context_menu (NAUTILUS_VIEW (view), event);
+ nautilus_files_view_pop_up_selection_context_menu (NAUTILUS_FILES_VIEW (view), event);
} else {
- nautilus_view_pop_up_background_context_menu (NAUTILUS_VIEW (view), event);
+ nautilus_files_view_pop_up_background_context_menu (NAUTILUS_FILES_VIEW (view), event);
}
}
@@ -888,7 +888,7 @@ row_expanded_callback (GtkTreeView *treeview,
DEBUG ("Row expaded callback for uri %s", uri);
g_free (uri);
- nautilus_view_add_subdirectory (NAUTILUS_VIEW (view), directory);
+ nautilus_files_view_add_subdirectory (NAUTILUS_FILES_VIEW (view), directory);
if (nautilus_directory_are_all_files_seen (directory)) {
nautilus_list_model_subdirectory_done_loading (view->details->model,
@@ -1026,13 +1026,13 @@ subdirectory_unloaded_callback (NautilusListModel *model,
g_signal_handlers_disconnect_by_func (directory,
G_CALLBACK (subdirectory_done_loading_callback),
view);
- nautilus_view_remove_subdirectory (NAUTILUS_VIEW (view), directory);
+ nautilus_files_view_remove_subdirectory (NAUTILUS_FILES_VIEW (view), directory);
}
static gboolean
key_press_callback (GtkWidget *widget, GdkEventKey *event, gpointer callback_data)
{
- NautilusView *view;
+ NautilusFilesView *view;
GdkEventButton button_event = { 0 };
gboolean handled;
GtkTreeView *tree_view;
@@ -1040,13 +1040,13 @@ key_press_callback (GtkWidget *widget, GdkEventKey *event, gpointer callback_dat
tree_view = GTK_TREE_VIEW (widget);
- view = NAUTILUS_VIEW (callback_data);
+ view = NAUTILUS_FILES_VIEW (callback_data);
handled = FALSE;
switch (event->keyval) {
case GDK_KEY_F10:
if (event->state & GDK_CONTROL_MASK) {
- nautilus_view_pop_up_background_context_menu (view, &button_event);
+ nautilus_files_view_pop_up_background_context_menu (view, &button_event);
handled = TRUE;
}
break;
@@ -1124,13 +1124,13 @@ test_expand_row_callback (GtkTreeView *tree_view,
}
static void
-nautilus_list_view_reveal_selection (NautilusView *view)
+nautilus_list_view_reveal_selection (NautilusFilesView *view)
{
GList *selection;
g_return_if_fail (NAUTILUS_IS_LIST_VIEW (view));
- selection = nautilus_view_get_selection (view);
+ selection = nautilus_files_view_get_selection (view);
/* Make sure at least one of the selected items is scrolled into view */
if (selection != NULL) {
@@ -1188,7 +1188,7 @@ sort_column_changed_callback (GtkTreeSortable *sortable,
char *reversed_attr, *default_reversed_attr;
gboolean default_sort_reversed;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (view));
gtk_tree_sortable_get_sort_column_id (sortable, &sort_column_id, &reversed);
sort_attr = nautilus_list_model_get_attribute_from_sort_column_id (view->details->model, sort_column_id);
@@ -1229,7 +1229,7 @@ sort_column_changed_callback (GtkTreeSortable *sortable,
default_reversed_attr, reversed_attr);
/* Make sure selected item(s) is visible after sort */
- nautilus_list_view_reveal_selection (NAUTILUS_VIEW (view));
+ nautilus_list_view_reveal_selection (NAUTILUS_FILES_VIEW (view));
view->details->last_sort_attr = sort_attr;
}
@@ -1242,7 +1242,7 @@ get_root_uri_callback (NautilusTreeViewDragDest *dest,
view = NAUTILUS_LIST_VIEW (user_data);
- return nautilus_view_get_uri (NAUTILUS_VIEW (view));
+ return nautilus_files_view_get_uri (NAUTILUS_FILES_VIEW (view));
}
static NautilusFile *
@@ -1262,7 +1262,7 @@ static void
list_view_handle_netscape_url (NautilusTreeViewDragDest *dest, const char *encoded_url,
const char *target_uri, GdkDragAction action, int x, int y, NautilusListView *view)
{
- nautilus_view_handle_netscape_url_drop (NAUTILUS_VIEW (view),
+ nautilus_files_view_handle_netscape_url_drop (NAUTILUS_FILES_VIEW (view),
encoded_url, target_uri, action, x, y);
}
@@ -1271,7 +1271,7 @@ list_view_handle_uri_list (NautilusTreeViewDragDest *dest, const char *item_uris
const char *target_uri,
GdkDragAction action, int x, int y, NautilusListView *view)
{
- nautilus_view_handle_uri_list_drop (NAUTILUS_VIEW (view),
+ nautilus_files_view_handle_uri_list_drop (NAUTILUS_FILES_VIEW (view),
item_uris, target_uri, action, x, y);
}
@@ -1280,7 +1280,7 @@ list_view_handle_text (NautilusTreeViewDragDest *dest, const char *text,
const char *target_uri,
GdkDragAction action, int x, int y, NautilusListView *view)
{
- nautilus_view_handle_text_drop (NAUTILUS_VIEW (view),
+ nautilus_files_view_handle_text_drop (NAUTILUS_FILES_VIEW (view),
text, target_uri, action, x, y);
}
@@ -1289,7 +1289,7 @@ list_view_handle_raw (NautilusTreeViewDragDest *dest, const char *raw_data,
int length, const char *target_uri, const char *direct_save_uri,
GdkDragAction action, int x, int y, NautilusListView *view)
{
- nautilus_view_handle_raw_drop (NAUTILUS_VIEW (view),
+ nautilus_files_view_handle_raw_drop (NAUTILUS_FILES_VIEW (view),
raw_data, length, target_uri, direct_save_uri,
action, x, y);
}
@@ -1299,7 +1299,7 @@ list_view_handle_hover (NautilusTreeViewDragDest *dest,
const char *target_uri,
NautilusListView *view)
{
- nautilus_view_handle_hover (NAUTILUS_VIEW (view), target_uri);
+ nautilus_files_view_handle_hover (NAUTILUS_FILES_VIEW (view), target_uri);
}
static void
@@ -1312,12 +1312,12 @@ move_copy_items_callback (NautilusTreeViewDragDest *dest,
gpointer user_data)
{
- NautilusView *view = user_data;
+ NautilusFilesView *view = user_data;
nautilus_clipboard_clear_if_colliding_uris (GTK_WIDGET (view),
item_uris,
- nautilus_view_get_copied_files_atom (view));
- nautilus_view_move_copy_items (view,
+ nautilus_files_view_get_copied_files_atom (view));
+ nautilus_files_view_move_copy_items (view,
item_uris,
NULL,
target_uri,
@@ -1337,7 +1337,7 @@ column_header_menu_toggled (GtkCheckMenuItem *menu_item,
GList *l;
int i;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (list_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (list_view));
visible_columns = get_visible_columns (list_view);
column_order = get_column_order (list_view);
column = g_object_get_data (G_OBJECT (menu_item), "column-name");
@@ -1383,7 +1383,7 @@ column_header_menu_use_default (GtkMenuItem *menu_item,
char **default_columns;
char **default_order;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (list_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (list_view));
nautilus_file_set_metadata_list (file, NAUTILUS_METADATA_KEY_LIST_VIEW_COLUMN_ORDER, NULL);
nautilus_file_set_metadata_list (file, NAUTILUS_METADATA_KEY_LIST_VIEW_VISIBLE_COLUMNS, NULL);
@@ -1419,7 +1419,7 @@ column_header_clicked (GtkWidget *column_button,
return FALSE;
}
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (list_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (list_view));
visible_columns = get_visible_columns (list_view);
column_order = get_column_order (list_view);
@@ -1518,7 +1518,7 @@ apply_columns_settings (NautilusListView *list_view,
GList *l;
int i;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (list_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (list_view));
/* prepare ordered list of view columns using column_order and visible_columns */
view_columns = NULL;
@@ -1641,7 +1641,7 @@ location_cell_data_func (GtkTreeViewColumn *column,
GFile *base_location;
gchar *where = NULL;
- directory = nautilus_view_get_model (NAUTILUS_VIEW (view));
+ directory = nautilus_files_view_get_model (NAUTILUS_FILES_VIEW (view));
home_location = g_file_new_for_path (g_get_home_dir ());
@@ -1803,7 +1803,7 @@ create_and_set_up_tree_view (NautilusListView *view)
gchar **default_column_order, **default_visible_columns;
GtkWidget *content_widget;
- content_widget = nautilus_view_get_content_widget (NAUTILUS_VIEW (view));
+ content_widget = nautilus_files_view_get_content_widget (NAUTILUS_FILES_VIEW (view));
view->details->tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
view->details->columns = g_hash_table_new_full (g_str_hash,
g_str_equal,
@@ -2045,7 +2045,7 @@ create_and_set_up_tree_view (NautilusListView *view)
}
static void
-nautilus_list_view_add_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
+nautilus_list_view_add_file (NautilusFilesView *view, NautilusFile *file, NautilusDirectory *directory)
{
NautilusListModel *model;
@@ -2059,13 +2059,13 @@ get_default_visible_columns (NautilusListView *list_view)
NautilusFile *file;
NautilusDirectory *directory;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (list_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (list_view));
if (nautilus_file_is_in_trash (file)) {
return g_strdupv ((gchar **) default_trash_visible_columns);
}
- directory = nautilus_view_get_model (NAUTILUS_VIEW (list_view));
+ directory = nautilus_files_view_get_model (NAUTILUS_FILES_VIEW (list_view));
if (NAUTILUS_IS_SEARCH_DIRECTORY (directory)) {
return g_strdupv ((gchar **) default_search_visible_columns);
}
@@ -2080,7 +2080,7 @@ get_visible_columns (NautilusListView *list_view)
NautilusFile *file;
GList *visible_columns;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (list_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (list_view));
visible_columns = nautilus_file_get_metadata_list
(file,
@@ -2110,13 +2110,13 @@ get_default_column_order (NautilusListView *list_view)
NautilusFile *file;
NautilusDirectory *directory;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (list_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (list_view));
if (nautilus_file_is_in_trash (file)) {
return g_strdupv ((gchar **) default_trash_columns_order);
}
- directory = nautilus_view_get_model (NAUTILUS_VIEW (list_view));
+ directory = nautilus_files_view_get_model (NAUTILUS_FILES_VIEW (list_view));
if (NAUTILUS_IS_SEARCH_DIRECTORY (directory)) {
return g_strdupv ((gchar **) default_search_columns_order);
}
@@ -2131,7 +2131,7 @@ get_column_order (NautilusListView *list_view)
NautilusFile *file;
GList *column_order;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (list_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (list_view));
column_order = nautilus_file_get_metadata_list
(file,
@@ -2179,7 +2179,7 @@ set_sort_order_from_metadata_and_preferences (NautilusListView *list_view)
gboolean sort_reversed, default_sort_reversed;
const gchar *default_sort_order;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (list_view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (list_view));
sort_attribute = nautilus_file_get_metadata (file,
NAUTILUS_METADATA_KEY_LIST_VIEW_SORT_COLUMN,
NULL);
@@ -2220,7 +2220,7 @@ get_default_zoom_level (void) {
}
static void
-nautilus_list_view_begin_loading (NautilusView *view)
+nautilus_list_view_begin_loading (NautilusFilesView *view)
{
NautilusListView *list_view;
@@ -2231,7 +2231,7 @@ nautilus_list_view_begin_loading (NautilusView *view)
}
static void
-nautilus_list_view_clear (NautilusView *view)
+nautilus_list_view_clear (NautilusFilesView *view)
{
NautilusListView *list_view;
@@ -2243,7 +2243,7 @@ nautilus_list_view_clear (NautilusView *view)
}
static void
-nautilus_list_view_file_changed (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
+nautilus_list_view_file_changed (NautilusFilesView *view, NautilusFile *file, NautilusDirectory *directory)
{
NautilusListView *listview;
@@ -2317,7 +2317,7 @@ tree_selection_has_common_parent (GtkTreeSelection *selection,
}
static char *
-nautilus_list_view_get_backing_uri (NautilusView *view)
+nautilus_list_view_get_backing_uri (NautilusFilesView *view)
{
NautilusListView *list_view;
NautilusListModel *list_model;
@@ -2382,7 +2382,7 @@ nautilus_list_view_get_backing_uri (NautilusView *view)
/* Check that all the selected items belong to the same
* directory and that directory is not the root directory (which
- * is handled by NautilusView::get_backing_directory.) */
+ * is handled by NautilusFilesView::get_backing_directory.) */
tree_selection_has_common_parent (selection, &is_common, &is_root);
@@ -2403,7 +2403,7 @@ nautilus_list_view_get_backing_uri (NautilusView *view)
return uri;
}
- return NAUTILUS_VIEW_CLASS (nautilus_list_view_parent_class)->get_backing_uri (view);
+ return NAUTILUS_FILES_VIEW_CLASS (nautilus_list_view_parent_class)->get_backing_uri (view);
}
static void
@@ -2424,7 +2424,7 @@ nautilus_list_view_get_selection_foreach_func (GtkTreeModel *model, GtkTreePath
}
static GList *
-nautilus_list_view_get_selection (NautilusView *view)
+nautilus_list_view_get_selection (NautilusFilesView *view)
{
GList *list;
@@ -2470,7 +2470,7 @@ nautilus_list_view_get_selection_for_file_transfer_foreach_func (GtkTreeModel *m
static GList *
-nautilus_list_view_get_selection_for_file_transfer (NautilusView *view)
+nautilus_list_view_get_selection_for_file_transfer (NautilusFilesView *view)
{
struct SelectionForeachData selection_data;
@@ -2484,13 +2484,13 @@ nautilus_list_view_get_selection_for_file_transfer (NautilusView *view)
}
static gboolean
-nautilus_list_view_is_empty (NautilusView *view)
+nautilus_list_view_is_empty (NautilusFilesView *view)
{
return nautilus_list_model_is_empty (NAUTILUS_LIST_VIEW (view)->details->model);
}
static void
-nautilus_list_view_end_file_changes (NautilusView *view)
+nautilus_list_view_end_file_changes (NautilusFilesView *view)
{
NautilusListView *list_view;
@@ -2506,7 +2506,7 @@ nautilus_list_view_end_file_changes (NautilusView *view)
}
static void
-nautilus_list_view_remove_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
+nautilus_list_view_remove_file (NautilusFilesView *view, NautilusFile *file, NautilusDirectory *directory)
{
GtkTreePath *path;
GtkTreePath *file_path;
@@ -2565,7 +2565,7 @@ nautilus_list_view_remove_file (NautilusView *view, NautilusFile *file, Nautilus
}
static void
-nautilus_list_view_set_selection (NautilusView *view, GList *selection)
+nautilus_list_view_set_selection (NautilusFilesView *view, GList *selection)
{
NautilusListView *list_view;
GtkTreeSelection *tree_selection;
@@ -2591,11 +2591,11 @@ nautilus_list_view_set_selection (NautilusView *view, GList *selection)
}
g_signal_handlers_unblock_by_func (tree_selection, list_selection_changed_callback, view);
- nautilus_view_notify_selection_changed (view);
+ nautilus_files_view_notify_selection_changed (view);
}
static void
-nautilus_list_view_invert_selection (NautilusView *view)
+nautilus_list_view_invert_selection (NautilusFilesView *view)
{
NautilusListView *list_view;
GtkTreeSelection *tree_selection;
@@ -2628,17 +2628,17 @@ nautilus_list_view_invert_selection (NautilusView *view)
g_list_free (selection);
g_signal_handlers_unblock_by_func (tree_selection, list_selection_changed_callback, view);
- nautilus_view_notify_selection_changed (view);
+ nautilus_files_view_notify_selection_changed (view);
}
static void
-nautilus_list_view_select_all (NautilusView *view)
+nautilus_list_view_select_all (NautilusFilesView *view)
{
gtk_tree_selection_select_all (gtk_tree_view_get_selection (NAUTILUS_LIST_VIEW (view)->details->tree_view));
}
static void
-nautilus_list_view_select_first (NautilusView *view)
+nautilus_list_view_select_first (NautilusFilesView *view)
{
GtkTreeSelection *selection;
GtkTreeIter iter;
@@ -2651,7 +2651,7 @@ nautilus_list_view_select_first (NautilusView *view)
}
static void
-nautilus_list_view_zoom_to_level (NautilusView *view,
+nautilus_list_view_zoom_to_level (NautilusFilesView *view,
gint zoom_level)
{
NautilusListView *list_view;
@@ -2665,10 +2665,10 @@ nautilus_list_view_zoom_to_level (NautilusView *view,
}
nautilus_list_view_set_zoom_level (list_view, zoom_level);
- g_action_group_change_action_state (nautilus_view_get_action_group (view),
+ g_action_group_change_action_state (nautilus_files_view_get_action_group (view),
"zoom-to-level", g_variant_new_int32 (zoom_level));
- nautilus_view_update_toolbar_menus (view);
+ nautilus_files_view_update_toolbar_menus (view);
}
static void
@@ -2676,12 +2676,12 @@ action_zoom_to_level (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
- NautilusView *view;
+ NautilusFilesView *view;
NautilusListZoomLevel zoom_level;
- g_assert (NAUTILUS_IS_VIEW (user_data));
+ g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
- view = NAUTILUS_VIEW (user_data);
+ view = NAUTILUS_FILES_VIEW (user_data);
zoom_level = g_variant_get_int32 (state);
nautilus_list_view_zoom_to_level (view, zoom_level);
@@ -2709,7 +2709,7 @@ column_chooser_changed_callback (NautilusColumnChooser *chooser,
GList *list;
int i;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (view));
nautilus_column_chooser_get_settings (chooser,
&visible_columns,
@@ -2783,8 +2783,8 @@ column_chooser_use_default_callback (NautilusColumnChooser *chooser,
char **default_columns;
char **default_order;
- file = nautilus_view_get_directory_as_file
- (NAUTILUS_VIEW (view));
+ file = nautilus_files_view_get_directory_as_file
+ (NAUTILUS_FILES_VIEW (view));
nautilus_file_set_metadata_list (file, NAUTILUS_METADATA_KEY_LIST_VIEW_COLUMN_ORDER, NULL);
nautilus_file_set_metadata_list (file, NAUTILUS_METADATA_KEY_LIST_VIEW_VISIBLE_COLUMNS, NULL);
@@ -2816,7 +2816,7 @@ create_column_editor (NautilusListView *view)
char *name;
const char *label_text;
- file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (view));
+ file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (view));
name = nautilus_file_get_display_name (file);
str = g_strdup_printf (_("%s Visible Columns"), name);
g_free (name);
@@ -2924,7 +2924,7 @@ nautilus_list_view_set_zoom_level (NautilusListView *view,
}
static void
-nautilus_list_view_bump_zoom_level (NautilusView *view, int zoom_increment)
+nautilus_list_view_bump_zoom_level (NautilusFilesView *view, int zoom_increment)
{
NautilusListView *list_view;
gint new_level;
@@ -2941,7 +2941,7 @@ nautilus_list_view_bump_zoom_level (NautilusView *view, int zoom_increment)
}
static void
-nautilus_list_view_restore_default_zoom_level (NautilusView *view)
+nautilus_list_view_restore_default_zoom_level (NautilusFilesView *view)
{
g_return_if_fail (NAUTILUS_IS_LIST_VIEW (view));
@@ -2949,7 +2949,7 @@ nautilus_list_view_restore_default_zoom_level (NautilusView *view)
}
static gboolean
-nautilus_list_view_can_zoom_in (NautilusView *view)
+nautilus_list_view_can_zoom_in (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_LIST_VIEW (view), FALSE);
@@ -2957,7 +2957,7 @@ nautilus_list_view_can_zoom_in (NautilusView *view)
}
static gboolean
-nautilus_list_view_can_zoom_out (NautilusView *view)
+nautilus_list_view_can_zoom_out (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_LIST_VIEW (view), FALSE);
@@ -2965,7 +2965,7 @@ nautilus_list_view_can_zoom_out (NautilusView *view)
}
static void
-nautilus_list_view_click_policy_changed (NautilusView *directory_view)
+nautilus_list_view_click_policy_changed (NautilusFilesView *directory_view)
{
GdkWindow *win;
GdkDisplay *display;
@@ -3038,18 +3038,18 @@ default_column_order_changed_callback (gpointer callback_data)
}
static void
-nautilus_list_view_sort_directories_first_changed (NautilusView *view)
+nautilus_list_view_sort_directories_first_changed (NautilusFilesView *view)
{
NautilusListView *list_view;
list_view = NAUTILUS_LIST_VIEW (view);
nautilus_list_model_set_should_sort_directories_first (list_view->details->model,
- nautilus_view_should_sort_directories_first (view));
+ nautilus_files_view_should_sort_directories_first (view));
}
static int
-nautilus_list_view_compare_files (NautilusView *view, NautilusFile *file1, NautilusFile *file2)
+nautilus_list_view_compare_files (NautilusFilesView *view, NautilusFile *file1, NautilusFile *file2)
{
NautilusListView *list_view;
@@ -3058,7 +3058,7 @@ nautilus_list_view_compare_files (NautilusView *view, NautilusFile *file1, Nauti
}
static gboolean
-nautilus_list_view_using_manual_layout (NautilusView *view)
+nautilus_list_view_using_manual_layout (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_LIST_VIEW (view), FALSE);
@@ -3140,7 +3140,7 @@ nautilus_list_view_finalize (GObject *object)
}
static char *
-nautilus_list_view_get_first_visible_file (NautilusView *view)
+nautilus_list_view_get_first_visible_file (NautilusFilesView *view)
{
NautilusFile *file;
GtkTreePath *path;
@@ -3196,7 +3196,7 @@ nautilus_list_view_scroll_to_file (NautilusListView *view,
}
static void
-list_view_scroll_to_file (NautilusView *view,
+list_view_scroll_to_file (NautilusFilesView *view,
const char *uri)
{
NautilusFile *file;
@@ -3232,7 +3232,7 @@ list_view_notify_clipboard_info (NautilusClipboardMonitor *monitor,
}
static void
-nautilus_list_view_end_loading (NautilusView *view,
+nautilus_list_view_end_loading (NautilusFilesView *view,
gboolean all_files_seen)
{
NautilusClipboardMonitor *monitor;
@@ -3245,13 +3245,13 @@ nautilus_list_view_end_loading (NautilusView *view,
}
static const char *
-nautilus_list_view_get_id (NautilusView *view)
+nautilus_list_view_get_id (NautilusFilesView *view)
{
return NAUTILUS_LIST_VIEW_ID;
}
static GdkRectangle*
-nautilus_list_view_compute_rename_popover_relative_to (NautilusView *view)
+nautilus_list_view_compute_rename_popover_relative_to (NautilusFilesView *view)
{
GtkTreeSelection *selection;
GtkTreePath *path;
@@ -3286,7 +3286,7 @@ nautilus_list_view_compute_rename_popover_relative_to (NautilusView *view)
}
static GIcon*
-nautilus_list_view_get_icon (NautilusView *view)
+nautilus_list_view_get_icon (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_LIST_VIEW (view), NULL);
@@ -3296,42 +3296,42 @@ nautilus_list_view_get_icon (NautilusView *view)
static void
nautilus_list_view_class_init (NautilusListViewClass *class)
{
- NautilusViewClass *nautilus_view_class;
+ NautilusFilesViewClass *nautilus_files_view_class;
- nautilus_view_class = NAUTILUS_VIEW_CLASS (class);
+ nautilus_files_view_class = NAUTILUS_FILES_VIEW_CLASS (class);
G_OBJECT_CLASS (class)->dispose = nautilus_list_view_dispose;
G_OBJECT_CLASS (class)->finalize = nautilus_list_view_finalize;
- nautilus_view_class->add_file = nautilus_list_view_add_file;
- nautilus_view_class->begin_loading = nautilus_list_view_begin_loading;
- nautilus_view_class->end_loading = nautilus_list_view_end_loading;
- nautilus_view_class->bump_zoom_level = nautilus_list_view_bump_zoom_level;
- nautilus_view_class->can_zoom_in = nautilus_list_view_can_zoom_in;
- nautilus_view_class->can_zoom_out = nautilus_list_view_can_zoom_out;
- nautilus_view_class->click_policy_changed = nautilus_list_view_click_policy_changed;
- nautilus_view_class->clear = nautilus_list_view_clear;
- nautilus_view_class->file_changed = nautilus_list_view_file_changed;
- nautilus_view_class->get_backing_uri = nautilus_list_view_get_backing_uri;
- nautilus_view_class->get_selection = nautilus_list_view_get_selection;
- nautilus_view_class->get_selection_for_file_transfer = nautilus_list_view_get_selection_for_file_transfer;
- nautilus_view_class->is_empty = nautilus_list_view_is_empty;
- nautilus_view_class->remove_file = nautilus_list_view_remove_file;
- nautilus_view_class->restore_default_zoom_level = nautilus_list_view_restore_default_zoom_level;
- nautilus_view_class->reveal_selection = nautilus_list_view_reveal_selection;
- nautilus_view_class->select_all = nautilus_list_view_select_all;
- nautilus_view_class->select_first = nautilus_list_view_select_first;
- nautilus_view_class->set_selection = nautilus_list_view_set_selection;
- nautilus_view_class->invert_selection = nautilus_list_view_invert_selection;
- nautilus_view_class->compare_files = nautilus_list_view_compare_files;
- nautilus_view_class->sort_directories_first_changed = nautilus_list_view_sort_directories_first_changed;
- nautilus_view_class->end_file_changes = nautilus_list_view_end_file_changes;
- nautilus_view_class->using_manual_layout = nautilus_list_view_using_manual_layout;
- nautilus_view_class->get_view_id = nautilus_list_view_get_id;
- nautilus_view_class->get_first_visible_file = nautilus_list_view_get_first_visible_file;
- nautilus_view_class->scroll_to_file = list_view_scroll_to_file;
- nautilus_view_class->compute_rename_popover_relative_to = nautilus_list_view_compute_rename_popover_relative_to;
- nautilus_view_class->get_icon = nautilus_list_view_get_icon;
+ nautilus_files_view_class->add_file = nautilus_list_view_add_file;
+ nautilus_files_view_class->begin_loading = nautilus_list_view_begin_loading;
+ nautilus_files_view_class->end_loading = nautilus_list_view_end_loading;
+ nautilus_files_view_class->bump_zoom_level = nautilus_list_view_bump_zoom_level;
+ nautilus_files_view_class->can_zoom_in = nautilus_list_view_can_zoom_in;
+ nautilus_files_view_class->can_zoom_out = nautilus_list_view_can_zoom_out;
+ nautilus_files_view_class->click_policy_changed = nautilus_list_view_click_policy_changed;
+ nautilus_files_view_class->clear = nautilus_list_view_clear;
+ nautilus_files_view_class->file_changed = nautilus_list_view_file_changed;
+ nautilus_files_view_class->get_backing_uri = nautilus_list_view_get_backing_uri;
+ nautilus_files_view_class->get_selection = nautilus_list_view_get_selection;
+ nautilus_files_view_class->get_selection_for_file_transfer = nautilus_list_view_get_selection_for_file_transfer;
+ nautilus_files_view_class->is_empty = nautilus_list_view_is_empty;
+ nautilus_files_view_class->remove_file = nautilus_list_view_remove_file;
+ nautilus_files_view_class->restore_default_zoom_level = nautilus_list_view_restore_default_zoom_level;
+ nautilus_files_view_class->reveal_selection = nautilus_list_view_reveal_selection;
+ nautilus_files_view_class->select_all = nautilus_list_view_select_all;
+ nautilus_files_view_class->select_first = nautilus_list_view_select_first;
+ nautilus_files_view_class->set_selection = nautilus_list_view_set_selection;
+ nautilus_files_view_class->invert_selection = nautilus_list_view_invert_selection;
+ nautilus_files_view_class->compare_files = nautilus_list_view_compare_files;
+ nautilus_files_view_class->sort_directories_first_changed = nautilus_list_view_sort_directories_first_changed;
+ nautilus_files_view_class->end_file_changes = nautilus_list_view_end_file_changes;
+ nautilus_files_view_class->using_manual_layout = nautilus_list_view_using_manual_layout;
+ nautilus_files_view_class->get_view_id = nautilus_list_view_get_id;
+ nautilus_files_view_class->get_first_visible_file = nautilus_list_view_get_first_visible_file;
+ nautilus_files_view_class->scroll_to_file = list_view_scroll_to_file;
+ nautilus_files_view_class->compute_rename_popover_relative_to = nautilus_list_view_compute_rename_popover_relative_to;
+ nautilus_files_view_class->get_icon = nautilus_list_view_get_icon;
}
static void
@@ -3364,9 +3364,9 @@ nautilus_list_view_init (NautilusListView *list_view)
G_CALLBACK (default_column_order_changed_callback),
list_view);
- nautilus_list_view_click_policy_changed (NAUTILUS_VIEW (list_view));
+ nautilus_list_view_click_policy_changed (NAUTILUS_FILES_VIEW (list_view));
- nautilus_list_view_sort_directories_first_changed (NAUTILUS_VIEW (list_view));
+ nautilus_list_view_sort_directories_first_changed (NAUTILUS_FILES_VIEW (list_view));
nautilus_list_view_set_zoom_level (list_view, get_default_zoom_level ());
list_view->details->hover_path = NULL;
@@ -3375,17 +3375,17 @@ nautilus_list_view_init (NautilusListView *list_view)
"clipboard-info",
G_CALLBACK (list_view_notify_clipboard_info), list_view);
- view_action_group = nautilus_view_get_action_group (NAUTILUS_VIEW (list_view));
+ view_action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (list_view));
g_action_map_add_action_entries (G_ACTION_MAP (view_action_group),
list_view_entries,
G_N_ELEMENTS (list_view_entries),
list_view);
/* Keep the action synced with the actual value, so the toolbar can poll it */
- g_action_group_change_action_state (nautilus_view_get_action_group (NAUTILUS_VIEW (list_view)),
+ g_action_group_change_action_state (nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (list_view)),
"zoom-to-level", g_variant_new_int32 (get_default_zoom_level ()));
}
-NautilusView *
+NautilusFilesView *
nautilus_list_view_new (NautilusWindowSlot *slot)
{
return g_object_new (NAUTILUS_TYPE_LIST_VIEW,
diff --git a/src/nautilus-list-view.h b/src/nautilus-list-view.h
index caeee0830..03f027e82 100644
--- a/src/nautilus-list-view.h
+++ b/src/nautilus-list-view.h
@@ -26,7 +26,7 @@
#ifndef NAUTILUS_LIST_VIEW_H
#define NAUTILUS_LIST_VIEW_H
-#include "nautilus-view.h"
+#include "nautilus-files-view.h"
#define NAUTILUS_TYPE_LIST_VIEW nautilus_list_view_get_type()
#define NAUTILUS_LIST_VIEW(obj) \
@@ -43,15 +43,15 @@
typedef struct NautilusListViewDetails NautilusListViewDetails;
typedef struct {
- NautilusView parent_instance;
+ NautilusFilesView parent_instance;
NautilusListViewDetails *details;
} NautilusListView;
typedef struct {
- NautilusViewClass parent_class;
+ NautilusFilesViewClass parent_class;
} NautilusListViewClass;
GType nautilus_list_view_get_type (void);
-NautilusView * nautilus_list_view_new (NautilusWindowSlot *slot);
+NautilusFilesView * nautilus_list_view_new (NautilusWindowSlot *slot);
#endif /* NAUTILUS_LIST_VIEW_H */
diff --git a/src/nautilus-trash-bar.c b/src/nautilus-trash-bar.c
index ac6630857..0508198e9 100644
--- a/src/nautilus-trash-bar.c
+++ b/src/nautilus-trash-bar.c
@@ -26,7 +26,7 @@
#include "nautilus-trash-bar.h"
-#include "nautilus-view.h"
+#include "nautilus-files-view.h"
#include <libnautilus-private/nautilus-file-operations.h>
#include <libnautilus-private/nautilus-file-utilities.h>
#include <libnautilus-private/nautilus-file.h>
@@ -47,19 +47,19 @@ enum {
struct NautilusTrashBarPrivate
{
- NautilusView *view;
+ NautilusFilesView *view;
gulong selection_handler_id;
};
G_DEFINE_TYPE (NautilusTrashBar, nautilus_trash_bar, GTK_TYPE_INFO_BAR);
static void
-selection_changed_cb (NautilusView *view,
+selection_changed_cb (NautilusFilesView *view,
NautilusTrashBar *bar)
{
int count;
- count = nautilus_view_get_selection_count (view);
+ count = nautilus_files_view_get_selection_count (view);
gtk_info_bar_set_response_sensitive (GTK_INFO_BAR (bar),
TRASH_BAR_RESPONSE_RESTORE,
@@ -140,8 +140,8 @@ nautilus_trash_bar_class_init (NautilusTrashBarClass *klass)
PROP_VIEW,
g_param_spec_object ("view",
"view",
- "the NautilusView",
- NAUTILUS_TYPE_VIEW,
+ "the NautilusFilesView",
+ NAUTILUS_TYPE_FILES_VIEW,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
@@ -166,7 +166,7 @@ trash_bar_response_cb (GtkInfoBar *infobar,
nautilus_file_operations_empty_trash (window);
break;
case TRASH_BAR_RESPONSE_RESTORE:
- files = nautilus_view_get_selection (bar->priv->view);
+ files = nautilus_files_view_get_selection (bar->priv->view);
nautilus_restore_files_from_trash (files, GTK_WINDOW (window));
nautilus_file_list_free (files);
break;
@@ -224,7 +224,7 @@ nautilus_trash_bar_init (NautilusTrashBar *bar)
}
GtkWidget *
-nautilus_trash_bar_new (NautilusView *view)
+nautilus_trash_bar_new (NautilusFilesView *view)
{
return g_object_new (NAUTILUS_TYPE_TRASH_BAR,
"view", view,
diff --git a/src/nautilus-trash-bar.h b/src/nautilus-trash-bar.h
index 9190415fd..234cc84d0 100644
--- a/src/nautilus-trash-bar.h
+++ b/src/nautilus-trash-bar.h
@@ -22,7 +22,7 @@
#ifndef __NAUTILUS_TRASH_BAR_H
#define __NAUTILUS_TRASH_BAR_H
-#include "nautilus-view.h"
+#include "nautilus-files-view.h"
#include <gtk/gtk.h>
@@ -51,7 +51,7 @@ typedef struct
GType nautilus_trash_bar_get_type (void) G_GNUC_CONST;
-GtkWidget *nautilus_trash_bar_new (NautilusView *view);
+GtkWidget *nautilus_trash_bar_new (NautilusFilesView *view);
G_END_DECLS
diff --git a/src/nautilus-view-dnd.c b/src/nautilus-view-dnd.c
deleted file mode 100644
index d9fe0fe69..000000000
--- a/src/nautilus-view-dnd.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-
-/*
- * nautilus-view-dnd.c: DnD helpers for NautilusView
- *
- * Copyright (C) 1999, 2000 Free Software Foundaton
- * Copyright (C) 2000, 2001 Eazel, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Ettore Perazzoli
- * Darin Adler <darin@bentspoon.com>
- * John Sullivan <sullivan@eazel.com>
- * Pavel Cisler <pavel@eazel.com>
- */
-
-#include <config.h>
-
-#include "nautilus-view-dnd.h"
-
-#include "nautilus-view.h"
-
-#include <eel/eel-stock-dialogs.h>
-#include <eel/eel-string.h>
-
-#include <glib/gi18n.h>
-
-#include <libnautilus-private/nautilus-clipboard.h>
-#include <libnautilus-private/nautilus-dnd.h>
-
-#define GET_ANCESTOR(obj) \
- GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (obj), GTK_TYPE_WINDOW))
-
-static inline void
-view_widget_to_file_operation_position (NautilusView *view,
- GdkPoint *position)
-{
- NautilusViewClass *class = NAUTILUS_VIEW_GET_CLASS (view);
-
- if (class->widget_to_file_operation_position != NULL) {
- class->widget_to_file_operation_position (view, position);
- }
-}
-
-static void
-view_widget_to_file_operation_position_xy (NautilusView *view,
- int *x, int *y)
-{
- GdkPoint position;
-
- position.x = *x;
- position.y = *y;
- view_widget_to_file_operation_position (view, &position);
- *x = position.x;
- *y = position.y;
-}
-
-typedef struct {
- NautilusView *view;
- char *link_name;
- char *target_uri;
- char *url;
- GdkPoint point;
-} NetscapeUrlDropLink;
-
-static void
-revert_slashes (char *string)
-{
- while (*string != 0) {
- if (*string == '/') {
- *string = '\\';
- }
- string++;
- }
-}
-
-static void
-handle_netscape_url_drop_link_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- NetscapeUrlDropLink *data = user_data;
- char *link_name = data->link_name;
- char *link_display_name;
- gint screen_num;
- GFileInfo *info;
- char *icon_name = NULL;
- GdkScreen *screen;
-
- info = g_file_query_info_finish (G_FILE (source_object),
- res, NULL);
-
- if (info != NULL) {
- GIcon *icon;
- const char * const *names;
-
- icon = g_file_info_get_icon (info);
-
- if (G_IS_THEMED_ICON (icon)) {
- names = g_themed_icon_get_names (G_THEMED_ICON (icon));
- icon_name = g_strdup (names[0]);
- }
-
- g_object_unref (info);
- }
-
- if (icon_name == NULL) {
- icon_name = g_strdup ("text-html");
- }
-
- link_display_name = g_strdup_printf (_("Link to %s"), link_name);
-
- /* The filename can't contain slashes, strip em.
- (the basename of http://foo/ is http://foo/) */
- revert_slashes (link_name);
-
- screen = gtk_widget_get_screen (GTK_WIDGET (data->view));
- screen_num = gdk_screen_get_number (screen);
-
- nautilus_link_local_create (data->target_uri,
- link_name,
- link_display_name,
- icon_name,
- data->url,
- &data->point,
- screen_num,
- TRUE);
-
- g_free (link_display_name);
- g_free (icon_name);
-
- g_free (data->url);
- g_free (data->link_name);
- g_free (data->target_uri);
-
- g_object_unref (data->view);
- g_slice_free (NetscapeUrlDropLink, data);
-}
-
-void
-nautilus_view_handle_netscape_url_drop (NautilusView *view,
- const char *encoded_url,
- const char *target_uri,
- GdkDragAction action,
- int x,
- int y)
-{
- char *url, *title;
- char *link_name;
- GArray *points;
- char **bits;
- GList *uri_list = NULL;
- GFile *f;
-
- f = g_file_new_for_uri (target_uri);
-
- if (!g_file_is_native (f)) {
- eel_show_warning_dialog (_("Drag and drop is not supported."),
- _("Drag and drop is only supported on local file systems."),
- GET_ANCESTOR (view));
- g_object_unref (f);
- return;
- }
-
- g_object_unref (f);
-
- /* _NETSCAPE_URL_ works like this: $URL\n$TITLE */
- bits = g_strsplit (encoded_url, "\n", 0);
- switch (g_strv_length (bits)) {
- case 0:
- g_strfreev (bits);
- return;
- case 1:
- url = bits[0];
- title = NULL;
- break;
- default:
- url = bits[0];
- title = bits[1];
- }
-
- f = g_file_new_for_uri (url);
-
- view_widget_to_file_operation_position_xy (view, &x, &y);
-
- /* We don't support GDK_ACTION_ASK or GDK_ACTION_PRIVATE
- * and we don't support combinations either. */
- if ((action != GDK_ACTION_DEFAULT) &&
- (action != GDK_ACTION_COPY) &&
- (action != GDK_ACTION_MOVE) &&
- (action != GDK_ACTION_LINK)) {
- eel_show_warning_dialog (_("Drag and drop is not supported."),
- _("An invalid drag type was used."),
- GET_ANCESTOR (view));
- return;
- }
-
- if (action == GDK_ACTION_LINK) {
- if (g_strcmp0 (title, NULL) == 0) {
- link_name = g_file_get_basename (f);
- } else {
- link_name = g_strdup (title);
- }
-
- if (g_strcmp0 (link_name, NULL) != 0) {
- NetscapeUrlDropLink *data;
-
- data = g_slice_new0 (NetscapeUrlDropLink);
- data->link_name = link_name;
- data->point.x = x;
- data->point.y = y;
- data->view = g_object_ref (view);
- data->target_uri = g_strdup (target_uri);
- data->url = g_strdup (url);
-
- g_file_query_info_async (f,
- G_FILE_ATTRIBUTE_STANDARD_ICON,
- 0, 0, NULL,
- handle_netscape_url_drop_link_cb,
- data);
- }
- } else {
- GdkPoint tmp_point = { 0, 0 };
-
- /* pass in a 1-item array of icon positions, relative to x, y */
- points = g_array_new (FALSE, TRUE, sizeof (GdkPoint));
- g_array_append_val (points, tmp_point);
-
- uri_list = g_list_append (uri_list, url);
-
- nautilus_view_move_copy_items (view, uri_list, points,
- target_uri,
- action, x, y);
-
- g_list_free (uri_list);
- g_array_free (points, TRUE);
- }
-
- g_object_unref (f);
- g_strfreev (bits);
-}
-
-void
-nautilus_view_handle_uri_list_drop (NautilusView *view,
- const char *item_uris,
- const char *target_uri,
- GdkDragAction action,
- int x,
- int y)
-{
- gchar **uri_list;
- GList *real_uri_list = NULL;
- char *container_uri;
- int n_uris, i;
- GArray *points;
-
- if (item_uris == NULL) {
- return;
- }
-
- container_uri = NULL;
- if (target_uri == NULL) {
- container_uri = nautilus_view_get_backing_uri (view);
- g_assert (container_uri != NULL);
- }
-
- if (action == GDK_ACTION_ASK) {
- action = nautilus_drag_drop_action_ask
- (GTK_WIDGET (view),
- GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
- if (action == 0) {
- g_free (container_uri);
- return;
- }
- }
-
- /* We don't support GDK_ACTION_ASK or GDK_ACTION_PRIVATE
- * and we don't support combinations either. */
- if ((action != GDK_ACTION_DEFAULT) &&
- (action != GDK_ACTION_COPY) &&
- (action != GDK_ACTION_MOVE) &&
- (action != GDK_ACTION_LINK)) {
- eel_show_warning_dialog (_("Drag and drop is not supported."),
- _("An invalid drag type was used."),
- GET_ANCESTOR (view));
- g_free (container_uri);
- return;
- }
-
- n_uris = 0;
- uri_list = g_uri_list_extract_uris (item_uris);
- for (i = 0; uri_list[i] != NULL; i++) {
- real_uri_list = g_list_append (real_uri_list, uri_list[i]);
- n_uris++;
- }
- g_free (uri_list);
-
- /* do nothing if no real uris are left */
- if (n_uris == 0) {
- g_free (container_uri);
- return;
- }
-
- if (n_uris == 1) {
- GdkPoint tmp_point = { 0, 0 };
-
- /* pass in a 1-item array of icon positions, relative to x, y */
- points = g_array_new (FALSE, TRUE, sizeof (GdkPoint));
- g_array_append_val (points, tmp_point);
- } else {
- points = NULL;
- }
-
- view_widget_to_file_operation_position_xy (view, &x, &y);
-
- nautilus_view_move_copy_items (view, real_uri_list, points,
- target_uri != NULL ? target_uri : container_uri,
- action, x, y);
-
- g_list_free_full (real_uri_list, g_free);
-
- if (points != NULL)
- g_array_free (points, TRUE);
-
- g_free (container_uri);
-}
-
-#define MAX_LEN_FILENAME 128
-#define MIN_LEN_FILENAME 10
-
-static char *
-get_drop_filename (const char *text)
-{
- char *filename;
- char trimmed[MAX_LEN_FILENAME];
- int i;
- int last_word = -1;
- int last_sentence = -1;
- int last_nonspace = -1;
- int num_attrs;
- PangoLogAttr *attrs;
- gchar *current_char;
-
- num_attrs = MIN (g_utf8_strlen (text, -1), MAX_LEN_FILENAME) + 1;
- attrs = g_new (PangoLogAttr, num_attrs);
- g_utf8_strncpy (trimmed, text, num_attrs - 1);
- pango_get_log_attrs (trimmed, -1, -1, pango_language_get_default (), attrs, num_attrs);
-
- /* since the end of the text will always match a word boundary don't include it */
- for (i = 0; (i < num_attrs - 1); i++) {
- if (!attrs[i].is_white)
- last_nonspace = i;
- if (attrs[i].is_sentence_end)
- last_sentence = last_nonspace;
- if (attrs[i].is_word_boundary)
- last_word = last_nonspace;
- }
- g_free (attrs);
-
- if (last_sentence > 0)
- i = last_sentence;
- else
- i = last_word;
-
- if (i > MIN_LEN_FILENAME) {
- char basename[MAX_LEN_FILENAME];
- g_utf8_strncpy (basename, trimmed, i);
- filename = g_strdup_printf ("%s.txt", basename);
- } else {
- /* Translator: This is the filename used for when you dnd text to a directory */
- filename = g_strdup (_("Dropped Text.txt"));
- }
-
- /* Remove any invalid characters */
- for (current_char = filename;
- *current_char;
- current_char = g_utf8_next_char (current_char)) {
- if ( G_IS_DIR_SEPARATOR ( g_utf8_get_char (current_char))) {
- *current_char = '-';
- }
- }
-
- return filename;
-}
-
-void
-nautilus_view_handle_text_drop (NautilusView *view,
- const char *text,
- const char *target_uri,
- GdkDragAction action,
- int x,
- int y)
-{
- int length;
- char *container_uri;
- GdkPoint pos;
- char *filename;
-
- if (text == NULL) {
- return;
- }
-
- g_return_if_fail (action == GDK_ACTION_COPY);
-
- container_uri = NULL;
- if (target_uri == NULL) {
- container_uri = nautilus_view_get_backing_uri (view);
- g_assert (container_uri != NULL);
- }
-
- length = strlen (text);
-
- pos.x = x;
- pos.y = y;
- view_widget_to_file_operation_position (view, &pos);
-
- /* try to get text to use as a filename */
- filename = get_drop_filename (text);
-
- nautilus_view_new_file_with_initial_contents (view,
- target_uri != NULL ? target_uri : container_uri,
- filename,
- text,
- length,
- &pos);
- g_free (filename);
- g_free (container_uri);
-}
-
-void
-nautilus_view_handle_raw_drop (NautilusView *view,
- const char *raw_data,
- int length,
- const char *target_uri,
- const char *direct_save_uri,
- GdkDragAction action,
- int x,
- int y)
-{
- char *container_uri, *filename;
- GFile *direct_save_full;
- GdkPoint pos;
-
- if (raw_data == NULL) {
- return;
- }
-
- g_return_if_fail (action == GDK_ACTION_COPY);
-
- container_uri = NULL;
- if (target_uri == NULL) {
- container_uri = nautilus_view_get_backing_uri (view);
- g_assert (container_uri != NULL);
- }
-
- pos.x = x;
- pos.y = y;
- view_widget_to_file_operation_position (view, &pos);
-
- filename = NULL;
- if (direct_save_uri != NULL) {
- direct_save_full = g_file_new_for_uri (direct_save_uri);
- filename = g_file_get_basename (direct_save_full);
- }
- if (filename == NULL) {
- /* Translator: This is the filename used for when you dnd raw
- * data to a directory, if the source didn't supply a name.
- */
- filename = g_strdup (_("dropped data"));
- }
-
- nautilus_view_new_file_with_initial_contents (
- view, target_uri != NULL ? target_uri : container_uri,
- filename, raw_data, length, &pos);
-
- g_free (container_uri);
- g_free (filename);
-}
-
-void
-nautilus_view_drop_proxy_received_uris (NautilusView *view,
- const GList *source_uri_list,
- const char *target_uri,
- GdkDragAction action)
-{
- char *container_uri;
-
- container_uri = NULL;
- if (target_uri == NULL) {
- container_uri = nautilus_view_get_backing_uri (view);
- g_assert (container_uri != NULL);
- }
-
- if (action == GDK_ACTION_ASK) {
- action = nautilus_drag_drop_action_ask
- (GTK_WIDGET (view),
- GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
- if (action == 0) {
- return;
- }
- }
-
- nautilus_clipboard_clear_if_colliding_uris (GTK_WIDGET (view),
- source_uri_list,
- nautilus_view_get_copied_files_atom (view));
-
- nautilus_view_move_copy_items (view, source_uri_list, NULL,
- target_uri != NULL ? target_uri : container_uri,
- action, 0, 0);
-
- g_free (container_uri);
-}
-
-void
-nautilus_view_handle_hover (NautilusView *view,
- const char *target_uri)
-{
- NautilusWindowSlot *slot;
- GFile *location;
- GFile *current_location;
- NautilusFile *target_file;
- gboolean target_is_dir;
-
- slot = nautilus_view_get_nautilus_window_slot (view);
-
- location = g_file_new_for_uri (target_uri);
- target_file = nautilus_file_get_existing (location);
- target_is_dir = nautilus_file_get_file_type (target_file) == G_FILE_TYPE_DIRECTORY;
- current_location = nautilus_window_slot_get_location (slot);
- if (target_is_dir && ! (current_location != NULL && g_file_equal(location, current_location))) {
- nautilus_window_slot_open_location (slot, location, 0);
- }
- g_object_unref (location);
- nautilus_file_unref (target_file);
-}
diff --git a/src/nautilus-view-dnd.h b/src/nautilus-view-dnd.h
deleted file mode 100644
index bd09af404..000000000
--- a/src/nautilus-view-dnd.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-
-/*
- * nautilus-view-dnd.h: DnD helpers for NautilusView
- *
- * Copyright (C) 1999, 2000 Free Software Foundaton
- * Copyright (C) 2000, 2001 Eazel, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Ettore Perazzoli
- * Darin Adler <darin@bentspoon.com>
- * John Sullivan <sullivan@eazel.com>
- * Pavel Cisler <pavel@eazel.com>
- */
-
-#ifndef __NAUTILUS_VIEW_DND_H__
-#define __NAUTILUS_VIEW_DND_H__
-
-#include "nautilus-view.h"
-
-void nautilus_view_handle_netscape_url_drop (NautilusView *view,
- const char *encoded_url,
- const char *target_uri,
- GdkDragAction action,
- int x,
- int y);
-void nautilus_view_handle_uri_list_drop (NautilusView *view,
- const char *item_uris,
- const char *target_uri,
- GdkDragAction action,
- int x,
- int y);
-void nautilus_view_handle_text_drop (NautilusView *view,
- const char *text,
- const char *target_uri,
- GdkDragAction action,
- int x,
- int y);
-void nautilus_view_handle_raw_drop (NautilusView *view,
- const char *raw_data,
- int length,
- const char *target_uri,
- const char *direct_save_uri,
- GdkDragAction action,
- int x,
- int y);
-void nautilus_view_handle_hover (NautilusView *view,
- const char *target_uri);
-
-void nautilus_view_drop_proxy_received_uris (NautilusView *view,
- const GList *uris,
- const char *target_location,
- GdkDragAction action);
-
-
-#endif /* __NAUTILUS_VIEW_DND_H__ */
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
deleted file mode 100644
index 752334f4d..000000000
--- a/src/nautilus-view.c
+++ /dev/null
@@ -1,8113 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-
-/* nautilus-view.c
- *
- * Copyright (C) 1999, 2000 Free Software Foundation
- * Copyright (C) 2000, 2001 Eazel, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Ettore Perazzoli,
- * John Sullivan <sullivan@eazel.com>,
- * Darin Adler <darin@bentspoon.com>,
- * Pavel Cisler <pavel@eazel.com>,
- * David Emory Watson <dwatson@cs.ucr.edu>
- */
-
-#include <config.h>
-
-#include "nautilus-view.h"
-
-#include "nautilus-application.h"
-#include "nautilus-desktop-canvas-view.h"
-#include "nautilus-error-reporting.h"
-#include "nautilus-floating-bar.h"
-#include "nautilus-list-view.h"
-#include "nautilus-mime-actions.h"
-#include "nautilus-previewer.h"
-#include "nautilus-properties-window.h"
-#include "nautilus-window.h"
-#include "nautilus-toolbar.h"
-
-#if ENABLE_EMPTY_VIEW
-#include "nautilus-empty-view.h"
-#endif
-
-#ifdef HAVE_X11_XF86KEYSYM_H
-#include <X11/XF86keysym.h>
-#endif
-
-#include <gdk/gdkx.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <glib/gstdio.h>
-#include <gio/gio.h>
-#include <math.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <eel/eel-glib-extensions.h>
-#include <eel/eel-gnome-extensions.h>
-#include <eel/eel-gtk-extensions.h>
-#include <eel/eel-stock-dialogs.h>
-#include <eel/eel-string.h>
-#include <eel/eel-vfs-extensions.h>
-
-#include <libnautilus-extension/nautilus-menu-provider.h>
-#include <libnautilus-private/nautilus-clipboard.h>
-#include <libnautilus-private/nautilus-clipboard-monitor.h>
-#include <libnautilus-private/nautilus-desktop-icon-file.h>
-#include <libnautilus-private/nautilus-desktop-directory.h>
-#include <libnautilus-private/nautilus-search-directory.h>
-#include <libnautilus-private/nautilus-directory.h>
-#include <libnautilus-private/nautilus-dnd.h>
-#include <libnautilus-private/nautilus-file-attributes.h>
-#include <libnautilus-private/nautilus-file-changes-queue.h>
-#include <libnautilus-private/nautilus-file-dnd.h>
-#include <libnautilus-private/nautilus-file-operations.h>
-#include <libnautilus-private/nautilus-file-utilities.h>
-#include <libnautilus-private/nautilus-file-private.h>
-#include <libnautilus-private/nautilus-global-preferences.h>
-#include <libnautilus-private/nautilus-link.h>
-#include <libnautilus-private/nautilus-metadata.h>
-#include <libnautilus-private/nautilus-recent.h>
-#include <libnautilus-private/nautilus-module.h>
-#include <libnautilus-private/nautilus-profile.h>
-#include <libnautilus-private/nautilus-program-choosing.h>
-#include <libnautilus-private/nautilus-trash-monitor.h>
-#include <libnautilus-private/nautilus-ui-utilities.h>
-#include <libnautilus-private/nautilus-signaller.h>
-#include <libnautilus-private/nautilus-icon-names.h>
-
-#define GNOME_DESKTOP_USE_UNSTABLE_API
-#include <gdesktop-enums.h>
-
-#define DEBUG_FLAG NAUTILUS_DEBUG_DIRECTORY_VIEW
-#include <libnautilus-private/nautilus-debug.h>
-
-/* Minimum starting update inverval */
-#define UPDATE_INTERVAL_MIN 100
-/* Maximum update interval */
-#define UPDATE_INTERVAL_MAX 2000
-/* Amount of miliseconds the update interval is increased */
-#define UPDATE_INTERVAL_INC 250
-/* Interval at which the update interval is increased */
-#define UPDATE_INTERVAL_TIMEOUT_INTERVAL 250
-/* Milliseconds that have to pass without a change to reset the update interval */
-#define UPDATE_INTERVAL_RESET 1000
-
-#define SILENT_WINDOW_OPEN_LIMIT 5
-
-#define DUPLICATE_HORIZONTAL_ICON_OFFSET 70
-#define DUPLICATE_VERTICAL_ICON_OFFSET 30
-
-#define MAX_QUEUED_UPDATES 500
-
-#define MAX_MENU_LEVELS 5
-#define TEMPLATE_LIMIT 30
-
-/* Delay to show the duplicated label when creating a folder */
-#define FILE_NAME_DUPLICATED_LABEL_TIMEOUT 500
-
-/* Delay to show the Loading... floating bar */
-#define FLOATING_BAR_LOADING_DELAY 500 /* ms */
-
-enum {
- ADD_FILE,
- BEGIN_FILE_CHANGES,
- BEGIN_LOADING,
- CLEAR,
- END_FILE_CHANGES,
- END_LOADING,
- FILE_CHANGED,
- MOVE_COPY_ITEMS,
- REMOVE_FILE,
- SELECTION_CHANGED,
- TRASH,
- DELETE,
- LAST_SIGNAL
-};
-
-enum {
- PROP_WINDOW_SLOT = 1,
- PROP_SUPPORTS_ZOOMING,
- PROP_ICON,
- PROP_VIEW_WIDGET,
- NUM_PROPERTIES
-};
-
-static guint signals[LAST_SIGNAL];
-static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
-
-static GdkAtom copied_files_atom;
-
-static char *scripts_directory_uri = NULL;
-static int scripts_directory_uri_length;
-
-struct NautilusViewDetails
-{
- NautilusWindowSlot *slot;
- NautilusDirectory *model;
- NautilusFile *directory_as_file;
- guint dir_merge_id;
-
- gint duplicated_label_timeout_id;
- GtkWidget *rename_file_popover;
-
- gboolean supports_zooming;
-
- GList *scripts_directory_list;
- GList *templates_directory_list;
-
- guint display_selection_idle_id;
- guint update_context_menus_timeout_id;
- guint update_status_idle_id;
- guint reveal_selection_idle_id;
-
- guint display_pending_source_id;
- guint changes_timeout_id;
-
- guint update_interval;
- guint64 last_queued;
-
- guint files_added_handler_id;
- guint files_changed_handler_id;
- guint load_error_handler_id;
- guint done_loading_handler_id;
- guint file_changed_handler_id;
-
- GList *new_added_files;
- GList *new_changed_files;
-
- GHashTable *non_ready_files;
-
- GList *old_added_files;
- GList *old_changed_files;
-
- GList *pending_selection;
-
- /* whether we are in the active slot */
- gboolean active;
-
- /* loading indicates whether this view has begun loading a directory.
- * This flag should need not be set inside subclasses. NautilusView automatically
- * sets 'loading' to TRUE before it begins loading a directory's contents and to FALSE
- * after it finishes loading the directory and its view.
- */
- gboolean loading;
- gboolean templates_present;
- gboolean scripts_present;
-
- gboolean sort_directories_first;
-
- gboolean show_foreign_files;
- gboolean show_hidden_files;
- gboolean ignore_hidden_file_preferences;
-
- gboolean batching_selection_level;
- gboolean selection_changed_while_batched;
-
- gboolean selection_was_removed;
-
- gboolean metadata_for_directory_as_file_pending;
- gboolean metadata_for_files_in_directory_pending;
-
- GList *subdirectory_list;
-
- GdkPoint context_menu_position;
-
- GMenu *selection_menu;
- GMenu *background_menu;
-
- GActionGroup *view_action_group;
-
- GtkWidget *scrolled_window;
-
- /* Empty states */
- GtkWidget *folder_is_empty_widget;
- GtkWidget *no_search_results_widget;
-
- /* Floating bar */
- guint floating_bar_set_status_timeout_id;
- guint floating_bar_loading_timeout_id;
- GtkWidget *floating_bar;
-
- /* View menu */
- GtkWidget *view_menu_widget;
- GtkWidget *view_icon;
- GtkWidget *sort_menu;
- GtkWidget *sort_trash_time;
- GtkWidget *sort_search_relevance;
- GtkWidget *visible_columns;
- GtkWidget *stop;
- GtkWidget *reload;
- GtkAdjustment *zoom_adjustment;
- GtkWidget *zoom_level_scale;
-
- gulong stop_signal_handler;
- gulong reload_signal_handler;
-};
-
-typedef struct {
- NautilusFile *file;
- NautilusDirectory *directory;
-} FileAndDirectory;
-
-/* forward declarations */
-
-static gboolean display_selection_info_idle_callback (gpointer data);
-static void trash_or_delete_files (GtkWindow *parent_window,
- const GList *files,
- NautilusView *view);
-static void load_directory (NautilusView *view,
- NautilusDirectory *directory);
-static void clipboard_changed_callback (NautilusClipboardMonitor *monitor,
- NautilusView *view);
-static void open_one_in_new_window (gpointer data,
- gpointer callback_data);
-static void schedule_update_context_menus (NautilusView *view);
-static void remove_update_context_menus_timeout_callback (NautilusView *view);
-static void schedule_update_status (NautilusView *view);
-static void remove_update_status_idle_callback (NautilusView *view);
-static void reset_update_interval (NautilusView *view);
-static void schedule_idle_display_of_pending_files (NautilusView *view);
-static void unschedule_display_of_pending_files (NautilusView *view);
-static void disconnect_model_handlers (NautilusView *view);
-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,
- GList *files,
- gpointer callback_data);
-static void nautilus_view_trash_state_changed_callback (NautilusTrashMonitor *trash,
- gboolean state,
- gpointer callback_data);
-static void nautilus_view_select_file (NautilusView *view,
- NautilusFile *file);
-
-static void update_templates_directory (NautilusView *view);
-
-static void check_empty_states (NautilusView *view);
-
-G_DEFINE_TYPE (NautilusView, nautilus_view, GTK_TYPE_OVERLAY);
-
-static const struct {
- unsigned int keyval;
- const char *action;
-} extra_view_keybindings [] = {
-#ifdef HAVE_X11_XF86KEYSYM_H
- /* View actions */
- { XF86XK_ZoomIn, "zoom-in" },
- { XF86XK_ZoomOut, "zoom-out" },
-
-#endif
-};
-
-static void
-check_empty_states (NautilusView *view)
-{
- GList *files;
- GList *filtered;
- gboolean show_hidden_files;
-
- gtk_widget_hide (view->details->no_search_results_widget);
- gtk_widget_hide (view->details->folder_is_empty_widget);
- if (!view->details->loading && view->details->model) {
- files = nautilus_directory_get_file_list (view->details->model);
- show_hidden_files = g_settings_get_boolean (gtk_filechooser_preferences,
- NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES);
- filtered = nautilus_file_list_filter_hidden (files, show_hidden_files);
- if (g_list_length (filtered) == 0) {
- if (nautilus_view_is_search (view)) {
- gtk_widget_show (view->details->no_search_results_widget);
- } else {
- gtk_widget_show (view->details->folder_is_empty_widget);
- }
- }
- nautilus_file_list_unref (filtered);
- nautilus_file_list_unref (files);
- }
-}
-
-/*
- * Floating Bar code
- */
-static void
-remove_loading_floating_bar (NautilusView *view)
-{
- if (view->details->floating_bar_loading_timeout_id != 0) {
- g_source_remove (view->details->floating_bar_loading_timeout_id);
- view->details->floating_bar_loading_timeout_id = 0;
- }
-
- gtk_widget_hide (view->details->floating_bar);
- nautilus_floating_bar_cleanup_actions (NAUTILUS_FLOATING_BAR (view->details->floating_bar));
-}
-
-static void
-real_setup_loading_floating_bar (NautilusView *view)
-{
- gboolean disable_chrome;
-
- g_object_get (nautilus_view_get_window (view),
- "disable-chrome", &disable_chrome,
- NULL);
-
- if (disable_chrome) {
- gtk_widget_hide (view->details->floating_bar);
- return;
- }
-
- nautilus_floating_bar_cleanup_actions (NAUTILUS_FLOATING_BAR (view->details->floating_bar));
- nautilus_floating_bar_set_primary_label (NAUTILUS_FLOATING_BAR (view->details->floating_bar),
- nautilus_view_is_search (view) ? _("Searching…") : _("Loading…"));
- nautilus_floating_bar_set_details_label (NAUTILUS_FLOATING_BAR (view->details->floating_bar), NULL);
- nautilus_floating_bar_set_show_spinner (NAUTILUS_FLOATING_BAR (view->details->floating_bar), view->details->loading);
- nautilus_floating_bar_add_action (NAUTILUS_FLOATING_BAR (view->details->floating_bar),
- "process-stop-symbolic",
- NAUTILUS_FLOATING_BAR_ACTION_ID_STOP);
-
- gtk_widget_set_halign (view->details->floating_bar, GTK_ALIGN_END);
- gtk_widget_show (view->details->floating_bar);
-}
-
-static gboolean
-setup_loading_floating_bar_timeout_cb (gpointer user_data)
-{
- NautilusView *view = user_data;
-
- view->details->floating_bar_loading_timeout_id = 0;
- real_setup_loading_floating_bar (view);
-
- return FALSE;
-}
-
-static void
-setup_loading_floating_bar (NautilusView *view)
-{
- /* setup loading overlay */
- if (view->details->floating_bar_set_status_timeout_id != 0) {
- g_source_remove (view->details->floating_bar_set_status_timeout_id);
- view->details->floating_bar_set_status_timeout_id = 0;
- }
-
- if (view->details->floating_bar_loading_timeout_id != 0) {
- g_source_remove (view->details->floating_bar_loading_timeout_id);
- view->details->floating_bar_loading_timeout_id = 0;
- }
-
- view->details->floating_bar_loading_timeout_id =
- g_timeout_add (FLOATING_BAR_LOADING_DELAY, setup_loading_floating_bar_timeout_cb, view);
-}
-
-static void
-floating_bar_action_cb (NautilusFloatingBar *floating_bar,
- gint action,
- NautilusView *view)
-{
- if (action == NAUTILUS_FLOATING_BAR_ACTION_ID_STOP) {
- remove_loading_floating_bar (view);
- nautilus_window_slot_stop_loading (view->details->slot);
- }
-}
-
-static void
-real_floating_bar_set_short_status (NautilusView *view,
- const gchar *primary_status,
- const gchar *detail_status)
-{
- gboolean disable_chrome;
-
- nautilus_floating_bar_cleanup_actions (NAUTILUS_FLOATING_BAR (view->details->floating_bar));
- nautilus_floating_bar_set_show_spinner (NAUTILUS_FLOATING_BAR (view->details->floating_bar), view->details->loading);
-
- g_object_get (nautilus_view_get_window (view),
- "disable-chrome", &disable_chrome,
- NULL);
-
- if ((primary_status == NULL && detail_status == NULL) || disable_chrome) {
- gtk_widget_hide (view->details->floating_bar);
- return;
- }
-
- nautilus_floating_bar_set_labels (NAUTILUS_FLOATING_BAR (view->details->floating_bar),
- primary_status,
- detail_status);
-
- gtk_widget_show (view->details->floating_bar);
-}
-
-typedef struct {
- gchar *primary_status;
- gchar *detail_status;
- NautilusView *view;
-} FloatingBarSetStatusData;
-
-static void
-floating_bar_set_status_data_free (gpointer data)
-{
- FloatingBarSetStatusData *status_data = data;
-
- g_free (status_data->primary_status);
- g_free (status_data->detail_status);
-
- g_slice_free (FloatingBarSetStatusData, data);
-}
-
-static gboolean
-floating_bar_set_status_timeout_cb (gpointer data)
-{
- FloatingBarSetStatusData *status_data = data;
-
- status_data->view->details->floating_bar_set_status_timeout_id = 0;
- real_floating_bar_set_short_status (status_data->view,
- status_data->primary_status,
- status_data->detail_status);
-
- return FALSE;
-}
-
-static void
-set_floating_bar_status (NautilusView *view,
- const gchar *primary_status,
- const gchar *detail_status)
-{
- GtkSettings *settings;
- gint double_click_time;
- FloatingBarSetStatusData *status_data;
-
- if (view->details->floating_bar_set_status_timeout_id != 0) {
- g_source_remove (view->details->floating_bar_set_status_timeout_id);
- view->details->floating_bar_set_status_timeout_id = 0;
- }
-
- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (view)));
- g_object_get (settings,
- "gtk-double-click-time", &double_click_time,
- NULL);
-
- status_data = g_slice_new0 (FloatingBarSetStatusData);
- status_data->primary_status = g_strdup (primary_status);
- status_data->detail_status = g_strdup (detail_status);
- status_data->view = view;
-
- /* waiting for half of the double-click-time before setting
- * the status seems to be a good approximation of not setting it
- * too often and not delaying the statusbar too much.
- */
- view->details->floating_bar_set_status_timeout_id =
- g_timeout_add_full (G_PRIORITY_DEFAULT,
- (guint) (double_click_time / 2),
- floating_bar_set_status_timeout_cb,
- status_data,
- floating_bar_set_status_data_free);
-}
-
-static char *
-real_get_backing_uri (NautilusView *view)
-{
- NautilusDirectory *directory;
- char *uri;
-
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
-
- if (view->details->model == NULL) {
- return NULL;
- }
-
- directory = view->details->model;
-
- if (NAUTILUS_IS_DESKTOP_DIRECTORY (directory)) {
- directory = nautilus_desktop_directory_get_real_directory (NAUTILUS_DESKTOP_DIRECTORY (directory));
- } else {
- nautilus_directory_ref (directory);
- }
-
- uri = nautilus_directory_get_uri (directory);
-
- nautilus_directory_unref (directory);
-
- return uri;
-}
-
-/**
- *
- * nautilus_view_get_backing_uri:
- *
- * Returns the URI for the target location of new directory, new file, new
- * link and paste operations.
- */
-
-char *
-nautilus_view_get_backing_uri (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
-
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_backing_uri (view);
-}
-
-/**
- * nautilus_view_select_all:
- *
- * select all the items in the view
- *
- **/
-static void
-nautilus_view_select_all (NautilusView *view)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->select_all (view);
-}
-
-static void
-nautilus_view_select_first (NautilusView *view)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->select_first (view);
-}
-
-static void
-nautilus_view_call_set_selection (NautilusView *view, GList *selection)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->set_selection (view, selection);
-}
-
-static GList *
-nautilus_view_get_selection_for_file_transfer (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
-
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_selection_for_file_transfer (view);
-}
-
-static void
-nautilus_view_invert_selection (NautilusView *view)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->invert_selection (view);
-}
-
-/**
- * nautilus_view_reveal_selection:
- *
- * Scroll as necessary to reveal the selected items.
- **/
-static void
-nautilus_view_reveal_selection (NautilusView *view)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->reveal_selection (view);
-}
-
-static gboolean
-nautilus_view_using_manual_layout (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
-
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->using_manual_layout (view);
-}
-
-/**
- * nautilus_view_get_icon:
- * @view: a #NautilusView
- *
- * Retrieves the #GIcon that represents @view.
- *
- * Returns: (transfer none): the #Gicon that represents @view
- */
-GIcon*
-nautilus_view_get_icon (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
-
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_icon (view);
-}
-
-/**
- * nautilus_view_get_view_widget:
- * @view: a #NautilusView
- *
- * Retrieves the view menu, as a #GtkWidget. If it's %NULL,
- * the button renders insensitive.
- *
- * Returns: (transfer none): a #GtkWidget for the view menu
- */
-GtkWidget*
-nautilus_view_get_view_widget (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
-
- return view->details->view_menu_widget;
-}
-
-/**
- * nautilus_view_can_rename_file
- *
- * Determine whether a file can be renamed.
- * @file: A NautilusFile
- *
- * Return value: TRUE if @file can be renamed, FALSE otherwise.
- *
- **/
-static gboolean
-nautilus_view_can_rename_file (NautilusView *view, NautilusFile *file)
-{
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->can_rename_file (view, file);
-}
-
-static gboolean
-nautilus_view_is_read_only (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
-
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->is_read_only (view);
-}
-
-static gboolean
-showing_trash_directory (NautilusView *view)
-{
- NautilusFile *file;
-
- file = nautilus_view_get_directory_as_file (view);
- if (file != NULL) {
- return nautilus_file_is_in_trash (file);
- }
- return FALSE;
-}
-
-static gboolean
-showing_network_directory (NautilusView *view)
-{
- NautilusFile *file;
-
- file = nautilus_view_get_directory_as_file (view);
- if (file != NULL) {
- return nautilus_file_is_in_network (file);
- }
- return FALSE;
-}
-
-static gboolean
-showing_recent_directory (NautilusView *view)
-{
- NautilusFile *file;
-
- file = nautilus_view_get_directory_as_file (view);
- if (file != NULL) {
- return nautilus_file_is_in_recent (file);
- }
- return FALSE;
-}
-
-static gboolean
-nautilus_view_supports_creating_files (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
-
- return !nautilus_view_is_read_only (view)
- && !showing_trash_directory (view)
- && !showing_recent_directory (view);
-}
-
-static gboolean
-nautilus_view_is_empty (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
-
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->is_empty (view);
-}
-
-/**
- * nautilus_view_bump_zoom_level:
- *
- * bump the current zoom level by invoking the relevant subclass through the slot
- *
- **/
-void
-nautilus_view_bump_zoom_level (NautilusView *view,
- int zoom_increment)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- if (!nautilus_view_supports_zooming (view)) {
- return;
- }
-
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->bump_zoom_level (view, zoom_increment);
-}
-
-/**
- * nautilus_view_can_zoom_in:
- *
- * Determine whether the view can be zoomed any closer.
- * @view: The zoomable NautilusView.
- *
- * Return value: TRUE if @view can be zoomed any closer, FALSE otherwise.
- *
- **/
-gboolean
-nautilus_view_can_zoom_in (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
-
- if (!nautilus_view_supports_zooming (view)) {
- return FALSE;
- }
-
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->can_zoom_in (view);
-}
-
-/**
- * nautilus_view_can_zoom_out:
- *
- * Determine whether the view can be zoomed any further away.
- * @view: The zoomable NautilusView.
- *
- * Return value: TRUE if @view can be zoomed any further away, FALSE otherwise.
- *
- **/
-gboolean
-nautilus_view_can_zoom_out (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
-
- if (!nautilus_view_supports_zooming (view)) {
- return FALSE;
- }
-
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->can_zoom_out (view);
-}
-
-gboolean
-nautilus_view_supports_zooming (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
-
- return view->details->supports_zooming;
-}
-
-/**
- * nautilus_view_restore_default_zoom_level:
- *
- * restore to the default zoom level by invoking the relevant subclass through the slot
- *
- **/
-void
-nautilus_view_restore_default_zoom_level (NautilusView *view)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- if (!nautilus_view_supports_zooming (view)) {
- return;
- }
-
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->restore_default_zoom_level (view);
-}
-
-gboolean
-nautilus_view_is_search (NautilusView *view)
-{
- if (!view->details->model)
- return FALSE;
-
- return NAUTILUS_IS_SEARCH_DIRECTORY (view->details->model);
-}
-
-const char *
-nautilus_view_get_view_id (NautilusView *view)
-{
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_view_id (view);
-}
-
-char *
-nautilus_view_get_first_visible_file (NautilusView *view)
-{
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_first_visible_file (view);
-}
-
-void
-nautilus_view_scroll_to_file (NautilusView *view,
- const char *uri)
-{
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->scroll_to_file (view, uri);
-}
-
-/**
- * nautilus_view_get_selection:
- *
- * Get a list of NautilusFile pointers that represents the
- * currently-selected items in this view. Subclasses must override
- * the signal handler for the 'get_selection' signal. Callers are
- * responsible for g_free-ing the list (but not its data).
- * @view: NautilusView whose selected items are of interest.
- *
- * Return value: GList of NautilusFile pointers representing the selection.
- *
- **/
-GList *
-nautilus_view_get_selection (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
-
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_selection (view);
-}
-
-typedef struct {
- NautilusFile *file;
- NautilusView *directory_view;
-} ScriptLaunchParameters;
-
-typedef struct {
- NautilusFile *file;
- NautilusView *directory_view;
-} CreateTemplateParameters;
-
-static GList *
-file_and_directory_list_to_files (GList *fad_list)
-{
- GList *res, *l;
- FileAndDirectory *fad;
-
- res = NULL;
- for (l = fad_list; l != NULL; l = l->next) {
- fad = l->data;
- res = g_list_prepend (res, nautilus_file_ref (fad->file));
- }
- return g_list_reverse (res);
-}
-
-
-static GList *
-file_and_directory_list_from_files (NautilusDirectory *directory, GList *files)
-{
- GList *res, *l;
- FileAndDirectory *fad;
-
- res = NULL;
- for (l = files; l != NULL; l = l->next) {
- fad = g_new0 (FileAndDirectory, 1);
- fad->directory = nautilus_directory_ref (directory);
- fad->file = nautilus_file_ref (l->data);
- res = g_list_prepend (res, fad);
- }
- return g_list_reverse (res);
-}
-
-static void
-file_and_directory_free (FileAndDirectory *fad)
-{
- nautilus_directory_unref (fad->directory);
- nautilus_file_unref (fad->file);
- g_free (fad);
-}
-
-
-static void
-file_and_directory_list_free (GList *list)
-{
- GList *l;
-
- for (l = list; l != NULL; l = l->next) {
- file_and_directory_free (l->data);
- }
-
- g_list_free (list);
-}
-
-static gboolean
-file_and_directory_equal (gconstpointer v1,
- gconstpointer v2)
-{
- const FileAndDirectory *fad1, *fad2;
- fad1 = v1;
- fad2 = v2;
-
- return (fad1->file == fad2->file &&
- fad1->directory == fad2->directory);
-}
-
-static guint
-file_and_directory_hash (gconstpointer v)
-{
- const FileAndDirectory *fad;
-
- fad = v;
- return GPOINTER_TO_UINT (fad->file) ^ GPOINTER_TO_UINT (fad->directory);
-}
-
-static ScriptLaunchParameters *
-script_launch_parameters_new (NautilusFile *file,
- NautilusView *directory_view)
-{
- ScriptLaunchParameters *result;
-
- result = g_new0 (ScriptLaunchParameters, 1);
- g_object_ref (directory_view);
- result->directory_view = directory_view;
- nautilus_file_ref (file);
- result->file = file;
-
- return result;
-}
-
-static void
-script_launch_parameters_free (ScriptLaunchParameters *parameters)
-{
- g_object_unref (parameters->directory_view);
- nautilus_file_unref (parameters->file);
- g_free (parameters);
-}
-
-static CreateTemplateParameters *
-create_template_parameters_new (NautilusFile *file,
- NautilusView *directory_view)
-{
- CreateTemplateParameters *result;
-
- result = g_new0 (CreateTemplateParameters, 1);
- g_object_ref (directory_view);
- result->directory_view = directory_view;
- nautilus_file_ref (file);
- result->file = file;
-
- return result;
-}
-
-static void
-create_templates_parameters_free (CreateTemplateParameters *parameters)
-{
- g_object_unref (parameters->directory_view);
- nautilus_file_unref (parameters->file);
- g_free (parameters);
-}
-
-NautilusWindow *
-nautilus_view_get_window (NautilusView *view)
-{
- return nautilus_window_slot_get_window (view->details->slot);
-}
-
-NautilusWindowSlot *
-nautilus_view_get_nautilus_window_slot (NautilusView *view)
-{
- g_assert (view->details->slot != NULL);
-
- return view->details->slot;
-}
-
-/* Returns the GtkWindow that this directory view occupies, or NULL
- * if at the moment this directory view is not in a GtkWindow or the
- * GtkWindow cannot be determined. Primarily used for parenting dialogs.
- */
-static GtkWindow *
-nautilus_view_get_containing_window (NautilusView *view)
-{
- GtkWidget *window;
-
- g_assert (NAUTILUS_IS_VIEW (view));
-
- window = gtk_widget_get_ancestor (GTK_WIDGET (view), GTK_TYPE_WINDOW);
- if (window == NULL) {
- return NULL;
- }
-
- return GTK_WINDOW (window);
-}
-
-static gboolean
-nautilus_view_confirm_multiple (GtkWindow *parent_window,
- int count,
- gboolean tabs)
-{
- GtkDialog *dialog;
- char *prompt;
- char *detail;
- int response;
-
- if (count <= SILENT_WINDOW_OPEN_LIMIT) {
- return TRUE;
- }
-
- prompt = _("Are you sure you want to open all files?");
- if (tabs) {
- detail = g_strdup_printf (ngettext("This will open %'d separate tab.",
- "This will open %'d separate tabs.", count), count);
- } else {
- detail = g_strdup_printf (ngettext("This will open %'d separate window.",
- "This will open %'d separate windows.", count), count);
- }
- dialog = eel_show_yes_no_dialog (prompt, detail,
- _("_OK"), _("_Cancel"),
- parent_window);
- g_free (detail);
-
- response = gtk_dialog_run (dialog);
- gtk_widget_destroy (GTK_WIDGET (dialog));
-
- return response == GTK_RESPONSE_YES;
-}
-
-static gboolean
-selection_not_empty_in_menu_callback (NautilusView *view, GList *selection)
-{
- if (selection != NULL) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-static char *
-get_view_directory (NautilusView *view)
-{
- char *uri, *path;
- GFile *f;
-
- uri = nautilus_directory_get_uri (view->details->model);
- if (eel_uri_is_desktop (uri)) {
- g_free (uri);
- uri = nautilus_get_desktop_directory_uri ();
-
- }
- f = g_file_new_for_uri (uri);
- path = g_file_get_path (f);
- g_object_unref (f);
- g_free (uri);
-
- return path;
-}
-
-void
-nautilus_view_preview_files (NautilusView *view,
- GList *files,
- GArray *locations)
-{
- gchar *uri;
- guint xid;
- GtkWidget *toplevel;
-
- uri = nautilus_file_get_uri (files->data);
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view));
-
- xid = gdk_x11_window_get_xid (gtk_widget_get_window (toplevel));
- nautilus_previewer_call_show_file (uri, xid, TRUE);
-
- g_free (uri);
-}
-
-void
-nautilus_view_activate_selection (NautilusView *view)
-{
- GList *selection;
-
- selection = nautilus_view_get_selection (view);
- nautilus_view_activate_files (view,
- selection,
- 0,
- TRUE);
- nautilus_file_list_free (selection);
-}
-
-void
-nautilus_view_activate_files (NautilusView *view,
- GList *files,
- NautilusWindowOpenFlags flags,
- gboolean confirm_multiple)
-{
- char *path;
-
- path = get_view_directory (view);
- nautilus_mime_activate_files (nautilus_view_get_containing_window (view),
- view->details->slot,
- files,
- path,
- flags,
- confirm_multiple);
-
- g_free (path);
-}
-
-static void
-nautilus_view_activate_file (NautilusView *view,
- NautilusFile *file,
- NautilusWindowOpenFlags flags)
-{
- char *path;
-
- path = get_view_directory (view);
- nautilus_mime_activate_file (nautilus_view_get_containing_window (view),
- view->details->slot,
- file,
- path,
- flags);
-
- g_free (path);
-}
-
-static void
-action_open_with_default_application (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (user_data);
- nautilus_view_activate_selection (view);
-}
-static void
-action_open_file_and_close_window (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- GList *selection;
- NautilusView *view;
-
- view = NAUTILUS_VIEW (user_data);
-
- selection = nautilus_view_get_selection (view);
- nautilus_view_activate_files (view,
- selection,
- NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND,
- TRUE);
- nautilus_file_list_free (selection);
-}
-
-static void
-got_it_clicked (GtkDialog *dialog,
- gint response_id,
- gpointer user_data)
-{
- g_settings_set_boolean (nautilus_preferences,
- NAUTILUS_PREFERENCES_SHOW_MOVE_TO_TRASH_SHORTCUT_CHANGED_DIALOG,
- FALSE);
-}
-
-static void
-action_show_move_to_trash_shortcut_changed_dialog (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
- GtkWindow *dialog;
- GtkBuilder *builder;
- gboolean show_dialog_preference;
-
- view = NAUTILUS_VIEW (user_data);
- show_dialog_preference = g_settings_get_boolean (nautilus_preferences,
- NAUTILUS_PREFERENCES_SHOW_MOVE_TO_TRASH_SHORTCUT_CHANGED_DIALOG);
- if (show_dialog_preference) {
- builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-move-to-trash-shortcut-changed.ui");
- dialog = GTK_WINDOW (gtk_builder_get_object (builder, "move_to_trash_shortcut_changed_dialog"));
-
- gtk_window_set_transient_for (dialog, GTK_WINDOW (nautilus_view_get_window (view)));
- g_signal_connect (dialog, "response",
- G_CALLBACK (got_it_clicked),
- view);
-
- gtk_widget_show (GTK_WIDGET (dialog));
- gtk_dialog_run(GTK_DIALOG (dialog));
- gtk_widget_destroy (GTK_WIDGET (dialog));
-
- g_object_unref (builder);
- }
-}
-static void
-action_open_item_location (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
- GList *selection;
- NautilusFile *item;
- GFile *activation_location;
- NautilusFile *activation_file;
- NautilusFile *location;
-
- view = NAUTILUS_VIEW (user_data);
- selection = nautilus_view_get_selection (view);
-
- if (!selection)
- return;
-
- item = NAUTILUS_FILE (selection->data);
- activation_location = nautilus_file_get_activation_location (item);
- activation_file = nautilus_file_get (activation_location);
- location = nautilus_file_get_parent (activation_file);
-
- nautilus_view_activate_file (view, location, 0);
-
- nautilus_file_unref (location);
- nautilus_file_unref (activation_file);
- g_object_unref (activation_location);
- nautilus_file_list_free (selection);
-}
-
-static void
-action_open_item_new_tab (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
- GList *selection;
- GtkWindow *window;
-
- view = NAUTILUS_VIEW (user_data);
- selection = nautilus_view_get_selection (view);
-
- window = nautilus_view_get_containing_window (view);
-
- if (nautilus_view_confirm_multiple (window, g_list_length (selection), TRUE)) {
- nautilus_view_activate_files (view,
- selection,
- NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB,
- FALSE);
- }
-
- nautilus_file_list_free (selection);
-}
-
-static void
-app_chooser_dialog_response_cb (GtkDialog *dialog,
- gint response_id,
- gpointer user_data)
-{
- GtkWindow *parent_window;
- GList *files;
- GAppInfo *info;
-
- parent_window = user_data;
- files = g_object_get_data (G_OBJECT (dialog), "directory-view:files");
-
- if (response_id != GTK_RESPONSE_OK)
- goto out;
-
- info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (dialog));
-
- g_signal_emit_by_name (nautilus_signaller_get_current (), "mime-data-changed");
-
- nautilus_launch_application (info, files, parent_window);
-
- g_object_unref (info);
-out:
- gtk_widget_destroy (GTK_WIDGET (dialog));
-}
-
-static void
-choose_program (NautilusView *view,
- GList *files)
-{
- GtkWidget *dialog;
- gchar *mime_type;
- GtkWindow *parent_window;
-
- g_assert (NAUTILUS_IS_VIEW (view));
-
- mime_type = nautilus_file_get_mime_type (files->data);
- parent_window = nautilus_view_get_containing_window (view);
-
- dialog = gtk_app_chooser_dialog_new_for_content_type (parent_window,
- GTK_DIALOG_MODAL |
- GTK_DIALOG_DESTROY_WITH_PARENT |
- GTK_DIALOG_USE_HEADER_BAR,
- mime_type);
- g_object_set_data_full (G_OBJECT (dialog),
- "directory-view:files",
- files,
- (GDestroyNotify) nautilus_file_list_free);
- gtk_widget_show (dialog);
-
- g_signal_connect_object (dialog, "response",
- G_CALLBACK (app_chooser_dialog_response_cb),
- parent_window, 0);
-}
-
-static void
-open_with_other_program (NautilusView *view)
-{
- GList *selection;
-
- g_assert (NAUTILUS_IS_VIEW (view));
-
- selection = nautilus_view_get_selection (view);
- choose_program (view, selection);
-}
-
-static void
-action_open_with_other_application (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- open_with_other_program (NAUTILUS_VIEW (user_data));
-}
-
-static void
-trash_or_delete_selected_files (NautilusView *view)
-{
- GList *selection;
-
- /* This might be rapidly called multiple times for the same selection
- * when using keybindings. So we remember if the current selection
- * was already removed (but the view doesn't know about it yet).
- */
- if (!view->details->selection_was_removed) {
- selection = nautilus_view_get_selection_for_file_transfer (view);
- trash_or_delete_files (nautilus_view_get_containing_window (view),
- selection,
- view);
- nautilus_file_list_free (selection);
- view->details->selection_was_removed = TRUE;
- }
-}
-
-static void
-action_move_to_trash (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- trash_or_delete_selected_files (NAUTILUS_VIEW (user_data));
-}
-
-static void
-action_remove_from_recent (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- /* TODO:implement a set of functions for this, is very confusing to
- * call trash_or_delete_file to remove from recent, even if it does like
- * that not deleting/moving the files to trash */
- trash_or_delete_selected_files (NAUTILUS_VIEW (user_data));
-}
-
-static void
-delete_selected_files (NautilusView *view)
-{
- GList *selection;
- GList *node;
- GList *locations;
-
- selection = nautilus_view_get_selection_for_file_transfer (view);
- if (selection == NULL) {
- return;
- }
-
- locations = NULL;
- for (node = selection; node != NULL; node = node->next) {
- locations = g_list_prepend (locations,
- nautilus_file_get_location ((NautilusFile *) node->data));
- }
- locations = g_list_reverse (locations);
-
- nautilus_file_operations_delete (locations, nautilus_view_get_containing_window (view), NULL, NULL);
-
- g_list_free_full (locations, g_object_unref);
- nautilus_file_list_free (selection);
-}
-
-static void
-action_delete (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- delete_selected_files (NAUTILUS_VIEW (user_data));
-}
-
-static void
-action_restore_from_trash (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
- GList *selection;
-
- view = NAUTILUS_VIEW (user_data);
-
- selection = nautilus_view_get_selection_for_file_transfer (view);
- nautilus_restore_files_from_trash (selection,
- nautilus_view_get_containing_window (view));
-
- nautilus_file_list_free (selection);
-
-}
-
-static void
-action_select_all (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
-
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- view = NAUTILUS_VIEW (user_data);
-
- nautilus_view_select_all (view);
-}
-
-static void
-action_invert_selection (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- nautilus_view_invert_selection (user_data);
-}
-
-static void
-pattern_select_response_cb (GtkWidget *dialog, int response, gpointer user_data)
-{
- NautilusView *view;
- NautilusDirectory *directory;
- GtkWidget *entry;
- GList *selection;
-
- view = NAUTILUS_VIEW (user_data);
-
- switch (response) {
- case GTK_RESPONSE_OK :
- entry = g_object_get_data (G_OBJECT (dialog), "entry");
- directory = nautilus_view_get_model (view);
- selection = nautilus_directory_match_pattern (directory,
- gtk_entry_get_text (GTK_ENTRY (entry)));
-
- if (selection) {
- nautilus_view_call_set_selection (view, selection);
- nautilus_file_list_free (selection);
-
- nautilus_view_reveal_selection(view);
- }
- /* fall through */
- case GTK_RESPONSE_NONE :
- case GTK_RESPONSE_DELETE_EVENT :
- case GTK_RESPONSE_CANCEL :
- gtk_widget_destroy (GTK_WIDGET (dialog));
- break;
- default :
- g_assert_not_reached ();
- }
-}
-
-static void
-select_pattern (NautilusView *view)
-{
- GtkWidget *dialog;
- GtkWidget *label;
- GtkWidget *example;
- GtkWidget *grid;
- GtkWidget *entry;
- char *example_pattern;
-
- dialog = gtk_dialog_new_with_buttons (_("Select Items Matching"),
- nautilus_view_get_containing_window (view),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR,
- _("_Cancel"),
- GTK_RESPONSE_CANCEL,
- _("_Select"),
- GTK_RESPONSE_OK,
- NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog),
- GTK_RESPONSE_OK);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
- gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 2);
-
- label = gtk_label_new_with_mnemonic (_("_Pattern:"));
- gtk_widget_set_halign (label, GTK_ALIGN_START);
-
- example = gtk_label_new (NULL);
- gtk_widget_set_halign (example, GTK_ALIGN_START);
- example_pattern = g_strdup_printf ("%s<i>%s</i> ",
- _("Examples: "),
- "*.png, file\?\?.txt, pict*.\?\?\?");
- gtk_label_set_markup (GTK_LABEL (example), example_pattern);
- g_free (example_pattern);
-
- entry = gtk_entry_new ();
- gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
- gtk_widget_set_hexpand (entry, TRUE);
-
- grid = gtk_grid_new ();
- g_object_set (grid,
- "orientation", GTK_ORIENTATION_VERTICAL,
- "border-width", 6,
- "row-spacing", 6,
- "column-spacing", 12,
- NULL);
-
- gtk_container_add (GTK_CONTAINER (grid), label);
- gtk_grid_attach_next_to (GTK_GRID (grid), entry, label,
- GTK_POS_RIGHT, 1, 1);
- gtk_grid_attach_next_to (GTK_GRID (grid), example, entry,
- GTK_POS_BOTTOM, 1, 1);
-
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
- gtk_widget_show_all (grid);
- gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), grid);
- g_object_set_data (G_OBJECT (dialog), "entry", entry);
- g_signal_connect (dialog, "response",
- G_CALLBACK (pattern_select_response_cb),
- view);
- gtk_widget_show_all (dialog);
-}
-
-static void
-action_select_pattern (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- select_pattern(user_data);
-}
-
-static void
-zoom_level_changed (GtkRange *range,
- NautilusView *view)
-{
- g_action_group_change_action_state (view->details->view_action_group,
- "zoom-to-level",
- g_variant_new_int32 (gtk_range_get_value (range)));
-}
-
-static void
-reveal_newly_added_folder (NautilusView *view, NautilusFile *new_file,
- NautilusDirectory *directory, GFile *target_location)
-{
- GFile *location;
-
- location = nautilus_file_get_location (new_file);
- if (g_file_equal (location, target_location)) {
- g_signal_handlers_disconnect_by_func (view,
- G_CALLBACK (reveal_newly_added_folder),
- (void *) target_location);
- nautilus_view_select_file (view, new_file);
- }
- g_object_unref (location);
-}
-
-typedef struct {
- NautilusView *directory_view;
- GHashTable *added_locations;
- GList *selection;
-} NewFolderData;
-
-typedef struct {
- NautilusView *directory_view;
- GHashTable *to_remove_locations;
- NautilusFile *new_folder;
-} NewFolderSelectionData;
-
-static void
-track_newly_added_locations (NautilusView *view, NautilusFile *new_file,
- NautilusDirectory *directory, gpointer user_data)
-{
- NewFolderData *data;
-
- data = user_data;
-
- g_hash_table_insert (data->added_locations, nautilus_file_get_location (new_file), NULL);
-}
-
-static void
-new_folder_done (GFile *new_folder,
- gboolean success,
- gpointer user_data)
-{
- NautilusView *directory_view;
- NautilusFile *file;
- char screen_string[32];
- GdkScreen *screen;
- NewFolderData *data;
-
- data = (NewFolderData *)user_data;
-
- directory_view = data->directory_view;
-
- if (directory_view == NULL) {
- goto fail;
- }
-
- g_signal_handlers_disconnect_by_func (directory_view,
- G_CALLBACK (track_newly_added_locations),
- (void *) data);
-
- if (new_folder == NULL) {
- goto fail;
- }
-
- screen = gtk_widget_get_screen (GTK_WIDGET (directory_view));
- g_snprintf (screen_string, sizeof (screen_string), "%d", gdk_screen_get_number (screen));
-
-
- file = nautilus_file_get (new_folder);
- nautilus_file_set_metadata
- (file, NAUTILUS_METADATA_KEY_SCREEN,
- NULL,
- screen_string);
-
- if (data->selection != NULL) {
- NewFolderSelectionData *sdata;
- GList *uris, *l;
- char *target_uri;
-
- sdata = g_new (NewFolderSelectionData, 1);
- sdata->directory_view = directory_view;
- sdata->to_remove_locations = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
- g_object_unref, NULL);
- sdata->new_folder = g_object_ref (file);
-
- uris = NULL;
- for (l = data->selection; l != NULL; l = l->next) {
- GFile *old_location;
- GFile *new_location;
- char *basename;
-
- uris = g_list_prepend (uris, nautilus_file_get_uri ((NautilusFile *) l->data));
-
- old_location = nautilus_file_get_location (l->data);
- basename = g_file_get_basename (old_location);
- new_location = g_file_resolve_relative_path (new_folder, basename);
- g_hash_table_insert (sdata->to_remove_locations, new_location, NULL);
- g_free (basename);
- g_object_unref (old_location);
- }
- uris = g_list_reverse (uris);
-
- target_uri = nautilus_file_get_uri (file);
-
- nautilus_view_move_copy_items (directory_view,
- uris,
- NULL,
- target_uri,
- GDK_ACTION_MOVE,
- 0, 0);
- g_list_free_full (uris, g_free);
- g_free (target_uri);
- } else {
- if (g_hash_table_lookup_extended (data->added_locations, new_folder, NULL, NULL)) {
- /* The file was already added */
- nautilus_view_select_file (directory_view, file);
- } else {
- /* We need to run after the default handler adds the folder we want to
- * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
- * must use connect_after.
- */
- g_signal_connect_data (directory_view,
- "add-file",
- G_CALLBACK (reveal_newly_added_folder),
- g_object_ref (new_folder),
- (GClosureNotify)g_object_unref,
- G_CONNECT_AFTER);
- }
- }
-
- nautilus_file_unref (file);
-
- fail:
- g_hash_table_destroy (data->added_locations);
-
- if (data->directory_view != NULL) {
- g_object_remove_weak_pointer (G_OBJECT (data->directory_view),
- (gpointer *) &data->directory_view);
- }
-
- nautilus_file_list_free (data->selection);
- g_free (data);
-}
-
-
-static NewFolderData *
-new_folder_data_new (NautilusView *directory_view,
- gboolean with_selection)
-{
- NewFolderData *data;
-
- data = g_new (NewFolderData, 1);
- data->directory_view = directory_view;
- data->added_locations = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
- g_object_unref, NULL);
- if (with_selection) {
- data->selection = nautilus_view_get_selection_for_file_transfer (directory_view);
- } else {
- data->selection = NULL;
- }
- g_object_add_weak_pointer (G_OBJECT (data->directory_view),
- (gpointer *) &data->directory_view);
-
- return data;
-}
-
-static GdkPoint *
-context_menu_to_file_operation_position (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
-
- if (nautilus_view_using_manual_layout (view)
- && view->details->context_menu_position.x >= 0
- && view->details->context_menu_position.y >= 0) {
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->widget_to_file_operation_position
- (view, &view->details->context_menu_position);
- return &view->details->context_menu_position;
- } else {
- return NULL;
- }
-}
-
-typedef struct {
- NautilusView *view;
- GtkWidget *widget;
- GtkWidget *error_label;
- GtkWidget *name_entry;
- GtkWidget *activate_button;
- gboolean target_is_folder;
- NautilusFile *target_file;
- gboolean duplicated_is_folder;
- void (*on_name_accepted) (gpointer data);
- /* For create folder only */
- gboolean with_selection;
-} FileNameWidgetData;
-
-static gboolean
-duplicated_file_label_show (FileNameWidgetData *data)
-{
- if (data->duplicated_is_folder)
- gtk_label_set_label (GTK_LABEL (data->error_label), _("A folder with that name already exists."));
- else
- gtk_label_set_label (GTK_LABEL (data->error_label), _("A file with that name already exists."));
-
- data->view->details->duplicated_label_timeout_id = 0;
-
- return G_SOURCE_REMOVE;
-}
-
-static gchar*
-validate_file_name (const gchar *name,
- gboolean is_folder)
-{
- gchar *error_message = NULL;
-
- if (strstr (name, "/") != NULL) {
- if (is_folder)
- error_message = _("Folder names cannot contain “/”.");
- else
- error_message = _("Files names cannot contain “/”.");
- } else if (strcmp (name, ".") == 0){
- if (is_folder)
- error_message = _("A folder can not be called “.”.");
- else
- error_message = _("A file can not be called “.”.");
- } else if (strcmp (name, "..") == 0){
- if (is_folder)
- error_message = _("A folder can not be called “..”.");
- else
- error_message = _("A file can not be called “..”.");
- }
-
- return error_message;
-}
-
-static void
-file_name_widget_entry_on_changed (gpointer user_data)
-{
- FileNameWidgetData *data;
- NautilusFile *existing_file;
- gchar *name;
- gchar *error_message;
- gboolean valid_name;
- gboolean duplicated;
-
- data = (FileNameWidgetData *) user_data;
- name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry))));
- error_message = validate_file_name (name, TRUE);
- gtk_label_set_label (GTK_LABEL (data->error_label), error_message);
-
- existing_file = nautilus_directory_get_file_by_name (data->view->details->model, name);
-
- valid_name = strlen (name) > 0 && error_message == NULL;
- /* If there is a target file and the name is the same, we don't show it
- * as duplicated. This is the case for renaming. */
- duplicated = existing_file != NULL &&
- (data->target_file == NULL ||
- nautilus_file_compare_display_name (data->target_file, name) != 0);
- gtk_widget_set_sensitive (data->activate_button, valid_name && !duplicated);
-
- if (data->view->details->duplicated_label_timeout_id > 0) {
- g_source_remove (data->view->details->duplicated_label_timeout_id);
- data->view->details->duplicated_label_timeout_id = 0;
- }
-
- /* Report duplicated file only if not other message shown (for instance,
- * folders like "." or ".." will always exists, but we consider it as an
- * error, not as a duplicated file or if the name is the same as the file
- * we are renaming also don't report as a duplicated */
- if (duplicated && valid_name) {
- data->duplicated_is_folder = nautilus_file_is_directory (existing_file);
- data->view->details->duplicated_label_timeout_id =
- g_timeout_add (FILE_NAME_DUPLICATED_LABEL_TIMEOUT,
- (GSourceFunc)duplicated_file_label_show,
- data);
- }
-
- if (existing_file != NULL)
- nautilus_file_unref (existing_file);
-
- g_free (name);
-}
-
-static void
-create_folder_dialog_on_response (GtkDialog *dialog,
- gint response_id,
- gpointer user_data)
-{
- FileNameWidgetData *widget_data;
-
- widget_data = (FileNameWidgetData *) user_data;
-
- if (response_id == GTK_RESPONSE_OK) {
- NewFolderData *data;
- GdkPoint *pos;
- char *parent_uri;
- gchar *name;
-
- data = new_folder_data_new (widget_data->view, widget_data->with_selection);
-
- name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (widget_data->name_entry))));
- g_signal_connect_data (widget_data->view,
- "add-file",
- G_CALLBACK (track_newly_added_locations),
- data,
- (GClosureNotify)NULL,
- G_CONNECT_AFTER);
-
- pos = context_menu_to_file_operation_position (widget_data->view);
-
- parent_uri = nautilus_view_get_backing_uri (widget_data->view);
- nautilus_file_operations_new_folder (GTK_WIDGET (widget_data->view),
- pos, parent_uri, name,
- new_folder_done, data);
-
- g_free (parent_uri);
- g_free (name);
- }
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
- g_free (user_data);
-}
-
-
-static void
-create_folder_on_name_accepted (gpointer user_data)
-{
- FileNameWidgetData *data;
-
- data = (FileNameWidgetData *) user_data;
- gtk_dialog_response (GTK_DIALOG (data->widget),
- GTK_RESPONSE_OK);
-}
-
-static void
-rename_file_on_name_accepted (gpointer user_data)
-{
- FileNameWidgetData *data;
- gchar *name;
-
- data = (FileNameWidgetData *) user_data;
-
- name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry))));
- nautilus_rename_file (data->target_file, name, NULL, NULL);
-
- nautilus_view_select_file (data->view, data->target_file);
- nautilus_view_reveal_selection (data->view);
-
- gtk_widget_hide (data->widget);
-
- g_free (name);
-}
-
-static void
-file_name_widget_on_activate (gpointer user_data)
-{
- FileNameWidgetData *data;
- NautilusFile *existing_file;
- gchar *name;
- gchar *error_message;
- gboolean valid_name;
- gboolean duplicated;
-
- data = (FileNameWidgetData *) user_data;
- name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry))));
- existing_file = nautilus_directory_get_file_by_name (data->view->details->model, name);
- error_message = validate_file_name (name, TRUE);
- valid_name = strlen (name) > 0 && error_message == NULL;
- duplicated = existing_file != NULL &&
- (data->target_file == NULL ||
- nautilus_file_compare_display_name (data->target_file, name) != 0);
-
- if (data->view->details->duplicated_label_timeout_id > 0) {
- g_source_remove (data->view->details->duplicated_label_timeout_id);
- data->view->details->duplicated_label_timeout_id = 0;
- }
-
- if (valid_name && !duplicated) {
- data->on_name_accepted ((gpointer) data);
- } else {
- /* Report duplicated file only if not other message shown (for instance,
- * folders like "." or ".." will always exists, but we consider it as an
- * error, not as a duplicated file) */
- if (existing_file != NULL && valid_name) {
- data->duplicated_is_folder = nautilus_file_is_directory (existing_file);
- /* Show it inmediatily since the user tried to trigger the action */
- duplicated_file_label_show (data);
- }
- }
-
- if (existing_file != NULL)
- nautilus_file_unref (existing_file);
-
- g_free (name);
-}
-
-static void
-rename_file_popover_on_closed (GtkPopover *popover,
- gpointer user_data)
-{
- FileNameWidgetData *widget_data;
-
- widget_data = (FileNameWidgetData *) user_data;
- widget_data->view->details->rename_file_popover = NULL;
- g_free (widget_data);
-}
-
-static GdkRectangle*
-nautilus_view_compute_rename_popover_relative_to (NautilusView *view)
-{
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->compute_rename_popover_relative_to (view);
-}
-
-static void
-nautilus_view_rename_file_popover_new (NautilusView *view,
- NautilusFile *target_file)
-{
- FileNameWidgetData *widget_data;
- GtkWidget *label_file_name;
- GtkBuilder *builder;
- gint start_offset, end_offset;
- GdkRectangle *relative_to;
-
- if (view->details->rename_file_popover != NULL)
- return;
-
- builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-rename-file-popover.ui");
- label_file_name = GTK_WIDGET (gtk_builder_get_object (builder, "name_label"));
-
- widget_data = g_new (FileNameWidgetData, 1);
- widget_data->view = view;
- widget_data->on_name_accepted = rename_file_on_name_accepted;
- widget_data->widget = GTK_WIDGET (gtk_builder_get_object (builder, "rename_file_popover"));
- widget_data->activate_button = GTK_WIDGET (gtk_builder_get_object (builder, "rename_button"));
- widget_data->error_label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
- widget_data->name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
- widget_data->target_is_folder = nautilus_file_is_directory (target_file);
- widget_data->target_file = target_file;
-
- view->details->rename_file_popover = widget_data->widget;
-
- /* Connect signals */
- gtk_builder_add_callback_symbols (builder,
- "file_name_widget_entry_on_changed",
- G_CALLBACK (file_name_widget_entry_on_changed),
- "file_name_widget_on_activate",
- G_CALLBACK (file_name_widget_on_activate),
- "rename_file_popover_on_closed",
- G_CALLBACK (rename_file_popover_on_closed),
- "rename_file_popover_on_unmap",
- G_CALLBACK (gtk_widget_destroy),
- NULL);
-
- gtk_builder_connect_signals (builder, widget_data);
-
- if (widget_data->target_is_folder)
- gtk_label_set_text (GTK_LABEL (label_file_name), _("Folder name"));
- else
- gtk_label_set_text (GTK_LABEL (label_file_name), _("File name"));
- gtk_entry_set_text (GTK_ENTRY (widget_data->name_entry), nautilus_file_get_name (target_file));
-
- relative_to = nautilus_view_compute_rename_popover_relative_to (view);
- gtk_popover_set_default_widget (GTK_POPOVER (widget_data->widget),
- widget_data->activate_button);
- gtk_popover_set_pointing_to (GTK_POPOVER (widget_data->widget), relative_to);
- gtk_popover_set_relative_to (GTK_POPOVER (widget_data->widget),
- GTK_WIDGET (view));
- gtk_widget_show (widget_data->widget);
- gtk_widget_grab_focus (widget_data->widget);
-
- /* Select the name part withouth the file extension */
- eel_filename_get_rename_region (nautilus_file_get_name (target_file),
- &start_offset, &end_offset);
- gtk_editable_select_region (GTK_EDITABLE (widget_data->name_entry),
- start_offset, end_offset);
-
- /* Update the rename button status */
- file_name_widget_entry_on_changed (widget_data);
-
-
- g_object_unref (builder);
-}
-
-static void
-nautilus_view_new_folder_dialog_new (NautilusView *view,
- gboolean with_selection)
-{
- FileNameWidgetData *widget_data;
- GtkWidget *label_file_name;
- GtkBuilder *builder;
-
- builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-create-folder-dialog.ui");
- label_file_name = GTK_WIDGET (gtk_builder_get_object (builder, "name_label"));
-
- widget_data = g_new (FileNameWidgetData, 1);
- widget_data->view = view;
- widget_data->on_name_accepted = create_folder_on_name_accepted;
- widget_data->widget = GTK_WIDGET (gtk_builder_get_object (builder, "create_folder_dialog"));
- widget_data->activate_button = GTK_WIDGET (gtk_builder_get_object (builder, "ok_button"));
- widget_data->error_label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
- widget_data->name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
- widget_data->target_is_folder = TRUE;
- widget_data->target_file = NULL;
- widget_data->with_selection = with_selection;
-
- gtk_window_set_transient_for (GTK_WINDOW (widget_data->widget),
- GTK_WINDOW (nautilus_view_get_window (view)));
-
- /* Connect signals */
- gtk_builder_add_callback_symbols (builder,
- "file_name_widget_entry_on_changed",
- G_CALLBACK (file_name_widget_entry_on_changed),
- "file_name_widget_on_activate",
- G_CALLBACK (file_name_widget_on_activate),
- "create_folder_dialog_on_response",
- G_CALLBACK (create_folder_dialog_on_response),
- NULL);
-
- gtk_builder_connect_signals (builder, widget_data);
- gtk_button_set_label (GTK_BUTTON (widget_data->activate_button),
- _("Create"));
- gtk_label_set_text (GTK_LABEL (label_file_name), _("Folder name"));
- gtk_window_set_title (GTK_WINDOW (widget_data->widget), _("New Folder"));
-
- gtk_widget_show_all (widget_data->widget);
- /* Update the ok button status */
- file_name_widget_entry_on_changed (widget_data);
-
- g_object_unref (builder);
-}
-
-static void
-nautilus_view_new_folder (NautilusView *directory_view,
- gboolean with_selection)
-{
- nautilus_view_new_folder_dialog_new (directory_view, with_selection);
-}
-
-static NewFolderData *
-setup_new_folder_data (NautilusView *directory_view)
-{
- NewFolderData *data;
-
- data = new_folder_data_new (directory_view, FALSE);
-
- g_signal_connect_data (directory_view,
- "add-file",
- G_CALLBACK (track_newly_added_locations),
- data,
- (GClosureNotify)NULL,
- G_CONNECT_AFTER);
-
- return data;
-}
-
-void
-nautilus_view_new_file_with_initial_contents (NautilusView *view,
- const char *parent_uri,
- const char *filename,
- const char *initial_contents,
- int length,
- GdkPoint *pos)
-{
- NewFolderData *data;
-
- g_assert (parent_uri != NULL);
-
- data = setup_new_folder_data (view);
-
- if (pos == NULL) {
- pos = context_menu_to_file_operation_position (view);
- }
-
- nautilus_file_operations_new_file (GTK_WIDGET (view),
- pos, parent_uri, filename,
- initial_contents, length,
- new_folder_done, data);
-}
-
-static void
-nautilus_view_new_file (NautilusView *directory_view,
- const char *parent_uri,
- NautilusFile *source)
-{
- GdkPoint *pos;
- NewFolderData *data;
- char *source_uri;
- char *container_uri;
-
- container_uri = NULL;
- if (parent_uri == NULL) {
- container_uri = nautilus_view_get_backing_uri (directory_view);
- g_assert (container_uri != NULL);
- }
-
- if (source == NULL) {
- nautilus_view_new_file_with_initial_contents (directory_view,
- parent_uri != NULL ? parent_uri : container_uri,
- NULL,
- NULL,
- 0,
- NULL);
- g_free (container_uri);
- return;
- }
-
- g_return_if_fail (nautilus_file_is_local (source));
-
- pos = context_menu_to_file_operation_position (directory_view);
-
- data = setup_new_folder_data (directory_view);
-
- source_uri = nautilus_file_get_uri (source);
-
- nautilus_file_operations_new_file_from_template (GTK_WIDGET (directory_view),
- pos,
- parent_uri != NULL ? parent_uri : container_uri,
- NULL,
- source_uri,
- new_folder_done, data);
-
- g_free (source_uri);
- g_free (container_uri);
-}
-
-static void
-action_new_folder (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- nautilus_view_new_folder (NAUTILUS_VIEW (user_data), FALSE);
-}
-
-static void
-action_new_folder_with_selection (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- nautilus_view_new_folder (NAUTILUS_VIEW (user_data), TRUE);
-}
-
-static void
-action_properties (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
- GList *selection;
- GList *files;
-
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- view = NAUTILUS_VIEW (user_data);
- selection = nautilus_view_get_selection (view);
- if (g_list_length (selection) == 0) {
- if (view->details->directory_as_file != NULL) {
- files = g_list_append (NULL, nautilus_file_ref (view->details->directory_as_file));
-
- nautilus_properties_window_present (files, GTK_WIDGET (view), NULL);
-
- nautilus_file_list_free (files);
- }
- } else {
- nautilus_properties_window_present (selection, GTK_WIDGET (view), NULL);
- }
- nautilus_file_list_free (selection);
-}
-
-static void
-nautilus_view_set_show_hidden_files (NautilusView *view,
- gboolean show_hidden)
-{
- if (view->details->ignore_hidden_file_preferences) {
- return;
- }
-
- if (show_hidden != view->details->show_hidden_files) {
- view->details->show_hidden_files = show_hidden;
-
- g_settings_set_boolean (gtk_filechooser_preferences,
- NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
- show_hidden);
-
- if (view->details->model != NULL) {
- load_directory (view, view->details->model);
- }
- }
-}
-
-static void
-action_show_hidden_files (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- gboolean show_hidden;
- NautilusView *view;
-
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- view = NAUTILUS_VIEW (user_data);
- show_hidden = g_variant_get_boolean (state);
-
- nautilus_view_set_show_hidden_files (view, show_hidden);
-
- g_simple_action_set_state (action, state);
-}
-
-static void
-action_zoom_in (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
-
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- view = NAUTILUS_VIEW (user_data);
-
- nautilus_view_bump_zoom_level (view, 1);
-}
-
-static void
-action_zoom_out (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
-
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- view = NAUTILUS_VIEW (user_data);
-
- nautilus_view_bump_zoom_level (view, -1);
-}
-
-static void
-action_zoom_default (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- nautilus_view_restore_default_zoom_level (user_data);
-}
-
-static void
-action_open_item_new_window (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
- GtkWindow *window;
- GList *selection;
-
- view = NAUTILUS_VIEW (user_data);
- selection = nautilus_view_get_selection (view);
- window = GTK_WINDOW (nautilus_view_get_containing_window (view));
-
- if (nautilus_view_confirm_multiple (window, g_list_length (selection), TRUE)) {
- g_list_foreach (selection, open_one_in_new_window, view);
- }
-
- nautilus_file_list_free (selection);
-}
-
-static void
-paste_clipboard_data (NautilusView *view,
- GtkSelectionData *selection_data,
- char *destination_uri)
-{
- gboolean cut;
- GList *item_uris;
-
- cut = FALSE;
- item_uris = nautilus_clipboard_get_uri_list_from_selection_data (selection_data, &cut,
- copied_files_atom);
-
- if (item_uris != NULL && destination_uri != NULL) {
- nautilus_view_move_copy_items (view, item_uris, NULL, destination_uri,
- cut ? GDK_ACTION_MOVE : GDK_ACTION_COPY,
- 0, 0);
-
- /* If items are cut then remove from clipboard */
- if (cut) {
- gtk_clipboard_clear (nautilus_clipboard_get (GTK_WIDGET (view)));
- }
-
- g_list_free_full (item_uris, g_free);
- }
-}
-
-static void
-paste_clipboard_received_callback (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- gpointer data)
-{
- NautilusView *view;
- char *view_uri;
-
- view = NAUTILUS_VIEW (data);
-
- view_uri = nautilus_view_get_backing_uri (view);
-
- if (view->details->slot != NULL) {
- paste_clipboard_data (view, selection_data, view_uri);
- }
-
- g_free (view_uri);
-
- g_object_unref (view);
-}
-
-static void
-action_paste_files (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
-
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- view = NAUTILUS_VIEW (user_data);
-
- g_object_ref (view);
- gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
- copied_files_atom,
- paste_clipboard_received_callback,
- view);
-}
-
-static void
-click_policy_changed_callback (gpointer callback_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (callback_data);
-
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->click_policy_changed (view);
-}
-
-gboolean
-nautilus_view_should_sort_directories_first (NautilusView *view)
-{
- return view->details->sort_directories_first;
-}
-
-static void
-sort_directories_first_changed_callback (gpointer callback_data)
-{
- NautilusView *view;
- gboolean preference_value;
-
- view = NAUTILUS_VIEW (callback_data);
-
- preference_value =
- g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
-
- if (preference_value != view->details->sort_directories_first) {
- view->details->sort_directories_first = preference_value;
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->sort_directories_first_changed (view);
- }
-}
-
-static void
-show_hidden_files_changed_callback (gpointer callback_data)
-{
- NautilusView *view;
- gboolean preference_value;
-
- view = NAUTILUS_VIEW (callback_data);
-
- preference_value =
- g_settings_get_boolean (gtk_filechooser_preferences, NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES);
-
- nautilus_view_set_show_hidden_files (view, preference_value);
-}
-
-static gboolean
-set_up_scripts_directory_global (void)
-{
- char *old_scripts_directory_path;
- char *scripts_directory_path;
- const char *override;
-
- if (scripts_directory_uri != NULL) {
- return TRUE;
- }
-
- scripts_directory_path = nautilus_get_scripts_directory_path ();
-
- override = g_getenv ("GNOME22_USER_DIR");
-
- if (override) {
- old_scripts_directory_path = g_build_filename (override,
- "nautilus-scripts",
- NULL);
- } else {
- old_scripts_directory_path = g_build_filename (g_get_home_dir (),
- ".gnome2",
- "nautilus-scripts",
- NULL);
- }
-
- if (g_file_test (old_scripts_directory_path, G_FILE_TEST_IS_DIR)
- && !g_file_test (scripts_directory_path, G_FILE_TEST_EXISTS)) {
- char *updated;
- const char *message;
-
- /* test if we already attempted to migrate first */
- updated = g_build_filename (old_scripts_directory_path, "DEPRECATED-DIRECTORY", NULL);
- message = _("Nautilus 3.6 deprecated this directory and tried migrating "
- "this configuration to ~/.local/share/nautilus");
- if (!g_file_test (updated, G_FILE_TEST_EXISTS)) {
- char *parent_dir;
-
- parent_dir = g_path_get_dirname (scripts_directory_path);
- if (g_mkdir_with_parents (parent_dir, 0700) == 0) {
- int fd, res;
-
- /* rename() works fine if the destination directory is
- * empty.
- */
- res = g_rename (old_scripts_directory_path, scripts_directory_path);
- if (res == -1) {
- fd = g_creat (updated, 0600);
- if (fd != -1) {
- res = write (fd, message, strlen (message));
- close (fd);
- }
- }
- }
- g_free (parent_dir);
- }
-
- g_free (updated);
- }
-
- if (g_mkdir_with_parents (scripts_directory_path, 0700) == 0) {
- scripts_directory_uri = g_filename_to_uri (scripts_directory_path, NULL, NULL);
- scripts_directory_uri_length = strlen (scripts_directory_uri);
- }
-
- g_free (scripts_directory_path);
- g_free (old_scripts_directory_path);
-
- return (scripts_directory_uri != NULL) ? TRUE : FALSE;
-}
-
-static void
-scripts_added_or_changed_callback (NautilusDirectory *directory,
- GList *files,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (callback_data);
-
- if (view->details->active) {
- schedule_update_context_menus (view);
- }
-}
-
-static void
-templates_added_or_changed_callback (NautilusDirectory *directory,
- GList *files,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (callback_data);
-
- if (view->details->active) {
- schedule_update_context_menus (view);
- }
-}
-
-static void
-add_directory_to_directory_list (NautilusView *view,
- NautilusDirectory *directory,
- GList **directory_list,
- GCallback changed_callback)
-{
- NautilusFileAttributes attributes;
-
- if (g_list_find (*directory_list, directory) == NULL) {
- nautilus_directory_ref (directory);
-
- attributes =
- NAUTILUS_FILE_ATTRIBUTES_FOR_ICON |
- NAUTILUS_FILE_ATTRIBUTE_INFO |
- NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT;
-
- nautilus_directory_file_monitor_add (directory, directory_list,
- FALSE, attributes,
- (NautilusDirectoryCallback)changed_callback, view);
-
- g_signal_connect_object (directory, "files-added",
- G_CALLBACK (changed_callback), view, 0);
- g_signal_connect_object (directory, "files-changed",
- G_CALLBACK (changed_callback), view, 0);
-
- *directory_list = g_list_append (*directory_list, directory);
- }
-}
-
-static void
-remove_directory_from_directory_list (NautilusView *view,
- NautilusDirectory *directory,
- GList **directory_list,
- GCallback changed_callback)
-{
- *directory_list = g_list_remove (*directory_list, directory);
-
- g_signal_handlers_disconnect_by_func (directory,
- G_CALLBACK (changed_callback),
- view);
-
- nautilus_directory_file_monitor_remove (directory, directory_list);
-
- nautilus_directory_unref (directory);
-}
-
-
-static void
-add_directory_to_scripts_directory_list (NautilusView *view,
- NautilusDirectory *directory)
-{
- add_directory_to_directory_list (view, directory,
- &view->details->scripts_directory_list,
- G_CALLBACK (scripts_added_or_changed_callback));
-}
-
-static void
-remove_directory_from_scripts_directory_list (NautilusView *view,
- NautilusDirectory *directory)
-{
- remove_directory_from_directory_list (view, directory,
- &view->details->scripts_directory_list,
- G_CALLBACK (scripts_added_or_changed_callback));
-}
-
-static void
-add_directory_to_templates_directory_list (NautilusView *view,
- NautilusDirectory *directory)
-{
- add_directory_to_directory_list (view, directory,
- &view->details->templates_directory_list,
- G_CALLBACK (templates_added_or_changed_callback));
-}
-
-static void
-remove_directory_from_templates_directory_list (NautilusView *view,
- NautilusDirectory *directory)
-{
- remove_directory_from_directory_list (view, directory,
- &view->details->templates_directory_list,
- G_CALLBACK (templates_added_or_changed_callback));
-}
-
-static void
-slot_active (NautilusWindowSlot *slot,
- NautilusView *view)
-{
- if (view->details->active) {
- return;
- }
-
- view->details->active = TRUE;
-
- /* Avoid updating the toolbar withouth making sure the toolbar
- * zoom slider has the correct adjustment that changes when the
- * view mode changes
- */
- nautilus_window_slot_sync_view_mode (slot);
- nautilus_view_update_context_menus(view);
- nautilus_view_update_toolbar_menus (view);
-
- schedule_update_context_menus (view);
-
- gtk_widget_insert_action_group (GTK_WIDGET (nautilus_view_get_window (view)),
- "view",
- G_ACTION_GROUP (view->details->view_action_group));
-}
-
-static void
-slot_inactive (NautilusWindowSlot *slot,
- NautilusView *view)
-{
- if (!view->details->active) {
- return;
- }
-
- view->details->active = FALSE;
-
- remove_update_context_menus_timeout_callback (view);
- gtk_widget_insert_action_group (GTK_WIDGET (nautilus_view_get_window (view)),
- "view",
- NULL);
-}
-
-static void
-nautilus_view_grab_focus (GtkWidget *widget)
-{
- /* focus the child of the scrolled window if it exists */
- NautilusView *view;
- GtkWidget *child;
-
- view = NAUTILUS_VIEW (widget);
- child = gtk_bin_get_child (GTK_BIN (view->details->scrolled_window));
-
- GTK_WIDGET_CLASS (nautilus_view_parent_class)->grab_focus (widget);
-
- if (child) {
- gtk_widget_grab_focus (GTK_WIDGET (child));
- }
-}
-
-int
-nautilus_view_get_selection_count (NautilusView *view)
-{
- /* FIXME: This could be faster if we special cased it in subclasses */
- GList *files;
- int len;
-
- files = nautilus_view_get_selection (NAUTILUS_VIEW (view));
- len = g_list_length (files);
- nautilus_file_list_free (files);
-
- return len;
-}
-
-void
-nautilus_view_set_selection (NautilusView *nautilus_view,
- GList *selection)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (nautilus_view);
-
- if (!view->details->loading) {
- /* If we aren't still loading, set the selection right now,
- * and reveal the new selection.
- */
- nautilus_view_call_set_selection (view, selection);
- nautilus_view_reveal_selection (view);
- } else {
- /* If we are still loading, set the list of pending URIs instead.
- * done_loading() will eventually select the pending URIs and reveal them.
- */
- g_list_free_full (view->details->pending_selection, g_object_unref);
- view->details->pending_selection =
- g_list_copy_deep (selection, (GCopyFunc) g_object_ref, NULL);
- }
-}
-
-static char *
-get_bulk_rename_tool ()
-{
- char *bulk_rename_tool;
- g_settings_get (nautilus_preferences, NAUTILUS_PREFERENCES_BULK_RENAME_TOOL, "^ay", &bulk_rename_tool);
- return g_strstrip (bulk_rename_tool);
-}
-
-static gboolean
-have_bulk_rename_tool ()
-{
- char *bulk_rename_tool;
- gboolean have_tool;
-
- bulk_rename_tool = get_bulk_rename_tool ();
- have_tool = ((bulk_rename_tool != NULL) && (*bulk_rename_tool != '\0'));
- g_free (bulk_rename_tool);
- return have_tool;
-}
-
-static void
-nautilus_view_destroy (GtkWidget *object)
-{
- NautilusView *view;
- GList *node, *next;
-
- view = NAUTILUS_VIEW (object);
-
- nautilus_view_stop_loading (view);
-
- for (node = view->details->scripts_directory_list; node != NULL; node = next) {
- next = node->next;
- remove_directory_from_scripts_directory_list (view, node->data);
- }
-
- for (node = view->details->templates_directory_list; node != NULL; node = next) {
- next = node->next;
- remove_directory_from_templates_directory_list (view, node->data);
- }
-
- while (view->details->subdirectory_list != NULL) {
- nautilus_view_remove_subdirectory (view,
- view->details->subdirectory_list->data);
- }
-
- remove_update_context_menus_timeout_callback (view);
- remove_update_status_idle_callback (view);
-
- if (view->details->display_selection_idle_id != 0) {
- g_source_remove (view->details->display_selection_idle_id);
- view->details->display_selection_idle_id = 0;
- }
-
- if (view->details->reveal_selection_idle_id != 0) {
- g_source_remove (view->details->reveal_selection_idle_id);
- view->details->reveal_selection_idle_id = 0;
- }
-
- if (view->details->floating_bar_set_status_timeout_id != 0) {
- g_source_remove (view->details->floating_bar_set_status_timeout_id);
- view->details->floating_bar_set_status_timeout_id = 0;
- }
-
- if (view->details->floating_bar_loading_timeout_id != 0) {
- g_source_remove (view->details->floating_bar_loading_timeout_id);
- view->details->floating_bar_loading_timeout_id = 0;
- }
-
-
- if (view->details->directory_as_file) {
- nautilus_file_unref (view->details->directory_as_file);
- view->details->directory_as_file = NULL;
- }
-
- /* We don't own the slot, so no unref */
- view->details->slot = NULL;
-
- GTK_WIDGET_CLASS (nautilus_view_parent_class)->destroy (object);
-}
-
-static void
-nautilus_view_finalize (GObject *object)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (object);
-
- g_signal_handlers_disconnect_by_func (nautilus_preferences,
- schedule_update_context_menus, view);
- g_signal_handlers_disconnect_by_func (nautilus_preferences,
- click_policy_changed_callback, view);
- g_signal_handlers_disconnect_by_func (nautilus_preferences,
- sort_directories_first_changed_callback, view);
- g_signal_handlers_disconnect_by_func (gtk_filechooser_preferences,
- show_hidden_files_changed_callback, view);
- g_signal_handlers_disconnect_by_func (nautilus_window_state,
- nautilus_view_display_selection_info, view);
-
- g_signal_handlers_disconnect_by_func (gnome_lockdown_preferences,
- schedule_update_context_menus, view);
-
- g_hash_table_destroy (view->details->non_ready_files);
-
- if (view->details->rename_file_popover != NULL) {
- gtk_popover_set_relative_to (GTK_POPOVER (view->details->rename_file_popover),
- NULL);
- }
-
- G_OBJECT_CLASS (nautilus_view_parent_class)->finalize (object);
-}
-
-/**
- * nautilus_view_display_selection_info:
- *
- * Display information about the current selection, and notify the view frame of the changed selection.
- * @view: NautilusView for which to display selection info.
- *
- **/
-void
-nautilus_view_display_selection_info (NautilusView *view)
-{
- GList *selection;
- goffset non_folder_size;
- gboolean non_folder_size_known;
- guint non_folder_count, folder_count, folder_item_count;
- gboolean folder_item_count_known;
- guint file_item_count;
- GList *p;
- char *first_item_name;
- char *non_folder_count_str;
- char *non_folder_item_count_str;
- char *folder_count_str;
- char *folder_item_count_str;
- char *primary_status;
- char *detail_status;
- NautilusFile *file;
-
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- selection = nautilus_view_get_selection (view);
-
- folder_item_count_known = TRUE;
- folder_count = 0;
- folder_item_count = 0;
- non_folder_count = 0;
- non_folder_size_known = FALSE;
- non_folder_size = 0;
- first_item_name = NULL;
- folder_count_str = NULL;
- folder_item_count_str = NULL;
- non_folder_count_str = NULL;
- non_folder_item_count_str = NULL;
-
- for (p = selection; p != NULL; p = p->next) {
- file = p->data;
- if (nautilus_file_is_directory (file)) {
- folder_count++;
- if (nautilus_file_get_directory_item_count (file, &file_item_count, NULL)) {
- folder_item_count += file_item_count;
- } else {
- folder_item_count_known = FALSE;
- }
- } else {
- non_folder_count++;
- if (!nautilus_file_can_get_size (file)) {
- non_folder_size_known = TRUE;
- non_folder_size += nautilus_file_get_size (file);
- }
- }
-
- if (first_item_name == NULL) {
- first_item_name = nautilus_file_get_display_name (file);
- }
- }
-
- nautilus_file_list_free (selection);
-
- /* Break out cases for localization's sake. But note that there are still pieces
- * being assembled in a particular order, which may be a problem for some localizers.
- */
-
- if (folder_count != 0) {
- if (folder_count == 1 && non_folder_count == 0) {
- folder_count_str = g_strdup_printf (_("“%s” selected"), first_item_name);
- } else {
- folder_count_str = g_strdup_printf (ngettext("%'d folder selected",
- "%'d folders selected",
- folder_count),
- folder_count);
- }
-
- if (folder_count == 1) {
- if (!folder_item_count_known) {
- folder_item_count_str = g_strdup ("");
- } else {
- folder_item_count_str = g_strdup_printf (ngettext("(containing %'d item)",
- "(containing %'d items)",
- folder_item_count),
- folder_item_count);
- }
- }
- else {
- if (!folder_item_count_known) {
- folder_item_count_str = g_strdup ("");
- } else {
- /* translators: this is preceded with a string of form 'N folders' (N more than 1) */
- folder_item_count_str = g_strdup_printf (ngettext("(containing a total of %'d item)",
- "(containing a total of %'d items)",
- folder_item_count),
- folder_item_count);
- }
-
- }
- }
-
- if (non_folder_count != 0) {
- if (folder_count == 0) {
- if (non_folder_count == 1) {
- non_folder_count_str = g_strdup_printf (_("“%s” selected"),
- first_item_name);
- } else {
- non_folder_count_str = g_strdup_printf (ngettext("%'d item selected",
- "%'d items selected",
- non_folder_count),
- non_folder_count);
- }
- } else {
- /* Folders selected also, use "other" terminology */
- non_folder_count_str = g_strdup_printf (ngettext("%'d other item selected",
- "%'d other items selected",
- non_folder_count),
- non_folder_count);
- }
-
- if (non_folder_size_known) {
- char *size_string;
-
- size_string = g_format_size (non_folder_size);
- /* This is marked for translation in case a localiser
- * needs to use something other than parentheses. The
- * the message in parentheses is the size of the selected items.
- */
- non_folder_item_count_str = g_strdup_printf (_("(%s)"), size_string);
- g_free (size_string);
- } else {
- non_folder_item_count_str = g_strdup ("");
- }
- }
-
- if (folder_count == 0 && non_folder_count == 0) {
- primary_status = NULL;
- detail_status = NULL;
- } else if (folder_count == 0) {
- primary_status = g_strdup (non_folder_count_str);
- detail_status = g_strdup (non_folder_item_count_str);
- } else if (non_folder_count == 0) {
- primary_status = g_strdup (folder_count_str);
- detail_status = g_strdup (folder_item_count_str);
- } else {
- /* This is marked for translation in case a localizer
- * needs to change ", " to something else. The comma
- * is between the message about the number of folders
- * and the number of items in those folders and the
- * message about the number of other items and the
- * total size of those items.
- */
- primary_status = g_strdup_printf (_("%s %s, %s %s"),
- folder_count_str,
- folder_item_count_str,
- non_folder_count_str,
- non_folder_item_count_str);
- detail_status = NULL;
- }
-
- g_free (first_item_name);
- g_free (folder_count_str);
- g_free (folder_item_count_str);
- g_free (non_folder_count_str);
- g_free (non_folder_item_count_str);
-
- set_floating_bar_status (view, primary_status, detail_status);
-
- g_free (primary_status);
- g_free (detail_status);
-}
-
-static void
-nautilus_view_send_selection_change (NautilusView *view)
-{
- g_signal_emit (view, signals[SELECTION_CHANGED], 0);
-}
-
-void
-nautilus_view_load_location (NautilusView *nautilus_view,
- GFile *location)
-{
- NautilusDirectory *directory;
-
- nautilus_profile_start (NULL);
- directory = nautilus_directory_get (location);
- load_directory (nautilus_view, directory);
- nautilus_directory_unref (directory);
- nautilus_profile_end (NULL);
-}
-
-static gboolean
-reveal_selection_idle_callback (gpointer data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (data);
-
- view->details->reveal_selection_idle_id = 0;
- nautilus_view_reveal_selection (view);
-
- return FALSE;
-}
-
-static void
-done_loading (NautilusView *view,
- gboolean all_files_seen)
-{
- GList *selection;
- gboolean do_reveal = FALSE;
-
- if (!view->details->loading) {
- return;
- }
-
- nautilus_profile_start (NULL);
-
- /* This can be called during destruction, in which case we set the model
- * as NULL. */
- if (view->details->model != NULL) {
- nautilus_view_update_toolbar_menus (view);
- remove_loading_floating_bar (view);
- schedule_update_context_menus (view);
- schedule_update_status (view);
- reset_update_interval (view);
-
- selection = view->details->pending_selection;
-
- if (nautilus_view_is_search (view) && all_files_seen) {
- nautilus_view_select_first (view);
- do_reveal = TRUE;
- } else if (selection != NULL && all_files_seen) {
- view->details->pending_selection = NULL;
-
- nautilus_view_call_set_selection (view, selection);
- g_list_free_full (selection, g_object_unref);
- do_reveal = TRUE;
- }
-
- if (do_reveal) {
- if (NAUTILUS_IS_LIST_VIEW (view)) {
- /* HACK: We should be able to directly call reveal_selection here,
- * but at this point the GtkTreeView hasn't allocated the new nodes
- * yet, and it has a bug in the scroll calculation dealing with this
- * special case. It would always make the selection the top row, even
- * if no scrolling would be neccessary to reveal it. So we let it
- * allocate before revealing.
- */
- if (view->details->reveal_selection_idle_id != 0) {
- g_source_remove (view->details->reveal_selection_idle_id);
- }
- view->details->reveal_selection_idle_id =
- g_idle_add (reveal_selection_idle_callback, view);
- } else {
- nautilus_view_reveal_selection (view);
- }
- }
- nautilus_view_display_selection_info (view);
- }
-
- view->details->loading = FALSE;
- g_signal_emit (view, signals[END_LOADING], 0, all_files_seen);
-
- check_empty_states (view);
-
- nautilus_profile_end (NULL);
-}
-
-
-typedef struct {
- GHashTable *debuting_files;
- GList *added_files;
-} DebutingFilesData;
-
-static void
-debuting_files_data_free (DebutingFilesData *data)
-{
- g_hash_table_unref (data->debuting_files);
- nautilus_file_list_free (data->added_files);
- g_free (data);
-}
-
-/* This signal handler watch for the arrival of the icons created
- * as the result of a file operation. Once the last one is detected
- * it selects and reveals them all.
- */
-static void
-debuting_files_add_file_callback (NautilusView *view,
- NautilusFile *new_file,
- NautilusDirectory *directory,
- DebutingFilesData *data)
-{
- GFile *location;
-
- nautilus_profile_start (NULL);
-
- location = nautilus_file_get_location (new_file);
-
- if (g_hash_table_remove (data->debuting_files, location)) {
- nautilus_file_ref (new_file);
- data->added_files = g_list_prepend (data->added_files, new_file);
-
- if (g_hash_table_size (data->debuting_files) == 0) {
- nautilus_view_call_set_selection (view, data->added_files);
- nautilus_view_reveal_selection (view);
- g_signal_handlers_disconnect_by_func (view,
- G_CALLBACK (debuting_files_add_file_callback),
- data);
- }
- }
-
- nautilus_profile_end (NULL);
-
- g_object_unref (location);
-}
-
-typedef struct {
- GList *added_files;
- NautilusView *directory_view;
-} CopyMoveDoneData;
-
-static void
-copy_move_done_data_free (CopyMoveDoneData *data)
-{
- g_assert (data != NULL);
-
- if (data->directory_view != NULL) {
- g_object_remove_weak_pointer (G_OBJECT (data->directory_view),
- (gpointer *) &data->directory_view);
- }
-
- nautilus_file_list_free (data->added_files);
- g_free (data);
-}
-
-static void
-pre_copy_move_add_file_callback (NautilusView *view,
- NautilusFile *new_file,
- NautilusDirectory *directory,
- CopyMoveDoneData *data)
-{
- nautilus_file_ref (new_file);
- data->added_files = g_list_prepend (data->added_files, new_file);
-}
-
-/* This needs to be called prior to nautilus_file_operations_copy_move.
- * It hooks up a signal handler to catch any icons that get added before
- * the copy_done_callback is invoked. The return value should be passed
- * as the data for uri_copy_move_done_callback.
- */
-static CopyMoveDoneData *
-pre_copy_move (NautilusView *directory_view)
-{
- CopyMoveDoneData *copy_move_done_data;
-
- copy_move_done_data = g_new0 (CopyMoveDoneData, 1);
- copy_move_done_data->directory_view = directory_view;
-
- g_object_add_weak_pointer (G_OBJECT (copy_move_done_data->directory_view),
- (gpointer *) &copy_move_done_data->directory_view);
-
- /* We need to run after the default handler adds the folder we want to
- * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
- * must use connect_after.
- */
- g_signal_connect (directory_view, "add-file",
- G_CALLBACK (pre_copy_move_add_file_callback), copy_move_done_data);
-
- return copy_move_done_data;
-}
-
-/* This function is used to pull out any debuting uris that were added
- * and (as a side effect) remove them from the debuting uri hash table.
- */
-static gboolean
-copy_move_done_partition_func (gpointer data, gpointer callback_data)
-{
- GFile *location;
- gboolean result;
-
- location = nautilus_file_get_location (NAUTILUS_FILE (data));
- result = g_hash_table_remove ((GHashTable *) callback_data, location);
- g_object_unref (location);
-
- return result;
-}
-
-static gboolean
-remove_not_really_moved_files (gpointer key,
- gpointer value,
- gpointer callback_data)
-{
- GList **added_files;
- GFile *loc;
-
- loc = key;
-
- if (GPOINTER_TO_INT (value)) {
- return FALSE;
- }
-
- added_files = callback_data;
- *added_files = g_list_prepend (*added_files,
- nautilus_file_get (loc));
- return TRUE;
-}
-
-/* When this function is invoked, the file operation is over, but all
- * the icons may not have been added to the directory view yet, so
- * we can't select them yet.
- *
- * We're passed a hash table of the uri's to look out for, we hook
- * up a signal handler to await their arrival.
- */
-static void
-copy_move_done_callback (GHashTable *debuting_files,
- gboolean success,
- gpointer data)
-{
- NautilusView *directory_view;
- CopyMoveDoneData *copy_move_done_data;
- DebutingFilesData *debuting_files_data;
-
- copy_move_done_data = (CopyMoveDoneData *) data;
- directory_view = copy_move_done_data->directory_view;
-
- if (directory_view != NULL) {
- g_assert (NAUTILUS_IS_VIEW (directory_view));
-
- debuting_files_data = g_new (DebutingFilesData, 1);
- debuting_files_data->debuting_files = g_hash_table_ref (debuting_files);
- debuting_files_data->added_files = eel_g_list_partition
- (copy_move_done_data->added_files,
- copy_move_done_partition_func,
- debuting_files,
- &copy_move_done_data->added_files);
-
- /* We're passed the same data used by pre_copy_move_add_file_callback, so disconnecting
- * it will free data. We've already siphoned off the added_files we need, and stashed the
- * directory_view pointer.
- */
- g_signal_handlers_disconnect_by_func (directory_view,
- G_CALLBACK (pre_copy_move_add_file_callback),
- data);
-
- /* Any items in the debuting_files hash table that have
- * "FALSE" as their value aren't really being copied
- * or moved, so we can't wait for an add_file signal
- * to come in for those.
- */
- g_hash_table_foreach_remove (debuting_files,
- remove_not_really_moved_files,
- &debuting_files_data->added_files);
-
- if (g_hash_table_size (debuting_files) == 0) {
- /* on the off-chance that all the icons have already been added */
- if (debuting_files_data->added_files != NULL) {
- nautilus_view_call_set_selection (directory_view,
- debuting_files_data->added_files);
- nautilus_view_reveal_selection (directory_view);
- }
- debuting_files_data_free (debuting_files_data);
- } else {
- /* We need to run after the default handler adds the folder we want to
- * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
- * must use connect_after.
- */
- g_signal_connect_data (directory_view,
- "add-file",
- G_CALLBACK (debuting_files_add_file_callback),
- debuting_files_data,
- (GClosureNotify) debuting_files_data_free,
- G_CONNECT_AFTER);
- }
- /* Schedule menu update for undo items */
- schedule_update_context_menus (directory_view);
- }
-
- copy_move_done_data_free (copy_move_done_data);
-}
-
-static gboolean
-view_file_still_belongs (NautilusView *view,
- NautilusFile *file,
- NautilusDirectory *directory)
-{
- if (view->details->model != directory &&
- g_list_find (view->details->subdirectory_list, directory) == NULL) {
- return FALSE;
- }
-
- return nautilus_directory_contains_file (directory, file);
-}
-
-static gboolean
-still_should_show_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
-{
- return nautilus_view_should_show_file (view, file) &&
- view_file_still_belongs (view, file, directory);
-}
-
-static gboolean
-ready_to_load (NautilusFile *file)
-{
- return nautilus_file_check_if_ready (file,
- NAUTILUS_FILE_ATTRIBUTES_FOR_ICON);
-}
-
-static int
-compare_files_cover (gconstpointer a, gconstpointer b, gpointer callback_data)
-{
- const FileAndDirectory *fad1, *fad2;
- NautilusView *view;
-
- view = callback_data;
- fad1 = a; fad2 = b;
-
- if (fad1->directory < fad2->directory) {
- return -1;
- } else if (fad1->directory > fad2->directory) {
- return 1;
- } else {
- return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->compare_files (view, fad1->file, fad2->file);
- }
-}
-static void
-sort_files (NautilusView *view, GList **list)
-{
- *list = g_list_sort_with_data (*list, compare_files_cover, view);
-
-}
-
-/* Go through all the new added and changed files.
- * Put any that are not ready to load in the non_ready_files hash table.
- * Add all the rest to the old_added_files and old_changed_files lists.
- * Sort the old_*_files lists if anything was added to them.
- */
-static void
-process_new_files (NautilusView *view)
-{
- GList *new_added_files, *new_changed_files, *old_added_files, *old_changed_files;
- GHashTable *non_ready_files;
- GList *node, *next;
- FileAndDirectory *pending;
- gboolean in_non_ready;
-
- new_added_files = view->details->new_added_files;
- view->details->new_added_files = NULL;
- new_changed_files = view->details->new_changed_files;
- view->details->new_changed_files = NULL;
-
- non_ready_files = view->details->non_ready_files;
-
- old_added_files = view->details->old_added_files;
- old_changed_files = view->details->old_changed_files;
-
- /* Newly added files go into the old_added_files list if they're
- * ready, and into the hash table if they're not.
- */
- for (node = new_added_files; node != NULL; node = next) {
- next = node->next;
- pending = (FileAndDirectory *)node->data;
- in_non_ready = g_hash_table_lookup (non_ready_files, pending) != NULL;
- if (nautilus_view_should_show_file (view, pending->file)) {
- if (ready_to_load (pending->file)) {
- if (in_non_ready) {
- g_hash_table_remove (non_ready_files, pending);
- }
- new_added_files = g_list_delete_link (new_added_files, node);
- old_added_files = g_list_prepend (old_added_files, pending);
- } else {
- if (!in_non_ready) {
- new_added_files = g_list_delete_link (new_added_files, node);
- g_hash_table_insert (non_ready_files, pending, pending);
- }
- }
- }
- }
- file_and_directory_list_free (new_added_files);
-
- /* Newly changed files go into the old_added_files list if they're ready
- * and were seen non-ready in the past, into the old_changed_files list
- * if they are read and were not seen non-ready in the past, and into
- * the hash table if they're not ready.
- */
- for (node = new_changed_files; node != NULL; node = next) {
- next = node->next;
- pending = (FileAndDirectory *)node->data;
- if (!still_should_show_file (view, pending->file, pending->directory) || ready_to_load (pending->file)) {
- if (g_hash_table_lookup (non_ready_files, pending) != NULL) {
- g_hash_table_remove (non_ready_files, pending);
- if (still_should_show_file (view, pending->file, pending->directory)) {
- new_changed_files = g_list_delete_link (new_changed_files, node);
- old_added_files = g_list_prepend (old_added_files, pending);
- }
- } else if (nautilus_view_should_show_file (view, pending->file)) {
- new_changed_files = g_list_delete_link (new_changed_files, node);
- old_changed_files = g_list_prepend (old_changed_files, pending);
- }
- }
- }
- file_and_directory_list_free (new_changed_files);
-
- /* If any files were added to old_added_files, then resort it. */
- if (old_added_files != view->details->old_added_files) {
- view->details->old_added_files = old_added_files;
- sort_files (view, &view->details->old_added_files);
- }
-
- /* Resort old_changed_files too, since file attributes
- * relevant to sorting could have changed.
- */
- if (old_changed_files != view->details->old_changed_files) {
- view->details->old_changed_files = old_changed_files;
- sort_files (view, &view->details->old_changed_files);
- }
-
-}
-
-static void
-process_old_files (NautilusView *view)
-{
- GList *files_added, *files_changed, *node;
- FileAndDirectory *pending;
- GList *selection, *files;
- gboolean send_selection_change;
-
- files_added = view->details->old_added_files;
- files_changed = view->details->old_changed_files;
-
- send_selection_change = FALSE;
-
- if (files_added != NULL || files_changed != NULL) {
- g_signal_emit (view, signals[BEGIN_FILE_CHANGES], 0);
-
- for (node = files_added; node != NULL; node = node->next) {
- pending = node->data;
- g_signal_emit (view,
- signals[ADD_FILE], 0, pending->file, pending->directory);
- }
-
- for (node = files_changed; node != NULL; node = node->next) {
- pending = node->data;
- g_signal_emit (view,
- signals[still_should_show_file (view, pending->file, pending->directory)
- ? FILE_CHANGED : REMOVE_FILE], 0,
- pending->file, pending->directory);
- }
-
- g_signal_emit (view, signals[END_FILE_CHANGES], 0);
- check_empty_states (view);
-
- if (files_changed != NULL) {
- selection = nautilus_view_get_selection (view);
- files = file_and_directory_list_to_files (files_changed);
- send_selection_change = eel_g_lists_sort_and_check_for_intersection
- (&files, &selection);
- nautilus_file_list_free (files);
- nautilus_file_list_free (selection);
- }
-
- file_and_directory_list_free (view->details->old_added_files);
- view->details->old_added_files = NULL;
-
- file_and_directory_list_free (view->details->old_changed_files);
- view->details->old_changed_files = NULL;
- }
-
- if (send_selection_change) {
- /* Send a selection change since some file names could
- * have changed.
- */
- nautilus_view_send_selection_change (view);
- }
-}
-
-static void
-display_pending_files (NautilusView *view)
-{
- process_new_files (view);
- process_old_files (view);
-
- if (view->details->model != NULL
- && nautilus_directory_are_all_files_seen (view->details->model)
- && g_hash_table_size (view->details->non_ready_files) == 0) {
- done_loading (view, TRUE);
- }
-}
-
-static gboolean
-display_selection_info_idle_callback (gpointer data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (data);
-
- g_object_ref (G_OBJECT (view));
-
- view->details->display_selection_idle_id = 0;
- nautilus_view_display_selection_info (view);
- nautilus_view_send_selection_change (view);
-
- g_object_unref (G_OBJECT (view));
-
- return FALSE;
-}
-
-static void
-remove_update_context_menus_timeout_callback (NautilusView *view)
-{
- if (view->details->update_context_menus_timeout_id != 0) {
- g_source_remove (view->details->update_context_menus_timeout_id);
- view->details->update_context_menus_timeout_id = 0;
- }
-}
-
-static void
-update_context_menus_if_pending (NautilusView *view)
-{
- remove_update_context_menus_timeout_callback (view);
-
- nautilus_view_update_context_menus(view);
-}
-
-static gboolean
-update_context_menus_timeout_callback (gpointer data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (data);
-
- g_object_ref (G_OBJECT (view));
-
- view->details->update_context_menus_timeout_id = 0;
- nautilus_view_update_context_menus(view);
-
- g_object_unref (G_OBJECT (view));
-
- return FALSE;
-}
-
-static gboolean
-display_pending_callback (gpointer data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (data);
-
- g_object_ref (G_OBJECT (view));
-
- view->details->display_pending_source_id = 0;
-
- display_pending_files (view);
-
- g_object_unref (G_OBJECT (view));
-
- return FALSE;
-}
-
-static void
-schedule_idle_display_of_pending_files (NautilusView *view)
-{
- /* Get rid of a pending source as it might be a timeout */
- unschedule_display_of_pending_files (view);
-
- /* We want higher priority than the idle that handles the relayout
- to avoid a resort on each add. But we still want to allow repaints
- and other hight prio events while we have pending files to show. */
- view->details->display_pending_source_id =
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE - 20,
- display_pending_callback, view, NULL);
-}
-
-static void
-schedule_timeout_display_of_pending_files (NautilusView *view, guint interval)
-{
- /* No need to schedule an update if there's already one pending. */
- if (view->details->display_pending_source_id != 0) {
- return;
- }
-
- view->details->display_pending_source_id =
- g_timeout_add (interval, display_pending_callback, view);
-}
-
-static void
-unschedule_display_of_pending_files (NautilusView *view)
-{
- /* Get rid of source if it's active. */
- if (view->details->display_pending_source_id != 0) {
- g_source_remove (view->details->display_pending_source_id);
- view->details->display_pending_source_id = 0;
- }
-}
-
-static void
-queue_pending_files (NautilusView *view,
- NautilusDirectory *directory,
- GList *files,
- GList **pending_list)
-{
- if (files == NULL) {
- return;
- }
-
- *pending_list = g_list_concat (file_and_directory_list_from_files (directory, files),
- *pending_list);
-
- if (! view->details->loading || nautilus_directory_are_all_files_seen (directory)) {
- schedule_timeout_display_of_pending_files (view, view->details->update_interval);
- }
-}
-
-static void
-remove_changes_timeout_callback (NautilusView *view)
-{
- if (view->details->changes_timeout_id != 0) {
- g_source_remove (view->details->changes_timeout_id);
- view->details->changes_timeout_id = 0;
- }
-}
-
-static void
-reset_update_interval (NautilusView *view)
-{
- view->details->update_interval = UPDATE_INTERVAL_MIN;
- remove_changes_timeout_callback (view);
- /* Reschedule a pending timeout to idle */
- if (view->details->display_pending_source_id != 0) {
- schedule_idle_display_of_pending_files (view);
- }
-}
-
-static gboolean
-changes_timeout_callback (gpointer data)
-{
- gint64 now;
- gint64 time_delta;
- gboolean ret;
- NautilusView *view;
-
- view = NAUTILUS_VIEW (data);
-
- g_object_ref (G_OBJECT (view));
-
- now = g_get_monotonic_time ();
- time_delta = now - view->details->last_queued;
-
- if (time_delta < UPDATE_INTERVAL_RESET*1000) {
- if (view->details->update_interval < UPDATE_INTERVAL_MAX &&
- view->details->loading) {
- /* Increase */
- view->details->update_interval += UPDATE_INTERVAL_INC;
- }
- ret = TRUE;
- } else {
- /* Reset */
- reset_update_interval (view);
- ret = FALSE;
- }
-
- g_object_unref (G_OBJECT (view));
-
- return ret;
-}
-
-static void
-schedule_changes (NautilusView *view)
-{
- /* Remember when the change was queued */
- view->details->last_queued = g_get_monotonic_time ();
-
- /* No need to schedule if there are already changes pending or during loading */
- if (view->details->changes_timeout_id != 0 ||
- view->details->loading) {
- return;
- }
-
- view->details->changes_timeout_id =
- g_timeout_add (UPDATE_INTERVAL_TIMEOUT_INTERVAL, changes_timeout_callback, view);
-}
-
-static void
-files_added_callback (NautilusDirectory *directory,
- GList *files,
- gpointer callback_data)
-{
- NautilusView *view;
- GtkWindow *window;
- char *uri;
-
- view = NAUTILUS_VIEW (callback_data);
-
- nautilus_profile_start (NULL);
-
- window = nautilus_view_get_containing_window (view);
- uri = nautilus_view_get_uri (view);
- DEBUG_FILES (files, "Files added in window %p: %s",
- window, uri ? uri : "(no directory)");
- g_free (uri);
-
- schedule_changes (view);
-
- queue_pending_files (view, directory, files, &view->details->new_added_files);
-
- /* The number of items could have changed */
- schedule_update_status (view);
-
- nautilus_profile_end (NULL);
-}
-
-static void
-files_changed_callback (NautilusDirectory *directory,
- GList *files,
- gpointer callback_data)
-{
- NautilusView *view;
- GtkWindow *window;
- char *uri;
-
- view = NAUTILUS_VIEW (callback_data);
-
- window = nautilus_view_get_containing_window (view);
- uri = nautilus_view_get_uri (view);
- DEBUG_FILES (files, "Files changed in window %p: %s",
- window, uri ? uri : "(no directory)");
- g_free (uri);
-
- schedule_changes (view);
-
- queue_pending_files (view, directory, files, &view->details->new_changed_files);
-
- /* The free space or the number of items could have changed */
- schedule_update_status (view);
-
- /* A change in MIME type could affect the Open with menu, for
- * one thing, so we need to update menus when files change.
- */
- schedule_update_context_menus (view);
-}
-
-static void
-done_loading_callback (NautilusDirectory *directory,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (callback_data);
-
- nautilus_profile_start (NULL);
- process_new_files (view);
- if (g_hash_table_size (view->details->non_ready_files) == 0) {
- /* Unschedule a pending update and schedule a new one with the minimal
- * update interval. This gives the view a short chance at gathering the
- * (cached) deep counts.
- */
- unschedule_display_of_pending_files (view);
- schedule_timeout_display_of_pending_files (view, UPDATE_INTERVAL_MIN);
-
- remove_loading_floating_bar (view);
- }
- nautilus_profile_end (NULL);
-}
-
-static void
-load_error_callback (NautilusDirectory *directory,
- GError *error,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (callback_data);
-
- /* FIXME: By doing a stop, we discard some pending files. Is
- * that OK?
- */
- nautilus_view_stop_loading (view);
-
- nautilus_report_error_loading_directory
- (nautilus_view_get_directory_as_file (view),
- error,
- nautilus_view_get_containing_window (view));
-}
-
-void
-nautilus_view_add_subdirectory (NautilusView *view,
- NautilusDirectory*directory)
-{
- NautilusFileAttributes attributes;
-
- g_assert (!g_list_find (view->details->subdirectory_list, directory));
-
- nautilus_directory_ref (directory);
-
- attributes =
- NAUTILUS_FILE_ATTRIBUTES_FOR_ICON |
- NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
- NAUTILUS_FILE_ATTRIBUTE_INFO |
- NAUTILUS_FILE_ATTRIBUTE_LINK_INFO |
- NAUTILUS_FILE_ATTRIBUTE_MOUNT |
- NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO;
-
- nautilus_directory_file_monitor_add (directory,
- &view->details->model,
- view->details->show_hidden_files,
- attributes,
- files_added_callback, view);
-
- g_signal_connect
- (directory, "files-added",
- G_CALLBACK (files_added_callback), view);
- g_signal_connect
- (directory, "files-changed",
- G_CALLBACK (files_changed_callback), view);
-
- view->details->subdirectory_list = g_list_prepend (
- view->details->subdirectory_list, directory);
-}
-
-void
-nautilus_view_remove_subdirectory (NautilusView *view,
- NautilusDirectory*directory)
-{
- g_assert (g_list_find (view->details->subdirectory_list, directory));
-
- view->details->subdirectory_list = g_list_remove (
- view->details->subdirectory_list, directory);
-
- g_signal_handlers_disconnect_by_func (directory,
- G_CALLBACK (files_added_callback),
- view);
- g_signal_handlers_disconnect_by_func (directory,
- G_CALLBACK (files_changed_callback),
- view);
-
- nautilus_directory_file_monitor_remove (directory, &view->details->model);
-
- nautilus_directory_unref (directory);
-}
-
-/**
- * nautilus_view_get_loading:
- * @view: an #NautilusView.
- *
- * Return value: #gboolean inicating whether @view is currently loaded.
- *
- **/
-gboolean
-nautilus_view_get_loading (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
-
- return view->details->loading;
-}
-
-/**
- * nautilus_view_get_model:
- *
- * Get the model for this NautilusView.
- * @view: NautilusView of interest.
- *
- * Return value: NautilusDirectory for this view.
- *
- **/
-NautilusDirectory *
-nautilus_view_get_model (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
-
- return view->details->model;
-}
-
-GtkWidget*
-nautilus_view_get_content_widget (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
-
- return view->details->scrolled_window;
-}
-
-GdkAtom
-nautilus_view_get_copied_files_atom (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), GDK_NONE);
-
- return copied_files_atom;
-}
-
-static void
-offset_drop_points (GArray *relative_item_points,
- int x_offset, int y_offset)
-{
- 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;
- }
-}
-
-/* special_link_in_selection
- *
- * Return TRUE if one of our special links is in the selection.
- * Special links include the following:
- * NAUTILUS_DESKTOP_LINK_TRASH, NAUTILUS_DESKTOP_LINK_HOME, NAUTILUS_DESKTOP_LINK_MOUNT
- */
-
-static gboolean
-special_link_in_selection (GList *selection)
-{
- gboolean saw_link;
- GList *node;
- NautilusFile *file;
-
- saw_link = FALSE;
-
- for (node = selection; node != NULL; node = node->next) {
- file = NAUTILUS_FILE (node->data);
-
- saw_link = NAUTILUS_IS_DESKTOP_ICON_FILE (file);
-
- if (saw_link) {
- break;
- }
- }
-
- return saw_link;
-}
-
-/* desktop_or_home_dir_in_selection
- *
- * Return TRUE if either the desktop or the home directory is in the selection.
- */
-
-static gboolean
-desktop_or_home_dir_in_selection (GList *selection)
-{
- gboolean saw_desktop_or_home_dir;
- GList *node;
- NautilusFile *file;
-
- saw_desktop_or_home_dir = FALSE;
-
- for (node = selection; node != NULL; node = node->next) {
- file = NAUTILUS_FILE (node->data);
-
- saw_desktop_or_home_dir =
- nautilus_file_is_home (file)
- || nautilus_file_is_desktop_directory (file);
-
- if (saw_desktop_or_home_dir) {
- break;
- }
- }
-
- return saw_desktop_or_home_dir;
-}
-
-static void
-trash_or_delete_done_cb (GHashTable *debuting_uris,
- gboolean user_cancel,
- NautilusView *view)
-{
- if (user_cancel) {
- view->details->selection_was_removed = FALSE;
- }
-}
-
-static void
-trash_or_delete_files (GtkWindow *parent_window,
- const GList *files,
- NautilusView *view)
-{
- GList *locations;
- const GList *node;
-
- locations = NULL;
- for (node = files; node != NULL; node = node->next) {
- locations = g_list_prepend (locations,
- nautilus_file_get_location ((NautilusFile *) node->data));
- }
-
- locations = g_list_reverse (locations);
-
- nautilus_file_operations_trash_or_delete (locations,
- parent_window,
- (NautilusDeleteCallback) trash_or_delete_done_cb,
- view);
- g_list_free_full (locations, g_object_unref);
-}
-
-static gboolean
-can_rename_file (NautilusView *view, NautilusFile *file)
-{
- return nautilus_file_can_rename (file);
-}
-
-static void
-open_one_in_new_window (gpointer data, gpointer callback_data)
-{
- g_assert (NAUTILUS_IS_FILE (data));
- g_assert (NAUTILUS_IS_VIEW (callback_data));
-
- nautilus_view_activate_file (NAUTILUS_VIEW (callback_data),
- NAUTILUS_FILE (data),
- NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
-}
-
-static void
-update_context_menu_position_from_event (NautilusView *view,
- GdkEventButton *event)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- if (event != NULL) {
- view->details->context_menu_position.x = event->x;
- view->details->context_menu_position.y = event->y;
- } else {
- view->details->context_menu_position.x = -1;
- view->details->context_menu_position.y = -1;
- }
-}
-
-NautilusFile *
-nautilus_view_get_directory_as_file (NautilusView *view)
-{
- g_assert (NAUTILUS_IS_VIEW (view));
-
- return view->details->directory_as_file;
-}
-
-static GdkPixbuf *
-get_menu_icon_for_file (NautilusFile *file,
- GtkWidget *widget)
-{
- NautilusIconInfo *info;
- GdkPixbuf *pixbuf;
- int size, scale;
-
- size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
- scale = gtk_widget_get_scale_factor (widget);
-
- info = nautilus_file_get_icon (file, size, scale, 0);
- pixbuf = nautilus_icon_info_get_pixbuf_nodefault_at_size (info, size);
- g_object_unref (info);
-
- return pixbuf;
-}
-
-static GList *
-get_extension_selection_menu_items (NautilusView *view)
-{
- NautilusWindow *window;
- GList *items;
- GList *providers;
- GList *l;
- GList *selection;
-
- window = nautilus_view_get_window (view);
- selection = nautilus_view_get_selection (view);
- providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
- items = NULL;
-
- for (l = providers; l != NULL; l = l->next) {
- NautilusMenuProvider *provider;
- GList *file_items;
-
- provider = NAUTILUS_MENU_PROVIDER (l->data);
- file_items = nautilus_menu_provider_get_file_items (provider,
- GTK_WIDGET (window),
- selection);
- items = g_list_concat (items, file_items);
- }
-
- nautilus_module_extension_list_free (providers);
-
- return items;
-}
-
-static GList *
-get_extension_background_menu_items (NautilusView *view)
-{
- NautilusWindow *window;
- NautilusFile *file;
- GList *items;
- GList *providers;
- GList *l;
-
- window = nautilus_view_get_window (view);
- providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
- file = nautilus_window_slot_get_file (view->details->slot);
- items = NULL;
-
- for (l = providers; l != NULL; l = l->next) {
- NautilusMenuProvider *provider;
- GList *file_items;
-
- provider = NAUTILUS_MENU_PROVIDER (l->data);
- file_items = nautilus_menu_provider_get_background_items (provider,
- GTK_WIDGET (window),
- file);
- items = g_list_concat (items, file_items);
- }
-
- nautilus_module_extension_list_free (providers);
-
- return items;
-}
-
-static void
-extension_action_callback (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusMenuItem *item = user_data;
- nautilus_menu_item_activate (item);
-}
-
-static void
-add_extension_action (NautilusView *view,
- NautilusMenuItem *item,
- const char *action_name)
-{
- gboolean sensitive;
- GSimpleAction *action;
-
- g_object_get (item,
- "sensitive", &sensitive,
- NULL);
-
- action = g_simple_action_new (action_name, NULL);
- g_signal_connect_data (action, "activate",
- G_CALLBACK (extension_action_callback),
- g_object_ref (item),
- (GClosureNotify) g_object_unref, 0);
-
- g_action_map_add_action (G_ACTION_MAP (view->details->view_action_group),
- G_ACTION (action));
- g_simple_action_set_enabled (action, sensitive);
-
- g_object_unref (action);
-}
-
-static GMenu *
-build_menu_for_extension_menu_items (NautilusView *view,
- const gchar *extension_prefix,
- GList *menu_items)
-{
- GList *l;
- GMenu *gmenu;
- gint idx = 0;
-
- gmenu = g_menu_new ();
-
- for (l = menu_items; l; l = l->next) {
- NautilusMenuItem *item;
- NautilusMenu *menu;
- GMenuItem *menu_item;
- char *name, *label;
- char *extension_id, *prefix, *parsed_name, *detailed_action_name;
-
- item = NAUTILUS_MENU_ITEM (l->data);
-
- g_object_get (item,
- "label", &label,
- "menu", &menu,
- "name", &name,
- NULL);
-
- extension_id = g_strdup_printf ("%s_%d", extension_prefix, idx);
- prefix = g_strdup_printf ("extension_%s_", extension_id);
- parsed_name = nautilus_escape_action_name (name, prefix);
- add_extension_action (view, item, parsed_name);
-
- detailed_action_name = g_strconcat ("view.", parsed_name, NULL);
- menu_item = g_menu_item_new (label, detailed_action_name);
-
- if (menu != NULL) {
- GList *children;
- GMenu *children_menu;
-
- children = nautilus_menu_get_items (menu);
- children_menu = build_menu_for_extension_menu_items (view, extension_id, children);
- g_menu_item_set_submenu (menu_item, G_MENU_MODEL (children_menu));
-
- nautilus_menu_item_list_free (children);
- g_object_unref (children_menu);
- }
-
- g_menu_append_item (gmenu, menu_item);
- idx++;
-
- g_free (extension_id);
- g_free (parsed_name);
- g_free (prefix);
- g_free (detailed_action_name);
- g_free (name);
- g_free (label);
- g_object_unref (menu_item);
- }
-
- return gmenu;
-}
-
-static void
-add_extension_menu_items (NautilusView *view,
- const gchar *extension_prefix,
- GList *menu_items,
- GMenu *insertion_menu)
-{
- GMenu *menu;
-
- menu = build_menu_for_extension_menu_items (view, extension_prefix, menu_items);
- nautilus_gmenu_merge (insertion_menu,
- menu,
- "extensions",
- FALSE);
-
- g_object_unref (menu);
-}
-
-static void
-update_extensions_menus (NautilusView *view)
-{
- GList *selection_items, *background_items;
-
- selection_items = get_extension_selection_menu_items (view);
- if (selection_items != NULL) {
- add_extension_menu_items (view,
- "selection",
- selection_items,
- view->details->selection_menu);
- nautilus_menu_item_list_free (selection_items);
- }
-
- background_items = get_extension_background_menu_items (view);
- if (background_items != NULL) {
- add_extension_menu_items (view,
- "background",
- background_items,
- view->details->background_menu);
- nautilus_menu_item_list_free (background_items);
- }
-}
-
-static char *
-change_to_view_directory (NautilusView *view)
-{
- char *path;
- char *old_path;
-
- old_path = g_get_current_dir ();
-
- path = get_view_directory (view);
-
- /* FIXME: What to do about non-local directories? */
- if (path != NULL) {
- g_chdir (path);
- }
-
- g_free (path);
-
- return old_path;
-}
-
-static char **
-get_file_names_as_parameter_array (GList *selection,
- NautilusDirectory *model)
-{
- NautilusFile *file;
- char **parameters;
- GList *node;
- GFile *file_location;
- GFile *model_location;
- int i;
-
- if (model == NULL) {
- return NULL;
- }
-
- parameters = g_new (char *, g_list_length (selection) + 1);
-
- model_location = nautilus_directory_get_location (model);
-
- for (node = selection, i = 0; node != NULL; node = node->next, i++) {
- file = NAUTILUS_FILE (node->data);
-
- if (!nautilus_file_is_local (file)) {
- parameters[i] = NULL;
- g_strfreev (parameters);
- return NULL;
- }
-
- file_location = nautilus_file_get_location (NAUTILUS_FILE (node->data));
- parameters[i] = g_file_get_relative_path (model_location, file_location);
- if (parameters[i] == NULL) {
- parameters[i] = g_file_get_path (file_location);
- }
- g_object_unref (file_location);
- }
-
- g_object_unref (model_location);
-
- parameters[i] = NULL;
- return parameters;
-}
-
-static char *
-get_file_paths_or_uris_as_newline_delimited_string (GList *selection, gboolean get_paths)
-{
- char *path;
- char *uri;
- char *result;
- NautilusDesktopLink *link;
- GString *expanding_string;
- GList *node;
- GFile *location;
-
- expanding_string = g_string_new ("");
- for (node = selection; node != NULL; node = node->next) {
- uri = NULL;
- if (NAUTILUS_IS_DESKTOP_ICON_FILE (node->data)) {
- link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (node->data));
- if (link != NULL) {
- location = nautilus_desktop_link_get_activation_location (link);
- uri = g_file_get_uri (location);
- g_object_unref (location);
- g_object_unref (G_OBJECT (link));
- }
- } else {
- uri = nautilus_file_get_uri (NAUTILUS_FILE (node->data));
- }
- if (uri == NULL) {
- continue;
- }
-
- if (get_paths) {
- path = g_filename_from_uri (uri, NULL, NULL);
- if (path != NULL) {
- g_string_append (expanding_string, path);
- g_free (path);
- g_string_append (expanding_string, "\n");
- }
- } else {
- g_string_append (expanding_string, uri);
- g_string_append (expanding_string, "\n");
- }
- g_free (uri);
- }
-
- result = expanding_string->str;
- g_string_free (expanding_string, FALSE);
-
- return result;
-}
-
-static char *
-get_file_paths_as_newline_delimited_string (GList *selection)
-{
- return get_file_paths_or_uris_as_newline_delimited_string (selection, TRUE);
-}
-
-static char *
-get_file_uris_as_newline_delimited_string (GList *selection)
-{
- return get_file_paths_or_uris_as_newline_delimited_string (selection, FALSE);
-}
-
-/* returns newly allocated strings for setting the environment variables */
-static void
-get_strings_for_environment_variables (NautilusView *view, GList *selected_files,
- char **file_paths, char **uris, char **uri)
-{
- char *directory_uri;
-
- /* We need to check that the directory uri starts with "file:" since
- * nautilus_directory_is_local returns FALSE for nfs.
- */
- directory_uri = nautilus_directory_get_uri (view->details->model);
- if (g_str_has_prefix (directory_uri, "file:") ||
- eel_uri_is_desktop (directory_uri) ||
- eel_uri_is_trash (directory_uri)) {
- *file_paths = get_file_paths_as_newline_delimited_string (selected_files);
- } else {
- *file_paths = g_strdup ("");
- }
- g_free (directory_uri);
-
- *uris = get_file_uris_as_newline_delimited_string (selected_files);
-
- *uri = nautilus_directory_get_uri (view->details->model);
- if (eel_uri_is_desktop (*uri)) {
- g_free (*uri);
- *uri = nautilus_get_desktop_directory_uri ();
- }
-}
-
-/*
- * Set up some environment variables that scripts can use
- * to take advantage of the current Nautilus state.
- */
-static void
-set_script_environment_variables (NautilusView *view, GList *selected_files)
-{
- char *file_paths;
- char *uris;
- char *uri;
- char *geometry_string;
-
- get_strings_for_environment_variables (view, selected_files,
- &file_paths, &uris, &uri);
-
- g_setenv ("NAUTILUS_SCRIPT_SELECTED_FILE_PATHS", file_paths, TRUE);
- g_free (file_paths);
-
- g_setenv ("NAUTILUS_SCRIPT_SELECTED_URIS", uris, TRUE);
- g_free (uris);
-
- g_setenv ("NAUTILUS_SCRIPT_CURRENT_URI", uri, TRUE);
- g_free (uri);
-
- geometry_string = eel_gtk_window_get_geometry_string
- (GTK_WINDOW (nautilus_view_get_containing_window (view)));
- g_setenv ("NAUTILUS_SCRIPT_WINDOW_GEOMETRY", geometry_string, TRUE);
- g_free (geometry_string);
-}
-
-/* Unset all the special script environment variables. */
-static void
-unset_script_environment_variables (void)
-{
- g_unsetenv ("NAUTILUS_SCRIPT_SELECTED_FILE_PATHS");
- g_unsetenv ("NAUTILUS_SCRIPT_SELECTED_URIS");
- g_unsetenv ("NAUTILUS_SCRIPT_CURRENT_URI");
- g_unsetenv ("NAUTILUS_SCRIPT_WINDOW_GEOMETRY");
-}
-
-static void
-run_script (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- ScriptLaunchParameters *launch_parameters;
- GdkScreen *screen;
- GList *selected_files;
- char *file_uri;
- char *local_file_path;
- char *quoted_path;
- char *old_working_dir;
- char **parameters;
-
- launch_parameters = (ScriptLaunchParameters *) user_data;
-
- file_uri = nautilus_file_get_uri (launch_parameters->file);
- local_file_path = g_filename_from_uri (file_uri, NULL, NULL);
- g_assert (local_file_path != NULL);
- g_free (file_uri);
-
- quoted_path = g_shell_quote (local_file_path);
- g_free (local_file_path);
-
- old_working_dir = change_to_view_directory (launch_parameters->directory_view);
-
- selected_files = nautilus_view_get_selection (launch_parameters->directory_view);
- set_script_environment_variables (launch_parameters->directory_view, selected_files);
-
- parameters = get_file_names_as_parameter_array (selected_files,
- launch_parameters->directory_view->details->model);
-
- screen = gtk_widget_get_screen (GTK_WIDGET (launch_parameters->directory_view));
-
- DEBUG ("run_script, script_path=“%s” (omitting script parameters)",
- local_file_path);
-
- nautilus_launch_application_from_command_array (screen, quoted_path, FALSE,
- (const char * const *) parameters);
- g_strfreev (parameters);
-
- nautilus_file_list_free (selected_files);
- unset_script_environment_variables ();
- g_chdir (old_working_dir);
- g_free (old_working_dir);
- g_free (quoted_path);
-}
-
-static void
-add_script_to_scripts_menus (NautilusView *view,
- NautilusFile *file,
- GMenu *menu)
-{
- gchar *name;
- GdkPixbuf *mimetype_icon;
- gchar *action_name, *detailed_action_name;
- ScriptLaunchParameters *launch_parameters;
- GAction *action;
- GMenuItem *menu_item;
-
- launch_parameters = script_launch_parameters_new (file, view);
-
- name = nautilus_file_get_display_name (file);
- action_name = nautilus_escape_action_name (name, "script_");
-
- action = G_ACTION (g_simple_action_new (action_name, NULL));
-
- g_signal_connect_data (action, "activate",
- G_CALLBACK (run_script),
- launch_parameters,
- (GClosureNotify)script_launch_parameters_free, 0);
-
- g_action_map_add_action (G_ACTION_MAP (view->details->view_action_group), action);
-
- g_object_unref (action);
-
- detailed_action_name = g_strconcat ("view.", action_name, NULL);
- menu_item = g_menu_item_new (name, detailed_action_name);
-
- mimetype_icon = get_menu_icon_for_file (file, GTK_WIDGET (view));
- if (mimetype_icon != NULL) {
- g_menu_item_set_icon (menu_item, G_ICON (mimetype_icon));
- g_object_unref (mimetype_icon);
- }
-
- g_menu_append_item (menu, menu_item);
-
- g_free (name);
- g_free (action_name);
- g_free (detailed_action_name);
- g_object_unref (menu_item);
-}
-
-static gboolean
-directory_belongs_in_scripts_menu (const char *uri)
-{
- int num_levels;
- int i;
-
- if (!g_str_has_prefix (uri, scripts_directory_uri)) {
- return FALSE;
- }
-
- num_levels = 0;
- for (i = scripts_directory_uri_length; uri[i] != '\0'; i++) {
- if (uri[i] == '/') {
- num_levels++;
- }
- }
-
- if (num_levels > MAX_MENU_LEVELS) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-static GMenu *
-update_directory_in_scripts_menu (NautilusView *view,
- NautilusDirectory *directory)
-{
- GList *file_list, *filtered, *node;
- GMenu *menu, *children_menu;
- GMenuItem *menu_item;
- gboolean any_scripts;
- NautilusFile *file;
- NautilusDirectory *dir;
- char *uri;
- gchar *file_name;
- int num;
-
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
- g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
-
- file_list = nautilus_directory_get_file_list (directory);
- filtered = nautilus_file_list_filter_hidden (file_list, FALSE);
- nautilus_file_list_free (file_list);
- menu = g_menu_new ();
-
- file_list = nautilus_file_list_sort_by_display_name (filtered);
-
- num = 0;
- any_scripts = FALSE;
- for (node = file_list; num < TEMPLATE_LIMIT && node != NULL; node = node->next, num++) {
- file = node->data;
- if (nautilus_file_is_directory (file)) {
- uri = nautilus_file_get_uri (file);
- if (directory_belongs_in_scripts_menu (uri)) {
- dir = nautilus_directory_get_by_uri (uri);
- add_directory_to_scripts_directory_list (view, dir);
-
- children_menu = update_directory_in_scripts_menu (view, dir);
-
- if (children_menu != NULL) {
- file_name = nautilus_file_get_display_name (file);
- menu_item = g_menu_item_new_submenu (file_name,
- G_MENU_MODEL (children_menu));
- g_menu_append_item (menu, menu_item);
- any_scripts = TRUE;
- g_object_unref (menu_item);
- g_object_unref (children_menu);
- g_free (file_name);
- }
-
- nautilus_directory_unref (dir);
- }
- g_free (uri);
- } else if (nautilus_file_is_launchable (file)) {
- add_script_to_scripts_menus (view, file, menu);
- any_scripts = TRUE;
- }
- }
-
- nautilus_file_list_free (file_list);
-
- if (!any_scripts) {
- g_object_unref (menu);
- menu = NULL;
- }
-
- return menu;
-}
-
-
-
-static void
-update_scripts_menu (NautilusView *view)
-{
- GList *sorted_copy, *node;
- NautilusDirectory *directory;
- GMenu *submenu;
- char *uri;
-
- sorted_copy = nautilus_directory_list_sort_by_uri
- (nautilus_directory_list_copy (view->details->scripts_directory_list));
-
- for (node = sorted_copy; node != NULL; node = node->next) {
- directory = node->data;
-
- uri = nautilus_directory_get_uri (directory);
- if (!directory_belongs_in_scripts_menu (uri)) {
- remove_directory_from_scripts_directory_list (view, directory);
- }
- g_free (uri);
- }
- nautilus_directory_list_free (sorted_copy);
-
- directory = nautilus_directory_get_by_uri (scripts_directory_uri);
- submenu = update_directory_in_scripts_menu (view, directory);
- if (submenu != NULL) {
- nautilus_gmenu_merge (view->details->selection_menu,
- submenu,
- "scripts-submenu",
- TRUE);
- g_object_unref (submenu);
- }
-
- view->details->scripts_present = submenu != NULL;
-}
-
-static void
-create_template (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
-
- CreateTemplateParameters *parameters;
-
- parameters = user_data;
-
- nautilus_view_new_file (parameters->directory_view, NULL, parameters->file);
-}
-
-static void
-add_template_to_templates_menus (NautilusView *view,
- NautilusFile *file,
- GMenu *menu)
-{
- char *tmp, *uri, *name;
- GdkPixbuf *mimetype_icon;
- char *action_name, *detailed_action_name;
- CreateTemplateParameters *parameters;
- GAction *action;
- GMenuItem *menu_item;
-
- tmp = nautilus_file_get_display_name (file);
- name = eel_filename_strip_extension (tmp);
- g_free (tmp);
-
- uri = nautilus_file_get_uri (file);
- action_name = nautilus_escape_action_name (uri, "template_");
- action = G_ACTION (g_simple_action_new (action_name, NULL));
- parameters = create_template_parameters_new (file, view);
-
- g_signal_connect_data (action, "activate",
- G_CALLBACK (create_template),
- parameters,
- (GClosureNotify)create_templates_parameters_free, 0);
-
- g_action_map_add_action (G_ACTION_MAP (view->details->view_action_group), action);
-
- detailed_action_name = g_strconcat ("view.", action_name, NULL);
- menu_item = g_menu_item_new (name, detailed_action_name);
-
- mimetype_icon = get_menu_icon_for_file (file, GTK_WIDGET (view));
- if (mimetype_icon != NULL) {
- g_menu_item_set_icon (menu_item, G_ICON (mimetype_icon));
- g_object_unref (mimetype_icon);
- }
-
- g_menu_append_item (menu, menu_item);
-
- g_free (name);
- g_free (uri);
- g_free (action_name);
- g_free (detailed_action_name);
- g_object_unref (action);
- g_object_unref (menu_item);
-}
-
-static void
-update_templates_directory (NautilusView *view)
-{
- NautilusDirectory *templates_directory;
- GList *node, *next;
- char *templates_uri;
-
- for (node = view->details->templates_directory_list; node != NULL; node = next) {
- next = node->next;
- remove_directory_from_templates_directory_list (view, node->data);
- }
-
- if (nautilus_should_use_templates_directory ()) {
- templates_uri = nautilus_get_templates_directory_uri ();
- templates_directory = nautilus_directory_get_by_uri (templates_uri);
- g_free (templates_uri);
- add_directory_to_templates_directory_list (view, templates_directory);
- nautilus_directory_unref (templates_directory);
- }
-}
-
-static gboolean
-directory_belongs_in_templates_menu (const char *templates_directory_uri,
- const char *uri)
-{
- int num_levels;
- int i;
-
- if (templates_directory_uri == NULL) {
- return FALSE;
- }
-
- if (!g_str_has_prefix (uri, templates_directory_uri)) {
- return FALSE;
- }
-
- num_levels = 0;
- for (i = strlen (templates_directory_uri); uri[i] != '\0'; i++) {
- if (uri[i] == '/') {
- num_levels++;
- }
- }
-
- if (num_levels > MAX_MENU_LEVELS) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-static GMenu *
-update_directory_in_templates_menu (NautilusView *view,
- NautilusDirectory *directory)
-{
- GList *file_list, *filtered, *node;
- GMenu *menu, *children_menu;
- GMenuItem *menu_item;
- gboolean any_templates;
- NautilusFile *file;
- NautilusDirectory *dir;
- char *uri;
- char *templates_directory_uri;
- int num;
-
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
- g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
-
- file_list = nautilus_directory_get_file_list (directory);
- filtered = nautilus_file_list_filter_hidden (file_list, FALSE);
- nautilus_file_list_free (file_list);
- templates_directory_uri = nautilus_get_templates_directory_uri ();
- menu = g_menu_new ();
-
- file_list = nautilus_file_list_sort_by_display_name (filtered);
-
- num = 0;
- any_templates = FALSE;
- for (node = file_list; num < TEMPLATE_LIMIT && node != NULL; node = node->next, num++) {
- file = node->data;
- if (nautilus_file_is_directory (file)) {
- uri = nautilus_file_get_uri (file);
- if (directory_belongs_in_templates_menu (templates_directory_uri, uri)) {
- dir = nautilus_directory_get_by_uri (uri);
- add_directory_to_templates_directory_list (view, dir);
-
- children_menu = update_directory_in_templates_menu (view, dir);
-
- if (children_menu != NULL) {
- menu_item = g_menu_item_new_submenu (nautilus_file_get_display_name (file),
- G_MENU_MODEL (children_menu));
- g_menu_append_item (menu, menu_item);
- any_templates = TRUE;
- g_object_unref (menu_item);
- g_object_unref (children_menu);
- }
-
- nautilus_directory_unref (dir);
- }
- g_free (uri);
- } else if (nautilus_file_can_read (file)) {
- add_template_to_templates_menus (view, file, menu);
- any_templates = TRUE;
- }
- }
-
- nautilus_file_list_free (file_list);
- g_free (templates_directory_uri);
-
- if (!any_templates) {
- g_object_unref (menu);
- menu = NULL;
- }
-
- return menu;
-}
-
-
-
-static void
-update_templates_menu (NautilusView *view)
-{
- GList *sorted_copy, *node;
- NautilusDirectory *directory;
- GMenu *submenu;
- char *uri;
- char *templates_directory_uri;
-
- if (nautilus_should_use_templates_directory ()) {
- templates_directory_uri = nautilus_get_templates_directory_uri ();
- } else {
- view->details->templates_present = FALSE;
- return;
- }
-
-
- sorted_copy = nautilus_directory_list_sort_by_uri
- (nautilus_directory_list_copy (view->details->templates_directory_list));
-
- for (node = sorted_copy; node != NULL; node = node->next) {
- directory = node->data;
-
- uri = nautilus_directory_get_uri (directory);
- if (!directory_belongs_in_templates_menu (templates_directory_uri, uri)) {
- remove_directory_from_templates_directory_list (view, directory);
- }
- g_free (uri);
- }
- nautilus_directory_list_free (sorted_copy);
-
- directory = nautilus_directory_get_by_uri (templates_directory_uri);
- submenu = update_directory_in_templates_menu (view, directory);
- if (submenu != NULL) {
- nautilus_gmenu_merge (view->details->background_menu,
- submenu,
- "templates-submenu",
- FALSE);
- g_object_unref (submenu);
- }
-
- view->details->templates_present = submenu != NULL;
-
- g_free (templates_directory_uri);
-}
-
-
-static void
-action_open_scripts_folder (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
- static GFile *location = NULL;
-
- if (location == NULL) {
- location = g_file_new_for_uri (scripts_directory_uri);
- }
-
- view = NAUTILUS_VIEW (user_data);
- nautilus_window_slot_open_location (view->details->slot, location, 0);
-}
-
-typedef struct _CopyCallbackData {
- NautilusView *view;
- GtkFileChooser *chooser;
- GHashTable *locations;
- GList *selection;
- gboolean is_move;
-} CopyCallbackData;
-
-static void
-add_bookmark_for_uri (CopyCallbackData *data,
- const char *uri)
-{
- GError *error = NULL;
- int count;
-
- count = GPOINTER_TO_INT (g_hash_table_lookup (data->locations, uri));
- if (count == 0) {
- gtk_file_chooser_add_shortcut_folder_uri (data->chooser,
- uri,
- &error);
- if (error != NULL) {
- DEBUG ("Unable to add location '%s' to file selector: %s", uri, error->message);
- g_clear_error (&error);
- }
- }
- g_hash_table_replace (data->locations, g_strdup (uri), GINT_TO_POINTER (count + 1));
-}
-
-static void
-remove_bookmark_for_uri (CopyCallbackData *data,
- const char *uri)
-{
- GError *error = NULL;
- int count;
-
- count = GPOINTER_TO_INT (g_hash_table_lookup (data->locations, uri));
- if (count == 1) {
- gtk_file_chooser_remove_shortcut_folder_uri (data->chooser,
- uri,
- &error);
- if (error != NULL) {
- DEBUG ("Unable to remove location '%s' to file selector: %s", uri, error->message);
- g_clear_error (&error);
- }
- g_hash_table_remove (data->locations, uri);
- } else {
- g_hash_table_replace (data->locations, g_strdup (uri), GINT_TO_POINTER (count - 1));
- }
-}
-
-static void
-add_bookmarks_for_window_slot (CopyCallbackData *data,
- NautilusWindowSlot *slot)
-{
- char *uri;
-
- uri = nautilus_window_slot_get_location_uri (slot);
- if (uri != NULL) {
- add_bookmark_for_uri (data, uri);
- }
- g_free (uri);
-}
-
-static void
-remove_bookmarks_for_window_slot (CopyCallbackData *data,
- NautilusWindowSlot *slot)
-{
- char *uri;
-
- uri = nautilus_window_slot_get_location_uri (slot);
- if (uri != NULL) {
- remove_bookmark_for_uri (data, uri);
- }
- g_free (uri);
-}
-
-static void
-on_slot_location_changed (NautilusWindowSlot *slot,
- const char *from,
- const char *to,
- CopyCallbackData *data)
-{
- if (from != NULL) {
- remove_bookmark_for_uri (data, from);
- }
-
- if (to != NULL) {
- add_bookmark_for_uri (data, to);
- }
-}
-
-static void
-on_slot_added (NautilusWindow *window,
- NautilusWindowSlot *slot,
- CopyCallbackData *data)
-{
- add_bookmarks_for_window_slot (data, slot);
- g_signal_connect (slot, "location-changed", G_CALLBACK (on_slot_location_changed), data);
-}
-
-static void
-on_slot_removed (NautilusWindow *window,
- NautilusWindowSlot *slot,
- CopyCallbackData *data)
-{
- remove_bookmarks_for_window_slot (data, slot);
- g_signal_handlers_disconnect_by_func (slot,
- G_CALLBACK (on_slot_location_changed),
- data);
-}
-
-static void
-add_bookmarks_for_window (CopyCallbackData *data,
- NautilusWindow *window)
-{
- GList *s;
- GList *slots;
-
- slots = nautilus_window_get_slots (window);
- for (s = slots; s != NULL; s = s->next) {
- NautilusWindowSlot *slot = s->data;
- add_bookmarks_for_window_slot (data, slot);
- g_signal_connect (slot, "location-changed", G_CALLBACK (on_slot_location_changed), data);
- }
- g_signal_connect (window, "slot-added", G_CALLBACK (on_slot_added), data);
- g_signal_connect (window, "slot-removed", G_CALLBACK (on_slot_removed), data);
-}
-
-static void
-remove_bookmarks_for_window (CopyCallbackData *data,
- NautilusWindow *window)
-{
- GList *s;
- GList *slots;
-
- slots = nautilus_window_get_slots (window);
- for (s = slots; s != NULL; s = s->next) {
- NautilusWindowSlot *slot = s->data;
- remove_bookmarks_for_window_slot (data, slot);
- g_signal_handlers_disconnect_by_func (slot,
- G_CALLBACK (on_slot_location_changed),
- data);
- }
- g_signal_handlers_disconnect_by_func (window,
- G_CALLBACK (on_slot_added),
- data);
- g_signal_handlers_disconnect_by_func (window,
- G_CALLBACK (on_slot_removed),
- data);
-}
-
-static void
-on_app_window_added (GtkApplication *application,
- GtkWindow *window,
- CopyCallbackData *data)
-{
- add_bookmarks_for_window (data, NAUTILUS_WINDOW (window));
-}
-
-static void
-on_app_window_removed (GtkApplication *application,
- GtkWindow *window,
- CopyCallbackData *data)
-{
- remove_bookmarks_for_window (data, NAUTILUS_WINDOW (window));
-}
-
-static void
-copy_data_free (CopyCallbackData *data)
-{
- NautilusApplication *application;
- GList *windows;
- GList *w;
-
- application = NAUTILUS_APPLICATION (g_application_get_default ());
- g_signal_handlers_disconnect_by_func (application,
- G_CALLBACK (on_app_window_added),
- data);
- g_signal_handlers_disconnect_by_func (application,
- G_CALLBACK (on_app_window_removed),
- data);
-
- windows = nautilus_application_get_windows (application);
- for (w = windows; w != NULL; w = w->next) {
- NautilusWindow *window = w->data;
- GList *slots;
- GList *s;
-
- slots = nautilus_window_get_slots (window);
- for (s = slots; s != NULL; s = s->next) {
- NautilusWindowSlot *slot = s->data;
- g_signal_handlers_disconnect_by_func (slot, G_CALLBACK (on_slot_location_changed), data);
- }
- g_signal_handlers_disconnect_by_func (window, G_CALLBACK (on_slot_added), data);
- g_signal_handlers_disconnect_by_func (window, G_CALLBACK (on_slot_removed), data);
- }
-
- nautilus_file_list_free (data->selection);
- g_hash_table_destroy (data->locations);
- g_free (data);
-}
-
-static gboolean
-uri_is_parent_of_selection (GList *selection,
- const char *uri)
-{
- gboolean found;
- GList *l;
- GFile *file;
-
- found = FALSE;
-
- file = g_file_new_for_uri (uri);
- for (l = selection; !found && l != NULL; l = l->next) {
- GFile *parent;
- parent = nautilus_file_get_parent_location (l->data);
- found = g_file_equal (file, parent);
- g_object_unref (parent);
- }
- g_object_unref (file);
- return found;
-}
-
-static void
-on_destination_dialog_folder_changed (GtkFileChooser *chooser,
- gpointer user_data)
-{
- CopyCallbackData *copy_data = user_data;
- char *uri;
- gboolean found;
-
- uri = gtk_file_chooser_get_current_folder_uri (chooser);
- found = uri_is_parent_of_selection (copy_data->selection, uri);
- gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser), GTK_RESPONSE_OK, !found);
- g_free (uri);
-}
-
-static void
-on_destination_dialog_response (GtkDialog *dialog,
- gint response_id,
- gpointer user_data)
-{
- CopyCallbackData *copy_data = user_data;
-
- if (response_id == GTK_RESPONSE_OK) {
- char *target_uri;
- GList *uris, *l;
-
- target_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
-
- uris = NULL;
- for (l = copy_data->selection; l != NULL; l = l->next) {
- uris = g_list_prepend (uris,
- nautilus_file_get_uri ((NautilusFile *) l->data));
- }
- uris = g_list_reverse (uris);
-
- nautilus_view_move_copy_items (copy_data->view, uris, NULL, target_uri,
- copy_data->is_move ? GDK_ACTION_MOVE : GDK_ACTION_COPY,
- 0, 0);
-
- g_list_free_full (uris, g_free);
- g_free (target_uri);
- }
-
- copy_data_free (copy_data);
- gtk_widget_destroy (GTK_WIDGET (dialog));
-}
-
-static gboolean
-destination_dialog_filter_cb (const GtkFileFilterInfo *filter_info,
- gpointer user_data)
-{
- GList *selection = user_data;
- GList *l;
-
- for (l = selection; l != NULL; l = l->next) {
- char *uri;
- uri = nautilus_file_get_uri (l->data);
- if (strcmp (uri, filter_info->uri) == 0) {
- g_free (uri);
- return FALSE;
- }
- g_free (uri);
- }
-
- return TRUE;
-}
-
-static GList *
-get_selected_folders (GList *selection)
-{
- GList *folders;
- GList *l;
-
- folders = NULL;
- for (l = selection; l != NULL; l = l->next) {
- if (nautilus_file_is_directory (l->data))
- folders = g_list_prepend (folders, nautilus_file_ref (l->data));
- }
- return g_list_reverse (folders);
-}
-
-static void
-add_window_location_bookmarks (CopyCallbackData *data)
-{
- NautilusApplication *application;
- GList *windows;
- GList *w;
-
- application = NAUTILUS_APPLICATION (g_application_get_default ());
- windows = nautilus_application_get_windows (application);
- g_signal_connect (application, "window-added", G_CALLBACK (on_app_window_added), data);
- g_signal_connect (application, "window-removed", G_CALLBACK (on_app_window_removed), data);
-
- for (w = windows; w != NULL; w = w->next) {
- NautilusWindow *window = w->data;
- add_bookmarks_for_window (data, window);
- }
-}
-
-static void
-copy_or_move_selection (NautilusView *view,
- gboolean is_move)
-{
- GtkWidget *dialog;
- char *uri;
- CopyCallbackData *copy_data;
- GList *selection;
- const gchar *title;
-
- if (is_move) {
- title = _("Select Move Destination");
- } else {
- title = _("Select Copy Destination");
- }
-
- selection = nautilus_view_get_selection_for_file_transfer (view);
-
- dialog = gtk_file_chooser_dialog_new (title,
- GTK_WINDOW (nautilus_view_get_window (view)),
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
- _("_Cancel"), GTK_RESPONSE_CANCEL,
- _("_Select"), GTK_RESPONSE_OK,
- NULL);
- gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-
- copy_data = g_new0 (CopyCallbackData, 1);
- copy_data->view = view;
- copy_data->selection = selection;
- copy_data->is_move = is_move;
- copy_data->chooser = GTK_FILE_CHOOSER (dialog);
- copy_data->locations = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
- add_window_location_bookmarks (copy_data);
-
- if (selection != NULL) {
- GtkFileFilter *filter;
- GList *folders;
-
- folders = get_selected_folders (selection);
-
- filter = gtk_file_filter_new ();
- gtk_file_filter_add_custom (filter,
- GTK_FILE_FILTER_URI,
- destination_dialog_filter_cb,
- folders,
- (GDestroyNotify)nautilus_file_list_free);
- gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
- }
-
- uri = nautilus_directory_get_uri (view->details->model);
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), uri);
- g_free (uri);
- g_signal_connect (dialog, "current-folder-changed",
- G_CALLBACK (on_destination_dialog_folder_changed),
- copy_data);
- g_signal_connect (dialog, "response",
- G_CALLBACK (on_destination_dialog_response),
- copy_data);
-
- gtk_widget_show_all (dialog);
-}
-
-static void
-copy_or_cut_files (NautilusView *view,
- GList *clipboard_contents,
- gboolean cut)
-{
- NautilusClipboardInfo info;
- GtkTargetList *target_list;
- GtkTargetEntry *targets;
- int n_targets;
-
- info.files = clipboard_contents;
- info.cut = cut;
-
- target_list = gtk_target_list_new (NULL, 0);
- gtk_target_list_add (target_list, copied_files_atom, 0, 0);
- gtk_target_list_add_uri_targets (target_list, 0);
- gtk_target_list_add_text_targets (target_list, 0);
-
- targets = gtk_target_table_new_from_list (target_list, &n_targets);
- gtk_target_list_unref (target_list);
-
- gtk_clipboard_set_with_data (nautilus_clipboard_get (GTK_WIDGET (view)),
- targets, n_targets,
- nautilus_get_clipboard_callback, nautilus_clear_clipboard_callback,
- NULL);
- gtk_target_table_free (targets, n_targets);
-
- nautilus_clipboard_monitor_set_clipboard_info (nautilus_clipboard_monitor_get (), &info);
-}
-
-static void
-action_copy (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
- GList *selection;
-
- view = NAUTILUS_VIEW (user_data);
-
- selection = nautilus_view_get_selection_for_file_transfer (view);
- copy_or_cut_files (view, selection, FALSE);
- nautilus_file_list_free (selection);
-}
-
-static void
-action_cut (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
- GList *selection;
-
- view = NAUTILUS_VIEW (user_data);
-
- selection = nautilus_view_get_selection_for_file_transfer (view);
- copy_or_cut_files (view, selection, TRUE);
- nautilus_file_list_free (selection);
-}
-
-static void
-action_copy_to (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (user_data);
- copy_or_move_selection (view, FALSE);
-}
-
-static void
-action_move_to (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (user_data);
- copy_or_move_selection (view, TRUE);
-}
-
-typedef struct {
- NautilusView *view;
- NautilusFile *target;
-} PasteIntoData;
-
-static void
-paste_into_clipboard_received_callback (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- gpointer callback_data)
-{
- PasteIntoData *data;
- NautilusView *view;
- char *directory_uri;
-
- data = (PasteIntoData *) callback_data;
-
- view = NAUTILUS_VIEW (data->view);
-
- if (view->details->slot != NULL) {
- directory_uri = nautilus_file_get_activation_uri (data->target);
-
- paste_clipboard_data (view, selection_data, directory_uri);
-
- g_free (directory_uri);
- }
-
- g_object_unref (view);
- nautilus_file_unref (data->target);
- g_free (data);
-}
-
-static void
-paste_into (NautilusView *view,
- NautilusFile *target)
-{
- PasteIntoData *data;
-
- g_assert (NAUTILUS_IS_VIEW (view));
- g_assert (NAUTILUS_IS_FILE (target));
-
- data = g_new (PasteIntoData, 1);
-
- data->view = g_object_ref (view);
- data->target = nautilus_file_ref (target);
-
- gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
- copied_files_atom,
- paste_into_clipboard_received_callback,
- data);
-}
-
-static void
-action_paste_files_into (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusView *view;
- GList *selection;
-
- view = NAUTILUS_VIEW (user_data);
- selection = nautilus_view_get_selection (view);
- if (selection != NULL) {
- paste_into (view, NAUTILUS_FILE (selection->data));
- nautilus_file_list_free (selection);
- }
-
-}
-
-static void
-invoke_external_bulk_rename_utility (NautilusView *view,
- GList *selection)
-{
- GString *cmd;
- char *parameter;
- char *quoted_parameter;
- char *bulk_rename_tool;
- GList *walk;
- NautilusFile *file;
-
- /* assemble command line */
- bulk_rename_tool = get_bulk_rename_tool ();
- cmd = g_string_new (bulk_rename_tool);
- g_free (bulk_rename_tool);
- for (walk = selection; walk; walk = walk->next) {
- file = walk->data;
- parameter = nautilus_file_get_uri (file);
- quoted_parameter = g_shell_quote (parameter);
- g_free (parameter);
- cmd = g_string_append (cmd, " ");
- cmd = g_string_append (cmd, quoted_parameter);
- g_free (quoted_parameter);
- }
-
- /* spawning and error handling */
- nautilus_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (view)),
- cmd->str, FALSE, NULL);
- g_string_free (cmd, TRUE);
-}
-
-static void
-real_action_rename (NautilusView *view,
- gboolean select_all)
-{
- NautilusFile *file;
- GList *selection;
-
- g_assert (NAUTILUS_IS_VIEW (view));
-
- selection = nautilus_view_get_selection (view);
-
- if (selection_not_empty_in_menu_callback (view, selection)) {
- /* If there is more than one file selected, invoke a batch renamer */
- if (selection->next != NULL) {
- if (have_bulk_rename_tool ()) {
- invoke_external_bulk_rename_utility (view, selection);
- }
- } else {
- file = NAUTILUS_FILE (selection->data);
- if (!select_all) {
- /* directories don't have a file extension, so
- * they are always pre-selected as a whole */
- select_all = nautilus_file_is_directory (file);
- }
- nautilus_view_rename_file_popover_new (view, file);
- }
- }
-
- nautilus_file_list_free (selection);
-}
-
-static void
-action_rename (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- real_action_rename (NAUTILUS_VIEW (user_data), FALSE);
-}
-
-#define BG_KEY_PRIMARY_COLOR "primary-color"
-#define BG_KEY_SECONDARY_COLOR "secondary-color"
-#define BG_KEY_COLOR_TYPE "color-shading-type"
-#define BG_KEY_PICTURE_PLACEMENT "picture-options"
-#define BG_KEY_PICTURE_URI "picture-uri"
-
-static void
-set_uri_as_wallpaper (const char *uri)
-{
- GSettings *settings;
-
- settings = gnome_background_preferences;
-
- g_settings_delay (settings);
-
- if (uri == NULL)
- uri = "";
-
- g_settings_set_string (settings, BG_KEY_PICTURE_URI, uri);
- g_settings_set_string (settings, BG_KEY_PRIMARY_COLOR, "#000000");
- g_settings_set_string (settings, BG_KEY_SECONDARY_COLOR, "#000000");
- g_settings_set_enum (settings, BG_KEY_COLOR_TYPE, G_DESKTOP_BACKGROUND_SHADING_SOLID);
- g_settings_set_enum (settings, BG_KEY_PICTURE_PLACEMENT, G_DESKTOP_BACKGROUND_STYLE_ZOOM);
-
- /* Apply changes atomically. */
- g_settings_apply (settings);
-}
-
-static void
-wallpaper_copy_done_callback (GHashTable *debuting_files,
- gboolean success,
- gpointer data)
-{
- GHashTableIter iter;
- gpointer key, value;
-
- g_hash_table_iter_init (&iter, debuting_files);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- char *uri;
- uri = g_file_get_uri (G_FILE (key));
- set_uri_as_wallpaper (uri);
- g_free (uri);
- break;
- }
-}
-
-static gboolean
-can_set_wallpaper (GList *selection)
-{
- NautilusFile *file;
-
- if (g_list_length (selection) != 1) {
- return FALSE;
- }
-
- file = NAUTILUS_FILE (selection->data);
- if (!nautilus_file_is_mime_type (file, "image/*")) {
- return FALSE;
- }
-
- /* FIXME: check file size? */
-
- return TRUE;
-}
-
-static void
-action_set_as_wallpaper (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- GList *selection;
-
- /* Copy the item to Pictures/Wallpaper since it may be
- remote. Then set it as the current wallpaper. */
-
- g_assert (NAUTILUS_IS_VIEW (user_data));
-
- selection = nautilus_view_get_selection (user_data);
-
- if (can_set_wallpaper (selection)
- && selection_not_empty_in_menu_callback (user_data, selection)) {
- NautilusFile *file;
- char *target_uri;
- GList *uris;
- GFile *parent;
- GFile *target;
-
- file = NAUTILUS_FILE (selection->data);
-
- parent = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_PICTURES));
- target = g_file_get_child (parent, "Wallpapers");
- g_object_unref (parent);
- g_file_make_directory_with_parents (target, NULL, NULL);
- target_uri = g_file_get_uri (target);
- g_object_unref (target);
- uris = g_list_prepend (NULL, nautilus_file_get_uri (file));
- nautilus_file_operations_copy_move (uris,
- NULL,
- target_uri,
- GDK_ACTION_COPY,
- GTK_WIDGET (user_data),
- wallpaper_copy_done_callback,
- NULL);
- g_free (target_uri);
- g_list_free_full (uris, g_free);
- }
-
- nautilus_file_list_free (selection);
-}
-
-static void
-file_mount_callback (NautilusFile *file,
- GFile *result_location,
- GError *error,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (callback_data);
-
- if (error != NULL &&
- (error->domain != G_IO_ERROR ||
- (error->code != G_IO_ERROR_CANCELLED &&
- error->code != G_IO_ERROR_FAILED_HANDLED &&
- error->code != G_IO_ERROR_ALREADY_MOUNTED))) {
- char *text;
- char *name;
- name = nautilus_file_get_display_name (file);
- /* Translators: %s is a file name formatted for display */
- text = g_strdup_printf (_("Unable to access “%s”"), name);
- eel_show_error_dialog (text, error->message,
- GTK_WINDOW (nautilus_view_get_window (view)));
- g_free (text);
- g_free (name);
- }
-}
-
-static void
-file_unmount_callback (NautilusFile *file,
- GFile *result_location,
- GError *error,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (callback_data);
- g_object_unref (view);
-
- if (error != NULL &&
- (error->domain != G_IO_ERROR ||
- (error->code != G_IO_ERROR_CANCELLED &&
- error->code != G_IO_ERROR_FAILED_HANDLED))) {
- char *text;
- char *name;
- name = nautilus_file_get_display_name (file);
- /* Translators: %s is a file name formatted for display */
- text = g_strdup_printf (_("Unable to remove “%s”"), name);
- eel_show_error_dialog (text, error->message,
- GTK_WINDOW (nautilus_view_get_window (view)));
- g_free (text);
- g_free (name);
- }
-}
-
-static void
-file_eject_callback (NautilusFile *file,
- GFile *result_location,
- GError *error,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (callback_data);
- g_object_unref (view);
-
- if (error != NULL &&
- (error->domain != G_IO_ERROR ||
- (error->code != G_IO_ERROR_CANCELLED &&
- error->code != G_IO_ERROR_FAILED_HANDLED))) {
- char *text;
- char *name;
- name = nautilus_file_get_display_name (file);
- /* Translators: %s is a file name formatted for display */
- text = g_strdup_printf (_("Unable to eject “%s”"), name);
- eel_show_error_dialog (text, error->message,
- GTK_WINDOW (nautilus_view_get_window (view)));
- g_free (text);
- g_free (name);
- }
-}
-
-static void
-file_stop_callback (NautilusFile *file,
- GFile *result_location,
- GError *error,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (callback_data);
-
- if (error != NULL &&
- (error->domain != G_IO_ERROR ||
- (error->code != G_IO_ERROR_CANCELLED &&
- error->code != G_IO_ERROR_FAILED_HANDLED))) {
- eel_show_error_dialog (_("Unable to stop drive"),
- error->message,
- GTK_WINDOW (nautilus_view_get_window (view)));
- }
-}
-
-static void
-action_mount_volume (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusFile *file;
- GList *selection, *l;
- NautilusView *view;
- GMountOperation *mount_op;
-
- view = NAUTILUS_VIEW (user_data);
-
- selection = nautilus_view_get_selection (view);
- for (l = selection; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- if (nautilus_file_can_mount (file)) {
- mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
- g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
- nautilus_file_mount (file, mount_op, NULL,
- file_mount_callback,
- view);
- g_object_unref (mount_op);
- }
- }
- nautilus_file_list_free (selection);
-}
-
-static void
-action_unmount_volume (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusFile *file;
- GList *selection, *l;
- NautilusView *view;
-
- view = NAUTILUS_VIEW (user_data);
-
- selection = nautilus_view_get_selection (view);
-
- for (l = selection; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
- if (nautilus_file_can_unmount (file)) {
- GMountOperation *mount_op;
- mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
- nautilus_file_unmount (file, mount_op, NULL,
- file_unmount_callback, g_object_ref (view));
- g_object_unref (mount_op);
- }
- }
- nautilus_file_list_free (selection);
-}
-
-static void
-action_eject_volume (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusFile *file;
- GList *selection, *l;
- NautilusView *view;
-
- view = NAUTILUS_VIEW (user_data);
-
- selection = nautilus_view_get_selection (view);
- for (l = selection; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- if (nautilus_file_can_eject (file)) {
- GMountOperation *mount_op;
- mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
- nautilus_file_eject (file, mount_op, NULL,
- file_eject_callback, g_object_ref (view));
- g_object_unref (mount_op);
- }
- }
- nautilus_file_list_free (selection);
-}
-
-static void
-file_start_callback (NautilusFile *file,
- GFile *result_location,
- GError *error,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (callback_data);
-
- if (error != NULL &&
- (error->domain != G_IO_ERROR ||
- (error->code != G_IO_ERROR_CANCELLED &&
- error->code != G_IO_ERROR_FAILED_HANDLED &&
- error->code != G_IO_ERROR_ALREADY_MOUNTED))) {
- char *text;
- char *name;
- name = nautilus_file_get_display_name (file);
- /* Translators: %s is a file name formatted for display */
- text = g_strdup_printf (_("Unable to start “%s”"), name);
- eel_show_error_dialog (text, error->message,
- GTK_WINDOW (nautilus_view_get_window (view)));
- g_free (text);
- g_free (name);
- }
-}
-
-static void
-action_start_volume (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusFile *file;
- GList *selection, *l;
- NautilusView *view;
- GMountOperation *mount_op;
-
- view = NAUTILUS_VIEW (user_data);
-
- selection = nautilus_view_get_selection (view);
- for (l = selection; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- if (nautilus_file_can_start (file) || nautilus_file_can_start_degraded (file)) {
- mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
- nautilus_file_start (file, mount_op, NULL,
- file_start_callback, view);
- g_object_unref (mount_op);
- }
- }
- nautilus_file_list_free (selection);
-}
-
-static void
-action_stop_volume (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusFile *file;
- GList *selection, *l;
- NautilusView *view;
-
- view = NAUTILUS_VIEW (user_data);
-
- selection = nautilus_view_get_selection (view);
- for (l = selection; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- if (nautilus_file_can_stop (file)) {
- GMountOperation *mount_op;
- mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
- nautilus_file_stop (file, mount_op, NULL,
- file_stop_callback, view);
- g_object_unref (mount_op);
- }
- }
- nautilus_file_list_free (selection);
-}
-
-static void
-action_detect_media (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusFile *file;
- GList *selection, *l;
- NautilusView *view;
-
- view = NAUTILUS_VIEW (user_data);
-
- selection = nautilus_view_get_selection (view);
- for (l = selection; l != NULL; l = l->next) {
- file = NAUTILUS_FILE (l->data);
-
- if (nautilus_file_can_poll_for_media (file) && !nautilus_file_is_media_check_automatic (file)) {
- nautilus_file_poll_for_media (file);
- }
- }
- nautilus_file_list_free (selection);
-}
-
-const GActionEntry view_entries[] = {
- /* Toolbar menu */
- { "zoom-in", action_zoom_in },
- { "zoom-out", action_zoom_out },
- { "zoom-default", action_zoom_default },
- { "show-hidden-files", NULL, NULL, "true", action_show_hidden_files },
- /* Background menu */
- { "new-folder", action_new_folder },
- { "select-all", action_select_all },
- { "paste", action_paste_files },
- { "new-document" },
- /* Selection menu */
- { "scripts" },
- { "new-folder-with-selection", action_new_folder_with_selection },
- { "open-scripts-folder", action_open_scripts_folder },
- { "open-item-location", action_open_item_location },
- { "open-with-default-application", action_open_with_default_application },
- { "open-with-other-application", action_open_with_other_application },
- { "open-item-new-window", action_open_item_new_window },
- { "open-item-new-tab", action_open_item_new_tab },
- { "cut", action_cut},
- { "copy", action_copy},
- { "move-to", action_move_to},
- { "copy-to", action_copy_to},
- { "move-to-trash", action_move_to_trash},
- { "delete-from-trash", action_delete },
- /* We separate the shortcut and the menu item since we want the shortcut
- * to always be available, but we don't want the menu item shown if not
- * completely necesary. Since the visibility of the menu item is based on
- * the action enability, we need to split the actions for the menu and the
- * shortcut. */
- { "delete-permanently-shortcut", action_delete },
- { "delete-permanently-menu-item", action_delete },
- { "remove-from-recent", action_remove_from_recent },
- { "restore-from-trash", action_restore_from_trash},
- { "paste-into", action_paste_files_into },
- { "rename", action_rename},
- { "properties", action_properties},
- { "set-as-wallpaper", action_set_as_wallpaper },
- { "mount-volume", action_mount_volume },
- { "unmount-volume", action_unmount_volume },
- { "eject-volume", action_eject_volume },
- { "start-volume", action_start_volume },
- { "stop-volume", action_stop_volume },
- { "detect-media", action_detect_media },
- /* Only accesible by shorcuts */
- { "select-pattern", action_select_pattern },
- { "invert-selection", action_invert_selection },
- { "open-file-and-close-window", action_open_file_and_close_window },
- /* Warning dialog for the change of the shorcut to move to trash */
- { "show-move-to-trash-shortcut-changed-dialog", action_show_move_to_trash_shortcut_changed_dialog }
-};
-
-static gboolean
-can_paste_into_file (NautilusFile *file)
-{
- if (nautilus_file_is_directory (file) &&
- nautilus_file_can_write (file)) {
- return TRUE;
- }
- if (nautilus_file_has_activation_uri (file)) {
- GFile *location;
- NautilusFile *activation_file;
- gboolean res;
-
- location = nautilus_file_get_activation_location (file);
- activation_file = nautilus_file_get (location);
- g_object_unref (location);
-
- /* The target location might not have data for it read yet,
- and we can't want to do sync I/O, so treat the unknown
- case as can-write */
- res = (nautilus_file_get_file_type (activation_file) == G_FILE_TYPE_UNKNOWN) ||
- (nautilus_file_get_file_type (activation_file) == G_FILE_TYPE_DIRECTORY &&
- nautilus_file_can_write (activation_file));
-
- nautilus_file_unref (activation_file);
-
- return res;
- }
-
- return FALSE;
-}
-
-static void
-clipboard_targets_received (GtkClipboard *clipboard,
- GdkAtom *targets,
- int n_targets,
- gpointer user_data)
-{
- NautilusView *view;
- gboolean can_paste;
- int i;
- GAction *action;
-
- view = NAUTILUS_VIEW (user_data);
- can_paste = FALSE;
-
- if (view->details->slot == NULL ||
- !view->details->active) {
- /* We've been destroyed or became inactive since call */
- g_object_unref (view);
- return;
- }
-
- if (targets) {
- for (i = 0; i < n_targets; i++) {
- if (targets[i] == copied_files_atom) {
- can_paste = TRUE;
- }
- }
- }
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view->details->view_action_group),
- "paste");
- /* Take into account if the action was previously disabled for other reasons,
- * like the directory not being writabble */
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_paste && g_action_get_enabled (action));
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view->details->view_action_group),
- "paste-into");
-
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_paste && g_action_get_enabled (action));
-
- g_object_unref (view);
-}
-
-static void
-file_should_show_foreach (NautilusFile *file,
- gboolean *show_mount,
- gboolean *show_unmount,
- gboolean *show_eject,
- gboolean *show_start,
- gboolean *show_stop,
- gboolean *show_poll,
- GDriveStartStopType *start_stop_type)
-{
- *show_mount = FALSE;
- *show_unmount = FALSE;
- *show_eject = FALSE;
- *show_start = FALSE;
- *show_stop = FALSE;
- *show_poll = FALSE;
-
- if (nautilus_file_can_eject (file)) {
- *show_eject = TRUE;
- }
-
- if (nautilus_file_can_mount (file)) {
- *show_mount = TRUE;
- }
-
- if (nautilus_file_can_start (file) || nautilus_file_can_start_degraded (file)) {
- *show_start = TRUE;
- }
-
- if (nautilus_file_can_stop (file)) {
- *show_stop = TRUE;
- }
-
- /* Dot not show both Unmount and Eject/Safe Removal; too confusing to
- * have too many menu entries */
- if (nautilus_file_can_unmount (file) && !*show_eject && !*show_stop) {
- *show_unmount = TRUE;
- }
-
- if (nautilus_file_can_poll_for_media (file) && !nautilus_file_is_media_check_automatic (file)) {
- *show_poll = TRUE;
- }
-
- *start_stop_type = nautilus_file_get_start_stop_type (file);
-}
-
-static gboolean
-can_restore_from_trash (GList *files)
-{
- NautilusFile *original_file;
- NautilusFile *original_dir;
- GHashTable *original_dirs_hash;
- GList *original_dirs;
- gboolean can_restore;
-
- original_file = NULL;
- original_dir = NULL;
- original_dirs = NULL;
- original_dirs_hash = NULL;
-
- if (files != NULL) {
- if (g_list_length (files) == 1) {
- original_file = nautilus_file_get_trash_original_file (files->data);
- } else {
- original_dirs_hash = nautilus_trashed_files_get_original_directories (files, NULL);
- if (original_dirs_hash != NULL) {
- original_dirs = g_hash_table_get_keys (original_dirs_hash);
- if (g_list_length (original_dirs) == 1) {
- original_dir = nautilus_file_ref (NAUTILUS_FILE (original_dirs->data));
- }
- }
- }
- }
-
- can_restore = original_file != NULL || original_dirs != NULL;
-
- nautilus_file_unref (original_file);
- nautilus_file_unref (original_dir);
- g_list_free (original_dirs);
-
- if (original_dirs_hash != NULL) {
- g_hash_table_destroy (original_dirs_hash);
- }
- return can_restore;
-}
-
-static void
-clipboard_changed_callback (NautilusClipboardMonitor *monitor, NautilusView *view)
-{
- /* Update paste menu item */
- nautilus_view_update_context_menus (view);
-}
-
-static gboolean
-can_delete_all (GList *files)
-{
- NautilusFile *file;
- GList *l;
-
- for (l = files; l != NULL; l = l->next) {
- file = l->data;
- if (!nautilus_file_can_delete (file)) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static gboolean
-can_trash_all (GList *files)
-{
- NautilusFile *file;
- GList *l;
-
- for (l = files; l != NULL; l = l->next) {
- file = l->data;
- if (!nautilus_file_can_trash (file)) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static gboolean
-all_in_trash (GList *files)
-{
- NautilusFile *file;
- GList *l;
-
- for (l = files; l != NULL; l = l->next) {
- file = l->data;
- if (!nautilus_file_is_in_trash (file)) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-GActionGroup *
-nautilus_view_get_action_group (NautilusView *view)
-{
- g_assert (NAUTILUS_IS_VIEW (view));
-
- return view->details->view_action_group;
-}
-
-static void
-real_update_actions_state (NautilusView *view)
-{
- GList *selection, *l;
- NautilusFile *file;
- gint selection_count;
- gboolean selection_contains_special_link;
- gboolean selection_contains_desktop_or_home_dir;
- gboolean selection_contains_recent;
- gboolean selection_contains_search;
- gboolean selection_all_in_trash;
- gboolean selection_is_read_only;
- gboolean can_create_files;
- gboolean can_delete_files;
- gboolean can_move_files;
- gboolean can_trash_files;
- gboolean can_copy_files;
- gboolean can_paste_files_into;
- gboolean show_app, show_run;
- gboolean item_opens_in_view;
- gboolean is_read_only;
- GAction *action;
- GAppInfo *app;
- gboolean show_properties;
- GActionGroup *view_action_group;
- gboolean show_mount;
- gboolean show_unmount;
- gboolean show_eject;
- gboolean show_start;
- gboolean show_stop;
- gboolean show_detect_media;
- GDriveStartStopType start_stop_type;
-
- view_action_group = view->details->view_action_group;
-
- selection = nautilus_view_get_selection (view);
- selection_count = g_list_length (selection);
- selection_contains_special_link = special_link_in_selection (selection);
- selection_contains_desktop_or_home_dir = desktop_or_home_dir_in_selection (selection);
- selection_contains_recent = showing_recent_directory (view);
- selection_contains_search = nautilus_view_is_search (view);
- selection_is_read_only = selection_count == 1 &&
- (!nautilus_file_can_write (NAUTILUS_FILE (selection->data)) &&
- !nautilus_file_has_activation_uri (NAUTILUS_FILE (selection->data)));
- selection_all_in_trash = all_in_trash (selection);
-
- is_read_only = nautilus_view_is_read_only (view);
- can_create_files = nautilus_view_supports_creating_files (view);
- can_delete_files =
- can_delete_all (selection) &&
- selection_count != 0 &&
- !selection_contains_special_link &&
- !selection_contains_desktop_or_home_dir;
- can_trash_files =
- can_trash_all (selection) &&
- selection_count != 0 &&
- !selection_contains_special_link &&
- !selection_contains_desktop_or_home_dir;
- can_copy_files = selection_count != 0
- && !selection_contains_special_link;
- can_move_files = can_delete_files && !selection_contains_recent;
- can_paste_files_into = (!selection_contains_recent &&
- selection_count == 1 &&
- can_paste_into_file (NAUTILUS_FILE (selection->data)));
- show_properties = !showing_network_directory (view) &&
- (!NAUTILUS_IS_DESKTOP_CANVAS_VIEW (view) || selection_count > 0);
-
- /* Right click actions */
- /* Selection menu actions */
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "new-folder-with-selection");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_create_files && can_delete_files && (selection_count > 1) && !selection_contains_recent);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "rename");
- if (selection_count > 1) {
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- have_bulk_rename_tool ());
- } else {
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- selection_count == 1 &&
- nautilus_view_can_rename_file (view, selection->data));
- }
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "open-item-location");
-
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- selection_count == 1 &&
- (selection_contains_recent || selection_contains_search));
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "new-folder");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_create_files);
-
-
- selection = nautilus_view_get_selection (view);
- selection_count = g_list_length (selection);
-
- show_app = show_run = item_opens_in_view = selection_count != 0;
-
- for (l = selection; l != NULL; l = l->next) {
- NautilusFile *file;
-
- file = NAUTILUS_FILE (selection->data);
-
- if (!nautilus_mime_file_opens_in_external_app (file)) {
- show_app = FALSE;
- }
-
- if (!nautilus_mime_file_launches (file)) {
- show_run = FALSE;
- }
-
- if (!nautilus_mime_file_opens_in_view (file)) {
- item_opens_in_view = FALSE;
- }
-
- if (!show_app && !show_run && !item_opens_in_view) {
- break;
- }
- }
-
- /* Open With <App> menu item */
- app = NULL;
- if (show_app) {
- app = nautilus_mime_get_default_application_for_files (selection);
- }
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "open-with-default-application");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action), selection_count != 0);
-
- /* Allow to select a different application to open the item */
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "open-with-other-application");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- app != NULL ||
- (selection_count > 0 &&
- nautilus_file_is_directory (NAUTILUS_FILE (selection->data))));
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "open-item-new-tab");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action), item_opens_in_view);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "open-item-new-window");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action), item_opens_in_view);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "set-as-wallpaper");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_set_wallpaper (selection));
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "restore-from-trash");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_restore_from_trash (selection));
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "move-to-trash");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_trash_files);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "delete-from-trash");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_delete_files && selection_all_in_trash);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "delete-permanently-shortcut");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_delete_files);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "delete-permanently-menu-item");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_delete_files && !can_trash_files &&
- !selection_all_in_trash && !selection_contains_recent);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "remove-from-recent");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- selection_contains_recent && selection_count > 0);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "cut");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_move_files && !selection_contains_recent);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "copy");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_copy_files);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "copy-to");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_copy_files);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "move-to");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_move_files && !selection_contains_recent);
-
- /* Drive menu */
- show_mount = show_unmount = show_eject = show_start = show_stop = show_detect_media = FALSE;
- for (l = selection; l != NULL && (show_mount || show_unmount
- || show_eject
- || show_start || show_stop
- || show_detect_media);
- l = l->next) {
- gboolean show_mount_one;
- gboolean show_unmount_one;
- gboolean show_eject_one;
- gboolean show_start_one;
- gboolean show_stop_one;
- gboolean show_detect_media_one;
-
- file = NAUTILUS_FILE (l->data);
- file_should_show_foreach (file,
- &show_mount_one,
- &show_unmount_one,
- &show_eject_one,
- &show_start_one,
- &show_stop_one,
- &show_detect_media_one,
- &start_stop_type);
-
- show_mount &= show_mount_one;
- show_unmount &= show_unmount_one;
- show_eject &= show_eject_one;
- show_start &= show_start_one;
- show_stop &= show_stop_one;
- show_detect_media &= show_detect_media_one;
- }
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "mount-volume");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- show_mount);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "unmount-volume");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- show_unmount);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "eject-volume");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- show_eject);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "start-volume");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- show_start);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "stop-volume");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- show_stop);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "detect-media");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- show_detect_media);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "scripts");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- view->details->scripts_present);
-
- /* Background menu actions */
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "new-folder");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_create_files);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "paste");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- !is_read_only && !selection_contains_recent);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "paste-into");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- !selection_is_read_only && !selection_contains_recent &&
- can_paste_files_into);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "properties");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- show_properties);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "new-document");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- can_create_files &&
- !selection_contains_recent &&
- view->details->templates_present);
-
- /* Ask the clipboard */
- g_object_ref (view); /* Need to keep the object alive until we get the reply */
- gtk_clipboard_request_targets (nautilus_clipboard_get (GTK_WIDGET (view)),
- clipboard_targets_received,
- view);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "select-all");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- !nautilus_view_is_empty (view));
-
- /* Toolbar menu actions */
- g_action_group_change_action_state (view_action_group,
- "show-hidden-files",
- g_variant_new_boolean (view->details->show_hidden_files));
-
- /* Zoom */
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "zoom-in");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- nautilus_view_can_zoom_in (view));
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "zoom-out");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- nautilus_view_can_zoom_out (view));
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
- "zoom-default");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- nautilus_view_supports_zooming (view));
-}
-
-/* Convenience function to be called when updating menus,
- * so children can subclass it and it will be called when
- * they chain up to the parent in update_context_menus
- * or update_toolbar_menus
- */
-void
-nautilus_view_update_actions_state (NautilusView *view)
-{
- g_assert(NAUTILUS_IS_VIEW (view));
-
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->update_actions_state (view);
-}
-
-static void
-update_selection_menu (NautilusView *view)
-{
- GList *selection, *l;
- NautilusFile *file;
- gint selection_count;
- gboolean show_app, show_run;
- gboolean item_opens_in_view;
- gchar *item_label;
- GAppInfo *app;
- GIcon *app_icon;
- GMenuItem *menu_item;
- gboolean show_mount;
- gboolean show_unmount;
- gboolean show_eject;
- gboolean show_start;
- gboolean show_stop;
- gboolean show_detect_media;
- GDriveStartStopType start_stop_type;
-
- selection = nautilus_view_get_selection (view);
- selection_count = g_list_length (selection);
-
- show_mount = (selection != NULL);
- show_unmount = (selection != NULL);
- show_eject = (selection != NULL);
- show_start = (selection != NULL && selection_count == 1);
- show_stop = (selection != NULL && selection_count == 1);
- show_detect_media = (selection != NULL && selection_count == 1);
- start_stop_type = G_DRIVE_START_STOP_TYPE_UNKNOWN;
- item_label = g_strdup_printf (ngettext ("New Folder with Selection (%'d Item)",
- "New Folder with Selection (%'d Items)",
- selection_count),
- selection_count);
- menu_item = g_menu_item_new (item_label, "view.new-folder-with-selection");
- g_menu_item_set_attribute (menu_item, "hidden-when", "s", "action-disabled");
- nautilus_gmenu_add_item_in_submodel (view->details->selection_menu,
- menu_item,
- "new-folder-with-selection-section",
- FALSE);
- g_object_unref (menu_item);
- g_free (item_label);
-
- /* Open With <App> menu item */
- show_app = show_run = item_opens_in_view = selection_count != 0;
- for (l = selection; l != NULL; l = l->next) {
- NautilusFile *file;
-
- file = NAUTILUS_FILE (selection->data);
-
- if (!nautilus_mime_file_opens_in_external_app (file)) {
- show_app = FALSE;
- }
-
- if (!nautilus_mime_file_launches (file)) {
- show_run = FALSE;
- }
-
- if (!nautilus_mime_file_opens_in_view (file)) {
- item_opens_in_view = FALSE;
- }
-
- if (!show_app && !show_run && !item_opens_in_view) {
- break;
- }
- }
-
- item_label = NULL;
- app = NULL;
- app_icon = NULL;
- if (show_app) {
- app = nautilus_mime_get_default_application_for_files (selection);
- }
-
- char *escaped_app;
-
- if (app != NULL) {
- escaped_app = eel_str_double_underscores (g_app_info_get_name (app));
- item_label = g_strdup_printf (_("Open With %s"), escaped_app);
-
- app_icon = g_app_info_get_icon (app);
- if (app_icon != NULL) {
- g_object_ref (app_icon);
- }
- g_free (escaped_app);
- g_object_unref (app);
- } else if (show_run) {
- item_label = g_strdup (_("Run"));
- } else {
- item_label = g_strdup (_("Open"));
- }
-
- menu_item = g_menu_item_new (item_label, "view.open-with-default-application");
- if (app_icon != NULL)
- g_menu_item_set_icon (menu_item, app_icon);
-
- nautilus_gmenu_add_item_in_submodel (view->details->selection_menu,
- menu_item,
- "open-with-default-application-section",
- FALSE);
-
- g_free (item_label);
- g_object_unref (menu_item);
-
- /* Drives */
- for (l = selection; l != NULL && (show_mount || show_unmount
- || show_eject
- || show_start || show_stop
- || show_detect_media);
- l = l->next) {
- gboolean show_mount_one;
- gboolean show_unmount_one;
- gboolean show_eject_one;
- gboolean show_start_one;
- gboolean show_stop_one;
- gboolean show_detect_media_one;
-
- file = NAUTILUS_FILE (l->data);
- file_should_show_foreach (file,
- &show_mount_one,
- &show_unmount_one,
- &show_eject_one,
- &show_start_one,
- &show_stop_one,
- &show_detect_media_one,
- &start_stop_type);
-
- show_mount &= show_mount_one;
- show_unmount &= show_unmount_one;
- show_eject &= show_eject_one;
- show_start &= show_start_one;
- show_stop &= show_stop_one;
- show_detect_media &= show_detect_media_one;
- }
-
- if (show_start) {
- switch (start_stop_type) {
- default:
- case G_DRIVE_START_STOP_TYPE_UNKNOWN:
- case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
- item_label = _("_Start");
- break;
- case G_DRIVE_START_STOP_TYPE_NETWORK:
- item_label = _("_Connect");
- break;
- case G_DRIVE_START_STOP_TYPE_MULTIDISK:
- item_label = _("_Start Multi-disk Drive");
- break;
- case G_DRIVE_START_STOP_TYPE_PASSWORD:
- item_label = _("U_nlock Drive");
- break;
- }
-
- menu_item = g_menu_item_new (item_label, "view.start-volume");
- nautilus_gmenu_add_item_in_submodel (view->details->selection_menu,
- menu_item,
- "drive-section",
- FALSE);
- g_object_unref (menu_item);
- }
-
- if (show_stop) {
- switch (start_stop_type) {
- default:
- case G_DRIVE_START_STOP_TYPE_UNKNOWN:
- item_label = _("Stop Drive");
- break;
- case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
- item_label = _("_Safely Remove Drive");
- break;
- case G_DRIVE_START_STOP_TYPE_NETWORK:
- item_label = _("_Disconnect");
- break;
- case G_DRIVE_START_STOP_TYPE_MULTIDISK:
- item_label = _("_Stop Multi-disk Drive");
- break;
- case G_DRIVE_START_STOP_TYPE_PASSWORD:
- item_label = _("_Lock Drive");
- break;
- }
-
- menu_item = g_menu_item_new (item_label, "view.stop-volume");
- nautilus_gmenu_add_item_in_submodel (view->details->selection_menu,
- menu_item,
- "drive-section",
- FALSE);
- g_object_unref (menu_item);
- }
-
- update_scripts_menu (view);
-}
-
-static void
-update_background_menu (NautilusView *view)
-{
-
- if (nautilus_view_supports_creating_files (view) &&
- !showing_recent_directory (view))
- update_templates_menu (view);
-}
-
-static void
-real_update_context_menus (NautilusView *view)
-{
- g_clear_object (&view->details->background_menu);
- g_clear_object (&view->details->selection_menu);
-
- GtkBuilder *builder;
- builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-view-context-menus.xml");
- view->details->background_menu = g_object_ref (G_MENU (gtk_builder_get_object (builder, "background-menu")));
- view->details->selection_menu = g_object_ref (G_MENU (gtk_builder_get_object (builder, "selection-menu")));
- g_object_unref (builder);
-
- update_selection_menu (view);
- update_background_menu (view);
- update_extensions_menus (view);
-
- nautilus_view_update_actions_state (view);
-}
-
-/* Convenience function to reset the context menus owned by the view and update
- * them with the current state.
- * Children can subclass it and add items on the menu after chaining up to the
- * parent, so menus are already reseted.
- * It will also update the actions state, which will also update children
- * actions state if the children subclass nautilus_view_update_actions_state
- */
-void
-nautilus_view_update_context_menus (NautilusView *view)
-{
- g_assert(NAUTILUS_IS_VIEW (view));
-
- NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->update_context_menus (view);
-}
-
-static void
-nautilus_view_reset_view_menu (NautilusView *view)
-{
- GActionGroup *view_action_group;
- GVariant *variant;
- GVariantIter iter;
- gboolean show_sort_trash, show_sort_search, show_sort_access, show_sort_modification, enable_sort;
- const gchar *hint;
-
- view_action_group = nautilus_view_get_action_group (view);
-
- gtk_widget_set_visible (view->details->visible_columns,
- g_action_group_has_action (view_action_group, "visible-columns"));
-
- enable_sort = g_action_group_get_action_enabled (view_action_group, "sort");
- show_sort_trash = show_sort_search = show_sort_modification = show_sort_access = FALSE;
- gtk_widget_set_visible (view->details->sort_menu, enable_sort);
-
- if (enable_sort) {
- variant = g_action_group_get_action_state_hint (view_action_group, "sort");
- g_variant_iter_init (&iter, variant);
-
- while (g_variant_iter_next (&iter, "&s", &hint)) {
- if (g_strcmp0 (hint, "trash-time") == 0)
- show_sort_trash = TRUE;
- if (g_strcmp0 (hint, "search-relevance") == 0)
- show_sort_search = TRUE;
- }
-
- g_variant_unref (variant);
- }
-
- gtk_widget_set_visible (view->details->sort_trash_time, show_sort_trash);
- gtk_widget_set_visible (view->details->sort_search_relevance, show_sort_search);
-
- variant = g_action_group_get_action_state (view_action_group, "zoom-to-level");
- gtk_adjustment_set_value (view->details->zoom_adjustment,
- g_variant_get_int32 (variant));
- g_variant_unref (variant);
-}
-
-/* Convenience function to reset the menus owned by the view but managed on
- * the toolbar, and update them with the current state.
- * It will also update the actions state, which will also update children
- * actions state if the children subclass nautilus_view_update_actions_state
- */
-void
-nautilus_view_update_toolbar_menus (NautilusView *view)
-{
- NautilusWindow *window;
-
- g_assert (NAUTILUS_IS_VIEW (view));
-
- /* Don't update after destroy (#349551),
- * or if we are not active.
- */
- if (view->details->slot == NULL ||
- !view->details->active) {
- return;
- }
- window = nautilus_view_get_window (view);
- nautilus_window_reset_menus (window);
-
- nautilus_view_reset_view_menu (view);
- nautilus_view_update_actions_state (view);
-}
-
-/**
- * nautilus_view_pop_up_selection_context_menu
- *
- * Pop up a context menu appropriate to the selected items.
- * @view: NautilusView of interest.
- * @event: The event that triggered this context menu.
- *
- **/
-void
-nautilus_view_pop_up_selection_context_menu (NautilusView *view,
- GdkEventButton *event)
-{
- g_assert (NAUTILUS_IS_VIEW (view));
-
- /* Make the context menu items not flash as they update to proper disabled,
- * etc. states by forcing menus to update now.
- */
- update_context_menus_if_pending (view);
-
- update_context_menu_position_from_event (view, event);
-
- nautilus_pop_up_context_menu (GTK_WIDGET (view), view->details->selection_menu, event);
-}
-
-/**
- * nautilus_view_pop_up_background_context_menu
- *
- * Pop up a context menu appropriate to the view globally at the last right click location.
- * @view: NautilusView of interest.
- *
- **/
-void
-nautilus_view_pop_up_background_context_menu (NautilusView *view,
- GdkEventButton *event)
-{
- g_assert (NAUTILUS_IS_VIEW (view));
-
- /* Make the context menu items not flash as they update to proper disabled,
- * etc. states by forcing menus to update now.
- */
- update_context_menus_if_pending (view);
-
- update_context_menu_position_from_event (view, event);
-
- nautilus_pop_up_context_menu (GTK_WIDGET (view), view->details->background_menu, event);
-}
-
-static void
-schedule_update_context_menus (NautilusView *view)
-{
- g_assert (NAUTILUS_IS_VIEW (view));
-
- /* Don't schedule updates after destroy (#349551),
- * or if we are not active.
- */
- if (view->details->slot == NULL ||
- !view->details->active) {
- return;
- }
-
- /* Schedule a menu update with the current update interval */
- if (view->details->update_context_menus_timeout_id == 0) {
- view->details->update_context_menus_timeout_id
- = g_timeout_add (view->details->update_interval, update_context_menus_timeout_callback, view);
- }
-}
-
-static void
-remove_update_status_idle_callback (NautilusView *view)
-{
- if (view->details->update_status_idle_id != 0) {
- g_source_remove (view->details->update_status_idle_id);
- view->details->update_status_idle_id = 0;
- }
-}
-
-static gboolean
-update_status_idle_callback (gpointer data)
-{
- NautilusView *view;
-
- view = NAUTILUS_VIEW (data);
- nautilus_view_display_selection_info (view);
- view->details->update_status_idle_id = 0;
- return FALSE;
-}
-
-static void
-schedule_update_status (NautilusView *view)
-{
- g_assert (NAUTILUS_IS_VIEW (view));
-
- /* Make sure we haven't already destroyed it */
- if (view->details->slot == NULL) {
- return;
- }
-
- if (view->details->loading) {
- /* Don't update status bar while loading the dir */
- return;
- }
-
- if (view->details->update_status_idle_id == 0) {
- view->details->update_status_idle_id =
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE - 20,
- update_status_idle_callback, view, NULL);
- }
-}
-
-/**
- * nautilus_view_notify_selection_changed:
- *
- * Notify this view that the selection has changed. This is normally
- * called only by subclasses.
- * @view: NautilusView whose selection has changed.
- *
- **/
-void
-nautilus_view_notify_selection_changed (NautilusView *view)
-{
- GtkWindow *window;
- GList *selection;
-
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- selection = nautilus_view_get_selection (view);
- window = nautilus_view_get_containing_window (view);
- DEBUG_FILES (selection, "Selection changed in window %p", window);
- nautilus_file_list_free (selection);
-
- view->details->selection_was_removed = FALSE;
-
- /* Schedule a display of the new selection. */
- if (view->details->display_selection_idle_id == 0) {
- view->details->display_selection_idle_id
- = g_idle_add (display_selection_info_idle_callback,
- view);
- }
-
- if (view->details->batching_selection_level != 0) {
- view->details->selection_changed_while_batched = TRUE;
- } else {
- /* Here is the work we do only when we're not
- * batching selection changes. In other words, it's the slower
- * stuff that we don't want to slow down selection techniques
- * such as rubberband-selecting in icon view.
- */
-
- /* Schedule an update of menu item states to match selection */
- schedule_update_context_menus (view);
- }
-}
-
-static void
-file_changed_callback (NautilusFile *file, gpointer callback_data)
-{
- NautilusView *view = NAUTILUS_VIEW (callback_data);
-
- schedule_changes (view);
-
- schedule_update_context_menus (view);
- schedule_update_status (view);
-}
-
-/**
- * load_directory:
- *
- * Switch the displayed location to a new uri. If the uri is not valid,
- * the location will not be switched; user feedback will be provided instead.
- * @view: NautilusView whose location will be changed.
- * @uri: A string representing the uri to switch to.
- *
- **/
-static void
-load_directory (NautilusView *view,
- NautilusDirectory *directory)
-{
- NautilusDirectory *old_directory;
- NautilusFile *old_file;
- NautilusFileAttributes attributes;
-
- g_assert (NAUTILUS_IS_VIEW (view));
- g_assert (NAUTILUS_IS_DIRECTORY (directory));
-
- nautilus_profile_start (NULL);
-
- nautilus_view_stop_loading (view);
- g_signal_emit (view, signals[CLEAR], 0);
-
- view->details->loading = TRUE;
-
- setup_loading_floating_bar (view);
-
- /* Update menus when directory is empty, before going to new
- * location, so they won't have any false lingering knowledge
- * of old selection.
- */
- schedule_update_context_menus (view);
-
- while (view->details->subdirectory_list != NULL) {
- nautilus_view_remove_subdirectory (view,
- view->details->subdirectory_list->data);
- }
-
- old_directory = view->details->model;
-
- nautilus_directory_ref (directory);
- view->details->model = directory;
- nautilus_directory_unref (old_directory);
-
- old_file = view->details->directory_as_file;
- view->details->directory_as_file =
- nautilus_directory_get_corresponding_file (directory);
- nautilus_file_unref (old_file);
-
- /* FIXME bugzilla.gnome.org 45062: In theory, we also need to monitor metadata here (as
- * well as doing a call when ready), in case external forces
- * change the directory's file metadata.
- */
- attributes =
- NAUTILUS_FILE_ATTRIBUTE_INFO |
- NAUTILUS_FILE_ATTRIBUTE_MOUNT |
- NAUTILUS_FILE_ATTRIBUTE_FILESYSTEM_INFO;
- view->details->metadata_for_directory_as_file_pending = TRUE;
- view->details->metadata_for_files_in_directory_pending = TRUE;
- nautilus_file_call_when_ready
- (view->details->directory_as_file,
- attributes,
- metadata_for_directory_as_file_ready_callback, view);
- nautilus_directory_call_when_ready
- (view->details->model,
- attributes,
- FALSE,
- metadata_for_files_in_directory_ready_callback, view);
-
- /* If capabilities change, then we need to update the menus
- * because of New Folder, and relative emblems.
- */
- attributes =
- NAUTILUS_FILE_ATTRIBUTE_INFO |
- NAUTILUS_FILE_ATTRIBUTE_FILESYSTEM_INFO;
- nautilus_file_monitor_add (view->details->directory_as_file,
- &view->details->directory_as_file,
- attributes);
-
- view->details->file_changed_handler_id = g_signal_connect
- (view->details->directory_as_file, "changed",
- G_CALLBACK (file_changed_callback), view);
-
- nautilus_profile_end (NULL);
-}
-
-static void
-finish_loading (NautilusView *view)
-{
- NautilusFileAttributes attributes;
-
- nautilus_profile_start (NULL);
-
- /* Tell interested parties that we've begun loading this directory now.
- * Subclasses use this to know that the new metadata is now available.
- */
- nautilus_profile_start ("BEGIN_LOADING");
- g_signal_emit (view, signals[BEGIN_LOADING], 0);
- nautilus_profile_end ("BEGIN_LOADING");
-
- check_empty_states (view);
-
- if (nautilus_directory_are_all_files_seen (view->details->model)) {
- /* Unschedule a pending update and schedule a new one with the minimal
- * update interval. This gives the view a short chance at gathering the
- * (cached) deep counts.
- */
- unschedule_display_of_pending_files (view);
- schedule_timeout_display_of_pending_files (view, UPDATE_INTERVAL_MIN);
- }
-
- /* Start loading. */
-
- /* Connect handlers to learn about loading progress. */
- view->details->done_loading_handler_id = g_signal_connect
- (view->details->model, "done-loading",
- G_CALLBACK (done_loading_callback), view);
- view->details->load_error_handler_id = g_signal_connect
- (view->details->model, "load-error",
- G_CALLBACK (load_error_callback), view);
-
- /* Monitor the things needed to get the right icon. Also
- * monitor a directory's item count because the "size"
- * attribute is based on that, and the file's metadata
- * and possible custom name.
- */
- attributes =
- NAUTILUS_FILE_ATTRIBUTES_FOR_ICON |
- NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
- NAUTILUS_FILE_ATTRIBUTE_INFO |
- NAUTILUS_FILE_ATTRIBUTE_LINK_INFO |
- NAUTILUS_FILE_ATTRIBUTE_MOUNT |
- NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO;
-
- nautilus_directory_file_monitor_add (view->details->model,
- &view->details->model,
- view->details->show_hidden_files,
- attributes,
- files_added_callback, view);
-
- view->details->files_added_handler_id = g_signal_connect
- (view->details->model, "files-added",
- G_CALLBACK (files_added_callback), view);
- view->details->files_changed_handler_id = g_signal_connect
- (view->details->model, "files-changed",
- G_CALLBACK (files_changed_callback), view);
-
- nautilus_profile_end (NULL);
-}
-
-static void
-finish_loading_if_all_metadata_loaded (NautilusView *view)
-{
- if (!view->details->metadata_for_directory_as_file_pending &&
- !view->details->metadata_for_files_in_directory_pending) {
- finish_loading (view);
- }
-}
-
-static void
-metadata_for_directory_as_file_ready_callback (NautilusFile *file,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = callback_data;
-
- g_assert (NAUTILUS_IS_VIEW (view));
- g_assert (view->details->directory_as_file == file);
- g_assert (view->details->metadata_for_directory_as_file_pending);
-
- nautilus_profile_start (NULL);
-
- view->details->metadata_for_directory_as_file_pending = FALSE;
-
- finish_loading_if_all_metadata_loaded (view);
- nautilus_profile_end (NULL);
-}
-
-static void
-metadata_for_files_in_directory_ready_callback (NautilusDirectory *directory,
- GList *files,
- gpointer callback_data)
-{
- NautilusView *view;
-
- view = callback_data;
-
- g_assert (NAUTILUS_IS_VIEW (view));
- g_assert (view->details->model == directory);
- g_assert (view->details->metadata_for_files_in_directory_pending);
-
- nautilus_profile_start (NULL);
-
- view->details->metadata_for_files_in_directory_pending = FALSE;
-
- finish_loading_if_all_metadata_loaded (view);
- nautilus_profile_end (NULL);
-}
-
-static void
-disconnect_handler (GObject *object, guint *id)
-{
- if (*id != 0) {
- g_signal_handler_disconnect (object, *id);
- *id = 0;
- }
-}
-
-static void
-disconnect_directory_handler (NautilusView *view, guint *id)
-{
- disconnect_handler (G_OBJECT (view->details->model), id);
-}
-
-static void
-disconnect_directory_as_file_handler (NautilusView *view, guint *id)
-{
- disconnect_handler (G_OBJECT (view->details->directory_as_file), id);
-}
-
-static void
-disconnect_model_handlers (NautilusView *view)
-{
- if (view->details->model == NULL) {
- return;
- }
- disconnect_directory_handler (view, &view->details->files_added_handler_id);
- disconnect_directory_handler (view, &view->details->files_changed_handler_id);
- disconnect_directory_handler (view, &view->details->done_loading_handler_id);
- disconnect_directory_handler (view, &view->details->load_error_handler_id);
- disconnect_directory_as_file_handler (view, &view->details->file_changed_handler_id);
- nautilus_file_cancel_call_when_ready (view->details->directory_as_file,
- metadata_for_directory_as_file_ready_callback,
- view);
- nautilus_directory_cancel_callback (view->details->model,
- metadata_for_files_in_directory_ready_callback,
- view);
- nautilus_directory_file_monitor_remove (view->details->model,
- &view->details->model);
- nautilus_file_monitor_remove (view->details->directory_as_file,
- &view->details->directory_as_file);
-}
-
-static void
-nautilus_view_select_file (NautilusView *view, NautilusFile *file)
-{
- GList file_list;
-
- file_list.data = file;
- file_list.next = NULL;
- file_list.prev = NULL;
- nautilus_view_call_set_selection (view, &file_list);
-}
-
-static gboolean
-remove_all (gpointer key, gpointer value, gpointer callback_data)
-{
- return TRUE;
-}
-
-/**
- * nautilus_view_stop_loading:
- *
- * Stop the current ongoing process, such as switching to a new uri.
- * @view: NautilusView in question.
- *
- **/
-void
-nautilus_view_stop_loading (NautilusView *view)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- disconnect_model_handlers (view);
- if (view->details->model) {
- nautilus_directory_unref (view->details->model);
- view->details->model = NULL;
- }
- unschedule_display_of_pending_files (view);
- reset_update_interval (view);
-
- /* Free extra undisplayed files */
- file_and_directory_list_free (view->details->new_added_files);
- view->details->new_added_files = NULL;
-
- file_and_directory_list_free (view->details->new_changed_files);
- view->details->new_changed_files = NULL;
-
- g_hash_table_foreach_remove (view->details->non_ready_files, remove_all, NULL);
-
- file_and_directory_list_free (view->details->old_added_files);
- view->details->old_added_files = NULL;
-
- file_and_directory_list_free (view->details->old_changed_files);
- view->details->old_changed_files = NULL;
-
- g_list_free_full (view->details->pending_selection, g_object_unref);
- view->details->pending_selection = NULL;
-
- done_loading (view, FALSE);
-}
-
-gboolean
-nautilus_view_is_editable (NautilusView *view)
-{
- NautilusDirectory *directory;
-
- directory = nautilus_view_get_model (view);
-
- if (directory != NULL) {
- return nautilus_directory_is_editable (directory);
- }
-
- return TRUE;
-}
-
-static gboolean
-real_is_read_only (NautilusView *view)
-{
- NautilusFile *file;
-
- if (!nautilus_view_is_editable (view)) {
- return TRUE;
- }
-
- file = nautilus_view_get_directory_as_file (view);
- if (file != NULL) {
- return !nautilus_file_can_write (file);
- }
- return FALSE;
-}
-
-/**
- * nautilus_view_should_show_file
- *
- * Returns whether or not this file should be displayed based on
- * current filtering options.
- */
-gboolean
-nautilus_view_should_show_file (NautilusView *view, NautilusFile *file)
-{
- return nautilus_file_should_show (file,
- view->details->show_hidden_files,
- view->details->show_foreign_files);
-}
-
-static gboolean
-real_using_manual_layout (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
-
- return FALSE;
-}
-
-void
-nautilus_view_ignore_hidden_file_preferences (NautilusView *view)
-{
- g_return_if_fail (view->details->model == NULL);
-
- if (view->details->ignore_hidden_file_preferences) {
- return;
- }
-
- view->details->show_hidden_files = FALSE;
- view->details->ignore_hidden_file_preferences = TRUE;
-}
-
-void
-nautilus_view_set_show_foreign (NautilusView *view,
- gboolean show_foreign)
-{
- view->details->show_foreign_files = show_foreign;
-}
-
-char *
-nautilus_view_get_uri (NautilusView *view)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
- if (view->details->model == NULL) {
- return NULL;
- }
- return nautilus_directory_get_uri (view->details->model);
-}
-
-void
-nautilus_view_move_copy_items (NautilusView *view,
- const GList *item_uris,
- GArray *relative_item_points,
- const char *target_uri,
- int copy_action,
- int x, int y)
-{
- NautilusFile *target_file;
-
- 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);
-
- target_file = nautilus_file_get_existing_by_uri (target_uri);
- /* special-case "command:" here instead of starting a move/copy */
- if (target_file != NULL && nautilus_file_is_launcher (target_file)) {
- nautilus_file_unref (target_file);
- nautilus_launch_desktop_file (
- gtk_widget_get_screen (GTK_WIDGET (view)),
- target_uri, item_uris,
- nautilus_view_get_containing_window (view));
- return;
- } else if (copy_action == GDK_ACTION_COPY &&
- nautilus_is_file_roller_installed () &&
- target_file != NULL &&
- nautilus_file_is_archive (target_file)) {
- char *command, *quoted_uri, *tmp;
- const GList *l;
- GdkScreen *screen;
-
- /* Handle dropping onto a file-roller archiver file, instead of starting a move/copy */
-
- nautilus_file_unref (target_file);
-
- quoted_uri = g_shell_quote (target_uri);
- command = g_strconcat ("file-roller -a ", quoted_uri, NULL);
- g_free (quoted_uri);
-
- for (l = item_uris; l != NULL; l = l->next) {
- quoted_uri = g_shell_quote ((char *) l->data);
-
- tmp = g_strconcat (command, " ", quoted_uri, NULL);
- g_free (command);
- command = tmp;
-
- g_free (quoted_uri);
- }
-
- screen = gtk_widget_get_screen (GTK_WIDGET (view));
- if (screen == NULL) {
- screen = gdk_screen_get_default ();
- }
-
- nautilus_launch_application_from_command (screen, command, FALSE, NULL);
- g_free (command);
-
- return;
- }
- nautilus_file_unref (target_file);
-
- nautilus_file_operations_copy_move
- (item_uris, relative_item_points,
- target_uri, copy_action, GTK_WIDGET (view),
- copy_move_done_callback, pre_copy_move (view));
-}
-
-static void
-nautilus_view_trash_state_changed_callback (NautilusTrashMonitor *trash_monitor,
- gboolean state, gpointer callback_data)
-{
- NautilusView *view;
-
- view = (NautilusView *) callback_data;
- g_assert (NAUTILUS_IS_VIEW (view));
-
- schedule_update_context_menus (view);
-}
-
-void
-nautilus_view_start_batching_selection_changes (NautilusView *view)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
-
- ++view->details->batching_selection_level;
- view->details->selection_changed_while_batched = FALSE;
-}
-
-void
-nautilus_view_stop_batching_selection_changes (NautilusView *view)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW (view));
- g_return_if_fail (view->details->batching_selection_level > 0);
-
- if (--view->details->batching_selection_level == 0) {
- if (view->details->selection_changed_while_batched) {
- nautilus_view_notify_selection_changed (view);
- }
- }
-}
-
-static GArray *
-real_get_selected_icon_locations (NautilusView *view)
-{
- /* By default, just return an empty list. */
- return g_array_new (FALSE, TRUE, sizeof (GdkPoint));
-}
-
-static void
-nautilus_view_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- NautilusView *view = NAUTILUS_VIEW (object);
-
- switch (prop_id) {
- case PROP_ICON:
- g_value_set_object (value, nautilus_view_get_icon (view));
- break;
-
- case PROP_VIEW_WIDGET:
- g_value_set_object (value, nautilus_view_get_view_widget (view));
- break;
-
- default:
- g_assert_not_reached ();
-
- }
-}
-
-static void
-nautilus_view_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- NautilusView *directory_view;
- NautilusWindowSlot *slot;
-
- directory_view = NAUTILUS_VIEW (object);
-
- switch (prop_id) {
- case PROP_WINDOW_SLOT:
- g_assert (directory_view->details->slot == NULL);
-
- slot = NAUTILUS_WINDOW_SLOT (g_value_get_object (value));
- directory_view->details->slot = slot;
-
- g_signal_connect_object (directory_view->details->slot,
- "active", G_CALLBACK (slot_active),
- directory_view, 0);
- g_signal_connect_object (directory_view->details->slot,
- "inactive", G_CALLBACK (slot_inactive),
- directory_view, 0);
- break;
- case PROP_SUPPORTS_ZOOMING:
- directory_view->details->supports_zooming = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-gboolean
-nautilus_view_handle_scroll_event (NautilusView *directory_view,
- GdkEventScroll *event)
-{
- static gdouble total_delta_y = 0;
- gdouble delta_x, delta_y;
-
- if (event->state & GDK_CONTROL_MASK) {
- switch (event->direction) {
- case GDK_SCROLL_UP:
- /* Zoom In */
- nautilus_view_bump_zoom_level (directory_view, 1);
- return TRUE;
-
- case GDK_SCROLL_DOWN:
- /* Zoom Out */
- nautilus_view_bump_zoom_level (directory_view, -1);
- return TRUE;
-
- case GDK_SCROLL_SMOOTH:
- gdk_event_get_scroll_deltas ((const GdkEvent *) event,
- &delta_x, &delta_y);
-
- /* try to emulate a normal scrolling event by summing deltas */
- total_delta_y += delta_y;
-
- if (total_delta_y >= 1) {
- total_delta_y = 0;
- /* emulate scroll down */
- nautilus_view_bump_zoom_level (directory_view, -1);
- return TRUE;
- } else if (total_delta_y <= - 1) {
- total_delta_y = 0;
- /* emulate scroll up */
- nautilus_view_bump_zoom_level (directory_view, 1);
- return TRUE;
- } else {
- /* eat event */
- return TRUE;
- }
-
- case GDK_SCROLL_LEFT:
- case GDK_SCROLL_RIGHT:
- break;
-
- default:
- g_assert_not_reached ();
- }
- }
-
- return FALSE;
-}
-
-/* handle Shift+Scroll, which will cause a zoom-in/out */
-static gboolean
-nautilus_view_scroll_event (GtkWidget *widget,
- GdkEventScroll *event)
-{
- NautilusView *directory_view;
-
- directory_view = NAUTILUS_VIEW (widget);
- if (nautilus_view_handle_scroll_event (directory_view, event)) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-static void
-action_reload_enabled_changed (GActionGroup *action_group,
- gchar *action_name,
- gboolean enabled,
- NautilusView *view)
-{
- gtk_widget_set_visible (view->details->reload, enabled);
-}
-
-static void
-action_stop_enabled_changed (GActionGroup *action_group,
- gchar *action_name,
- gboolean enabled,
- NautilusView *view)
-{
- gtk_widget_set_visible (view->details->stop, enabled);
-}
-
-static void
-nautilus_view_parent_set (GtkWidget *widget,
- GtkWidget *old_parent)
-{
- NautilusWindow *window;
- NautilusView *view;
- GtkWidget *parent;
-
- view = NAUTILUS_VIEW (widget);
-
- parent = gtk_widget_get_parent (widget);
- window = nautilus_view_get_window (view);
- g_assert (parent == NULL || old_parent == NULL);
-
- if (GTK_WIDGET_CLASS (nautilus_view_parent_class)->parent_set != NULL) {
- GTK_WIDGET_CLASS (nautilus_view_parent_class)->parent_set (widget, old_parent);
- }
-
- if (view->details->stop_signal_handler > 0) {
- g_signal_handler_disconnect (window, view->details->stop_signal_handler);
- view->details->stop_signal_handler = 0;
- }
-
- if (view->details->reload_signal_handler > 0) {
- g_signal_handler_disconnect (window, view->details->reload_signal_handler);
- view->details->reload_signal_handler = 0;
- }
-
- if (parent != NULL) {
- g_assert (old_parent == NULL);
-
- if (view->details->slot == nautilus_window_get_active_slot (window)) {
- view->details->active = TRUE;
- gtk_widget_insert_action_group (GTK_WIDGET (nautilus_view_get_window (view)),
- "view",
- G_ACTION_GROUP (view->details->view_action_group));
- }
-
- view->details->stop_signal_handler =
- g_signal_connect (window,
- "action-enabled-changed::stop",
- G_CALLBACK (action_stop_enabled_changed),
- view);
- view->details->reload_signal_handler =
- g_signal_connect (window,
- "action-enabled-changed::reload",
- G_CALLBACK (action_reload_enabled_changed),
- view);
- } else {
- remove_update_context_menus_timeout_callback (view);
- gtk_widget_insert_action_group (GTK_WIDGET (nautilus_view_get_window (view)),
- "view",
- NULL);
- }
-}
-
-static gboolean
-nautilus_view_key_press_event (GtkWidget *widget,
- GdkEventKey *event)
-{
- NautilusView *view;
- gint i;
-
- view = NAUTILUS_VIEW (widget);
-
- for (i = 0; i < G_N_ELEMENTS (extra_view_keybindings); i++) {
- if (extra_view_keybindings[i].keyval == event->keyval) {
- GAction *action;
-
- action = g_action_map_lookup_action (G_ACTION_MAP (view->details->view_action_group),
- extra_view_keybindings[i].action);
-
- if (g_action_get_enabled (action)) {
- g_action_activate (action, NULL);
- return GDK_EVENT_STOP;
- }
-
- break;
- }
- }
-
- return GDK_EVENT_PROPAGATE;
-}
-
-static void
-nautilus_view_class_init (NautilusViewClass *klass)
-{
- GObjectClass *oclass;
- GtkWidgetClass *widget_class;
-
- widget_class = GTK_WIDGET_CLASS (klass);
- oclass = G_OBJECT_CLASS (klass);
-
- oclass->finalize = nautilus_view_finalize;
- oclass->get_property = nautilus_view_get_property;
- oclass->set_property = nautilus_view_set_property;
-
- widget_class->destroy = nautilus_view_destroy;
- widget_class->key_press_event = nautilus_view_key_press_event;
- widget_class->scroll_event = nautilus_view_scroll_event;
- widget_class->parent_set = nautilus_view_parent_set;
- widget_class->grab_focus = nautilus_view_grab_focus;
-
- g_type_class_add_private (klass, sizeof (NautilusViewDetails));
-
- signals[ADD_FILE] =
- g_signal_new ("add-file",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NautilusViewClass, add_file),
- NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE, 2, NAUTILUS_TYPE_FILE, NAUTILUS_TYPE_DIRECTORY);
- signals[BEGIN_FILE_CHANGES] =
- g_signal_new ("begin-file-changes",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NautilusViewClass, begin_file_changes),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- signals[BEGIN_LOADING] =
- g_signal_new ("begin-loading",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NautilusViewClass, begin_loading),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- signals[CLEAR] =
- g_signal_new ("clear",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NautilusViewClass, clear),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- signals[END_FILE_CHANGES] =
- g_signal_new ("end-file-changes",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NautilusViewClass, end_file_changes),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- signals[END_LOADING] =
- g_signal_new ("end-loading",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NautilusViewClass, end_loading),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
- signals[FILE_CHANGED] =
- g_signal_new ("file-changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NautilusViewClass, file_changed),
- NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE, 2, NAUTILUS_TYPE_FILE, NAUTILUS_TYPE_DIRECTORY);
- signals[REMOVE_FILE] =
- g_signal_new ("remove-file",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NautilusViewClass, remove_file),
- NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE, 2, NAUTILUS_TYPE_FILE, NAUTILUS_TYPE_DIRECTORY);
- signals[SELECTION_CHANGED] =
- g_signal_new ("selection-changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- klass->get_selected_icon_locations = real_get_selected_icon_locations;
- klass->is_read_only = real_is_read_only;
- klass->can_rename_file = can_rename_file;
- klass->get_backing_uri = real_get_backing_uri;
- klass->using_manual_layout = real_using_manual_layout;
- klass->get_window = nautilus_view_get_window;
- klass->update_context_menus = real_update_context_menus;
- klass->update_actions_state = real_update_actions_state;
-
- copied_files_atom = gdk_atom_intern ("x-special/gnome-copied-files", FALSE);
-
- properties[PROP_WINDOW_SLOT] =
- g_param_spec_object ("window-slot",
- "Window Slot",
- "The parent window slot reference",
- NAUTILUS_TYPE_WINDOW_SLOT,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY);
- properties[PROP_SUPPORTS_ZOOMING] =
- g_param_spec_boolean ("supports-zooming",
- "Supports zooming",
- "Whether the view supports zooming",
- TRUE,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- properties[PROP_ICON] =
- g_param_spec_object ("icon",
- "Icon",
- "The icon that represents the view",
- G_TYPE_ICON,
- G_PARAM_READABLE);
-
- properties[PROP_VIEW_WIDGET] =
- g_param_spec_object ("view-widget",
- "View widget",
- "The view's widget that will appear under the view menu button",
- GTK_TYPE_WIDGET,
- G_PARAM_READABLE);
-
- g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
-}
-
-static void
-nautilus_view_init (NautilusView *view)
-{
- GtkBuilder *builder;
- AtkObject *atk_object;
- NautilusDirectory *scripts_directory;
- NautilusDirectory *templates_directory;
- gchar *templates_uri;
- GApplication *app;
- const gchar *open_accels[] = {
- "<control>o",
- "<alt>Down",
- NULL
- };
-
- nautilus_profile_start (NULL);
-
- view->details = G_TYPE_INSTANCE_GET_PRIVATE (view, NAUTILUS_TYPE_VIEW,
- NautilusViewDetails);
-
- /* NautilusFloatingBar listen to its parent's 'enter-notify-event' signal
- * and GtkOverlay doesn't have it enabled by default, so we have to add them
- * here.
- */
- gtk_widget_add_events (GTK_WIDGET (view),
- GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
-
- /* View menu */
- builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-toolbar-view-menu.xml");
- view->details->view_menu_widget = g_object_ref (gtk_builder_get_object (builder, "view_menu_widget"));
- view->details->zoom_level_scale = GTK_WIDGET (gtk_builder_get_object (builder, "zoom_level_scale"));
- view->details->zoom_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "zoom_adjustment"));
-
- view->details->sort_menu = GTK_WIDGET (gtk_builder_get_object (builder, "sort_menu"));
- view->details->sort_trash_time = GTK_WIDGET (gtk_builder_get_object (builder, "sort_trash_time"));
- view->details->sort_search_relevance = GTK_WIDGET (gtk_builder_get_object (builder, "sort_search_relevance"));
- view->details->visible_columns = GTK_WIDGET (gtk_builder_get_object (builder, "visible_columns"));
- view->details->reload = GTK_WIDGET (gtk_builder_get_object (builder, "reload"));
- view->details->stop = GTK_WIDGET (gtk_builder_get_object (builder, "stop"));
-
- g_signal_connect (view->details->zoom_level_scale, "value-changed",
- G_CALLBACK (zoom_level_changed), view);
-
- g_object_unref (builder);
-
- /* Scrolled Window */
- view->details->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view->details->scrolled_window),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_widget_show (view->details->scrolled_window);
-
- g_signal_connect_swapped (view->details->scrolled_window,
- "scroll-event",
- G_CALLBACK (nautilus_view_scroll_event),
- view);
-
- gtk_container_add (GTK_CONTAINER (view), view->details->scrolled_window);
-
- /* Empty states */
- builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-no-search-results.ui");
- view->details->no_search_results_widget = GTK_WIDGET (gtk_builder_get_object (builder, "no_search_results"));
- gtk_overlay_add_overlay (GTK_OVERLAY (view), view->details->no_search_results_widget);
- g_object_unref (builder);
-
- builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-folder-is-empty.ui");
- view->details->folder_is_empty_widget = GTK_WIDGET (gtk_builder_get_object (builder, "folder_is_empty"));
- gtk_overlay_add_overlay (GTK_OVERLAY (view), view->details->folder_is_empty_widget);
- g_object_unref (builder);
-
- /* Floating bar */
- view->details->floating_bar = nautilus_floating_bar_new (NULL, NULL, FALSE);
- gtk_widget_set_halign (view->details->floating_bar, GTK_ALIGN_END);
- gtk_widget_set_valign (view->details->floating_bar, GTK_ALIGN_END);
- gtk_overlay_add_overlay (GTK_OVERLAY (view), view->details->floating_bar);
-
- g_signal_connect (view->details->floating_bar,
- "action",
- G_CALLBACK (floating_bar_action_cb),
- view);
-
- /* Default to true; desktop-icon-view sets to false */
- view->details->show_foreign_files = TRUE;
-
- view->details->non_ready_files =
- g_hash_table_new_full (file_and_directory_hash,
- file_and_directory_equal,
- (GDestroyNotify)file_and_directory_free,
- NULL);
-
- gtk_style_context_set_junction_sides (gtk_widget_get_style_context (GTK_WIDGET (view)),
- GTK_JUNCTION_TOP | GTK_JUNCTION_LEFT);
-
- if (set_up_scripts_directory_global ()) {
- scripts_directory = nautilus_directory_get_by_uri (scripts_directory_uri);
- add_directory_to_scripts_directory_list (view, scripts_directory);
- nautilus_directory_unref (scripts_directory);
- } else {
- g_warning ("Ignoring scripts directory, it may be a broken link\n");
- }
-
- if (nautilus_should_use_templates_directory ()) {
- templates_uri = nautilus_get_templates_directory_uri ();
- templates_directory = nautilus_directory_get_by_uri (templates_uri);
- g_free (templates_uri);
- add_directory_to_templates_directory_list (view, templates_directory);
- nautilus_directory_unref (templates_directory);
- }
- update_templates_directory (view);
-
- view->details->sort_directories_first =
- g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
- view->details->show_hidden_files =
- g_settings_get_boolean (gtk_filechooser_preferences, NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES);
-
- g_signal_connect_object (nautilus_trash_monitor_get (), "trash-state-changed",
- G_CALLBACK (nautilus_view_trash_state_changed_callback), view, 0);
-
- /* React to clipboard changes */
- g_signal_connect_object (nautilus_clipboard_monitor_get (), "clipboard-changed",
- G_CALLBACK (clipboard_changed_callback), view, 0);
-
- /* Register to menu provider extension signal managing menu updates */
- g_signal_connect_object (nautilus_signaller_get_current (), "popup-menu-changed",
- G_CALLBACK (schedule_update_context_menus), view, G_CONNECT_SWAPPED);
-
- gtk_widget_show (GTK_WIDGET (view));
-
- g_signal_connect_swapped (nautilus_preferences,
- "changed::" NAUTILUS_PREFERENCES_CLICK_POLICY,
- G_CALLBACK (click_policy_changed_callback),
- view);
- g_signal_connect_swapped (nautilus_preferences,
- "changed::" NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST,
- G_CALLBACK (sort_directories_first_changed_callback), view);
- g_signal_connect_swapped (gtk_filechooser_preferences,
- "changed::" NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
- G_CALLBACK (show_hidden_files_changed_callback), view);
- g_signal_connect_swapped (gnome_lockdown_preferences,
- "changed::" NAUTILUS_PREFERENCES_LOCKDOWN_COMMAND_LINE,
- G_CALLBACK (schedule_update_context_menus), view);
-
- /* Accessibility */
- atk_object = gtk_widget_get_accessible (GTK_WIDGET (view));
- atk_object_set_name (atk_object, _("Content View"));
- atk_object_set_description (atk_object, _("View of the current folder"));
-
- view->details->view_action_group = G_ACTION_GROUP (g_simple_action_group_new ());
- g_action_map_add_action_entries (G_ACTION_MAP (view->details->view_action_group),
- view_entries,
- G_N_ELEMENTS (view_entries),
- view);
- gtk_widget_insert_action_group (GTK_WIDGET (view),
- "view",
- G_ACTION_GROUP (view->details->view_action_group));
- app = g_application_get_default ();
-
- /* Toolbar menu */
- nautilus_application_add_accelerator (app, "view.zoom-in", "<control>plus");
- nautilus_application_add_accelerator (app, "view.zoom-out", "<control>minus");
- nautilus_application_add_accelerator (app, "view.show-hidden-files", "<control>h");
- /* Background menu */
- nautilus_application_add_accelerator (app, "view.select-all", "<control>a");
- nautilus_application_add_accelerator (app, "view.paste", "<control>v");
- /* Selection menu */
- gtk_application_set_accels_for_action (GTK_APPLICATION (app),
- "view.open-with-default-application", open_accels);
- nautilus_application_add_accelerator (app, "view.open-item-new-tab", "<shift><control>t");
- nautilus_application_add_accelerator (app, "view.open-item-new-window", "<shift><control>w");
- nautilus_application_add_accelerator (app, "view.move-to-trash", "Delete");
- nautilus_application_add_accelerator (app, "view.delete-from-trash", "Delete");
- nautilus_application_add_accelerator (app, "view.delete-permanently-shortcut", "<shift>Delete");
- nautilus_application_add_accelerator (app, "view.properties", "<control>i");
- nautilus_application_add_accelerator (app, "view.open-item-location", "<control><alt>o");
- nautilus_application_add_accelerator (app, "view.rename", "F2");
- nautilus_application_add_accelerator (app, "view.cut", "<control>x");
- nautilus_application_add_accelerator (app, "view.copy", "<control>c");
- nautilus_application_add_accelerator (app, "view.new-folder", "<control><shift>n");
- /* Only accesible by shorcuts */
- nautilus_application_add_accelerator (app, "view.select-pattern", "<control>s");
- nautilus_application_add_accelerator (app, "view.zoom-default", "<control>0");
- nautilus_application_add_accelerator (app, "view.invert-selection", "<shift><control>i");
- nautilus_application_add_accelerator (app, "view.open-file-and-close-window", "<control><shift>Down");
-
- /* Show a warning dialog to inform the user that the shorcut for move to trash
- * changed */
- nautilus_application_add_accelerator (app, "view.show-move-to-trash-shortcut-changed-dialog", "<control>Delete");
-
- nautilus_profile_end (NULL);
-}
-
-NautilusView *
-nautilus_view_new (const gchar *id,
- NautilusWindowSlot *slot)
-{
- NautilusView *view = NULL;
-
- if (g_strcmp0 (id, NAUTILUS_CANVAS_VIEW_ID) == 0) {
- view = nautilus_canvas_view_new (slot);
- } else if (g_strcmp0 (id, NAUTILUS_LIST_VIEW_ID) == 0) {
- view = nautilus_list_view_new (slot);
- } else if (g_strcmp0 (id, NAUTILUS_DESKTOP_CANVAS_VIEW_ID) == 0) {
- view = nautilus_desktop_canvas_view_new (slot);
- }
-#if ENABLE_EMPTY_VIEW
- else if (g_strcmp0 (id, NAUTILUS_EMPTY_VIEW_ID) == 0) {
- view = nautilus_empty_view_new (slot);
- }
-#endif
-
- if (view == NULL) {
- g_critical ("Unknown view type ID: %s", id);
- } else if (g_object_is_floating (view)) {
- g_object_ref_sink (view);
- }
-
- return view;
-}
diff --git a/src/nautilus-view.h b/src/nautilus-view.h
deleted file mode 100644
index 263eec97e..000000000
--- a/src/nautilus-view.h
+++ /dev/null
@@ -1,401 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* nautilus-view.h
- *
- * Copyright (C) 1999, 2000 Free Software Foundaton
- * Copyright (C) 2000, 2001 Eazel, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Ettore Perazzoli
- * Darin Adler <darin@bentspoon.com>
- * John Sullivan <sullivan@eazel.com>
- * Pavel Cisler <pavel@eazel.com>
- */
-
-#ifndef NAUTILUS_VIEW_H
-#define NAUTILUS_VIEW_H
-
-#include <gtk/gtk.h>
-#include <gio/gio.h>
-
-#include <libnautilus-private/nautilus-directory.h>
-#include <libnautilus-private/nautilus-file.h>
-#include <libnautilus-private/nautilus-link.h>
-
-typedef struct NautilusView NautilusView;
-typedef struct NautilusViewClass NautilusViewClass;
-
-#include "nautilus-window.h"
-#include "nautilus-window-slot.h"
-
-#if ENABLE_EMPTY_VIEW
-#define NAUTILUS_EMPTY_VIEW_ID "OAFIID:Nautilus_File_Manager_Empty_View"
-#endif
-
-#define NAUTILUS_CANVAS_VIEW_ID "OAFIID:Nautilus_File_Manager_Canvas_View"
-#define NAUTILUS_DESKTOP_CANVAS_VIEW_ID "OAFIID:Nautilus_File_Manager_Desktop_Canvas_View"
-#define NAUTILUS_LIST_VIEW_ID "OAFIID:Nautilus_File_Manager_List_View"
-
-#define NAUTILUS_TYPE_VIEW nautilus_view_get_type()
-#define NAUTILUS_VIEW(obj)\
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_VIEW, NautilusView))
-#define NAUTILUS_VIEW_CLASS(klass)\
- (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_VIEW, NautilusViewClass))
-#define NAUTILUS_IS_VIEW(obj)\
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_VIEW))
-#define NAUTILUS_IS_VIEW_CLASS(klass)\
- (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_VIEW))
-#define NAUTILUS_VIEW_GET_CLASS(obj)\
- (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_VIEW, NautilusViewClass))
-
-typedef struct NautilusViewDetails NautilusViewDetails;
-
-struct NautilusView {
- GtkOverlay parent;
-
- NautilusViewDetails *details;
-};
-
-struct NautilusViewClass {
- GtkOverlayClass parent_class;
-
- /* The 'clear' signal is emitted to empty the view of its contents.
- * It must be replaced by each subclass.
- */
- void (* clear) (NautilusView *view);
-
- /* The 'begin_file_changes' signal is emitted before a set of files
- * are added to the view. It can be replaced by a subclass to do any
- * necessary preparation for a set of new files. The default
- * implementation does nothing.
- */
- void (* begin_file_changes) (NautilusView *view);
-
- /* The 'add_file' signal is emitted to add one file to the view.
- * It must be replaced by each subclass.
- */
- void (* add_file) (NautilusView *view,
- NautilusFile *file,
- NautilusDirectory *directory);
- void (* remove_file) (NautilusView *view,
- NautilusFile *file,
- NautilusDirectory *directory);
-
- /* The 'file_changed' signal is emitted to signal a change in a file,
- * including the file being removed.
- * It must be replaced by each subclass.
- */
- void (* file_changed) (NautilusView *view,
- NautilusFile *file,
- NautilusDirectory *directory);
-
- /* The 'end_file_changes' signal is emitted after a set of files
- * are added to the view. It can be replaced by a subclass to do any
- * necessary cleanup (typically, cleanup for code in begin_file_changes).
- * The default implementation does nothing.
- */
- void (* end_file_changes) (NautilusView *view);
-
- /* The 'begin_loading' signal is emitted before any of the contents
- * of a directory are added to the view. It can be replaced by a
- * subclass to do any necessary preparation to start dealing with a
- * new directory. The default implementation does nothing.
- */
- void (* begin_loading) (NautilusView *view);
-
- /* The 'end_loading' signal is emitted after all of the contents
- * of a directory are added to the view. It can be replaced by a
- * subclass to do any necessary clean-up. The default implementation
- * does nothing.
- *
- * If all_files_seen is true, the handler may assume that
- * no load error ocurred, and all files of the underlying
- * directory were loaded.
- *
- * Otherwise, end_loading was emitted due to cancellation,
- * which usually means that not all files are available.
- */
- void (* end_loading) (NautilusView *view,
- gboolean all_files_seen);
-
- /* Function pointers that don't have corresponding signals */
-
- /* get_backing uri is a function pointer for subclasses to
- * override. Subclasses may replace it with a function that
- * returns the URI for the location where to create new folders,
- * files, links and paste the clipboard to.
- */
-
- char * (* get_backing_uri) (NautilusView *view);
-
- /* get_selection is not a signal; it is just a function pointer for
- * subclasses to replace (override). Subclasses must replace it
- * with a function that returns a newly-allocated GList of
- * NautilusFile pointers.
- */
- GList * (* get_selection) (NautilusView *view);
-
- /* get_selection_for_file_transfer is a function pointer for
- * subclasses to replace (override). Subclasses must replace it
- * with a function that returns a newly-allocated GList of
- * NautilusFile pointers. The difference from get_selection is
- * that any files in the selection that also has a parent folder
- * in the selection is not included.
- */
- GList * (* get_selection_for_file_transfer)(NautilusView *view);
-
- /* select_all is a function pointer that subclasses must override to
- * select all of the items in the view */
- void (* select_all) (NautilusView *view);
-
- /* select_first is a function pointer that subclasses must override to
- * select the first item in the view */
- void (* select_first) (NautilusView *view);
-
- /* set_selection is a function pointer that subclasses must
- * override to select the specified items (and unselect all
- * others). The argument is a list of NautilusFiles. */
-
- void (* set_selection) (NautilusView *view,
- GList *selection);
-
- /* invert_selection is a function pointer that subclasses must
- * override to invert selection. */
-
- void (* invert_selection) (NautilusView *view);
-
- /* Return an array of locations of selected icons in their view. */
- GArray * (* get_selected_icon_locations) (NautilusView *view);
-
- /* bump_zoom_level is a function pointer that subclasses must override
- * to change the zoom level of an object. */
- void (* bump_zoom_level) (NautilusView *view,
- int zoom_increment);
-
- /* restore_default_zoom_level is a function pointer that subclasses must override
- * to restore the zoom level of an object to a default setting. */
- void (* restore_default_zoom_level) (NautilusView *view);
-
- /* can_zoom_in is a function pointer that subclasses must override to
- * return whether the view is at maximum size (furthest-in zoom level) */
- gboolean (* can_zoom_in) (NautilusView *view);
-
- /* can_zoom_out is a function pointer that subclasses must override to
- * return whether the view is at minimum size (furthest-out zoom level) */
- gboolean (* can_zoom_out) (NautilusView *view);
-
- /* reveal_selection is a function pointer that subclasses may
- * override to make sure the selected items are sufficiently
- * apparent to the user (e.g., scrolled into view). By default,
- * this does nothing.
- */
- void (* reveal_selection) (NautilusView *view);
-
- /* merge_menus is a function pointer that subclasses can override to
- * add their own menu items to the window's menu bar.
- * If overridden, subclasses must call parent class's function.
- */
- void (* merge_menus) (NautilusView *view);
- void (* unmerge_menus) (NautilusView *view);
-
- /* update_menus is a function pointer that subclasses can override to
- * update the sensitivity or wording of menu items in the menu bar.
- * It is called (at least) whenever the selection changes. If overridden,
- * subclasses must call parent class's function.
- */
- void (* update_context_menus) (NautilusView *view);
-
- void (* update_actions_state) (NautilusView *view);
-
- /* sort_files is a function pointer that subclasses can override
- * to provide a sorting order to determine which files should be
- * presented when only a partial list is provided.
- */
- int (* compare_files) (NautilusView *view,
- NautilusFile *a,
- NautilusFile *b);
-
- /* using_manual_layout is a function pointer that subclasses may
- * override to control whether or not items can be freely positioned
- * on the user-visible area.
- * Note that this value is not guaranteed to be constant within the
- * view's lifecycle. */
- gboolean (* using_manual_layout) (NautilusView *view);
-
- /* is_read_only is a function pointer that subclasses may
- * override to control whether or not the user is allowed to
- * change the contents of the currently viewed directory. The
- * default implementation checks the permissions of the
- * directory.
- */
- gboolean (* is_read_only) (NautilusView *view);
-
- /* is_empty is a function pointer that subclasses must
- * override to report whether the view contains any items.
- */
- gboolean (* is_empty) (NautilusView *view);
-
- gboolean (* can_rename_file) (NautilusView *view,
- NautilusFile *file);
-
- /* convert *point from widget's coordinate system to a coordinate
- * system used for specifying file operation positions, which is view-specific.
- *
- * This is used by the the icon view, which converts the screen position to a zoom
- * level-independent coordinate system.
- */
- void (* widget_to_file_operation_position) (NautilusView *view,
- GdkPoint *position);
-
- /* Preference change callbacks, overriden by icon and list views.
- * Icon and list views respond by synchronizing to the new preference
- * values and forcing an update if appropriate.
- */
- void (* click_policy_changed) (NautilusView *view);
- void (* sort_directories_first_changed) (NautilusView *view);
-
- /* Get the id string for this view. Its a constant string, not memory managed */
- const char * (* get_view_id) (NautilusView *view);
-
- /* Return the uri of the first visible file */
- char * (* get_first_visible_file) (NautilusView *view);
- /* Scroll the view so that the file specified by the uri is at the top
- of the view */
- void (* scroll_to_file) (NautilusView *view,
- const char *uri);
-
- NautilusWindow * (*get_window) (NautilusView *view);
-
- GdkRectangle * (*compute_rename_popover_relative_to) (NautilusView *view);
-
- GIcon * (* get_icon) (NautilusView *view);
-};
-
-/* GObject support */
-GType nautilus_view_get_type (void);
-
-NautilusView * nautilus_view_new (const gchar *id,
- NautilusWindowSlot *slot);
-
-/* Functions callable from the user interface and elsewhere. */
-NautilusWindowSlot *nautilus_view_get_nautilus_window_slot (NautilusView *view);
-char * nautilus_view_get_uri (NautilusView *view);
-
-void nautilus_view_display_selection_info (NautilusView *view);
-
-GdkAtom nautilus_view_get_copied_files_atom (NautilusView *view);
-
-/* Wrappers for signal emitters. These are normally called
- * only by NautilusView itself. They have corresponding signals
- * that observers might want to connect with.
- */
-gboolean nautilus_view_get_loading (NautilusView *view);
-
-/* Hooks for subclasses to call. These are normally called only by
- * NautilusView and its subclasses
- */
-void nautilus_view_activate_files (NautilusView *view,
- GList *files,
- NautilusWindowOpenFlags flags,
- gboolean confirm_multiple);
-void nautilus_view_preview_files (NautilusView *view,
- GList *files,
- GArray *locations);
-void nautilus_view_start_batching_selection_changes (NautilusView *view);
-void nautilus_view_stop_batching_selection_changes (NautilusView *view);
-void nautilus_view_notify_selection_changed (NautilusView *view);
-NautilusDirectory *nautilus_view_get_model (NautilusView *view);
-NautilusFile *nautilus_view_get_directory_as_file (NautilusView *view);
-void nautilus_view_pop_up_background_context_menu (NautilusView *view,
- GdkEventButton *event);
-void nautilus_view_pop_up_selection_context_menu (NautilusView *view,
- GdkEventButton *event);
-gboolean nautilus_view_should_show_file (NautilusView *view,
- NautilusFile *file);
-gboolean nautilus_view_should_sort_directories_first (NautilusView *view);
-void nautilus_view_ignore_hidden_file_preferences (NautilusView *view);
-void nautilus_view_set_show_foreign (NautilusView *view,
- gboolean show_foreign);
-gboolean nautilus_view_handle_scroll_event (NautilusView *view,
- GdkEventScroll *event);
-
-void nautilus_view_add_subdirectory (NautilusView *view,
- NautilusDirectory*directory);
-void nautilus_view_remove_subdirectory (NautilusView *view,
- NautilusDirectory*directory);
-
-gboolean nautilus_view_is_editable (NautilusView *view);
-NautilusWindow * nautilus_view_get_window (NautilusView *view);
-
-/* NautilusView methods */
-const char * nautilus_view_get_view_id (NautilusView *view);
-
-/* file operations */
-char * nautilus_view_get_backing_uri (NautilusView *view);
-void nautilus_view_move_copy_items (NautilusView *view,
- const GList *item_uris,
- GArray *relative_item_points,
- const char *target_uri,
- int copy_action,
- int x,
- int y);
-void nautilus_view_new_file_with_initial_contents (NautilusView *view,
- const char *parent_uri,
- const char *filename,
- const char *initial_contents,
- int length,
- GdkPoint *pos);
-
-/* selection handling */
-void nautilus_view_activate_selection (NautilusView *view);
-int nautilus_view_get_selection_count (NautilusView *view);
-GList * nautilus_view_get_selection (NautilusView *view);
-void nautilus_view_set_selection (NautilusView *view,
- GList *selection);
-
-
-void nautilus_view_load_location (NautilusView *view,
- GFile *location);
-void nautilus_view_stop_loading (NautilusView *view);
-
-char * nautilus_view_get_first_visible_file (NautilusView *view);
-void nautilus_view_scroll_to_file (NautilusView *view,
- const char *uri);
-char * nautilus_view_get_title (NautilusView *view);
-gboolean nautilus_view_supports_zooming (NautilusView *view);
-void nautilus_view_bump_zoom_level (NautilusView *view,
- int zoom_increment);
-void nautilus_view_zoom_to_level (NautilusView *view,
- gint level);
-void nautilus_view_restore_default_zoom_level (NautilusView *view);
-gboolean nautilus_view_can_zoom_in (NautilusView *view);
-gboolean nautilus_view_can_zoom_out (NautilusView *view);
-void nautilus_view_update_menus (NautilusView *view);
-
-void nautilus_view_update_context_menus (NautilusView *view);
-void nautilus_view_update_toolbar_menus (NautilusView *view);
-void nautilus_view_update_actions_state (NautilusView *view);
-
-void nautilus_view_action_show_hidden_files (NautilusView *view,
- gboolean show_hidden);
-
-GActionGroup * nautilus_view_get_action_group (NautilusView *view);
-GtkWidget* nautilus_view_get_content_widget (NautilusView *view);
-gboolean nautilus_view_is_search (NautilusView *view);
-
-GIcon* nautilus_view_get_icon (NautilusView *view);
-
-GtkWidget* nautilus_view_get_view_widget (NautilusView *view);
-
-#endif /* NAUTILUS_VIEW_H */
diff --git a/src/nautilus-window-slot-dnd.c b/src/nautilus-window-slot-dnd.c
index 548515cda..71386b140 100644
--- a/src/nautilus-window-slot-dnd.c
+++ b/src/nautilus-window-slot-dnd.c
@@ -26,7 +26,7 @@
#include <config.h>
#include "nautilus-notebook.h"
-#include "nautilus-view-dnd.h"
+#include "nautilus-files-view-dnd.h"
#include "nautilus-window-slot-dnd.h"
typedef struct {
@@ -331,7 +331,7 @@ slot_proxy_handle_drop (GtkWidget *widget,
{
GtkWidget *window;
NautilusWindowSlot *target_slot;
- NautilusView *target_view;
+ NautilusFilesView *target_view;
char *target_uri;
GList *uri_list;
@@ -368,18 +368,18 @@ slot_proxy_handle_drop (GtkWidget *widget,
uri_list = nautilus_drag_uri_list_from_selection_list (drag_info->data.selection_list);
g_assert (uri_list != NULL);
- nautilus_view_drop_proxy_received_uris (target_view,
+ nautilus_files_view_drop_proxy_received_uris (target_view,
uri_list,
target_uri,
gdk_drag_context_get_selected_action (context));
g_list_free_full (uri_list, g_free);
} else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST) {
- nautilus_view_drop_proxy_received_uris (target_view,
+ nautilus_files_view_drop_proxy_received_uris (target_view,
drag_info->data.uri_list,
target_uri,
gdk_drag_context_get_selected_action (context));
} if (drag_info->info == NAUTILUS_ICON_DND_NETSCAPE_URL) {
- nautilus_view_handle_netscape_url_drop (target_view,
+ nautilus_files_view_handle_netscape_url_drop (target_view,
drag_info->data.netscape_url,
target_uri,
gdk_drag_context_get_selected_action (context),
diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c
index 0c5e3934e..9791cfc31 100644
--- a/src/nautilus-window-slot.c
+++ b/src/nautilus-window-slot.c
@@ -74,8 +74,8 @@ struct NautilusWindowSlotDetails {
gchar *title;
/* Viewed file */
- NautilusView *content_view;
- NautilusView *new_content_view;
+ NautilusFilesView *content_view;
+ NautilusFilesView *new_content_view;
NautilusFile *viewed_file;
gboolean viewed_file_seen;
gboolean viewed_file_in_trash;
@@ -137,7 +137,7 @@ nautilus_window_slot_sync_search_widgets (NautilusWindowSlot *slot)
nautilus_window_slot_set_search_visible (slot,
slot->details->search_visible ||
(slot->details->content_view &&
- nautilus_view_is_search (slot->details->content_view)));
+ nautilus_files_view_is_search (slot->details->content_view)));
}
static gboolean
@@ -147,7 +147,7 @@ nautilus_window_slot_content_view_matches_iid (NautilusWindowSlot *slot,
if (slot->details->content_view == NULL) {
return FALSE;
}
- return g_strcmp0 (nautilus_view_get_view_id (slot->details->content_view), iid) == 0;
+ return g_strcmp0 (nautilus_files_view_get_view_id (slot->details->content_view), iid) == 0;
}
void
@@ -244,7 +244,7 @@ query_editor_activated_callback (NautilusQueryEditor *editor,
NautilusWindowSlot *slot)
{
if (slot->details->content_view != NULL) {
- nautilus_view_activate_selection (slot->details->content_view);
+ nautilus_files_view_activate_selection (slot->details->content_view);
}
}
@@ -741,7 +741,7 @@ nautilus_window_slot_open_location_full (NautilusWindowSlot *slot,
old_selection = NULL;
if (slot->details->content_view != NULL) {
- old_selection = nautilus_view_get_selection (slot->details->content_view);
+ old_selection = nautilus_files_view_get_selection (slot->details->content_view);
}
if (target_window == window && target_slot == slot && !is_desktop &&
@@ -834,7 +834,7 @@ begin_location_change (NautilusWindowSlot *slot,
/* We are going to change the location, so make sure we stop any loading
* or searching of the previous view, so we avoid to be slow */
if (slot->details->content_view) {
- nautilus_view_stop_loading (slot->details->content_view);
+ nautilus_files_view_stop_loading (slot->details->content_view);
}
/* If there is no new selection and the new location is
@@ -905,7 +905,7 @@ begin_location_change (NautilusWindowSlot *slot,
/* Set current_bookmark scroll pos */
if (slot->details->current_location_bookmark != NULL &&
slot->details->content_view != NULL) {
- current_pos = nautilus_view_get_first_visible_file (slot->details->content_view);
+ current_pos = nautilus_files_view_get_first_visible_file (slot->details->content_view);
nautilus_bookmark_set_scroll_pos (slot->details->current_location_bookmark, current_pos);
g_free (current_pos);
}
@@ -1213,7 +1213,7 @@ got_file_info_for_view_selection_callback (NautilusFile *file,
* so the view mode of the current view will be the one search is using,
* which is not the one we are interested in */
if (slot->details->view_mode_before_search == NULL) {
- slot->details->view_mode_before_search = g_strdup (nautilus_view_get_view_id (slot->details->content_view));
+ slot->details->view_mode_before_search = g_strdup (nautilus_files_view_get_view_id (slot->details->content_view));
}
view_id = g_strdup (NAUTILUS_LIST_VIEW_IID);
} else {
@@ -1231,7 +1231,7 @@ got_file_info_for_view_selection_callback (NautilusFile *file,
g_free (slot->details->view_mode_before_search);
slot->details->view_mode_before_search = NULL;
} else {
- view_id = g_strdup (nautilus_view_get_view_id (slot->details->content_view));
+ view_id = g_strdup (nautilus_files_view_get_view_id (slot->details->content_view));
}
}
@@ -1340,7 +1340,7 @@ create_content_view (NautilusWindowSlot *slot,
GError **error_out)
{
NautilusWindow *window;
- NautilusView *view;
+ NautilusFilesView *view;
GList *selection;
gboolean ret = TRUE;
GError *error = NULL;
@@ -1371,7 +1371,7 @@ create_content_view (NautilusWindowSlot *slot,
g_object_ref (view);
} else {
/* create a new content view */
- view = nautilus_view_new (view_id, slot);
+ view = nautilus_files_view_new (view_id, slot);
slot->details->new_content_view = view;
}
@@ -1400,7 +1400,7 @@ create_content_view (NautilusWindowSlot *slot,
slot->details->load_with_search = FALSE;
if (slot->details->pending_selection == NULL) {
- slot->details->pending_selection = nautilus_view_get_selection (slot->details->content_view);
+ slot->details->pending_selection = nautilus_files_view_get_selection (slot->details->content_view);
}
}
@@ -1416,7 +1416,7 @@ create_content_view (NautilusWindowSlot *slot,
g_list_free_full (slot->details->pending_selection, g_object_unref);
slot->details->pending_selection = NULL;
} else if (old_location != NULL) {
- selection = nautilus_view_get_selection (slot->details->content_view);
+ selection = nautilus_files_view_get_selection (slot->details->content_view);
load_new_location (slot,
old_location,
selection,
@@ -1448,7 +1448,7 @@ load_new_location (NautilusWindowSlot *slot,
gboolean tell_new_content_view)
{
GList *selection_copy;
- NautilusView *view;
+ NautilusFilesView *view;
g_assert (slot != NULL);
g_assert (location != NULL);
@@ -1460,19 +1460,19 @@ load_new_location (NautilusWindowSlot *slot,
/* Note, these may recurse into report_load_underway */
if (slot->details->content_view != NULL && tell_current_content_view) {
view = slot->details->content_view;
- nautilus_view_load_location (slot->details->content_view, location);
+ nautilus_files_view_load_location (slot->details->content_view, location);
}
if (slot->details->new_content_view != NULL && tell_new_content_view &&
(!tell_current_content_view ||
slot->details->new_content_view != slot->details->content_view) ) {
view = slot->details->new_content_view;
- nautilus_view_load_location (slot->details->new_content_view, location);
+ nautilus_files_view_load_location (slot->details->new_content_view, location);
}
if (view != NULL) {
/* new_content_view might have changed here if
report_load_underway was called from load_location */
- nautilus_view_set_selection (view, selection_copy);
+ nautilus_files_view_set_selection (view, selection_copy);
}
g_list_free_full (selection_copy, g_object_unref);
@@ -1542,7 +1542,7 @@ cancel_location_change (NautilusWindowSlot *slot)
directory = nautilus_directory_get (slot->details->location);
/* Stops current loading or search if any, so we are not slow */
- nautilus_view_stop_loading (slot->details->content_view);
+ nautilus_files_view_stop_loading (slot->details->content_view);
nautilus_directory_unref (directory);
if (slot->details->pending_location != NULL
@@ -1554,7 +1554,7 @@ cancel_location_change (NautilusWindowSlot *slot)
* be told, or it is the very pending change we wish
* to cancel.
*/
- selection = nautilus_view_get_selection (slot->details->content_view);
+ selection = nautilus_files_view_get_selection (slot->details->content_view);
load_new_location (slot,
location,
selection,
@@ -1654,10 +1654,10 @@ nautilus_window_slot_set_content_view (NautilusWindowSlot *slot,
nautilus_window_slot_set_allow_stop (slot, TRUE);
- if (nautilus_view_get_selection_count (slot->details->content_view) == 0) {
+ if (nautilus_files_view_get_selection_count (slot->details->content_view) == 0) {
/* If there is no selection, queue a scroll to the same icon that
* is currently visible */
- slot->details->pending_scroll_to = nautilus_view_get_first_visible_file (slot->details->content_view);
+ slot->details->pending_scroll_to = nautilus_files_view_get_first_visible_file (slot->details->content_view);
}
slot->details->location_change_type = NAUTILUS_LOCATION_CHANGE_RELOAD;
@@ -1740,8 +1740,8 @@ nautilus_window_slot_force_reload (NautilusWindowSlot *slot)
current_pos = NULL;
selection = NULL;
if (slot->details->content_view != NULL) {
- current_pos = nautilus_view_get_first_visible_file (slot->details->content_view);
- selection = nautilus_view_get_selection (slot->details->content_view);
+ current_pos = nautilus_files_view_get_first_visible_file (slot->details->content_view);
+ selection = nautilus_files_view_get_selection (slot->details->content_view);
}
begin_location_change
(slot, location, location, selection,
@@ -1763,7 +1763,7 @@ nautilus_window_slot_queue_reload (NautilusWindowSlot *slot)
if (slot->details->pending_location != NULL
|| slot->details->content_view == NULL
- || nautilus_view_get_loading (slot->details->content_view)) {
+ || nautilus_files_view_get_loading (slot->details->content_view)) {
/* there is a reload in flight */
slot->details->needs_reload = TRUE;
return;
@@ -2038,7 +2038,7 @@ static void
nautilus_window_slot_show_trash_bar (NautilusWindowSlot *slot)
{
GtkWidget *bar;
- NautilusView *view;
+ NautilusFilesView *view;
view = nautilus_window_slot_get_current_view (slot);
bar = nautilus_trash_bar_new (view);
@@ -2129,7 +2129,7 @@ nautilus_window_slot_update_for_new_location (NautilusWindowSlot *slot)
}
static void
-view_end_loading_cb (NautilusView *view,
+view_end_loading_cb (NautilusFilesView *view,
gboolean all_files_seen,
NautilusWindowSlot *slot)
{
@@ -2137,7 +2137,7 @@ view_end_loading_cb (NautilusView *view,
* Don't handle it if its from an old view we've switched from */
if (view == slot->details->content_view && all_files_seen) {
if (slot->details->pending_scroll_to != NULL) {
- nautilus_view_scroll_to_file (slot->details->content_view,
+ nautilus_files_view_scroll_to_file (slot->details->content_view,
slot->details->pending_scroll_to);
}
end_location_change (slot);
@@ -2152,7 +2152,7 @@ view_end_loading_cb (NautilusView *view,
}
static void
-view_begin_loading_cb (NautilusView *view,
+view_begin_loading_cb (NautilusFilesView *view,
NautilusWindowSlot *slot)
{
nautilus_profile_start (NULL);
@@ -2522,7 +2522,7 @@ nautilus_window_slot_set_window (NautilusWindowSlot *slot,
}
}
-NautilusView *
+NautilusFilesView *
nautilus_window_slot_get_view (NautilusWindowSlot *slot)
{
return slot->details->content_view;
@@ -2606,7 +2606,7 @@ nautilus_window_slot_get_current_uri (NautilusWindowSlot *slot)
return NULL;
}
-NautilusView *
+NautilusFilesView *
nautilus_window_slot_get_current_view (NautilusWindowSlot *slot)
{
if (slot->details->content_view != NULL) {
@@ -2685,23 +2685,23 @@ nautilus_window_slot_new (NautilusWindow *window)
GIcon*
nautilus_window_slot_get_icon (NautilusWindowSlot *slot)
{
- NautilusView *view;
+ NautilusFilesView *view;
g_return_val_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot), NULL);
view = nautilus_window_slot_get_current_view (slot);
- return view ? nautilus_view_get_icon (view) : NULL;
+ return view ? nautilus_files_view_get_icon (view) : NULL;
}
GtkWidget*
nautilus_window_slot_get_view_widget (NautilusWindowSlot *slot)
{
- NautilusView *view;
+ NautilusFilesView *view;
g_return_val_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot), NULL);
view = nautilus_window_slot_get_current_view (slot);
- return view ? nautilus_view_get_view_widget (view) : NULL;
+ return view ? nautilus_files_view_get_view_widget (view) : NULL;
}
diff --git a/src/nautilus-window-slot.h b/src/nautilus-window-slot.h
index 36d27bc27..fc433fff5 100644
--- a/src/nautilus-window-slot.h
+++ b/src/nautilus-window-slot.h
@@ -29,7 +29,7 @@ typedef struct NautilusWindowSlot NautilusWindowSlot;
typedef struct NautilusWindowSlotClass NautilusWindowSlotClass;
typedef struct NautilusWindowSlotDetails NautilusWindowSlotDetails;
-#include "nautilus-view.h"
+#include "nautilus-files-view.h"
#include "nautilus-window.h"
#define NAUTILUS_TYPE_WINDOW_SLOT (nautilus_window_slot_get_type())
@@ -55,7 +55,7 @@ struct NautilusWindowSlotClass {
};
/* Each NautilusWindowSlot corresponds to a location in the window
- * for displaying a NautilusView, i.e. a tab.
+ * for displaying a NautilusFilesView, i.e. a tab.
*/
struct NautilusWindowSlot {
GtkBox parent;
@@ -87,9 +87,9 @@ char * nautilus_window_slot_get_location_uri (NautilusWindowSlot *slot);
NautilusFile * nautilus_window_slot_get_file (NautilusWindowSlot *slot);
NautilusBookmark *nautilus_window_slot_get_bookmark (NautilusWindowSlot *slot);
-NautilusView * nautilus_window_slot_get_view (NautilusWindowSlot *slot);
+NautilusFilesView * nautilus_window_slot_get_view (NautilusWindowSlot *slot);
-NautilusView * nautilus_window_slot_get_current_view (NautilusWindowSlot *slot);
+NautilusFilesView * nautilus_window_slot_get_current_view (NautilusWindowSlot *slot);
char * nautilus_window_slot_get_current_uri (NautilusWindowSlot *slot);
GList * nautilus_window_slot_get_back_history (NautilusWindowSlot *slot);
diff --git a/src/nautilus-window.h b/src/nautilus-window.h
index 7bb3e2d04..2bffe051e 100644
--- a/src/nautilus-window.h
+++ b/src/nautilus-window.h
@@ -54,7 +54,7 @@ typedef gboolean (* NautilusWindowGoToCallback) (NautilusWindow *window,
GError *error,
gpointer user_data);
-#include "nautilus-view.h"
+#include "nautilus-files-view.h"
#include "nautilus-window-slot.h"
#define NAUTILUS_TYPE_WINDOW nautilus_window_get_type()
diff --git a/src/nautilus.gresource.xml b/src/nautilus.gresource.xml
index c80a529d4..5a3e324e9 100644
--- a/src/nautilus.gresource.xml
+++ b/src/nautilus.gresource.xml
@@ -10,7 +10,7 @@
<file>nautilus-toolbar-action-menu.xml</file>
<file>nautilus-create-folder-dialog.ui</file>
<file>nautilus-rename-file-popover.ui</file>
- <file>nautilus-view-context-menus.xml</file>
+ <file>nautilus-files-view-context-menus.xml</file>
<file>nautilus-progress-info-widget.xml</file>
<file>nautilus-move-to-trash-shortcut-changed.ui</file>
<file>nautilus-window.ui</file>