4 * Copyright (C) 2008 The Geeqie Team
8 * This software is released under the GNU General Public License (GNU GPL).
9 * Please read the included file COPYING for more information.
10 * This software comes with no warranty of any kind, use at your own risk!
14 #include "cache_maint.h"
19 #include "thumb_standard.h"
20 #include "ui_fileops.h"
22 #include "ui_spinner.h"
23 #include "ui_tabcomp.h"
24 #include "ui_utildlg.h"
27 typedef struct _CMData CMData;
36 GtkWidget *button_stop;
37 GtkWidget *button_close;
42 #define PURGE_DIALOG_WIDTH 400
46 *-------------------------------------------------------------------
48 *-------------------------------------------------------------------
51 static gint extension_truncate(gchar *path, const gchar *ext)
56 if (!path || !ext) return FALSE;
61 if (l < el || strcmp(path + (l - el), ext) != 0) return FALSE;
68 static gchar *extension_find_dot(gchar *path)
72 if (!path || *path == '\0') return NULL;
75 while (*ptr != '\0') ptr++;
77 while (ptr > path && *ptr != '.') ptr--;
79 if (ptr == path) return NULL;
84 static gint isempty(const gchar *path)
90 pathl = path_from_utf8(path);
93 if (!dp) return FALSE;
95 while ((dir = readdir(dp)) != NULL)
97 gchar *name = dir->d_name;
99 if (!(name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) )
110 static void cache_maintain_home_close(CMData *cm)
112 if (cm->idle_id != -1) g_source_remove(cm->idle_id);
113 if (cm->gd) generic_dialog_close(cm->gd);
114 path_list_free(cm->list);
115 g_list_free(cm->done_list);
119 static void cache_maintain_home_stop(CMData *cm)
121 if (cm->idle_id != -1)
123 g_source_remove(cm->idle_id);
127 gtk_entry_set_text(GTK_ENTRY(cm->entry), _("done"));
128 spinner_set_interval(cm->spinner, -1);
130 gtk_widget_set_sensitive(cm->button_stop, FALSE);
131 gtk_widget_set_sensitive(cm->button_close, TRUE);
134 static gint cache_maintain_home_cb(gpointer data)
140 gint just_done = FALSE;
141 gint still_have_a_file = TRUE;
143 const gchar *cache_folder;
147 cache_folder = GQ_CACHE_RC_METADATA;
151 cache_folder = GQ_CACHE_RC_THUMB;
154 base_length = strlen(homedir()) + strlen("/") + strlen(cache_folder);
158 if (debug) printf("purge chk done.\n");
160 cache_maintain_home_stop(cm);
164 path = cm->list->data;
166 if (debug) printf("purge chk (%d) \"%s\"\n", (cm->clear && !cm->metadata), path);
168 if (g_list_find(cm->done_list, path) == NULL)
170 cm->done_list = g_list_prepend(cm->done_list, path);
172 if (path_list(path, &list, &dlist))
177 still_have_a_file = FALSE;
182 gchar *path_buf = work->data;
185 dot = extension_find_dot(path_buf);
187 if (dot) *dot = '\0';
188 if ((!cm->metadata && cm->clear) ||
189 (strlen(path_buf) > base_length && !isfile(path_buf + base_length)) )
192 if (!unlink_file(path_buf)) printf("failed to delete:%s\n", path_buf);
196 still_have_a_file = TRUE;
202 path_list_free(list);
204 cm->list = g_list_concat(dlist, cm->list);
206 if (cm->list && g_list_find(cm->done_list, cm->list->data) != NULL)
208 /* check if the dir is empty */
210 if (cm->list->data == path && just_done)
212 if (!still_have_a_file && !dlist && cm->list->next && !rmdir_utf8(path))
214 printf("Unable to delete dir: %s\n", path);
219 /* must re-check for an empty dir */
220 if (isempty(path) && cm->list->next && !rmdir_utf8(path))
222 printf("Unable to delete dir: %s\n", path);
226 path = cm->list->data;
227 cm->done_list = g_list_remove(cm->done_list, path);
228 cm->list = g_list_remove(cm->list, path);
236 path = cm->list->data;
237 if (strlen(path) > base_length)
239 buf = path + base_length;
245 gtk_entry_set_text(GTK_ENTRY(cm->entry), buf);
251 static void cache_maintain_home_close_cb(GenericDialog *gd, gpointer data)
255 if (!GTK_WIDGET_SENSITIVE(cm->button_close)) return;
257 cache_maintain_home_close(cm);
260 static void cache_maintain_home_stop_cb(GenericDialog *gd, gpointer data)
264 cache_maintain_home_stop(cm);
267 /* sorry for complexity (cm->done_list), but need it to remove empty dirs */
268 void cache_maintain_home(gint metadata, gint clear, GtkWidget *parent)
274 const gchar *cache_folder;
279 cache_folder = GQ_CACHE_RC_METADATA;
283 cache_folder = GQ_CACHE_RC_THUMB;
286 base = g_strconcat(homedir(), "/", cache_folder, NULL);
288 if (!path_list(base, NULL, &dlist))
294 dlist = g_list_append(dlist, base);
296 cm = g_new0(CMData, 1);
298 cm->done_list = NULL;
300 cm->metadata = metadata;
304 msg = _("Removing old metadata...");
308 msg = _("Clearing cached thumbnails...");
312 msg = _("Removing old thumbnails...");
315 cm->gd = generic_dialog_new(_("Maintenance"),
316 GQ_WMCLASS, "main_maintenance",
319 cm->gd->cancel_cb = cache_maintain_home_close_cb;
320 cm->button_close = generic_dialog_add_button(cm->gd, GTK_STOCK_CLOSE, NULL,
321 cache_maintain_home_close_cb, FALSE);
322 gtk_widget_set_sensitive(cm->button_close, FALSE);
323 cm->button_stop = generic_dialog_add_button(cm->gd, GTK_STOCK_STOP, NULL,
324 cache_maintain_home_stop_cb, FALSE);
326 generic_dialog_add_message(cm->gd, NULL, msg, NULL);
327 gtk_window_set_default_size(GTK_WINDOW(cm->gd->dialog), PURGE_DIALOG_WIDTH, -1);
329 hbox = gtk_hbox_new(FALSE, 0);
330 gtk_box_pack_start(GTK_BOX(cm->gd->vbox), hbox, FALSE, FALSE, 5);
331 gtk_widget_show(hbox);
333 cm->entry = gtk_entry_new();
334 GTK_WIDGET_UNSET_FLAGS(cm->entry, GTK_CAN_FOCUS);
335 gtk_editable_set_editable(GTK_EDITABLE(cm->entry), FALSE);
336 gtk_box_pack_start(GTK_BOX(hbox), cm->entry, TRUE, TRUE, 0);
337 gtk_widget_show(cm->entry);
339 cm->spinner = spinner_new(NULL, SPINNER_SPEED);
340 gtk_box_pack_start(GTK_BOX(hbox), cm->spinner, FALSE, FALSE, 0);
341 gtk_widget_show(cm->spinner);
343 gtk_widget_show(cm->gd->dialog);
345 cm->idle_id = g_idle_add(cache_maintain_home_cb, cm);
348 /* This checks all files in ~/GQ_RC_DIR/thumbnails and
349 * removes them if thay have no source counterpart.
350 * (this assumes all cache files have an extension of 4 chars including '.')
352 gint cache_maintain_home_dir(const gchar *dir, gint recursive, gint clear)
358 gint still_have_a_file = FALSE;
360 if (debug) printf("maintainance check: %s\n", dir);
362 base_length = strlen(homedir()) + strlen("/") + strlen(GQ_CACHE_RC_THUMB);
363 base = g_strconcat(homedir(), "/", GQ_CACHE_RC_THUMB, dir, NULL);
365 if (path_list(base, &flist, &dlist))
372 gchar *path = work->data;
373 if (recursive && strlen(path) > base_length &&
374 !cache_maintain_home_dir(path + base_length, recursive, clear))
376 if (debug) printf("Deleting thumb dir: %s\n", path);
377 if (!rmdir_utf8(path))
379 printf("Unable to delete dir: %s\n", path);
384 still_have_a_file = TRUE;
392 gchar *path = work->data;
395 dot = extension_find_dot(path);
397 if (dot) *dot = '\0';
399 (strlen(path) > base_length && !isfile(path + base_length)) )
402 if (!unlink_file(path)) printf("failed to delete:%s\n", path);
406 still_have_a_file = TRUE;
413 path_list_free(dlist);
414 path_list_free(flist);
417 return still_have_a_file;
420 /* This checks relative caches in dir/.thumbnails and
421 * removes them if they have no source counterpart.
423 gint cache_maintain_dir(const gchar *dir, gint recursive, gint clear)
427 gint still_have_a_file = FALSE;
430 cachedir = g_strconcat(dir, "/", GQ_CACHE_LOCAL_THUMB, NULL);
432 path_list(cachedir, &list, NULL);
443 source = g_strconcat(dir, "/", filename_from_path(path), NULL);
446 extension_truncate(source, GQ_CACHE_EXT_THUMB) ||
447 extension_truncate(source, GQ_CACHE_EXT_SIM))
449 if (!clear && isfile(source))
451 still_have_a_file = TRUE;
455 if (!unlink_file(path))
457 if (debug) printf("Failed to remove cache file %s\n", path);
458 still_have_a_file = TRUE;
464 still_have_a_file = TRUE;
469 path_list_free(list);
476 path_list(dir, NULL, &list);
480 const gchar *path = work->data;
483 still_have_a_file |= cache_maintain_dir(path, recursive, clear);
486 path_list_free(list);
489 return still_have_a_file;
492 static void cache_file_move(const gchar *src, const gchar *dest)
494 if (!dest || !src || !isfile(src)) return;
496 if (!move_file(src, dest))
498 if (debug) printf("Failed to move cache file %s\nto %s\n", src, dest);
499 /* we remove it anyway - it's stale */
504 void cache_maint_moved(FileData *fd)
508 const gchar *src = fd->change->source;
509 const gchar *dest = fd->change->dest;
511 if (!src || !dest) return;
513 base = cache_get_location(CACHE_TYPE_THUMB, dest, FALSE, &mode);
514 if (cache_ensure_dir_exists(base, mode))
519 buf = cache_find_location(CACHE_TYPE_THUMB, src);
520 d = cache_get_location(CACHE_TYPE_THUMB, dest, TRUE, NULL);
521 cache_file_move(buf, d);
525 buf = cache_find_location(CACHE_TYPE_SIM, src);
526 d = cache_get_location(CACHE_TYPE_SIM, dest, TRUE, NULL);
527 cache_file_move(buf, d);
533 printf("Failed to create cache dir for move %s\n", base);
537 base = cache_get_location(CACHE_TYPE_METADATA, dest, FALSE, &mode);
538 if (cache_ensure_dir_exists(base, mode))
543 buf = cache_find_location(CACHE_TYPE_METADATA, src);
544 d = cache_get_location(CACHE_TYPE_METADATA, dest, TRUE, NULL);
545 cache_file_move(buf, d);
551 if (options->thumbnails.enable_caching && options->thumbnails.spec_standard)
552 thumb_std_maint_moved(src, dest);
555 static void cache_file_remove(const gchar *path)
557 if (path && isfile(path) && !unlink_file(path))
559 if (debug) printf("Failed to remove cache file %s\n", path);
563 void cache_maint_removed(FileData *fd)
567 buf = cache_find_location(CACHE_TYPE_THUMB, fd->path);
568 cache_file_remove(buf);
571 buf = cache_find_location(CACHE_TYPE_SIM, fd->path);
572 cache_file_remove(buf);
575 buf = cache_find_location(CACHE_TYPE_METADATA, fd->path);
576 cache_file_remove(buf);
579 if (options->thumbnails.enable_caching && options->thumbnails.spec_standard)
580 thumb_std_maint_removed(fd->path);
583 void cache_maint_copied(FileData *fd)
589 src_cache = cache_find_location(CACHE_TYPE_METADATA, fd->change->source);
590 if (!src_cache) return;
592 dest_base = cache_get_location(CACHE_TYPE_METADATA, fd->change->dest, FALSE, &mode);
593 if (cache_ensure_dir_exists(dest_base, mode))
597 path = cache_get_location(CACHE_TYPE_METADATA, fd->change->dest, TRUE, NULL);
598 if (!copy_file(src_cache, path))
600 if (debug) printf("failed to copy metadata %s to %s\n", src_cache, path);
610 *-------------------------------------------------------------------
611 * new cache maintenance utilities
612 *-------------------------------------------------------------------
615 typedef struct _CacheManager CacheManager;
618 GenericDialog *dialog;
619 GtkWidget *folder_entry;
628 typedef struct _CleanData CleanData;
640 GtkWidget *button_close;
641 GtkWidget *button_stop;
642 GtkWidget *button_start;
658 static void cache_manager_render_reset(CleanData *cd)
660 path_list_free(cd->list);
663 path_list_free(cd->list_dir);
666 thumb_loader_free((ThumbLoader *)cd->tl);
670 static void cache_manager_render_close_cb(GenericDialog *fd, gpointer data)
672 CleanData *cd = data;
674 if (!GTK_WIDGET_SENSITIVE(cd->button_close)) return;
676 cache_manager_render_reset(cd);
677 generic_dialog_close(cd->gd);
681 static void cache_manager_render_finish(CleanData *cd)
683 cache_manager_render_reset(cd);
685 gtk_entry_set_text(GTK_ENTRY(cd->progress), _("done"));
686 spinner_set_interval(cd->spinner, -1);
688 gtk_widget_set_sensitive(cd->group, TRUE);
689 gtk_widget_set_sensitive(cd->button_start, TRUE);
690 gtk_widget_set_sensitive(cd->button_stop, FALSE);
691 gtk_widget_set_sensitive(cd->button_close, TRUE);
694 static void cache_manager_render_stop_cb(GenericDialog *fd, gpointer data)
696 CleanData *cd = data;
698 cache_manager_render_finish(cd);
701 static void cache_manager_render_folder(CleanData *cd, const gchar *path)
703 GList *list_d = NULL;
704 GList *list_f = NULL;
708 path_list(path, &list_f, &list_d);
712 path_list(path, &list_f, NULL);
715 list_f = path_list_filter(list_f, FALSE);
716 list_d = path_list_filter(list_d, TRUE);
718 cd->list = g_list_concat(list_f, cd->list);
719 cd->list_dir = g_list_concat(list_d, cd->list_dir);
722 static gint cache_manager_render_file(CleanData *cd);
724 static void cache_manager_render_thumb_done_cb(ThumbLoader *tl, gpointer data)
726 CleanData *cd = data;
728 thumb_loader_free((ThumbLoader *)cd->tl);
731 while (cache_manager_render_file(cd));
734 static gint cache_manager_render_file(CleanData *cd)
741 path = cd->list->data;
742 cd->list = g_list_remove(cd->list, path);
744 cd->tl = (ThumbLoaderStd *)thumb_loader_new(options->thumbnails.max_width, options->thumbnails.max_height);
745 thumb_loader_set_callbacks((ThumbLoader *)cd->tl,
746 cache_manager_render_thumb_done_cb,
747 cache_manager_render_thumb_done_cb,
749 thumb_loader_set_cache((ThumbLoader *)cd->tl, TRUE, cd->local, TRUE);
750 success = thumb_loader_start((ThumbLoader *)cd->tl, path);
753 gtk_entry_set_text(GTK_ENTRY(cd->progress), path);
757 thumb_loader_free((ThumbLoader *)cd->tl);
765 else if (cd->list_dir)
769 path = cd->list_dir->data;
770 cd->list_dir = g_list_remove(cd->list_dir, path);
772 cache_manager_render_folder(cd, path);
779 cache_manager_render_finish(cd);
784 static void cache_manager_render_start_cb(GenericDialog *fd, gpointer data)
786 CleanData *cd = data;
789 if (cd->list || !GTK_WIDGET_SENSITIVE(cd->button_start)) return;
791 path = remove_trailing_slash((gtk_entry_get_text(GTK_ENTRY(cd->entry))));
792 parse_out_relatives(path);
796 warning_dialog(_("Invalid folder"),
797 _("The specified folder can not be found."),
798 GTK_STOCK_DIALOG_WARNING, cd->gd->dialog);
802 gtk_widget_set_sensitive(cd->group, FALSE);
803 gtk_widget_set_sensitive(cd->button_start, FALSE);
804 gtk_widget_set_sensitive(cd->button_stop, TRUE);
805 gtk_widget_set_sensitive(cd->button_close, FALSE);
807 spinner_set_interval(cd->spinner, SPINNER_SPEED);
809 cache_manager_render_folder(cd, path);
810 while (cache_manager_render_file(cd));
816 static void cache_manager_render_dialog(GtkWidget *widget, const gchar *path)
823 cd = g_new0(CleanData, 1);
825 cd->gd = generic_dialog_new(_("Create thumbnails"),
826 GQ_WMCLASS, "create_thumbnails",
829 gtk_window_set_default_size(GTK_WINDOW(cd->gd->dialog), PURGE_DIALOG_WIDTH, -1);
830 cd->gd->cancel_cb = cache_manager_render_close_cb;
831 cd->button_close = generic_dialog_add_button(cd->gd, GTK_STOCK_CLOSE, NULL,
832 cache_manager_render_close_cb, FALSE);
833 cd->button_start = generic_dialog_add_button(cd->gd, GTK_STOCK_OK, _("S_tart"),
834 cache_manager_render_start_cb, FALSE);
835 cd->button_stop = generic_dialog_add_button(cd->gd, GTK_STOCK_STOP, NULL,
836 cache_manager_render_stop_cb, FALSE);
837 gtk_widget_set_sensitive(cd->button_stop, FALSE);
839 generic_dialog_add_message(cd->gd, NULL, _("Create thumbnails"), NULL);
841 hbox = pref_box_new(cd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, 0);
842 pref_spacer(hbox, PREF_PAD_INDENT);
843 cd->group = pref_box_new(hbox, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
845 hbox = pref_box_new(cd->group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
846 pref_label_new(hbox, _("Folder:"));
848 label = tab_completion_new(&cd->entry, path, NULL, NULL);
849 tab_completion_add_select_button(cd->entry,_("Select folder") , TRUE);
850 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
851 gtk_widget_show(label);
853 pref_checkbox_new_int(cd->group, _("Include subfolders"), FALSE, &cd->recurse);
854 button = pref_checkbox_new_int(cd->group, _("Store thumbnails local to source images"), FALSE, &cd->local);
855 gtk_widget_set_sensitive(button, options->thumbnails.spec_standard);
857 pref_line(cd->gd->vbox, PREF_PAD_SPACE);
858 hbox = pref_box_new(cd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
860 cd->progress = gtk_entry_new();
861 GTK_WIDGET_UNSET_FLAGS(cd->progress, GTK_CAN_FOCUS);
862 gtk_editable_set_editable(GTK_EDITABLE(cd->progress), FALSE);
863 gtk_entry_set_text(GTK_ENTRY(cd->progress), _("click start to begin"));
864 gtk_box_pack_start(GTK_BOX(hbox), cd->progress, TRUE, TRUE, 0);
865 gtk_widget_show(cd->progress);
867 cd->spinner = spinner_new(NULL, -1);
868 gtk_box_pack_start(GTK_BOX(hbox), cd->spinner, FALSE, FALSE, 0);
869 gtk_widget_show(cd->spinner);
873 gtk_widget_show(cd->gd->dialog);
879 static void cache_manager_standard_clean_close_cb(GenericDialog *gd, gpointer data)
881 CleanData *cd = data;
883 if (!GTK_WIDGET_SENSITIVE(cd->button_close)) return;
885 generic_dialog_close(cd->gd);
887 thumb_loader_std_thumb_file_validate_cancel(cd->tl);
888 path_list_free(cd->list);
892 static void cache_manager_standard_clean_done(CleanData *cd)
894 gtk_widget_set_sensitive(cd->button_stop, FALSE);
895 gtk_widget_set_sensitive(cd->button_close, TRUE);
897 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress), 1.0);
898 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("done"));
900 if (cd->idle_id != -1)
902 g_source_remove(cd->idle_id);
906 thumb_loader_std_thumb_file_validate_cancel(cd->tl);
909 path_list_free(cd->list);
913 static void cache_manager_standard_clean_stop_cb(GenericDialog *gd, gpointer data)
915 CleanData *cd = data;
917 cache_manager_standard_clean_done(cd);
920 static gint cache_manager_standard_clean_clear_cb(gpointer data)
922 CleanData *cd = data;
928 next_path = cd->list->data;
929 cd->list = g_list_remove(cd->list, next_path);
931 if (debug) printf("thumb removed: %s\n", next_path);
933 unlink_file(next_path);
937 if (cd->count_total != 0)
939 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress),
940 (gdouble)cd->count_done / cd->count_total);
947 cache_manager_standard_clean_done(cd);
951 static void cache_manager_standard_clean_valid_cb(const gchar *path, gint valid, gpointer data)
953 CleanData *cd = data;
959 if (debug) printf("thumb cleaned: %s\n", path);
964 if (cd->count_total != 0)
966 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress),
967 (gdouble)cd->count_done / cd->count_total);
976 next_path = cd->list->data;
977 cd->list = g_list_remove(cd->list, next_path);
979 cd->tl = thumb_loader_std_thumb_file_validate(next_path, cd->days,
980 cache_manager_standard_clean_valid_cb, cd);
985 cache_manager_standard_clean_done(cd);
989 static void cache_manager_standard_clean_start_cb(GenericDialog *gd, gpointer data)
991 CleanData *cd = data;
995 if (cd->list || !GTK_WIDGET_SENSITIVE(cd->button_start)) return;
997 gtk_widget_set_sensitive(cd->button_start, FALSE);
998 gtk_widget_set_sensitive(cd->button_stop, TRUE);
999 gtk_widget_set_sensitive(cd->button_close, FALSE);
1001 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("running..."));
1003 path = g_strconcat(homedir(), "/", THUMB_FOLDER_GLOBAL, "/", THUMB_FOLDER_NORMAL, NULL);
1005 path_list(path, &list, NULL);
1009 path = g_strconcat(homedir(), "/", THUMB_FOLDER_GLOBAL, "/", THUMB_FOLDER_LARGE, NULL);
1011 path_list(path, &list, NULL);
1012 cd->list = g_list_concat(cd->list, list);
1015 path = g_strconcat(homedir(), "/", THUMB_FOLDER_GLOBAL, "/", THUMB_FOLDER_FAIL, NULL);
1017 path_list(path, &list, NULL);
1018 cd->list = g_list_concat(cd->list, list);
1021 cd->count_total = g_list_length(cd->list);
1024 /* start iterating */
1027 cd->idle_id = g_idle_add(cache_manager_standard_clean_clear_cb, cd);
1031 cache_manager_standard_clean_valid_cb(NULL, TRUE, cd);
1035 static void cache_manager_standard_process(GtkWidget *widget, gint clear)
1038 const gchar *stock_id;
1041 cd = g_new0(CleanData, 1);
1046 stock_id = GTK_STOCK_DELETE;
1047 msg = _("Clearing thumbnails...");
1051 stock_id = GTK_STOCK_CLEAR;
1052 msg = _("Removing old thumbnails...");
1055 cd->gd = generic_dialog_new(_("Maintenance"),
1056 GQ_WMCLASS, "standard_maintenance",
1059 cd->gd->cancel_cb = cache_manager_standard_clean_close_cb;
1060 cd->button_close = generic_dialog_add_button(cd->gd, GTK_STOCK_CLOSE, NULL,
1061 cache_manager_standard_clean_close_cb, FALSE);
1062 cd->button_start = generic_dialog_add_button(cd->gd, GTK_STOCK_OK, _("S_tart"),
1063 cache_manager_standard_clean_start_cb, FALSE);
1064 cd->button_stop = generic_dialog_add_button(cd->gd, GTK_STOCK_STOP, NULL,
1065 cache_manager_standard_clean_stop_cb, FALSE);
1066 gtk_widget_set_sensitive(cd->button_stop, FALSE);
1068 generic_dialog_add_message(cd->gd, stock_id, msg, NULL);
1070 cd->progress = gtk_progress_bar_new();
1071 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("click start to begin"));
1072 gtk_box_pack_start(GTK_BOX(cd->gd->vbox), cd->progress, FALSE, FALSE, 0);
1073 gtk_widget_show(cd->progress);
1079 gtk_widget_show(cd->gd->dialog);
1082 static void cache_manager_standard_clean_cb(GtkWidget *widget, gpointer data)
1084 cache_manager_standard_process(widget, FALSE);
1087 static void cache_manager_standard_clear_cb(GtkWidget *widget, gpointer data)
1089 cache_manager_standard_process(widget, TRUE);
1093 static void cache_manager_main_clean_cb(GtkWidget *widget, gpointer data)
1095 cache_maintain_home(FALSE, FALSE, widget);
1099 static void dummy_cancel_cb(GenericDialog *gd, gpointer data)
1101 /* no op, only so cancel button appears */
1104 static void cache_manager_main_clear_ok_cb(GenericDialog *gd, gpointer data)
1106 cache_maintain_home(FALSE, TRUE, NULL);
1109 void cache_manager_main_clear_confirm(GtkWidget *parent)
1113 gd = generic_dialog_new(_("Clear cache"),
1114 GQ_WMCLASS, "clear_cache", parent, TRUE,
1115 dummy_cancel_cb, NULL);
1116 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Clear cache"),
1117 _("This will remove all thumbnails that have\nbeen saved to disk, continue?"));
1118 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, cache_manager_main_clear_ok_cb, TRUE);
1120 gtk_widget_show(gd->dialog);
1123 static void cache_manager_main_clear_cb(GtkWidget *widget, gpointer data)
1125 cache_manager_main_clear_confirm(widget);
1128 static void cache_manager_render_cb(GtkWidget *widget, gpointer data)
1130 cache_manager_render_dialog(widget, homedir());
1133 static void cache_manager_metadata_clean_cb(GtkWidget *widget, gpointer data)
1135 cache_maintain_home(TRUE, FALSE, widget);
1139 static CacheManager *cache_manager = NULL;
1141 static void cache_manager_close_cb(GenericDialog *gd, gpointer data)
1143 generic_dialog_close(gd);
1145 g_free(cache_manager);
1146 cache_manager = NULL;
1149 void cache_manager_show(void)
1156 GtkSizeGroup *sizegroup;
1162 gtk_window_present(GTK_WINDOW(cache_manager->dialog->dialog));
1166 cache_manager = g_new0(CacheManager, 1);
1168 title = g_strdup_printf("%s - %s", _("Cache Maintenance"), GQ_APPNAME);
1169 cache_manager->dialog = generic_dialog_new(title,
1170 GQ_WMCLASS, "cache_manager",
1172 NULL, cache_manager);
1174 gd = cache_manager->dialog;
1176 gd->cancel_cb = cache_manager_close_cb;
1177 generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL,
1178 cache_manager_close_cb, FALSE);
1180 generic_dialog_add_message(gd, NULL, _("Cache and Data Maintenance"), NULL);
1182 sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1184 group = pref_group_new(gd->vbox, FALSE, _("Thumbnail cache"), GTK_ORIENTATION_VERTICAL);
1186 buf = g_strconcat(_("Location:"), " ", homedir(), "/", GQ_CACHE_RC_THUMB, NULL);
1187 label = pref_label_new(group, buf);
1188 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1191 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1193 button = pref_table_button(table, 0, 0, GTK_STOCK_CLEAR, _("Clean up"), FALSE,
1194 G_CALLBACK(cache_manager_main_clean_cb), cache_manager);
1195 gtk_size_group_add_widget(sizegroup, button);
1196 pref_table_label(table, 1, 0, _("Remove orphaned or outdated thumbnails."), 0.0);
1198 button = pref_table_button(table, 0, 1, GTK_STOCK_DELETE, _("Clear cache"), FALSE,
1199 G_CALLBACK(cache_manager_main_clear_cb), cache_manager);
1200 gtk_size_group_add_widget(sizegroup, button);
1201 pref_table_label(table, 1, 1, _("Delete all cached thumbnails."), 0.0);
1204 group = pref_group_new(gd->vbox, FALSE, _("Shared thumbnail cache"), GTK_ORIENTATION_VERTICAL);
1206 buf = g_strconcat(_("Location:"), " ", homedir(), "/", THUMB_FOLDER_GLOBAL, NULL);
1207 label = pref_label_new(group, buf);
1208 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1211 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1213 button = pref_table_button(table, 0, 0, GTK_STOCK_CLEAR, _("Clean up"), FALSE,
1214 G_CALLBACK(cache_manager_standard_clean_cb), cache_manager);
1215 gtk_size_group_add_widget(sizegroup, button);
1216 pref_table_label(table, 1, 0, _("Remove orphaned or outdated thumbnails."), 0.0);
1218 button = pref_table_button(table, 0, 1, GTK_STOCK_DELETE, _("Clear cache"), FALSE,
1219 G_CALLBACK(cache_manager_standard_clear_cb), cache_manager);
1220 gtk_size_group_add_widget(sizegroup, button);
1221 pref_table_label(table, 1, 1, _("Delete all cached thumbnails."), 0.0);
1223 group = pref_group_new(gd->vbox, FALSE, _("Create thumbnails"), GTK_ORIENTATION_VERTICAL);
1225 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1227 button = pref_table_button(table, 0, 1, GTK_STOCK_EXECUTE, _("Render"), FALSE,
1228 G_CALLBACK(cache_manager_render_cb), cache_manager);
1229 gtk_size_group_add_widget(sizegroup, button);
1230 pref_table_label(table, 1, 1, _("Render thumbnails for a specific folder."), 0.0);
1232 group = pref_group_new(gd->vbox, FALSE, _("Metadata"), GTK_ORIENTATION_VERTICAL);
1234 buf = g_strconcat(_("Location:"), " ", homedir(), "/", GQ_CACHE_RC_METADATA, NULL);
1235 label = pref_label_new(group, buf);
1236 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1239 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1241 button = pref_table_button(table, 0, 0, GTK_STOCK_CLEAR, _("Clean up"), FALSE,
1242 G_CALLBACK(cache_manager_metadata_clean_cb), cache_manager);
1243 gtk_size_group_add_widget(sizegroup, button);
1244 pref_table_label(table, 1, 0, _("Remove orphaned keywords and comments."), 0.0);
1246 gtk_widget_show(cache_manager->dialog->dialog);