81#include <gdk/gdkkeysyms.h>
85#ifdef GDK_WINDOWING_QUARTZ
180 N_(
"import timestamp"),
181 N_(
"change timestamp"),
182 N_(
"export timestamp"),
183 N_(
"print timestamp"),
194 N_(
"focus distance"),
204 "",
"",
"",
"",
"",
"",
"",
"",
220 return _(
"EXIF and IPTC");
225 static const char *
v[] = {
"darkroom",
"lighttable",
"map",
"print",
"slideshow",
"studio_capture", NULL};
260#define NODATA_STRING "-"
272 m->index =
m->order =
i;
274 d->metadata = g_list_prepend(
d->metadata,
m);
283 if(g_utf8_validate(
string, -1, 0))
return;
285 unsigned char *str = (
unsigned char *)
string;
288 while(*str !=
'\000' &&
n < length)
290 if((*str < 0x20) || (*str >= 0x7f)) *str =
'.';
303 if(
m->index == index)
316 GtkLabel *label = GTK_LABEL(gtk_grid_get_child_at(GTK_GRID(
d->grid), 1,
m->order));
317 char *markup = g_markup_printf_escaped(format, gtk_label_get_text(label));
318 gtk_label_set_markup(label, markup);
330 gchar *line = g_strdelimit(g_strdup(
value),
"\r\n",
' ');
331 gtk_label_set_text(GTK_LABEL(label), line);
339 gboolean validated = g_utf8_validate(
value, -1, NULL);
348 m->value = g_strdup(str);
349 GtkWidget *w_value = gtk_grid_get_child_at(GTK_GRID(
d->grid), 1,
m->order);
351 const char *
tooltip =
m->tooltip ?
m->tooltip :
m->value;
352 gtk_widget_set_tooltip_text(GTK_WIDGET(w_value),
tooltip);
392#define EMPTY_FIELD '.'
393#define FALSE_FIELD '.'
394#define TRUE_FIELD '!'
398 char *flags_tooltip = NULL;
399 char *flag_descriptions[] = { N_(
"unused"),
400 N_(
"unused/deprecated"),
404 N_(
"marked for deletion"),
405 N_(
"auto-applying presets applied"),
406 N_(
"legacy flag. set for all new images"),
412 char *tooltip_parts[
FLAG_NB] = { 0 };
413 int next_tooltip_part = 0;
417 int stars = img->
flags & 0x7;
418 char *star_string = NULL;
422 tooltip_parts[next_tooltip_part++] = _(
"image rejected");
426 value[0] =
'0' + stars;
427 tooltip_parts[next_tooltip_part++] = star_string = g_strdup_printf(ngettext(
"image has %d star",
"image has %d stars", stars), stars);
434 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[0]);
442 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[1]);
450 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[2]);
456 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[3]);
462 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[4]);
468 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[5]);
474 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[6]);
480 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[7]);
486 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[8]);
492 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[9]);
498 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[10]);
504 tooltip_parts[next_tooltip_part++] = _(flag_descriptions[11]);
510 tooltip_parts[next_tooltip_part++] = loader_tooltip;
514 flags_tooltip = g_strjoinv(
"\n", tooltip_parts);
518 (
void)g_strlcpy(
tooltip, flags_tooltip, tooltip_size);
553 skip[md] = (counts[md] > 1);
558 gboolean same_tags =
TRUE;
559 gboolean same_categories =
TRUE;
597 if(!have_thumb_info)
return;
599 if(img_id ==
d->imgid)
return;
608 for(int32_t md = 0; md <
md_size; md++)
629 char tooltip_filmroll[300] = {0};
630 g_strlcpy(text, tinfo.
filmroll,
sizeof(text));
631 snprintf(tooltip_filmroll,
sizeof(tooltip_filmroll), _(
"double-click to jump to film roll\n%s"), text);
638 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
film_id);
643 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
id);
648 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
group_id);
657 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
version);
663 g_strlcpy(text, tinfo.
fullpath,
sizeof(text));
692 char tooltip_flags[300] = {0};
762 const gboolean milliseconds =
dt_conf_get_bool(
"lighttable/ui/milliseconds");
772 (
void)g_snprintf(text,
sizeof(text),
"%d (%d)", tinfo.
p_width, tinfo.
width);
777 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
width);
790 (
void)g_snprintf(text,
sizeof(text),
"%d", tinfo.
height);
867 char *tagstring = NULL;
868 char *categoriesstring = NULL;
871 for(GList *taglist = tags; taglist; taglist = g_list_next(taglist))
873 const char *tagname = ((
dt_tag_t *)taglist->data)->leave;
882 char *category = g_strdup(((
dt_tag_t *)taglist->data)->tag);
883 char *catend = g_strrstr(category,
"|");
887 char *catstart = g_strrstr(category,
"|");
888 catstart = catstart ? catstart + 1 : category;
890 !
IS_NULL_PTR(categoriesstring) ?
", %s: %s" :
"%s: %s",
891 catstart, ((
dt_tag_t *)taglist->data)->leave);
896 ((
dt_tag_t *)taglist->data)->leave);
930 g_strlcpy(text, (
char *)
res->data,
sizeof(text));
959 snprintf(collect,
sizeof(collect),
"1:0:0:%s$", path);
966 if(event->type != GDK_2BUTTON_PRESS)
return FALSE;
993 pref[strlen(pref) - 1] =
'\0';
1009 GtkWidget *w_name = gtk_grid_get_child_at(GTK_GRID(
d->grid), 0, j);
1010 gtk_label_set_text(GTK_LABEL(w_name), _(
m->name));
1011 gtk_widget_set_tooltip_text(w_name, _(
m->name));
1012 GtkWidget *w_value = gtk_grid_get_child_at(GTK_GRID(
d->grid), 1, j);
1014 const char *
tooltip =
m->tooltip ?
m->tooltip :
m->value;
1015 gtk_widget_set_tooltip_text(w_value,
tooltip);
1017 const int i =
m->index;
1018 gtk_label_set_ellipsize(GTK_LABEL(w_value),
1020 ? PANGO_ELLIPSIZE_END : PANGO_ELLIPSIZE_MIDDLE);
1024 if(
d->filmroll_event && GTK_IS_WIDGET(
d->filmroll_event))
1025 g_signal_handlers_disconnect_by_func(
d->filmroll_event, G_CALLBACK(
_filmroll_clicked), NULL);
1026 g_signal_connect(G_OBJECT(w_value),
"button-press-event", G_CALLBACK(
_filmroll_clicked), NULL);
1027 d->filmroll_event = G_OBJECT(w_value);
1030 gtk_widget_set_visible(w_name,
m->visible);
1031 gtk_widget_set_visible(w_value,
m->visible);
1045 GtkWidget *w_name = gtk_label_new(_(
m->name));
1046 gtk_widget_set_halign(w_name, GTK_ALIGN_START);
1047 gtk_label_set_xalign(GTK_LABEL(w_name), 0.0f);
1048 gtk_label_set_ellipsize(GTK_LABEL(w_name), PANGO_ELLIPSIZE_END);
1049 gtk_widget_set_tooltip_text(w_name, _(
m->name));
1052 gtk_widget_set_name(w_value,
"brightbg");
1053 gtk_label_set_selectable(GTK_LABEL(w_value),
TRUE);
1054 gtk_widget_set_halign(w_value, GTK_ALIGN_FILL);
1055 gtk_label_set_xalign(GTK_LABEL(w_value), 0.0f);
1057 gtk_grid_attach(GTK_GRID(
d->grid), w_name, 0, j, 1, 1);
1058 gtk_grid_attach(GTK_GRID(
d->grid), w_value, 1, j, 1, 1);
1065 if(!prefs_list || !prefs_list[0])
return;
1070 for(GList *pref = prefs; pref; pref = g_list_next(pref))
1072 const char *
name = (
char *)pref->data;
1073 gboolean visible =
TRUE;
1087 m->visible = visible;
1110 GtkListStore *
store = (GtkListStore *)user_data;
1112 GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
1115 gtk_tree_model_get_iter(GTK_TREE_MODEL(
store), &iter, path);
1119 gtk_tree_path_free(path);
1122static void _drag_data_inserted(GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
1132 GtkWidget *dialog = gtk_dialog_new_with_buttons(_(
"metadata settings"), GTK_WINDOW(win),
1133 GTK_DIALOG_DESTROY_WITH_PARENT, _(
"default"), GTK_RESPONSE_YES,
1134 _(
"cancel"), GTK_RESPONSE_NONE, _(
"save"), GTK_RESPONSE_ACCEPT, NULL);
1136 GtkWidget *area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
1138 GtkWidget *w = gtk_scrolled_window_new(NULL, NULL);
1140 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(w), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1141 gtk_scrolled_window_set_overlay_scrolling(GTK_SCROLLED_WINDOW(w),
FALSE);
1143 gtk_box_pack_start(GTK_BOX(area), w,
TRUE,
TRUE, 0);
1146 G_TYPE_INT, G_TYPE_STRING, G_TYPE_BOOLEAN);
1156 gtk_list_store_append(
store, &iter);
1157 gtk_list_store_set(
store, &iter,
1165 g_object_unref(
model);
1166 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
1167 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_(
"metadata"), renderer,
1169 gtk_tree_view_column_set_expand(column,
TRUE);
1170 gtk_tree_view_append_column(GTK_TREE_VIEW(
view), column);
1171 GtkWidget *header = gtk_tree_view_column_get_button(column);
1172 gtk_widget_set_tooltip_text(header,
1173 _(
"drag and drop one row at a time until you get the desired order"
1174 "\nuntick to hide metadata which are not of interest for you"
1175 "\nif different settings are needed, use presets"));
1176 renderer = gtk_cell_renderer_toggle_new();
1178 column = gtk_tree_view_column_new_with_attributes(_(
"visible"), renderer,
1180 gtk_tree_view_append_column(GTK_TREE_VIEW(
view), column);
1183 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(
view),
TRUE);
1186 gtk_container_add(GTK_CONTAINER(w),
view);
1188#ifdef GDK_WINDOWING_QUARTZ
1191 gtk_widget_show_all(dialog);
1193 int res = gtk_dialog_run(GTK_DIALOG(dialog));
1194 while(
res == GTK_RESPONSE_YES)
1196 gtk_tree_model_get_iter_first(
model, &iter);
1203 gtk_list_store_set(
store, &iter,
1208 gtk_tree_model_iter_next(
model, &iter);
1210 res = gtk_dialog_run(GTK_DIALOG(dialog));
1214 if(
res == GTK_RESPONSE_ACCEPT)
1216 gboolean valid = gtk_tree_model_get_iter_first(
model, &iter);
1221 gtk_tree_model_get(
model, &iter,
1228 if(
m->index == index)
1231 m->visible = visible;
1236 valid = gtk_tree_model_iter_next(
model, &iter);
1242 gtk_widget_destroy(dialog);
1247 GtkWidget *mi = gtk_menu_item_new_with_label(_(
"preferences..."));
1249 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1277 m->order =
m->index;
1287 self->
data = (
void *)
d;
1292 GtkWidget *child_grid_window = gtk_grid_new();
1293 d->grid = child_grid_window;
1300 gtk_widget_show_all(
d->grid);
1301 gtk_widget_set_no_show_all(
d->grid,
TRUE);
1346 m->order =
m->index;
int32_t dt_act_on_get_first_image()
GtkWidget * dt_gui_main_window(void)
struct dt_ui_t * dt_gui_get_ui(void)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_collection_deserialize(const char *buf)
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
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)
Borrow the stored string for name without copying it.
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)
int32_t dt_control_get_mouse_over_id()
struct dt_gui_gtk_t * dt_gui_get_global(void)
gboolean dt_datetime_gtimespan_to_local(char *local, const size_t local_size, const GTimeSpan gts, const gboolean msec, const gboolean tz)
GtkTreeStore * store
its model, owned by the view
GHashTable * selected
set of checked row labels, mirrored to conf on every change
GtkWidget * view
the tree view
static const struct @4 loaders_info[LOADER_COUNT]
@ DT_IMAGE_NO_LEGACY_PRESETS
@ DT_IMAGE_AUTO_PRESETS_APPLIED
@ DT_IMAGE_THUMBNAIL_DEPRECATED
dt_image_t * dt_image_cache_get(const int32_t imgid, char mode)
void dt_image_cache_read_release(const dt_image_t *img)
int * dt_image_repository_count_distinct_fields(GList *imgids)
How many DISTINCT values each dt_image_field_t takes over imgids.
Reading and writing one dt_image_t to and from the library database. The SQL half of what used to be ...
static CameraMetaData * meta
static const dt_iop_drawlayer_params_t * params
gboolean dt_handle_dialog_enter(GtkWidget *widget, GdkEventKey *event, gpointer data)
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
dt_mipmap_buffer_dsc_flags flags
#define DT_MODULE(MODVER)
Instantiate the version handshake every module must export. Use once, at file scope,...
void dt_osx_disallow_fullscreen(GtkWidget *widget)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
int32_t dt_selection_get_first_id(struct dt_selection_t *selection)
struct dt_selection_t * dt_selection_get_global(void)
int dt_selection_get_length(struct dt_selection_t *selection)
GList * dt_selection_get_list(struct dt_selection_t *selection)
int32_t dt_selection_repository_get_lowest_id(void)
The lowest selected image id, or UNKNOWN_IMAGE when nothing is selected.
main.selected_images, and the memory.selected_backup it is pushed onto.
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ 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)
static const dt_aligned_pixel_simd_t value
GTimeSpan export_timestamp
float exif_focus_distance
GTimeSpan import_timestamp
GTimeSpan change_timestamp
GTimeSpan print_timestamp
GTimeSpan exif_datetime_taken
char filmroll[DT_PATH_MAX]
char filename[DT_MAX_FILENAME_LEN]
char fullpath[DT_PATH_MAX]
void dt_tag_repository_get_agreement(GList *imgids, gboolean *same_tags, gboolean *same_categories)
Do all of imgids carry exactly the same tags? The same categories?
data.tags and main.tagged_images.
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