diff -Naur Thunar-1.4.0_orig/po/en_GB.po Thunar-1.4.0/po/en_GB.po --- Thunar-1.4.0_orig/po/en_GB.po 2012-04-28 23:16:38.000000000 +0300 +++ Thunar-1.4.0/po/en_GB.po 2012-07-24 09:26:30.000000000 +0300 @@ -2001,6 +2001,11 @@ msgid "_Mount Volume" msgstr "_Mount Volume" +#. append the "Unmount Volume" menu action +#: ../thunar/thunar-shortcuts-view.c:861 ../thunar/thunar-tree-view.c:1131 +msgid "_Unmount Volume" +msgstr "_Unmount Volume" + #. append the "Eject Volume" menu action #: ../thunar/thunar-shortcuts-view.c:861 ../thunar/thunar-tree-view.c:1131 msgid "E_ject Volume" diff -Naur Thunar-1.4.0_orig/po/ru.po Thunar-1.4.0/po/ru.po --- Thunar-1.4.0_orig/po/ru.po 2012-04-28 23:16:38.000000000 +0300 +++ Thunar-1.4.0/po/ru.po 2012-07-24 10:13:15.000000000 +0300 @@ -2029,6 +2029,11 @@ msgid "_Mount Volume" msgstr "_Подключить том" +#. append the "Unmount Volume" menu action +#: ../thunar/thunar-shortcuts-view.c:861 ../thunar/thunar-tree-view.c:1131 +msgid "_Unmount Volume" +msgstr "О_тключить том" + #. append the "Eject Volume" menu action #: ../thunar/thunar-shortcuts-view.c:861 ../thunar/thunar-tree-view.c:1131 msgid "E_ject Volume" @@ -3664,9 +3669,6 @@ #~ "Соберите thunar-vfs с поддержкой HAL для поддержки управления томами в " #~ "Thunar." -#~ msgid "_Unmount Volume" -#~ msgstr "О_тключить том" - #~ msgid "Failed to unmount \"%s\"" #~ msgstr "Не удалось отключить \"%s\"" diff -Naur Thunar-1.4.0_orig/thunar/thunar-gio-extensions.c Thunar-1.4.0/thunar/thunar-gio-extensions.c --- Thunar-1.4.0_orig/thunar/thunar-gio-extensions.c 2012-04-28 23:16:39.000000000 +0300 +++ Thunar-1.4.0/thunar/thunar-gio-extensions.c 2012-07-24 09:31:21.000000000 +0300 @@ -511,7 +511,30 @@ return (!is_internal) && (can_eject || can_unmount || is_removable || can_mount); } +gboolean +thunar_g_volume_is_unmountable (GVolume *volume) +{ + gboolean can_unmount = FALSE; + gboolean is_internal = FALSE; + GMount *mount; + + /* determine the mount for the volume (if it is mounted at all) */ + mount = g_volume_get_mount (volume); + if (mount != NULL) + { +#ifdef HAVE_GIO_UNIX + is_internal = thunar_g_mount_is_internal (mount); +#endif + + /* check if the volume can be unmounted */ + can_unmount = g_mount_can_unmount (mount); + /* release the mount */ + g_object_unref (mount); + } + + return can_unmount; +} gboolean thunar_g_volume_is_mounted (GVolume *volume) diff -Naur Thunar-1.4.0_orig/thunar/thunar-gio-extensions.h Thunar-1.4.0/thunar/thunar-gio-extensions.h --- Thunar-1.4.0_orig/thunar/thunar-gio-extensions.h 2012-04-28 23:16:39.000000000 +0300 +++ Thunar-1.4.0/thunar/thunar-gio-extensions.h 2012-07-24 09:32:22.000000000 +0300 @@ -68,6 +68,7 @@ void thunar_g_file_list_free (GList *list); gboolean thunar_g_volume_is_removable (GVolume *volume); +gboolean thunar_g_volume_is_unmountable (GVolume *volume); gboolean thunar_g_volume_is_mounted (GVolume *volume); gboolean thunar_g_volume_is_present (GVolume *volume); diff -Naur Thunar-1.4.0_orig/thunar/thunar-shortcuts-view.c Thunar-1.4.0/thunar/thunar-shortcuts-view.c --- Thunar-1.4.0_orig/thunar/thunar-shortcuts-view.c 2012-04-28 23:16:39.000000000 +0300 +++ Thunar-1.4.0/thunar/thunar-shortcuts-view.c 2012-07-24 10:27:14.000000000 +0300 @@ -125,6 +125,7 @@ static void thunar_shortcuts_view_open_in_new_window_clicked (ThunarShortcutsView *view); static void thunar_shortcuts_view_empty_trash (ThunarShortcutsView *view); static void thunar_shortcuts_view_eject (ThunarShortcutsView *view); +static void thunar_shortcuts_view_unmount (ThunarShortcutsView *view); static void thunar_shortcuts_view_mount (ThunarShortcutsView *view); static gboolean thunar_shortcuts_view_separator_func (GtkTreeModel *model, GtkTreeIter *iter, @@ -857,6 +858,15 @@ /* check if the volume is present and can be ejected */ if (thunar_g_volume_is_present (volume) && thunar_g_volume_is_removable (volume)) { + /* append the "Unmount Volume" menu action */ + if (thunar_g_volume_is_unmountable (volume)) + { + item = gtk_image_menu_item_new_with_mnemonic (_("_Unmount Volume")); + g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_unmount), view); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); + } + /* append the "Eject Volume" menu action */ item = gtk_image_menu_item_new_with_mnemonic (_("E_ject Volume")); g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_eject), view); @@ -1466,6 +1476,57 @@ } + +static void +thunar_shortcuts_view_unmount (ThunarShortcutsView *view) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + GVolume *volume; + GMount *mount; + GMountOperation *mount_operation; + GtkWidget *window; + + _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view)); + + /* determine the selected item */ + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + /* determine the volume for the shortcut at the given tree iterator */ + gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, -1); + if (G_UNLIKELY (volume != NULL)) + { + /* prepare a mount operation */ + window = gtk_widget_get_toplevel (GTK_WIDGET (view)); + mount_operation = gtk_mount_operation_new (GTK_WINDOW (window)); + + /* determine the mount of the volume */ + mount = g_volume_get_mount (volume); + if (G_LIKELY (mount != NULL)) + { +#ifdef HAVE_LIBNOTIFY + thunar_notify_unmount (mount); +#endif + + /* the volume is mounted, try to unmount the mount */ + g_mount_unmount_with_operation (mount, G_MOUNT_UNMOUNT_NONE, mount_operation, NULL, + thunar_shortcuts_view_unmount_finish, + g_object_ref (view)); + + /* release the mount */ + g_object_unref (mount); + } + + /* cleanup */ + g_object_unref (volume); + g_object_unref (mount_operation); + } + } +} + + static void thunar_shortcuts_view_eject (ThunarShortcutsView *view) diff -Naur Thunar-1.4.0_orig/thunar/thunar-tree-view.c Thunar-1.4.0/thunar/thunar-tree-view.c --- Thunar-1.4.0_orig/thunar/thunar-tree-view.c 2012-04-28 23:16:39.000000000 +0300 +++ Thunar-1.4.0/thunar/thunar-tree-view.c 2012-07-24 10:32:56.000000000 +0300 @@ -150,6 +150,7 @@ static void thunar_tree_view_action_cut (ThunarTreeView *view); static void thunar_tree_view_action_delete (ThunarTreeView *view); static void thunar_tree_view_action_rename (ThunarTreeView *view); +static void thunar_tree_view_action_unmount (ThunarTreeView *view); static void thunar_tree_view_action_eject (ThunarTreeView *view); static void thunar_tree_view_action_empty_trash (ThunarTreeView *view); static void thunar_tree_view_action_mount (ThunarTreeView *view); @@ -1127,6 +1128,15 @@ /* check if the volume is present and can be ejected */ if (thunar_g_volume_is_present (volume) && thunar_g_volume_is_removable (volume)) { + /* append the "Unmount Volume" menu action */ + if (thunar_g_volume_is_unmountable (volume)) + { + item = gtk_image_menu_item_new_with_mnemonic (_("_Unmount Volume")); + g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_unmount), view); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); + } + /* append the "Eject Volume" menu action */ item = gtk_image_menu_item_new_with_mnemonic (_("E_ject Volume")); g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_eject), view); @@ -1801,6 +1811,48 @@ } + +static void +thunar_tree_view_action_unmount (ThunarTreeView *view) +{ + GVolume *volume; + GMount *mount; + GMountOperation *mount_operation; + GtkWidget *window; + + _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); + + /* determine the selected volume */ + volume = thunar_tree_view_get_selected_volume (view); + if (G_LIKELY (volume != NULL)) + { + /* prepare a mount operation */ + window = gtk_widget_get_toplevel (GTK_WIDGET (view)); + mount_operation = gtk_mount_operation_new (GTK_WINDOW (window)); + + /* determine the mount of the volume */ + mount = g_volume_get_mount (volume); + if (G_LIKELY (mount != NULL)) + { +#ifdef HAVE_LIBNOTIFY + thunar_notify_unmount (mount); +#endif + + /* the volume is mounted, try to unmount the mount */ + g_mount_unmount_with_operation (mount, G_MOUNT_UNMOUNT_NONE, mount_operation, NULL, + thunar_tree_view_action_unmount_finish, + g_object_ref (view)); + + /* release the mount */ + g_object_unref (mount); + } + /* release the volume */ + g_object_unref (volume); + g_object_unref (mount_operation); + } +} + + static void thunar_tree_view_action_eject (ThunarTreeView *view)