[gnome-commander] Implement option to use the trash can instead of permanent file deletion; fixing #2



commit ca43c1548896df4fadfc7f784771c37d798589ea
Author: Uwe Scholz <u scholz83 gmx de>
Date:   Sat Jan 8 20:25:25 2022 +0100

    Implement option to use the trash can instead of permanent file deletion; fixing #2

 NEWS                                       |  1 +
 data/org.gnome.gnome-commander.gschema.xml |  7 +++++
 doc/C/releases.xml                         |  3 ++
 src/dialogs/gnome-cmd-delete-dialog.cc     | 45 ++++++++++++++++++++++++------
 src/dialogs/gnome-cmd-delete-dialog.h      | 10 ++++++-
 src/dialogs/gnome-cmd-options-dialog.cc    | 12 ++++++++
 src/gnome-cmd-data.cc                      | 16 +++++++++++
 src/gnome-cmd-data.h                       |  3 ++
 src/gnome-cmd-file-list.cc                 |  9 ++++--
 src/gnome-cmd-file-list.h                  |  2 +-
 src/gnome-cmd-main-menu.cc                 |  2 +-
 src/gnome-cmd-xfer.cc                      |  1 +
 12 files changed, 97 insertions(+), 14 deletions(-)
---
diff --git a/NEWS b/NEWS
index 7c46ab40..d51d931d 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ gnome-commander 1.14
 
 New features:
  * Selectable default action when drag-n-drop files with the mouse
