Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
run.c
Go to the documentation of this file.
1/*
2 This file is part of the Ansel project.
3 Copyright (C) 2023-2026 Aurélien PIERRE.
4
5 Ansel is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 Ansel is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Ansel. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "gui/actions/menu.h"
19#include "common/paths.h" // DT_PATH_MAX
20#include "control/control.h"
21#include "control/crawler.h"
22#include "database/database.h"
23#include "caches/mipmap_cache.h"
24#include "common/selection.h"
25#include "common/utility.h"
26#include "control/jobs.h"
28#include "develop/develop.h"
30#include "gui/application.h"
31#include "gui/dtgtk/thumbnail.h"
33
39
40static gboolean clear_caches_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
41{
42 dt_develop_t *const dev = dt_dev_get_global();
45 return TRUE;
46}
47
48static gboolean optimize_database_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
49{
51 return TRUE;
52}
53
54static gboolean backup_database_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
55{
57 return TRUE;
58}
59
60static gboolean crawl_xmp_changes(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
61{
62 GList *changed_xmp_files = dt_control_crawler_run();
63 dt_control_crawler_show_image_list(changed_xmp_files);
64 return TRUE;
65}
66
67static int32_t preload_image_cache(dt_job_t *job)
68{
69 // Retrieve the maximum mipmap size to generate from job parameters
71 const dt_mipmap_size_t max_mipmap_size = (params) ? params->max_mipmap_size : DT_MIPMAP_2;
72
73 // Load the mipmap cache sizes 0 to max_mipmap_size of the current selection
75 int i = 0;
76 float imgs = (float)dt_selection_get_length(dt_selection_get_global()) * (max_mipmap_size + 1);
77 GList *img = g_list_first(selection);
78
80 {
81 const int32_t imgid = GPOINTER_TO_INT(img->data);
82
83 // Note : we generate from large scale to small,
84 // because the mipmap code has a mechanism that downscales
85 // higher resolution thumbnails if present, rather
86 // than recomputing a pipe from scratch.
87 for(int k = max_mipmap_size; k >= DT_MIPMAP_0 && dt_control_job_get_state(job) != DT_JOB_STATE_CANCELLED; k--)
88 {
89 char filename[DT_PATH_MAX] = { 0 };
90 dt_mipmap_get_cache_filename(filename, k, imgid);
91
92 // if a valid thumbnail file is already on disc - do nothing
93 if(dt_util_test_image_file(filename))
94 {
95 i++;
96 continue;
97 }
98
99 // else, generate thumbnail and store in mipmap cache.
101 dt_mipmap_cache_get(&buf, imgid, k, DT_MIPMAP_BLOCKING, 'r');
103
104 i++;
105 dt_control_job_set_progress(job, (float)i / imgs);
106 }
107
108 // and immediately write thumbs to disc and remove from mipmap cache.
110
111 img = g_list_next(img);
112 }
113
114 g_list_free(selection);
115 selection = NULL;
116 return 0;
117}
118
121{
123 params->max_mipmap_size = max_size;
124
126 dt_control_job_set_params(job, params, g_free);
129 return TRUE;
130}
131
132// Callback functions for each mipmap size
133static gboolean preload_to_mipmap_0_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
134{
135 return _preload_image_cache_with_max_size(DT_MIPMAP_0, _("Preloading cache (up to 360x225 px) for current collection"));
136}
137
138static gboolean preload_to_mipmap_1_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
139{
140 return _preload_image_cache_with_max_size(DT_MIPMAP_1, _("Preloading cache (up to 720x450 px) for current collection"));
141}
142
143static gboolean preload_to_mipmap_2_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
144{
145 return _preload_image_cache_with_max_size(DT_MIPMAP_2, _("Preloading cache (up to 1440x900 px) for current collection"));
146}
147
148static gboolean preload_to_mipmap_3_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
149{
150 return _preload_image_cache_with_max_size(DT_MIPMAP_3, _("Preloading cache (up to Full HD 1080p) for current collection"));
151}
152
153static gboolean preload_to_mipmap_4_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
154{
155 return _preload_image_cache_with_max_size(DT_MIPMAP_4, _("Preloading cache (up to 2560x1440 px) for current collection"));
156}
157
158static gboolean preload_to_mipmap_5_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
159{
160 return _preload_image_cache_with_max_size(DT_MIPMAP_5, _("Preloading cache (up to 4K/UHD) for current collection"));
161}
162
163static gboolean preload_to_mipmap_6_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
164{
165 return _preload_image_cache_with_max_size(DT_MIPMAP_6, _("Preloading cache (up to 5K) for current collection"));
166}
167
168static gboolean preload_to_mipmap_7_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
169{
170 return _preload_image_cache_with_max_size(DT_MIPMAP_7, _("Preloading cache (up to 6K) for current collection"));
171}
172
173static gboolean preload_to_mipmap_8_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
174{
175 return _preload_image_cache_with_max_size(DT_MIPMAP_8, _("Preloading cache (up to 8K) for current collection"));
176}
177
178static gboolean preload_auto_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
179{
181 const int width = ceilf(table->thumb_width * dt_gui_get_global()->ppd);
182 const int height = ceilf(table->thumb_height * dt_gui_get_global()->ppd);
184 fprintf(stdout, "mipmap %i\n", mip);
185 return _preload_image_cache_with_max_size(mip, _("Preloading cache for current collection"));
186}
187
188static gboolean clear_image_cache(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
189{
191
192 for(GList *img = g_list_first(selection); img; img = g_list_next(img))
193 {
194 const int32_t imgid = GPOINTER_TO_INT(img->data);
196 }
197
198 g_list_free(selection);
199 selection = NULL;
200
201 // Redraw thumbnails
203 return TRUE;
204}
205
206static gboolean doc_screenshot_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
207{
209 return TRUE;
210}
211
214
215void append_run(GtkWidget **menus, GList **lists, const dt_menus_t index)
216{
217 add_sub_menu_entry(menus, lists, _("Clear darkroom pipeline caches"), index, NULL, clear_caches_callback, NULL, NULL, NULL, 0, 0);
218
219 // Create submenu for preloading selected thumbnails with different maximum mipmap sizes
220 add_top_submenu_entry(menus, lists, _("Preload selected thumbnails in cache"), index);
221 GtkWidget *parent = get_last_widget(lists);
222
223 // Add mipmap size options to the submenu
224 add_sub_sub_menu_entry(menus, parent, lists, _("up to 360x225 px"), index, NULL, preload_to_mipmap_0_callback, NULL, NULL, has_active_images, 0, 0);
225 add_sub_sub_menu_entry(menus, parent, lists, _("up to 720x450 px"), index, NULL, preload_to_mipmap_1_callback, NULL, NULL, has_active_images, 0, 0);
226 add_sub_sub_menu_entry(menus, parent, lists, _("up to 1440x900 px"), index, NULL, preload_to_mipmap_2_callback, NULL, NULL, has_active_images, 0, 0);
227 add_sub_sub_menu_entry(menus, parent, lists, _("up to Full HD 1080p"), index, NULL, preload_to_mipmap_3_callback, NULL, NULL, has_active_images, 0, 0);
228 add_sub_sub_menu_entry(menus, parent, lists, _("up to 2560x1440 px"), index, NULL, preload_to_mipmap_4_callback, NULL, NULL, has_active_images, 0, 0);
229 add_sub_sub_menu_entry(menus, parent, lists, _("up to 4K/UHD"), index, NULL, preload_to_mipmap_5_callback, NULL, NULL, has_active_images, 0, 0);
230 add_sub_sub_menu_entry(menus, parent, lists, _("up to 5K"), index, NULL, preload_to_mipmap_6_callback, NULL, NULL, has_active_images, 0, 0);
231 add_sub_sub_menu_entry(menus, parent, lists, _("up to 6K"), index, NULL, preload_to_mipmap_7_callback, NULL, NULL, has_active_images, 0, 0);
232 add_sub_sub_menu_entry(menus, parent, lists, _("up to 8K"), index, NULL, preload_to_mipmap_8_callback, NULL, NULL, has_active_images, 0, 0);
234 add_sub_sub_menu_entry(menus, parent, lists, _("for current grid size"), index, NULL, preload_auto_callback, NULL, NULL, has_active_images, 0, 0);
235
236 add_sub_menu_entry(menus, lists, _("Purge selected thumbnails from cache"), index, NULL, clear_image_cache, NULL, NULL, has_active_images, 0, 0);
237 add_menu_separator(menus[index]);
238 add_sub_menu_entry(menus, lists, _("Defragment the library"), index, NULL, optimize_database_callback, NULL, NULL, NULL, 0, 0);
239 add_sub_menu_entry(menus, lists, _("Backup the library"), index, NULL, backup_database_callback, NULL, NULL, NULL, 0, 0);
240 add_menu_separator(menus[index]);
241 add_sub_menu_entry(menus, lists, _("Synchronize developments from XMP to database"), index, NULL, crawl_xmp_changes, NULL, NULL, NULL, 0, 0);
242 add_sub_menu_entry(menus, lists, _("Synchronize developments from database to XMP"), index, NULL, GET_ACCEL_WRAPPER(dt_control_write_sidecar_files), NULL, NULL, has_active_images, 0, 0);
243 add_menu_separator(menus[index]);
244 add_sub_menu_entry(menus, lists, _("Resynchronize local copies with distant XMP"), index, NULL, GET_ACCEL_WRAPPER(dt_image_local_copy_synch), NULL, NULL, NULL, 0, 0);
245
246 // Documentation mode: the capture panel is only offered when the application was started
247 // with --doc, so a regular user never sees an entry that only serves the manual.
249 {
250 add_menu_separator(menus[index]);
251 add_sub_menu_entry(menus, lists, _("Capture widget screenshots..."), index, NULL, doc_screenshot_callback, NULL, NULL, NULL, 0, 0);
252 }
253}
struct dt_ui_t * dt_gui_get_ui(void)
const char ** description(struct dt_iop_module_t *self)
Definition ashift.c:168
#define TRUE
Definition ashift_lsd.c:162
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
void dt_image_local_copy_synch()
void dt_control_write_sidecar_files()
struct dt_control_t * dt_control_get_global(void)
Definition darktable.c:651
void dt_control_crawler_show_image_list(GList *images)
Definition crawler.c:989
GList * dt_control_crawler_run(void)
Definition crawler.c:533
struct dt_develop_t * dt_dev_get_global(void)
Definition darktable.c:528
struct dt_gui_gtk_t * dt_gui_get_global(void)
Definition darktable.c:523
gboolean dt_database_snapshot(void)
Definition database.c:4118
void dt_database_perform_maintenance(void)
Definition database.c:3883
void dt_dev_pixelpipe_reset_all(dt_develop_t *dev)
#define dt_dev_pixelpipe_resync_history_all(dev)
void dt_gui_doc_screenshot_window_show(void)
gboolean dt_gui_doc_screenshot_enabled(void)
#define UNKNOWN_IMAGE
Definition image.h:78
dt_job_state_t dt_control_job_get_state(_dt_job_t *job)
Definition jobs.c:105
dt_job_t * dt_control_job_create(dt_job_execute_callback execute, const char *msg,...)
Definition jobs.c:137
int dt_control_add_job(dt_control_t *control, dt_job_queue_t queue_id, _dt_job_t *job)
Definition jobs.c:407
void * dt_control_job_get_params(const _dt_job_t *job)
Definition jobs.c:131
void dt_control_job_set_progress(dt_job_t *job, double value)
Definition jobs.c:628
void dt_control_job_add_progress(dt_job_t *job, const char *message, gboolean cancellable)
Definition jobs.c:614
void dt_control_job_set_params(_dt_job_t *job, void *params, dt_job_destroy_callback callback)
Definition jobs.c:114
@ DT_JOB_QUEUE_USER_BG
Definition jobs.h:56
@ DT_JOB_STATE_CANCELLED
Definition jobs.h:47
float *const restrict const size_t k
static const int max_size
Definition map.c:132
void add_sub_sub_menu_entry(GtkWidget **menus, GtkWidget *parent, GList **lists, const gchar *label, const dt_menus_t index, void *data, gboolean(*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data), gboolean(*checked_callback)(GtkWidget *widget), gboolean(*active_callback)(GtkWidget *widget), gboolean(*sensitive_callback)(GtkWidget *widget), guint key_val, GdkModifierType mods)
Definition menu.c:607
GtkWidget * get_last_widget(GList **list)
Definition menu.c:641
void add_sub_menu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index, void *data, gboolean(*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data), gboolean(*checked_callback)(GtkWidget *widget), gboolean(*active_callback)(GtkWidget *widget), gboolean(*sensitive_callback)(GtkWidget *widget), guint key_val, GdkModifierType mods)
Definition menu.c:565
void add_sub_menu_separator(GtkWidget *parent)
Definition menu.c:628
void add_top_submenu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index)
Definition menu.c:538
void add_menu_separator(GtkWidget *menu)
Definition menu.c:621
gboolean has_active_images()
Definition menu.c:659
#define GET_ACCEL_WRAPPER(cb)
Definition menu.h:239
#define MAKE_ACCEL_WRAPPER(cb)
Definition menu.h:227
dt_menus_t
Definition menu.h:42
uint32_t width
Definition mipmap_cache.c:0
void dt_mipmap_cache_remove(const int32_t imgid, const gboolean flush_disk)
uint32_t height
Definition mipmap_cache.c:1
void dt_mimap_cache_evict(const int32_t imgid)
dt_mipmap_size_t dt_mipmap_cache_get_matching_size(const int32_t width, const int32_t height, const uint32_t imgid)
void dt_mipmap_get_cache_filename(char path[DT_PATH_MAX], dt_mipmap_size_t mip, const int32_t imgid)
@ DT_MIPMAP_BLOCKING
dt_mipmap_size_t
@ DT_MIPMAP_6
@ DT_MIPMAP_1
@ DT_MIPMAP_4
@ DT_MIPMAP_7
@ DT_MIPMAP_0
@ DT_MIPMAP_5
@ DT_MIPMAP_2
@ DT_MIPMAP_3
@ DT_MIPMAP_8
#define dt_mipmap_cache_get(B, C, D, E, F)
#define dt_mipmap_cache_release(B)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
Definition paths.h:57
static gboolean doc_screenshot_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:206
static gboolean preload_to_mipmap_8_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:173
static gboolean preload_to_mipmap_0_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:133
static gboolean preload_to_mipmap_7_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:168
static gboolean preload_to_mipmap_1_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:138
static gboolean preload_to_mipmap_6_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:163
void append_run(GtkWidget **menus, GList **lists, const dt_menus_t index)
Definition run.c:215
static int32_t preload_image_cache(dt_job_t *job)
Definition run.c:67
static gboolean preload_to_mipmap_3_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:148
static gboolean preload_to_mipmap_4_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:153
static gboolean _preload_image_cache_with_max_size(dt_mipmap_size_t max_size, const char *description)
Helper function to create a preload job with the specified maximum mipmap size.
Definition run.c:120
static gboolean clear_caches_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:40
static gboolean preload_auto_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:178
static gboolean preload_to_mipmap_5_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:158
static gboolean clear_image_cache(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:188
static gboolean backup_database_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:54
static gboolean optimize_database_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:48
static gboolean crawl_xmp_changes(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:60
struct _preload_cache_params_t preload_cache_params_t
Job parameters for preloading image cache with a maximum mipmap size.
static gboolean preload_to_mipmap_2_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:143
struct dt_selection_t * dt_selection_get_global(void)
Definition selection.c:80
int dt_selection_get_length(struct dt_selection_t *selection)
Definition selection.c:193
GList * dt_selection_get_list(struct dt_selection_t *selection)
Definition selection.c:185
Job parameters for preloading image cache with a maximum mipmap size.
Definition run.c:36
dt_mipmap_size_t max_mipmap_size
Maximum mipmap size to generate.
Definition run.c:37
dt_thumbtable_t * thumbtable_lighttable
A widget to manage and display image thumbnails in Ansel's lighttable and filmstrip views.
#define dt_thumbtable_refresh_thumbnail(table, imgid, reinit)
Definition thumbtable.h:298
gboolean dt_util_test_image_file(const char *filename)
Definition utility.c:322