summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWilliam Jon McCann <jmccann@redhat.com>2012-07-09 09:35:50 -0400
committerWilliam Jon McCann <jmccann@redhat.com>2012-07-10 10:30:23 -0400
commit338091bd0f28345b822c1d55055673d5ff963bc4 (patch)
tree589bf7cb8d2904e5efa3d7789f0b6c7f586a56e3 /src
parent5c06328bc1f06a306dc63eca712b46af7018344e (diff)
downloadnautilus-338091bd0f28345b822c1d55055673d5ff963bc4.tar.gz
Add locations for open windows to the destination selection dialog
These locations are identified as interesting by the fact that they are in use and it makes sense to offer them as quick options for explicit copies and moves. https://bugzilla.gnome.org/show_bug.cgi?id=679580
Diffstat (limited to 'src')
-rw-r--r--src/nautilus-view.c235
-rw-r--r--src/nautilus-window-manage-views.c21
-rw-r--r--src/nautilus-window-slot.c11
-rw-r--r--src/nautilus-window.c29
-rw-r--r--src/nautilus-window.h1
5 files changed, 287 insertions, 10 deletions
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
index 6679bc84b..9142983d5 100644
--- a/src/nautilus-view.c
+++ b/src/nautilus-view.c
@@ -5727,12 +5727,208 @@ create_popup_menu (NautilusView *view, const char *popup_path)
}
typedef struct _CopyCallbackData {
- NautilusView *view;
- GList *selection;
- gboolean is_move;
+ 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)
+{
+ GtkApplication *application;
+ GList *windows;
+ GList *w;
+
+ application = gtk_window_get_application (GTK_WINDOW (data->view->details->window));
+ 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 = gtk_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 void
on_destination_dialog_response (GtkDialog *dialog,
gint response_id,
gpointer user_data)
@@ -5760,10 +5956,26 @@ on_destination_dialog_response (GtkDialog *dialog,
g_free (target_uri);
}
- nautilus_file_list_free (copy_data->selection);
- g_free (copy_data);
+ copy_data_free (copy_data);
gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+add_window_location_bookmarks (CopyCallbackData *data)
+{
+ GtkApplication *application;
+ GList *windows;
+ GList *w;
+ application = gtk_window_get_application (GTK_WINDOW (data->view->details->window));
+ windows = gtk_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
@@ -5786,14 +5998,19 @@ copy_or_move_selection (NautilusView *view,
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- uri = nautilus_directory_get_uri (view->details->model);
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), uri);
- g_free (uri);
-
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);
+
+ 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, "response",
G_CALLBACK (on_destination_dialog_response),
copy_data);
diff --git a/src/nautilus-window-manage-views.c b/src/nautilus-window-manage-views.c
index bbcf1c149..c41a2059d 100644
--- a/src/nautilus-window-manage-views.c
+++ b/src/nautilus-window-manage-views.c
@@ -1082,6 +1082,23 @@ nautilus_window_emit_location_change (NautilusWindow *window,
g_free (uri);
}
+static void
+nautilus_window_slot_emit_location_change (NautilusWindowSlot *slot,
+ GFile *from,
+ GFile *to)
+{
+ char *from_uri = NULL;
+ char *to_uri = NULL;
+
+ if (from != NULL)
+ from_uri = g_file_get_uri (from);
+ if (to != NULL)
+ to_uri = g_file_get_uri (to);
+ g_signal_emit_by_name (slot, "location-changed", from_uri, to_uri);
+ g_free (to_uri);
+ g_free (from_uri);
+}
+
/* reports location change to window's "loading-uri" clients, i.e.
* sidebar panels [used when switching tabs]. It will emit the pending
* location, or the existing location if none is pending.
@@ -1344,7 +1361,9 @@ update_for_new_location (NautilusWindowSlot *slot)
location_really_changed =
slot->location == NULL ||
!g_file_equal (slot->location, new_location);
-
+
+ nautilus_window_slot_emit_location_change (slot, slot->location, new_location);
+
/* Set the new location. */
g_clear_object (&slot->location);
slot->location = new_location;
diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c
index fcd536542..e815b559b 100644
--- a/src/nautilus-window-slot.c
+++ b/src/nautilus-window-slot.c
@@ -45,6 +45,7 @@ G_DEFINE_TYPE (NautilusWindowSlot, nautilus_window_slot, GTK_TYPE_BOX);
enum {
ACTIVE,
INACTIVE,
+ LOCATION_CHANGED,
LAST_SIGNAL
};
@@ -302,6 +303,16 @@ nautilus_window_slot_class_init (NautilusWindowSlotClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ signals[LOCATION_CHANGED] =
+ g_signal_new ("location-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
}
GFile *
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
index c91db78ad..9cf6e3647 100644
--- a/src/nautilus-window.c
+++ b/src/nautilus-window.c
@@ -104,6 +104,8 @@ enum {
PROMPT_FOR_LOCATION,
LOADING_URI,
HIDDEN_FILES_MODE_CHANGED,
+ SLOT_ADDED,
+ SLOT_REMOVED,
LAST_SIGNAL
};
@@ -459,6 +461,8 @@ close_slot (NautilusWindow *window,
DEBUG ("Closing slot %p", slot);
+ g_signal_emit (window, signals[SLOT_REMOVED], 0, slot);
+
nautilus_window_manage_views_close_slot (slot);
notebook = GTK_NOTEBOOK (window->details->notebook);
@@ -503,6 +507,7 @@ nautilus_window_open_slot (NautilusWindow *window,
window);
window->details->slots = g_list_append (window->details->slots, slot);
+ g_signal_emit (window, signals[SLOT_ADDED], 0, slot);
return slot;
}
@@ -2152,6 +2157,14 @@ nautilus_window_get_active_slot (NautilusWindow *window)
return window->details->active_slot;
}
+GList *
+nautilus_window_get_slots (NautilusWindow *window)
+{
+ g_assert (NAUTILUS_IS_WINDOW (window));
+
+ return window->details->slots;
+}
+
static void
nautilus_window_reload (NautilusWindow *window)
{
@@ -2361,6 +2374,22 @@ nautilus_window_class_init (NautilusWindowClass *class)
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1,
G_TYPE_STRING);
+ signals[SLOT_ADDED] =
+ g_signal_new ("slot-added",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, NAUTILUS_TYPE_WINDOW_SLOT);
+ signals[SLOT_REMOVED] =
+ g_signal_new ("slot-removed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, NAUTILUS_TYPE_WINDOW_SLOT);
binding_set = gtk_binding_set_by_class (class);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_BackSpace, 0,
diff --git a/src/nautilus-window.h b/src/nautilus-window.h
index 1f022e835..2578cc820 100644
--- a/src/nautilus-window.h
+++ b/src/nautilus-window.h
@@ -131,6 +131,7 @@ void nautilus_window_report_load_underway (NautilusWindow *wind
void nautilus_window_view_visible (NautilusWindow *window,
NautilusView *view);
NautilusWindowSlot * nautilus_window_get_active_slot (NautilusWindow *window);
+GList * nautilus_window_get_slots (NautilusWindow *window);
NautilusWindowSlot * nautilus_window_open_slot (NautilusWindow *window,
NautilusWindowOpenSlotFlags flags);
void nautilus_window_slot_close (NautilusWindow *window,