Mercurial > hg > forks > geeqie
view src/image_load_collection.c @ 2798:d9764817aad8
Collection preview
If the folder containing collection files (usually
$HOME/.local/share/geeqie/collections) is opened, the image pane will
show a montage of the thumbnails (to a maximum of 20) of the images in
the selected collection.
Requires ImageMagick.
This is a simplistic implementation, and should be improved e.g.
Use collect-io.c to parse the collection file
Use cached thumbnails instead of re-creating
Use Geeqie to create the montage instead of using ImageMagick
author | Colin Clark <colin.clark@cclark.uk> |
---|---|
date | Wed, 18 Jul 2018 10:16:41 +0100 |
parents | |
children | 0ecd4885dc09 |
line wrap: on
line source
/* * Copyright (C) 20018 - The Geeqie Team * * Author: Colin Clark * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "main.h" #include "image-load.h" #include "image_load_collection.h" #include "misc.h" typedef struct _ImageLoaderCOLLECTION ImageLoaderCOLLECTION; struct _ImageLoaderCOLLECTION { ImageLoaderBackendCbAreaUpdated area_updated_cb; ImageLoaderBackendCbSize size_cb; ImageLoaderBackendCbAreaPrepared area_prepared_cb; gpointer data; GdkPixbuf *pixbuf; guint requested_width; guint requested_height; gboolean abort; }; static gboolean image_loader_collection_load(gpointer loader, const guchar *buf, gsize count, GError **error) { ImageLoaderCOLLECTION *ld = (ImageLoaderCOLLECTION *) loader; ImageLoader *il = ld->data; #define LINE_LENGTH 1000 #define MAX_LINES 23 gboolean ret = FALSE; gchar *randname; gchar *cmd_line; FILE *fp = NULL; gint line_count = 0; GString *file_names = g_string_new(NULL); gchar line[LINE_LENGTH]; if (runcmd("which montage >/dev/null 2>&1") == 0) { fp = fopen(il->fd->path, "r"); if (fp) { while(fgets(line, LINE_LENGTH, fp) && line_count < MAX_LINES) { /* get rid of ending \n from fgets */ line[strlen(line) - 1] = '\0'; if (line[0] && line[0] != '#') { file_names = g_string_append(file_names, line); file_names = g_string_append(file_names, " "); } line_count++; } fclose(fp); if (file_names->len > 0) { randname = g_strdup("geeqie_collection_XXXXXX.png"); g_mkstemp(randname); cmd_line = g_strdup_printf("montage %s -geometry %dx%d+1+1 %s >/dev/null 2>&1", file_names->str, options->thumbnails.max_width, options->thumbnails.max_height, randname); runcmd(cmd_line); ld->pixbuf = gdk_pixbuf_new_from_file(randname, NULL); if (ld->pixbuf) { ld->area_updated_cb(loader, 0, 0, gdk_pixbuf_get_width(ld->pixbuf), gdk_pixbuf_get_height(ld->pixbuf), ld->data); } unlink(randname); g_free(randname); g_string_free(file_names, TRUE); g_free(cmd_line); ret = TRUE; } else { g_string_free(file_names, TRUE); } } } return ret; } static gpointer image_loader_collection_new(ImageLoaderBackendCbAreaUpdated area_updated_cb, ImageLoaderBackendCbSize size_cb, ImageLoaderBackendCbAreaPrepared area_prepared_cb, gpointer data) { ImageLoaderCOLLECTION *loader = g_new0(ImageLoaderCOLLECTION, 1); loader->area_updated_cb = area_updated_cb; loader->size_cb = size_cb; loader->area_prepared_cb = area_prepared_cb; loader->data = data; return (gpointer) loader; } static void image_loader_collection_set_size(gpointer loader, int width, int height) { ImageLoaderCOLLECTION *ld = (ImageLoaderCOLLECTION *) loader; ld->requested_width = width; ld->requested_height = height; } static GdkPixbuf* image_loader_collection_get_pixbuf(gpointer loader) { ImageLoaderCOLLECTION *ld = (ImageLoaderCOLLECTION *) loader; return ld->pixbuf; } static gchar* image_loader_collection_get_format_name(gpointer loader) { return g_strdup("collection"); } static gchar** image_loader_collection_get_format_mime_types(gpointer loader) { static gchar *mime[] = {"image/png", NULL}; return g_strdupv(mime); } static gboolean image_loader_collection_close(gpointer loader, GError **error) { return TRUE; } static void image_loader_collection_abort(gpointer loader) { ImageLoaderCOLLECTION *ld = (ImageLoaderCOLLECTION *) loader; ld->abort = TRUE; } static void image_loader_collection_free(gpointer loader) { ImageLoaderCOLLECTION *ld = (ImageLoaderCOLLECTION *) loader; if (ld->pixbuf) g_object_unref(ld->pixbuf); g_free(ld); } void image_loader_backend_set_collection(ImageLoaderBackend *funcs) { funcs->loader_new = image_loader_collection_new; funcs->set_size = image_loader_collection_set_size; funcs->load = image_loader_collection_load; funcs->write = NULL; funcs->get_pixbuf = image_loader_collection_get_pixbuf; funcs->close = image_loader_collection_close; funcs->abort = image_loader_collection_abort; funcs->free = image_loader_collection_free; funcs->get_format_name = image_loader_collection_get_format_name; funcs->get_format_mime_types = image_loader_collection_get_format_mime_types; } /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */