Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
history/history.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010-2011 Henrik Andersson.
4 Copyright (C) 2010-2012, 2014 johannes hanika.
5 Copyright (C) 2010-2016, 2019 Tobias Ellinghaus.
6 Copyright (C) 2012-2014, 2019-2022 Aldric Renaudin.
7 Copyright (C) 2012 Frédéric Grollier.
8 Copyright (C) 2012-2015, 2018-2022 Pascal Obry.
9 Copyright (C) 2012 Richard Wonka.
10 Copyright (C) 2012 Ulrich Pegelow.
11 Copyright (C) 2013 José Carlos García Sogo.
12 Copyright (C) 2013 Simon Spannagel.
13 Copyright (C) 2014-2016 Roman Lebedev.
14 Copyright (C) 2015 Jan Kundrát.
15 Copyright (C) 2018-2019 Edgardo Hoszowski.
16 Copyright (C) 2019 Alexander Blinne.
17 Copyright (C) 2019, 2022 Hanno Schwalm.
18 Copyright (C) 2019-2020 Heiko Bauke.
19 Copyright (C) 2019-2020 Philippe Weyland.
20 Copyright (C) 2020 Chris Elston.
21 Copyright (C) 2020-2021 Hubert Kowalski.
22 Copyright (C) 2020 JP Verrue.
23 Copyright (C) 2021 Ralf Brown.
24 Copyright (C) 2022-2023, 2025-2026 Aurélien PIERRE.
25 Copyright (C) 2022 Martin Bařinka.
26 Copyright (C) 2023 Luca Zulberti.
27
28 darktable is free software: you can redistribute it and/or modify
29 it under the terms of the GNU General Public License as published by
30 the Free Software Foundation, either version 3 of the License, or
31 (at your option) any later version.
32
33 darktable is distributed in the hope that it will be useful,
34 but WITHOUT ANY WARRANTY; without even the implied warranty of
35 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 GNU General Public License for more details.
37
38 You should have received a copy of the GNU General Public License
39 along with darktable. If not, see <http://www.gnu.org/licenses/>.
40*/
41
44#include "history/history.h"
45#include "history/notify.h"
46#include "system/macros.h"
47#include "system/mem_alloc.h"
48#include "common/logging.h"
50#include "caches/image_cache.h"
51#include "caches/mipmap_cache.h"
52#include "metadata/tags.h"
53#include "common/undo.h"
54#include "common/glib_utils.h"
55#include "common/utility.h"
56
57#define DT_IOP_ORDER_INFO (dt_get_debug_flags() & DT_DEBUG_IOPORDER)
58
60
65
66const char *dt_history_operation_name(const char *operation)
67{
69 if(resolver == NULL) return operation; // untranslated, but legible
70 return resolver(operation);
71}
72
73void dt_history_item_free(gpointer data)
74{
76 dt_free(item->op);
77 dt_free(item->name);
78 item->op = NULL;
79 item->name = NULL;
80 dt_free(item);
81}
82
83static void _remove_preset_flag(const int32_t imgid)
84{
85 dt_image_t *image = dt_image_cache_get(imgid, 'w');
86 if(IS_NULL_PTR(image)) return;
87
88 // clear flag
90
91 // write through to sql+xmp
93}
94
95void dt_history_delete_on_image_ext(int32_t imgid, gboolean undo)
96{
98
99 if(undo)
100 {
101 hist->imgid = imgid;
103 }
104
106
107 _remove_preset_flag(imgid);
108
109 /* make sure mipmaps are recomputed */
111
112 /* remove darktable|style|* tags */
113 dt_tag_detach_by_string("darktable|style|%", imgid, FALSE, FALSE);
114 dt_tag_detach_by_string("darktable|changed", imgid, FALSE, FALSE);
115
116 // signal that the mipmap need to be updated
118
119 if(undo)
120 {
122
127 }
128}
129
135
136char *dt_history_item_as_string(const char *name, gboolean enabled)
137{
138 return g_strconcat(enabled ? "\342\227\217" : "\342\227\213", " ", name, NULL);
139}
140
141static void _collect_item(void *user_data, const int num, const char *operation,
142 const gboolean enabled, const char *multi_name)
143{
144 GList **result = (GList **)user_data;
145
146 if(strcmp(operation, "mask_manager") == 0) return;
147
148 char name[512] = { 0 };
150 item->num = num;
151 item->enabled = enabled;
152
153 if(strcmp(multi_name, "0") == 0)
154 g_snprintf(name, sizeof(name), "%s", dt_history_operation_name(operation));
155 else
156 g_snprintf(name, sizeof(name), "%s %s", dt_history_operation_name(operation), multi_name);
157
158 item->name = g_strdup(name);
159 item->op = g_strdup(operation);
160 *result = g_list_prepend(*result, item);
161}
162
163GList *dt_history_get_items(const int32_t imgid, gboolean enabled)
164{
165 GList *result = NULL;
167 return g_list_reverse(result); // list was built in reverse order, so un-reverse it
168}
169
170static void _collect_item_string(void *user_data, const int num, const char *operation,
171 const gboolean enabled, const char *multi_name)
172{
173 GList **items = (GList **)user_data;
174 char *decorated = NULL;
175
176 if(multi_name && *multi_name && g_strcmp0(multi_name, " ") != 0 && g_strcmp0(multi_name, "0") != 0)
177 decorated = g_strconcat(" ", multi_name, NULL);
178
179 char *iname = dt_history_item_as_string(dt_history_operation_name(operation), enabled);
180 char *name = g_strconcat(iname, decorated ? decorated : "", NULL);
181 // delete_underscore() is this call, and it lives in widgets/label.h -- a whole toolkit
182 // layer for one string substitution
184
185 dt_free(iname);
186 dt_free(name);
188}
189
190char *dt_history_get_items_as_string(const int32_t imgid)
191{
192 GList *items = NULL;
194 items = g_list_reverse(items); // list was built in reverse order, so un-reverse it
195 char *result = dt_util_glist_to_str("\n", items);
197 return result;
198}
199
200
201#undef DT_IOP_ORDER_INFO
202// clang-format off
203// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
204// vim: shiftwidth=2 expandtab tabstop=2 cindent
205// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
206// clang-format on
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
const dt_collection_sort_t items[]
Definition filter.c:101
static gchar * dt_string_replace(const char *string, const char *to_replace)
Definition glib_utils.h:64
static void _collect_item(void *user_data, const int num, const char *operation, const gboolean enabled, const char *multi_name)
void dt_history_set_operation_name_resolver(dt_history_operation_name_resolver_t resolver)
char * dt_history_get_items_as_string(const int32_t imgid)
char * dt_history_item_as_string(const char *name, gboolean enabled)
static void _collect_item_string(void *user_data, const int num, const char *operation, const gboolean enabled, const char *multi_name)
void dt_history_delete_on_image_ext(int32_t imgid, gboolean undo)
static dt_history_operation_name_resolver_t _operation_name_resolver
GList * dt_history_get_items(const int32_t imgid, gboolean enabled)
static void _remove_preset_flag(const int32_t imgid)
const char * dt_history_operation_name(const char *operation)
Resolve operation through the installed resolver, or return it unchanged.
void dt_history_delete_on_image(int32_t imgid)
void dt_history_item_free(gpointer data)
void dt_history_changed(const dt_history_change_t what)
Raise it. Internal to this code.
Everything the history, styles and presets code says to the outside world: messages for the user,...
@ DT_HISTORY_CHANGE_TAGS
const char *(* dt_history_operation_name_resolver_t)(const char *operation)
Turns an operation string ("exposure", "colorbalancergb") into the name a user should read.
Definition history.h:109
void dt_history_repository_foreach_last_item(const int32_t imgid, const gboolean enabled, dt_history_repository_item_cb cb, void *user_data)
gboolean dt_history_repository_delete_all_for_image(const int32_t imgid)
void dt_history_repository_foreach_item(const int32_t imgid, dt_history_repository_item_cb cb, void *user_data)
void dt_history_snapshot_undo_create(const int32_t imgid, int *snap_id, int *history_end)
void dt_history_snapshot_undo_lt_history_data_free(gpointer data)
dt_undo_lt_history_t * dt_history_snapshot_item_init(void)
void dt_history_snapshot_undo_pop(gpointer user_data, dt_undo_type_t type, dt_undo_data_t data, dt_undo_action_t action, GList **imgs)
void dt_image_cache_write_release(dt_image_t *img, dt_image_cache_write_mode_t mode)
dt_image_t * dt_image_cache_get(const int32_t imgid, char mode)
@ DT_IMAGE_CACHE_SAFE
Definition image_cache.h:48
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:65
static void dt_free_gpointer(gpointer ptr)
Definition mem_alloc.h:104
#define dt_free(ptr)
Definition mem_alloc.h:97
void dt_mipmap_cache_remove(const int32_t imgid, const gboolean flush_disk)
const char * name
Definition pdf.h:90
gboolean enabled
Definition history.h:83
int32_t flags
Definition image.h:377
gboolean dt_tag_detach_by_string(const char *name, const int32_t imgid, const gboolean undo_on, const gboolean group_on)
Definition tags.c:500
void dt_thumbnail_notify_image_changed(int32_t imgid, gboolean refresh_filmstrip)
void dt_undo_end_group(dt_undo_t *self)
Definition undo.c:149
void dt_undo_start_group(dt_undo_t *self, dt_undo_type_t type)
Definition undo.c:134
void dt_undo_record(dt_undo_t *self, gpointer user_data, dt_undo_type_t type, dt_undo_data_t data, void(*undo)(gpointer user_data, dt_undo_type_t type, dt_undo_data_t item, dt_undo_action_t action, GList **imgs), void(*free_data)(gpointer data))
Definition undo.c:163
@ DT_UNDO_LT_HISTORY
Definition undo.h:49
dt_undo_t * dt_undo_get_global(void)
Definition darktable.c:638
void * dt_undo_data_t
Definition undo.h:68
gchar * dt_util_glist_to_str(const gchar *separator, GList *items)
Definition utility.c:169