Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
tagging_completion.c
Go to the documentation of this file.
1/*
2 This file is part of Ansel,
3 Copyright (C) 2026 Guillaume Stutin.
4 Copyright (C) 2026 Paolo SANTUCCI.
5
6 Ansel is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Ansel is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Ansel. If not, see <http://www.gnu.org/licenses/>.
18*/
19
21
22#include "metadata/tags.h"
23#include "system/macros.h"
24#include "system/mem_alloc.h"
25
27{
28 gtk_list_store_clear(store);
29 GList *tags = NULL;
31 for(GList *tag_iter = tags; tag_iter; tag_iter = g_list_next(tag_iter))
32 {
33 const dt_tag_t *tag = (const dt_tag_t *)tag_iter->data;
34 if(IS_NULL_PTR(tag->tag)) continue;
35 GtkTreeIter store_iter;
36 gtk_list_store_append(store, &store_iter);
37 gtk_list_store_set(store, &store_iter, 0, tag->tag, -1);
38 }
39 dt_tag_free_result(&tags);
40}
41
42gboolean dt_tagging_completion_match_selected(GtkEntryCompletion *completion, GtkTreeModel *model,
43 GtkTreeIter *iter, gpointer user_data)
44{
45 const int column = gtk_entry_completion_get_text_column(completion);
46 if(gtk_tree_model_get_column_type(model, column) != G_TYPE_STRING) return TRUE;
47
48 GtkEditable *entry = GTK_EDITABLE(gtk_entry_completion_get_entry(completion));
49 if(!GTK_IS_EDITABLE(entry)) return FALSE;
50
51 char *tag = NULL;
52 gtk_tree_model_get(model, iter, column, &tag, -1);
53 gint cursor_position = gtk_editable_get_position(entry);
54 gchar *current_text = gtk_editable_get_chars(entry, 0, -1);
55 const gchar *last_tag = g_strrstr(current_text, ",");
56 const gint cut_off = last_tag
57 ? (int)(g_utf8_strlen(current_text, -1) - g_utf8_strlen(last_tag, -1)) + 1
58 : 0;
59 dt_free(current_text);
60
61 const gboolean inline_completion = gtk_entry_completion_get_inline_completion(completion);
62 gtk_entry_completion_set_inline_completion(completion, FALSE);
63 gtk_editable_delete_text(entry, cut_off, cursor_position);
64 cursor_position = cut_off;
65 gtk_editable_insert_text(entry, tag, -1, &cursor_position);
66 gtk_editable_set_position(entry, cursor_position);
67 gtk_entry_completion_set_inline_completion(completion, inline_completion);
68 dt_free(tag);
69 return TRUE;
70}
71
72void dt_tagging_entry_clear(GtkEntry *entry, GCallback key_handler, gpointer user_data)
73{
74 GtkEntryCompletion *completion = gtk_entry_get_completion(entry);
75 if(!IS_NULL_PTR(completion))
76 {
77 g_object_ref(completion);
78 gtk_entry_set_completion(entry, NULL);
79 }
80 gtk_entry_set_text(entry, "");
81 if(!IS_NULL_PTR(completion))
82 {
83 gtk_entry_set_completion(entry, completion);
84 g_object_unref(completion);
85 // Detaching is the only public way to cancel the completion's pending timeout and idle, and
86 // reattaching put its key handler last: Return, Escape and the arrows belong to its popup.
87 if(!IS_NULL_PTR(key_handler) && g_signal_handlers_disconnect_by_func(entry, key_handler, user_data))
88 g_signal_connect(entry, "key-press-event", key_handler, user_data);
89 }
90}
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
GtkTreeStore * store
its model, owned by the view
const char * model
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:96
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
Definition mem_alloc.h:171
gboolean dt_tagging_completion_match_selected(GtkEntryCompletion *completion, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
void dt_tagging_completion_refresh(GtkListStore *store)
void dt_tagging_entry_clear(GtkEntry *entry, GCallback key_handler, gpointer user_data)
void dt_tag_free_result(GList **result)
Definition tags.c:1003
uint32_t dt_tag_get_with_usage(GList **result)
Definition tags.c:890