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!
13 #include "cache_maint.h"
18 #include "thumb_standard.h"
19 #include "ui_fileops.h"
21 #include "ui_spinner.h"
22 #include "ui_tabcomp.h"
23 #include "ui_utildlg.h"
26 typedef struct _CMData CMData;
35 GtkWidget *button_stop;
36 GtkWidget *button_close;
41 #define PURGE_DIALOG_WIDTH 400
45 *-------------------------------------------------------------------
47 *-------------------------------------------------------------------
50 static gint extension_truncate(gchar *path, const gchar *ext)
55 if (!path || !ext) return FALSE;
60 if (l < el || strcmp(path + (l - el), ext) != 0) return FALSE;
67 static gchar *extension_find_dot(gchar *path)
71 if (!path || *path == '\0') return NULL;
74 while (*ptr != '\0') ptr++;
76 while (ptr > path && *ptr != '.') ptr--;
78 if (ptr == path) return NULL;
83 static gint isempty(const gchar *path)
89 pathl = path_from_utf8(path);
92 if (!dp) return FALSE;
94 while ((dir = readdir(dp)) != NULL)
96 gchar *name = dir->d_name;
98 if (!(name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) )
109 static void cache_maintain_home_close(CMData *cm)
111 if (cm->idle_id != -1) g_source_remove(cm->idle_id);
112 if (cm->gd) generic_dialog_close(cm->gd);
113 path_list_free(cm->list);
114 g_list_free(cm->done_list);
118 static void cache_maintain_home_stop(CMData *cm)
120 if (cm->idle_id != -1)
122 g_source_remove(cm->idle_id);
126 gtk_entry_set_text(GTK_ENTRY(cm->entry), _("done"));
127 spinner_set_interval(cm->spinner, -1);
129 gtk_widget_set_sensitive(cm->button_stop, FALSE);
130 gtk_widget_set_sensitive(cm->button_close, TRUE);
133 static gint cache_maintain_home_cb(gpointer data)
139 gint just_done = FALSE;
140 gint still_have_a_file = TRUE;
142 const gchar *cache_folder;
146 cache_folder = GQVIEW_CACHE_RC_METADATA;
150 cache_folder = GQVIEW_CACHE_RC_THUMB;
153 base_length = strlen(homedir()) + strlen("/") + strlen(cache_folder);
157 if (debug) printf("purge chk done.\n");
159 cache_maintain_home_stop(cm);
163 path = cm->list->data;
165 if (debug) printf("purge chk (%d) \"%s\"\n", (cm->clear && !cm->metadata), path);
167 if (g_list_find(cm->done_list, path) == NULL)
169 cm->done_list = g_list_prepend(cm->done_list, path);
171 if (path_list(path, &list, &dlist))
176 still_have_a_file = FALSE;
181 gchar *path_buf = work->data;
184 dot = extension_find_dot(path_buf);
186 if (dot) *dot = '\0';
187 if ((!cm->metadata && cm->clear) ||
188 (strlen(path_buf) > base_length && !isfile(path_buf + base_length)) )
191 if (!unlink_file(path_buf)) printf("failed to delete:%s\n", path_buf);
195 still_have_a_file = TRUE;
201 path_list_free(list);
203 cm->list = g_list_concat(dlist, cm->list);
205 if (cm->list && g_list_find(cm->done_list, cm->list->data) != NULL)
207 /* check if the dir is empty */
209 if (cm->list->data == path && just_done)
211 if (!still_have_a_file && !dlist && cm->list->next && !rmdir_utf8(path))
213 printf("Unable to delete dir: %s\n", path);
218 /* must re-check for an empty dir */
219 if (isempty(path) && cm->list->next && !rmdir_utf8(path))
221 printf("Unable to delete dir: %s\n", path);
225 path = cm->list->data;
226 cm->done_list = g_list_remove(cm->done_list, path);
227 cm->list = g_list_remove(cm->list, path);
235 path = cm->list->data;
236 if (strlen(path) > base_length)
238 buf = path + base_length;
244 gtk_entry_set_text(GTK_ENTRY(cm->entry), buf);
250 static void cache_maintain_home_close_cb(GenericDialog *gd, gpointer data)
254 if (!GTK_WIDGET_SENSITIVE(cm->button_close)) return;
256 cache_maintain_home_close(cm);
259 static void cache_maintain_home_stop_cb(GenericDialog *gd, gpointer data)
263 cache_maintain_home_stop(cm);
266 /* sorry for complexity (cm->done_list), but need it to remove empty dirs */
267 void cache_maintain_home(gint metadata, gint clear, GtkWidget *parent)
273 const gchar *cache_folder;
278 cache_folder = GQVIEW_CACHE_RC_METADATA;
282 cache_folder = GQVIEW_CACHE_RC_THUMB;
285 base = g_strconcat(homedir(), "/", cache_folder, NULL);
287 if (!path_list(base, NULL, &dlist))
293 dlist = g_list_append(dlist, base);
295 cm = g_new0(CMData, 1);
297 cm->done_list = NULL;
299 cm->metadata = metadata;
303 msg = _("Removing old metadata...");
307 msg = _("Clearing cached thumbnails...");
311 msg = _("Removing old thumbnails...");
314 cm->gd = generic_dialog_new(_("Maintenance"),
315 GQ_WMCLASS, "main_maintenance",
318 cm->gd->cancel_cb = cache_maintain_home_close_cb;
319 cm->button_close = generic_dialog_add_button(cm->gd, GTK_STOCK_CLOSE, NULL,
320 cache_maintain_home_close_cb, FALSE);
321 gtk_widget_set_sensitive(cm->button_close, FALSE);
322 cm->button_stop = generic_dialog_add_button(cm->gd, GTK_STOCK_STOP, NULL,
323 cache_maintain_home_stop_cb, FALSE);
325 generic_dialog_add_message(cm->gd, NULL, msg, NULL);
326 gtk_window_set_default_size(GTK_WINDOW(cm->gd->dialog), PURGE_DIALOG_WIDTH, -1);
328 hbox = gtk_hbox_new(FALSE, 0);
329 gtk_box_pack_start(GTK_BOX(cm->gd->vbox), hbox, FALSE, FALSE, 5);
330 gtk_widget_show(hbox);
332 cm->entry = gtk_entry_new();
333 GTK_WIDGET_UNSET_FLAGS(cm->entry, GTK_CAN_FOCUS);
334 gtk_editable_set_editable(GTK_EDITABLE(cm->entry), FALSE);
335 gtk_box_pack_start(GTK_BOX(hbox), cm->entry, TRUE, TRUE, 0);
336 gtk_widget_show(cm->entry);
338 cm->spinner = spinner_new(NULL, SPINNER_SPEED);
339 gtk_box_pack_start(GTK_BOX(hbox), cm->spinner, FALSE, FALSE, 0);
340 gtk_widget_show(cm->spinner);
342 gtk_widget_show(cm->gd->dialog);
344 cm->idle_id = g_idle_add(cache_maintain_home_cb, cm);
347 /* This checks all files in ~/.geeqie/thumbnails and
348 * removes them if thay have no source counterpart.
349 * (this assumes all cache files have an extension of 4 chars including '.')
351 gint cache_maintain_home_dir(const gchar *dir, gint recursive, gint clear)
357 gint still_have_a_file = FALSE;
359 if (debug) printf("maintainance check: %s\n", dir);
361 base_length = strlen(homedir()) + strlen("/") + strlen(GQVIEW_CACHE_RC_THUMB);
362 base = g_strconcat(homedir(), "/", GQVIEW_CACHE_RC_THUMB, dir, NULL);
364 if (path_list(base, &flist, &dlist))
371 gchar *path = work->data;
372 if (recursive && strlen(path) > base_length &&
373 !cache_maintain_home_dir(path + base_length, recursive, clear))
375 if (debug) printf("Deleting thumb dir: %s\n", path);
376 if (!rmdir_utf8(path))
378 printf("Unable to delete dir: %s\n", path);
383 still_have_a_file = TRUE;
391 gchar *path = work->data;
394 dot = extension_find_dot(path);
396 if (dot) *dot = '\0';
398 (strlen(path) > base_length && !isfile(path + base_length)) )
401 if (!unlink_file(path)) printf("failed to delete:%s\n", path);
405 still_have_a_file = TRUE;
412 path_list_free(dlist);
413 path_list_free(flist);
416 return still_have_a_file;
419 /* This checks relative caches in dir/.thumbnails and
420 * removes them if they have no source counterpart.
422 gint cache_maintain_dir(const gchar *dir, gint recursive, gint clear)
426 gint still_have_a_file = FALSE;
429 cachedir = g_strconcat(dir, "/", GQVIEW_CACHE_LOCAL_THUMB, NULL);
431 path_list(cachedir, &list, NULL);
442 source = g_strconcat(dir, "/", filename_from_path(path), NULL);
445 extension_truncate(source, GQVIEW_CACHE_EXT_THUMB) ||
446 extension_truncate(source, GQVIEW_CACHE_EXT_SIM))
448 if (!clear && isfile(source))
450 still_have_a_file = TRUE;
454 if (!unlink_file(path))
456 if (debug) printf("Failed to remove cache file %s\n", path);
457 still_have_a_file = TRUE;
463 still_have_a_file = TRUE;
468 path_list_free(list);
475 path_list(dir, NULL, &list);
479 const gchar *path = work->data;
482 still_have_a_file |= cache_maintain_dir(path, recursive, clear);
485 path_list_free(list);
488 return still_have_a_file;
491 static void cache_file_move(const gchar *src, const gchar *dest)
493 if (!dest || !src || !isfile(src)) return;
495 if (!move_file(src, dest))
497 if (debug) printf("Failed to move cache file %s\nto %s\n", src, dest);
498 /* we remove it anyway - it's stale */
503 void cache_maint_moved(FileData *fd)
507 const gchar *src = fd->change->source;
508 const gchar *dest = fd->change->dest;
510 if (!src || !dest) return;
512 base = cache_get_location(CACHE_TYPE_THUMB, dest, FALSE, &mode);
513 if (cache_ensure_dir_exists(base, mode))
518 buf = cache_find_location(CACHE_TYPE_THUMB, src);
519 d = cache_get_location(CACHE_TYPE_THUMB, dest, TRUE, NULL);
520 cache_file_move(buf, d);
524 buf = cache_find_location(CACHE_TYPE_SIM, src);
525 d = cache_get_location(CACHE_TYPE_SIM, dest, TRUE, NULL);
526 cache_file_move(buf, d);
532 printf("Failed to create cache dir for move %s\n", base);
536 base = cache_get_location(CACHE_TYPE_METADATA, dest, FALSE, &mode);
537 if (cache_ensure_dir_exists(base, mode))
542 buf = cache_find_location(CACHE_TYPE_METADATA, src);
543 d = cache_get_location(CACHE_TYPE_METADATA, dest, TRUE, NULL);
544 cache_file_move(buf, d);
550 if (enable_thumb_caching && thumbnail_spec_standard) thumb_std_maint_moved(src, dest);
553 static void cache_file_remove(const gchar *path)
555 if (path && isfile(path) && !unlink_file(path))
557 if (debug) printf("Failed to remove cache file %s\n", path);
561 void cache_maint_removed(FileData *fd)
565 buf = cache_find_location(CACHE_TYPE_THUMB, fd->path);
566 cache_file_remove(buf);
569 buf = cache_find_location(CACHE_TYPE_SIM, fd->path);
570 cache_file_remove(buf);
573 buf = cache_find_location(CACHE_TYPE_METADATA, fd->path);
574 cache_file_remove(buf);
577 if (enable_thumb_caching && thumbnail_spec_standard) thumb_std_maint_removed(fd->path);
580 void cache_maint_copied(FileData *fd)
586 src_cache = cache_find_location(CACHE_TYPE_METADATA, fd->change->source);
587 if (!src_cache) return;
589 dest_base = cache_get_location(CACHE_TYPE_METADATA, fd->change->dest, FALSE, &mode);
590 if (cache_ensure_dir_exists(dest_base, mode))
594 path = cache_get_location(CACHE_TYPE_METADATA, fd->change->dest, TRUE, NULL);
595 if (!copy_file(src_cache, path))
597 if (debug) printf("failed to copy metadata %s to %s\n", src_cache, path);
607 *-------------------------------------------------------------------
608 * new cache maintenance utilities
609 *-------------------------------------------------------------------
612 typedef struct _CacheManager CacheManager;
615 GenericDialog *dialog;
616 GtkWidget *folder_entry;
625 typedef struct _CleanData CleanData;
637 GtkWidget *button_close;
638 GtkWidget *button_stop;
639 GtkWidget *button_start;
655 static void cache_manager_render_reset(CleanData *cd)
657 path_list_free(cd->list);
660 path_list_free(cd->list_dir);
663 thumb_loader_free((ThumbLoader *)cd->tl);
667 static void cache_manager_render_close_cb(GenericDialog *fd, gpointer data)
669 CleanData *cd = data;
671 if (!GTK_WIDGET_SENSITIVE(cd->button_close)) return;
673 cache_manager_render_reset(cd);
674 generic_dialog_close(cd->gd);
678 static void cache_manager_render_finish(CleanData *cd)
680 cache_manager_render_reset(cd);
682 gtk_entry_set_text(GTK_ENTRY(cd->progress), _("done"));
683 spinner_set_interval(cd->spinner, -1);
685 gtk_widget_set_sensitive(cd->group, TRUE);
686 gtk_widget_set_sensitive(cd->button_start, TRUE);
687 gtk_widget_set_sensitive(cd->button_stop, FALSE);
688 gtk_widget_set_sensitive(cd->button_close, TRUE);
691 static void cache_manager_render_stop_cb(GenericDialog *fd, gpointer data)
693 CleanData *cd = data;
695 cache_manager_render_finish(cd);
698 static void cache_manager_render_folder(CleanData *cd, const gchar *path)
700 GList *list_d = NULL;
701 GList *list_f = NULL;
705 path_list(path, &list_f, &list_d);
709 path_list(path, &list_f, NULL);
712 list_f = path_list_filter(list_f, FALSE);
713 list_d = path_list_filter(list_d, TRUE);
715 cd->list = g_list_concat(list_f, cd->list);
716 cd->list_dir = g_list_concat(list_d, cd->list_dir);
719 static gint cache_manager_render_file(CleanData *cd);
721 static void cache_manager_render_thumb_done_cb(ThumbLoader *tl, gpointer data)
723 CleanData *cd = data;
725 thumb_loader_free((ThumbLoader *)cd->tl);
728 while (cache_manager_render_file(cd));
731 static gint cache_manager_render_file(CleanData *cd)
738 path = cd->list->data;
739 cd->list = g_list_remove(cd->list, path);
741 cd->tl = (ThumbLoaderStd *)thumb_loader_new(thumb_max_width, thumb_max_height);
742 thumb_loader_set_callbacks((ThumbLoader *)cd->tl,
743 cache_manager_render_thumb_done_cb,
744 cache_manager_render_thumb_done_cb,
746 thumb_loader_set_cache((ThumbLoader *)cd->tl, TRUE, cd->local, TRUE);
747 success = thumb_loader_start((ThumbLoader *)cd->tl, path);
750 gtk_entry_set_text(GTK_ENTRY(cd->progress), path);
754 thumb_loader_free((ThumbLoader *)cd->tl);
762 else if (cd->list_dir)
766 path = cd->list_dir->data;
767 cd->list_dir = g_list_remove(cd->list_dir, path);
769 cache_manager_render_folder(cd, path);
776 cache_manager_render_finish(cd);
781 static void cache_manager_render_start_cb(GenericDialog *fd, gpointer data)
783 CleanData *cd = data;
786 if (cd->list || !GTK_WIDGET_SENSITIVE(cd->button_start)) return;
788 path = remove_trailing_slash((gtk_entry_get_text(GTK_ENTRY(cd->entry))));
789 parse_out_relatives(path);
793 warning_dialog(_("Invalid folder"),
794 _("The specified folder can not be found."),
795 GTK_STOCK_DIALOG_WARNING, cd->gd->dialog);
799 gtk_widget_set_sensitive(cd->group, FALSE);
800 gtk_widget_set_sensitive(cd->button_start, FALSE);
801 gtk_widget_set_sensitive(cd->button_stop, TRUE);
802 gtk_widget_set_sensitive(cd->button_close, FALSE);
804 spinner_set_interval(cd->spinner, SPINNER_SPEED);
806 cache_manager_render_folder(cd, path);
807 while (cache_manager_render_file(cd));
813 static void cache_manager_render_dialog(GtkWidget *widget, const gchar *path)
820 cd = g_new0(CleanData, 1);
822 cd->gd = generic_dialog_new(_("Create thumbnails"),
823 GQ_WMCLASS, "create_thumbnails",
826 gtk_window_set_default_size(GTK_WINDOW(cd->gd->dialog), PURGE_DIALOG_WIDTH, -1);
827 cd->gd->cancel_cb = cache_manager_render_close_cb;
828 cd->button_close = generic_dialog_add_button(cd->gd, GTK_STOCK_CLOSE, NULL,
829 cache_manager_render_close_cb, FALSE);
830 cd->button_start = generic_dialog_add_button(cd->gd, GTK_STOCK_OK, _("S_tart"),
831 cache_manager_render_start_cb, FALSE);
832 cd->button_stop = generic_dialog_add_button(cd->gd, GTK_STOCK_STOP, NULL,
833 cache_manager_render_stop_cb, FALSE);
834 gtk_widget_set_sensitive(cd->button_stop, FALSE);
836 generic_dialog_add_message(cd->gd, NULL, _("Create thumbnails"), NULL);
838 hbox = pref_box_new(cd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, 0);
839 pref_spacer(hbox, PREF_PAD_INDENT);
840 cd->group = pref_box_new(hbox, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
842 hbox = pref_box_new(cd->group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
843 pref_label_new(hbox, _("Folder:"));
845 label = tab_completion_new(&cd->entry, path, NULL, NULL);
846 tab_completion_add_select_button(cd->entry,_("Select folder") , TRUE);
847 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
848 gtk_widget_show(label);
850 pref_checkbox_new_int(cd->group, _("Include subfolders"), FALSE, &cd->recurse);
851 button = pref_checkbox_new_int(cd->group, _("Store thumbnails local to source images"), FALSE, &cd->local);
852 gtk_widget_set_sensitive(button, thumbnail_spec_standard);
854 pref_line(cd->gd->vbox, PREF_PAD_SPACE);
855 hbox = pref_box_new(cd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
857 cd->progress = gtk_entry_new();
858 GTK_WIDGET_UNSET_FLAGS(cd->progress, GTK_CAN_FOCUS);
859 gtk_editable_set_editable(GTK_EDITABLE(cd->progress), FALSE);
860 gtk_entry_set_text(GTK_ENTRY(cd->progress), _("click start to begin"));
861 gtk_box_pack_start(GTK_BOX(hbox), cd->progress, TRUE, TRUE, 0);
862 gtk_widget_show(cd->progress);
864 cd->spinner = spinner_new(NULL, -1);
865 gtk_box_pack_start(GTK_BOX(hbox), cd->spinner, FALSE, FALSE, 0);
866 gtk_widget_show(cd->spinner);
870 gtk_widget_show(cd->gd->dialog);
876 static void cache_manager_standard_clean_close_cb(GenericDialog *gd, gpointer data)
878 CleanData *cd = data;
880 if (!GTK_WIDGET_SENSITIVE(cd->button_close)) return;
882 generic_dialog_close(cd->gd);
884 thumb_loader_std_thumb_file_validate_cancel(cd->tl);
885 path_list_free(cd->list);
889 static void cache_manager_standard_clean_done(CleanData *cd)
891 gtk_widget_set_sensitive(cd->button_stop, FALSE);
892 gtk_widget_set_sensitive(cd->button_close, TRUE);
894 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress), 1.0);
895 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("done"));
897 if (cd->idle_id != -1)
899 g_source_remove(cd->idle_id);
903 thumb_loader_std_thumb_file_validate_cancel(cd->tl);
906 path_list_free(cd->list);
910 static void cache_manager_standard_clean_stop_cb(GenericDialog *gd, gpointer data)
912 CleanData *cd = data;
914 cache_manager_standard_clean_done(cd);
917 static gint cache_manager_standard_clean_clear_cb(gpointer data)
919 CleanData *cd = data;
925 next_path = cd->list->data;
926 cd->list = g_list_remove(cd->list, next_path);
928 if (debug) printf("thumb removed: %s\n", next_path);
930 unlink_file(next_path);
934 if (cd->count_total != 0)
936 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress),
937 (gdouble)cd->count_done / cd->count_total);
944 cache_manager_standard_clean_done(cd);
948 static void cache_manager_standard_clean_valid_cb(const gchar *path, gint valid, gpointer data)
950 CleanData *cd = data;
956 if (debug) printf("thumb cleaned: %s\n", path);
961 if (cd->count_total != 0)
963 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress),
964 (gdouble)cd->count_done / cd->count_total);
973 next_path = cd->list->data;
974 cd->list = g_list_remove(cd->list, next_path);
976 cd->tl = thumb_loader_std_thumb_file_validate(next_path, cd->days,
977 cache_manager_standard_clean_valid_cb, cd);
982 cache_manager_standard_clean_done(cd);
986 static void cache_manager_standard_clean_start_cb(GenericDialog *gd, gpointer data)
988 CleanData *cd = data;
992 if (cd->list || !GTK_WIDGET_SENSITIVE(cd->button_start)) return;
994 gtk_widget_set_sensitive(cd->button_start, FALSE);
995 gtk_widget_set_sensitive(cd->button_stop, TRUE);
996 gtk_widget_set_sensitive(cd->button_close, FALSE);
998 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("running..."));
1000 path = g_strconcat(homedir(), "/", THUMB_FOLDER_GLOBAL, "/", THUMB_FOLDER_NORMAL, NULL);
1002 path_list(path, &list, NULL);
1006 path = g_strconcat(homedir(), "/", THUMB_FOLDER_GLOBAL, "/", THUMB_FOLDER_LARGE, NULL);
1008 path_list(path, &list, NULL);
1009 cd->list = g_list_concat(cd->list, list);
1012 path = g_strconcat(homedir(), "/", THUMB_FOLDER_GLOBAL, "/", THUMB_FOLDER_FAIL, NULL);
1014 path_list(path, &list, NULL);
1015 cd->list = g_list_concat(cd->list, list);
1018 cd->count_total = g_list_length(cd->list);
1021 /* start iterating */
1024 cd->idle_id = g_idle_add(cache_manager_standard_clean_clear_cb, cd);
1028 cache_manager_standard_clean_valid_cb(NULL, TRUE, cd);
1032 static void cache_manager_standard_process(GtkWidget *widget, gint clear)
1035 const gchar *stock_id;
1038 cd = g_new0(CleanData, 1);
1043 stock_id = GTK_STOCK_DELETE;
1044 msg = _("Clearing thumbnails...");
1048 stock_id = GTK_STOCK_CLEAR;
1049 msg = _("Removing old thumbnails...");
1052 cd->gd = generic_dialog_new(_("Maintenance"),
1053 GQ_WMCLASS, "standard_maintenance",
1056 cd->gd->cancel_cb = cache_manager_standard_clean_close_cb;
1057 cd->button_close = generic_dialog_add_button(cd->gd, GTK_STOCK_CLOSE, NULL,
1058 cache_manager_standard_clean_close_cb, FALSE);
1059 cd->button_start = generic_dialog_add_button(cd->gd, GTK_STOCK_OK, _("S_tart"),
1060 cache_manager_standard_clean_start_cb, FALSE);
1061 cd->button_stop = generic_dialog_add_button(cd->gd, GTK_STOCK_STOP, NULL,
1062 cache_manager_standard_clean_stop_cb, FALSE);
1063 gtk_widget_set_sensitive(cd->button_stop, FALSE);
1065 generic_dialog_add_message(cd->gd, stock_id, msg, NULL);
1067 cd->progress = gtk_progress_bar_new();
1068 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("click start to begin"));
1069 gtk_box_pack_start(GTK_BOX(cd->gd->vbox), cd->progress, FALSE, FALSE, 0);
1070 gtk_widget_show(cd->progress);
1076 gtk_widget_show(cd->gd->dialog);
1079 static void cache_manager_standard_clean_cb(GtkWidget *widget, gpointer data)
1081 cache_manager_standard_process(widget, FALSE);
1084 static void cache_manager_standard_clear_cb(GtkWidget *widget, gpointer data)
1086 cache_manager_standard_process(widget, TRUE);
1090 static void cache_manager_main_clean_cb(GtkWidget *widget, gpointer data)
1092 cache_maintain_home(FALSE, FALSE, widget);
1096 static void dummy_cancel_cb(GenericDialog *gd, gpointer data)
1098 /* no op, only so cancel button appears */
1101 static void cache_manager_main_clear_ok_cb(GenericDialog *gd, gpointer data)
1103 cache_maintain_home(FALSE, TRUE, NULL);
1106 void cache_manager_main_clear_confirm(GtkWidget *parent)
1110 gd = generic_dialog_new(_("Clear cache"),
1111 GQ_WMCLASS, "clear_cache", parent, TRUE,
1112 dummy_cancel_cb, NULL);
1113 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Clear cache"),
1114 _("This will remove all thumbnails that have\nbeen saved to disk, continue?"));
1115 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, cache_manager_main_clear_ok_cb, TRUE);
1117 gtk_widget_show(gd->dialog);
1120 static void cache_manager_main_clear_cb(GtkWidget *widget, gpointer data)
1122 cache_manager_main_clear_confirm(widget);
1125 static void cache_manager_render_cb(GtkWidget *widget, gpointer data)
1127 cache_manager_render_dialog(widget, homedir());
1130 static void cache_manager_metadata_clean_cb(GtkWidget *widget, gpointer data)
1132 cache_maintain_home(TRUE, FALSE, widget);
1136 static CacheManager *cache_manager = NULL;
1138 static void cache_manager_close_cb(GenericDialog *gd, gpointer data)
1140 generic_dialog_close(gd);
1142 g_free(cache_manager);
1143 cache_manager = NULL;
1146 void cache_manager_show(void)
1153 GtkSizeGroup *sizegroup;
1158 gtk_window_present(GTK_WINDOW(cache_manager->dialog->dialog));
1162 cache_manager = g_new0(CacheManager, 1);
1164 cache_manager->dialog = generic_dialog_new(_("Cache Maintenance - Geeqie"),
1165 GQ_WMCLASS, "cache_manager",
1167 NULL, cache_manager);
1168 gd = cache_manager->dialog;
1170 gd->cancel_cb = cache_manager_close_cb;
1171 generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL,
1172 cache_manager_close_cb, FALSE);
1174 generic_dialog_add_message(gd, NULL, _("Cache and Data Maintenance"), NULL);
1176 sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1178 group = pref_group_new(gd->vbox, FALSE, _("Geeqie thumbnail cache"), GTK_ORIENTATION_VERTICAL);
1180 buf = g_strconcat(_("Location:"), " ", homedir(), "/", GQVIEW_CACHE_RC_THUMB, NULL);
1181 label = pref_label_new(group, buf);
1182 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1185 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1187 button = pref_table_button(table, 0, 0, GTK_STOCK_CLEAR, _("Clean up"), FALSE,
1188 G_CALLBACK(cache_manager_main_clean_cb), cache_manager);
1189 gtk_size_group_add_widget(sizegroup, button);
1190 pref_table_label(table, 1, 0, _("Remove orphaned or outdated thumbnails."), 0.0);
1192 button = pref_table_button(table, 0, 1, GTK_STOCK_DELETE, _("Clear cache"), FALSE,
1193 G_CALLBACK(cache_manager_main_clear_cb), cache_manager);
1194 gtk_size_group_add_widget(sizegroup, button);
1195 pref_table_label(table, 1, 1, _("Delete all cached thumbnails."), 0.0);
1198 group = pref_group_new(gd->vbox, FALSE, _("Shared thumbnail cache"), GTK_ORIENTATION_VERTICAL);
1200 buf = g_strconcat(_("Location:"), " ", homedir(), "/", THUMB_FOLDER_GLOBAL, NULL);
1201 label = pref_label_new(group, buf);
1202 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1205 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1207 button = pref_table_button(table, 0, 0, GTK_STOCK_CLEAR, _("Clean up"), FALSE,
1208 G_CALLBACK(cache_manager_standard_clean_cb), cache_manager);
1209 gtk_size_group_add_widget(sizegroup, button);
1210 pref_table_label(table, 1, 0, _("Remove orphaned or outdated thumbnails."), 0.0);
1212 button = pref_table_button(table, 0, 1, GTK_STOCK_DELETE, _("Clear cache"), FALSE,
1213 G_CALLBACK(cache_manager_standard_clear_cb), cache_manager);
1214 gtk_size_group_add_widget(sizegroup, button);
1215 pref_table_label(table, 1, 1, _("Delete all cached thumbnails."), 0.0);
1217 group = pref_group_new(gd->vbox, FALSE, _("Create thumbnails"), GTK_ORIENTATION_VERTICAL);
1219 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1221 button = pref_table_button(table, 0, 1, GTK_STOCK_EXECUTE, _("Render"), FALSE,
1222 G_CALLBACK(cache_manager_render_cb), cache_manager);
1223 gtk_size_group_add_widget(sizegroup, button);
1224 pref_table_label(table, 1, 1, _("Render thumbnails for a specific folder."), 0.0);
1226 group = pref_group_new(gd->vbox, FALSE, _("Metadata"), GTK_ORIENTATION_VERTICAL);
1228 buf = g_strconcat(_("Location:"), " ", homedir(), "/", GQVIEW_CACHE_RC_METADATA, NULL);
1229 label = pref_label_new(group, buf);
1230 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1233 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1235 button = pref_table_button(table, 0, 0, GTK_STOCK_CLEAR, _("Clean up"), FALSE,
1236 G_CALLBACK(cache_manager_metadata_clean_cb), cache_manager);
1237 gtk_size_group_add_widget(sizegroup, button);
1238 pref_table_label(table, 1, 0, _("Remove orphaned keywords and comments."), 0.0);
1240 gtk_widget_show(cache_manager->dialog->dialog);