69 return _(
"Duplicates");
74 static const char *
v[] = {
"darkroom", NULL};
92 const int32_t imgid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget),
"imgid"));
95 dt_metadata_set(imgid,
"Xmp.darktable.version_name", gtk_entry_get_text(GTK_ENTRY(widget)),
FALSE);
104 const int32_t imgid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),
"imgid"));
109 for(GList *l =
d->thumbs; l; l = g_list_next(l))
112 if(thumb->
info.
id == imgid)
114 GList *
l2 = g_list_next(l);
130 g_list_prepend(NULL, GINT_TO_POINTER(imgid)));
135 if(event->button == 1 && event->type == GDK_BUTTON_PRESS)
141 const int32_t imgid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget),
"imgid"));
142 if(imgid <= 0)
return FALSE;
148 if(
d->preview_cached_imgid != imgid)
173 if(event->type == GDK_LEAVE_NOTIFY && event->crossing.detail == GDK_NOTIFY_INFERIOR)
return FALSE;
189 if(
IS_NULL_PTR(
d) ||
d->imgid <= 0 ||
d->preview_cached_imgid !=
d->imgid)
return;
192 float image_box[4] = { 0.0f };
194 if(image_box[2] <= 0.0f || image_box[3] <= 0.0f)
return;
216 gtk_container_remove(GTK_CONTAINER(parent), thumb->
w_main);
250 "SELECT i.version, i.id, m.value"
252 " LEFT JOIN meta_data AS m ON m.id = i.id AND m.key = ?3"
253 " WHERE film_id = ?1 AND filename = ?2"
254 " ORDER BY i.version",
259 sqlite3_clear_bindings(stmt);
267 while(sqlite3_step(stmt) == SQLITE_ROW)
270 const int32_t imgid = sqlite3_column_int(stmt, 1);
280 gtk_widget_queue_draw(thumb->
widget);
284 g_object_set_data(G_OBJECT(thumb->
widget),
"imgid", GINT_TO_POINTER(imgid));
285 g_signal_connect(G_OBJECT(thumb->
widget),
"button-press-event",
287 g_signal_connect(G_OBJECT(thumb->
widget),
"button-release-event",
291 gtk_widget_add_events(thumb->
widget, GDK_LEAVE_NOTIFY_MASK);
292 g_signal_connect(G_OBJECT(thumb->
widget),
"leave-notify-event",
297 gchar *path = (gchar *)sqlite3_column_text(stmt, 2);
298 g_snprintf(chl,
sizeof(chl),
"%d", sqlite3_column_int(stmt, 0));
302 if(path) gtk_entry_set_text(GTK_ENTRY(tb), path);
303 gtk_entry_set_width_chars(GTK_ENTRY(tb), 0);
304 gtk_widget_set_hexpand(tb,
TRUE);
305 g_object_set_data (G_OBJECT(tb),
"imgid", GINT_TO_POINTER(imgid));
306 gtk_widget_add_events(tb, GDK_FOCUS_CHANGE_MASK);
309 gtk_widget_set_hexpand(lb,
TRUE);
312 g_object_set_data(G_OBJECT(bt),
"imgid", GINT_TO_POINTER(imgid));
315 gtk_grid_attach(GTK_GRID(hb), thumb->
widget, 0, 0, 1, 2);
316 gtk_grid_attach(GTK_GRID(hb), bt, 2, 0, 1, 1);
317 gtk_grid_attach(GTK_GRID(hb), lb, 1, 0, 1, 1);
318 gtk_grid_attach(GTK_GRID(hb), tb, 1, 1, 2, 1);
321 gtk_widget_show(thumb->
widget);
325 gtk_box_pack_start(GTK_BOX(
d->duplicate_box), hb,
FALSE,
FALSE, 0);
326 d->thumbs = g_list_append(
d->thumbs, thumb);
331 gtk_widget_show(
d->duplicate_box);
336 gtk_widget_set_sensitive(bt,
FALSE);
337 gtk_widget_set_visible(bt,
FALSE);
353 gtk_widget_queue_draw (
d->duplicate_box);
362 self->
data = (
void *)
d;
375 gtk_box_pack_start(GTK_BOX(self->
widget),
380 gtk_widget_show_all(self->
widget);
void dt_collection_update_query(const dt_collection_t *collection, dt_collection_change_t query_change, dt_collection_properties_t changed_property, GList *list)
dt_collection_properties_t
@ DT_COLLECTION_PROP_UNDEF
@ DT_COLLECTION_CHANGE_RELOAD
void dt_control_queue_redraw_center()
request redraw of center window. This redraws the center view within a gdk critical section to preven...
void dt_control_change_cursor_by_name_and_flush(const char *curs_str)
Apply a named cursor immediatelly and flush display updates for immediate feedback.
void dt_control_commit_cursor()
void dt_control_save_xmp(const int32_t imgid)
void dt_control_delete_image(int32_t imgid)
#define DT_MODULE(MODVER)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
sqlite3 * dt_database_get(const dt_database_t *db)
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_BIND_TEXT(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c)
void dt_dev_snapshot_draw(dt_dev_snapshot_t *snap, cairo_t *cri, struct dt_develop_t *dev, int32_t width, int32_t height, double clip_x, double clip_y, double clip_w, double clip_h)
void dt_dev_snapshot_clear(dt_dev_snapshot_t *snap)
gboolean dt_dev_snapshot_capture(dt_dev_snapshot_t *snap, int32_t imgid, float scale, GList *history_override, GList *iop_order_override, int32_t history_end_override)
void dt_dev_get_image_box_in_widget(const dt_develop_t *dev, const int32_t width, const int32_t height, float *box)
Get the displayed image rectangle in darkroom widget coordinates.
void dtgtk_cairo_paint_remove(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
static sqlite3_stmt * _duplicate_versions_stmt
static void _lib_duplicate_preview_updated_callback(gpointer instance, dt_lib_module_t *self)
static void _lib_duplicate_collection_changed(gpointer instance, dt_collection_change_t query_change, dt_collection_properties_t changed_property, gpointer imgs, int next, dt_lib_module_t *self)
static gboolean _lib_duplicate_thumb_revert_callback(GtkWidget *widget, GdkEvent *event, dt_lib_module_t *self)
static void _lib_duplicate_init_callback(gpointer instance, dt_lib_module_t *self)
void gui_cleanup(dt_lib_module_t *self)
static void _lib_duplicate_delete(GtkButton *button, dt_lib_module_t *self)
static void _thumb_remove(gpointer user_data)
uint32_t container(dt_lib_module_t *self)
void view_leave(struct dt_lib_module_t *self, struct dt_view_t *old_view, struct dt_view_t *new_view)
void gui_init(dt_lib_module_t *self)
const char ** views(dt_lib_module_t *self)
static gboolean _lib_duplicate_thumb_press_callback(GtkWidget *widget, GdkEventButton *event, dt_lib_module_t *self)
void gui_post_expose(dt_lib_module_t *self, cairo_t *cri, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
static gboolean _lib_duplicate_caption_out_callback(GtkWidget *widget, GdkEvent *event, dt_lib_module_t *self)
void dt_gui_container_destroy_children(GtkContainer *container)
GtkWidget * dt_ui_scroll_wrap(GtkWidget *w, gint min_size, char *config_str, dt_ui_resize_mode_t mode)
Wrap a scrollable content widget in a recessed, vertically resizable scrolled window.
void dt_accels_disconnect_on_text_input(GtkWidget *widget)
Disconnects accels when a text or search entry gets the focus, and reconnects them when it looses it....
void dt_gui_add_class(GtkWidget *widget, const gchar *class_name)
#define DT_GUI_BOX_SPACING
#define DT_PIXEL_APPLY_DPI(value)
void dt_control_signal_unblock_by_func(const struct dt_control_signal_t *ctlsig, GCallback cb, gpointer user_data)
void dt_control_signal_block_by_func(const struct dt_control_signal_t *ctlsig, GCallback cb, gpointer user_data)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ DT_SIGNAL_DEVELOP_INITIALIZE
This signal is raised when darktable.develop is initialized.
@ DT_SIGNAL_VIEWMANAGER_THUMBTABLE_ACTIVATE
@ DT_SIGNAL_DEVELOP_IMAGE_CHANGED
This signal is raised when image is changed in darkroom.
@ DT_SIGNAL_DEVELOP_PREVIEW_PIPE_FINISHED
This signal is raised when develop preview pipe process is finished no param, no returned value.
@ DT_SIGNAL_COLLECTION_CHANGED
This signal is raised when collection changed. To avoid leaking the list, dt_collection_t is connecte...
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
struct _GtkWidget GtkWidget
struct dt_collection_t * collection
const struct dt_database_t * db
struct dt_control_signal_t * signals
struct dt_develop_t * develop
char filename[DT_MAX_FILENAME_LEN]
int32_t preview_cached_imgid
dt_dev_snapshot_t preview
GtkWidget * duplicate_box
gboolean disable_mouseover
dt_thumbnail_t * dt_thumbnail_new(int rowid, dt_thumbnail_overlay_t over, dt_thumbtable_t *table, dt_image_t *info)
void dt_thumbnail_set_mouseover(dt_thumbnail_t *thumb, gboolean over)
int dt_thumbnail_destroy(dt_thumbnail_t *thumb)
void dt_thumbnail_update_selection(dt_thumbnail_t *thumb, gboolean selected)
void dt_thumbnail_resize(dt_thumbnail_t *thumb, int width, int height)
@ DT_THUMBNAIL_OVERLAYS_NONE
@ DT_UI_CONTAINER_PANEL_LEFT_CENTER