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 "control/crawler.h"
20#include "common/collection.h"
21#include "common/mipmap_cache.h"
22#include "common/selection.h"
23#include "control/jobs.h"
25
31
32static gboolean clear_caches_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
33{
36 return TRUE;
37}
38
39static gboolean optimize_database_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
40{
42 return TRUE;
43}
44
45static gboolean backup_database_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
46{
48 return TRUE;
49}
50
51static gboolean crawl_xmp_changes(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
52{
53 GList *changed_xmp_files = dt_control_crawler_run();
54 dt_control_crawler_show_image_list(changed_xmp_files);
55 return TRUE;
56}
57
58static int32_t preload_image_cache(dt_job_t *job)
59{
60 // Retrieve the maximum mipmap size to generate from job parameters
62 const dt_mipmap_size_t max_mipmap_size = (params) ? params->max_mipmap_size : DT_MIPMAP_2;
63
64 // Load the mipmap cache sizes 0 to max_mipmap_size of the current selection
65 GList *selection = dt_selection_get_list(darktable.selection);
66 int i = 0;
67 float imgs = (float)dt_selection_get_length(darktable.selection) * (max_mipmap_size + 1);
68 GList *img = g_list_first(selection);
69
71 {
72 const int32_t imgid = GPOINTER_TO_INT(img->data);
73
74 // Note : we generate from large scale to small,
75 // because the mipmap code has a mechanism that downscales
76 // higher resolution thumbnails if present, rather
77 // than recomputing a pipe from scratch.
78 for(int k = max_mipmap_size; k >= DT_MIPMAP_0 && dt_control_job_get_state(job) != DT_JOB_STATE_CANCELLED; k--)
79 {
80 char filename[PATH_MAX] = { 0 };
82
83 // if a valid thumbnail file is already on disc - do nothing
84 if(dt_util_test_image_file(filename))
85 {
86 i++;
87 continue;
88 }
89
90 // else, generate thumbnail and store in mipmap cache.
94
95 i++;
96 dt_control_job_set_progress(job, (float)i / imgs);
97 }
98
99 // and immediately write thumbs to disc and remove from mipmap cache.
101
102 img = g_list_next(img);
103 }
104
105 g_list_free(selection);
106 selection = NULL;
107 return 0;
108}
109
112{
114 params->max_mipmap_size = max_size;
115
117 dt_control_job_set_params(job, params, g_free);
120 return TRUE;
121}
122
123// Callback functions for each mipmap size
124static gboolean preload_to_mipmap_0_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
125{
126 return _preload_image_cache_with_max_size(DT_MIPMAP_0, _("Preloading cache (up to 360x225 px) for current collection"));
127}
128
129static gboolean preload_to_mipmap_1_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
130{
131 return _preload_image_cache_with_max_size(DT_MIPMAP_1, _("Preloading cache (up to 720x450 px) for current collection"));
132}
133
134static gboolean preload_to_mipmap_2_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
135{
136 return _preload_image_cache_with_max_size(DT_MIPMAP_2, _("Preloading cache (up to 1440x900 px) for current collection"));
137}
138
139static gboolean preload_to_mipmap_3_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
140{
141 return _preload_image_cache_with_max_size(DT_MIPMAP_3, _("Preloading cache (up to Full HD 1080p) for current collection"));
142}
143
144static gboolean preload_to_mipmap_4_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
145{
146 return _preload_image_cache_with_max_size(DT_MIPMAP_4, _("Preloading cache (up to 2560x1440 px) for current collection"));
147}
148
149static gboolean preload_to_mipmap_5_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
150{
151 return _preload_image_cache_with_max_size(DT_MIPMAP_5, _("Preloading cache (up to 4K/UHD) for current collection"));
152}
153
154static gboolean preload_to_mipmap_6_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
155{
156 return _preload_image_cache_with_max_size(DT_MIPMAP_6, _("Preloading cache (up to 5K) for current collection"));
157}
158
159static gboolean preload_to_mipmap_7_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
160{
161 return _preload_image_cache_with_max_size(DT_MIPMAP_7, _("Preloading cache (up to 6K) for current collection"));
162}
163
164static gboolean preload_to_mipmap_8_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
165{
166 return _preload_image_cache_with_max_size(DT_MIPMAP_8, _("Preloading cache (up to 8K) for current collection"));
167}
168
169static gboolean preload_auto_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
170{
172 const int width = ceilf(table->thumb_width * darktable.gui->ppd);
173 const int height = ceilf(table->thumb_height * darktable.gui->ppd);
176 fprintf(stdout, "mipmap %i\n", mip);
177 return _preload_image_cache_with_max_size(mip, _("Preloading cache for current collection"));
178}
179
180static gboolean clear_image_cache(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
181{
182 GList *selection = dt_selection_get_list(darktable.selection);
183
184 for(GList *img = g_list_first(selection); img; img = g_list_next(img))
185 {
186 const int32_t imgid = GPOINTER_TO_INT(img->data);
188 }
189
190 g_list_free(selection);
191 selection = NULL;
192
193 // Redraw thumbnails
195 return TRUE;
196}
197
200
201void append_run(GtkWidget **menus, GList **lists, const dt_menus_t index)
202{
203 add_sub_menu_entry(menus, lists, _("Clear darkroom pipeline caches"), index, NULL, clear_caches_callback, NULL, NULL, NULL, 0, 0);
204
205 // Create submenu for preloading selected thumbnails with different maximum mipmap sizes
206 add_top_submenu_entry(menus, lists, _("Preload selected thumbnails in cache"), index);
207 GtkWidget *parent = get_last_widget(lists);
208
209 // Add mipmap size options to the submenu
210 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);
211 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);
212 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);
213 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);
214 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);
215 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);
216 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);
217 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);
218 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);
220 add_sub_sub_menu_entry(menus, parent, lists, _("for current grid size"), index, NULL, preload_auto_callback, NULL, NULL, has_active_images, 0, 0);
221
222 add_sub_menu_entry(menus, lists, _("Purge selected thumbnails from cache"), index, NULL, clear_image_cache, NULL, NULL, has_active_images, 0, 0);
223 add_menu_separator(menus[index]);
224 add_sub_menu_entry(menus, lists, _("Defragment the library"), index, NULL, optimize_database_callback, NULL, NULL, NULL, 0, 0);
225 add_sub_menu_entry(menus, lists, _("Backup the library"), index, NULL, backup_database_callback, NULL, NULL, NULL, 0, 0);
226 add_menu_separator(menus[index]);
227 add_sub_menu_entry(menus, lists, _("Synchronize developments from XMP to database"), index, NULL, crawl_xmp_changes, NULL, NULL, NULL, 0, 0);
228 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);
229 add_menu_separator(menus[index]);
230 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);
231}
const char ** description(struct dt_iop_module_t *self)
Definition ashift.c:160
#define TRUE
Definition ashift_lsd.c:162
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_image_local_copy_synch()
void dt_control_write_sidecar_files()
void dt_control_crawler_show_image_list(GList *images)
Definition crawler.c:680
GList * dt_control_crawler_run(void)
Definition crawler.c:121
darktable_t darktable
Definition darktable.c:181
#define UNKNOWN_IMAGE
Definition darktable.h:182
#define PATH_MAX
Definition darktable.h:1062
gboolean dt_database_snapshot(const struct dt_database_t *db)
Definition database.c:3972
void dt_database_perform_maintenance(const struct dt_database_t *db)
Definition database.c:3728
void dt_dev_pixelpipe_reset_all(dt_develop_t *dev)
#define dt_dev_pixelpipe_resync_history_all(dev)
dt_job_state_t dt_control_job_get_state(_dt_job_t *job)
Definition jobs.c:103
dt_job_t * dt_control_job_create(dt_job_execute_callback execute, const char *msg,...)
Definition jobs.c:135
int dt_control_add_job(dt_control_t *control, dt_job_queue_t queue_id, _dt_job_t *job)
Definition jobs.c:405
void * dt_control_job_get_params(const _dt_job_t *job)
Definition jobs.c:129
void dt_control_job_set_progress(dt_job_t *job, double value)
Definition jobs.c:626
void dt_control_job_add_progress(dt_job_t *job, const char *message, gboolean cancellable)
Definition jobs.c:612
void dt_control_job_set_params(_dt_job_t *job, void *params, dt_job_destroy_callback callback)
Definition jobs.c:112
@ DT_JOB_QUEUE_USER_BG
Definition jobs.h:55
@ DT_JOB_STATE_CANCELLED
Definition jobs.h:46
float *const restrict const size_t k
static const int max_size
Definition map.c:130
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:584
GtkWidget * get_last_widget(GList **list)
Definition menu.c:618
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:542
void add_sub_menu_separator(GtkWidget *parent)
Definition menu.c:605
void add_top_submenu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index)
Definition menu.c:515
void add_menu_separator(GtkWidget *menu)
Definition menu.c:598
gboolean has_active_images()
Definition menu.c:636
#define GET_ACCEL_WRAPPER(cb)
Definition menu.h:244
#define MAKE_ACCEL_WRAPPER(cb)
Definition menu.h:232
dt_menus_t
Definition menu.h:42
void dt_mipmap_get_cache_filename(char path[PATH_MAX], const dt_mipmap_cache_t *cache, dt_mipmap_size_t mip, const int32_t imgid)
void dt_mipmap_cache_remove(dt_mipmap_cache_t *cache, const int32_t imgid, const gboolean flush_disk)
void dt_mimap_cache_evict(dt_mipmap_cache_t *cache, const int32_t imgid)
dt_mipmap_size_t dt_mipmap_cache_get_matching_size(const dt_mipmap_cache_t *cache, const int32_t width, const int32_t height, const uint32_t imgid)
#define dt_mipmap_cache_get(A, B, C, D, E, F)
@ DT_MIPMAP_BLOCKING
#define dt_mipmap_cache_release(A, B)
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
static gboolean preload_to_mipmap_8_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:164
static gboolean preload_to_mipmap_0_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:124
static gboolean preload_to_mipmap_7_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:159
static gboolean preload_to_mipmap_1_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:129
static gboolean preload_to_mipmap_6_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:154
void append_run(GtkWidget **menus, GList **lists, const dt_menus_t index)
Definition run.c:201
static int32_t preload_image_cache(dt_job_t *job)
Definition run.c:58
static gboolean preload_to_mipmap_3_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:139
static gboolean preload_to_mipmap_4_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:144
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:111
static gboolean clear_caches_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:32
static gboolean preload_auto_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:169
static gboolean preload_to_mipmap_5_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:149
static gboolean clear_image_cache(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:180
static gboolean backup_database_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:45
static gboolean optimize_database_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:39
static gboolean crawl_xmp_changes(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition run.c:51
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:134
int dt_selection_get_length(struct dt_selection_t *selection)
Definition selection.c:179
GList * dt_selection_get_list(struct dt_selection_t *selection)
Definition selection.c:172
struct _GtkWidget GtkWidget
Definition splash.h:29
Job parameters for preloading image cache with a maximum mipmap size.
Definition run.c:28
dt_mipmap_size_t max_mipmap_size
Maximum mipmap size to generate.
Definition run.c:29
struct dt_gui_gtk_t * gui
Definition darktable.h:775
struct dt_mipmap_cache_t * mipmap_cache
Definition darktable.h:776
struct dt_selection_t * selection
Definition darktable.h:782
const struct dt_database_t * db
Definition darktable.h:779
struct dt_develop_t * develop
Definition darktable.h:770
struct dt_control_t * control
Definition darktable.h:773
double ppd
Definition gtk.h:200
dt_ui_t * ui
Definition gtk.h:164
dt_thumbtable_t * thumbtable_lighttable
#define dt_thumbtable_refresh_thumbnail(table, imgid, reinit)
Definition thumbtable.h:283
gboolean dt_util_test_image_file(const char *filename)
Definition utility.c:318