Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
grouping.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2011-2012, 2014, 2016 Tobias Ellinghaus.
4 Copyright (C) 2013 Simon Spannagel.
5 Copyright (C) 2014 johannes hanika.
6 Copyright (C) 2016 Roman Lebedev.
7 Copyright (C) 2019-2020 Philippe Weyland.
8 Copyright (C) 2020 Hanno Schwalm.
9 Copyright (C) 2020-2021 Hubert Kowalski.
10 Copyright (C) 2020-2021 Pascal Obry.
11 Copyright (C) 2021 Ralf Brown.
12 Copyright (C) 2022 Aldric Renaudin.
13 Copyright (C) 2022, 2025 Aurélien PIERRE.
14 Copyright (C) 2022 Martin Bařinka.
15
16 darktable is free software: you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
20
21 darktable is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with darktable. If not, see <http://www.gnu.org/licenses/>.
28*/
29
30#include "common/grouping.h"
31#include "common/collection.h"
32#include "system/macros.h"
33#include "system/mem_alloc.h"
36#include "caches/image_cache.h"
37
38int32_t dt_grouping_get_image_group(const int32_t image_id)
39{
40 const dt_image_t *img = dt_image_cache_get(image_id, 'r');
41 const int img_group_id = img->group_id;
43 return img_group_id;
44}
45
47void dt_grouping_add_to_group(const int32_t group_id, const int32_t image_id)
48{
49 // remove from old group
51
52 dt_image_t *img = dt_image_cache_get(image_id, 'w');
53 img->group_id = group_id;
55}
56
58int dt_grouping_remove_from_group(const int32_t image_id)
59{
60 int new_group_id = -1;
61 GList *imgs = NULL;
62
63 const dt_image_t *img = dt_image_cache_get(image_id, 'r');
64 if(!img) return -1;
65 const int img_group_id = img->group_id;
67 if(img_group_id == image_id)
68 {
69 // get a new group_id for all the others in the group. also write it to the dt_image_t struct.
70 GList *others = dt_image_repository_get_group_members(img_group_id, image_id);
71 for(GList *o = others; o; o = g_list_next(o))
72 {
73 const int other_id = GPOINTER_TO_INT(o->data);
74 if(new_group_id == -1) new_group_id = other_id;
75 dt_image_t *other_img = dt_image_cache_get(other_id, 'w');
76 other_img->group_id = new_group_id;
78 imgs = g_list_prepend(imgs, GINT_TO_POINTER(other_id));
79 }
80 g_list_free(others);
81
82 if(new_group_id != -1)
83 {
84 dt_image_repository_reassign_group(img_group_id, new_group_id, image_id);
85 }
86 else
87 {
88 // no change was made, no point in raising signal, bailing early
89 return -1;
90 }
91 }
92 else
93 {
94 // change the group_id for this image.
95 dt_image_t *wimg = dt_image_cache_get(image_id, 'w');
96 new_group_id = wimg->group_id;
97 wimg->group_id = image_id;
99 imgs = g_list_prepend(imgs, GINT_TO_POINTER(image_id));
100 // refresh also the group leader which may be alone now
101 imgs = g_list_prepend(imgs, GINT_TO_POINTER(img_group_id));
102 }
103
104 return new_group_id;
105}
106
108int dt_grouping_change_representative(const int32_t image_id)
109{
110 dt_image_t *img = dt_image_cache_get(image_id, 'r');
111 const int group_id = img->group_id;
113
114 GList *imgs = NULL;
115 GList *members = dt_image_repository_get_group_members(group_id, -1);
116 for(GList *m = members; m; m = g_list_next(m))
117 {
118 const int other_id = GPOINTER_TO_INT(m->data);
119 dt_image_t *other_img = dt_image_cache_get(other_id, 'w');
120 other_img->group_id = image_id;
122 imgs = g_list_prepend(imgs, GINT_TO_POINTER(other_id));
123 }
124 g_list_free(members);
125
126 return image_id;
127}
128
130GList *dt_grouping_get_group_images(const int32_t imgid)
131{
132 GList *imgs = NULL;
133 const dt_image_t *image = dt_image_cache_get(imgid, 'r');
134 if(image)
135 {
136 const int img_group_id = image->group_id;
138
139 GList *members = dt_image_repository_get_group_members(img_group_id, -1);
140 for(GList *m = members; m; m = g_list_next(m))
141 imgs = g_list_prepend(imgs, m->data);
142 g_list_free(members);
143 }
144 return g_list_reverse(imgs);
145}
146
149{
150 if(IS_NULL_PTR(*images)) return;
151 GList *gimgs = NULL;
152 for(GList *imgs = *images; imgs; imgs = g_list_next(imgs))
153 {
154 const dt_image_t *image = dt_image_cache_get(GPOINTER_TO_INT(imgs->data), 'r');
155 if(image)
156 {
157 const int img_group_id = image->group_id;
160 {
161 GList *members = dt_collection_query_get_group_members(img_group_id,
162 GPOINTER_TO_INT(imgs->data));
163 for(GList *m = members; m; m = g_list_next(m))
164 gimgs = g_list_prepend(gimgs, m->data);
165 g_list_free(members);
166 }
167 }
168 }
169
170 if(gimgs)
171 *images = g_list_concat(*images, g_list_reverse(gimgs));
172}
173
174// clang-format off
175// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
176// vim: shiftwidth=2 expandtab tabstop=2 cindent
177// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
178// clang-format on
#define m
Definition basecurve.c:283
dt_collection_t * dt_collection_get_global(void)
Definition collection.c:138
GList * dt_collection_query_get_group_members(const int32_t group_id, const int32_t exclude_imgid)
int dt_grouping_change_representative(const int32_t image_id)
Definition grouping.c:108
int dt_grouping_remove_from_group(const int32_t image_id)
Definition grouping.c:58
int32_t dt_grouping_get_image_group(const int32_t image_id)
Definition grouping.c:38
void dt_grouping_add_grouped_images(GList **images)
Definition grouping.c:148
void dt_grouping_add_to_group(const int32_t group_id, const int32_t image_id)
Definition grouping.c:47
GList * dt_grouping_get_group_images(const int32_t imgid)
Definition grouping.c:130
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)
void dt_image_cache_read_release(const dt_image_t *img)
@ DT_IMAGE_CACHE_SAFE
Definition image_cache.h:48
void dt_image_repository_reassign_group(const int32_t from_group_id, const int32_t to_group_id, const int32_t exclude_imgid)
Move every member of from_group_id into to_group_id, except exclude_imgid.
GList * dt_image_repository_get_group_members(const int32_t group_id, const int32_t exclude_imgid)
Image ids in group group_id.
Reading and writing one dt_image_t to and from the library database. The SQL half of what used to be ...
#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:96
int32_t group_id
Definition image.h:401