+ * Optional usage of the trash can instead of permanent file deletion (see issue #2)
  * Menu entry for (un)selecting only files
 
 Bug fixes:
diff --git a/data/org.gnome.gnome-commander.gschema.xml b/data/org.gnome.gnome-commander.gschema.xml
index fcf129a6..17762b8d 100644
--- a/data/org.gnome.gnome-commander.gschema.xml
+++ b/data/org.gnome.gnome-commander.gschema.xml
@@ -147,6 +147,13 @@
         Defines what happens when the right mouse button is clicked on an item.
       </description>
     </key>
+    <key name="delete-to-trash" type="b">
+      <default>true</default>
+      <summary>Use trash</summary>
+      <description>
+          Defines if items should be moved to trash by default instead of really deleting them.
+      </description>
+    </key>
     <key name="icon-size" type="u">
       <default>16</default>
       <summary>Icon size</summary>
diff --git a/doc/C/releases.xml b/doc/C/releases.xml
index fc752fe1..36786d4b 100644
--- a/doc/C/releases.xml
+++ b/doc/C/releases.xml
@@ -94,6 +94,9 @@
                         <listitem>
                             <para>Selectable default action when drag-n-drop files with the mouse</para>
                         </listitem>
+                        <listitem>
+                            <para>Optional usage of the trash can instead of permanent file deletion (see 
issue #2)</para>
+                        </listitem>
                         <listitem>
                             <para>Menu entry for (un)selecting only files</para>
                         </listitem>
diff --git a/src/dialogs/gnome-cmd-delete-dialog.cc b/src/dialogs/gnome-cmd-delete-dialog.cc
index 868905d0..d6d71dd5 100644
--- a/src/dialogs/gnome-cmd-delete-dialog.cc
+++ b/src/dialogs/gnome-cmd-delete-dialog.cc
@@ -205,7 +205,19 @@ static gboolean perform_delete_operation_r(DeleteData *deleteData, GList *gnomeC
         if (gnomeCmdFile->is_dotdot || strcmp(filenameTmp, ".") == 0)
             continue;
 
-        g_file_delete (gnomeCmdFile->gFile, nullptr, &tmpError);
+        switch (deleteData->originAction)
+        {
+            case DeleteData::OriginAction::FORCE_DELETE:
+            case DeleteData::OriginAction::MOVE:
+                g_file_delete (gnomeCmdFile->gFile, nullptr, &tmpError);
+                break;
+            case DeleteData::OriginAction::DELETE:
+            default:
+                gnome_cmd_data.options.deleteToTrash
+                    ? g_file_trash (gnomeCmdFile->gFile, nullptr, &tmpError)
+                    : g_file_delete (gnomeCmdFile->gFile, nullptr, &tmpError);
+                break;
+        }
 
         if (tmpError && g_error_matches (tmpError, G_IO_ERROR, G_IO_ERROR_NOT_EMPTY))
         {
@@ -469,7 +481,7 @@ static GList *remove_items_from_list_to_be_deleted(GList *files)
 /**
  * Creates a delete dialog for the given list of GnomeCmdFiles
  */
-void gnome_cmd_delete_dialog_show (GList *files)
+void gnome_cmd_delete_dialog_show (GList *files, gboolean forceDelete)
 {
     g_return_if_fail (files != nullptr);
 
@@ -483,22 +495,34 @@ void gnome_cmd_delete_dialog_show (GList *files)
 
         if (n_files == 1)
         {
-            auto f = (GnomeCmdFile *) g_list_nth_data (files, 0);
-            g_return_if_fail (GNOME_CMD_IS_FILE(f));
+            auto gnomeCmdFile = static_cast<GnomeCmdFile*> (g_list_nth_data (files, 0));
+            g_return_if_fail (GNOME_CMD_IS_FILE(gnomeCmdFile));
 
-            if (f->is_dotdot)
+            if (gnomeCmdFile->is_dotdot)
                 return;
 
-            msg = g_strdup_printf (_("Do you want to delete “%s”?"), f->get_name());
+            msg = forceDelete || !gnome_cmd_data.options.deleteToTrash
+                ? g_strdup_printf (_("Do you want to permanently delete “%s”?"), gnomeCmdFile->get_name())
+                : g_strdup_printf (_("Do you want to move “%s” to the trash can?"), 
gnomeCmdFile->get_name());
         }
         else
-            msg = g_strdup_printf (ngettext("Do you want to delete the selected file?",
-                                            "Do you want to delete the %d selected files?",
+        {
+            msg = forceDelete || !gnome_cmd_data.options.deleteToTrash
+                ? g_strdup_printf (ngettext("Do you want to permanently delete the selected file?",
+                                            "Do you want to permanently delete the %d selected files?",
+                                            n_files),
+                                   n_files)
+                : g_strdup_printf (ngettext("Do you want to move the selected file to the trash can?",
+                                            "Do you want to move the %d selected files to the trash can?",
                                             n_files),
                                    n_files);
+        }
 
         response = run_simple_dialog (*main_win, FALSE,
-                                      GTK_MESSAGE_QUESTION, msg, _("Delete"),
+                                      forceDelete || !gnome_cmd_data.options.deleteToTrash
+                                        ? GTK_MESSAGE_WARNING
+                                        : GTK_MESSAGE_QUESTION,
+                                      msg, _("Delete"),
                                       gnome_cmd_data.options.confirm_delete_default==GTK_BUTTONS_CANCEL ? 0 
: 1, _("Cancel"), _("Delete"), NULL);
 
         g_free (msg);
@@ -519,6 +543,9 @@ void gnome_cmd_delete_dialog_show (GList *files)
     DeleteData *deleteData = g_new0 (DeleteData, 1);
 
     deleteData->gnomeCmdFiles = files;
+    deleteData->originAction = forceDelete
+        ? DeleteData::OriginAction::FORCE_DELETE
+        : DeleteData::OriginAction::DELETE;
 
     // Refing files for the delete procedure
     gnome_cmd_file_list_ref (deleteData->gnomeCmdFiles);
diff --git a/src/dialogs/gnome-cmd-delete-dialog.h b/src/dialogs/gnome-cmd-delete-dialog.h
index 6c369e6f..f2062a5d 100644
--- a/src/dialogs/gnome-cmd-delete-dialog.h
+++ b/src/dialogs/gnome-cmd-delete-dialog.h
@@ -22,6 +22,13 @@
 
 struct DeleteData
 {
+    enum OriginAction
+    {
+        MOVE,
+        DELETE,
+        FORCE_DELETE
+    };
+
     GtkWidget *progbar;
     GtkWidget *proglabel;
     GtkWidget *progwin;
@@ -40,8 +47,9 @@ struct DeleteData
     GMutex mutex{nullptr};                // used to sync the main and worker thread
     guint64 itemsDeleted{0};              // items deleted in the current run
     guint64 itemsTotal{0};                // total number of items which should be deleted
+    OriginAction originAction;            // As delete can also used when moving files, we have to 
distinguish here
 };
 
 void do_delete (DeleteData *deleteData, gboolean showProgress);
 
-void gnome_cmd_delete_dialog_show (GList *files);
+void gnome_cmd_delete_dialog_show (GList *files, gboolean forceDelete = false);
diff --git a/src/dialogs/gnome-cmd-options-dialog.cc b/src/dialogs/gnome-cmd-options-dialog.cc
index 3288508d..33df7cc7 100644
--- a/src/dialogs/gnome-cmd-options-dialog.cc
+++ b/src/dialogs/gnome-cmd-options-dialog.cc
@@ -158,6 +158,16 @@ static GtkWidget *create_general_tab (GtkWidget *parent, GnomeCmdData::Options &
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
 
 
+    // Delete options
+    cat_box = create_vbox (parent, FALSE, 0);
+    cat = create_category (parent, cat_box, _("Deletion"));
+    gtk_box_pack_start (GTK_BOX (vbox), cat, FALSE, TRUE, 0);
+
+    check = create_check (parent, _("Move to trash"), "delete_to_trash");
+    gtk_box_pack_start (GTK_BOX (cat_box), check, FALSE, TRUE, 0);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), cfg.deleteToTrash);
+
+
     // Selection options
     cat_box = create_vbox (parent, FALSE, 0);
     cat = create_category (parent, cat_box, _("Selection"));
@@ -262,6 +272,7 @@ void store_general_options (GtkWidget *dialog, GnomeCmdData::Options &cfg)
     GtkWidget *mmb_cd_up_radio = lookup_widget (dialog, "mmb_cd_up_radio");
     GtkWidget *rmb_popup_radio = lookup_widget (dialog, "rmb_popup_radio");
     GtkWidget *select_dirs = lookup_widget (dialog, "select_dirs");
+    GtkWidget *delete_to_trash = lookup_widget (dialog, "delete_to_trash");
     GtkWidget *case_sens_check = lookup_widget (dialog, "case_sens_check");
     GtkWidget *ctrl_alt_quick_search = lookup_widget (dialog, "ctrl_alt_quick_search");
     GtkWidget *alt_quick_search = lookup_widget (dialog, "alt_quick_search");
@@ -288,6 +299,7 @@ void store_general_options (GtkWidget *dialog, GnomeCmdData::Options &cfg)
                                                                                                      : 
GnomeCmdData::RIGHT_BUTTON_SELECTS;
 
     cfg.select_dirs = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (select_dirs));
+    cfg.deleteToTrash = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (delete_to_trash));
     cfg.case_sens_sort = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (case_sens_check));
     if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ctrl_alt_quick_search)))
         cfg.quick_search = GNOME_CMD_QUICK_SEARCH_CTRL_ALT;
