Bug fix #229: File Compression and Archiving
[geeqie.git] / src / view_file / view_file.c
index 5e6674a..1d4eaf3 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"
@@ -77,11 +78,16 @@ FileData *vf_index_get_data(ViewFile *vf, gint row)
 
 gint vf_index_by_fd(ViewFile *vf, FileData *fd)
 {
+       gint ret;
+
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_index_by_fd(vf, fd);
-       case FILEVIEW_ICON: return vficon_index_by_fd(vf, fd);
+       case FILEVIEW_LIST: ret = vflist_index_by_fd(vf, fd); break;
+       case FILEVIEW_ICON: ret = vficon_index_by_fd(vf, fd); break;
+       default: ret = 0;
        }
+
+       return ret;
 }
 
 guint vf_count(ViewFile *vf, gint64 *bytes)
@@ -128,12 +134,16 @@ GList *vf_get_list(ViewFile *vf)
 static gboolean vf_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
        ViewFile *vf = data;
+       gboolean ret;
 
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_press_key_cb(widget, event, data);
-       case FILEVIEW_ICON: return vficon_press_key_cb(widget, event, data);
+       case FILEVIEW_LIST: ret = vflist_press_key_cb(widget, event, data); break;
+       case FILEVIEW_ICON: ret = vficon_press_key_cb(widget, event, data); break;
+       default: ret = FALSE;
        }
+
+       return ret;
 }
 
 /*
@@ -145,23 +155,31 @@ static gboolean vf_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer
 static gboolean vf_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
 {
        ViewFile *vf = data;
+       gboolean ret;
 
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_press_cb(widget, bevent, data);
-       case FILEVIEW_ICON: return vficon_press_cb(widget, bevent, data);
+       case FILEVIEW_LIST: ret = vflist_press_cb(widget, bevent, data); break;
+       case FILEVIEW_ICON: ret = vficon_press_cb(widget, bevent, data); break;
+       default: ret = FALSE;
        }
+
+       return ret;
 }
 
 static gboolean vf_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
 {
        ViewFile *vf = data;
+       gboolean ret;
 
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_release_cb(widget, bevent, data);
-       case FILEVIEW_ICON: return vficon_release_cb(widget, bevent, data);
+       case FILEVIEW_LIST: ret = vflist_release_cb(widget, bevent, data); break;
+       case FILEVIEW_ICON: ret = vficon_release_cb(widget, bevent, data); break;
+       default: ret = FALSE;
        }
+
+       return ret;
 }
 
 
@@ -173,29 +191,44 @@ static gboolean vf_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointe
 
 guint vf_selection_count(ViewFile *vf, gint64 *bytes)
 {
+       guint ret;
+
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_selection_count(vf, bytes);
-       case FILEVIEW_ICON: return vficon_selection_count(vf, bytes);
+       case FILEVIEW_LIST: ret = vflist_selection_count(vf, bytes); break;
+       case FILEVIEW_ICON: ret = vficon_selection_count(vf, bytes); break;
+       default: ret = 0;
        }
+
+       return ret;
 }
 
 GList *vf_selection_get_list(ViewFile *vf)
 {
+       GList *ret;
+
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_selection_get_list(vf);
-       case FILEVIEW_ICON: return vficon_selection_get_list(vf);
+       case FILEVIEW_LIST: ret = vflist_selection_get_list(vf); break;
+       case FILEVIEW_ICON: ret = vficon_selection_get_list(vf); break;
+       default: ret = NULL;
        }
+
+       return ret;
 }
 
 GList *vf_selection_get_list_by_index(ViewFile *vf)
 {
+       GList *ret;
+
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_selection_get_list_by_index(vf);
-       case FILEVIEW_ICON: return vficon_selection_get_list_by_index(vf);
+       case FILEVIEW_LIST: ret = vflist_selection_get_list_by_index(vf); break;
+       case FILEVIEW_ICON: ret = vficon_selection_get_list_by_index(vf); break;
+       default: ret = NULL;
        }
+
+       return ret;
 }
 
 void vf_select_all(ViewFile *vf)
@@ -285,20 +318,30 @@ static void vf_dnd_init(ViewFile *vf)
 
 GList *vf_pop_menu_file_list(ViewFile *vf)
 {
+       GList *ret;
+
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_pop_menu_file_list(vf);
-       case FILEVIEW_ICON: return vficon_pop_menu_file_list(vf);
+       case FILEVIEW_LIST: ret = vflist_pop_menu_file_list(vf); break;
+       case FILEVIEW_ICON: ret = vficon_pop_menu_file_list(vf); break;
+       default: ret = NULL;
        }
+
+       return ret;
 }
 
 GList *vf_selection_get_one(ViewFile *vf, FileData *fd)
 {
+       GList *ret;
+
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_selection_get_one(vf, fd);
-       case FILEVIEW_ICON: return vficon_selection_get_one(vf, fd);
+       case FILEVIEW_LIST: ret = vflist_selection_get_one(vf, fd); break;
+       case FILEVIEW_ICON: ret = vficon_selection_get_one(vf, fd); break;
+       default: ret = NULL;
        }
+
+       return ret;
 }
 
 static void vf_pop_menu_edit_cb(GtkWidget *widget, gpointer data)
@@ -324,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;
@@ -544,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 != NULL && 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 != NULL && VFICON(vf)->click_fd->format_class == FORMAT_CLASS_ARCHIVE);
                break;
        }
 
@@ -615,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);
@@ -698,20 +776,30 @@ GtkWidget *vf_pop_menu(ViewFile *vf)
 
 gboolean vf_refresh(ViewFile *vf)
 {
+       gboolean ret;
+
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_refresh(vf);
-       case FILEVIEW_ICON: return vficon_refresh(vf);
+       case FILEVIEW_LIST: ret = vflist_refresh(vf); break;
+       case FILEVIEW_ICON: ret = vficon_refresh(vf); break;
+       default: ret = FALSE;
        }
+
+       return ret;
 }
 
 gboolean vf_set_fd(ViewFile *vf, FileData *dir_fd)
 {
+       gboolean ret;
+
        switch (vf->type)
        {
-       case FILEVIEW_LIST: return vflist_set_fd(vf, dir_fd);
-       case FILEVIEW_ICON: return vficon_set_fd(vf, dir_fd);
+       case FILEVIEW_LIST: ret = vflist_set_fd(vf, dir_fd); break;
+       case FILEVIEW_ICON: ret = vficon_set_fd(vf, dir_fd); break;
+       default: ret = FALSE;
        }
+
+       return ret;
 }
 
 static void vf_destroy_cb(GtkWidget *widget, gpointer data)
@@ -1625,7 +1713,7 @@ void vf_notify_cb(FileData *fd, NotifyType type, gpointer data)
 
        NotifyType interested = NOTIFY_CHANGE | NOTIFY_REREAD | NOTIFY_GROUPING;
        if (vf->marks_enabled) interested |= NOTIFY_MARKS | NOTIFY_METADATA;
-       /* FIXME: NOTIFY_METADATA should be checked by the keyword-to-mark functions and converted to NOTIFY_MARKS only if there was a change */
+       /** @FIXME NOTIFY_METADATA should be checked by the keyword-to-mark functions and converted to NOTIFY_MARKS only if there was a change */
 
        if (!(type & interested) || vf->refresh_idle_id || !vf->dir_fd) return;