Skip to content

Commit

Permalink
simplify variables completion list handling
Browse files Browse the repository at this point in the history
  • Loading branch information
zisoft committed Dec 22, 2024
1 parent 84d7e3f commit f48d993
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 102 deletions.
122 changes: 85 additions & 37 deletions src/gui/gtkentry.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,20 @@

#include "gtkentry.h"
#include "common/darktable.h"
#include "common/metadata.h"

typedef struct completion_spec
{
gchar *varname;
gchar *description;
} dt_gtkentry_completion_spec;

typedef enum
{
COMPL_ID = 0,
COMPL_VARNAME,
COMPL_DESCRIPTION
} dtGtkEntryCompletionSpecCol;


static dt_gtkentry_completion_spec _default_path_compl_list[]
= { { "ROLL.NAME", N_("$(ROLL.NAME) - roll of the input image") },
Expand Down Expand Up @@ -109,6 +122,9 @@ static dt_gtkentry_completion_spec _default_path_compl_list[]
{ NULL, NULL } };


static GtkListStore *_completion_model = NULL;


/**
* Called when the user selects an entry from the autocomplete list.
*
Expand All @@ -119,7 +135,9 @@ static dt_gtkentry_completion_spec _default_path_compl_list[]
*
* @return Currently always true
*/
static gboolean _on_match_select(GtkEntryCompletion *widget, GtkTreeModel *model, GtkTreeIter *iter,
static gboolean _on_match_select(GtkEntryCompletion *widget,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer user_data)
{

Expand Down Expand Up @@ -169,7 +187,9 @@ static gboolean _on_match_select(GtkEntryCompletion *widget, GtkTreeModel *model
* @param iter Item in list of autocomplete database to compare key against.
* @param user_data Unused.
*/
static gboolean _on_match_func(GtkEntryCompletion *completion, const gchar *key, GtkTreeIter *iter,
static gboolean _on_match_func(GtkEntryCompletion *completion,
const gchar *key,
GtkTreeIter *iter,
gpointer user_data)
{
gboolean ret = FALSE;
Expand Down Expand Up @@ -223,36 +243,23 @@ static gboolean _on_match_func(GtkEntryCompletion *completion, const gchar *key,
return ret;
}

/**
* This function initializes entry with the variables table.
*
* @param[in] entry GtkEntry
*/
void dt_gtkentry_setup_variables_completion(GtkEntry *entry)
static void _init_completion_model()
{
if(!entry)
return;

GtkEntryCompletion *completion = gtk_entry_get_completion(entry);
if(completion)
{
g_object_unref(completion);
gtk_entry_set_completion(entry, NULL);
}

completion = gtk_entry_completion_new();
GtkListStore *model = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
_completion_model = gtk_list_store_new(3,
G_TYPE_INT,
G_TYPE_STRING,
G_TYPE_STRING);
GtkTreeIter iter;

gtk_entry_completion_set_text_column(completion, COMPL_DESCRIPTION);
gtk_entry_set_completion(entry, completion);
g_signal_connect(G_OBJECT(completion), "match-selected", G_CALLBACK(_on_match_select), NULL);

/* Populate the completion database. */
for(const dt_gtkentry_completion_spec *l = _default_path_compl_list; l && l->varname; l++)
{
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter, COMPL_VARNAME, l->varname, COMPL_DESCRIPTION, _(l->description), -1);
gtk_list_store_append(_completion_model, &iter);
gtk_list_store_set(_completion_model, &iter,
COMPL_ID, -1, // -1 = internal
COMPL_VARNAME, l->varname,
COMPL_DESCRIPTION, _(l->description),
-1);
}

// metadata
Expand All @@ -261,20 +268,61 @@ void dt_gtkentry_setup_variables_completion(GtkEntry *entry)
{
dt_metadata_t *metadata = (dt_metadata_t *)md_iter->data;
if(!metadata->internal)
{
gchar *varname = g_utf8_strup(dt_metadata_get_tag_subkey(metadata->tagname), -1);
gchar *description = g_strdup_printf("$(%s) - %s", varname, _("from metadata"));
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter, COMPL_VARNAME, varname, COMPL_DESCRIPTION, description, -1);
g_free(varname);
g_free(description);
}
dt_gtkentry_variables_add_metadata(metadata);
}
dt_pthread_mutex_unlock(&darktable.metadata_threadsafe);
}

gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(model));
void dt_gtkentry_setup_variables_completion(GtkEntry *entry)
{
if(!_completion_model)
_init_completion_model();

GtkEntryCompletion *completion = gtk_entry_completion_new();
gtk_entry_completion_set_text_column(completion, COMPL_DESCRIPTION);
gtk_entry_set_completion(entry, completion);
g_signal_connect(G_OBJECT(completion), "match-selected", G_CALLBACK(_on_match_select), NULL);

gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(_completion_model));
gtk_entry_completion_set_match_func(completion, _on_match_func, NULL, NULL);
g_object_unref(model);
}

void dt_gtkentry_variables_add_metadata(dt_metadata_t *metadata)
{
GtkTreeIter iter;

gchar *varname = g_utf8_strup(dt_metadata_get_tag_subkey(metadata->tagname), -1);
gchar *description = g_strdup_printf("$(%s) - %s", varname, _("from metadata"));
gtk_list_store_append(_completion_model, &iter);
gtk_list_store_set(_completion_model, &iter,
COMPL_ID, metadata->key,
COMPL_VARNAME, varname,
COMPL_DESCRIPTION, description,
-1);
g_free(varname);
g_free(description);
}

void dt_gtkentry_variables_remove_metadata(dt_metadata_t *metadata)
{
GtkTreeIter iter;

gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(_completion_model), &iter);
while(valid)
{
int32_t id;
gtk_tree_model_get(GTK_TREE_MODEL(_completion_model), &iter,
COMPL_ID, &id,
-1);

if(id == metadata->key)
{
gtk_list_store_remove(_completion_model, &iter);
break;
}

valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(_completion_model), &iter);
}
}


Expand Down
19 changes: 8 additions & 11 deletions src/gui/gtkentry.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,17 @@
#include <stdio.h>
#include <stdlib.h>

typedef struct completion_spec
{
gchar *varname;
gchar *description;
} dt_gtkentry_completion_spec;

typedef enum
{
COMPL_VARNAME = 0,
COMPL_DESCRIPTION
} dtGtkEntryCompletionSpecCol;
#include "common/metadata.h"

/** initialize entry with the variables table */
void dt_gtkentry_setup_variables_completion(GtkEntry *entry);

/** add a metadata to the variables substitution */
void dt_gtkentry_variables_add_metadata(dt_metadata_t *metadata);

/** remove a metadata from the variables substitution */
void dt_gtkentry_variables_remove_metadata(dt_metadata_t *metadata);


// clang-format off
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
Expand Down
10 changes: 0 additions & 10 deletions src/imageio/storage/disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,6 @@ static void onsave_action_toggle_callback(GtkWidget *widget,
dt_bauhaus_combobox_get(widget));
}

static void _setup_variables_completion(gpointer instance, int type, dt_imageio_module_storage_t *self)
{
disk_t *d = self->gui_data;

if(type == DT_METADATA_SIGNAL_PREF_CHANGED)
dt_gtkentry_setup_variables_completion(d->entry);
}

void gui_init(dt_imageio_module_storage_t *self)
{
disk_t *d = malloc(sizeof(disk_t));
Expand All @@ -279,7 +271,6 @@ void gui_init(dt_imageio_module_storage_t *self)
dt_gtkentry_setup_variables_completion(d->entry);
gtk_editable_set_position(GTK_EDITABLE(d->entry), -1);
gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(d->entry), TRUE, TRUE, 0);
DT_CONTROL_SIGNAL_CONNECT(DT_SIGNAL_METADATA_CHANGED, _setup_variables_completion, self);

GtkWidget *widget = dtgtk_button_new(dtgtk_cairo_paint_directory, CPF_NONE, NULL);
gtk_widget_set_name(widget, "non-flat");
Expand All @@ -299,7 +290,6 @@ void gui_init(dt_imageio_module_storage_t *self)

void gui_cleanup(dt_imageio_module_storage_t *self)
{
DT_CONTROL_SIGNAL_DISCONNECT(_setup_variables_completion, self);
free(self->gui_data);
}

Expand Down
10 changes: 0 additions & 10 deletions src/imageio/storage/gallery.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,6 @@ static void title_changed_callback(GtkEntry *entry,
gtk_entry_get_text(entry));
}

static void _setup_variables_completion(gpointer instance, int type, dt_imageio_module_storage_t *self)
{
gallery_t *d = self->gui_data;

if(type == DT_METADATA_SIGNAL_PREF_CHANGED)
dt_gtkentry_setup_variables_completion(d->entry);
}

void gui_init(dt_imageio_module_storage_t *self)
{
gallery_t *d = malloc(sizeof(gallery_t));
Expand All @@ -214,7 +206,6 @@ void gui_init(dt_imageio_module_storage_t *self)
dt_conf_get_string_const("plugins/imageio/storage/gallery/file_directory")));
dt_gtkentry_setup_variables_completion(d->entry);
gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(d->entry), TRUE, TRUE, 0);
DT_CONTROL_SIGNAL_CONNECT(DT_SIGNAL_METADATA_CHANGED, _setup_variables_completion, self);

widget = dtgtk_button_new(dtgtk_cairo_paint_directory, CPF_NONE, NULL);
gtk_widget_set_name(widget, "non-flat");
Expand All @@ -236,7 +227,6 @@ void gui_init(dt_imageio_module_storage_t *self)

void gui_cleanup(dt_imageio_module_storage_t *self)
{
DT_CONTROL_SIGNAL_DISCONNECT(_setup_variables_completion, self);
free(self->gui_data);
}

Expand Down
10 changes: 0 additions & 10 deletions src/imageio/storage/latex.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,6 @@ static void title_changed_callback(GtkEntry *entry, gpointer user_data)
dt_conf_set_string("plugins/imageio/storage/latex/title", gtk_entry_get_text(entry));
}

static void _setup_variables_completion(gpointer instance, int type, dt_imageio_module_storage_t *self)
{
latex_t *d = self->gui_data;

if(type == DT_METADATA_SIGNAL_PREF_CHANGED)
dt_gtkentry_setup_variables_completion(d->entry);
}

void gui_init(dt_imageio_module_storage_t *self)
{
latex_t *d = malloc(sizeof(latex_t));
Expand All @@ -200,7 +192,6 @@ void gui_init(dt_imageio_module_storage_t *self)
dt_conf_get_string_const("plugins/imageio/storage/latex/file_directory")));
dt_gtkentry_setup_variables_completion(d->entry);
gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(d->entry), TRUE, TRUE, 0);
DT_CONTROL_SIGNAL_CONNECT(DT_SIGNAL_METADATA_CHANGED, _setup_variables_completion, self);

widget = dtgtk_button_new(dtgtk_cairo_paint_directory, CPF_NONE, NULL);
gtk_widget_set_name(widget, "non-flat");
Expand All @@ -223,7 +214,6 @@ void gui_init(dt_imageio_module_storage_t *self)

void gui_cleanup(dt_imageio_module_storage_t *self)
{
DT_CONTROL_SIGNAL_DISCONNECT(_setup_variables_completion, self);
free(self->gui_data);
}

Expand Down
10 changes: 0 additions & 10 deletions src/imageio/storage/piwigo.c
Original file line number Diff line number Diff line change
Expand Up @@ -999,14 +999,6 @@ static void _filname_pattern_entry_changed_callback(GtkEntry *entry,
dt_conf_set_string("plugins/imageio/storage/export/piwigo/filename_pattern", gtk_entry_get_text(entry));
}

static void _setup_variables_completion(gpointer instance, int type, dt_imageio_module_storage_t *self)
{
dt_storage_piwigo_gui_data_t *ui = self->gui_data;

if(type == DT_METADATA_SIGNAL_PREF_CHANGED)
dt_gtkentry_setup_variables_completion(ui->filename_pattern_entry);
}

void gui_init(dt_imageio_module_storage_t *self)
{
self->gui_data = g_malloc0(sizeof(dt_storage_piwigo_gui_data_t));
Expand Down Expand Up @@ -1182,7 +1174,6 @@ void gui_init(dt_imageio_module_storage_t *self)
gtk_box_pack_start(GTK_BOX(hbox), dt_ui_label_new(_("filename pattern")), FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui->filename_pattern_entry), TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(hbox), TRUE, TRUE, 0);
DT_CONTROL_SIGNAL_CONNECT(DT_SIGNAL_METADATA_CHANGED, _setup_variables_completion, self);

// action on conflict
ui->conflict_action = dt_bauhaus_combobox_new(NULL);
Expand All @@ -1199,7 +1190,6 @@ void gui_init(dt_imageio_module_storage_t *self)

void gui_cleanup(dt_imageio_module_storage_t *self)
{
DT_CONTROL_SIGNAL_DISCONNECT(_setup_variables_completion, self);
g_free(self->gui_data);
}

Expand Down
13 changes: 0 additions & 13 deletions src/iop/watermark.c
Original file line number Diff line number Diff line change
Expand Up @@ -1292,17 +1292,6 @@ void init(dt_iop_module_t *self)
g_strlcpy(d->font, "DejaVu Sans 10", sizeof(d->font));
}

static void _setup_variables_completion(gpointer instance, int type, dt_iop_module_t *self)
{
dt_iop_watermark_gui_data_t *g = self->gui_data;

if(type == DT_METADATA_SIGNAL_PREF_CHANGED) {
++darktable.gui->reset;
dt_gtkentry_setup_variables_completion(GTK_ENTRY(g->text));
--darktable.gui->reset;
}
}

void gui_init(dt_iop_module_t *self)
{
dt_iop_watermark_gui_data_t *g = IOP_GUI_ALLOC(watermark);
Expand Down Expand Up @@ -1343,7 +1332,6 @@ void gui_init(dt_iop_module_t *self)
gtk_entry_set_placeholder_text(GTK_ENTRY(g->text), _("content"));
gtk_grid_attach(grid, label, 0, line++, 1, 1);
gtk_grid_attach_next_to(grid, g->text, label, GTK_POS_RIGHT, 2, 1);
DT_CONTROL_SIGNAL_CONNECT(DT_SIGNAL_METADATA_CHANGED, _setup_variables_completion, self);

// Text font
label = dtgtk_reset_label_new(_("font"), self, &p->font, sizeof(p->font));
Expand Down Expand Up @@ -1448,7 +1436,6 @@ void gui_init(dt_iop_module_t *self)

void gui_cleanup(dt_iop_module_t *self)
{
DT_CONTROL_SIGNAL_DISCONNECT(_setup_variables_completion, self);
dt_iop_watermark_gui_data_t *g = self->gui_data;
g_list_free_full(g->watermarks_filenames, g_free);
g->watermarks_filenames = NULL;
Expand Down
13 changes: 12 additions & 1 deletion src/libs/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "dtgtk/button.h"
#include "gui/accelerators.h"
#include "gui/gtk.h"
#include "gui/gtkentry.h"
#include "gui/metadata_tags.h"
#include "libs/lib.h"
#include "libs/lib_api.h"
Expand Down Expand Up @@ -1021,8 +1022,17 @@ static void _menuitem_preferences(GtkMenuItem *menuitem,

g_free(keys);

// re-initialze the metadata list
dt_pthread_mutex_lock(&darktable.metadata_threadsafe);
// remove the metadata from the variables substitution list
for(GList *key_iter = d->metadata_to_delete; key_iter; key_iter = key_iter->next)
{
uint32_t keyid = GPOINTER_TO_INT(key_iter->data);
dt_metadata_t *metadata = dt_metadata_get_metadata_by_keyid(keyid);
if(metadata)
dt_gtkentry_variables_remove_metadata(metadata);
}

// re-initialze the metadata list
dt_metadata_init();
dt_pthread_mutex_unlock(&darktable.metadata_threadsafe);

Expand Down Expand Up @@ -1064,6 +1074,7 @@ static void _menuitem_preferences(GtkMenuItem *menuitem,
md->priv = private;
md->display_order = display_order;
dt_metadata_add_metadata(md);
dt_gtkentry_variables_add_metadata(md);

d->needs_rebuild = TRUE;
}
Expand Down

0 comments on commit f48d993

Please sign in to comment.