From 6c10b619698d68cfc9ce6c22b0a1366f028187eb Mon Sep 17 00:00:00 2001 From: Colin Clark Date: Wed, 22 Sep 2021 12:46:10 +0100 Subject: [PATCH] Addl fix #299: File Compression and Archiving https://github.com/BestImageViewer/geeqie/issues/299 Improve error handling. Update list of archive file types. Open archive file on right-click. --- src/filefilter.c | 2 +- src/layout_image.c | 27 +++++++++++++++++++++++++++ src/misc.c | 30 +++++++++++++++++++++++++----- src/view_file/view_file.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 6 deletions(-) diff --git a/src/filefilter.c b/src/filefilter.c index a45a025f..e79ae30a 100644 --- a/src/filefilter.c +++ b/src/filefilter.c @@ -308,7 +308,7 @@ void filter_add_defaults(void) filter_add_if_missing("jp2", "JPEG 2000", ".jp2", FORMAT_CLASS_IMAGE, FALSE, FALSE, TRUE); #endif #ifdef HAVE_ARCHIVE - filter_add_if_missing("zip", "Archive files", ".zip;.rar;.tar;.tar.gz;.cbr;.cbz;.bz2;.lzh;.lza;.7z", FORMAT_CLASS_ARCHIVE, FALSE, FALSE, TRUE); + filter_add_if_missing("zip", "Archive files", ".zip;.rar;.tar;.tar.gz;.tar.bz2;.tar.xz;.tgz;.tbz;.txz;.cbr;.cbz;.gz;.bz2;.xz;.lzh;.lza;.7z", FORMAT_CLASS_ARCHIVE, FALSE, FALSE, TRUE); #endif filter_add_if_missing("psd", "Adobe Photoshop Document", ".psd", FORMAT_CLASS_IMAGE, FALSE, FALSE, TRUE); filter_add_if_missing("apng", "Animated Portable Network Graphic", ".apng", FORMAT_CLASS_IMAGE, FALSE, FALSE, TRUE); diff --git a/src/layout_image.c b/src/layout_image.c index 7caccf69..949b8175 100644 --- a/src/layout_image.c +++ b/src/layout_image.c @@ -681,6 +681,27 @@ static void li_set_layout_path_cb(GtkWidget *widget, gpointer data) if (fd) layout_set_fd(lw, fd); } +static void li_open_archive_cb(GtkWidget *widget, gpointer data) +{ + LayoutWindow *lw = data; + LayoutWindow *lw_new; + gchar *dest_dir; + + if (!layout_valid(&lw)) return; + + dest_dir = open_archive(layout_image_get_fd(lw)); + if (dest_dir) + { + lw_new = layout_new_from_default(); + layout_set_path(lw_new, dest_dir); + g_free(dest_dir); + } + else + { + warning_dialog(_("Cannot open archive file"), _("See the Log Window"), GTK_STOCK_DIALOG_WARNING, NULL); + } +} + static gboolean li_check_if_current_path(LayoutWindow *lw, const gchar *path) { gchar *dirname; @@ -774,6 +795,12 @@ static GtkWidget *layout_image_pop_menu(LayoutWindow *lw) item = menu_item_add(menu, _("_Go to directory view"), G_CALLBACK(li_set_layout_path_cb), lw); if (!path || li_check_if_current_path(lw, path)) gtk_widget_set_sensitive(item, FALSE); + item = menu_item_add_stock(menu, _("Open archive"), GTK_STOCK_OPEN, G_CALLBACK(li_open_archive_cb), lw); + if (!path || lw->image->image_fd->format_class != FORMAT_CLASS_ARCHIVE) + { + gtk_widget_set_sensitive(item, FALSE); + } + menu_item_add_divider(menu); item = menu_item_add_stock(menu, _("_Copy..."), GTK_STOCK_COPY, G_CALLBACK(li_pop_menu_copy_cb), lw); diff --git a/src/misc.c b/src/misc.c index 418f26b1..a5a0e658 100644 --- a/src/misc.c +++ b/src/misc.c @@ -433,18 +433,38 @@ gchar *open_archive(FileData *fd) gchar *current_dir; gchar *destination_dir; gboolean success; + gint error; destination_dir = g_build_filename(g_get_tmp_dir(), GQ_ARCHIVE_DIR, instance_identifier, fd->path, NULL); - recursive_mkdir_if_not_exists(destination_dir, 0755); + if (!recursive_mkdir_if_not_exists(destination_dir, 0755)) + { + log_printf("%s%s%s", _("Open Archive - Cannot create directory: "), destination_dir, "\n"); + g_free(destination_dir); + return NULL; + } current_dir = g_get_current_dir(); - chdir(destination_dir); + error = chdir(destination_dir); + if (error) + { + log_printf("%s%s%s%s%s", _("Open Archive - Cannot change directory to: "), destination_dir, _("\n Error code: "), strerror(errno), "\n"); + g_free(destination_dir); + g_free(current_dir); + return NULL; + } flags = ARCHIVE_EXTRACT_TIME; success = extract(fd->path, 1, flags); - chdir(current_dir); + error = chdir(current_dir); + if (error) + { + log_printf("%s%s%s%s%s", _("Open Archive - Cannot change directory to: "), current_dir, _("\n Error code: "), strerror(errno), "\n"); + g_free(destination_dir); + g_free(current_dir); + return NULL; + } g_free(current_dir); if (!success) @@ -563,7 +583,7 @@ static int copy_data(struct archive *ar, struct archive *aw) static void msg(const char *m) { - log_printf("%s \n", m); + log_printf("Open Archive - libarchive error: %s \n", m); } static void errmsg(const char *m) @@ -572,7 +592,7 @@ static void errmsg(const char *m) { m = "Error: No error description provided.\n"; } - log_printf("%s \n", m); + log_printf("Open Archive - libarchive error: %s \n", m); } #endif /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/view_file/view_file.c b/src/view_file/view_file.c index fdea4356..58ba46b4 100644 --- a/src/view_file/view_file.c +++ b/src/view_file/view_file.c @@ -28,6 +28,7 @@ #include "history_list.h" #include "layout.h" #include "menu.h" +#include "misc.h" #include "pixbuf_util.h" #include "thumb.h" #include "ui_menu.h" @@ -366,6 +367,36 @@ static void vf_pop_menu_view_cb(GtkWidget *widget, gpointer data) } } +static void vf_pop_menu_open_archive_cb(GtkWidget *widget, gpointer data) +{ + ViewFile *vf = data; + LayoutWindow *lw_new; + FileData *fd; + gchar *dest_dir; + + switch (vf->type) + { + case FILEVIEW_LIST: + fd = (VFLIST(vf)->click_fd); + break; + case FILEVIEW_ICON: + fd = (VFICON(vf)->click_fd); + break; + } + + dest_dir = open_archive(fd); + if (dest_dir) + { + lw_new = layout_new_from_default(); + layout_set_path(lw_new, dest_dir); + g_free(dest_dir); + } + else + { + warning_dialog(_("Cannot open archive file"), _("See the Log Window"), GTK_STOCK_DIALOG_WARNING, NULL); + } +} + static void vf_pop_menu_copy_cb(GtkWidget *widget, gpointer data) { ViewFile *vf = data; @@ -586,15 +617,18 @@ GtkWidget *vf_pop_menu(ViewFile *vf) GtkWidget *item; GtkWidget *submenu; gboolean active = FALSE; + gboolean class_archive = FALSE; switch (vf->type) { case FILEVIEW_LIST: vflist_color_set(vf, VFLIST(vf)->click_fd, TRUE); active = (VFLIST(vf)->click_fd != NULL); + class_archive = (VFLIST(vf)->click_fd->format_class == FORMAT_CLASS_ARCHIVE); break; case FILEVIEW_ICON: active = (VFICON(vf)->click_fd != NULL); + class_archive = (VFICON(vf)->click_fd->format_class == FORMAT_CLASS_ARCHIVE); break; } @@ -657,6 +691,8 @@ GtkWidget *vf_pop_menu(ViewFile *vf) menu_item_add_stock_sensitive(menu, _("View in _new window"), GTK_STOCK_NEW, active, G_CALLBACK(vf_pop_menu_view_cb), vf); + menu_item_add_stock_sensitive(menu, _("Open archive"), GTK_STOCK_OPEN, active & class_archive, G_CALLBACK(vf_pop_menu_open_archive_cb), vf); + menu_item_add_divider(menu); menu_item_add_stock_sensitive(menu, _("_Copy..."), GTK_STOCK_COPY, active, G_CALLBACK(vf_pop_menu_copy_cb), vf); -- 2.20.1