summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxmusjackson <[email protected]>2023-05-14 20:57:35 -0500
committermouse <[email protected]>2023-05-29 09:43:42 +0800
commita043e0a81460a94e0732672afc3831689984caf8 (patch)
tree35dec7665b3b8747c172f8c478a59071e89d6dca
parente4cdb9e1a846390bafef8e36085242f793464edd (diff)
downloadengrampa-a043e0a81460a94e0732672afc3831689984caf8.tar.bz2
engrampa-a043e0a81460a94e0732672afc3831689984caf8.tar.xz
Add "Extract to subdirectory" option
This commit adds an "Extract to subdirectory" option to the extract dialog which allows the user to extract the contents of the archive to a directory with the name of the archive (without the extension.) The user will be prompted if the directory must be created. file-utils.c: Improve remove_extension_from_path Rework this function so that it correctly parses and truncates files with multiple extensions like .tar.gz file-utils.c: Improve get_file_extension Improve this function to correctly identify and return supported compressed tar file extensions
-rw-r--r--data/org.mate.engrampa.gschema.xml.in4
-rw-r--r--src/dlg-extract.c16
-rw-r--r--src/file-utils.c37
-rw-r--r--src/fr-window.c22
-rw-r--r--src/fr-window.h1
-rw-r--r--src/preferences.h1
-rw-r--r--src/ui/dlg-extract.ui16
7 files changed, 74 insertions, 23 deletions
diff --git a/data/org.mate.engrampa.gschema.xml.in b/data/org.mate.engrampa.gschema.xml.in
index fed9a1e..5b62190 100644
--- a/data/org.mate.engrampa.gschema.xml.in
+++ b/data/org.mate.engrampa.gschema.xml.in
@@ -154,6 +154,10 @@
<default>false</default>
<summary>Close dialog after decompression</summary>
</key>
+ <key name="create-subdirectory" type="b">
+ <default>false</default>
+ <summary>Create a folder with the archive name and extract there</summary>
+ </key>
</schema>
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.mate.engrampa.dialogs.add" path="/org/mate/engrampa/dialogs/add/">
<key name="current-folder" type="s">
diff --git a/src/dlg-extract.c b/src/dlg-extract.c
index 263528b..6d63059 100644
--- a/src/dlg-extract.c
+++ b/src/dlg-extract.c
@@ -69,6 +69,8 @@ extract_cb (GtkWidget *w,
FrWindow *window = data->window;
gboolean do_not_extract = FALSE;
char *extract_to_dir;
+ char *sub_dir;
+ gboolean extract_sub_dir;
gboolean overwrite;
gboolean skip_newer;
gboolean selected_files;
@@ -179,16 +181,18 @@ extract_cb (GtkWidget *w,
return FALSE;
}
- fr_window_set_extract_default_dir (window, extract_to_dir, TRUE);
-
overwrite = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("overwrite_checkbutton")));
skip_newer = ! gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (GET_WIDGET ("not_newer_checkbutton"))) && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("not_newer_checkbutton")));
junk_paths = ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("recreate_dir_checkbutton")));
+ extract_sub_dir = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("create_subdir_checkbutton")));
g_settings_set_boolean (data->settings, PREF_EXTRACT_OVERWRITE, overwrite);
if (! gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (GET_WIDGET ("not_newer_checkbutton"))))
g_settings_set_boolean (data->settings, PREF_EXTRACT_SKIP_NEWER, skip_newer);
g_settings_set_boolean (data->settings, PREF_EXTRACT_RECREATE_FOLDERS, ! junk_paths);
+ g_settings_set_boolean (data->settings, PREF_EXTRACT_CREATE_SUBDIR, extract_sub_dir);
+
+ fr_window_set_extract_default_dir (window, extract_to_dir, !extract_sub_dir);
selected_files = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("selected_files_radiobutton")));
pattern_files = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("file_pattern_radiobutton")));
@@ -220,6 +224,11 @@ extract_cb (GtkWidget *w,
else
base_dir = NULL;
+ if (extract_sub_dir)
+ sub_dir = remove_extension_from_path (g_filename_display_basename (fr_window_get_archive_uri (window)));
+ else
+ sub_dir = NULL;
+
/* close the dialog. */
gtk_widget_destroy (data->dialog);
@@ -229,6 +238,7 @@ extract_cb (GtkWidget *w,
fr_window_archive_extract (window,
file_list,
extract_to_dir,
+ sub_dir,
base_dir,
skip_newer,
overwrite ? FR_OVERWRITE_YES : FR_OVERWRITE_NO,
@@ -237,6 +247,7 @@ extract_cb (GtkWidget *w,
path_list_free (file_list);
g_free (extract_to_dir);
+ g_free (sub_dir);
g_free (base_dir);
return TRUE;
@@ -331,6 +342,7 @@ dlg_extract__common (FrWindow *window,
}
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("recreate_dir_checkbutton")), g_settings_get_boolean (data->settings, PREF_EXTRACT_RECREATE_FOLDERS));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("create_subdir_checkbutton")), g_settings_get_boolean (data->settings, PREF_EXTRACT_CREATE_SUBDIR));
button = GET_WIDGET ("close_dialog_checkbutton");
g_settings_bind (data->settings,
diff --git a/src/file-utils.c b/src/file-utils.c
index a2b782a..4983a7b 100644
--- a/src/file-utils.c
+++ b/src/file-utils.c
@@ -412,26 +412,16 @@ build_uri (const char *base, ...)
gchar *
remove_extension_from_path (const gchar *path)
{
- int len;
- int p;
- const char *ptr = path;
- char *new_path;
-
- if (! path)
- return NULL;
+ const char *ext;
- len = strlen (path);
- if (len == 1)
- return g_strdup (path);
+ if (path == NULL)
+ return NULL;
- p = len - 1;
- while ((p > 0) && (ptr[p] != '.'))
- p--;
- if (p == 0)
- p = len;
- new_path = g_strndup (path, (guint) p);
-
- return new_path;
+ ext = get_archive_filename_extension (path);
+ if (ext == NULL || strlen (ext) == strlen (path))
+ return g_strdup (path);
+ else
+ return g_strndup (path, strlen (path) - strlen (ext));
}
gboolean
@@ -517,6 +507,7 @@ get_file_extension (const char *filename)
int len;
int p;
const char *ext;
+ const char *tar_exts[] = {".7z", ".br", ".bz", ".bz2", ".gz", ".lrz", ".lz", ".lzma", ".lzo", ".xz", ".Z", ".xst", NULL};
if (filename == NULL)
return NULL;
@@ -532,10 +523,16 @@ get_file_extension (const char *filename)
return NULL;
ext = filename + p;
+ p = 0;
if (ext - 4 > filename) {
const char *test = ext - 4;
- if (strncmp (test, ".tar", 4) == 0)
- ext = ext - 4;
+ if (strncmp (test, ".tar", 4) == 0) {
+ while (tar_exts[p] != NULL) {
+ if (strcmp (ext, tar_exts[p]) == 0)
+ ext = ext - 4;
+ p++;
+ }
+ }
}
return ext;
}
diff --git a/src/fr-window.c b/src/fr-window.c
index 424cad4..cbb0ea6 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -127,6 +127,7 @@ typedef enum {
typedef struct {
GList *file_list;
char *extract_to_dir;
+ char *sub_dir;
char *base_dir;
gboolean skip_older;
FrOverwrite overwrite;
@@ -4181,6 +4182,7 @@ file_list_drag_end (GtkWidget *widget,
fr_window_archive_extract (window,
window->priv->drag_file_list,
window->priv->drag_destination_folder,
+ NULL,
window->priv->drag_base_dir,
FALSE,
FR_OVERWRITE_ASK,
@@ -6310,6 +6312,7 @@ fr_window_archive_remove (FrWindow *window,
static ExtractData*
extract_data_new (GList *file_list,
const char *extract_to_dir,
+ const char *sub_dir,
const char *base_dir,
gboolean skip_older,
FrOverwrite overwrite,
@@ -6318,11 +6321,21 @@ extract_data_new (GList *file_list,
gboolean ask_to_open_destination)
{
ExtractData *edata;
+ int i = 1;
edata = g_new0 (ExtractData, 1);
edata->file_list = path_list_dup (file_list);
- if (extract_to_dir != NULL)
+ if (sub_dir != NULL)
+ edata->sub_dir = g_strdup (sub_dir);
+ if (extract_to_dir != NULL && sub_dir == NULL) {
edata->extract_to_dir = g_strdup (extract_to_dir);
+ } else if (extract_to_dir != NULL && sub_dir != NULL) {
+ edata->extract_to_dir = g_build_filename (extract_to_dir, sub_dir, NULL);
+ while (uri_exists (edata->extract_to_dir) && uri_is_file (edata->extract_to_dir)) {
+ g_free (edata->extract_to_dir);
+ edata->extract_to_dir = g_strdup_printf ("%s/%s_%d", extract_to_dir, sub_dir, i++);
+ }
+ }
edata->skip_older = skip_older;
edata->overwrite = overwrite;
edata->junk_paths = junk_paths;
@@ -6340,6 +6353,7 @@ extract_to_data_new (const char *extract_to_dir)
return extract_data_new (NULL,
extract_to_dir,
NULL,
+ NULL,
FALSE,
TRUE,
FALSE,
@@ -6354,6 +6368,7 @@ extract_data_free (ExtractData *edata)
path_list_free (edata->file_list);
g_free (edata->extract_to_dir);
+ g_free (edata->sub_dir);
g_free (edata->base_dir);
g_free (edata);
@@ -6415,6 +6430,7 @@ fr_window_archive_extract_here (FrWindow *window,
edata = extract_data_new (NULL,
NULL,
NULL,
+ NULL,
skip_older,
overwrite,
junk_paths,
@@ -6630,6 +6646,7 @@ void
fr_window_archive_extract (FrWindow *window,
GList *file_list,
const char *extract_to_dir,
+ const char *sub_dir,
const char *base_dir,
gboolean skip_older,
FrOverwrite overwrite,
@@ -6642,6 +6659,7 @@ fr_window_archive_extract (FrWindow *window,
edata = extract_data_new (file_list,
extract_to_dir,
+ sub_dir,
base_dir,
skip_older,
overwrite,
@@ -8518,6 +8536,7 @@ fr_window_exec_batch_action (FrWindow *window,
fr_window_archive_extract (window,
edata->file_list,
edata->extract_to_dir,
+ edata->sub_dir,
edata->base_dir,
edata->skip_older,
edata->overwrite,
@@ -8544,6 +8563,7 @@ fr_window_exec_batch_action (FrWindow *window,
NULL,
window->priv->extract_default_dir,
NULL,
+ NULL,
FALSE,
FR_OVERWRITE_ASK,
FALSE,
diff --git a/src/fr-window.h b/src/fr-window.h
index 436dd3c..dcbd018 100644
--- a/src/fr-window.h
+++ b/src/fr-window.h
@@ -152,6 +152,7 @@ void fr_window_archive_remove (FrWindow *window,
void fr_window_archive_extract (FrWindow *window,
GList *file_list,
const char *extract_to_dir,
+ const char *sub_dir,
const char *base_dir,
gboolean skip_older,
FrOverwrite overwrite,
diff --git a/src/preferences.h b/src/preferences.h
index 575ffb3..330845e 100644
--- a/src/preferences.h
+++ b/src/preferences.h
@@ -63,6 +63,7 @@
#define PREF_EXTRACT_SKIP_NEWER "skip-newer"
#define PREF_EXTRACT_CLOSE_DIALOG "close-dialog"
#define PREF_EXTRACT_RECREATE_FOLDERS "recreate-folders"
+#define PREF_EXTRACT_CREATE_SUBDIR "create-subdirectory"
#define PREF_ADD_CURRENT_FOLDER "current-folder"
#define PREF_ADD_FILENAME "filename"
diff --git a/src/ui/dlg-extract.ui b/src/ui/dlg-extract.ui
index 745c548..e842512 100644
--- a/src/ui/dlg-extract.ui
+++ b/src/ui/dlg-extract.ui
@@ -304,6 +304,22 @@
<property name="position">2</property>
</packing>
</child>
+ <child>
+ <object class="GtkCheckButton" id="create_subdir_checkbutton">
+ <property name="label" translatable="yes">Extract to s_ubdirectory</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
</child>
</object>