diff --git a/src/gnome-cmd-data.cc b/src/gnome-cmd-data.cc
index 236741f8..269c88a6 100644
--- a/src/gnome-cmd-data.cc
+++ b/src/gnome-cmd-data.cc
@@ -415,6 +415,14 @@ static void on_tab_lock_indicator_changed ()
     main_win->update_style();
 }
 
+static void on_use_trash_changed()
+{
+    gboolean use_trash;
+
+    use_trash = g_settings_get_boolean (gnome_cmd_data.options.gcmd_settings->general, 
GCMD_SETTINGS_USE_TRASH);
+    gnome_cmd_data.options.deleteToTrash = use_trash;
+}
+
 static void on_confirm_delete_changed ()
 {
     gboolean confirm_delete;
@@ -1071,6 +1079,11 @@ static void gcmd_connect_gsettings_signals(GcmdSettings *gs)
                       G_CALLBACK (on_tab_lock_indicator_changed),
                       nullptr);
 
+    g_signal_connect (gs->general,
+                      "changed::delete-to-trash",
+                      G_CALLBACK (on_use_trash_changed),
+                      nullptr);
+
     g_signal_connect (gs->confirm,
                       "changed::delete",
                       G_CALLBACK (on_confirm_delete_changed),
@@ -1424,6 +1437,7 @@ GnomeCmdData::Options::Options(const Options &cfg)
     termexec = g_strdup (cfg.termexec);
     fav_apps = cfg.fav_apps;
     device_only_icon = cfg.device_only_icon;
+    deleteToTrash = cfg.deleteToTrash;
 #ifdef HAVE_SAMBA
     show_samba_workgroups_button = cfg.show_samba_workgroups_button;
 #endif
@@ -3160,6 +3174,7 @@ void GnomeCmdData::load()
     options.left_mouse_button_unselects = g_settings_get_boolean (options.gcmd_settings->general, 
GCMD_SETTINGS_LEFT_MOUSE_BUTTON_UNSELECTS);
     options.middle_mouse_button_mode = (MiddleMouseButtonMode) g_settings_get_enum 
(options.gcmd_settings->general, GCMD_SETTINGS_MIDDLE_MOUSE_BUTTON_MODE);
     options.right_mouse_button_mode = (RightMouseButtonMode) g_settings_get_enum 
(options.gcmd_settings->general, GCMD_SETTINGS_RIGHT_MOUSE_BUTTON_MODE);
+    options.deleteToTrash = g_settings_get_boolean (options.gcmd_settings->general, GCMD_SETTINGS_USE_TRASH);
     options.icon_size = g_settings_get_uint (options.gcmd_settings->general, GCMD_SETTINGS_ICON_SIZE);
     dev_icon_size = g_settings_get_uint (options.gcmd_settings->general, GCMD_SETTINGS_DEV_ICON_SIZE);
     options.icon_scale_quality = (GdkInterpType) g_settings_get_enum (options.gcmd_settings->general, 
GCMD_SETTINGS_ICON_SCALE_QUALITY);
@@ -3546,6 +3561,7 @@ void GnomeCmdData::save()
     set_gsettings_enum_when_changed (options.gcmd_settings->general, GCMD_SETTINGS_MIDDLE_MOUSE_BUTTON_MODE, 
options.middle_mouse_button_mode);
     set_gsettings_enum_when_changed (options.gcmd_settings->general, GCMD_SETTINGS_RIGHT_MOUSE_BUTTON_MODE, 
options.right_mouse_button_mode);
     set_gsettings_when_changed      (options.gcmd_settings->general, GCMD_SETTINGS_ICON_SIZE, 
&(options.icon_size));
+    set_gsettings_when_changed      (options.gcmd_settings->general, GCMD_SETTINGS_USE_TRASH, 
&(options.deleteToTrash));
     set_gsettings_when_changed      (options.gcmd_settings->general, GCMD_SETTINGS_DEV_ICON_SIZE, 
&(dev_icon_size));
     set_gsettings_enum_when_changed (options.gcmd_settings->general, GCMD_SETTINGS_ICON_SCALE_QUALITY, 
options.icon_scale_quality);
     set_gsettings_when_changed      (options.gcmd_settings->general, GCMD_SETTINGS_MIME_ICON_DIR, 
options.theme_icon_dir);
diff --git a/src/gnome-cmd-data.h b/src/gnome-cmd-data.h
index ece7e5c3..7c637647 100644
--- a/src/gnome-cmd-data.h
+++ b/src/gnome-cmd-data.h
@@ -66,6 +66,7 @@ GcmdSettings *gcmd_settings_new (void);
 #define GCMD_SETTINGS_LEFT_MOUSE_BUTTON_UNSELECTS     "left-mouse-btn-unselects"
 #define GCMD_SETTINGS_RIGHT_MOUSE_BUTTON_MODE         "right-mouse-btn-mode"
 #define GCMD_SETTINGS_MIDDLE_MOUSE_BUTTON_MODE        "middle-mouse-btn-mode"
+#define GCMD_SETTINGS_USE_TRASH                       "delete-to-trash"
 #define GCMD_SETTINGS_ICON_SIZE                       "icon-size"
 #define GCMD_SETTINGS_DEV_ICON_SIZE                   "dev-icon-size"
 #define GCMD_SETTINGS_ICON_SCALE_QUALITY              "icon-scale-quality"
@@ -333,6 +334,7 @@ struct GnomeCmdData
         gboolean                     search_window_is_transient {true};
         gchar                       *symlink_prefix;
         gint                         main_win_pos[2];
+        gboolean                     deleteToTrash;
         // Format
         GnomeCmdSizeDispMode         size_disp_mode;
         GnomeCmdPermDispMode         perm_disp_mode;
@@ -395,6 +397,7 @@ struct GnomeCmdData
                    save_search_history_on_exit(TRUE),
                    symlink_prefix(nullptr),
                    main_win_pos{0,25},
+                   deleteToTrash(TRUE),
                    size_disp_mode(GNOME_CMD_SIZE_DISP_MODE_POWERED),
                    perm_disp_mode(GNOME_CMD_PERM_DISP_MODE_TEXT),
                    date_format(nullptr),
diff --git a/src/gnome-cmd-file-list.cc b/src/gnome-cmd-file-list.cc
index 26c751b8..ca4ba19b 100644
--- a/src/gnome-cmd-file-list.cc
+++ b/src/gnome-cmd-file-list.cc
@@ -2403,7 +2403,7 @@ void gnome_cmd_file_list_show_rename_dialog (GnomeCmdFileList *fl)
 }
 
 
