From c6f8fb502bb69b69bbc03b4d528ba24873977c81 Mon Sep 17 00:00:00 2001 From: Sergios - Anestis Kefalidis <sergioskefalidis@gmail.com> Date: Sat, 10 Jul 2021 13:07:07 +0300 Subject: [PATCH] Provide additional menu item for trashed files: "restore and open folder" (Issue #382) Issue #382 MR !118 --- thunar/thunar-application.c | 4 +- thunar/thunar-enum-types.h | 15 +++++ thunar/thunar-launcher.c | 32 +++++++++++ thunar/thunar-launcher.h | 2 + thunar/thunar-menu.c | 7 ++- thunar/thunar-window.c | 111 ++++++++++++++++++++++++++++++++---- thunar/thunar-window.h | 4 +- 7 files changed, 158 insertions(+), 17 deletions(-) diff --git a/thunar/thunar-application.c b/thunar/thunar-application.c index 0e45aacb0..52a88c6db 100644 --- a/thunar/thunar-application.c +++ b/thunar/thunar-application.c @@ -1372,7 +1372,7 @@ thunar_application_open_window (ThunarApplication *application, list = g_list_last (list); if (directory != NULL) - thunar_window_notebook_add_new_tab (THUNAR_WINDOW (list->data), directory, TRUE); + thunar_window_notebook_add_new_tab (THUNAR_WINDOW (list->data), directory, THUNAR_NEW_TAB_BEHAVIOR_SWITCH); /* bring the window to front */ gtk_window_present (list->data); @@ -1592,7 +1592,7 @@ thunar_application_process_files_finish (ThunarBrowser *browser, g_object_unref (parent); files = g_list_append (files, thunar_file_get_file (file)); - thunar_window_select_files (THUNAR_WINDOW (window), files); + thunar_window_show_and_select_files (THUNAR_WINDOW (window), files); g_list_free (files); } } diff --git a/thunar/thunar-enum-types.h b/thunar/thunar-enum-types.h index 5fe3960bb..b0908a4ce 100644 --- a/thunar/thunar-enum-types.h +++ b/thunar/thunar-enum-types.h @@ -326,6 +326,21 @@ typedef enum /*< flags >*/ GType thunar_file_mode_get_type (void) G_GNUC_CONST; + + +/** + * ThunarNewTabBehavior: + * @THUNAR_NEW_TAB_BEHAVIOR_FOLLOW_PREFERENCE : switching to the new tab or not is controlled by a preference. + * @THUNAR_NEW_TAB_BEHAVIOR_SWITCH : switch to the new tab. + * @THUNAR_NEW_TAB_BEHAVIOR_STAY : stay at the current tab. + **/ +typedef enum +{ + THUNAR_NEW_TAB_BEHAVIOR_FOLLOW_PREFERENCE, + THUNAR_NEW_TAB_BEHAVIOR_SWITCH, + THUNAR_NEW_TAB_BEHAVIOR_STAY +} ThunarNewTabBehavior; + G_END_DECLS; #endif /* !__THUNAR_ENUM_TYPES_H__ */ diff --git a/thunar/thunar-launcher.c b/thunar/thunar-launcher.c index 26a4d37a1..324b50311 100644 --- a/thunar/thunar-launcher.c +++ b/thunar/thunar-launcher.c @@ -284,6 +284,7 @@ static XfceGtkActionEntry thunar_launcher_action_entries[] = {THUNAR_LAUNCHER_ACTION_CREATE_DOCUMENT, "<Actions>/ThunarStandardView/create-document", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Create _Document"), N_ ("Create a new document from a template"), "document-new", G_CALLBACK (NULL), }, {THUNAR_LAUNCHER_ACTION_RESTORE, "<Actions>/ThunarLauncher/restore", "", XFCE_GTK_MENU_ITEM, N_ ("_Restore"), NULL, NULL, G_CALLBACK (thunar_launcher_action_restore), }, + { THUNAR_LAUNCHER_ACTION_RESTORE_SHOW, "<Actions>/ThunarLauncher/restore-show", "", XFCE_GTK_MENU_ITEM, N_ ("_Restore and Show"), N_ ("_Restore and show the file(s)"), NULL, G_CALLBACK (thunar_launcher_action_restore_and_show), }, {THUNAR_LAUNCHER_ACTION_MOVE_TO_TRASH, "<Actions>/ThunarLauncher/move-to-trash", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Mo_ve to Trash"), NULL, "user-trash", G_CALLBACK (thunar_launcher_action_trash_delete), }, {THUNAR_LAUNCHER_ACTION_DELETE, "<Actions>/ThunarLauncher/delete", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Delete"), NULL, "edit-delete", G_CALLBACK (thunar_launcher_action_delete), }, {THUNAR_LAUNCHER_ACTION_DELETE, "<Actions>/ThunarLauncher/delete-2", "<Shift>Delete", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_launcher_action_delete), }, @@ -1587,6 +1588,18 @@ thunar_launcher_append_menu_item (ThunarLauncher *launcher, } return NULL; + case THUNAR_LAUNCHER_ACTION_RESTORE_SHOW: + if (launcher->files_are_selected && thunar_file_is_trashed (launcher->current_directory)) + { + tooltip_text = ngettext ("Restore the selected file to its original location and open the location in a new window/tab", + "Restore the selected files to their original locations and open the locations in a new window/tab", launcher->n_files_to_process); + item = xfce_gtk_menu_item_new (action_entry->menu_item_label_text, tooltip_text, action_entry->accel_path, + action_entry->callback, G_OBJECT (launcher), menu); + gtk_widget_set_sensitive (item, thunar_file_is_writable (launcher->current_directory)); + return item; + } + return NULL; + case THUNAR_LAUNCHER_ACTION_MOVE_TO_TRASH: if (!thunar_launcher_show_trash (launcher)) return NULL; @@ -2370,6 +2383,25 @@ thunar_launcher_action_restore (ThunarLauncher *launcher) } + +void +thunar_launcher_action_restore_and_show (ThunarLauncher *launcher) +{ + ThunarApplication *application; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (launcher->files_are_selected == FALSE || !thunar_file_is_trashed (launcher->current_directory)) + return; + + /* restore the selected files */ + application = thunar_application_get (); + thunar_application_restore_files (application, launcher->widget, launcher->files_to_process, launcher->new_files_created_closure); + g_object_unref (G_OBJECT (application)); +} + + + static void thunar_launcher_action_move_to_trash (ThunarLauncher *launcher) { diff --git a/thunar/thunar-launcher.h b/thunar/thunar-launcher.h index 9b88e9079..7e27f2d7b 100644 --- a/thunar/thunar-launcher.h +++ b/thunar/thunar-launcher.h @@ -57,6 +57,7 @@ typedef enum THUNAR_LAUNCHER_ACTION_CREATE_FOLDER, THUNAR_LAUNCHER_ACTION_CREATE_DOCUMENT, THUNAR_LAUNCHER_ACTION_RESTORE, + THUNAR_LAUNCHER_ACTION_RESTORE_SHOW, THUNAR_LAUNCHER_ACTION_MOVE_TO_TRASH, THUNAR_LAUNCHER_ACTION_DELETE, THUNAR_LAUNCHER_ACTION_TRASH_DELETE, @@ -110,6 +111,7 @@ void thunar_launcher_set_selection (ThunarLaun GFile *selected_location); void thunar_launcher_action_empty_trash (ThunarLauncher *launcher); void thunar_launcher_action_restore (ThunarLauncher *launcher); +void thunar_launcher_action_restore_and_show (ThunarLauncher *launcher); G_END_DECLS; diff --git a/thunar/thunar-menu.c b/thunar/thunar-menu.c index 4d3a11652..a5d32c88b 100644 --- a/thunar/thunar-menu.c +++ b/thunar/thunar-menu.c @@ -305,8 +305,11 @@ thunar_menu_add_sections (ThunarMenu *menu, } if (menu_sections & THUNAR_MENU_SECTION_RESTORE) { - if (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_RESTORE, FALSE) != NULL) - xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + item_added = FALSE; + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_RESTORE, FALSE) != NULL); + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_RESTORE_SHOW, FALSE) != NULL); + if (item_added) + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); } if (menu_sections & THUNAR_MENU_SECTION_REMOVE_FROM_RECENT) { diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c index 5573df1a0..769c545e8 100644 --- a/thunar/thunar-window.c +++ b/thunar/thunar-window.c @@ -252,6 +252,8 @@ static void thunar_window_update_window_icon (ThunarWindow static void thunar_window_create_menu (ThunarWindow *window, ThunarWindowAction action, GCallback cb_update_menu); +static void thunar_window_select_files (ThunarWindow *window, + GList *files_to_select); static void thunar_window_update_file_menu (ThunarWindow *window, GtkWidget *menu); static void thunar_window_update_edit_menu (ThunarWindow *window, @@ -735,7 +737,7 @@ thunar_window_init (ThunarWindow *window) g_object_bind_property (G_OBJECT (window), "current-directory", G_OBJECT (window->launcher), "current-directory", G_BINDING_SYNC_CREATE); g_signal_connect_swapped (G_OBJECT (window->launcher), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window); g_signal_connect_swapped (G_OBJECT (window->launcher), "open-new-tab", G_CALLBACK (thunar_window_notebook_open_new_tab), window); - g_signal_connect_swapped (G_OBJECT (window->launcher), "new-files-created", G_CALLBACK (thunar_window_select_files), window); + g_signal_connect_swapped (G_OBJECT (window->launcher), "new-files-created", G_CALLBACK (thunar_window_show_and_select_files), window); thunar_launcher_append_accelerators (window->launcher, window->accel_group); /* determine the default window size from the preferences */ @@ -953,6 +955,94 @@ thunar_window_screen_changed (GtkWidget *widget, } + +static void +hash_table_entry_show_and_select_files (gpointer key, gpointer list, gpointer application) +{ + ThunarFile *original_dir = NULL; + GList *window_list = NULL; + + _thunar_return_if_fail (key != NULL); + _thunar_return_if_fail (list != NULL); + _thunar_return_if_fail (application != NULL); + + /* open directory */ + original_dir = thunar_file_get_for_uri (key, NULL); + thunar_application_open_window (application, original_dir, NULL, NULL, FALSE); + + /* select files */ + window_list = thunar_application_get_windows (application); + window_list = g_list_last (window_list); /* this will be the topmost Window */ + thunar_window_select_files (THUNAR_WINDOW (window_list->data), list); + + /* free memory */ + g_list_free (window_list); + g_object_unref (original_dir); +} + + + +/** + * thunar_window_show_and_select_files: + * @window : a #ThunarWindow instance. + * @files_to_select : a list of #GFile<!---->s + * + * Visually selects the files, given by the list. If the files are being restored from the trash folder + * new tabs are opened and then the files are selected. + **/ +void +thunar_window_show_and_select_files (ThunarWindow *window, + GList *files_to_select) +{ + gboolean restore_and_show_in_progress; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + restore_and_show_in_progress = thunar_file_is_trash (window->current_directory) && thunar_g_file_is_trashed (files_to_select->data) == FALSE; + if (restore_and_show_in_progress) + { + ThunarApplication *application; + GHashTable *restore_show_table; /* <string, GList<GFile*>> */ + const gchar *original_uri; + GFile *original_dir_file; + gchar *original_dir_path; + + /* prepare hashtable */ + restore_show_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (void(*) (void*))thunar_g_list_free_full); + for (GList *lp = files_to_select; lp != NULL; lp = lp->next) + { + original_dir_file = g_file_get_parent (lp->data); + original_uri = g_file_get_uri (lp->data); + original_dir_path = g_file_get_uri (original_dir_file); + + if (g_hash_table_contains (restore_show_table, original_dir_path) == FALSE) + { + GList *list = g_list_prepend (NULL, g_file_new_for_commandline_arg (original_uri)); + g_hash_table_insert (restore_show_table, original_dir_path, list); + } + else + { + GList *list = g_hash_table_lookup (restore_show_table, original_dir_path); + list = g_list_append (list, g_file_new_for_commandline_arg (original_uri)); + } + + g_object_unref (original_dir_file); + } + /* open tabs and show files */ + application = thunar_application_get(); + g_hash_table_foreach (restore_show_table, hash_table_entry_show_and_select_files, application); + /* free memory */ + g_hash_table_destroy (restore_show_table); + g_object_unref (application); + } + else + { + thunar_window_select_files (window, files_to_select); + } +} + + + /** * thunar_window_select_files: * @window : a #ThunarWindow instance. @@ -960,15 +1050,13 @@ thunar_window_screen_changed (GtkWidget *widget, * * Visually selects the files, given by the list **/ -void +static void thunar_window_select_files (ThunarWindow *window, GList *files_to_select) { GList *thunar_files = NULL; ThunarFolder *thunar_folder; - _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - /* If possible, reload the current directory to make sure new files got added to the view */ thunar_folder = thunar_folder_get_for_file (window->current_directory); if (thunar_folder != NULL) @@ -2339,9 +2427,9 @@ thunar_window_split_view_is_active (ThunarWindow *window) void -thunar_window_notebook_add_new_tab (ThunarWindow *window, - ThunarFile *directory, - gboolean force_switch_to_new_tab) +thunar_window_notebook_add_new_tab (ThunarWindow *window, + ThunarFile *directory, + ThunarNewTabBehavior behavior) { ThunarHistory *history = NULL; GtkWidget *view; @@ -2364,7 +2452,8 @@ thunar_window_notebook_add_new_tab (ThunarWindow *window, /* switch to the new view */ g_object_get (G_OBJECT (window->preferences), "misc-switch-to-new-tab", &switch_to_new_tab, NULL); - if (switch_to_new_tab == TRUE || force_switch_to_new_tab == TRUE) + if ((behavior == THUNAR_NEW_TAB_BEHAVIOR_FOLLOW_PREFERENCE && switch_to_new_tab == TRUE) + || behavior == THUNAR_NEW_TAB_BEHAVIOR_SWITCH) { page_num = gtk_notebook_page_num (GTK_NOTEBOOK (window->notebook_selected), view); gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook_selected), page_num); @@ -2380,7 +2469,7 @@ void thunar_window_notebook_open_new_tab (ThunarWindow *window, ThunarFile *directory) { - thunar_window_notebook_add_new_tab (window, directory, FALSE /* don't override `misc-switch-to-new-tab` preference */); + thunar_window_notebook_add_new_tab (window, directory, THUNAR_NEW_TAB_BEHAVIOR_FOLLOW_PREFERENCE); } @@ -2756,7 +2845,7 @@ thunar_window_action_open_new_tab (ThunarWindow *window, GtkWidget *menu_item) { /* open new tab with current directory as default */ - thunar_window_notebook_add_new_tab (window, thunar_window_get_current_directory (window), TRUE /* force tab switch */); + thunar_window_notebook_add_new_tab (window, thunar_window_get_current_directory (window), THUNAR_NEW_TAB_BEHAVIOR_SWITCH); } @@ -4644,7 +4733,7 @@ thunar_window_open_home_clicked (GtkWidget *button, if (open_in_tab) { page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook_selected)); - thunar_window_notebook_add_new_tab (window, window->current_directory, TRUE); + thunar_window_notebook_add_new_tab (window, window->current_directory, THUNAR_NEW_TAB_BEHAVIOR_SWITCH); thunar_window_action_open_home (window); gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook_selected), page_num); } diff --git a/thunar/thunar-window.h b/thunar/thunar-window.h index a214220aa..c20942b56 100644 --- a/thunar/thunar-window.h +++ b/thunar/thunar-window.h @@ -122,7 +122,7 @@ void thunar_window_notebook_open_new_tab (Thu ThunarFile *directory); void thunar_window_notebook_add_new_tab (ThunarWindow *window, ThunarFile *directory, - gboolean force_switch_to_new_tab); + ThunarNewTabBehavior behavior); void thunar_window_notebook_remove_tab (ThunarWindow *window, gint tab); void thunar_window_notebook_set_current_tab (ThunarWindow *window, @@ -137,7 +137,7 @@ void thunar_window_redirect_menu_tooltips_to_statusbar (Thu GtkMenu *menu); const XfceGtkActionEntry* thunar_window_get_action_entry (ThunarWindow *window, ThunarWindowAction action); - void thunar_window_select_files (ThunarWindow *window, + void thunar_window_show_and_select_files (ThunarWindow *window, GList *files_to_select); G_END_DECLS; -- GitLab