Mercurial > geeqie.yaz
comparison src/collect-io.c @ 9:d907d608745f
Sync to GQview 1.5.9 release.
########
DO NOT BASE ENHANCEMENTS OR TRANSLATION UPDATES ON CODE IN THIS CVS!
This CVS is never up to date with current development and is provided
solely for reference purposes, please use the latest official release
package when making any changes or translation updates.
########
author | gqview |
---|---|
date | Sat, 26 Feb 2005 00:13:35 +0000 |
parents | |
children | ebbff299ad0d |
comparison
equal
deleted
inserted
replaced
8:e0d0593d519e | 9:d907d608745f |
---|---|
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 { | |
726 g_list_append(collection_manager_action_tail, action); | |
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 |