Updating branch refs/heads/jannis/new-shortcuts-pane to cf2b167f0cc2cb52e7bc6aa5ca7e821d88f365b0 (commit) from 5fabb32bbedcd2bedbcc3eede6c039a225659937 (commit)
commit cf2b167f0cc2cb52e7bc6aa5ca7e821d88f365b0 Author: Jannis Pohlmann <jannis.pohlm...@codethink.co.uk> Date: Fri Dec 9 19:29:36 2011 +0100 ThunarShortcut: rework internal state tracking, finish DND for files. We'll skip mounting volumes on-demand when performing DND for now. We'll also not wait until resolving is finished because this is tricky. The way it behaves now is consistent with previous versions of thunar: don't accept drops to stuff that is not mounted or resolved yet. thunar/thunar-shortcut.c | 466 +++++++++++++++++++++++++++------------------- 1 files changed, 272 insertions(+), 194 deletions(-) diff --git a/thunar/thunar-shortcut.c b/thunar/thunar-shortcut.c index 12ed3e2..280b636 100644 --- a/thunar/thunar-shortcut.c +++ b/thunar/thunar-shortcut.c @@ -34,6 +34,7 @@ #include <thunar/thunar-browser.h> #include <thunar/thunar-enum-types.h> #include <thunar/thunar-dialogs.h> +#include <thunar/thunar-dnd.h> #include <thunar/thunar-file.h> #include <thunar/thunar-marshal.h> #include <thunar/thunar-preferences.h> @@ -148,6 +149,7 @@ static void thunar_shortcut_button_clicked (ThunarShortcut GtkButton *button); static gboolean thunar_shortcut_matches_types (ThunarShortcut *shortcut, ThunarShortcutType types); +static void thunar_shortcut_update (ThunarShortcut *shortcut); static void thunar_shortcut_location_changed (ThunarShortcut *shortcut); static void thunar_shortcut_file_changed (ThunarShortcut *shortcut); static void thunar_shortcut_shortcut_type_changed (ThunarShortcut *shortcut); @@ -812,6 +814,9 @@ thunar_shortcut_drag_data_received (GtkWidget *widget, guint timestamp) { ThunarShortcut *shortcut = THUNAR_SHORTCUT (widget); + GdkDragAction actions; + GdkDragAction action; + gboolean success = FALSE; _thunar_return_if_fail (THUNAR_IS_SHORTCUT (widget)); _thunar_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); @@ -841,19 +846,45 @@ thunar_shortcut_drag_data_received (GtkWidget *widget, /* make sure we only handle text/uri-list */ if (info == TARGET_TEXT_URI_LIST) { - if (shortcut->drop_file_list != NULL) - g_debug (" have drop files, create bookmarks now"); - else - g_debug (" don't have drop files, abort drag and drop"); - } + if (shortcut->file != NULL) + { + /* determine the drop actions */ + actions = thunar_shortcut_compute_drop_actions (shortcut, context, + &action); + + /* check whether the actions are supported */ + if ((actions & (GDK_ACTION_COPY + | GDK_ACTION_MOVE + | GDK_ACTION_LINK)) != 0) + { + /* if necessary, ask the user what he wants to do */ + if (action == GDK_ACTION_ASK) + { + action = thunar_dnd_ask (widget, + shortcut->file, + shortcut->drop_file_list, + timestamp, + actions); + } + + /* if we have a drop action, perform it now */ + if (action != 0) + { + success = thunar_dnd_perform (widget, + shortcut->file, + shortcut->drop_file_list, + action, + NULL); + } + } + } - /* disable highlighting and release the drag data */ - /* TODO we might have to delay this until the shortcut has been resolved */ - thunar_shortcut_drag_leave (widget, context, timestamp); + /* disable highlighting and release the drag data */ + thunar_shortcut_drag_leave (widget, context, timestamp); - /* tell the peer that we handled the copy */ - /* TODO we might have to delay this until the shortcut has been resolved */ - gtk_drag_finish (context, shortcut->drop_file_list != NULL, FALSE, timestamp); + /* tell the peer that we handled the copy */ + gtk_drag_finish (context, success, FALSE, timestamp); + } } else { @@ -885,7 +916,7 @@ thunar_shortcut_drag_drop (GtkWidget *widget, /* request the drag data from the source and perform the drop */ gtk_drag_get_data (widget, context, target, timestamp); - return TRUE; + return TRUE; } else { @@ -993,16 +1024,15 @@ thunar_shortcut_compute_drop_actions (ThunarShortcut *shortcut, shortcut->drop_file_list, context, suggested_action); - - g_debug (" check whether %s accepts: move %s, copy %s, link %s, ask %s", - thunar_file_get_display_name (shortcut->file), - (actions & GDK_ACTION_MOVE) != 0 ? "yes" : "no", - (actions & GDK_ACTION_COPY) != 0 ? "yes" : "no", - (actions & GDK_ACTION_LINK) != 0 ? "yes" : "no", - (actions & GDK_ACTION_ASK ) != 0 ? "yes" : "no"); } - - /* TODO handle everything else */ + else + { + /* we know nothing about the file, just report back that dropping + * here is impossible */ + actions = 0; + if (suggested_action != NULL) + *suggested_action = 0; + } return actions; } @@ -1292,41 +1322,166 @@ thunar_shortcut_matches_types (ThunarShortcut *shortcut, static void -thunar_shortcut_location_changed (ThunarShortcut *shortcut) +thunar_shortcut_update (ThunarShortcut *shortcut) { - GIcon *icon; - gchar *uri; - gchar *base_name; + const gchar *display_name; + GIcon *icon; + gchar *base_name; + gchar *name; + gchar *uri; _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut)); - /* only update the shortcut if this is a file shortcut */ - if (!thunar_shortcut_matches_types (shortcut, - THUNAR_SHORTCUT_REGULAR_FILE - | THUNAR_SHORTCUT_NETWORK_FILE - | THUNAR_SHORTCUT_TRASH_FILE)) - { - return; - } - - /* check whether we have a location */ - if (shortcut->location != NULL) +#if 0 + thunar_shortcut_update_icon (shortcut); + thunar_shortcut_update_label (shortcut); + thunar_shortcut_update_button (shortcut); +#endif + + switch (shortcut->type) { - /* use the location base name as the default name */ - uri = g_file_get_uri (shortcut->location); - base_name = g_filename_display_basename (uri); - thunar_shortcut_set_name (shortcut, base_name); - g_free (base_name); - g_free (uri); + case THUNAR_SHORTCUT_REGULAR_FILE: + case THUNAR_SHORTCUT_TRASH_FILE: + case THUNAR_SHORTCUT_NETWORK_FILE: + /* hide the action button */ + gtk_widget_set_visible (shortcut->action_button, FALSE); + + if (shortcut->file != NULL) + { + /* update the name of the shortcut */ + display_name = thunar_file_get_display_name (shortcut->file); + thunar_shortcut_set_name (shortcut, display_name); + + /* update the icon of the shortcut */ + icon = thunar_file_get_icon (shortcut->file); + thunar_shortcut_set_icon (shortcut, icon); + } + else if (shortcut->location != NULL) + { + /* use the location base name as the default name */ + uri = g_file_get_uri (shortcut->location); + base_name = g_filename_display_basename (uri); + thunar_shortcut_set_name (shortcut, base_name); + g_free (base_name); + g_free (uri); + + /* use the folder icon as the default icon */ + if (shortcut->icon != NULL) + { + icon = g_themed_icon_new ("folder"); + thunar_shortcut_set_icon (shortcut, icon); + g_object_unref (icon); + } + } + else + { + if (shortcut->constructed) + _thunar_assert_not_reached (); + } + break; + + case THUNAR_SHORTCUT_REGULAR_MOUNT: + case THUNAR_SHORTCUT_ARCHIVE_MOUNT: + case THUNAR_SHORTCUT_NETWORK_MOUNT: + case THUNAR_SHORTCUT_DEVICE_MOUNT: + /* check if we have a proper mount */ + if (shortcut->mount != NULL) + { + /* update the name of the shortcut */ + name = g_mount_get_name (shortcut->mount); + thunar_shortcut_set_name (shortcut, name); + g_free (name); + + /* update the icon of the shortcut */ + icon = g_mount_get_icon (shortcut->mount); + thunar_shortcut_set_icon (shortcut, icon); + g_object_unref (icon); - /* use the folder icon as the default icon */ - if (shortcut->icon == NULL) + /* update the action button */ + if (g_mount_can_unmount (shortcut->mount) + || g_mount_can_eject (shortcut->mount)) + { + gtk_widget_set_visible (shortcut->action_button, TRUE); + } + else + { + gtk_widget_set_visible (shortcut->action_button, FALSE); + } + } + else { - icon = g_themed_icon_new ("folder"); + if (shortcut->constructed) + _thunar_assert_not_reached (); + } + break; + + case THUNAR_SHORTCUT_REGULAR_VOLUME: + case THUNAR_SHORTCUT_EJECTABLE_VOLUME: + /* check if we have a proper volume */ + if (shortcut->volume != NULL) + { + /* update the name of the shortcut */ + name = g_volume_get_name (shortcut->volume); + thunar_shortcut_set_name (shortcut, name); + g_free (name); + + /* update the icon of the shortcut */ + icon = g_volume_get_icon (shortcut->volume); thunar_shortcut_set_icon (shortcut, icon); g_object_unref (icon); + + /* update the action button */ + if (g_volume_can_eject (shortcut->volume)) + { + gtk_widget_set_visible (shortcut->action_button, TRUE); + } + else + { + /* check if we have a mount now */ + if (shortcut->mount != NULL) + { + /* show the disconnect button if the mount is removable */ + if (g_mount_can_unmount (shortcut->mount) + || g_mount_can_eject (shortcut->mount)) + { + gtk_widget_set_visible (shortcut->action_button, TRUE); + } + else + { + gtk_widget_set_visible (shortcut->action_button, FALSE); + } + } + else + { + /* we neither have a removable volume nor a removable mount, + * so hide the disconnect button */ + gtk_widget_set_visible (shortcut->action_button, FALSE); + } + } } + else + { + if (shortcut->constructed) + _thunar_assert_not_reached (); + } + break; + + default: + _thunar_assert_not_reached (); + break; + } +} + + +static void +thunar_shortcut_location_changed (ThunarShortcut *shortcut) +{ + _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut)); + + /* check whether we have a location */ + if (shortcut->location != NULL) + { /* load additional file information asynchronously */ thunar_browser_poke_location (THUNAR_BROWSER (shortcut), shortcut->location, @@ -1334,12 +1489,9 @@ thunar_shortcut_location_changed (ThunarShortcut *shortcut) thunar_shortcut_resolve_location_finish, NULL); } - else - { - /* if this is reached, there is something wrong with the - * shortcut classification */ - _thunar_assert (!shortcut->constructed); - } + + /* update icon, label and action button */ + thunar_shortcut_update (shortcut); } @@ -1347,30 +1499,10 @@ thunar_shortcut_location_changed (ThunarShortcut *shortcut) static void thunar_shortcut_file_changed (ThunarShortcut *shortcut) { - const gchar *display_name; - GIcon *icon; - _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut)); - /* only update the information if this is a file shortcut */ - if (!thunar_shortcut_matches_types (shortcut, - THUNAR_SHORTCUT_REGULAR_FILE - | THUNAR_SHORTCUT_NETWORK_FILE)) - { - return; - } - - /* update only if we have a file */ - if (shortcut->file != NULL) - { - /* update the name of the shortcut */ - display_name = thunar_file_get_display_name (shortcut->file); - thunar_shortcut_set_name (shortcut, display_name); - - /* update the icon of the shortcut */ - icon = thunar_file_get_icon (shortcut->file); - thunar_shortcut_set_icon (shortcut, icon); - } + /* update icon, label and action button */ + thunar_shortcut_update (shortcut); } @@ -1396,65 +1528,21 @@ static void thunar_shortcut_volume_changed (ThunarShortcut *shortcut) { GMount *mount; - GIcon *icon; - gchar *name; _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut)); - /* don't update if this is not a volume */ - if (!thunar_shortcut_matches_types (shortcut, - THUNAR_SHORTCUT_REGULAR_VOLUME - | THUNAR_SHORTCUT_EJECTABLE_VOLUME)) - { - return; - } - /* only update if we have a volume */ if (shortcut->volume != NULL) { - /* update the name of the shortcut */ - name = g_volume_get_name (shortcut->volume); - thunar_shortcut_set_name (shortcut, name); - g_free (name); - - /* update the icon of the shortcut */ - icon = g_volume_get_icon (shortcut->volume); - thunar_shortcut_set_icon (shortcut, icon); - g_object_unref (icon); - - if (g_volume_can_eject (shortcut->volume)) - { - gtk_widget_set_visible (shortcut->action_button, TRUE); - } - else - { - /* check if we have a mount now */ - mount = g_volume_get_mount (shortcut->volume); - if (mount != NULL) - { - /* show the disconnect button if the mount is removable */ - if (g_mount_can_unmount (mount) || g_mount_can_eject (mount)) - gtk_widget_set_visible (shortcut->action_button, TRUE); - else - gtk_widget_set_visible (shortcut->action_button, FALSE); - - /* release the mount */ - g_object_unref (mount); - } - else - { - /* we neither have a removable volume nor a removabl mount, - * so hide the disconnect button */ - gtk_widget_set_visible (shortcut->action_button, FALSE); - } - } - } - else - { - /* if this is reached, there is something wrong the - * shortcut classification */ - _thunar_assert(!shortcut->constructed); + /* set the mount if we have one now */ + mount = g_volume_get_mount (shortcut->volume); + thunar_shortcut_set_mount (shortcut, mount); + if (mount != NULL) + g_object_unref (mount); } + + /* update icon, label and action button */ + thunar_shortcut_update (shortcut); } @@ -1462,46 +1550,21 @@ thunar_shortcut_volume_changed (ThunarShortcut *shortcut) static void thunar_shortcut_mount_changed (ThunarShortcut *shortcut) { - GIcon *icon; - gchar *name; + GFile *mount_point; _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut)); - /* don't update the information if this is not a mount shortcut */ - if (!thunar_shortcut_matches_types (shortcut, - THUNAR_SHORTCUT_REGULAR_MOUNT - | THUNAR_SHORTCUT_ARCHIVE_MOUNT - | THUNAR_SHORTCUT_NETWORK_MOUNT - | THUNAR_SHORTCUT_DEVICE_MOUNT)) - { - return; - } - /* only update if we have a mount */ if (shortcut->mount != NULL) { - /* update the name of the shortcut */ - name = g_mount_get_name (shortcut->mount); - thunar_shortcut_set_name (shortcut, name); - g_free (name); - - /* update the icon of the shortcut */ - icon = g_mount_get_icon (shortcut->mount); - thunar_shortcut_set_icon (shortcut, icon); - g_object_unref (icon); - - /* update the action button */ - if (g_mount_can_unmount (shortcut->mount) || g_mount_can_eject (shortcut->mount)) - gtk_widget_set_visible (shortcut->action_button, TRUE); - else - gtk_widget_set_visible (shortcut->action_button, FALSE); - } - else - { - /* if this is reached, there is something wrong the - * shortcut classification */ - _thunar_assert (!shortcut->constructed); + /* resolve the location */ + mount_point = g_mount_get_root (shortcut->mount); + thunar_shortcut_set_location (shortcut, mount_point); + g_object_unref (mount_point); } + + /* update icon, label and action button */ + thunar_shortcut_update (shortcut); } @@ -1622,7 +1685,13 @@ thunar_shortcut_mount_unmount_finish (GObject *object, /* stop spinning */ thunar_shortcut_set_spinning (shortcut, FALSE, THUNAR_SHORTCUT_STATE_NORMAL); - if (!g_mount_unmount_with_operation_finish (mount, result, &error)) + if (g_mount_unmount_with_operation_finish (mount, result, &error)) + { + /* reset the file information */ + thunar_shortcut_set_location (shortcut, NULL); + thunar_shortcut_set_file (shortcut, NULL); + } + else { name = thunar_shortcut_get_display_name (shortcut); thunar_dialogs_show_error (GTK_WIDGET (shortcut), error, @@ -1650,7 +1719,13 @@ thunar_shortcut_mount_eject_finish (GObject *object, _thunar_return_if_fail (G_IS_MOUNT (mount)); _thunar_return_if_fail (G_IS_ASYNC_RESULT (result)); - if (!g_mount_eject_with_operation_finish (mount, result, &error)) + if (g_mount_eject_with_operation_finish (mount, result, &error)) + { + /* reset the file information */ + thunar_shortcut_set_location (shortcut, NULL); + thunar_shortcut_set_file (shortcut, NULL); + } + else { name = thunar_shortcut_get_display_name (shortcut); thunar_dialogs_show_error (GTK_WIDGET (shortcut), error, @@ -1678,7 +1753,14 @@ thunar_shortcut_volume_eject_finish (GObject *object, /* stop spinning */ thunar_shortcut_set_spinning (shortcut, FALSE, THUNAR_SHORTCUT_STATE_NORMAL); - if (!g_volume_eject_with_operation_finish (volume, result, &error)) + if (g_volume_eject_with_operation_finish (volume, result, &error)) + { + /* reset the mount and file information */ + thunar_shortcut_set_mount (shortcut, NULL); + thunar_shortcut_set_location (shortcut, NULL); + thunar_shortcut_set_file (shortcut, NULL); + } + else { name = thunar_shortcut_get_display_name (shortcut); thunar_dialogs_show_error (GTK_WIDGET (shortcut), error, @@ -1818,11 +1900,24 @@ thunar_shortcut_set_spinning (ThunarShortcut *shortcut, gtk_widget_hide (shortcut->spinner); gtk_widget_hide (shortcut->action_button); - /* assume the mount and volume have changed which will make - * the action button visible again if the volume or mount is - * mounted and can be ejected */ - thunar_shortcut_mount_changed (shortcut); - thunar_shortcut_volume_changed (shortcut); + if (thunar_shortcut_matches_types (shortcut, + THUNAR_SHORTCUT_REGULAR_MOUNT + | THUNAR_SHORTCUT_ARCHIVE_MOUNT + | THUNAR_SHORTCUT_NETWORK_MOUNT + | THUNAR_SHORTCUT_DEVICE_MOUNT)) + { + /* assume the mount has changed which will make the action button + * visible again if the mount can be ejected */ + thunar_shortcut_mount_changed (shortcut); + } + else if (thunar_shortcut_matches_types (shortcut, + THUNAR_SHORTCUT_REGULAR_VOLUME + | THUNAR_SHORTCUT_EJECTABLE_VOLUME)) + { + /* assume the volume has changed which will make the action button + * visible again if the volume can be ejected */ + thunar_shortcut_volume_changed (shortcut); + } } } @@ -2347,16 +2442,7 @@ thunar_shortcut_resolve_and_activate (ThunarShortcut *shortcut, g_cancellable_reset (shortcut->cancellable); } - if (shortcut->volume != NULL) - { - /* activate the spinner */ - thunar_shortcut_set_spinning (shortcut, TRUE, THUNAR_SHORTCUT_STATE_RESOLVING); - - thunar_browser_poke_volume (THUNAR_BROWSER (shortcut), shortcut->volume, - shortcut, thunar_shortcut_poke_volume_finish, - GUINT_TO_POINTER (open_in_new_window)); - } - else if (shortcut->file != NULL) + if (shortcut->file != NULL) { /* activate the spinner */ thunar_shortcut_set_spinning (shortcut, TRUE, THUNAR_SHORTCUT_STATE_RESOLVING); @@ -2374,6 +2460,15 @@ thunar_shortcut_resolve_and_activate (ThunarShortcut *shortcut, shortcut, thunar_shortcut_poke_location_finish, GUINT_TO_POINTER (open_in_new_window)); } + else if (shortcut->volume != NULL) + { + /* activate the spinner */ + thunar_shortcut_set_spinning (shortcut, TRUE, THUNAR_SHORTCUT_STATE_RESOLVING); + + thunar_browser_poke_volume (THUNAR_BROWSER (shortcut), shortcut->volume, + shortcut, thunar_shortcut_poke_volume_finish, + GUINT_TO_POINTER (open_in_new_window)); + } else { _thunar_assert_not_reached (); @@ -2434,8 +2529,6 @@ thunar_shortcut_unmount (ThunarShortcut *shortcut) /* start spinning */ thunar_shortcut_set_spinning (shortcut, TRUE, THUNAR_SHORTCUT_STATE_EJECTING); - g_debug (" unmount now"); - /* try unmounting the mount */ g_mount_unmount_with_operation (shortcut->mount, G_MOUNT_UNMOUNT_NONE, @@ -2447,23 +2540,16 @@ thunar_shortcut_unmount (ThunarShortcut *shortcut) } else if (shortcut->volume != NULL) { - g_debug (" have volume"); mount = g_volume_get_mount (shortcut->volume); if (mount != NULL) { - g_debug (" have mount"); - /* only handle mounts that can be unmounted here */ if (g_mount_can_unmount(mount)) { - g_debug (" can unmount"); - /* start spinning */ thunar_shortcut_set_spinning (shortcut, TRUE, THUNAR_SHORTCUT_STATE_EJECTING); - g_debug (" unmount now"); - /* try unmounting the mount */ g_mount_unmount_with_operation (mount, G_MOUNT_UNMOUNT_NONE, @@ -2499,8 +2585,6 @@ thunar_shortcut_disconnect (ThunarShortcut *shortcut) _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut)); - g_debug ("disconnect shortcut"); - /* check if we are currently mounting/ejecting something */ if (shortcut->state != THUNAR_SHORTCUT_STATE_NORMAL) { @@ -2517,18 +2601,12 @@ thunar_shortcut_disconnect (ThunarShortcut *shortcut) if (shortcut->mount != NULL) { - g_debug (" have mount"); - /* distinguish between ejectable and unmountable mounts */ if (g_mount_can_eject (shortcut->mount)) { - g_debug (" can eject"); - /* start spinning */ thunar_shortcut_set_spinning (shortcut, TRUE, THUNAR_SHORTCUT_STATE_EJECTING); - g_debug (" eject now"); - /* try ejecting the mount */ g_mount_eject_with_operation (shortcut->mount, G_MOUNT_UNMOUNT_NONE, _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org https://mail.xfce.org/mailman/listinfo/xfce4-commits