[nautilus] Add locations for open windows to the destination selection dialog
- From: William Jon McCann <mccann src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus] Add locations for open windows to the destination selection dialog
- Date: Tue, 10 Jul 2012 14:31:02 +0000 (UTC)
commit 338091bd0f28345b822c1d55055673d5ff963bc4
Author: William Jon McCann <jmccann redhat com>
Date: Mon Jul 9 09:35:50 2012 -0400
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
src/nautilus-view.c | 235 ++++++++++++++++++++++++++++++++++--
src/nautilus-window-manage-views.c | 21 +++-
src/nautilus-window-slot.c | 11 ++
src/nautilus-window.c | 29 +++++
src/nautilus-window.h | 1 +
5 files changed, 287 insertions(+), 10 deletions(-)
---
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
index 6679bc8..9142983 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 bbcf1c1..c41a205 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 fcd5365..e815b55 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 c91db78..9cf6e36 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 1f022e8..2578cc8 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,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]