1 /*
2     This file is part of darktable,
3     Copyright (C) 2011-2021 darktable developers.
4 
5     darktable 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     darktable 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 darktable.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 
21 #include <glib-object.h>
22 
23 /** \brief enum of signals to listen for in darktable.
24     \note To add a new signal, first off add a enum and
25     document what it's used for, then add a matching signal string
26     name to _strings in signal.c
27 */
28 typedef enum dt_signal_t
29 {
30   /** \brief This signal is raised when mouse hovers over image thumbs
31       both on lighttable and in the filmstrip.
32       no param, no returned value
33    */
34   DT_SIGNAL_MOUSE_OVER_IMAGE_CHANGE,
35 
36   /** \brief This signal is raised when image shown in the main view change
37       no param, no returned value
38    */
39   DT_SIGNAL_ACTIVE_IMAGES_CHANGE,
40 
41   /** \brief This signal is raised when dt_control_queue_redraw() is called.
42     no param, no returned value
43   */
44   DT_SIGNAL_CONTROL_REDRAW_ALL,
45 
46   /** \brief This signal is raised when dt_control_queue_redraw_center() is called.
47     no param, no returned value
48    */
49   DT_SIGNAL_CONTROL_REDRAW_CENTER,
50 
51   /** \brief This signal is raised by viewmanager when a view has changed.
52     1 : dt_view_t * the old view
53     2 : dt_view_t * the new (current) view
54     no returned value
55    */
56   DT_SIGNAL_VIEWMANAGER_VIEW_CHANGED,
57 
58   /** \brief This signal is raised by viewmanager when a view has changed.
59     1 : dt_view_t * the old view
60     2 : dt_view_t * the new (current) view
61     no returned value
62    */
63   DT_SIGNAL_VIEWMANAGER_VIEW_CANNOT_CHANGE,
64 
65   /** \bief This signal is raised when a thumb is doubleclicked in
66     thumbtable (filemananger, filmstrip)
67     1 : int the imageid of the thumbnail
68     no returned value
69    */
70   DT_SIGNAL_VIEWMANAGER_THUMBTABLE_ACTIVATE,
71 
72   /** \brief This signal is raised when collection changed. To avoid leaking the list,
73     dt_collection_t is connected to this event and responsible of that.
74     1 : dt_collection_change_t the reason why the collection has changed
75     2 : dt_collection_properties_t the property that has changed
76     3 : GList of imageids that have changed (can be null if it's a global change)
77     4 : next untouched imgid in the list (-1 if no list)
78     no returned value
79     */
80   /** image list not to be freed by the caller, automatically freed */
81   DT_SIGNAL_COLLECTION_CHANGED,
82 
83   /** \brief This signal is raised when the selection is changed
84   no param, no returned value
85     */
86   DT_SIGNAL_SELECTION_CHANGED,
87 
88   /** \brief This signal is raised when a tag is added/deleted/changed  */
89   DT_SIGNAL_TAG_CHANGED,
90 
91   /** \brief This signal is raised when a geotag is added/deleted/changed  */
92   // when imgs <> NULL these images have some geotag changes
93   // when imgs == NULL locations have changed
94   // if locid <> 0 it the new selected location on map
95   DT_SIGNAL_GEOTAG_CHANGED,
96 
97   /** \brief This signal is raised when metadata status (shown/hidden) or value has changed */
98   DT_SIGNAL_METADATA_CHANGED,
99 
100   /** \brief This signal is raised when any of image info has changed  */
101   /** image list not to be freed by the caller, automatically freed */
102   // TODO check if tag and metadata could be included there
103   DT_SIGNAL_IMAGE_INFO_CHANGED,
104 
105   /** \brief This signal is raised when a style is added/deleted/changed  */
106   DT_SIGNAL_STYLE_CHANGED,
107 
108   /** \brief This signal is raised to request image order change */
109   DT_SIGNAL_IMAGES_ORDER_CHANGE,
110 
111   /** \brief This signal is raised when a filmroll is deleted/changed but not imported
112       \note when a filmroll is imported, use DT_SIGNALS_FILMOLLS_IMPORTED, as the gui
113        has to behave differently
114   */
115   DT_SIGNAL_FILMROLLS_CHANGED,
116 
117   /** \brief This signal is raised only when a filmroll is imported
118     1 :  int the film_id for the film that triggered the import. in case of recursion, other filmrolls might
119     be affected
120     no return
121    */
122   DT_SIGNAL_FILMROLLS_IMPORTED,
123 
124   /** \brief This signal is raised only when a filmroll is removed */
125   DT_SIGNAL_FILMROLLS_REMOVED,
126 
127   /* \brief This signal is raised when a preset is created/updated/deleted */
128   DT_SIGNAL_PRESETS_CHANGED,
129 
130   /** \brief This signal is raised when darktable.develop is initialized.
131       \note any modules that wants to access darktable->develop should connect
132       to this signal to be sure darktable.develop is initialized.
133   no param, no returned value
134    */
135   DT_SIGNAL_DEVELOP_INITIALIZE,
136 
137   /** \brief This signal is raised when a mipmap has been generated and flushed to cache
138     1 :  int the imgid of the mipmap
139     no returned value
140     */
141   DT_SIGNAL_DEVELOP_MIPMAP_UPDATED,
142 
143   /** \brief This signal is raised when develop preview pipe process is finished
144   no param, no returned value
145     */
146   DT_SIGNAL_DEVELOP_PREVIEW_PIPE_FINISHED,
147 
148   /** \brief This signal is raised when develop preview2 pipe process is finished
149   no param, no returned value
150     */
151   DT_SIGNAL_DEVELOP_PREVIEW2_PIPE_FINISHED,
152 
153   /** \brief This signal is raised when pipe is finished and the gui is attached
154   no param, no returned value
155     */
156   DT_SIGNAL_DEVELOP_UI_PIPE_FINISHED,
157 
158   /** \brief This signal is raised when develop history is about to be changed
159     1 : GList *  the current history
160     2 : uint32_t the correpsing history end
161     3 : GList *  the current iop-order list
162   no returned value
163     */
164   DT_SIGNAL_DEVELOP_HISTORY_WILL_CHANGE,
165 
166   /** \brief This signal is raised when develop history is changed
167   no param, no returned value
168     */
169   DT_SIGNAL_DEVELOP_HISTORY_CHANGE,
170 
171   /** \brief This signal is raised when a module is removed from the history stack
172     1 module
173     no returned value
174     */
175   DT_SIGNAL_DEVELOP_MODULE_REMOVE,
176 
177   /** \brief This signal is raised when order of modules in pipeline is changed */
178   DT_SIGNAL_DEVELOP_MODULE_MOVED,
179 
180   /** \brief This signal is raised when image is changed in darkroom */
181   DT_SIGNAL_DEVELOP_IMAGE_CHANGED,
182 
183   /** \brief This signal is raised when the screen profile has changed
184   no param, no returned value
185     */
186   DT_SIGNAL_CONTROL_PROFILE_CHANGED,
187 
188   /** \brief This signal is raised when a profile is changed by the user
189     1 uint32_t :  the profile type that has changed
190     no return
191     */
192   DT_SIGNAL_CONTROL_PROFILE_USER_CHANGED,
193 
194   /** \brief This signal is raised when a new image is imported (not cloned)
195     1 uint32_t :  the new image id
196     no return
197     */
198   DT_SIGNAL_IMAGE_IMPORT,
199 
200   /** \brief This signal is raised after an image has been exported
201     to a file, but before it is sent to facebook/picasa etc...
202     export won't happen until this function returns
203     1 int : the imgid exported
204     2 char* : the filename we exported to
205     3 dt_imageio_module_format_t* : the format used for export
206     4 dt_imageio_module_data_t* : the format's data
207     5 dt_imageio_module_storage_t* : the storage used for export (can be NULL)
208     6 dt_imageio_module_data_t* : the storage's data (can be NULL)
209     no return
210     */
211   DT_SIGNAL_IMAGE_EXPORT_TMPFILE,
212 
213   /** \brief This signal is raised when a new storage module is loaded
214     noparameters
215     no return
216     */
217   DT_SIGNAL_IMAGEIO_STORAGE_CHANGE,
218 
219   /** \brief This signal is raised after preferences have been changed
220     no parameters
221     no return
222     */
223   DT_SIGNAL_PREFERENCES_CHANGE,
224 
225   /** \brief This signal is raised when new gphoto2 cameras might have been detected
226     no return
227    * */
228   DT_SIGNAL_CAMERA_DETECTED,
229 
230   /** \brief This signal is raised when dt_control_navigation_redraw() is called.
231     no param, no returned value
232   */
233   DT_SIGNAL_CONTROL_NAVIGATION_REDRAW,
234 
235   /** \brief This signal is raised when dt_control_log_redraw() is called.
236     no param, no returned value
237   */
238   DT_SIGNAL_CONTROL_LOG_REDRAW,
239 
240   /** \brief This signal is raised when dt_control_toast_redraw() is called.
241     no param, no returned value
242   */
243   DT_SIGNAL_CONTROL_TOAST_REDRAW,
244 
245   /** \brief This signal is raised when new color picker data are available in the pixelpipe.
246     1 module
247     2 piece
248     no returned value
249   */
250   DT_SIGNAL_CONTROL_PICKERDATA_READY,
251 
252   /* \brief This signal is raised when metadata view needs update */
253   DT_SIGNAL_METADATA_UPDATE,
254 
255   /* \brief This signal is raised when a module is in trouble and message is to be displayed */
256   DT_SIGNAL_TROUBLE_MESSAGE,
257 
258   /* \brief This signal is raised when the user choses a new location from map (module location)*/
259   DT_SIGNAL_LOCATION_CHANGED,
260 
261   /* do not touch !*/
262   DT_SIGNAL_COUNT
263 } dt_signal_t;
264 
265 typedef enum dt_debug_signal_action_t
266 {
267   // powers of two, masking
268   DT_DEBUG_SIGNAL_ACT_RAISE       = 1 << 0,
269   DT_DEBUG_SIGNAL_ACT_CONNECT     = 1 << 1,
270   DT_DEBUG_SIGNAL_ACT_DISCONNECT  = 1 << 2,
271   DT_DEBUG_SIGNAL_ACT_PRINT_TRACE = 1 << 3,
272 } dt_debug_signal_action_t;
273 
274 /* inititialize the signal framework */
275 struct dt_control_signal_t *dt_control_signal_init();
276 /* raises a signal */
277 void dt_control_signal_raise(const struct dt_control_signal_t *ctlsig, const dt_signal_t signal, ...);
278 /* connects a callback to a signal */
279 void dt_control_signal_connect(const struct dt_control_signal_t *ctlsig, const dt_signal_t signal,
280                                GCallback cb, gpointer user_data);
281 /* disconnects a callback from a sink */
282 void dt_control_signal_disconnect(const struct dt_control_signal_t *ctlsig, GCallback cb, gpointer user_data);
283 /* blocks a callback */
284 void dt_control_signal_block_by_func(const struct dt_control_signal_t *ctlsig, GCallback cb, gpointer user_data);
285 /* unblocks a callback */
286 void dt_control_signal_unblock_by_func(const struct dt_control_signal_t *ctlsig, GCallback cb, gpointer user_data);
287 
288 #define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal, ...)                                                                       \
289   do                                                                                                                             \
290   {                                                                                                                              \
291     if((darktable.unmuted_signal_dbg_acts & DT_DEBUG_SIGNAL_ACT_RAISE) && darktable.unmuted_signal_dbg[signal])                 \
292     {                                                                                                                            \
293       dt_print(DT_DEBUG_SIGNAL, "[signal] %s:%d, function %s(): raise signal %s\n", __FILE__, __LINE__, __FUNCTION__, #signal);  \
294     }                                                                                                                            \
295     dt_control_signal_raise(ctlsig, signal, ##__VA_ARGS__);                                                                      \
296   } while (0)
297 
298 #define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)                                                           \
299   do                                                                                                                             \
300   {                                                                                                                              \
301     if((darktable.unmuted_signal_dbg_acts & DT_DEBUG_SIGNAL_ACT_CONNECT) && darktable.unmuted_signal_dbg[signal])                \
302     {                                                                                                                            \
303       dt_print(DT_DEBUG_SIGNAL, "[signal] %s:%d, function: %s() connect handler %s to signal %s\n", __FILE__, __LINE__,          \
304                __FUNCTION__, #cb, #signal);                                                                                      \
305     }                                                                                                                            \
306     dt_control_signal_connect(ctlsig, signal, cb, user_data);                                                                    \
307   } while (0)
308 
309 #define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)                                                                \
310   do                                                                                                                             \
311   {                                                                                                                              \
312     if(darktable.unmuted_signal_dbg_acts & DT_DEBUG_SIGNAL_ACT_DISCONNECT)                                                       \
313     {                                                                                                                            \
314       dt_print(DT_DEBUG_SIGNAL, "[signal] %s:%d, function: %s() disconnect handler %s\n", __FILE__, __LINE__, __FUNCTION__, #cb);\
315     }                                                                                                                            \
316     dt_control_signal_disconnect(ctlsig, cb, user_data);                                                                         \
317   } while (0)
318 
319 // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
320 // vim: shiftwidth=2 expandtab tabstop=2 cindent
321 // kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
322