53#define DUPLICATE_COMPARE_SIZE 40
79 return _(
"Duplicates");
84 static const char *
v[] = {
"darkroom", NULL};
102 const int32_t imgid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget),
"imgid"));
105 dt_metadata_set(imgid,
"Xmp.darktable.version_name", gtk_entry_get_text(GTK_ENTRY(widget)),
FALSE);
114 const int32_t imgid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),
"imgid"));
119 for(GList *l =
d->thumbs; l; l = g_list_next(l))
122 if(thumb->
info.
id == imgid)
124 GList *
l2 = g_list_next(l);
140 g_list_prepend(NULL, GINT_TO_POINTER(imgid)));
145 if(event->button == 1)
147 if(event->type == GDK_BUTTON_PRESS)
179 cairo_surface_destroy(
d->preview_surf);
180 d->preview_surf = NULL;
192 gtk_container_remove(GTK_CONTAINER(parent), thumb->
w_main);
208 cairo_surface_destroy(
d->preview_surf);
209 d->preview_surf = NULL;
227 "SELECT i.version, i.id, m.value"
229 " LEFT JOIN meta_data AS m ON m.id = i.id AND m.key = ?3"
230 " WHERE film_id = ?1 AND filename = ?2"
231 " ORDER BY i.version",
236 sqlite3_clear_bindings(stmt);
244 while(sqlite3_step(stmt) == SQLITE_ROW)
247 const int32_t imgid = sqlite3_column_int(stmt, 1);
257 gtk_widget_queue_draw(thumb->
widget);
261 g_signal_connect(G_OBJECT(thumb->
widget),
"button-press-event",
263 g_signal_connect(G_OBJECT(thumb->
widget),
"button-release-event",
268 gchar *path = (gchar *)sqlite3_column_text(stmt, 2);
269 g_snprintf(chl,
sizeof(chl),
"%d", sqlite3_column_int(stmt, 0));
273 if(path) gtk_entry_set_text(GTK_ENTRY(tb), path);
274 gtk_entry_set_width_chars(GTK_ENTRY(tb), 0);
275 gtk_widget_set_hexpand(tb,
TRUE);
276 g_object_set_data (G_OBJECT(tb),
"imgid", GINT_TO_POINTER(imgid));
277 gtk_widget_add_events(tb, GDK_FOCUS_CHANGE_MASK);
280 gtk_widget_set_hexpand(lb,
TRUE);
283 g_object_set_data(G_OBJECT(bt),
"imgid", GINT_TO_POINTER(imgid));
286 gtk_grid_attach(GTK_GRID(hb), thumb->
widget, 0, 0, 1, 2);
287 gtk_grid_attach(GTK_GRID(hb), bt, 2, 0, 1, 1);
288 gtk_grid_attach(GTK_GRID(hb), lb, 1, 0, 1, 1);
289 gtk_grid_attach(GTK_GRID(hb), tb, 1, 1, 2, 1);
292 gtk_widget_show(thumb->
widget);
296 gtk_box_pack_start(GTK_BOX(
d->duplicate_box), hb,
FALSE,
FALSE, 0);
297 d->thumbs = g_list_append(
d->thumbs, thumb);
302 gtk_widget_show(
d->duplicate_box);
307 gtk_widget_set_sensitive(bt,
FALSE);
308 gtk_widget_set_visible(bt,
FALSE);
314 d->cur_final_width = 0;
315 d->cur_final_height = 0;
334 d->cur_final_width = 0;
335 d->cur_final_height = 0;
338 gtk_widget_queue_draw (
d->duplicate_box);
347 self->
data = (
void *)
d;
350 d->preview_surf = NULL;
351 d->preview_zoom = 1.0;
352 d->preview_width = 0;
353 d->preview_height = 0;
363 gtk_box_pack_start(GTK_BOX(self->
widget),
368 gtk_widget_show_all(self->
widget);
391 cairo_surface_destroy(
d->preview_surf);
392 d->preview_surf = NULL;
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_log_busy_leave()
void dt_control_toast_busy_leave()
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 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 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)
static gboolean _lib_duplicate_thumb_release_callback(GtkWidget *widget, GdkEventButton *event, 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)
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]
cairo_surface_t * preview_surf
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