-void gnome_cmd_file_list_show_delete_dialog (GnomeCmdFileList *fl)
+void gnome_cmd_file_list_show_delete_dialog (GnomeCmdFileList *fl, gboolean forceDelete)
 {
     g_return_if_fail (GNOME_CMD_IS_FILE_LIST (fl));
 
@@ -2411,7 +2411,7 @@ void gnome_cmd_file_list_show_delete_dialog (GnomeCmdFileList *fl)
 
     if (files)
     {
-        gnome_cmd_delete_dialog_show (files);
+        gnome_cmd_delete_dialog_show (files, forceDelete);
     }
 }
 
@@ -2628,6 +2628,11 @@ gboolean GnomeCmdFileList::key_pressed(GdkEventKey *event)
                 g_signal_emit_by_name (this, "scroll-vertical", GTK_SCROLL_JUMP, 1.0);
                 return TRUE;
 
+            case GDK_Delete:
+            case GDK_KP_Delete:
+                gnome_cmd_file_list_show_delete_dialog (this, TRUE);
+                return TRUE;
+
             default:
                 break;
         }
diff --git a/src/gnome-cmd-file-list.h b/src/gnome-cmd-file-list.h
index 06ceddfd..c01a0991 100644
--- a/src/gnome-cmd-file-list.h
+++ b/src/gnome-cmd-file-list.h
@@ -258,7 +258,7 @@ inline GnomeCmdFile *GnomeCmdFileList::get_selected_file()
     return !f || f->is_dotdot ? nullptr : f;
 }
 
-void gnome_cmd_file_list_show_delete_dialog (GnomeCmdFileList *fl);
+void gnome_cmd_file_list_show_delete_dialog (GnomeCmdFileList *fl, gboolean forceDelete = FALSE);
 void gnome_cmd_file_list_show_properties_dialog (GnomeCmdFileList *fl);
 void gnome_cmd_file_list_show_rename_dialog (GnomeCmdFileList *fl);
 void gnome_cmd_file_list_show_selpat_dialog (GnomeCmdFileList *fl, gboolean mode);
diff --git a/src/gnome-cmd-main-menu.cc b/src/gnome-cmd-main-menu.cc
index a2029366..5bc3fbf6 100644
--- a/src/gnome-cmd-main-menu.cc
+++ b/src/gnome-cmd-main-menu.cc
@@ -322,7 +322,7 @@ static GtkUIManager *get_file_menu_ui_manager()
         { "Cut",           GTK_STOCK_CUT,    _("Cu_t"),            "<Control>X", nullptr, (GCallback) 
edit_cap_cut },
         { "Copy",          GTK_STOCK_COPY,   _("_Copy"),           "<Control>C", nullptr, (GCallback) 
edit_cap_copy },
         { "Paste",         GTK_STOCK_PASTE,  _("_Paste"),          "<Control>V", nullptr, (GCallback) 
edit_cap_paste },
-        { "Delete",        GTK_STOCK_DELETE, _("_Delete"),         "Delete",   nullptr, (GCallback) 
file_delete },
+        { "Delete",        GTK_STOCK_DELETE, _("_Delete"),         "Delete",     nullptr, (GCallback) 
file_delete },
         { "CopyFileNames", nullptr,          _("Copy _File Names"), nullptr,     nullptr, (GCallback) 
edit_copy_fnames }
     };
 
diff --git a/src/gnome-cmd-xfer.cc b/src/gnome-cmd-xfer.cc
index b8b8accf..de946eff 100644
--- a/src/gnome-cmd-xfer.cc
+++ b/src/gnome-cmd-xfer.cc
@@ -1117,6 +1117,7 @@ gnome_cmd_move_gfile_recursive (GFile *srcGFile,
 
                 auto deleteData = g_new0 (DeleteData, 1);
                 deleteData->gnomeCmdFiles = g_list_append(nullptr, gnomeCmdDir);
+                deleteData->originAction = DeleteData::OriginAction::MOVE;
                 do_delete (deleteData, false); // false -> do not show progress window
 
                 g_free(gFileParentPath);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]