📄 collect-io.c
字号:
COLLECTION_MANAGER_ADD, COLLECTION_MANAGER_REMOVE} CollectManagerType;typedef struct _CollectManagerAction CollectManagerAction;struct _CollectManagerAction{ gchar *oldpath; gchar *newpath; CollectManagerType type; gint ref;};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 CollectManagerAction *collect_manager_action_new(const gchar *oldpath, const gchar *newpath, CollectManagerType type){ CollectManagerAction *action; action = g_new0(CollectManagerAction, 1); action->ref = 1; action->oldpath = g_strdup(oldpath); action->newpath = g_strdup(newpath); action->type = type; return action;}static void collect_manager_action_ref(CollectManagerAction *action){ action->ref++;}static void collect_manager_action_unref(CollectManagerAction *action){ action->ref--; if (action->ref > 0) return; g_free(action->oldpath); g_free(action->newpath); g_free(action);}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; 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; while (work) { CollectManagerAction *action; action = work->data; work = work->next; collect_manager_action_unref(action); } g_list_free(entry->action_list); g_free(entry->path); g_free(entry);}static void collect_manager_refresh(void){ GList *list = NULL; GList *work; gchar *base; base = g_strconcat(homedir(), "/", GQVIEW_RC_DIR_COLLECTIONS, NULL); path_list(base, &list, NULL); g_free(base); work = collection_manager_entry_list; while (work && list) { CollectManagerEntry *entry; GList *list_step; entry = work->data; work = work->next; list_step = list; while (list_step && entry) { gchar *path; path = list_step->data; list_step = list_step->next; if (strcmp(path, entry->path) == 0) { list = g_list_remove(list, path); g_free(path); entry = NULL; } else { collect_manager_entry_free(entry); } } } work = list; while (work) { gchar *path; path = work->data; work = work->next; collect_manager_entry_new(path); g_free(path); } g_list_free(list);}static void collect_manager_process_actions(gint max){ if (debug && collection_manager_action_list) { printf("collection manager processing actions\n"); } while (collection_manager_action_list != NULL && max > 0) { CollectManagerAction *action; GList *work; action = collection_manager_action_list->data; work = collection_manager_entry_list; while (work) { CollectManagerEntry *entry; entry = work->data; work = work->next; if (action->type == COLLECTION_MANAGER_UPDATE) { entry->action_list = g_list_prepend(entry->action_list, action); collect_manager_action_ref(action); } else if (action->oldpath && action->newpath && strcmp(action->newpath, entry->path) == 0) { /* convert action to standard add format */ g_free(action->newpath); if (action->type == COLLECTION_MANAGER_ADD) { action->newpath = action->oldpath; action->oldpath = NULL; } else if (action->type == COLLECTION_MANAGER_REMOVE) { action->newpath = NULL; } entry->action_list = g_list_prepend(entry->action_list, action); collect_manager_action_ref(action); } max--; } if (action->type != COLLECTION_MANAGER_UPDATE && action->oldpath && action->newpath) { printf("collection manager failed to %s %s for collection %s\n", (action->type == COLLECTION_MANAGER_ADD) ? "add" : "remove", action->oldpath, action->newpath); } if (collection_manager_action_tail == collection_manager_action_list) { collection_manager_action_tail = NULL; } collection_manager_action_list = g_list_remove(collection_manager_action_list, action); collect_manager_action_unref(action); }}static gint collect_manager_process_entry(CollectManagerEntry *entry){ CollectionData *cd; gint success; GList *work; if (!entry->action_list) 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; 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){ GList *work; work = collection_manager_entry_list; while (work) { CollectManagerEntry *entry; entry = work->data; work = work->next; if (collect_manager_process_entry(entry)) return TRUE; } return FALSE;}static gint collect_manager_process_cb(gpointer data){ if (collection_manager_action_list) collect_manager_refresh(); collect_manager_process_actions(COLLECT_MANAGER_ACTIONS_PER_IDLE); if (collection_manager_action_list) return TRUE; if (collect_manager_process_entry_list()) return TRUE; if (debug) printf("collection manager is up to date\n"); return FALSE;}static gint collect_manager_timer_cb(gpointer data){ if (debug) printf("collection manager timer expired\n"); g_idle_add_full(G_PRIORITY_LOW, collect_manager_process_cb, NULL, NULL); collection_manager_timer_id = -1; return FALSE;}static void collect_manager_timer_push(gint stop){ if (collection_manager_timer_id != -1) { if (!stop) return; g_source_remove(collection_manager_timer_id); collection_manager_timer_id = -1; } 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"); }}static void collect_manager_add_action(CollectManagerAction *action){ if (!action) return; /* we keep track of the list's tail to keep this a n(1) operation */ if (collection_manager_action_tail) { g_list_append(collection_manager_action_tail, action); collection_manager_action_tail = collection_manager_action_tail->next; } else { collection_manager_action_list = g_list_append(collection_manager_action_list, action); collection_manager_action_tail = collection_manager_action_list; } collect_manager_timer_push(FALSE);}void collect_manager_moved(const gchar *oldpath, const gchar *newpath){ CollectManagerAction *action; 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){ CollectManagerAction *action; CollectWindow *cw; if (!path || !collection) return; cw = collection_window_find_by_path(collection); if (cw) { if (collection_list_find(cw->cd->list, path) == NULL) { collection_add(cw->cd, path, FALSE); } return; } action = collect_manager_action_new(path, collection, COLLECTION_MANAGER_ADD); collect_manager_add_action(action);}void collect_manager_remove(const gchar *path, const gchar *collection){ CollectManagerAction *action; CollectWindow *cw; if (!path || !collection) return; cw = collection_window_find_by_path(collection); if (cw) { while (collection_remove(cw->cd, path)); return; } action = collect_manager_action_new(path, collection, COLLECTION_MANAGER_REMOVE); collect_manager_add_action(action);}void collect_manager_flush(void){ collect_manager_timer_push(TRUE); if (debug) printf("collection manager flushing\n"); while (collect_manager_process_cb(NULL));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -