2 * Copyright (C) 2006 John Ellis
3 * Copyright (C) 2008 - 2016 The Geeqie Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "cache_maint.h"
29 #include "thumb_standard.h"
30 #include "ui_fileops.h"
32 #include "ui_spinner.h"
33 #include "ui_tabcomp.h"
34 #include "ui_utildlg.h"
38 typedef struct _CMData CMData;
43 guint idle_id; /* event source id */
47 GtkWidget *button_stop;
48 GtkWidget *button_close;
54 #define PURGE_DIALOG_WIDTH 400
58 *-------------------------------------------------------------------
60 *-------------------------------------------------------------------
63 static gchar *extension_find_dot(gchar *path)
67 if (!path) return NULL;
71 if (*path == '.') dot = path;
78 static gboolean isempty(const gchar *path)
84 pathl = path_from_utf8(path);
87 if (!dp) return FALSE;
89 while ((dir = readdir(dp)) != NULL)
91 gchar *name = dir->d_name;
93 if (!(name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) )
104 static void cache_maintain_home_close(CMData *cm)
106 if (cm->idle_id) g_source_remove(cm->idle_id);
107 if (cm->gd) generic_dialog_close(cm->gd);
108 filelist_free(cm->list);
109 g_list_free(cm->done_list);
113 static void cache_maintain_home_stop(CMData *cm)
117 g_source_remove(cm->idle_id);
123 gtk_entry_set_text(GTK_ENTRY(cm->entry), _("done"));
124 spinner_set_interval(cm->spinner, -1);
126 gtk_widget_set_sensitive(cm->button_stop, FALSE);
127 gtk_widget_set_sensitive(cm->button_close, TRUE);
131 static gboolean cache_maintain_home_cb(gpointer data)
137 gboolean just_done = FALSE;
138 gboolean still_have_a_file = TRUE;
140 const gchar *cache_folder;
141 gboolean filter_disable;
145 cache_folder = get_metadata_cache_dir();
149 cache_folder = get_thumbnails_cache_dir();
152 base_length = strlen(cache_folder);
156 DEBUG_1("purge chk done.");
158 cache_maintain_home_stop(cm);
164 DEBUG_1("purge chk (%d) \"%s\"", (cm->clear && !cm->metadata), fd->path);
167 * It is necessary to disable the file filter when clearing the cache,
168 * otherwise the .sim (file similarity) files are not deleted.
170 filter_disable = options->file_filter.disable;
171 options->file_filter.disable = TRUE;
173 if (g_list_find(cm->done_list, fd) == NULL)
175 cm->done_list = g_list_prepend(cm->done_list, fd);
177 if (filelist_read(fd, &list, &dlist))
182 still_have_a_file = FALSE;
187 FileData *fd_list = work->data;
188 gchar *path_buf = g_strdup(fd_list->path);
191 dot = extension_find_dot(path_buf);
193 if (dot) *dot = '\0';
194 if ((!cm->metadata && cm->clear) ||
195 (strlen(path_buf) > base_length && !isfile(path_buf + base_length)) )
198 if (!unlink_file(path_buf)) log_printf("failed to delete:%s\n", path_buf);
202 still_have_a_file = TRUE;
209 options->file_filter.disable = filter_disable;
213 cm->list = g_list_concat(dlist, cm->list);
215 if (cm->list && g_list_find(cm->done_list, cm->list->data) != NULL)
217 /* check if the dir is empty */
219 if (cm->list->data == fd && just_done)
221 if (!still_have_a_file && !dlist && cm->list->next && !rmdir_utf8(fd->path))
223 log_printf("Unable to delete dir: %s\n", fd->path);
228 /* must re-check for an empty dir */
229 if (isempty(fd->path) && cm->list->next && !rmdir_utf8(fd->path))
231 log_printf("Unable to delete dir: %s\n", fd->path);
236 cm->done_list = g_list_remove(cm->done_list, fd);
237 cm->list = g_list_remove(cm->list, fd);
241 if (cm->list && !cm->remote)
246 if (strlen(fd->path) > base_length)
248 buf = fd->path + base_length;
254 gtk_entry_set_text(GTK_ENTRY(cm->entry), buf);
260 static void cache_maintain_home_close_cb(GenericDialog *gd, gpointer data)
264 if (!gtk_widget_get_sensitive(cm->button_close)) return;
266 cache_maintain_home_close(cm);
269 static void cache_maintain_home_stop_cb(GenericDialog *gd, gpointer data)
273 cache_maintain_home_stop(cm);
276 /* sorry for complexity (cm->done_list), but need it to remove empty dirs */
277 void cache_maintain_home(gboolean metadata, gboolean clear, GtkWidget *parent)
283 const gchar *cache_folder;
288 cache_folder = get_metadata_cache_dir();
292 cache_folder = get_thumbnails_cache_dir();
295 dir_fd = file_data_new_dir(cache_folder);
296 if (!filelist_read(dir_fd, NULL, &dlist))
298 file_data_unref(dir_fd);
302 dlist = g_list_append(dlist, dir_fd);
304 cm = g_new0(CMData, 1);
306 cm->done_list = NULL;
308 cm->metadata = metadata;
313 msg = _("Removing old metadata...");
317 msg = _("Clearing cached thumbnails...");
321 msg = _("Removing old thumbnails...");
324 cm->gd = generic_dialog_new(_("Maintenance"),
328 cm->gd->cancel_cb = cache_maintain_home_close_cb;
329 cm->button_close = generic_dialog_add_button(cm->gd, GTK_STOCK_CLOSE, NULL,
330 cache_maintain_home_close_cb, FALSE);
331 gtk_widget_set_sensitive(cm->button_close, FALSE);
332 cm->button_stop = generic_dialog_add_button(cm->gd, GTK_STOCK_STOP, NULL,
333 cache_maintain_home_stop_cb, FALSE);
335 generic_dialog_add_message(cm->gd, NULL, msg, NULL);
336 gtk_window_set_default_size(GTK_WINDOW(cm->gd->dialog), PURGE_DIALOG_WIDTH, -1);
338 hbox = gtk_hbox_new(FALSE, 0);
339 gtk_box_pack_start(GTK_BOX(cm->gd->vbox), hbox, FALSE, FALSE, 5);
340 gtk_widget_show(hbox);
342 cm->entry = gtk_entry_new();
343 gtk_widget_set_can_focus(cm->entry, FALSE);
344 gtk_editable_set_editable(GTK_EDITABLE(cm->entry), FALSE);
345 gtk_box_pack_start(GTK_BOX(hbox), cm->entry, TRUE, TRUE, 0);
346 gtk_widget_show(cm->entry);
348 cm->spinner = spinner_new(NULL, SPINNER_SPEED);
349 gtk_box_pack_start(GTK_BOX(hbox), cm->spinner, FALSE, FALSE, 0);
350 gtk_widget_show(cm->spinner);
352 gtk_widget_show(cm->gd->dialog);
354 cm->idle_id = g_idle_add(cache_maintain_home_cb, cm);
357 void cache_maintain_home_remote(gboolean metadata, gboolean clear)
362 const gchar *cache_folder;
366 cache_folder = get_metadata_cache_dir();
370 cache_folder = get_thumbnails_cache_dir();
373 dir_fd = file_data_new_dir(cache_folder);
374 if (!filelist_read(dir_fd, NULL, &dlist))
376 file_data_unref(dir_fd);
380 dlist = g_list_append(dlist, dir_fd);
382 cm = g_new0(CMData, 1);
384 cm->done_list = NULL;
386 cm->metadata = metadata;
389 cm->idle_id = g_idle_add(cache_maintain_home_cb, cm);
392 static void cache_file_move(const gchar *src, const gchar *dest)
394 if (!dest || !src || !isfile(src)) return;
396 if (!move_file(src, dest))
398 DEBUG_1("Failed to move cache file \"%s\" to \"%s\"", src, dest);
399 /* we remove it anyway - it's stale */
404 static void cache_maint_moved(FileData *fd)
408 const gchar *src = fd->change->source;
409 const gchar *dest = fd->change->dest;
411 if (!src || !dest) return;
413 base = cache_get_location(CACHE_TYPE_THUMB, dest, FALSE, &mode);
414 if (recursive_mkdir_if_not_exists(base, mode))
419 buf = cache_find_location(CACHE_TYPE_THUMB, src);
420 d = cache_get_location(CACHE_TYPE_THUMB, dest, TRUE, NULL);
421 cache_file_move(buf, d);
425 buf = cache_find_location(CACHE_TYPE_SIM, src);
426 d = cache_get_location(CACHE_TYPE_SIM, dest, TRUE, NULL);
427 cache_file_move(buf, d);
433 log_printf("Failed to create cache dir for move %s\n", base);
437 base = cache_get_location(CACHE_TYPE_METADATA, dest, FALSE, &mode);
438 if (recursive_mkdir_if_not_exists(base, mode))
443 buf = cache_find_location(CACHE_TYPE_METADATA, src);
444 d = cache_get_location(CACHE_TYPE_METADATA, dest, TRUE, NULL);
445 cache_file_move(buf, d);
451 if (options->thumbnails.enable_caching && options->thumbnails.spec_standard)
452 thumb_std_maint_moved(src, dest);
455 static void cache_file_remove(const gchar *path)
457 if (path && isfile(path) && !unlink_file(path))
459 DEBUG_1("Failed to remove cache file %s", path);
463 static void cache_maint_removed(FileData *fd)
467 buf = cache_find_location(CACHE_TYPE_THUMB, fd->path);
468 cache_file_remove(buf);
471 buf = cache_find_location(CACHE_TYPE_SIM, fd->path);
472 cache_file_remove(buf);
475 buf = cache_find_location(CACHE_TYPE_METADATA, fd->path);
476 cache_file_remove(buf);
479 if (options->thumbnails.enable_caching && options->thumbnails.spec_standard)
480 thumb_std_maint_removed(fd->path);
483 static void cache_maint_copied(FileData *fd)
489 src_cache = cache_find_location(CACHE_TYPE_METADATA, fd->change->source);
490 if (!src_cache) return;
492 dest_base = cache_get_location(CACHE_TYPE_METADATA, fd->change->dest, FALSE, &mode);
493 if (recursive_mkdir_if_not_exists(dest_base, mode))
497 path = cache_get_location(CACHE_TYPE_METADATA, fd->change->dest, TRUE, NULL);
498 if (!copy_file(src_cache, path))
500 DEBUG_1("failed to copy metadata %s to %s", src_cache, path);
509 void cache_notify_cb(FileData *fd, NotifyType type, gpointer data)
511 if (!(type & NOTIFY_CHANGE) || !fd->change) return;
513 DEBUG_1("Notify cache_maint: %s %04x", fd->path, type);
514 switch (fd->change->type)
516 case FILEDATA_CHANGE_MOVE:
517 case FILEDATA_CHANGE_RENAME:
518 cache_maint_moved(fd);
520 case FILEDATA_CHANGE_COPY:
521 cache_maint_copied(fd);
523 case FILEDATA_CHANGE_DELETE:
524 cache_maint_removed(fd);
526 case FILEDATA_CHANGE_UNSPECIFIED:
527 case FILEDATA_CHANGE_WRITE_METADATA:
534 *-------------------------------------------------------------------
535 * new cache maintenance utilities
536 *-------------------------------------------------------------------
539 typedef struct _CacheManager CacheManager;
542 GenericDialog *dialog;
543 GtkWidget *folder_entry;
552 typedef struct _CleanData CleanData;
564 GtkWidget *button_close;
565 GtkWidget *button_stop;
566 GtkWidget *button_start;
581 guint idle_id; /* event source id */
584 static void cache_manager_render_reset(CleanData *cd)
586 filelist_free(cd->list);
589 filelist_free(cd->list_dir);
592 thumb_loader_free((ThumbLoader *)cd->tl);
596 static void cache_manager_render_close_cb(GenericDialog *fd, gpointer data)
598 CleanData *cd = data;
600 if (!gtk_widget_get_sensitive(cd->button_close)) return;
602 cache_manager_render_reset(cd);
603 generic_dialog_close(cd->gd);
607 static void cache_manager_render_finish(CleanData *cd)
609 cache_manager_render_reset(cd);
612 gtk_entry_set_text(GTK_ENTRY(cd->progress), _("done"));
613 spinner_set_interval(cd->spinner, -1);
615 gtk_widget_set_sensitive(cd->group, TRUE);
616 gtk_widget_set_sensitive(cd->button_start, TRUE);
617 gtk_widget_set_sensitive(cd->button_stop, FALSE);
618 gtk_widget_set_sensitive(cd->button_close, TRUE);
622 static void cache_manager_render_stop_cb(GenericDialog *fd, gpointer data)
624 CleanData *cd = data;
626 cache_manager_render_finish(cd);
629 static void cache_manager_render_folder(CleanData *cd, FileData *dir_fd)
631 GList *list_d = NULL;
632 GList *list_f = NULL;
636 filelist_read(dir_fd, &list_f, &list_d);
640 filelist_read(dir_fd, &list_f, NULL);
643 list_f = filelist_filter(list_f, FALSE);
644 list_d = filelist_filter(list_d, TRUE);
646 cd->list = g_list_concat(list_f, cd->list);
647 cd->list_dir = g_list_concat(list_d, cd->list_dir);
650 static gboolean cache_manager_render_file(CleanData *cd);
652 static void cache_manager_render_thumb_done_cb(ThumbLoader *tl, gpointer data)
654 CleanData *cd = data;
656 thumb_loader_free((ThumbLoader *)cd->tl);
659 while (cache_manager_render_file(cd));
662 static gboolean cache_manager_render_file(CleanData *cd)
670 cd->list = g_list_remove(cd->list, fd);
672 cd->tl = (ThumbLoaderStd *)thumb_loader_new(options->thumbnails.max_width, options->thumbnails.max_height);
673 thumb_loader_set_callbacks((ThumbLoader *)cd->tl,
674 cache_manager_render_thumb_done_cb,
675 cache_manager_render_thumb_done_cb,
677 thumb_loader_set_cache((ThumbLoader *)cd->tl, TRUE, cd->local, TRUE);
678 success = thumb_loader_start((ThumbLoader *)cd->tl, fd);
683 gtk_entry_set_text(GTK_ENTRY(cd->progress), fd->path);
688 thumb_loader_free((ThumbLoader *)cd->tl);
696 else if (cd->list_dir)
700 fd = cd->list_dir->data;
701 cd->list_dir = g_list_remove(cd->list_dir, fd);
703 cache_manager_render_folder(cd, fd);
710 cache_manager_render_finish(cd);
715 static void cache_manager_render_start_cb(GenericDialog *fd, gpointer data)
717 CleanData *cd = data;
722 if (cd->list || !gtk_widget_get_sensitive(cd->button_start)) return;
725 path = remove_trailing_slash((gtk_entry_get_text(GTK_ENTRY(cd->entry))));
726 parse_out_relatives(path);
732 warning_dialog(_("Invalid folder"),
733 _("The specified folder can not be found."),
734 GTK_STOCK_DIALOG_WARNING, cd->gd->dialog);
738 log_printf("The specified folder can not be found: %s\n", path);
746 gtk_widget_set_sensitive(cd->group, FALSE);
747 gtk_widget_set_sensitive(cd->button_start, FALSE);
748 gtk_widget_set_sensitive(cd->button_stop, TRUE);
749 gtk_widget_set_sensitive(cd->button_close, FALSE);
751 spinner_set_interval(cd->spinner, SPINNER_SPEED);
753 dir_fd = file_data_new_dir(path);
754 cache_manager_render_folder(cd, dir_fd);
755 file_data_unref(dir_fd);
756 while (cache_manager_render_file(cd));
762 static void cache_manager_render_start_render_remote(CleanData *cd, const gchar *user_path)
766 path = remove_trailing_slash(user_path);
767 parse_out_relatives(path);
771 log_printf("The specified folder can not be found: %s\n", path);
777 dir_fd = file_data_new_dir(path);
778 cache_manager_render_folder(cd, dir_fd);
779 file_data_unref(dir_fd);
780 while (cache_manager_render_file(cd));
786 static void cache_manager_render_dialog(GtkWidget *widget, const gchar *path)
793 cd = g_new0(CleanData, 1);
796 cd->gd = generic_dialog_new(_("Create thumbnails"),
800 gtk_window_set_default_size(GTK_WINDOW(cd->gd->dialog), PURGE_DIALOG_WIDTH, -1);
801 cd->gd->cancel_cb = cache_manager_render_close_cb;
802 cd->button_close = generic_dialog_add_button(cd->gd, GTK_STOCK_CLOSE, NULL,
803 cache_manager_render_close_cb, FALSE);
804 cd->button_start = generic_dialog_add_button(cd->gd, GTK_STOCK_OK, _("S_tart"),
805 cache_manager_render_start_cb, FALSE);
806 cd->button_stop = generic_dialog_add_button(cd->gd, GTK_STOCK_STOP, NULL,
807 cache_manager_render_stop_cb, FALSE);
808 gtk_widget_set_sensitive(cd->button_stop, FALSE);
810 generic_dialog_add_message(cd->gd, NULL, _("Create thumbnails"), NULL);
812 hbox = pref_box_new(cd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, 0);
813 pref_spacer(hbox, PREF_PAD_INDENT);
814 cd->group = pref_box_new(hbox, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
816 hbox = pref_box_new(cd->group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
817 pref_label_new(hbox, _("Folder:"));
819 label = tab_completion_new(&cd->entry, path, NULL, NULL);
820 tab_completion_add_select_button(cd->entry,_("Select folder") , TRUE);
821 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
822 gtk_widget_show(label);
824 pref_checkbox_new_int(cd->group, _("Include subfolders"), FALSE, &cd->recurse);
825 button = pref_checkbox_new_int(cd->group, _("Store thumbnails local to source images"), FALSE, &cd->local);
826 gtk_widget_set_sensitive(button, options->thumbnails.spec_standard);
828 pref_line(cd->gd->vbox, PREF_PAD_SPACE);
829 hbox = pref_box_new(cd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
831 cd->progress = gtk_entry_new();
832 gtk_widget_set_can_focus(cd->progress, FALSE);
833 gtk_editable_set_editable(GTK_EDITABLE(cd->progress), FALSE);
834 gtk_entry_set_text(GTK_ENTRY(cd->progress), _("click start to begin"));
835 gtk_box_pack_start(GTK_BOX(hbox), cd->progress, TRUE, TRUE, 0);
836 gtk_widget_show(cd->progress);
838 cd->spinner = spinner_new(NULL, -1);
839 gtk_box_pack_start(GTK_BOX(hbox), cd->spinner, FALSE, FALSE, 0);
840 gtk_widget_show(cd->spinner);
844 gtk_widget_show(cd->gd->dialog);
847 void cache_manager_render_remote(const gchar *path, gboolean recurse, gboolean local)
851 cd = g_new0(CleanData, 1);
852 cd->recurse = recurse;
856 cache_manager_render_start_render_remote(cd, path);
859 static void cache_manager_standard_clean_close_cb(GenericDialog *gd, gpointer data)
861 CleanData *cd = data;
863 if (!gtk_widget_get_sensitive(cd->button_close)) return;
865 generic_dialog_close(cd->gd);
867 thumb_loader_std_thumb_file_validate_cancel(cd->tl);
868 filelist_free(cd->list);
872 static void cache_manager_standard_clean_done(CleanData *cd)
876 gtk_widget_set_sensitive(cd->button_stop, FALSE);
877 gtk_widget_set_sensitive(cd->button_close, TRUE);
879 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress), 1.0);
880 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("done"));
884 g_source_remove(cd->idle_id);
888 thumb_loader_std_thumb_file_validate_cancel(cd->tl);
891 filelist_free(cd->list);
895 static void cache_manager_standard_clean_stop_cb(GenericDialog *gd, gpointer data)
897 CleanData *cd = data;
899 cache_manager_standard_clean_done(cd);
902 static gint cache_manager_standard_clean_clear_cb(gpointer data)
904 CleanData *cd = data;
910 next_fd = cd->list->data;
911 cd->list = g_list_remove(cd->list, next_fd);
913 DEBUG_1("thumb removed: %s", next_fd->path);
915 unlink_file(next_fd->path);
916 file_data_unref(next_fd);
921 if (cd->count_total != 0)
923 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress),
924 (gdouble)cd->count_done / cd->count_total);
932 cache_manager_standard_clean_done(cd);
936 static void cache_manager_standard_clean_valid_cb(const gchar *path, gboolean valid, gpointer data)
938 CleanData *cd = data;
944 DEBUG_1("thumb cleaned: %s", path);
951 if (cd->count_total != 0)
953 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress),
954 (gdouble)cd->count_done / cd->count_total);
964 next_fd = cd->list->data;
965 cd->list = g_list_remove(cd->list, next_fd);
967 cd->tl = thumb_loader_std_thumb_file_validate(next_fd->path, cd->days,
968 cache_manager_standard_clean_valid_cb, cd);
969 file_data_unref(next_fd);
973 cache_manager_standard_clean_done(cd);
977 static void cache_manager_standard_clean_start(GenericDialog *gd, gpointer data)
979 CleanData *cd = data;
986 if (cd->list || !gtk_widget_get_sensitive(cd->button_start)) return;
988 gtk_widget_set_sensitive(cd->button_start, FALSE);
989 gtk_widget_set_sensitive(cd->button_stop, TRUE);
990 gtk_widget_set_sensitive(cd->button_close, FALSE);
992 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("running..."));
995 path = g_build_filename(homedir(), THUMB_FOLDER_GLOBAL, THUMB_FOLDER_NORMAL, NULL);
996 dir_fd = file_data_new_dir(path);
997 filelist_read(dir_fd, &list, NULL);
999 file_data_unref(dir_fd);
1002 path = g_build_filename(homedir(), THUMB_FOLDER_GLOBAL, THUMB_FOLDER_LARGE, NULL);
1003 dir_fd = file_data_new_dir(path);
1004 filelist_read(dir_fd, &list, NULL);
1005 cd->list = g_list_concat(cd->list, list);
1006 file_data_unref(dir_fd);
1009 path = g_build_filename(homedir(), THUMB_FOLDER_GLOBAL, THUMB_FOLDER_FAIL, NULL);
1010 dir_fd = file_data_new_dir(path);
1011 filelist_read(dir_fd, &list, NULL);
1012 cd->list = g_list_concat(cd->list, list);
1013 file_data_unref(dir_fd);
1016 cd->count_total = g_list_length(cd->list);
1019 /* start iterating */
1022 cd->idle_id = g_idle_add(cache_manager_standard_clean_clear_cb, cd);
1026 cache_manager_standard_clean_valid_cb(NULL, TRUE, cd);
1030 static void cache_manager_standard_clean_start_cb(GenericDialog *gd, gpointer data)
1032 cache_manager_standard_clean_start(gd, data);
1035 static void cache_manager_standard_process(GtkWidget *widget, gboolean clear)
1038 const gchar *stock_id;
1041 cd = g_new0(CleanData, 1);
1047 stock_id = GTK_STOCK_DELETE;
1048 msg = _("Clearing thumbnails...");
1052 stock_id = GTK_STOCK_CLEAR;
1053 msg = _("Removing old thumbnails...");
1056 cd->gd = generic_dialog_new(_("Maintenance"),
1057 "standard_maintenance",
1060 cd->gd->cancel_cb = cache_manager_standard_clean_close_cb;
1061 cd->button_close = generic_dialog_add_button(cd->gd, GTK_STOCK_CLOSE, NULL,
1062 cache_manager_standard_clean_close_cb, FALSE);
1063 cd->button_start = generic_dialog_add_button(cd->gd, GTK_STOCK_OK, _("S_tart"),
1064 cache_manager_standard_clean_start_cb, FALSE);
1065 cd->button_stop = generic_dialog_add_button(cd->gd, GTK_STOCK_STOP, NULL,
1066 cache_manager_standard_clean_stop_cb, FALSE);
1067 gtk_widget_set_sensitive(cd->button_stop, FALSE);
1069 generic_dialog_add_message(cd->gd, stock_id, msg, NULL);
1071 cd->progress = gtk_progress_bar_new();
1072 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("click start to begin"));
1073 #if GTK_CHECK_VERSION(3,0,0)
1074 gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(cd->progress), TRUE);
1076 gtk_box_pack_start(GTK_BOX(cd->gd->vbox), cd->progress, FALSE, FALSE, 0);
1077 gtk_widget_show(cd->progress);
1083 gtk_widget_show(cd->gd->dialog);
1086 void cache_manager_standard_process_remote(gboolean clear)
1090 cd = g_new0(CleanData, 1);
1097 cache_manager_standard_clean_start(NULL, cd);
1100 static void cache_manager_standard_clean_cb(GtkWidget *widget, gpointer data)
1102 cache_manager_standard_process(widget, FALSE);
1105 static void cache_manager_standard_clear_cb(GtkWidget *widget, gpointer data)
1107 cache_manager_standard_process(widget, TRUE);
1111 static void cache_manager_main_clean_cb(GtkWidget *widget, gpointer data)
1113 cache_maintain_home(FALSE, FALSE, widget);
1117 static void dummy_cancel_cb(GenericDialog *gd, gpointer data)
1119 /* no op, only so cancel button appears */
1122 static void cache_manager_main_clear_ok_cb(GenericDialog *gd, gpointer data)
1124 cache_maintain_home(FALSE, TRUE, NULL);
1127 void cache_manager_main_clear_confirm(GtkWidget *parent)
1131 gd = generic_dialog_new(_("Clear cache"),
1132 "clear_cache", parent, TRUE,
1133 dummy_cancel_cb, NULL);
1134 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Clear cache"),
1135 _("This will remove all thumbnails that have\nbeen saved to disk, continue?"));
1136 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, cache_manager_main_clear_ok_cb, TRUE);
1138 gtk_widget_show(gd->dialog);
1141 static void cache_manager_main_clear_cb(GtkWidget *widget, gpointer data)
1143 cache_manager_main_clear_confirm(widget);
1146 static void cache_manager_render_cb(GtkWidget *widget, gpointer data)
1148 const gchar *path = layout_get_path(NULL);
1150 if (!path || !*path) path = homedir();
1151 cache_manager_render_dialog(widget, path);
1154 static void cache_manager_metadata_clean_cb(GtkWidget *widget, gpointer data)
1156 cache_maintain_home(TRUE, FALSE, widget);
1160 static CacheManager *cache_manager = NULL;
1162 static void cache_manager_close_cb(GenericDialog *gd, gpointer data)
1164 generic_dialog_close(gd);
1166 g_free(cache_manager);
1167 cache_manager = NULL;
1170 static void cache_manager_help_cb(GenericDialog *gd, gpointer data)
1172 help_window_show("GuideReferenceManagement.html");
1175 static GtkWidget *cache_manager_location_label(GtkWidget *group, const gchar *subdir)
1180 buf = g_strdup_printf(_("Location: %s"), subdir);
1181 label = pref_label_new(group, buf);
1183 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1188 void cache_manager_show(void)
1194 GtkSizeGroup *sizegroup;
1199 gtk_window_present(GTK_WINDOW(cache_manager->dialog->dialog));
1203 cache_manager = g_new0(CacheManager, 1);
1205 cache_manager->dialog = generic_dialog_new(_("Cache Maintenance"),
1208 NULL, cache_manager);
1209 gd = cache_manager->dialog;
1211 gd->cancel_cb = cache_manager_close_cb;
1212 generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL,
1213 cache_manager_close_cb, FALSE);
1214 generic_dialog_add_button(gd, GTK_STOCK_HELP, NULL,
1215 cache_manager_help_cb, FALSE);
1217 generic_dialog_add_message(gd, NULL, _("Cache and Data Maintenance"), NULL);
1219 sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1221 group = pref_group_new(gd->vbox, FALSE, _("Thumbnail cache"), GTK_ORIENTATION_VERTICAL);
1223 cache_manager_location_label(group, get_thumbnails_cache_dir());
1225 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1227 button = pref_table_button(table, 0, 0, GTK_STOCK_CLEAR, _("Clean up"), FALSE,
1228 G_CALLBACK(cache_manager_main_clean_cb), cache_manager);
1229 gtk_size_group_add_widget(sizegroup, button);
1230 pref_table_label(table, 1, 0, _("Remove orphaned or outdated thumbnails."), 0.0);
1232 button = pref_table_button(table, 0, 1, GTK_STOCK_DELETE, _("Clear cache"), FALSE,
1233 G_CALLBACK(cache_manager_main_clear_cb), cache_manager);
1234 gtk_size_group_add_widget(sizegroup, button);
1235 pref_table_label(table, 1, 1, _("Delete all cached data."), 0.0);
1238 group = pref_group_new(gd->vbox, FALSE, _("Shared thumbnail cache"), GTK_ORIENTATION_VERTICAL);
1240 path = g_build_filename(homedir(), THUMB_FOLDER_GLOBAL, NULL);
1241 cache_manager_location_label(group, path);
1244 table = pref_table_new(group, 2, 2, FALSE, FALSE);
1246 button = pref_table_button(table, 0, 0, GTK_STOCK_CLEAR, _("Clean up"), FALSE,
1247 G_CALLBACK(cache_manager_standard_clean_cb), cache_manager);
1248 gtk_size_group_add_widget(sizegroup, button);
1249 pref_table_label(table, 1, 0, _("Remove orphaned or outdated thumbnails."), 0.0);
1251 button = pref_table_button(table, 0, 1, GTK_STOCK_DELETE, _("Clear cache"), FALSE,
1252 G_CALLBACK(cache_manager_standard_clear_cb), cache_manager);
1253 gtk_size_group_add_widget(sizegroup, button);
1254 pref_table_label(table, 1, 1, _("Delete all cached thumbnails."), 0.0);
1256 group = pref_group_new(gd->vbox, FALSE, _("Create thumbnails"), GTK_ORIENTATION_VERTICAL);
1258 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1260 button = pref_table_button(table, 0, 1, GTK_STOCK_EXECUTE, _("Render"), FALSE,
1261 G_CALLBACK(cache_manager_render_cb), cache_manager);
1262 gtk_size_group_add_widget(sizegroup, button);
1263 pref_table_label(table, 1, 1, _("Render thumbnails for a specific folder."), 0.0);
1265 group = pref_group_new(gd->vbox, FALSE, _("Metadata"), GTK_ORIENTATION_VERTICAL);
1267 cache_manager_location_label(group, get_metadata_cache_dir());
1269 table = pref_table_new(group, 2, 1, FALSE, FALSE);
1271 button = pref_table_button(table, 0, 0, GTK_STOCK_CLEAR, _("Clean up"), FALSE,
1272 G_CALLBACK(cache_manager_metadata_clean_cb), cache_manager);
1273 gtk_size_group_add_widget(sizegroup, button);
1274 pref_table_label(table, 1, 0, _("Remove orphaned keywords and comments."), 0.0);
1276 gtk_widget_show(cache_manager->dialog->dialog);
1278 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */