64#ifdef GDK_WINDOWING_QUARTZ
67#include <gdk/gdkkeysyms.h>
96 static const char *
v[] = {
"lighttable",
"tethering",
"studio_capture", NULL};
110 return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(textview),
"tv_multiple"));
115 GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview);
116 GtkTextIter start, end;
117 gtk_text_buffer_get_bounds(buffer, &start, &end);
118 return gtk_text_buffer_get_text(buffer, &start, &end,
TRUE);
123 GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview);
124 GtkTextIter start, end;
125 gtk_text_buffer_get_bounds(buffer, &start, &end);
126 gtk_text_buffer_select_range(buffer,
selected ? &start : &end, &end);
131 GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview);
132 GtkTextIter start, end;
133 gtk_text_buffer_get_bounds(buffer, &start, &end);
135 gtk_text_buffer_apply_tag_by_name(buffer,
"italic", &start, &end);
137 gtk_text_buffer_remove_tag_by_name(buffer,
"italic", &start, &end);
142 g_signal_handlers_block_matched(buffer, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
_textbuffer_changed, NULL);
143 gtk_text_buffer_set_text(buffer, text, -1);
144 g_signal_handlers_unblock_matched(buffer, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
_textbuffer_changed, NULL);
150 gboolean multi =
FALSE;
152 GtkTextBuffer *buffer = gtk_text_view_get_buffer(
d->textview[
i]);
166 g_object_set_data(G_OBJECT(
d->textview[
i]),
"tv_multiple", GINT_TO_POINTER(multi));
180 const uint32_t count)
199 if(!
d->editing)
return;
203 if(!
IS_NULL_PTR(
d->textview[
i]) && gtk_widget_has_focus(GTK_WIDGET(
d->textview[
i])))
225 if(imgs &&
d->last_act_on)
227 const GList *l =
d->last_act_on;
228 const GList *ll = imgs;
229 while(l && ll && GPOINTER_TO_INT(l->data) == GPOINTER_TO_INT(ll->data))
232 ll = g_list_next(ll);
247 g_list_free(
d->last_act_on);
248 d->last_act_on = imgs;
264 metadata_count[
i] = 0;
269 const uint32_t imgs_count = g_list_length(
d->last_act_on);
274 .imgs_count = imgs_count };
284 d->metadata_list[
i] = metadata[keyid];
285 metadata[keyid] = NULL;
292 metadata[
key] = NULL;
295 gtk_widget_set_sensitive(GTK_WIDGET(
d->apply_button), imgs_count > 0);
305 *l = g_list_append(*l, (gchar *)
key);
306 *l = g_list_append(*l, (gchar *)
value);
325 GList *key_value = NULL;
328 const int i = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(textview),
"tv_index"));
339 const GList *imgs =
d->last_act_on;
348 for(GList *l = key_value; l; l = l->next)
353 g_list_free(key_value);
376 event->state &= ~DT_PRIMARY_MASK;
393 case GDK_KEY_ISO_Left_Tab:
414 return gtk_text_view_im_context_filter_keypress(GTK_TEXT_VIEW(textview), event);
421 GtkTextView *textview = GINT_TO_POINTER(g_object_get_data(G_OBJECT(textbuffer),
"buffer_tv"));
422 g_object_set_data(G_OBJECT(textview),
"tv_multiple", GINT_TO_POINTER(
FALSE));
427 GtkWidget *target = g_object_get_data(G_OBJECT(widget),
d == GTK_DIR_TAB_FORWARD ?
"meta_next" :
"meta_prev");
428 gtk_widget_grab_focus(target);
439 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
457 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
473 GtkWidget *first = NULL, *previous = NULL;
480 gchar *setting = g_strdup_printf(
"plugins/lighttable/metadata/%s_flag",
name);
486 gtk_widget_set_visible(label, !hidden);
488 gtk_widget_set_visible(gtk_widget_get_parent(current), !hidden);
494 g_object_set_data(G_OBJECT(previous),
"meta_next", current);
495 g_object_set_data(G_OBJECT(current),
"meta_prev", previous);
497 g_object_set_data(G_OBJECT(current),
"meta_next", first);
498 g_object_set_data(G_OBJECT(first),
"meta_prev", current);
511 gchar *setting = g_strdup_printf(
"plugins/lighttable/metadata/%s_flag",
name);
518 GtkTextBuffer *buffer = gtk_text_view_get_buffer(
d->textview[
i]);
528 GtkListStore *
store = (GtkListStore *)user_data;
530 GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
533 gtk_tree_model_get_iter(GTK_TREE_MODEL(
store), &iter, path);
534 gtk_tree_model_get(GTK_TREE_MODEL(
store), &iter, column, &toggle, -1);
535 gtk_list_store_set(
store, &iter, column, !toggle, -1);
537 gtk_tree_path_free(path);
553 GtkWidget *dialog = gtk_dialog_new_with_buttons(_(
"metadata settings"), GTK_WINDOW(win),
554 GTK_DIALOG_DESTROY_WITH_PARENT, _(
"default"), GTK_RESPONSE_YES,
555 _(
"cancel"), GTK_RESPONSE_NONE, _(
"save"), GTK_RESPONSE_ACCEPT, NULL);
557 GtkWidget *area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
559 GtkWidget *w = gtk_scrolled_window_new(NULL, NULL);
561 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(w), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
563 gtk_box_pack_start(GTK_BOX(area), w,
TRUE,
TRUE, 0);
566 G_TYPE_INT, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
579 gchar *setting = g_strdup_printf(
"plugins/lighttable/metadata/%s_flag",
name[
i]);
584 gtk_list_store_append(
store, &iter);
585 gtk_list_store_set(
store, &iter,
595 g_object_unref(
model);
596 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
597 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_(
"metadata"), renderer,
599 gtk_tree_view_column_set_expand(column,
TRUE);
600 gtk_tree_view_append_column(GTK_TREE_VIEW(
view), column);
601 renderer = gtk_cell_renderer_toggle_new();
603 column = gtk_tree_view_column_new_with_attributes(_(
"visible"), renderer,
605 gtk_tree_view_append_column(GTK_TREE_VIEW(
view), column);
606 GtkWidget *header = gtk_tree_view_column_get_button(column);
607 gtk_widget_set_tooltip_text(header,
608 _(
"tick if the corresponding metadata is of interest for you"
609 "\nit will be visible from metadata editor, collection and import module"
610 "\nit will be also exported"));
611 renderer = gtk_cell_renderer_toggle_new();
613 column = gtk_tree_view_column_new_with_attributes(_(
"private"), renderer,
615 gtk_tree_view_append_column(GTK_TREE_VIEW(
view), column);
616 header = gtk_tree_view_column_get_button(column);
617 gtk_widget_set_tooltip_text(header,
618 _(
"tick if you want to keep this information private (not exported with images)"));
620 gtk_container_add(GTK_CONTAINER(w),
view);
622#ifdef GDK_WINDOWING_QUARTZ
625 gtk_widget_show_all(dialog);
627 int res = gtk_dialog_run(GTK_DIALOG(dialog));
628 while(
res == GTK_RESPONSE_YES)
630 gtk_tree_model_get_iter_first(
model, &iter);
637 gtk_list_store_set(
store, &iter,
641 gtk_tree_model_iter_next(
model, &iter);
644 res = gtk_dialog_run(GTK_DIALOG(dialog));
647 if(
res == GTK_RESPONSE_ACCEPT)
649 gboolean meta_signal =
FALSE;
650 gboolean meta_remove =
FALSE;
651 gboolean valid = gtk_tree_model_get_iter_first(
model, &iter);
654 gboolean new_visible;
655 gboolean new_private;
657 gtk_tree_model_get(
model, &iter,
664 gchar *setting = g_strdup_printf(
"plugins/lighttable/metadata/%s_flag",
name[
i]);
666 if(new_visible != visible[
i])
670 meta_remove = !new_visible ?
TRUE : meta_remove;
672 if(new_private !=
private[
i])
679 valid = gtk_tree_model_iter_next(
model, &iter);
686 gtk_widget_destroy(dialog);
691 GtkWidget *mi = gtk_menu_item_new_with_label(_(
"preferences..."));
693 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
698 GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview);
699 gtk_text_buffer_set_text(buffer, gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(menuitem)))), -1);
707 const int i = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(textview),
"tv_index"));
711 gtk_menu_shell_append(GTK_MENU_SHELL(popup),gtk_separator_menu_item_new());
713 for(GList *item =
d->metadata_list[
i]; item; item = g_list_next(item))
715 GtkWidget *new_line = gtk_menu_item_new_with_label(item->data);
717 gtk_menu_shell_append(GTK_MENU_SHELL(popup), new_line);
719 gtk_widget_show_all(popup);
724 if(event->type == GDK_2BUTTON_PRESS)
726 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
730 e.type = GDK_KEY_PRESS;
731 e.keyval = GDK_KEY_Return;
733 e.window = gtk_text_view_get_window(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT);
735 g_signal_emit_by_name(G_OBJECT(widget),
"key-press-event", &e, &ret_val);
743 self->
data = (
void *)
d;
747 GtkGrid *grid = GTK_GRID(gtk_grid_new());
748 self->
widget = GTK_WIDGET(grid);
757 GtkWidget *labelev = gtk_event_box_new();
758 gtk_widget_add_events(labelev, GDK_BUTTON_PRESS_MASK);
759 gtk_container_add(GTK_CONTAINER(labelev), label);
760 gtk_grid_attach(grid, labelev, 0,
i, 1, 1);
761 gtk_widget_set_tooltip_text(GTK_WIDGET(label),
762 _(
"metadata text. ctrl-wheel scroll to resize the text box"
763 "\n ctrl-enter inserts a new line (caution, may not be compatible with standard metadata)."
764 "\nif <leave unchanged> selected images have different metadata."
765 "\nin that case, right-click gives the possibility to choose one of them."
766 "\npress escape to exit the popup window"));
768 GtkWidget *textview = gtk_text_view_new();
771 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
772 g_object_set_data(G_OBJECT(buffer),
"buffer_tv", GINT_TO_POINTER(textview));
773 g_object_set_data(G_OBJECT(textview),
"tv_index", GINT_TO_POINTER(
i));
774 g_object_set_data(G_OBJECT(textview),
"tv_multiple", GINT_TO_POINTER(
FALSE));
775 gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)),
776 "italic",
"style", PANGO_STYLE_ITALIC, NULL);
778 gtk_grid_attach(grid, textview, 1,
i, 1, 1);
779 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD_CHAR);
780 gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(textview),
FALSE);
781 gtk_widget_add_events(textview, GDK_FOCUS_CHANGE_MASK);
783 g_signal_connect(textview,
"key-press-event", G_CALLBACK(
_key_pressed), self);
788 g_signal_connect(textview,
"focus", G_CALLBACK(
_textview_focus), self);
790 g_signal_connect(textview,
"grab-focus", G_CALLBACK(
_got_focus), self);
791 g_signal_connect(textview,
"focus-out-event", G_CALLBACK(
_lost_focus), self);
792 g_signal_connect(labelev,
"button-press-event", G_CALLBACK(
_metadata_reset), textview);
795 d->textview[
i] = GTK_TEXT_VIEW(textview);
796 gtk_widget_set_hexpand(textview,
TRUE);
797 gtk_widget_set_vexpand(textview,
TRUE);
802 _(
"write metadata for selected images"), 0, 0);
810 gtk_widget_show_all(self->
widget);
811 gtk_widget_set_no_show_all(self->
widget,
TRUE);
828 g_signal_handlers_block_by_func(
d->textview[
i],
_lost_focus, self);
830 d->metadata_list[
i] = NULL;
832 g_list_free(
d->last_act_on);
833 d->last_act_on = NULL;
842 const unsigned int params_size = strlen(
string) + metadata_nb;
845 memcpy(params + 4,
string,
params_size - metadata_nb);
855 add_rights_preset(self, _(
"CC BY-SA"), _(
"Creative Commons Attribution-ShareAlike (CC BY-SA)"));
856 add_rights_preset(self, _(
"CC BY-ND"), _(
"Creative Commons Attribution-NoDerivs (CC BY-ND)"));
857 add_rights_preset(self, _(
"CC BY-NC"), _(
"Creative Commons Attribution-NonCommercial (CC BY-NC)"));
859 _(
"Creative Commons Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)"));
861 _(
"Creative Commons Attribution-NonCommercial-NoDerivs (CC BY-NC-ND)"));
866 const int old_version,
int *new_version,
size_t *new_size)
870 const size_t new_params_size = old_params_size + 1;
871 char *new_params = calloc(
sizeof(
char), new_params_size);
873 const char *buf = (
const char *)old_params;
886 metadata_len[
i] = strlen(metadata[
i]) + 1;
887 buf += metadata_len[
i];
892 memcpy(new_params + pos, metadata[3], metadata_len[3]);
893 pos += metadata_len[3];
894 memcpy(new_params + pos, metadata[4], metadata_len[4]);
895 pos += metadata_len[4];
896 memcpy(new_params + pos, metadata[0], metadata_len[0]);
897 pos += metadata_len[0];
898 memcpy(new_params + pos, metadata[1], metadata_len[1]);
899 pos += metadata_len[1];
900 memcpy(new_params + pos, metadata[2], metadata_len[2]);
902 *new_size = new_params_size;
906 else if(old_version == 2)
908 const size_t new_params_size = old_params_size + 1;
909 char *new_params = calloc(
sizeof(
char), new_params_size);
911 memcpy(new_params, old_params, old_params_size);
913 *new_size = new_params_size;
933 GtkTextBuffer *buffer = gtk_text_view_get_buffer((GtkTextView *)
d->textview[
i]);
934 GtkTextIter start, end;
935 gtk_text_buffer_get_bounds(buffer, &start, &end);
936 metadata[keyid] = gtk_text_buffer_get_text(buffer, &start, &end,
TRUE);
937 if(!metadata[keyid]) metadata[keyid] = g_strdup(
"");
938 metadata_len[keyid] = strlen(metadata[keyid]) + 1;
939 *
size = *
size + metadata_len[keyid];
942 char *params = (
char *)malloc(*
size);
950 memcpy(params + pos, metadata[
i], metadata_len[
i]);
951 pos += metadata_len[
i];
955 g_assert(pos == *
size);
966 char *buf = (
char *)params;
969 uint32_t total_len = 0;
976 metadata_len[
i] = strlen(metadata[
i]) + 1;
977 buf += metadata_len[
i];
978 total_len += metadata_len[
i];
981 if(
size != total_len)
984 GList *key_value = NULL;
996 g_list_free(key_value);
1003 g_list_free(
d->last_act_on);
1004 d->last_act_on = NULL;
void dt_accels_disconnect_on_text_input(GtkWidget *widget)
Disconnect accels while a text or search entry has the focus, and reconnect them when it loses it....
Handle default and user-set shortcuts (accelerators)
GList * dt_act_on_get_images()
GtkWidget * dt_gui_main_window(void)
size_t params_size(dt_imageio_module_format_t *self)
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
Integer for name, clamped to the bounds declared in the XML.
void dt_image_synch_xmps(const GList *img)
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 guint dt_keys_mainpad_alternatives(const guint key_val)
Remap keypad keys to usual mainpad ones.
GtkWidget * dt_ui_label_new(const gchar *str)
void dt_gui_textview_set_padding(GtkTextView *textview)
Apply the standard recessed-input text padding to a GtkTextView.
gboolean dt_handle_dialog_enter(GtkWidget *widget, GdkEventKey *event, gpointer data)
void dt_lib_cancel_postponed_update(dt_lib_module_t *mod)
GtkWidget * dt_action_button_new(dt_lib_module_t *self, const gchar *label, gpointer callback, gpointer data, const gchar *tooltip, guint accel_key, GdkModifierType mods)
void dt_lib_presets_add(const char *name, const char *plugin_name, const int32_t version, const void *params, const int32_t params_size, gboolean readonly)
_lib_location_type_t type
#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.
#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_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ DT_SIGNAL_METADATA_CHANGED
This signal is raised when metadata status (shown/hidden) or value has changed.
@ 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
@ DT_UI_CONTAINER_PANEL_LEFT_CENTER