X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?p=geeqie.git;a=blobdiff_plain;f=src%2Fcollect-io.c;h=bb9967d424ba5602a3e7753147e8cb13660ce6ab;hp=fd515e6ac209b1423ea594142edb01e8eb540bd6;hb=c4114f7d7b6baa193ba4fbeb8693becfcd256943;hpb=1d1cbd4e738681d0fa7c06d3065974e6bdae9dfe diff --git a/src/collect-io.c b/src/collect-io.c index fd515e6a..bb9967d4 100644 --- a/src/collect-io.c +++ b/src/collect-io.c @@ -1,6 +1,7 @@ /* - * GQview + * Geeqie * (C) 2004 John Ellis + * Copyright (C) 2008 - 2012 The Geeqie Team * * Author: John Ellis * @@ -10,30 +11,38 @@ */ -#include "gqview.h" +#include "main.h" #include "collect-io.h" #include "collect.h" +#include "filedata.h" #include "layout_util.h" -#include "rcfile.h" +#include "misc.h" +#include "secure_save.h" #include "thumb.h" #include "ui_fileops.h" +#define GQ_COLLECTION_MARKER "#" GQ_APPNAME -#define GQVIEW_COLLECTION_MARKER "#GQview" - -#define GQVIEW_COLLECTION_FAIL_MIN 300 -#define GQVIEW_COLLECTION_FAIL_PERCENT 98 +#define GQ_COLLECTION_FAIL_MIN 300 +#define GQ_COLLECTION_FAIL_PERCENT 98 +#define GQ_COLLECTION_READ_BUFSIZE 4096 +typedef struct _CollectManagerEntry CollectManagerEntry; static void collection_load_thumb_step(CollectionData *cd); +static gint collection_save_private(CollectionData *cd, const gchar *path); + +static CollectManagerEntry *collect_manager_get_entry(const gchar *path); +static void collect_manager_entry_reset(CollectManagerEntry *entry); +static gint collect_manager_process_action(CollectManagerEntry *entry, gchar **path_ptr); -static gint scan_geometry(gchar *buffer, gint *x, gint *y, gint *w, gint *h) +static gboolean 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; + if (sscanf(buffer, "%d %d %d %d", &nx, &ny, &nw, &nh) != 4) return FALSE; *x = nx; *y = ny; @@ -43,79 +52,126 @@ static gint scan_geometry(gchar *buffer, gint *x, gint *y, gint *w, gint *h) return TRUE; } -static gint collection_load_private(CollectionData *cd, const gchar *path, gint append, gint flush) +static gboolean collection_load_private(CollectionData *cd, const gchar *path, CollectionLoadFlags flags) { - gchar s_buf[2048]; + gchar s_buf[GQ_COLLECTION_READ_BUFSIZE]; FILE *f; gchar *pathl; - gint official = FALSE; - gint success = TRUE; + gboolean limit_failures = TRUE; + gboolean success = TRUE; + gboolean has_official_header = FALSE; + gboolean has_geometry_header = FALSE; + gboolean has_gqview_header = FALSE; + gboolean need_header = TRUE; guint total = 0; guint fail = 0; + gboolean changed = FALSE; + CollectManagerEntry *entry = NULL; + guint flush = !!(flags & COLLECTION_LOAD_FLUSH); + guint append = !!(flags & COLLECTION_LOAD_APPEND); + guint only_geometry = !!(flags & COLLECTION_LOAD_GEOMETRY); - collection_load_stop(cd); + if (!only_geometry) + { + collection_load_stop(cd); - if (flush) collect_manager_flush(); + if (flush) + collect_manager_flush(); + else + entry = collect_manager_get_entry(path); - if (!append) - { - collection_list_free(cd->list); - cd->list = NULL; + if (!append) + { + collection_list_free(cd->list); + cd->list = NULL; + } } if (!path && !cd->path) return FALSE; if (!path) path = cd->path; + DEBUG_1("collection load: append=%d flush=%d only_geometry=%d path=%s", + append, flush, only_geometry, 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); + log_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]=='#') + gchar *p = s_buf; + + /* Skip whitespaces and empty lines */ + while (*p && g_ascii_isspace(*p)) p++; + if (*p == '\n' || *p == '\r') continue; + + /* Parse comments */ + if (*p == '#') { - if (strncasecmp(s_buf, GQVIEW_COLLECTION_MARKER, strlen(GQVIEW_COLLECTION_MARKER)) == 0) + if (!need_header) continue; + if (g_ascii_strncasecmp(p, GQ_COLLECTION_MARKER, strlen(GQ_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; + has_official_header = TRUE; + limit_failures = FALSE; } - 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) ) + else if (strncmp(p, "#geometry:", 10 ) == 0 && + scan_geometry(p + 10, &cd->window_x, &cd->window_y, &cd->window_w, &cd->window_h)) { + has_geometry_header = TRUE; cd->window_read = TRUE; + if (only_geometry) break; } + else if (g_ascii_strncasecmp(p, "#GQview collection", strlen("#GQview collection")) == 0) + { + /* As 2008/04/15 there is no difference between our collection file format + * and GQview 2.1.5 collection file format so ignore failures as well. */ + has_gqview_header = TRUE; + limit_failures = FALSE; + } + need_header = (!has_official_header && !has_gqview_header) || !has_geometry_header; continue; } - if (s_buf[0]=='\n') continue; - buf = quoted_value(s_buf); - if (buf) + if (only_geometry) continue; + + /* Read filenames */ + while (*p && *p != '"') p++; + if (*p) p++; + buf = p; + while (*p && *p != '"') p++; + *p = 0; + if (*buf) { - gint valid; + gboolean valid; - valid = (buf[0] == '/' && collection_add_check(cd, buf, FALSE, flush)); - g_free(buf); + if (!flush) + changed |= collect_manager_process_action(entry, &buf); + + valid = (buf[0] == G_DIR_SEPARATOR && collection_add_check(cd, file_data_new_group(buf), FALSE, TRUE)); + if (!valid) DEBUG_1("collection invalid file: %s", buf); total++; - if (!valid && !official) + if (!valid) { fail++; - if (fail > GQVIEW_COLLECTION_FAIL_MIN && - fail * 100 / total > GQVIEW_COLLECTION_FAIL_PERCENT) + if (limit_failures && + fail > GQ_COLLECTION_FAIL_MIN && + fail * 100 / total > GQ_COLLECTION_FAIL_PERCENT) { - printf("Too many invalid filenames in unoffical collection file, closing: %s\n", path); + log_printf("%d invalid filenames in unofficial collection file, closing: %s\n", fail, path); success = FALSE; break; } @@ -123,17 +179,40 @@ static gint collection_load_private(CollectionData *cd, const gchar *path, gint } } + DEBUG_1("collection files: total = %d fail = %d official=%d gqview=%d geometry=%d", + total, fail, has_official_header, has_gqview_header, has_geometry_header); + fclose(f); + if (only_geometry) return has_geometry_header; + + if (!flush) + { + gchar *buf = NULL; + while (collect_manager_process_action(entry, &buf)) + { + collection_add_check(cd, file_data_new_group(buf), FALSE, TRUE); + changed = TRUE; + g_free(buf); + buf = NULL; + } + } cd->list = collection_list_sort(cd->list, cd->sort_method); + + if (!flush && changed && success) + collection_save_private(cd, path); + + if (!flush) + collect_manager_entry_reset(entry); + if (!append) cd->changed = FALSE; return success; } -gint collection_load(CollectionData *cd, const gchar *path, gint append) +gboolean collection_load(CollectionData *cd, const gchar *path, CollectionLoadFlags flags) { - if (collection_load_private(cd, path, append, TRUE)) + if (collection_load_private(cd, path, flags | COLLECTION_LOAD_FLUSH)) { layout_recent_add_path(cd->path); return TRUE; @@ -148,7 +227,7 @@ static void collection_load_thumb_do(CollectionData *cd) if (!cd->thumb_loader || !g_list_find(cd->list, cd->thumb_info)) return; - pixbuf = thumb_loader_get_pixbuf(cd->thumb_loader, TRUE); + pixbuf = thumb_loader_get_pixbuf(cd->thumb_loader); collection_info_set_thumb(cd->thumb_info, pixbuf); g_object_unref(pixbuf); @@ -206,7 +285,7 @@ static void collection_load_thumb_step(CollectionData *cd) /* 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); + cd->thumb_loader = thumb_loader_new(options->thumbnails.max_width, options->thumbnails.max_height); thumb_loader_set_callbacks(cd->thumb_loader, collection_load_thumb_done_cb, collection_load_thumb_error_cb, @@ -214,10 +293,10 @@ static void collection_load_thumb_step(CollectionData *cd) cd); /* start it */ - if (!thumb_loader_start(cd->thumb_loader, ci->path)) + if (!thumb_loader_start(cd->thumb_loader, ci->fd)) { /* error, handle it, do next */ - if (debug) printf("error loading thumb for %s\n", ci->path); + DEBUG_1("error loading thumb for %s", ci->fd->path); collection_load_thumb_do(cd); collection_load_thumb_step(cd); } @@ -228,9 +307,9 @@ 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) +gboolean collection_load_begin(CollectionData *cd, const gchar *path, CollectionLoadFlags flags) { - if (!collection_load(cd, path, append)) return FALSE; + if (!collection_load(cd, path, flags)) return FALSE; collection_load_thumb_idle(cd); @@ -245,13 +324,11 @@ void collection_load_stop(CollectionData *cd) cd->thumb_loader = NULL; } -static gint collection_save_private(CollectionData *cd, const gchar *path) +static gboolean collection_save_private(CollectionData *cd, const gchar *path) { - FILE *f; + SecureSaveInfo *ssi; GList *work; - gchar *tmp_path; gchar *pathl; - mode_t save_mask; if (!path && !cd->path) return FALSE; @@ -260,62 +337,42 @@ static gint collection_save_private(CollectionData *cd, const gchar *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); + pathl = path_from_utf8(path); + ssi = secure_open(pathl); g_free(pathl); - - if (!f) + if (!ssi) { - /* file open failed */ - printf("failed to open collection (write) \"%s\"\n", tmp_path); - g_free(tmp_path); + log_printf(_("failed to open collection (write) \"%s\"\n"), path); return FALSE; } - fprintf(f, "%s collection\n", GQVIEW_COLLECTION_MARKER); - fprintf(f, "#created with GQview version %s\n", VERSION); + secure_fprintf(ssi, "%s collection\n", GQ_COLLECTION_MARKER); + secure_fprintf(ssi, "#created with %s version %s\n", GQ_APPNAME, 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); + secure_fprintf(ssi, "#geometry: %d %d %d %d\n", cd->window_x, cd->window_y, cd->window_w, cd->window_h); } work = cd->list; - while (work) + while (work && secsave_errno == SS_ERR_NONE) { 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; - } + secure_fprintf(ssi, "\"%s\"\n", ci->fd->path); work = work->next; } - fprintf(f, "#end\n"); - - fclose(f); + secure_fprintf(ssi, "#end\n"); - copy_file_attributes(path, tmp_path, TRUE, FALSE); - if (!rename_file(tmp_path, path)) + if (secure_close(ssi)) { - printf("collection save unable to rename %s to %s\n", tmp_path, path); - unlink_file(tmp_path); - g_free(tmp_path); + log_printf(_("error saving collection file: %s\nerror: %s\n"), path, + secsave_strerror(secsave_errno)); return FALSE; } - g_free(tmp_path); - if (!cd->path || strcmp(path, cd->path) != 0) { gchar *buf = cd->path; @@ -334,7 +391,7 @@ static gint collection_save_private(CollectionData *cd, const gchar *path) return TRUE; } -gint collection_save(CollectionData *cd, const gchar *path) +gboolean collection_save(CollectionData *cd, const gchar *path) { if (collection_save_private(cd, path)) { @@ -345,35 +402,9 @@ gint collection_save(CollectionData *cd, const gchar *path) return FALSE; } -gint collection_load_only_geometry(CollectionData *cd, const gchar *path) +gboolean 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; + return collection_load(cd, path, COLLECTION_LOAD_GEOMETRY); } @@ -386,11 +417,13 @@ gint collection_load_only_geometry(CollectionData *cd, const gchar *path) #define COLLECT_MANAGER_ACTIONS_PER_IDLE 1000 #define COLLECT_MANAGER_FLUSH_DELAY 10000 -typedef struct _CollectManagerEntry CollectManagerEntry; struct _CollectManagerEntry { gchar *path; - GList *action_list; + GList *add_list; + GHashTable *oldpath_hash; + GHashTable *newpath_hash; + gboolean empty; }; typedef enum { @@ -414,7 +447,7 @@ struct _CollectManagerAction static GList *collection_manager_entry_list = NULL; static GList *collection_manager_action_list = NULL; static GList *collection_manager_action_tail = NULL; -static gint collection_manager_timer_id = -1; +static guint collection_manager_timer_id = 0; /* event source id */ static CollectManagerAction *collect_manager_action_new(const gchar *oldpath, const gchar *newpath, @@ -449,50 +482,206 @@ static void collect_manager_action_unref(CollectManagerAction *action) g_free(action); } +static void collect_manager_entry_free_data(CollectManagerEntry *entry) +{ + GList *work; + + work = entry->add_list; + while (work) + { + CollectManagerAction *action; + + action = work->data; + work = work->next; + + collect_manager_action_unref(action); + } + g_list_free(entry->add_list); + if (g_hash_table_size(entry->oldpath_hash) > 0) + g_hash_table_destroy(entry->oldpath_hash); + else + g_hash_table_unref(entry->oldpath_hash); + if (g_hash_table_size(entry->newpath_hash) > 0) + g_hash_table_destroy(entry->newpath_hash); + else + g_hash_table_unref(entry->newpath_hash); +} + +static void collect_manager_entry_init_data(CollectManagerEntry *entry) +{ + entry->add_list = NULL; + entry->oldpath_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify) collect_manager_action_unref); + entry->newpath_hash = g_hash_table_new(g_str_hash, g_str_equal); + entry->empty = TRUE; + +} + static CollectManagerEntry *collect_manager_entry_new(const gchar *path) { CollectManagerEntry *entry; entry = g_new0(CollectManagerEntry, 1); entry->path = g_strdup(path); - entry->action_list = NULL; + collect_manager_entry_init_data(entry); collection_manager_entry_list = g_list_append(collection_manager_entry_list, entry); return entry; } + static void collect_manager_entry_free(CollectManagerEntry *entry) { - GList *work; - collection_manager_entry_list = g_list_remove(collection_manager_entry_list, entry); - work = entry->action_list; + collect_manager_entry_free_data(entry); + + g_free(entry->path); + g_free(entry); +} + +static void collect_manager_entry_reset(CollectManagerEntry *entry) +{ + collect_manager_entry_free_data(entry); + collect_manager_entry_init_data(entry); +} + +static CollectManagerEntry *collect_manager_get_entry(const gchar *path) +{ + GList *work; + + work = collection_manager_entry_list; while (work) { - CollectManagerAction *action; + CollectManagerEntry *entry; - action = work->data; + entry = work->data; work = work->next; + if (strcmp(entry->path, path) == 0) + { + return entry; + } + } + return NULL; - collect_manager_action_unref(action); +} + +static void collect_manager_entry_add_action(CollectManagerEntry *entry, CollectManagerAction *action) +{ + + CollectManagerAction *orig_action; + + entry->empty = FALSE; + + if (action->oldpath == NULL) + { + /* add file */ + if (action->newpath == NULL) + { + return; + } + + orig_action = g_hash_table_lookup(entry->newpath_hash, action->newpath); + if (orig_action) + { + /* target already exists */ + log_printf("collection manager failed to add another action for target %s in collection %s\n", + action->newpath, entry->path); + return; + } + entry->add_list = g_list_append(entry->add_list, action); + g_hash_table_insert(entry->newpath_hash, action->newpath, action); + collect_manager_action_ref(action); + return; } - g_list_free(entry->action_list); - g_free(entry->path); - g_free(entry); + orig_action = g_hash_table_lookup(entry->newpath_hash, action->oldpath); + if (orig_action) + { + /* new action with the same file */ + CollectManagerAction *new_action = collect_manager_action_new(orig_action->oldpath, action->newpath, action->type); + + if (new_action->oldpath) + { + g_hash_table_steal(entry->oldpath_hash, orig_action->oldpath); + g_hash_table_insert(entry->oldpath_hash, new_action->oldpath, new_action); + } + else + { + GList *work = g_list_find(entry->add_list, orig_action); + work->data = new_action; + } + + g_hash_table_steal(entry->newpath_hash, orig_action->newpath); + if (new_action->newpath) + { + g_hash_table_insert(entry->newpath_hash, new_action->newpath, new_action); + } + collect_manager_action_unref(orig_action); + return; + } + + + orig_action = g_hash_table_lookup(entry->oldpath_hash, action->oldpath); + if (orig_action) + { + /* another action for the same source, ignore */ + log_printf("collection manager failed to add another action for source %s in collection %s\n", + action->oldpath, entry->path); + return; + } + + g_hash_table_insert(entry->oldpath_hash, action->oldpath, action); + if (action->newpath) + { + g_hash_table_insert(entry->newpath_hash, action->newpath, action); + } + collect_manager_action_ref(action); +} + +static gboolean collect_manager_process_action(CollectManagerEntry *entry, gchar **path_ptr) +{ + gchar *path = *path_ptr; + CollectManagerAction *action; + + if (path == NULL) + { + /* get new files */ + if (entry->add_list) + { + action = entry->add_list->data; + g_assert(action->oldpath == NULL); + entry->add_list = g_list_remove(entry->add_list, action); + path = g_strdup(action->newpath); + g_hash_table_remove(entry->newpath_hash, path); + collect_manager_action_unref(action); + } + *path_ptr = path; + return (path != NULL); + } + + action = g_hash_table_lookup(entry->oldpath_hash, path); + + if (action) + { + g_free(path); + path = g_strdup(action->newpath); + *path_ptr = path; + return TRUE; + } + + return FALSE; /* no change */ } static void collect_manager_refresh(void) { - GList *list = NULL; + GList *list; GList *work; - gchar *base; + FileData *dir_fd; - base = g_strconcat(homedir(), "/", GQVIEW_RC_DIR_COLLECTIONS, NULL); - path_list(base, &list, NULL); - g_free(base); + dir_fd = file_data_new_dir(get_collections_dir()); + filelist_read(dir_fd, &list, NULL); + file_data_unref(dir_fd); work = collection_manager_entry_list; while (work && list) @@ -506,21 +695,23 @@ static void collect_manager_refresh(void) list_step = list; while (list_step && entry) { - gchar *path; + FileData *fd; - path = list_step->data; + fd = list_step->data; list_step = list_step->next; - if (strcmp(path, entry->path) == 0) + if (strcmp(fd->path, entry->path) == 0) { - list = g_list_remove(list, path); - g_free(path); + list = g_list_remove(list, fd); + file_data_unref(fd); entry = NULL; } else { collect_manager_entry_free(entry); + + entry = NULL; } } } @@ -528,24 +719,20 @@ static void collect_manager_refresh(void) work = list; while (work) { - gchar *path; + FileData *fd; - path = work->data; + fd = work->data; work = work->next; - collect_manager_entry_new(path); - g_free(path); + collect_manager_entry_new(fd->path); } - g_list_free(list); + filelist_free(list); } static void collect_manager_process_actions(gint max) { - if (debug && collection_manager_action_list) - { - printf("collection manager processing actions\n"); - } + if (collection_manager_action_list) DEBUG_1("collection manager processing actions"); while (collection_manager_action_list != NULL && max > 0) { @@ -563,8 +750,7 @@ static void collect_manager_process_actions(gint max) if (action->type == COLLECTION_MANAGER_UPDATE) { - entry->action_list = g_list_prepend(entry->action_list, action); - collect_manager_action_ref(action); + collect_manager_entry_add_action(entry, action); } else if (action->oldpath && action->newpath && strcmp(action->newpath, entry->path) == 0) @@ -580,9 +766,7 @@ static void collect_manager_process_actions(gint max) { action->newpath = NULL; } - - entry->action_list = g_list_prepend(entry->action_list, action); - collect_manager_action_ref(action); + collect_manager_entry_add_action(entry, action); } max--; @@ -591,7 +775,7 @@ static void collect_manager_process_actions(gint max) if (action->type != COLLECTION_MANAGER_UPDATE && action->oldpath && action->newpath) { - printf("collection manager failed to %s %s for collection %s\n", + log_printf("collection manager failed to %s %s for collection %s\n", (action->type == COLLECTION_MANAGER_ADD) ? "add" : "remove", action->oldpath, action->newpath); } @@ -605,60 +789,21 @@ static void collect_manager_process_actions(gint max) } } -static gint collect_manager_process_entry(CollectManagerEntry *entry) +static gboolean collect_manager_process_entry(CollectManagerEntry *entry) { CollectionData *cd; - gint success; - GList *work; - if (!entry->action_list) return FALSE; + if (entry->empty) return FALSE; cd = collection_new(entry->path); - success = collection_load_private(cd, entry->path, FALSE, FALSE); - - work = g_list_last(entry->action_list); - while (work) - { - CollectManagerAction *action; - - action = work->data; - work = work->prev; + (void) collection_load_private(cd, entry->path, COLLECTION_LOAD_NONE); - if (!action->oldpath) - { - /* add image */ - if (collection_list_find(cd->list, action->newpath) == NULL) - { - collection_add_check(cd, action->newpath, FALSE, FALSE); - } - } - else if (action->newpath) - { - /* rename image */ - while (collection_rename(cd, action->oldpath, action->newpath)); - } - else - { - /* remove image */ - while (collection_remove(cd, action->oldpath)); - } - collect_manager_action_unref(action); - } - - if (success && cd->changed) - { - collection_save_private(cd, entry->path); - if (debug) printf("collection manager updated: %s\n", entry->path); - } collection_unref(cd); - g_list_free(entry->action_list); - entry->action_list = NULL; - return TRUE; } -static gint collect_manager_process_entry_list(void) +static gboolean collect_manager_process_entry_list(void) { GList *work; @@ -675,7 +820,9 @@ static gint collect_manager_process_entry_list(void) return FALSE; } -static gint collect_manager_process_cb(gpointer data) + + +static gboolean collect_manager_process_cb(gpointer data) { if (collection_manager_action_list) collect_manager_refresh(); collect_manager_process_actions(COLLECT_MANAGER_ACTIONS_PER_IDLE); @@ -683,35 +830,35 @@ static gint collect_manager_process_cb(gpointer data) if (collect_manager_process_entry_list()) return TRUE; - if (debug) printf("collection manager is up to date\n"); + DEBUG_1("collection manager is up to date"); return FALSE; } -static gint collect_manager_timer_cb(gpointer data) +static gboolean collect_manager_timer_cb(gpointer data) { - if (debug) printf("collection manager timer expired\n"); + DEBUG_1("collection manager timer expired"); g_idle_add_full(G_PRIORITY_LOW, collect_manager_process_cb, NULL, NULL); - collection_manager_timer_id = -1; + collection_manager_timer_id = 0; return FALSE; } static void collect_manager_timer_push(gint stop) { - if (collection_manager_timer_id != -1) + if (collection_manager_timer_id) { if (!stop) return; g_source_remove(collection_manager_timer_id); - collection_manager_timer_id = -1; + collection_manager_timer_id = 0; } if (!stop) { collection_manager_timer_id = g_timeout_add(COLLECT_MANAGER_FLUSH_DELAY, collect_manager_timer_cb, NULL); - if (debug) printf("collection manager timer started\n"); + DEBUG_1("collection manager timer started"); } } @@ -735,50 +882,52 @@ static void collect_manager_add_action(CollectManagerAction *action) collect_manager_timer_push(FALSE); } -void collect_manager_moved(const gchar *oldpath, const gchar *newpath) +void collect_manager_moved(FileData *fd) { CollectManagerAction *action; + const gchar *oldpath = fd->change->source; + const gchar *newpath = fd->change->dest; action = collect_manager_action_new(oldpath, newpath, COLLECTION_MANAGER_UPDATE); collect_manager_add_action(action); } -void collect_manager_add(const gchar *path, const gchar *collection) +void collect_manager_add(FileData *fd, const gchar *collection) { CollectManagerAction *action; CollectWindow *cw; - if (!path || !collection) return; + if (!fd || !collection) return; cw = collection_window_find_by_path(collection); if (cw) { - if (collection_list_find(cw->cd->list, path) == NULL) + if (collection_list_find_fd(cw->cd->list, fd) == NULL) { - collection_add(cw->cd, path, FALSE); + collection_add(cw->cd, fd, FALSE); } return; } - action = collect_manager_action_new(path, collection, COLLECTION_MANAGER_ADD); + action = collect_manager_action_new(fd->path, collection, COLLECTION_MANAGER_ADD); collect_manager_add_action(action); } -void collect_manager_remove(const gchar *path, const gchar *collection) +void collect_manager_remove(FileData *fd, const gchar *collection) { CollectManagerAction *action; CollectWindow *cw; - if (!path || !collection) return; + if (!fd || !collection) return; cw = collection_window_find_by_path(collection); if (cw) { - while (collection_remove(cw->cd, path)); + while (collection_remove(cw->cd, fd)); return; } - action = collect_manager_action_new(path, collection, COLLECTION_MANAGER_REMOVE); + action = collect_manager_action_new(fd->path, collection, COLLECTION_MANAGER_REMOVE); collect_manager_add_action(action); } @@ -786,7 +935,30 @@ void collect_manager_flush(void) { collect_manager_timer_push(TRUE); - if (debug) printf("collection manager flushing\n"); + DEBUG_1("collection manager flushing"); while (collect_manager_process_cb(NULL)); } +void collect_manager_notify_cb(FileData *fd, NotifyType type, gpointer data) +{ + if (!(type & NOTIFY_CHANGE) || !fd->change) return; + + DEBUG_1("Notify collect_manager: %s %04x", fd->path, type); + switch (fd->change->type) + { + case FILEDATA_CHANGE_MOVE: + collect_manager_moved(fd); + break; + case FILEDATA_CHANGE_COPY: + break; + case FILEDATA_CHANGE_RENAME: + collect_manager_moved(fd); + break; + case FILEDATA_CHANGE_DELETE: + case FILEDATA_CHANGE_UNSPECIFIED: + case FILEDATA_CHANGE_WRITE_METADATA: + break; + } + +} +/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */