117#define NB_ITEMS (sizeof(items) / sizeof(dt_collection_sort_t))
151 static const char *
v[] = {
"lighttable", NULL};
174 gtk_widget_queue_draw(GTK_WIDGET(widget));
183 char *
p = (
char *)entry;
184 if(strlen(entry) > 1 && !(entry[0] ==
'"' && entry[1] ==
'"'))
190 if(entry[strlen(entry) - 1] ==
'"')
192 text = g_strconcat(start, (
char *)
p, NULL);
193 text[strlen(text) - 1] =
'\0';
196 text = g_strconcat(start, (
char *)
p,
"%", NULL);
205 char *text1 = g_strdup(text);
214 if(strlen(text1) > 1 && text1[strlen(text1) - 1] ==
'%')
216 text1[strlen(text1) - 1] =
'\0';
217 text2 = g_strconcat(start, (
char *)
p, NULL);
220 text2 = g_strconcat(start, (
char *)
p,
"\"", NULL);
235 if(clock -
d->last_key_time >= 0.4)
238 d->last_key_time = clock;
245 else if(!
d->time_out)
284 gtk_entry_set_text(GTK_ENTRY(
d->text),
"");
294 GdkModifierType modifier, gpointer data)
298 gtk_widget_grab_focus(GTK_WIDGET(
d->text));
321 gtk_widget_queue_draw(w);
389 flags &= ~COLLECTION_FILTER_ALTERED;
414 flags &= ~COLLECTION_FILTER_UNALTERED;
448 gtk_widget_set_halign(widget, GTK_ALIGN_FILL);
449 gtk_widget_set_hexpand(widget,
TRUE);
451 gtk_widget_set_valign(widget, GTK_ALIGN_CENTER);
452 gtk_widget_set_vexpand(widget,
FALSE);
472 for(
int i = 0;
i < 7;
i++)
504 gboolean include =
TRUE;
505 for(
int i = 6;
i > 1;
i--)
508 if(w ==
d->stars[
i]) include =
FALSE;
518 for(
int i = 0;
i < 7;
i++)
561 GtkWidget *spacer = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
567 GtkWidget *spacer = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
576 self->
data = (
void *)
d;
585 gtk_widget_set_tooltip_text(
d->refresh, _(
"Refresh the current collection to evict images\n"
586 "which properties have been changed\n"
587 "and don't match the current filters anymore."));
589 gtk_widget_set_name(
d->refresh,
"quick-filter-reload");
590 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
d->refresh),
FALSE,
FALSE, 0);
600 label = gtk_label_new(_(
"Include"));
604 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(hbox),
FALSE,
FALSE, 0);
605 gtk_widget_set_name(hbox,
"quick-filter-ratings");
608 for(
int k = 0;
k < 7;
k++)
613 gtk_widget_set_name(
d->stars[
k],
"no-star-filter");
618 gtk_widget_set_name(
d->stars[
k],
"rejected-filter");
624 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(
d->stars[
k]),
FALSE,
FALSE, 0);
625 g_signal_connect(G_OBJECT(
d->stars[
k]),
"button-press-event", G_CALLBACK(
_rating_clicked), self);
629 GtkWidget *spacer = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
631 gtk_box_pack_start(GTK_BOX(hbox), spacer,
FALSE,
FALSE, 0);
636 gtk_widget_set_tooltip_text(
d->stars[0], _(
"Toggle filtering in/out unrated images (0 star)"));
637 gtk_widget_set_tooltip_text(
d->stars[1], _(
"Toggle filtering in/out rejected images"));
638 gtk_widget_set_tooltip_text(
d->stars[2], _(
"Toggle filtering in/out images rated 1 star"));
639 gtk_widget_set_tooltip_text(
d->stars[3], _(
"Toggle filtering in/out images rated 2 stars"));
640 gtk_widget_set_tooltip_text(
d->stars[4], _(
"Toggle filtering in/out images rated 3 stars"));
641 gtk_widget_set_tooltip_text(
d->stars[5], _(
"Toggle filtering in/out images rated 4 stars"));
642 gtk_widget_set_tooltip_text(
d->stars[6], _(
"Toggle filtering in/out images rated 5 stars"));
648 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(hbox),
FALSE,
FALSE, 0);
649 gtk_widget_set_name(hbox,
"quickfilters-colors");
657 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(
d->colors[
k]),
FALSE,
FALSE, 0);
658 g_signal_connect(G_OBJECT(
d->colors[
k]),
"button-press-event", G_CALLBACK(
_colorlabel_clicked), self);
662 gtk_widget_set_tooltip_text(
d->colors[0], _(
"Toggle filtering in/out images without color label"));
663 gtk_widget_set_tooltip_text(
d->colors[1], _(
"Toggle filtering in/out images with red label"));
664 gtk_widget_set_tooltip_text(
d->colors[2], _(
"Toggle filtering in/out images with yellow label"));
665 gtk_widget_set_tooltip_text(
d->colors[3], _(
"Toggle filtering in/out images with green label"));
666 gtk_widget_set_tooltip_text(
d->colors[4], _(
"Toggle filtering in/out images with blue label"));
667 gtk_widget_set_tooltip_text(
d->colors[5], _(
"Toggle filtering in/out images with purple label"));
673 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(hbox),
FALSE,
FALSE, 0);
674 gtk_widget_set_name(hbox,
"quickfilters-altered");
677 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(
d->unaltered),
FALSE,
FALSE, 0);
678 g_signal_connect(G_OBJECT(
d->unaltered),
"button-press-event", G_CALLBACK(
_unaltered_clicked), self);
679 gtk_widget_set_tooltip_text(
d->unaltered, _(
"Toggle filtering in/out unedited images"));
682 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(
d->altered),
FALSE,
FALSE, 0);
683 g_signal_connect(G_OBJECT(
d->altered),
"button-press-event", G_CALLBACK(
_altered_clicked), self);
684 gtk_widget_set_tooltip_text(
d->altered, _(
"Toggle filtering in/out edited images"));
691 d->culling = gtk_toggle_button_new_with_label(_(
"Restrict to selection"));
692 gtk_widget_set_tooltip_text(
d->culling, _(
"Restrict the current view to only selected pictures"));
693 g_signal_connect(G_OBJECT(
d->culling),
"toggled", G_CALLBACK(
_culling_mode), (gpointer)self);
694 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
d->culling),
FALSE,
FALSE, 0);
695 gtk_widget_set_name(
d->culling,
"quickfilter-culling");
705 label = gtk_label_new(_(
"Sort by"));
711 d->sort = gtk_combo_box_text_new();
714 gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(
d->sort), NULL, _(
_sort_names[
i]));
719 gtk_widget_set_name(
d->sort,
"quick-filter-sort");
726 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
d->reverse),
FALSE,
FALSE, 0);
730 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
d->reverse),
738 d->text = gtk_search_entry_new();
740 gtk_widget_set_hexpand(
d->text,
TRUE);
743 gtk_entry_set_text(GTK_ENTRY(
d->text), text);
744 gtk_entry_set_placeholder_text(GTK_ENTRY(
d->text), _(
"Search an image..."));
747 g_signal_connect(G_OBJECT(
d->text),
"stop-search", G_CALLBACK(
_reset_text_entry), self);
748 gtk_entry_set_width_chars(GTK_ENTRY(
d->text), 24);
749 gtk_widget_set_tooltip_text(
d->text,
751 _(
"filter by text from images metadata, tags, file path and name"
753 "\n`%' is the wildcard character"
755 "\nby default start and end wildcards are auto-applied"
757 "\nstarting or ending with a double quote disables the corresponding wildcard"
759 "\nis dimmed during the search execution"));
761 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(
d->text),
TRUE,
TRUE, 0);
762 gtk_widget_set_name(
d->text,
"quickfilter-search-box");
773 d->menu = gtk_menu_new();
775 GtkWidget *first_entry = gtk_menu_item_new_with_label(_(
"Select all filters"));
776 gtk_menu_shell_append(GTK_MENU_SHELL(
d->menu), first_entry);
784 GtkWidget *second_entry = gtk_menu_item_new_with_label(_(
"Deselect all filters"));
785 gtk_menu_shell_append(GTK_MENU_SHELL(
d->menu), second_entry);
793 gtk_widget_show_all(
d->menu);
825 const uint32_t sort =
items[gtk_combo_box_get_active(GTK_COMBO_BOX(
d->sort))];
826 const gboolean descending = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
d->reverse));
840 const gboolean reverse = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
846 gtk_widget_queue_draw(GTK_WIDGET(widget));
void dt_accels_remove_shortcut(dt_accels_t *accels, const char *path)
Remove the shortcut object identified by path and all its accels.
gchar * dt_accels_build_path(const gchar *scope, const gchar *feature)
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....
void dt_accels_new_widget_shortcut(dt_accels_t *accels, GtkWidget *widget, const gchar *signal, GtkAccelGroup *accel_group, const gchar *accel_path, guint key_val, GdkModifierType accel_mods, const gboolean lock)
Register a new shortcut for a widget, setting up its path, default keys and accel group....
Handle default and user-set shortcuts (accelerators)
struct dt_accels_t * dt_gui_get_accels(void)
struct dt_ui_t * dt_gui_get_ui(void)
#define dt_accels_new_lighttable_action(a, b, w, c, d, e, f, g)
void dt_collection_update_query(const dt_collection_t *collection, dt_collection_change_t query_change, dt_collection_properties_t changed_property, GList *list)
void dt_culling_mode_to_selection()
void dt_collection_set_query_flags(const dt_collection_t *collection, dt_collection_query_flags_t flags)
void dt_collection_set_text_filter(const dt_collection_t *collection, char *text_filter)
dt_collection_t * dt_collection_get_global(void)
char * dt_collection_get_text_filter(const dt_collection_t *collection)
gboolean dt_collection_get_sort_descending(const dt_collection_t *collection)
void dt_collection_set_filter_flags(const dt_collection_t *collection, dt_collection_filter_flag_t flags)
dt_collection_filter_flag_t dt_collection_get_filter_flags(const dt_collection_t *collection)
dt_collection_sort_t dt_collection_get_sort_field(const dt_collection_t *collection)
void dt_collection_set_sort(const dt_collection_t *collection, dt_collection_sort_t sort, gboolean reverse)
dt_collection_properties_t
@ DT_COLLECTION_PROP_RATING
@ DT_COLLECTION_PROP_SORT
@ DT_COLLECTION_PROP_COLORLABEL
@ DT_COLLECTION_PROP_UNDEF
#define DT_COLLECTION_ORDER_FLAG
#define COLLECTION_QUERY_FULL
dt_collection_filter_flag_t
@ COLLECTION_FILTER_ALTERED
@ COLLECTION_FILTER_UNALTERED
@ COLLECTION_FILTER_GREEN
@ COLLECTION_FILTER_2_STAR
@ COLLECTION_FILTER_MAGENTA
@ COLLECTION_FILTER_0_STAR
@ COLLECTION_FILTER_1_STAR
@ COLLECTION_FILTER_5_STAR
@ COLLECTION_FILTER_YELLOW
@ COLLECTION_FILTER_REJECTED
@ COLLECTION_FILTER_4_STAR
@ COLLECTION_FILTER_3_STAR
@ COLLECTION_FILTER_WHITE
@ DT_COLLECTION_CHANGE_RELOAD
@ DT_COLLECTION_SORT_EXPORT_TIMESTAMP
@ DT_COLLECTION_SORT_IMPORT_TIMESTAMP
@ DT_COLLECTION_SORT_DATETIME
@ DT_COLLECTION_SORT_GROUP
@ DT_COLLECTION_SORT_FILENAME
@ DT_COLLECTION_SORT_RATING
@ DT_COLLECTION_SORT_PATH
@ DT_COLLECTION_SORT_TITLE
@ DT_COLLECTION_SORT_CHANGE_TIMESTAMP
@ DT_COLLECTION_SORT_NONE
@ DT_COLLECTION_SORT_PRINT_TIMESTAMP
@ DT_COLLECTION_SORT_COLOR
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
void dt_control_set_mouse_over_id(int32_t value)
void dt_control_set_keyboard_over_id(int32_t value)
struct dt_gui_gtk_t * dt_gui_get_global(void)
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
static gboolean _text_entry_changed_wait(gpointer user_data)
static void _launch_text_query(dt_lib_module_t *self)
static char * _encode_text_filter(const char *entry)
static void _reset_text_filter(dt_lib_module_t *self)
const dt_collection_filter_flag_t colors[6]
static gboolean _show_popover_menu(dt_lib_module_t *self, GtkWidget *w)
void _widget_align_left(GtkWidget *widget)
static void _culling_mode(GtkWidget *widget, gpointer data)
static int _filter_get_items(const dt_collection_sort_t sort)
const dt_collection_filter_flag_t ratings[7]
gboolean _focus_search_action(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval, GdkModifierType modifier, gpointer data)
static void _update_altered_filters(dt_lib_module_t *self)
static gboolean _rating_clicked(GtkWidget *w, GdkEventButton *e, dt_lib_module_t *self)
const dt_collection_sort_t items[]
static void _lib_filter_images_order_change(gpointer instance, int order, dt_lib_module_t *self)
static const char * _sort_names[]
void gui_cleanup(dt_lib_module_t *self)
static void _reset_text_entry(GtkButton *button, dt_lib_module_t *self)
static void _refresh_collection_callback(GtkButton *button, gpointer user_data)
static void _update_colors_filter(dt_lib_module_t *self)
static char * _decode_text_filter(const char *text)
static void _lib_filter_sort_combobox_changed(GtkWidget *widget, gpointer user_data)
static gboolean _colorlabel_clicked(GtkWidget *w, GdkEventButton *e, dt_lib_module_t *self)
static void _update_rating_filter(dt_lib_module_t *self)
static void _select_all_callback(GtkWidget *widget, dt_lib_module_t *self)
static void _select_none_callback(GtkWidget *widget, dt_lib_module_t *self)
uint32_t container(dt_lib_module_t *self)
static void _insert_subsection_sep(dt_lib_module_t *self)
void gui_init(dt_lib_module_t *self)
static gboolean _unaltered_clicked(GtkWidget *w, GdkEventButton *e, dt_lib_module_t *self)
const char ** views(dt_lib_module_t *self)
int expandable(dt_lib_module_t *self)
static void _set_widget_dimmed(GtkWidget *widget, const gboolean dimmed)
static void _dtgtk_button_set_active(GtkWidget *w, gboolean active)
static void _insert_section_sep(dt_lib_module_t *self)
static void _lib_filter_update_query(dt_lib_module_t *self, dt_collection_properties_t changed_property)
static gboolean _altered_clicked(GtkWidget *w, GdkEventButton *e, dt_lib_module_t *self)
static void _lib_filter_set_tag_order(dt_lib_module_t *self)
static void _text_entry_changed(GtkEntry *entry, dt_lib_module_t *self)
static void _lib_filter_reverse_button_changed(GtkDarktableToggleButton *widget, gpointer user_data)
float *const restrict const size_t k
#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,...
int32_t dt_selection_get_first_id(struct dt_selection_t *selection)
struct dt_selection_t * dt_selection_get_global(void)
#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_IMAGES_ORDER_CHANGE
This signal is raised to request image order change.
@ 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)
void dt_thumbtable_reset_collection(dt_thumbtable_t *table)
static double dt_get_wtime(void)
@ DT_UI_CONTAINER_PANEL_TOP_SECOND_ROW