71#include <gdk/gdkkeysyms.h>
73#ifdef GDK_WINDOWING_QUARTZ
168 N_(
"import timestamp"),
169 N_(
"change timestamp"),
170 N_(
"export timestamp"),
171 N_(
"print timestamp"),
182 N_(
"focus distance"),
192 "",
"",
"",
"",
"",
"",
"",
"",
208 return _(
"EXIF and IPTC");
213 static const char *
v[] = {
"darkroom",
"lighttable",
"map",
"print",
"slideshow", NULL};
248#define NODATA_STRING "-"
260 m->index =
m->order =
i;
262 d->metadata = g_list_prepend(
d->metadata,
m);
271 if(g_utf8_validate(
string, -1, 0))
return;
273 unsigned char *str = (
unsigned char *)
string;
276 while(*str !=
'\000' &&
n < length)
278 if((*str < 0x20) || (*str >= 0x7f)) *str =
'.';
291 if(
m->index == index)
304 GtkLabel *label = GTK_LABEL(gtk_grid_get_child_at(GTK_GRID(
d->grid), 1,
m->order));
305 char *markup = g_markup_printf_escaped(format, gtk_label_get_text(label));
306 gtk_label_set_markup(label, markup);
314 gboolean validated = g_utf8_validate(
value, -1, NULL);
323 m->value = g_strdup(str);
324 GtkWidget *w_value = gtk_grid_get_child_at(GTK_GRID(
d->grid), 1,
m->order);
325 gtk_label_set_text(GTK_LABEL(w_value), str);
326 const char *
tooltip =
m->tooltip ?
m->tooltip :
m->value;
327 gtk_widget_set_tooltip_text(GTK_WIDGET(w_value),
tooltip);
367#define EMPTY_FIELD '.'
368#define FALSE_FIELD '.'
369#define TRUE_FIELD '!'
373 char *flags_tooltip = NULL;
374 char *flag_descriptions[] = { N_(
"unused"),
375 N_(
"unused/deprecated"),
379 N_(
"marked for deletion"),
380 N_(
"auto-applying presets applied"),
381 N_(
"legacy flag. set for all new images"),
387 char *tooltip_parts[
FLAG_NB] = { 0 };
388 int next_tooltip_part = 0;
392 int stars = img->
flags & 0x7;
393 char *star_string = NULL;
397 tooltip_parts[next_tooltip_part++] = _(
"image rejected");
401 value[0] =
'0' + stars;
402 tooltip_parts[next_tooltip_part++] = star_string = g_strdup_printf(ngettext(
"image has %d star",
"image has %d stars", stars), stars);
409 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[0]);
417 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[1]);
425 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[2]);
431 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[3]);
437 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[4]);
443 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[5]);
449 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[6]);
455 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[7]);
461 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[8]);
467 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[9]);
473 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[10]);
479 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[11]);
485 tooltip_parts[next_tooltip_part++] = loader_tooltip;
489 flags_tooltip = g_strjoinv(
"\n", tooltip_parts);
493 (
void)g_strlcpy(
tooltip, flags_tooltip, tooltip_size);
520 sqlite3_stmt *stmt = NULL;
522 gchar *query = g_strdup_printf(
"SELECT COUNT(DISTINCT film_id), "
523 "COUNT(DISTINCT film_id), "
525 "COUNT(DISTINCT group_id), "
526 "COUNT(DISTINCT filename), "
527 "COUNT(DISTINCT version), "
528 "COUNT(DISTINCT film_id || '/' || filename), "
529 "COUNT(DISTINCT flags & 2048), "
530 "COUNT(DISTINCT import_timestamp), "
531 "COUNT(DISTINCT change_timestamp), "
532 "COUNT(DISTINCT export_timestamp), "
533 "COUNT(DISTINCT print_timestamp), "
534 "COUNT(DISTINCT flags), "
535 "COUNT(DISTINCT model), "
536 "COUNT(DISTINCT maker), "
537 "COUNT(DISTINCT lens), "
538 "COUNT(DISTINCT aperture), "
539 "COUNT(DISTINCT exposure), "
540 "COUNT(DISTINCT IFNULL(exposure_bias, '')), "
541 "COUNT(DISTINCT focal_length), "
542 "COUNT(DISTINCT focus_distance), "
543 "COUNT(DISTINCT iso), "
544 "COUNT(DISTINCT datetime_taken), "
545 "COUNT(DISTINCT width), "
546 "COUNT(DISTINCT height), "
547 "COUNT(DISTINCT IFNULL(output_width, '')), "
548 "COUNT(DISTINCT IFNULL(output_height, '')), "
549 "(SELECT COUNT(DISTINCT IFNULL(value,'')) FROM images LEFT JOIN meta_data ON meta_data.id = images.id AND key = 2 WHERE images.id in (%s)), "
550 "(SELECT COUNT(DISTINCT IFNULL(value,'')) FROM images LEFT JOIN meta_data ON meta_data.id = images.id AND key = 3 WHERE images.id in (%s)), "
551 "(SELECT COUNT(DISTINCT IFNULL(value,'')) FROM images LEFT JOIN meta_data ON meta_data.id = images.id AND key = 0 WHERE images.id in (%s)), "
552 "(SELECT COUNT(DISTINCT IFNULL(value,'')) FROM images LEFT JOIN meta_data ON meta_data.id = images.id AND key = 1 WHERE images.id in (%s)), "
553 "(SELECT COUNT(DISTINCT IFNULL(value,'')) FROM images LEFT JOIN meta_data ON meta_data.id = images.id AND key = 4 WHERE images.id in (%s)), "
554 "(SELECT COUNT(DISTINCT IFNULL(value,'')) FROM images LEFT JOIN meta_data ON meta_data.id = images.id AND key = 5 WHERE images.id in (%s)), "
555 "(SELECT COUNT(DISTINCT IFNULL(value,'')) FROM images LEFT JOIN meta_data ON meta_data.id = images.id AND key = 6 WHERE images.id in (%s)), "
556 "(SELECT COUNT(DISTINCT IFNULL(value,'')) FROM images LEFT JOIN meta_data ON meta_data.id = images.id AND key = 7 WHERE images.id in (%s)), "
557 "COUNT(DISTINCT IFNULL(latitude, '')), "
558 "COUNT(DISTINCT IFNULL(longitude, '')), "
559 "COUNT(DISTINCT IFNULL(altitude, '')) "
562 images, images, images, images, images, images, images, images, images);
567 sqlite3_stmt *stmt_tags = NULL;
569 gchar *tag_query = g_strdup_printf(
"SELECT flags, COUNT(DISTINCT imgid) "
570 "FROM main.tagged_images "
572 "ON data.tags.id = main.tagged_images.tagid AND name NOT LIKE 'darktable|%%' "
573 "WHERE imgid in (%s) GROUP BY tagid", images);
579 if(sqlite3_step(stmt) == SQLITE_ROW)
581 const int col_count = sqlite3_column_count(stmt);
582 for(int32_t md = 0; md <
md_tag_names && md < col_count; md++)
583 skip[md] = (sqlite3_column_int(stmt, md) > 1);
586 sqlite3_finalize(stmt);
589 gboolean same_tags =
TRUE;
590 gboolean same_categories =
TRUE;
592 while(sqlite3_step(stmt_tags) == SQLITE_ROW)
595 same_categories &= (sqlite3_column_int(stmt_tags, 1) == count);
597 same_tags &= (sqlite3_column_int(stmt_tags, 1) == count);
603 sqlite3_finalize(stmt_tags);
636 if(!have_thumb_info)
return;
638 if(img_id ==
d->imgid)
return;
647 for(int32_t md = 0; md <
md_size; md++)
668 char tooltip_filmroll[300] = {0};
669 g_strlcpy(text, tinfo.
filmroll,
sizeof(text));
670 snprintf(tooltip_filmroll,
sizeof(tooltip_filmroll), _(
"double-click to jump to film roll\n%s"), text);
677 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
film_id);
682 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
id);
687 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
group_id);
696 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
version);
702 g_strlcpy(text, tinfo.
fullpath,
sizeof(text));
731 char tooltip_flags[300] = {0};
801 const gboolean milliseconds =
dt_conf_get_bool(
"lighttable/ui/milliseconds");
811 (
void)g_snprintf(text,
sizeof(text),
"%d (%d)", tinfo.
p_width, tinfo.
width);
816 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
width);
829 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
height);
906 char *tagstring = NULL;
907 char *categoriesstring = NULL;
911 for(GList *taglist = tags; taglist; taglist = g_list_next(taglist))
913 const char *tagname = ((
dt_tag_t *)taglist->data)->leave;
917 length = length + strlen(tagname) + 2u;
923 length = strlen(tagname) + 2u;
929 char *category = g_strdup(((
dt_tag_t *)taglist->data)->tag);
930 char *catend = g_strrstr(category,
"|");
934 char *catstart = g_strrstr(category,
"|");
935 catstart = catstart ? catstart + 1 : category;
936 categoriesstring =
dt_util_dstrcat(categoriesstring, categoriesstring ?
"\n%s: %s " :
"%s: %s ",
937 catstart, ((
dt_tag_t *)taglist->data)->leave);
940 categoriesstring =
dt_util_dstrcat(categoriesstring, categoriesstring ?
"\n%s" :
"%s",
941 ((
dt_tag_t *)taglist->data)->leave);
945 if(tagstring) tagstring[strlen(tagstring)-2] =
'\0';
976 g_strlcpy(text, (
char *)res->data,
sizeof(text));
1003 if(sqlite3_step(stmt) == SQLITE_ROW) imgid = sqlite3_column_int(stmt, 0);
1004 sqlite3_finalize(stmt);
1013 snprintf(collect,
sizeof(collect),
"1:0:0:%s$", path);
1020 if(event->type != GDK_2BUTTON_PRESS)
return FALSE;
1047 pref[strlen(pref) - 1] =
'\0';
1063 GtkWidget *w_name = gtk_grid_get_child_at(GTK_GRID(
d->grid), 0, j);
1064 gtk_label_set_text(GTK_LABEL(w_name), _(
m->name));
1065 gtk_widget_set_tooltip_text(w_name, _(
m->name));
1066 GtkWidget *w_value = gtk_grid_get_child_at(GTK_GRID(
d->grid), 1, j);
1067 gtk_label_set_text(GTK_LABEL(w_value),
m->value);
1068 const char *
tooltip =
m->tooltip ?
m->tooltip :
m->value;
1069 gtk_widget_set_tooltip_text(w_value,
tooltip);
1071 const int i =
m->index;
1072 gtk_label_set_ellipsize(GTK_LABEL(w_value),
1074 ? PANGO_ELLIPSIZE_END : PANGO_ELLIPSIZE_MIDDLE);
1078 if(
d->filmroll_event && GTK_IS_WIDGET(
d->filmroll_event))
1079 g_signal_handlers_disconnect_by_func(
d->filmroll_event, G_CALLBACK(
_filmroll_clicked), NULL);
1080 g_signal_connect(G_OBJECT(w_value),
"button-press-event", G_CALLBACK(
_filmroll_clicked), NULL);
1081 d->filmroll_event = G_OBJECT(w_value);
1084 gtk_widget_set_visible(w_name,
m->visible);
1085 gtk_widget_set_visible(w_value,
m->visible);
1099 GtkWidget *w_name = gtk_label_new(_(
m->name));
1100 gtk_widget_set_halign(w_name, GTK_ALIGN_START);
1101 gtk_label_set_xalign(GTK_LABEL(w_name), 0.0f);
1102 gtk_label_set_ellipsize(GTK_LABEL(w_name), PANGO_ELLIPSIZE_END);
1103 gtk_widget_set_tooltip_text(w_name, _(
m->name));
1106 gtk_widget_set_name(w_value,
"brightbg");
1107 gtk_label_set_selectable(GTK_LABEL(w_value),
TRUE);
1108 gtk_widget_set_halign(w_value, GTK_ALIGN_FILL);
1109 gtk_label_set_xalign(GTK_LABEL(w_value), 0.0f);
1111 gtk_grid_attach(GTK_GRID(
d->grid), w_name, 0, j, 1, 1);
1112 gtk_grid_attach(GTK_GRID(
d->grid), w_value, 1, j, 1, 1);
1119 if(!prefs_list || !prefs_list[0])
return;
1124 for(GList *pref = prefs; pref; pref = g_list_next(pref))
1126 const char *
name = (
char *)pref->data;
1127 gboolean visible =
TRUE;
1141 m->visible = visible;
1164 GtkListStore *
store = (GtkListStore *)user_data;
1166 GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
1169 gtk_tree_model_get_iter(GTK_TREE_MODEL(
store), &iter, path);
1173 gtk_tree_path_free(path);
1176static void _drag_data_inserted(GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
1186 GtkWidget *dialog = gtk_dialog_new_with_buttons(_(
"metadata settings"), GTK_WINDOW(win),
1187 GTK_DIALOG_DESTROY_WITH_PARENT, _(
"default"), GTK_RESPONSE_YES,
1188 _(
"cancel"), GTK_RESPONSE_NONE, _(
"save"), GTK_RESPONSE_ACCEPT, NULL);
1190 GtkWidget *area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
1192 GtkWidget *w = gtk_scrolled_window_new(NULL, NULL);
1194 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(w), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1195 gtk_scrolled_window_set_overlay_scrolling(GTK_SCROLLED_WINDOW(w),
FALSE);
1197 gtk_box_pack_start(GTK_BOX(area), w,
TRUE,
TRUE, 0);
1200 G_TYPE_INT, G_TYPE_STRING, G_TYPE_BOOLEAN);
1210 gtk_list_store_append(
store, &iter);
1211 gtk_list_store_set(
store, &iter,
1219 g_object_unref(
model);
1220 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
1221 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_(
"metadata"), renderer,
1223 gtk_tree_view_column_set_expand(column,
TRUE);
1224 gtk_tree_view_append_column(GTK_TREE_VIEW(
view), column);
1225 GtkWidget *header = gtk_tree_view_column_get_button(column);
1226 gtk_widget_set_tooltip_text(header,
1227 _(
"drag and drop one row at a time until you get the desired order"
1228 "\nuntick to hide metadata which are not of interest for you"
1229 "\nif different settings are needed, use presets"));
1230 renderer = gtk_cell_renderer_toggle_new();
1232 column = gtk_tree_view_column_new_with_attributes(_(
"visible"), renderer,
1234 gtk_tree_view_append_column(GTK_TREE_VIEW(
view), column);
1237 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(
view),
TRUE);
1240 gtk_container_add(GTK_CONTAINER(w),
view);
1242#ifdef GDK_WINDOWING_QUARTZ
1245 gtk_widget_show_all(dialog);
1247 int res = gtk_dialog_run(GTK_DIALOG(dialog));
1248 while(res == GTK_RESPONSE_YES)
1250 gtk_tree_model_get_iter_first(
model, &iter);
1257 gtk_list_store_set(
store, &iter,
1262 gtk_tree_model_iter_next(
model, &iter);
1264 res = gtk_dialog_run(GTK_DIALOG(dialog));
1268 if(res == GTK_RESPONSE_ACCEPT)
1270 gboolean valid = gtk_tree_model_get_iter_first(
model, &iter);
1275 gtk_tree_model_get(
model, &iter,
1282 if(
m->index == index)
1285 m->visible = visible;
1290 valid = gtk_tree_model_iter_next(
model, &iter);
1296 gtk_widget_destroy(dialog);
1301 GtkWidget *mi = gtk_menu_item_new_with_label(_(
"preferences..."));
1303 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1311 *
size =strlen(params) + 1;
1331 m->order =
m->index;
1341 self->
data = (
void *)
d;
1346 GtkWidget *child_grid_window = gtk_grid_new();
1347 d->grid = child_grid_window;
1354 gtk_widget_show_all(
d->grid);
1355 gtk_widget_set_no_show_all(
d->grid,
TRUE);
1400 m->order =
m->index;
int32_t dt_act_on_get_first_image()
void dt_collection_deserialize(const char *buf)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
gboolean dt_image_is_raw(const dt_image_t *img)
int dt_image_monochrome_flags(const dt_image_t *img)
gboolean dt_image_is_hdr(const dt_image_t *img)
gboolean dt_image_is_ldr(const dt_image_t *img)
void dt_image_film_roll_directory(const dt_image_t *img, char *pathname, size_t pathname_len)
int dt_conf_get_bool(const char *name)
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
int32_t dt_control_get_mouse_over_id()
uint32_t view(const dt_view_t *self)
#define DT_MODULE(MODVER)
static void dt_free_gpointer(gpointer ptr)
static const dt_aligned_pixel_simd_t value
#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)
gboolean dt_datetime_gtimespan_to_local(char *local, const size_t local_size, const GTimeSpan gts, const gboolean msec, const gboolean tz)
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int32_t imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean export_masks, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent, dt_export_metadata_t *metadata)
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_gui_add_class(GtkWidget *widget, const gchar *class_name)
GtkWidget * dt_ui_main_window(dt_ui_t *ui)
get the main window widget
#define DT_GUI_BOX_SPACING
#define DT_PIXEL_APPLY_DPI(value)
@ DT_IMAGE_NO_LEGACY_PRESETS
@ DT_IMAGE_AUTO_PRESETS_APPLIED
@ DT_IMAGE_THUMBNAIL_DEPRECATED
static const struct @7 loaders_info[LOADER_COUNT]
void dt_image_cache_read_release(dt_image_cache_t *cache, const dt_image_t *img)
dt_image_t * dt_image_cache_get(dt_image_cache_t *cache, const int32_t imgid, char mode)
static CameraMetaData * meta
gboolean dt_handle_dialog_enter(GtkWidget *widget, GdkEventKey *event, gpointer data)
float *const restrict const size_t k
dt_mipmap_buffer_dsc_flags flags
void dt_osx_disallow_fullscreen(GtkWidget *widget)
int32_t dt_selection_get_first_id(struct dt_selection_t *selection)
gchar * dt_selection_ids_to_string(struct dt_selection_t *selection)
int dt_selection_get_length(struct dt_selection_t *selection)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
@ DT_SIGNAL_MOUSE_OVER_IMAGE_CHANGE
This signal is raised when mouse hovers over image thumbs both on lighttable and in the filmstrip....
@ DT_SIGNAL_SELECTION_CHANGED
This signal is raised when the selection is changed no param, no returned value.
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
struct _GtkWidget GtkWidget
unsigned __int64 uint64_t
struct dt_gui_gtk_t * gui
struct dt_selection_t * selection
const struct dt_database_t * db
struct dt_control_signal_t * signals
struct dt_image_cache_t * image_cache
GTimeSpan export_timestamp
float exif_focus_distance
GTimeSpan import_timestamp
GTimeSpan change_timestamp
GTimeSpan print_timestamp
GTimeSpan exif_datetime_taken
char filename[DT_MAX_FILENAME_LEN]
dt_thumbtable_t * thumbtable_lighttable
dt_thumbtable_t * thumbtable_filmstrip
typedef double((*spd)(unsigned long int wavelength, double TempK))
gboolean dt_thumbtable_get_thumbnail_info(dt_thumbtable_t *table, int32_t imgid, dt_image_t *out)
gchar * dt_util_longitude_str(float longitude)
gchar * dt_util_elevation_str(float elevation)
GList * dt_util_str_to_glist(const gchar *separator, const gchar *text)
char * dt_util_format_exposure(const float exposuretime)
gchar * dt_util_latitude_str(float latitude)
gchar * dt_util_dstrcat(gchar *str, const gchar *format,...)
@ DT_UI_CONTAINER_PANEL_LEFT_CENTER