Commit 338091bd authored by William Jon McCann's avatar William Jon McCann

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
parent 5c06328b
......@@ -5727,11 +5727,207 @@ 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,
......@@ -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);
......
......@@ -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;
......
......@@ -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 *
......
......@@ -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,
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment