Mercurial > geeqie.yaz
annotate src/collect-io.c @ 78:b192a0efe080
Sun Oct 15 12:36:06 2006 John Ellis <johne@verizon.net>
* pan-view.c: For now, also display the full size image under the
thumbnail's information bubble. Make clicking the info box close it.
author | gqview |
---|---|
date | Sun, 15 Oct 2006 16:39:19 +0000 |
parents | ebbff299ad0d |
children | 71e1ebee420e |
rev | line source |
---|---|
9 | 1 /* |
2 * GQview | |
3 * (C) 2004 John Ellis | |
4 * | |
5 * Author: John Ellis | |
6 * | |
7 * This software is released under the GNU General Public License (GNU GPL). | |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
10 */ | |
11 | |
12 | |
13 #include "gqview.h" | |
14 #include "collect-io.h" | |
15 | |
16 #include "collect.h" | |
17 #include "layout_util.h" | |
18 #include "rcfile.h" | |
19 #include "thumb.h" | |
20 #include "ui_fileops.h" | |
21 | |
22 | |
23 #define GQVIEW_COLLECTION_MARKER "#GQview" | |
24 | |
25 #define GQVIEW_COLLECTION_FAIL_MIN 300 | |
26 #define GQVIEW_COLLECTION_FAIL_PERCENT 98 | |
27 | |
28 | |
29 static void collection_load_thumb_step(CollectionData *cd); | |
30 | |
31 | |
32 static gint scan_geometry(gchar *buffer, gint *x, gint *y, gint *w, gint *h) | |
33 { | |
34 gint nx, ny, nw, nh; | |
35 | |
36 if(sscanf(buffer, "%d %d %d %d", &nx, &ny, &nw, &nh) != 4) return FALSE; | |
37 | |
38 *x = nx; | |
39 *y = ny; | |
40 *w = nw; | |
41 *h = nh; | |
42 | |
43 return TRUE; | |
44 } | |
45 | |
46 static gint collection_load_private(CollectionData *cd, const gchar *path, gint append, gint flush) | |
47 { | |
48 gchar s_buf[2048]; | |
49 FILE *f; | |
50 gchar *pathl; | |
51 gint official = FALSE; | |
52 gint success = TRUE; | |
53 guint total = 0; | |
54 guint fail = 0; | |
55 | |
56 collection_load_stop(cd); | |
57 | |
58 if (flush) collect_manager_flush(); | |
59 | |
60 if (!append) | |
61 { | |
62 collection_list_free(cd->list); | |
63 cd->list = NULL; | |
64 } | |
65 | |
66 if (!path && !cd->path) return FALSE; | |
67 | |
68 if (!path) path = cd->path; | |
69 | |
70 /* load it */ | |
71 pathl = path_from_utf8(path); | |
72 f = fopen(pathl, "r"); | |
73 g_free(pathl); | |
74 if (!f) | |
75 { | |
76 printf("Failed to open collection file: \"%s\"\n", path); | |
77 return FALSE; | |
78 } | |
79 | |
80 while (fgets(s_buf, sizeof(s_buf), f)) | |
81 { | |
82 gchar *buf; | |
83 if (s_buf[0]=='#') | |
84 { | |
85 if (strncasecmp(s_buf, GQVIEW_COLLECTION_MARKER, strlen(GQVIEW_COLLECTION_MARKER)) == 0) | |
86 { | |
87 /* Looks like an official collection, allow unchecked input. | |
88 * All this does is allow adding files that may not exist, | |
89 * which is needed for the collection manager to work. | |
90 * Also unofficial files abort after too many invalid entries. | |
91 */ | |
92 official = TRUE; | |
93 } | |
94 else if (strncmp(s_buf, "#geometry:", 10 ) == 0 && | |
95 scan_geometry(s_buf + 10, &cd->window_x, &cd->window_y, &cd->window_w, &cd->window_h) ) | |
96 { | |
97 cd->window_read = TRUE; | |
98 } | |
99 continue; | |
100 } | |
101 if (s_buf[0]=='\n') continue; | |
102 | |
103 buf = quoted_value(s_buf); | |
104 if (buf) | |
105 { | |
106 gint valid; | |
107 | |
108 valid = (buf[0] == '/' && collection_add_check(cd, buf, FALSE, flush)); | |
109 g_free(buf); | |
110 | |
111 total++; | |
112 if (!valid && !official) | |
113 { | |
114 fail++; | |
115 if (fail > GQVIEW_COLLECTION_FAIL_MIN && | |
116 fail * 100 / total > GQVIEW_COLLECTION_FAIL_PERCENT) | |
117 { | |
118 printf("Too many invalid filenames in unoffical collection file, closing: %s\n", path); | |
119 success = FALSE; | |
120 break; | |
121 } | |
122 } | |
123 } | |
124 } | |
125 | |
126 fclose(f); | |
127 | |
128 cd->list = collection_list_sort(cd->list, cd->sort_method); | |
129 if (!append) cd->changed = FALSE; | |
130 | |
131 return success; | |
132 } | |
133 | |
134 gint collection_load(CollectionData *cd, const gchar *path, gint append) | |
135 { | |
136 if (collection_load_private(cd, path, append, TRUE)) | |
137 { | |
138 layout_recent_add_path(cd->path); | |
139 return TRUE; | |
140 } | |
141 | |
142 return FALSE; | |
143 } | |
144 | |
145 static void collection_load_thumb_do(CollectionData *cd) | |
146 { | |
147 GdkPixbuf *pixbuf; | |
148 | |
149 if (!cd->thumb_loader || !g_list_find(cd->list, cd->thumb_info)) return; | |
150 | |
151 pixbuf = thumb_loader_get_pixbuf(cd->thumb_loader, TRUE); | |
152 collection_info_set_thumb(cd->thumb_info, pixbuf); | |
153 g_object_unref(pixbuf); | |
154 | |
155 if (cd->info_updated_func) cd->info_updated_func(cd, cd->thumb_info, cd->info_updated_data); | |
156 } | |
157 | |
158 static void collection_load_thumb_error_cb(ThumbLoader *tl, gpointer data) | |
159 { | |
160 CollectionData *cd = data; | |
161 | |
162 collection_load_thumb_do(cd); | |
163 collection_load_thumb_step(cd); | |
164 } | |
165 | |
166 static void collection_load_thumb_done_cb(ThumbLoader *tl, gpointer data) | |
167 { | |
168 CollectionData *cd = data; | |
169 | |
170 collection_load_thumb_do(cd); | |
171 collection_load_thumb_step(cd); | |
172 } | |
173 | |
174 static void collection_load_thumb_step(CollectionData *cd) | |
175 { | |
176 GList *work; | |
177 CollectInfo *ci; | |
178 | |
179 if (!cd->list) | |
180 { | |
181 collection_load_stop(cd); | |
182 return; | |
183 } | |
184 | |
185 work = cd->list; | |
186 ci = work->data; | |
187 work = work->next; | |
188 /* find first unloaded thumb */ | |
189 while (work && ci->pixbuf) | |
190 { | |
191 ci = work->data; | |
192 work = work->next; | |
193 } | |
194 | |
195 if (!ci || ci->pixbuf) | |
196 { | |
197 /* done */ | |
198 collection_load_stop(cd); | |
199 | |
200 /* send a NULL CollectInfo to notify end */ | |
201 if (cd->info_updated_func) cd->info_updated_func(cd, NULL, cd->info_updated_data); | |
202 | |
203 return; | |
204 } | |
205 | |
206 /* setup loader and call it */ | |
207 cd->thumb_info = ci; | |
208 thumb_loader_free(cd->thumb_loader); | |
209 cd->thumb_loader = thumb_loader_new(thumb_max_width, thumb_max_height); | |
210 thumb_loader_set_callbacks(cd->thumb_loader, | |
211 collection_load_thumb_done_cb, | |
212 collection_load_thumb_error_cb, | |
213 NULL, | |
214 cd); | |
215 | |
216 /* start it */ | |
217 if (!thumb_loader_start(cd->thumb_loader, ci->path)) | |
218 { | |
219 /* error, handle it, do next */ | |
220 if (debug) printf("error loading thumb for %s\n", ci->path); | |
221 collection_load_thumb_do(cd); | |
222 collection_load_thumb_step(cd); | |
223 } | |
224 } | |
225 | |
226 void collection_load_thumb_idle(CollectionData *cd) | |
227 { | |
228 if (!cd->thumb_loader) collection_load_thumb_step(cd); | |
229 } | |
230 | |
231 gint collection_load_begin(CollectionData *cd, const gchar *path, gint append) | |
232 { | |
233 if (!collection_load(cd, path, append)) return FALSE; | |
234 | |
235 collection_load_thumb_idle(cd); | |
236 | |
237 return TRUE; | |
238 } | |
239 | |
240 void collection_load_stop(CollectionData *cd) | |
241 { | |
242 if (!cd->thumb_loader) return; | |
243 | |
244 thumb_loader_free(cd->thumb_loader); | |
245 cd->thumb_loader = NULL; | |
246 } | |
247 | |
248 static gint collection_save_private(CollectionData *cd, const gchar *path) | |
249 { | |
250 FILE *f; | |
251 GList *work; | |
252 gchar *tmp_path; | |
253 gchar *pathl; | |
254 mode_t save_mask; | |
255 | |
256 if (!path && !cd->path) return FALSE; | |
257 | |
258 if (!path) | |
259 { | |
260 path = cd->path; | |
261 } | |
262 | |
263 tmp_path = unique_filename(path, ".tmp", "_", 3); | |
264 if (!tmp_path) return FALSE; | |
265 | |
266 pathl = path_from_utf8(tmp_path); | |
267 save_mask = umask(0077); | |
268 f = fopen(pathl, "w"); | |
269 umask(save_mask); | |
270 g_free(pathl); | |
271 | |
272 if (!f) | |
273 { | |
274 /* file open failed */ | |
275 printf("failed to open collection (write) \"%s\"\n", tmp_path); | |
276 g_free(tmp_path); | |
277 return FALSE; | |
278 } | |
279 | |
280 fprintf(f, "%s collection\n", GQVIEW_COLLECTION_MARKER); | |
281 fprintf(f, "#created with GQview version %s\n", VERSION); | |
282 | |
283 collection_update_geometry(cd); | |
284 if (cd->window_read) | |
285 { | |
286 fprintf(f, "#geometry: %d %d %d %d\n", cd->window_x, cd->window_y, cd->window_w, cd->window_h); | |
287 } | |
288 | |
289 work = cd->list; | |
290 while (work) | |
291 { | |
292 CollectInfo *ci = work->data; | |
293 if (fprintf(f, "\"%s\"\n", ci->path) < 0) | |
294 { | |
295 fclose(f); | |
296 printf("Error writing to %s\n", tmp_path); | |
297 unlink_file(tmp_path); | |
298 g_free(tmp_path); | |
299 return FALSE; | |
300 } | |
301 work = work->next; | |
302 } | |
303 | |
304 fprintf(f, "#end\n"); | |
305 | |
306 fclose(f); | |
307 | |
308 copy_file_attributes(path, tmp_path, TRUE, FALSE); | |
309 if (!rename_file(tmp_path, path)) | |
310 { | |
311 printf("collection save unable to rename %s to %s\n", tmp_path, path); | |
312 unlink_file(tmp_path); | |
313 g_free(tmp_path); | |
314 return FALSE; | |
315 } | |
316 | |
317 g_free(tmp_path); | |
318 | |
319 if (!cd->path || strcmp(path, cd->path) != 0) | |
320 { | |
321 gchar *buf = cd->path; | |
322 cd->path = g_strdup(path); | |
323 path = cd->path; | |
324 g_free(buf); | |
325 | |
326 g_free(cd->name); | |
327 cd->name = g_strdup(filename_from_path(cd->path)); | |
328 | |
329 collection_path_changed(cd); | |
330 } | |
331 | |
332 cd->changed = FALSE; | |
333 | |
334 return TRUE; | |
335 } | |
336 | |
337 gint collection_save(CollectionData *cd, const gchar *path) | |
338 { | |
339 if (collection_save_private(cd, path)) | |
340 { | |
341 layout_recent_add_path(cd->path); | |
342 return TRUE; | |
343 } | |
344 | |
345 return FALSE; | |
346 } | |
347 | |
348 gint collection_load_only_geometry(CollectionData *cd, const gchar *path) | |
349 { | |
350 gchar s_buf[2048]; | |
351 FILE *f; | |
352 gchar *pathl; | |
353 | |
354 if (!path && !cd->path) return FALSE; | |
355 | |
356 if (!path) path = cd->path; | |
357 | |
358 /* load it */ | |
359 pathl = path_from_utf8(path); | |
360 f = fopen(pathl, "r"); | |
361 g_free(pathl); | |
362 if (!f) return FALSE; | |
363 | |
364 while (fgets(s_buf, sizeof(s_buf), f)) | |
365 { | |
366 if (s_buf[0]=='#' && | |
367 strncmp(s_buf, "#geometry:", 10 ) == 0 && | |
368 scan_geometry(s_buf + 10, &cd->window_x, &cd->window_y, &cd->window_w, &cd->window_h) ) | |
369 { | |
370 cd->window_read = TRUE; | |
371 fclose(f); | |
372 return TRUE; | |
373 } | |
374 } | |
375 fclose(f); | |
376 return FALSE; | |
377 } | |
378 | |
379 | |
380 /* | |
381 *------------------------------------------------------------------- | |
382 * collection manager | |
383 *------------------------------------------------------------------- | |
384 */ | |
385 | |
386 #define COLLECT_MANAGER_ACTIONS_PER_IDLE 1000 | |
387 #define COLLECT_MANAGER_FLUSH_DELAY 10000 | |
388 | |
389 typedef struct _CollectManagerEntry CollectManagerEntry; | |
390 struct _CollectManagerEntry | |
391 { | |
392 gchar *path; | |
393 GList *action_list; | |
394 }; | |
395 | |
396 typedef enum { | |
397 COLLECTION_MANAGER_UPDATE, | |
398 COLLECTION_MANAGER_ADD, | |
399 COLLECTION_MANAGER_REMOVE | |
400 } CollectManagerType; | |
401 | |
402 typedef struct _CollectManagerAction CollectManagerAction; | |
403 struct _CollectManagerAction | |
404 { | |
405 gchar *oldpath; | |
406 gchar *newpath; | |
407 | |
408 CollectManagerType type; | |
409 | |
410 gint ref; | |
411 }; | |
412 | |
413 | |
414 static GList *collection_manager_entry_list = NULL; | |
415 static GList *collection_manager_action_list = NULL; | |
416 static GList *collection_manager_action_tail = NULL; | |
417 static gint collection_manager_timer_id = -1; | |
418 | |
419 | |
420 static CollectManagerAction *collect_manager_action_new(const gchar *oldpath, const gchar *newpath, | |
421 CollectManagerType type) | |
422 { | |
423 CollectManagerAction *action; | |
424 | |
425 action = g_new0(CollectManagerAction, 1); | |
426 action->ref = 1; | |
427 | |
428 action->oldpath = g_strdup(oldpath); | |
429 action->newpath = g_strdup(newpath); | |
430 | |
431 action->type = type; | |
432 | |
433 return action; | |
434 } | |
435 | |
436 static void collect_manager_action_ref(CollectManagerAction *action) | |
437 { | |
438 action->ref++; | |
439 } | |
440 | |
441 static void collect_manager_action_unref(CollectManagerAction *action) | |
442 { | |
443 action->ref--; | |
444 | |
445 if (action->ref > 0) return; | |
446 | |
447 g_free(action->oldpath); | |
448 g_free(action->newpath); | |
449 g_free(action); | |
450 } | |
451 | |
452 static CollectManagerEntry *collect_manager_entry_new(const gchar *path) | |
453 { | |
454 CollectManagerEntry *entry; | |
455 | |
456 entry = g_new0(CollectManagerEntry, 1); | |
457 entry->path = g_strdup(path); | |
458 entry->action_list = NULL; | |
459 | |
460 collection_manager_entry_list = g_list_append(collection_manager_entry_list, entry); | |
461 | |
462 return entry; | |
463 } | |
464 | |
465 static void collect_manager_entry_free(CollectManagerEntry *entry) | |
466 { | |
467 GList *work; | |
468 | |
469 collection_manager_entry_list = g_list_remove(collection_manager_entry_list, entry); | |
470 | |
471 work = entry->action_list; | |
472 while (work) | |
473 { | |
474 CollectManagerAction *action; | |
475 | |
476 action = work->data; | |
477 work = work->next; | |
478 | |
479 collect_manager_action_unref(action); | |
480 } | |
481 g_list_free(entry->action_list); | |
482 | |
483 g_free(entry->path); | |
484 g_free(entry); | |
485 } | |
486 | |
487 static void collect_manager_refresh(void) | |
488 { | |
489 GList *list = NULL; | |
490 GList *work; | |
491 gchar *base; | |
492 | |
493 base = g_strconcat(homedir(), "/", GQVIEW_RC_DIR_COLLECTIONS, NULL); | |
494 path_list(base, &list, NULL); | |
495 g_free(base); | |
496 | |
497 work = collection_manager_entry_list; | |
498 while (work && list) | |
499 { | |
500 CollectManagerEntry *entry; | |
501 GList *list_step; | |
502 | |
503 entry = work->data; | |
504 work = work->next; | |
505 | |
506 list_step = list; | |
507 while (list_step && entry) | |
508 { | |
509 gchar *path; | |
510 | |
511 path = list_step->data; | |
512 list_step = list_step->next; | |
513 | |
514 if (strcmp(path, entry->path) == 0) | |
515 { | |
516 list = g_list_remove(list, path); | |
517 g_free(path); | |
518 | |
519 entry = NULL; | |
520 } | |
521 else | |
522 { | |
523 collect_manager_entry_free(entry); | |
524 } | |
525 } | |
526 } | |
527 | |
528 work = list; | |
529 while (work) | |
530 { | |
531 gchar *path; | |
532 | |
533 path = work->data; | |
534 work = work->next; | |
535 | |
536 collect_manager_entry_new(path); | |
537 g_free(path); | |
538 } | |
539 | |
540 g_list_free(list); | |
541 } | |
542 | |
543 static void collect_manager_process_actions(gint max) | |
544 { | |
545 if (debug && collection_manager_action_list) | |
546 { | |
547 printf("collection manager processing actions\n"); | |
548 } | |
549 | |
550 while (collection_manager_action_list != NULL && max > 0) | |
551 { | |
552 CollectManagerAction *action; | |
553 GList *work; | |
554 | |
555 action = collection_manager_action_list->data; | |
556 work = collection_manager_entry_list; | |
557 while (work) | |
558 { | |
559 CollectManagerEntry *entry; | |
560 | |
561 entry = work->data; | |
562 work = work->next; | |
563 | |
564 if (action->type == COLLECTION_MANAGER_UPDATE) | |
565 { | |
566 entry->action_list = g_list_prepend(entry->action_list, action); | |
567 collect_manager_action_ref(action); | |
568 } | |
569 else if (action->oldpath && action->newpath && | |
570 strcmp(action->newpath, entry->path) == 0) | |
571 { | |
572 /* convert action to standard add format */ | |
573 g_free(action->newpath); | |
574 if (action->type == COLLECTION_MANAGER_ADD) | |
575 { | |
576 action->newpath = action->oldpath; | |
577 action->oldpath = NULL; | |
578 } | |
579 else if (action->type == COLLECTION_MANAGER_REMOVE) | |
580 { | |
581 action->newpath = NULL; | |
582 } | |
583 | |
584 entry->action_list = g_list_prepend(entry->action_list, action); | |
585 collect_manager_action_ref(action); | |
586 } | |
587 | |
588 max--; | |
589 } | |
590 | |
591 if (action->type != COLLECTION_MANAGER_UPDATE && | |
592 action->oldpath && action->newpath) | |
593 { | |
594 printf("collection manager failed to %s %s for collection %s\n", | |
595 (action->type == COLLECTION_MANAGER_ADD) ? "add" : "remove", | |
596 action->oldpath, action->newpath); | |
597 } | |
598 | |
599 if (collection_manager_action_tail == collection_manager_action_list) | |
600 { | |
601 collection_manager_action_tail = NULL; | |
602 } | |
603 collection_manager_action_list = g_list_remove(collection_manager_action_list, action); | |
604 collect_manager_action_unref(action); | |
605 } | |
606 } | |
607 | |
608 static gint collect_manager_process_entry(CollectManagerEntry *entry) | |
609 { | |
610 CollectionData *cd; | |
611 gint success; | |
612 GList *work; | |
613 | |
614 if (!entry->action_list) return FALSE; | |
615 | |
616 cd = collection_new(entry->path); | |
617 success = collection_load_private(cd, entry->path, FALSE, FALSE); | |
618 | |
619 work = g_list_last(entry->action_list); | |
620 while (work) | |
621 { | |
622 CollectManagerAction *action; | |
623 | |
624 action = work->data; | |
625 work = work->prev; | |
626 | |
627 if (!action->oldpath) | |
628 { | |
629 /* add image */ | |
630 if (collection_list_find(cd->list, action->newpath) == NULL) | |
631 { | |
632 collection_add_check(cd, action->newpath, FALSE, FALSE); | |
633 } | |
634 } | |
635 else if (action->newpath) | |
636 { | |
637 /* rename image */ | |
638 while (collection_rename(cd, action->oldpath, action->newpath)); | |
639 } | |
640 else | |
641 { | |
642 /* remove image */ | |
643 while (collection_remove(cd, action->oldpath)); | |
644 } | |
645 collect_manager_action_unref(action); | |
646 } | |
647 | |
648 if (success && cd->changed) | |
649 { | |
650 collection_save_private(cd, entry->path); | |
651 if (debug) printf("collection manager updated: %s\n", entry->path); | |
652 } | |
653 collection_unref(cd); | |
654 | |
655 g_list_free(entry->action_list); | |
656 entry->action_list = NULL; | |
657 | |
658 return TRUE; | |
659 } | |
660 | |
661 static gint collect_manager_process_entry_list(void) | |
662 { | |
663 GList *work; | |
664 | |
665 work = collection_manager_entry_list; | |
666 while (work) | |
667 { | |
668 CollectManagerEntry *entry; | |
669 | |
670 entry = work->data; | |
671 work = work->next; | |
672 if (collect_manager_process_entry(entry)) return TRUE; | |
673 } | |
674 | |
675 return FALSE; | |
676 } | |
677 | |
678 static gint collect_manager_process_cb(gpointer data) | |
679 { | |
680 if (collection_manager_action_list) collect_manager_refresh(); | |
681 collect_manager_process_actions(COLLECT_MANAGER_ACTIONS_PER_IDLE); | |
682 if (collection_manager_action_list) return TRUE; | |
683 | |
684 if (collect_manager_process_entry_list()) return TRUE; | |
685 | |
686 if (debug) printf("collection manager is up to date\n"); | |
687 return FALSE; | |
688 } | |
689 | |
690 static gint collect_manager_timer_cb(gpointer data) | |
691 { | |
692 if (debug) printf("collection manager timer expired\n"); | |
693 | |
694 g_idle_add_full(G_PRIORITY_LOW, collect_manager_process_cb, NULL, NULL); | |
695 | |
696 collection_manager_timer_id = -1; | |
697 return FALSE; | |
698 } | |
699 | |
700 static void collect_manager_timer_push(gint stop) | |
701 { | |
702 if (collection_manager_timer_id != -1) | |
703 { | |
704 if (!stop) return; | |
705 | |
706 g_source_remove(collection_manager_timer_id); | |
707 collection_manager_timer_id = -1; | |
708 } | |
709 | |
710 if (!stop) | |
711 { | |
712 collection_manager_timer_id = g_timeout_add(COLLECT_MANAGER_FLUSH_DELAY, | |
713 collect_manager_timer_cb, NULL); | |
714 if (debug) printf("collection manager timer started\n"); | |
715 } | |
716 } | |
717 | |
718 static void collect_manager_add_action(CollectManagerAction *action) | |
719 { | |
720 if (!action) return; | |
721 | |
722 /* we keep track of the list's tail to keep this a n(1) operation */ | |
723 | |
724 if (collection_manager_action_tail) | |
725 { | |
66
ebbff299ad0d
Fri Sep 1 02:12:45 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
726 collection_manager_action_tail = g_list_append(collection_manager_action_tail, action); |
9 | 727 collection_manager_action_tail = collection_manager_action_tail->next; |
728 } | |
729 else | |
730 { | |
731 collection_manager_action_list = g_list_append(collection_manager_action_list, action); | |
732 collection_manager_action_tail = collection_manager_action_list; | |
733 } | |
734 | |
735 collect_manager_timer_push(FALSE); | |
736 } | |
737 | |
738 void collect_manager_moved(const gchar *oldpath, const gchar *newpath) | |
739 { | |
740 CollectManagerAction *action; | |
741 | |
742 action = collect_manager_action_new(oldpath, newpath, COLLECTION_MANAGER_UPDATE); | |
743 collect_manager_add_action(action); | |
744 } | |
745 | |
746 void collect_manager_add(const gchar *path, const gchar *collection) | |
747 { | |
748 CollectManagerAction *action; | |
749 CollectWindow *cw; | |
750 | |
751 if (!path || !collection) return; | |
752 | |
753 cw = collection_window_find_by_path(collection); | |
754 if (cw) | |
755 { | |
756 if (collection_list_find(cw->cd->list, path) == NULL) | |
757 { | |
758 collection_add(cw->cd, path, FALSE); | |
759 } | |
760 return; | |
761 } | |
762 | |
763 action = collect_manager_action_new(path, collection, COLLECTION_MANAGER_ADD); | |
764 collect_manager_add_action(action); | |
765 } | |
766 | |
767 void collect_manager_remove(const gchar *path, const gchar *collection) | |
768 { | |
769 CollectManagerAction *action; | |
770 CollectWindow *cw; | |
771 | |
772 if (!path || !collection) return; | |
773 | |
774 cw = collection_window_find_by_path(collection); | |
775 if (cw) | |
776 { | |
777 while (collection_remove(cw->cd, path)); | |
778 return; | |
779 } | |
780 | |
781 action = collect_manager_action_new(path, collection, COLLECTION_MANAGER_REMOVE); | |
782 collect_manager_add_action(action); | |
783 } | |
784 | |
785 void collect_manager_flush(void) | |
786 { | |
787 collect_manager_timer_push(TRUE); | |
788 | |
789 if (debug) printf("collection manager flushing\n"); | |
790 while (collect_manager_process_cb(NULL)); | |
791 } | |
792 |