Addl fix #299: File Compression and Archiving
authorColin Clark <colin.clark@cclark.uk>
Wed, 22 Sep 2021 11:46:10 +0000 (12:46 +0100)
committerColin Clark <colin.clark@cclark.uk>
Wed, 22 Sep 2021 11:46:10 +0000 (12:46 +0100)
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
src/layout_image.c
src/misc.c
src/view_file/view_file.c

index a45a025..e79ae30 100644 (file)
@@ -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);
index 7caccf6..949b817 100644 (file)
@@ -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);
index 418f26b..a5a0e65 100644 (file)
@@ -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: */
index fdea435..58ba46b 100644 (file)
@@ -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);