📄 collect-io.c
字号:
/* * GQview * (C) 2004 John Ellis * * Author: John Ellis * * This software is released under the GNU General Public License (GNU GPL). * Please read the included file COPYING for more information. * This software comes with no warranty of any kind, use at your own risk! */#include "gqview.h"#include "collect-io.h"#include "collect.h"#include "layout_util.h"#include "rcfile.h"#include "thumb.h"#include "ui_fileops.h"#define GQVIEW_COLLECTION_MARKER "#GQview"#define GQVIEW_COLLECTION_FAIL_MIN 300#define GQVIEW_COLLECTION_FAIL_PERCENT 98static void collection_load_thumb_step(CollectionData *cd);static gint scan_geometry(gchar *buffer, gint *x, gint *y, gint *w, gint *h){ gint nx, ny, nw, nh; if(sscanf(buffer, "%d %d %d %d", &nx, &ny, &nw, &nh) != 4) return FALSE; *x = nx; *y = ny; *w = nw; *h = nh; return TRUE;}static gint collection_load_private(CollectionData *cd, const gchar *path, gint append, gint flush){ gchar s_buf[2048]; FILE *f; gchar *pathl; gint official = FALSE; gint success = TRUE; guint total = 0; guint fail = 0; collection_load_stop(cd); if (flush) collect_manager_flush(); if (!append) { collection_list_free(cd->list); cd->list = NULL; } if (!path && !cd->path) return FALSE; if (!path) path = cd->path; /* load it */ pathl = path_from_utf8(path); f = fopen(pathl, "r"); g_free(pathl); if (!f) { printf("Failed to open collection file: \"%s\"\n", path); return FALSE; } while (fgets(s_buf, sizeof(s_buf), f)) { gchar *buf; if (s_buf[0]=='#') { if (strncasecmp(s_buf, GQVIEW_COLLECTION_MARKER, strlen(GQVIEW_COLLECTION_MARKER)) == 0) { /* Looks like an official collection, allow unchecked input. * All this does is allow adding files that may not exist, * which is needed for the collection manager to work. * Also unofficial files abort after too many invalid entries. */ official = TRUE; } else if (strncmp(s_buf, "#geometry:", 10 ) == 0 && scan_geometry(s_buf + 10, &cd->window_x, &cd->window_y, &cd->window_w, &cd->window_h) ) { cd->window_read = TRUE; } continue; } if (s_buf[0]=='\n') continue; buf = quoted_value(s_buf); if (buf) { gint valid; valid = (buf[0] == '/' && collection_add_check(cd, buf, FALSE, flush)); g_free(buf); total++; if (!valid && !official) { fail++; if (fail > GQVIEW_COLLECTION_FAIL_MIN && fail * 100 / total > GQVIEW_COLLECTION_FAIL_PERCENT) { printf("Too many invalid filenames in unoffical collection file, closing: %s\n", path); success = FALSE; break; } } } } fclose(f); cd->list = collection_list_sort(cd->list, cd->sort_method); if (!append) cd->changed = FALSE; return success;}gint collection_load(CollectionData *cd, const gchar *path, gint append){ if (collection_load_private(cd, path, append, TRUE)) { layout_recent_add_path(cd->path); return TRUE; } return FALSE;}static void collection_load_thumb_do(CollectionData *cd){ GdkPixbuf *pixbuf; if (!cd->thumb_loader || !g_list_find(cd->list, cd->thumb_info)) return; pixbuf = thumb_loader_get_pixbuf(cd->thumb_loader, TRUE); collection_info_set_thumb(cd->thumb_info, pixbuf); g_object_unref(pixbuf); if (cd->info_updated_func) cd->info_updated_func(cd, cd->thumb_info, cd->info_updated_data);}static void collection_load_thumb_error_cb(ThumbLoader *tl, gpointer data){ CollectionData *cd = data; collection_load_thumb_do(cd); collection_load_thumb_step(cd);}static void collection_load_thumb_done_cb(ThumbLoader *tl, gpointer data){ CollectionData *cd = data; collection_load_thumb_do(cd); collection_load_thumb_step(cd);}static void collection_load_thumb_step(CollectionData *cd){ GList *work; CollectInfo *ci; if (!cd->list) { collection_load_stop(cd); return; } work = cd->list; ci = work->data; work = work->next; /* find first unloaded thumb */ while (work && ci->pixbuf) { ci = work->data; work = work->next; } if (!ci || ci->pixbuf) { /* done */ collection_load_stop(cd); /* send a NULL CollectInfo to notify end */ if (cd->info_updated_func) cd->info_updated_func(cd, NULL, cd->info_updated_data); return; } /* setup loader and call it */ cd->thumb_info = ci; thumb_loader_free(cd->thumb_loader); cd->thumb_loader = thumb_loader_new(thumb_max_width, thumb_max_height); thumb_loader_set_callbacks(cd->thumb_loader, collection_load_thumb_done_cb, collection_load_thumb_error_cb, NULL, cd); /* start it */ if (!thumb_loader_start(cd->thumb_loader, ci->path)) { /* error, handle it, do next */ if (debug) printf("error loading thumb for %s\n", ci->path); collection_load_thumb_do(cd); collection_load_thumb_step(cd); }}void collection_load_thumb_idle(CollectionData *cd){ if (!cd->thumb_loader) collection_load_thumb_step(cd);}gint collection_load_begin(CollectionData *cd, const gchar *path, gint append){ if (!collection_load(cd, path, append)) return FALSE; collection_load_thumb_idle(cd); return TRUE;}void collection_load_stop(CollectionData *cd){ if (!cd->thumb_loader) return; thumb_loader_free(cd->thumb_loader); cd->thumb_loader = NULL;}static gint collection_save_private(CollectionData *cd, const gchar *path){ FILE *f; GList *work; gchar *tmp_path; gchar *pathl; mode_t save_mask; if (!path && !cd->path) return FALSE; if (!path) { path = cd->path; } tmp_path = unique_filename(path, ".tmp", "_", 3); if (!tmp_path) return FALSE; pathl = path_from_utf8(tmp_path); save_mask = umask(0077); f = fopen(pathl, "w"); umask(save_mask); g_free(pathl); if (!f) { /* file open failed */ printf("failed to open collection (write) \"%s\"\n", tmp_path); g_free(tmp_path); return FALSE; } fprintf(f, "%s collection\n", GQVIEW_COLLECTION_MARKER); fprintf(f, "#created with GQview version %s\n", VERSION); collection_update_geometry(cd); if (cd->window_read) { fprintf(f, "#geometry: %d %d %d %d\n", cd->window_x, cd->window_y, cd->window_w, cd->window_h); } work = cd->list; while (work) { CollectInfo *ci = work->data; if (fprintf(f, "\"%s\"\n", ci->path) < 0) { fclose(f); printf("Error writing to %s\n", tmp_path); unlink_file(tmp_path); g_free(tmp_path); return FALSE; } work = work->next; } fprintf(f, "#end\n"); fclose(f); copy_file_attributes(path, tmp_path, TRUE, FALSE); if (!rename_file(tmp_path, path)) { printf("collection save unable to rename %s to %s\n", tmp_path, path); unlink_file(tmp_path); g_free(tmp_path); return FALSE; } g_free(tmp_path); if (!cd->path || strcmp(path, cd->path) != 0) { gchar *buf = cd->path; cd->path = g_strdup(path); path = cd->path; g_free(buf); g_free(cd->name); cd->name = g_strdup(filename_from_path(cd->path)); collection_path_changed(cd); } cd->changed = FALSE; return TRUE;}gint collection_save(CollectionData *cd, const gchar *path){ if (collection_save_private(cd, path)) { layout_recent_add_path(cd->path); return TRUE; } return FALSE;}gint collection_load_only_geometry(CollectionData *cd, const gchar *path){ gchar s_buf[2048]; FILE *f; gchar *pathl; if (!path && !cd->path) return FALSE; if (!path) path = cd->path; /* load it */ pathl = path_from_utf8(path); f = fopen(pathl, "r"); g_free(pathl); if (!f) return FALSE; while (fgets(s_buf, sizeof(s_buf), f)) { if (s_buf[0]=='#' && strncmp(s_buf, "#geometry:", 10 ) == 0 && scan_geometry(s_buf + 10, &cd->window_x, &cd->window_y, &cd->window_w, &cd->window_h) ) { cd->window_read = TRUE; fclose(f); return TRUE; } } fclose(f); return FALSE;}/* *------------------------------------------------------------------- * collection manager *------------------------------------------------------------------- */#define COLLECT_MANAGER_ACTIONS_PER_IDLE 1000#define COLLECT_MANAGER_FLUSH_DELAY 10000typedef struct _CollectManagerEntry CollectManagerEntry;struct _CollectManagerEntry{ gchar *path; GList *action_list;};typedef enum { COLLECTION_MANAGER_UPDATE,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -