--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<section id="GuideOptionsKeywords">\r
+ <title id="titleGuideOptionsKeywords">Keywords</title>\r
+ <para>This section describes the keywords list used for autocompletion.</para>\r
+ <para />\r
+ <section id="KeywordSearch">\r
+ <title>Keyword Search</title>\r
+ <para />\r
+ <para>Pressing the Search button will open a dialog which permits a recursive search to be made for keywords already attached to images. The result of the search is automatically appended to the existing list.</para>\r
+ </section>\r
+ <section id="KeywordList">\r
+ <title>Keyword List</title>\r
+ <para />\r
+ <para>\r
+ The list shows all keywords currently used for autocompletion. Text may be copy-pasted into the list or deleted from the list.\r
+ <para />\r
+ When the list is saved, duplicates will autmatically be removed and the list sorted into alphabetical order.\r
+ </para>\r
+ </section>\r
+</section>\r
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="GuideOptionsKeyboard.xml" />\r
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="GuideOptionsFiltering.xml" />\r
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="GuideOptionsMetadata.xml" />\r
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="GuideOptionsKeywords.xml" />\r
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="GuideOptionsColor.xml" />\r
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="GuideOptionsStereo.xml" />\r
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="GuideOptionsBehavior.xml" />\r
</note>\r
<para />\r
</section>\r
+ <section id="KeywordAutocompletion">\r
+ <title id="titleKeywordAutocompletion">Keyword Autocompletion</title>\r
+ <para>\r
+ The text box at the bottom of the keywords pane is used for autocompletion. Any keywords typed into the standard keyword box or the autocompletion box will be remembered as candidates for future autocompletion.\r
+ <para />\r
+ Frequently used sets of keywords can be entered as comma-delimited lists.\r
+ <para />\r
+ The list of keywords used for autocompletion can be edited on the\r
+ <link linkend="GuideOptionsKeywords">Keywords</link>\r
+ tab of the Preferences dialog.\r
+ <para />\r
+ The menu action "Keyword autocomplete", set to\r
+ <code>Alt + K</code>\r
+ by default, will shift the keyboard focus to the autocomplete box. Pressing\r
+ <code>Alt + K</code>\r
+ a second time will shift the keyboard focus back to the previous object.\r
+ </para>\r
+ <para />\r
+ </section>\r
<section id="Listpanes-ExifFileinfoCopyrightLocationandGPS">\r
<title id="titleExif">List panes</title>\r
<para>\r
#include "rcfile.h"
#include "layout.h"
#include "dnd.h"
+#include "secure_save.h"
//static void bar_pane_keywords_keyword_update_all(void);
static void bar_pane_keywords_changed(GtkTextBuffer *buffer, gpointer data);
+static void autocomplete_keywords_list_load(const gchar *path);
+static GtkListStore *keyword_store = NULL;
+static gboolean autocomplete_keywords_list_save(gchar *path);
+static gboolean autocomplete_activate_cb(GtkWidget *widget, gpointer data);
+
/*
*-------------------------------------------------------------------
* keyword / comment utils
gint height;
GList *expanded_rows;
+
+ GtkWidget *autocomplete;
};
typedef struct _ConfDialogData ConfDialogData;
if (gtk_widget_has_focus(pkd->keyword_view)) return gtk_widget_event(pkd->keyword_view, event);
+ if (gtk_widget_has_focus(pkd->autocomplete))
+ {
+ return gtk_widget_event(pkd->autocomplete, event);
+ }
return FALSE;
}
static void bar_pane_keywords_destroy(GtkWidget *widget, gpointer data)
{
PaneKeywordsData *pkd = data;
+ gchar *path;
+
+ path = g_build_filename(get_rc_dir(), "keywords", NULL);
+ autocomplete_keywords_list_save(path);
string_list_free(pkd->expanded_rows);
if (pkd->click_tpath) gtk_tree_path_free(pkd->click_tpath);
static GtkWidget *bar_pane_keywords_new(const gchar *id, const gchar *title, const gchar *key, gboolean expanded, gint height)
{
PaneKeywordsData *pkd;
- GtkWidget *hbox;
+ GtkWidget *hbox, *vbox;
GtkWidget *scrolled;
GtkTextBuffer *buffer;
GtkTreeModel *store;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeIter iter;
+ GtkEntryCompletion *completion;
+ gchar *path;
pkd = g_new0(PaneKeywordsData, 1);
pkd->expand_checked = TRUE;
pkd->expanded_rows = NULL;
+ vbox = gtk_vbox_new(FALSE, PREF_PAD_GAP);
hbox = gtk_hbox_new(FALSE, PREF_PAD_GAP);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
- pkd->widget = hbox;
+ pkd->widget = vbox;
g_object_set_data(G_OBJECT(pkd->widget), "pane_data", pkd);
g_signal_connect(G_OBJECT(pkd->widget), "destroy",
G_CALLBACK(bar_pane_keywords_destroy), pkd);
gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 0);
gtk_widget_show(scrolled);
+ pkd->autocomplete = gtk_entry_new();
+ gtk_box_pack_end(GTK_BOX(vbox), pkd->autocomplete, FALSE, FALSE, 0);
+ gtk_widget_show(pkd->autocomplete);
+ gtk_widget_show(vbox);
+ gtk_widget_set_tooltip_text(pkd->autocomplete, "Keyword autocomplete");
+
+ path = g_build_filename(get_rc_dir(), "keywords", NULL);
+ autocomplete_keywords_list_load(path);
+
+ completion = gtk_entry_completion_new();
+ gtk_entry_set_completion(GTK_ENTRY(pkd->autocomplete), completion);
+ gtk_entry_completion_set_inline_completion(completion, TRUE);
+ gtk_entry_completion_set_inline_selection(completion, TRUE);
+ g_object_unref(completion);
+
+ gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(keyword_store));
+ gtk_entry_completion_set_text_column(completion, 0);
+
+ g_signal_connect(G_OBJECT(pkd->autocomplete), "activate",
+ G_CALLBACK(autocomplete_activate_cb), pkd);
if (!keyword_tree || !gtk_tree_model_get_iter_first(GTK_TREE_MODEL(keyword_tree), &iter))
{
log_printf("unknown attribute %s = %s\n", option, value);
}
}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Autocomplete keywords
+ *-----------------------------------------------------------------------------
+ */
+
+static gboolean autocomplete_activate_cb(GtkWidget *widget, gpointer data)
+{
+ PaneKeywordsData *pkd = data;
+ gchar *entry_text;
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+ GtkTreeIter iter_t;
+ gchar *kw_cr;
+ gchar *kw_split;
+ gboolean valid;
+ gboolean found = FALSE;
+ gchar *string;
+
+ entry_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(pkd->autocomplete)));
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pkd->keyword_view));
+
+ kw_split = strtok(entry_text, ",");
+ while (kw_split != NULL)
+ {
+ kw_cr = g_strconcat(kw_split, "\n", NULL);
+ g_strchug(kw_cr);
+ gtk_text_buffer_get_end_iter(buffer, &iter);
+ gtk_text_buffer_insert(buffer, &iter, kw_cr, -1);
+
+ kw_split = strtok(NULL, ",");
+ g_free(kw_cr);
+ }
+
+ g_free(entry_text);
+ entry_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(pkd->autocomplete)));
+
+ gtk_entry_set_text(GTK_ENTRY(pkd->autocomplete), "");
+
+ valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(keyword_store), &iter_t);
+ while (valid)
+ {
+ gtk_tree_model_get (GTK_TREE_MODEL(keyword_store), &iter_t, 0, &string, -1);
+ if (g_strcmp0(entry_text, string) == 0)
+ {
+ found = TRUE;
+ break;
+ }
+ valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(keyword_store), &iter_t);
+ }
+
+ if (!found)
+ {
+ gtk_list_store_append (keyword_store, &iter_t);
+ gtk_list_store_set(keyword_store, &iter_t, 0, entry_text, -1);
+ }
+
+ g_free(entry_text);
+ return FALSE;
+}
+
+gint autocomplete_sort_iter_compare_func (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer userdata)
+{
+ gint ret = 0;
+ gchar *name1, *name2;
+
+ gtk_tree_model_get(model, a, 0, &name1, -1);
+ gtk_tree_model_get(model, b, 0, &name2, -1);
+
+ if (name1 == NULL || name2 == NULL)
+ {
+ if (name1 == NULL && name2 == NULL)
+ {
+ ret = 0;
+ }
+ else
+ {
+ ret = (name1 == NULL) ? -1 : 1;
+ }
+ }
+ else
+ {
+ ret = g_utf8_collate(name1,name2);
+ }
+
+ g_free(name1);
+ g_free(name2);
+
+ return ret;
+}
+
+static void autocomplete_keywords_list_load(const gchar *path)
+{
+ FILE *f;
+ gchar s_buf[1024];
+ gchar *pathl;
+ gint len;
+ GtkTreeIter iter;
+ GtkTreeSortable *sortable;
+
+ if (keyword_store) return;
+ keyword_store = gtk_list_store_new(1, G_TYPE_STRING);
+
+ sortable = GTK_TREE_SORTABLE(keyword_store);
+ gtk_tree_sortable_set_sort_func(sortable, 0, autocomplete_sort_iter_compare_func,
+ GINT_TO_POINTER(0), NULL);
+
+ gtk_tree_sortable_set_sort_column_id(sortable, 0, GTK_SORT_ASCENDING);
+
+ pathl = path_from_utf8(path);
+ f = fopen(pathl, "r");
+ g_free(pathl);
+
+ if (!f)
+ {
+ log_printf("Warning: keywords file %s not loaded", pathl);
+ return;
+ }
+
+ /* first line must start with Keywords comment */
+ if (!fgets(s_buf, sizeof(s_buf), f) ||
+ strncmp(s_buf, "#Keywords", 9) != 0)
+ {
+ fclose(f);
+ log_printf("Warning: keywords file %s not loaded", pathl);
+ return;
+ }
+
+ while (fgets(s_buf, sizeof(s_buf), f))
+ {
+ if (s_buf[0]=='#') continue;
+
+ len = strlen(s_buf);
+ if( s_buf[len-1] == '\n' )
+ {
+ s_buf[len-1] = 0;
+ }
+ gtk_list_store_append (keyword_store, &iter);
+ gtk_list_store_set(keyword_store, &iter, 0, g_strdup(s_buf), -1);
+ }
+
+ fclose(f);
+}
+
+static gboolean autocomplete_keywords_list_save(gchar *path)
+{
+ SecureSaveInfo *ssi;
+ gchar *pathl;
+ gchar *string;
+ gchar *string_nl;
+ GtkTreeIter iter;
+ gboolean valid;
+
+ pathl = path_from_utf8(path);
+ ssi = secure_open(pathl);
+ g_free(pathl);
+
+ if (!ssi)
+ {
+ log_printf(_("Error: Unable to write keywords list to: %s\n"), path);
+ return FALSE;
+ }
+
+ secure_fprintf(ssi, "#Keywords list\n");
+
+ valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(keyword_store), &iter);
+
+ while (valid)
+ {
+ gtk_tree_model_get (GTK_TREE_MODEL(keyword_store), &iter, 0, &string, -1);
+ string_nl = g_strconcat(string, "\n", NULL);
+ secure_fprintf(ssi, "%s", string_nl);
+
+ valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(keyword_store), &iter);
+
+ g_free(string_nl);
+ }
+
+ secure_fprintf(ssi, "#end\n");
+ return (secure_close(ssi) == 0);
+}
+
+GList *keyword_list_get()
+{
+ GList *ret_list = NULL;
+ gchar *string;
+ gchar *string_nl;
+ GtkTreeIter iter;
+ gboolean valid;
+
+ valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(keyword_store), &iter);
+
+ while (valid)
+ {
+ gtk_tree_model_get (GTK_TREE_MODEL(keyword_store), &iter, 0, &string, -1);
+ string_nl = g_strconcat(string, "\n", NULL);
+ ret_list = g_list_append(ret_list, string);
+ valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(keyword_store), &iter);
+
+ g_free(string_nl);
+ }
+
+ return ret_list;
+}
+
+void keyword_list_set(GList *keyword_list)
+{
+ GList *ret = NULL;
+ GtkTreeIter iter;
+
+ if (!keyword_list) return;
+
+ gtk_list_store_clear(keyword_store);
+
+ while (keyword_list)
+ {
+ gtk_list_store_append (keyword_store, &iter);
+ gtk_list_store_set(keyword_store, &iter, 0, keyword_list->data, -1);
+
+ keyword_list = keyword_list->next;
+ }
+}
+
+gboolean bar_keywords_autocomplete_focus(LayoutWindow *lw)
+{
+ GtkWidget *pane;
+ GtkWidget *current_focus;
+ GList *children;
+ gboolean ret;
+
+ current_focus = gtk_window_get_focus(GTK_WINDOW(lw->window));
+ pane = bar_find_pane_by_id(lw->bar, PANE_KEYWORDS, "keywords");
+
+ children = gtk_container_get_children(GTK_CONTAINER(pane));
+ children = g_list_last(children);
+
+ if (current_focus == children->data)
+ {
+ ret = TRUE;
+ }
+ else
+ {
+ gtk_widget_grab_focus(children->data);
+ ret = FALSE;
+ }
+
+ g_list_free(children);
+
+ return ret;
+}
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
/* used in search.c */
GList *keyword_list_pull(GtkWidget *text_widget);
+GList *keyword_list_get();
+void keyword_list_set(GList *keyword_list);
+gboolean bar_keywords_autocomplete_focus(LayoutWindow *lw);
#endif
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
#include "advanced_exif.h"
#include "bar_sort.h"
#include "bar.h"
+#include "bar_keywords.h"
#include "cache_maint.h"
#include "collect.h"
#include "collect-dlg.h"
metadata_write_queue_confirm(TRUE, NULL, NULL);
}
+static GtkWidget *last_focussed = NULL;
+static void layout_menu_keyword_autocomplete_cb(GtkAction *action, gpointer data)
+{
+ LayoutWindow *lw = data;
+ GtkWidget *tmp;
+ gboolean auto_has_focus;
+
+ tmp = gtk_window_get_focus(GTK_WINDOW(lw->window));
+ auto_has_focus = bar_keywords_autocomplete_focus(lw);
+
+ if (auto_has_focus)
+ {
+ gtk_widget_grab_focus(last_focussed);
+ }
+ else
+ {
+ last_focussed = tmp;
+ }
+}
/*
*-----------------------------------------------------------------------------
{ "Maintenance", PIXBUF_INLINE_ICON_MAINTENANCE, N_("_Cache maintenance..."), NULL, N_("Cache maintenance..."), CB(layout_menu_remove_thumb_cb) },
{ "Wallpaper", NULL, N_("Set as _wallpaper"), NULL, N_("Set as wallpaper"), CB(layout_menu_wallpaper_cb) },
{ "SaveMetadata", GTK_STOCK_SAVE, N_("_Save metadata"), "<control>S", N_("Save metadata"), CB(layout_menu_metadata_write_cb) },
+ { "KeywordAutocomplete", NULL, N_("Keyword autocomplete"), "<alt>K", N_("Keyword Autocomplete"), CB(layout_menu_keyword_autocomplete_cb) },
{ "ZoomIn", GTK_STOCK_ZOOM_IN, N_("Zoom _in"), "equal", N_("Zoom in"), CB(layout_menu_zoom_in_cb) },
{ "ZoomInAlt1", GTK_STOCK_ZOOM_IN, N_("Zoom _in"), "KP_Add", N_("Zoom in"), CB(layout_menu_zoom_in_cb) },
{ "ZoomOut", GTK_STOCK_ZOOM_OUT, N_("Zoom _out"), "minus", N_("Zoom out"), CB(layout_menu_zoom_out_cb) },
" <separator/>"
" </menu>"
" <menuitem action='SaveMetadata'/>"
+" <menuitem action='KeywordAutocomplete'/>"
" <placeholder name='PropertiesSection'/>"
" <separator/>"
" <menuitem action='DrawRectangle'/>"
#include "preferences.h"
#include "bar_exif.h"
+#include "bar_keywords.h"
#include "cache.h"
#include "cache_maint.h"
#include "editors.h"
#include "img-view.h"
#include "layout_config.h"
#include "layout_util.h"
+#include "metadata.h"
#include "pixbuf_util.h"
#include "slideshow.h"
#include "toolbar.h"
#include "utilops.h"
#include "ui_fileops.h"
#include "ui_misc.h"
+#include "ui_spinner.h"
#include "ui_tabcomp.h"
#include "ui_utildlg.h"
#include "window.h"
static void image_overlay_set_text_colours();
+GtkWidget *keyword_text;
+static void config_tab_keywords_save();
+
typedef struct _ThumbSize ThumbSize;
struct _ThumbSize
{
}
#endif
+ config_tab_keywords_save();
+
image_options_sync();
if (refresh)
gtk_widget_set_tooltip_text(ct_button,"On folder change, read DateTimeOriginal, DateTimeDigitized and Star Rating in the idle loop.\nIf this is not selected, initial loading of the folder will be faster but sorting on these items will be slower");
}
+/* keywords tab */
+
+typedef struct _KeywordFindData KeywordFindData;
+struct _KeywordFindData
+{
+ GenericDialog *gd;
+
+ GList *list;
+ GList *list_dir;
+
+ GtkWidget *button_close;
+ GtkWidget *button_stop;
+ GtkWidget *button_start;
+ GtkWidget *progress;
+ GtkWidget *spinner;
+
+ GtkWidget *group;
+ GtkWidget *entry;
+
+ gboolean recurse;
+
+ guint idle_id; /* event source id */
+};
+
+#define KEYWORD_DIALOG_WIDTH 400
+
+static void keywords_find_folder(KeywordFindData *kfd, FileData *dir_fd)
+{
+ GList *list_d = NULL;
+ GList *list_f = NULL;
+
+ if (kfd->recurse)
+ {
+ filelist_read(dir_fd, &list_f, &list_d);
+ }
+ else
+ {
+ filelist_read(dir_fd, &list_f, NULL);
+ }
+
+ list_f = filelist_filter(list_f, FALSE);
+ list_d = filelist_filter(list_d, TRUE);
+
+ kfd->list = g_list_concat(list_f, kfd->list);
+ kfd->list_dir = g_list_concat(list_d, kfd->list_dir);
+}
+
+static void keywords_find_reset(KeywordFindData *kfd)
+{
+ filelist_free(kfd->list);
+ kfd->list = NULL;
+
+ filelist_free(kfd->list_dir);
+ kfd->list_dir = NULL;
+}
+
+static void keywords_find_close_cb(GenericDialog *fd, gpointer data)
+{
+ KeywordFindData *kfd = data;
+
+ if (!gtk_widget_get_sensitive(kfd->button_close)) return;
+
+ keywords_find_reset(kfd);
+ generic_dialog_close(kfd->gd);
+ g_free(kfd);
+}
+
+static void keywords_find_finish(KeywordFindData *kfd)
+{
+ keywords_find_reset(kfd);
+
+ gtk_entry_set_text(GTK_ENTRY(kfd->progress), _("done"));
+ spinner_set_interval(kfd->spinner, -1);
+
+ gtk_widget_set_sensitive(kfd->group, TRUE);
+ gtk_widget_set_sensitive(kfd->button_start, TRUE);
+ gtk_widget_set_sensitive(kfd->button_stop, FALSE);
+ gtk_widget_set_sensitive(kfd->button_close, TRUE);
+}
+
+static void keywords_find_stop_cb(GenericDialog *fd, gpointer data)
+{
+ KeywordFindData *kfd = data;
+
+ g_idle_remove_by_data(kfd);
+
+ keywords_find_finish(kfd);
+}
+
+static gboolean keywords_find_file(gpointer data)
+{
+ KeywordFindData *kfd = data;
+ GtkTextIter iter;
+ GtkTextBuffer *buffer;
+ gchar *tmp;
+ GList *keywords;
+
+ if (kfd->list)
+ {
+ FileData *fd;
+
+ fd = kfd->list->data;
+ kfd->list = g_list_remove(kfd->list, fd);
+
+ keywords = metadata_read_list(fd, KEYWORD_KEY, METADATA_PLAIN);
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyword_text));
+
+ while (keywords)
+ {
+ gtk_text_buffer_get_end_iter(buffer, &iter);
+ tmp = g_strconcat(keywords->data, "\n", NULL);
+ gtk_text_buffer_insert(buffer, &iter, tmp, -1);
+ g_free(tmp);
+ keywords = keywords->next;
+ }
+
+ gtk_entry_set_text(GTK_ENTRY(kfd->progress), fd->path);
+ file_data_unref(fd);
+ string_list_free(keywords);
+
+ return (TRUE);
+ }
+ else if (kfd->list_dir)
+ {
+ FileData *fd;
+
+ fd = kfd->list_dir->data;
+ kfd->list_dir = g_list_remove(kfd->list_dir, fd);
+
+ keywords_find_folder(kfd, fd);
+
+ file_data_unref(fd);
+
+ return TRUE;
+ }
+
+ keywords_find_finish(kfd);
+
+ return FALSE;
+}
+
+static void keywords_find_start_cb(GenericDialog *fd, gpointer data)
+{
+ KeywordFindData *kfd = data;
+ gchar *path;
+
+ if (kfd->list || !gtk_widget_get_sensitive(kfd->button_start)) return;
+
+ path = remove_trailing_slash((gtk_entry_get_text(GTK_ENTRY(kfd->entry))));
+ parse_out_relatives(path);
+
+ if (!isdir(path))
+ {
+ warning_dialog(_("Invalid folder"),
+ _("The specified folder can not be found."),
+ GTK_STOCK_DIALOG_WARNING, kfd->gd->dialog);
+ }
+ else
+ {
+ FileData *dir_fd;
+
+ gtk_widget_set_sensitive(kfd->group, FALSE);
+ gtk_widget_set_sensitive(kfd->button_start, FALSE);
+ gtk_widget_set_sensitive(kfd->button_stop, TRUE);
+ gtk_widget_set_sensitive(kfd->button_close, FALSE);
+ spinner_set_interval(kfd->spinner, SPINNER_SPEED);
+
+ dir_fd = file_data_new_dir(path);
+ keywords_find_folder(kfd, dir_fd);
+ file_data_unref(dir_fd);
+ kfd->idle_id = g_idle_add(keywords_find_file, kfd);
+ }
+
+ g_free(path);
+}
+
+static void keywords_find_dialog(GtkWidget *widget, const gchar *path)
+{
+ KeywordFindData *kfd;
+ GtkWidget *hbox;
+ GtkWidget *label;
+
+ kfd = g_new0(KeywordFindData, 1);
+
+ kfd->gd = generic_dialog_new(_("Search for keywords"),
+ "search_for_keywords",
+ widget, FALSE,
+ NULL, kfd);
+ gtk_window_set_default_size(GTK_WINDOW(kfd->gd->dialog), KEYWORD_DIALOG_WIDTH, -1);
+ kfd->gd->cancel_cb = keywords_find_close_cb;
+ kfd->button_close = generic_dialog_add_button(kfd->gd, GTK_STOCK_CLOSE, NULL,
+ keywords_find_close_cb, FALSE);
+ kfd->button_start = generic_dialog_add_button(kfd->gd, GTK_STOCK_OK, _("S_tart"),
+ keywords_find_start_cb, FALSE);
+ kfd->button_stop = generic_dialog_add_button(kfd->gd, GTK_STOCK_STOP, NULL,
+ keywords_find_stop_cb, FALSE);
+ gtk_widget_set_sensitive(kfd->button_stop, FALSE);
+
+ generic_dialog_add_message(kfd->gd, NULL, _("Search for keywords"), NULL, FALSE);
+
+ hbox = pref_box_new(kfd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, 0);
+ pref_spacer(hbox, PREF_PAD_INDENT);
+ kfd->group = pref_box_new(hbox, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
+
+ hbox = pref_box_new(kfd->group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
+ pref_label_new(hbox, _("Folder:"));
+
+ label = tab_completion_new(&kfd->entry, path, NULL, NULL, NULL, NULL);
+ tab_completion_add_select_button(kfd->entry,_("Select folder") , TRUE);
+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+ gtk_widget_show(label);
+
+ pref_checkbox_new_int(kfd->group, _("Include subfolders"), FALSE, &kfd->recurse);
+
+ pref_line(kfd->gd->vbox, PREF_PAD_SPACE);
+ hbox = pref_box_new(kfd->gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
+
+ kfd->progress = gtk_entry_new();
+ gtk_widget_set_can_focus(kfd->progress, FALSE);
+ gtk_editable_set_editable(GTK_EDITABLE(kfd->progress), FALSE);
+ gtk_entry_set_text(GTK_ENTRY(kfd->progress), _("click start to begin"));
+ gtk_box_pack_start(GTK_BOX(hbox), kfd->progress, TRUE, TRUE, 0);
+ gtk_widget_show(kfd->progress);
+
+ kfd->spinner = spinner_new(NULL, -1);
+ gtk_box_pack_start(GTK_BOX(hbox), kfd->spinner, FALSE, FALSE, 0);
+ gtk_widget_show(kfd->spinner);
+
+ kfd->list = NULL;
+
+ gtk_widget_show(kfd->gd->dialog);
+}
+
+static void keywords_find_cb(GtkWidget *widget, gpointer data)
+{
+ const gchar *path = layout_get_path(NULL);
+
+ if (!path || !*path) path = homedir();
+ keywords_find_dialog(widget, path);
+}
+
+static void config_tab_keywords_save()
+{
+ GtkTextIter start, end;
+ GtkTextBuffer *buffer;
+ GList *kw_list = NULL;
+ GList *work;
+ gchar *buffer_text;
+ gchar *kw_split;
+ gboolean found;
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyword_text));
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+
+ buffer_text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
+
+ kw_split = strtok(buffer_text, "\n");
+ while (kw_split != NULL)
+ {
+ work = kw_list;
+ found = FALSE;
+ while (work)
+ {
+ if (g_strcmp0(work->data, kw_split) == 0)
+ {
+ found = TRUE;
+ break;
+ }
+ work = work->next;
+ }
+ if (!found)
+ {
+ kw_list = g_list_append(kw_list, g_strdup(kw_split));
+ }
+ kw_split = strtok(NULL, "\n");
+ }
+
+ keyword_list_set(kw_list);
+
+ string_list_free(kw_list);
+ g_free(buffer_text);
+}
+
+static void config_tab_keywords(GtkWidget *notebook)
+{
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *group;
+ GtkWidget *button;
+ GtkWidget *scrolled;
+ GtkTextIter iter;
+ GtkTextBuffer *buffer;
+ gchar *tmp;
+
+ vbox = scrolled_notebook_page(notebook, _("Keywords"));
+
+ group = pref_group_new(vbox, TRUE, _("Edit keywords autocompletion list"), GTK_ORIENTATION_VERTICAL);
+
+ hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP);
+
+ button = pref_button_new(hbox, GTK_STOCK_EXECUTE, _("Search"), FALSE,
+ G_CALLBACK(keywords_find_cb), keyword_text);
+ gtk_widget_set_tooltip_text(button, "Search for existing keywords");
+
+
+ keyword_text = gtk_text_view_new();
+ gtk_widget_set_size_request(keyword_text, 20, 20);
+ scrolled = gtk_scrolled_window_new(NULL, NULL);
+ gtk_box_pack_start(GTK_BOX(group), scrolled, TRUE, TRUE, 0);
+ gtk_widget_show(scrolled);
+
+ gtk_container_add(GTK_CONTAINER(scrolled), keyword_text);
+ gtk_widget_show(keyword_text);
+
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(keyword_text), TRUE);
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyword_text));
+ gtk_text_buffer_create_tag(buffer, "monospace",
+ "family", "monospace", NULL);
+
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(keyword_text), GTK_WRAP_WORD);
+ gtk_text_buffer_get_start_iter(buffer, &iter);
+ gtk_text_buffer_create_mark(buffer, "end", &iter, FALSE);
+ gchar *path;
+
+ path = g_build_filename(get_rc_dir(), "keywords", NULL);
+
+ GList *kwl = keyword_list_get();
+ kwl = g_list_first(kwl);
+ while (kwl)
+ {
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ tmp = g_strconcat(kwl->data, "\n", NULL);
+ gtk_text_buffer_insert(buffer, &iter, tmp, -1);
+ kwl = kwl->next;
+ g_free(tmp);
+ }
+
+ gtk_text_buffer_set_modified(buffer, FALSE);
+
+ g_free(path);
+}
+
/* metadata tab */
#ifdef HAVE_LCMS
static void intent_menu_cb(GtkWidget *combo, gpointer data)
config_tab_accelerators(notebook);
config_tab_files(notebook);
config_tab_metadata(notebook);
+ config_tab_keywords(notebook);
config_tab_color(notebook);
config_tab_stereo(notebook);
config_tab_behavior(notebook);
<span class="label">11.6. </span><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a>
</li>
<li>
-<span class="label">11.7. </span><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a>
+<span class="label">11.7. </span><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a>
</li>
<li>
-<span class="label">11.8. </span><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a>
+<span class="label">11.8. </span><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a>
</li>
<li>
-<span class="label">11.9. </span><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a>
+<span class="label">11.9. </span><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a>
</li>
<li>
-<span class="label">11.10. </span><a class="xref" href="GuideOptionsToolbar.html" title="Toolbar">Toolbar</a>
+<span class="label">11.10. </span><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a>
+</li>
+<li>
+<span class="label">11.11. </span><a class="xref" href="GuideOptionsToolbar.html" title="Toolbar">Toolbar</a>
</li>
</ul></div>
</li>
<li><a class="xref" href="GuideOptionsKeyboard.html" title="Keyboard Options">Keyboard Options</a></li>
<li><a class="xref" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></li>
<li><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a></li>
<li><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></li>
<li>Behavior Options</li>
<p class="para block block-first">This section describes the options presented under the Behavior Tab of the preferences dialog.</p>
<div class="autotoc"><ul>
<li>
-<span class="label">11.9.1. </span><a class="xref" href="GuideOptionsBehavior.html#Delete" title="Delete">Delete</a>
+<span class="label">11.10.1. </span><a class="xref" href="GuideOptionsBehavior.html#Delete" title="Delete">Delete</a>
</li>
<li>
-<span class="label">11.9.2. </span><a class="xref" href="GuideOptionsBehavior.html#Behaviour" title="Behavior">Behavior</a>
+<span class="label">11.10.2. </span><a class="xref" href="GuideOptionsBehavior.html#Behaviour" title="Behavior">Behavior</a>
</li>
<li>
-<span class="label">11.9.3. </span><a class="xref" href="GuideOptionsBehavior.html#Navigation" title="Navigation">Navigation</a>
+<span class="label">11.10.3. </span><a class="xref" href="GuideOptionsBehavior.html#Navigation" title="Navigation">Navigation</a>
</li>
<li>
-<span class="label">11.9.4. </span><a class="xref" href="GuideOptionsBehavior.html#Debugging" title="Debugging">Debugging</a>
+<span class="label">11.10.4. </span><a class="xref" href="GuideOptionsBehavior.html#Debugging" title="Debugging">Debugging</a>
</li>
</ul></div>
<div class="division section">
-<a name="Delete"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">11.9.1. </span>Delete</span></h2></div>
+<a name="Delete"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">11.10.1. </span>Delete</span></h2></div>
<div class="block list variablelist"><dl class="variablelist">
<dt class="term dt-first">
<span class="guilabel">Confirm file delete</span>
</dl></div>
</div>
<div class="division section">
-<a name="Behaviour"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">11.9.2. </span>Behavior</span></h2></div>
+<a name="Behaviour"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">11.10.2. </span>Behavior</span></h2></div>
<div class="block list variablelist"><dl class="variablelist">
<dt class="term dt-first">
<span class="guilabel">Descend folders in tree view</span>
</dl></div>
</div>
<div class="division section">
-<a name="Navigation"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">11.9.3. </span>Navigation</span></h2></div>
+<a name="Navigation"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">11.10.3. </span>Navigation</span></h2></div>
<div class="block list variablelist"><dl class="variablelist">
<dt class="term dt-first">
<span class="guilabel">Progressive keyboard scrolling</span>
</dl></div>
</div>
<div class="division section">
-<a name="Debugging"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">11.9.4. </span>Debugging</span></h2></div>
+<a name="Debugging"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">11.10.4. </span>Debugging</span></h2></div>
<div class="block list variablelist"><dl class="variablelist">
<dt class="term dt-first">
<span class="guilabel">Debug level</span>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Color management options</title>
-<link rel="previous" href="GuideOptionsMetadata.html" title="Metadata">
+<link rel="previous" href="GuideOptionsKeywords.html" title="Keywords">
<link rel="next" href="GuideOptionsStereo.html" title="Stereo image management">
<link rel="top" href="GuideIndex.html" title="The Geeqie User Manual">
<style type="text/css">
</head>
<body>
<div class="navbar navbar-top"><table class="navbar"><tr>
-<td class="navbar-prev"><a class="navbar-prev" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></td>
+<td class="navbar-prev"><a class="navbar-prev" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></td>
<td class="navbar-next"><a class="navbar-next" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></td>
</tr></table></div>
<div class="sidebar"><div class="sidenav"><div class="autotoc"><ul>
<li><a class="xref" href="GuideOptionsKeyboard.html" title="Keyboard Options">Keyboard Options</a></li>
<li><a class="xref" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></li>
<li><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li>Color management options</li>
<li><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></li>
<li><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a></li>
</dl></div>
</div></div>
<div class="navbar navbar-bottom"><table class="navbar"><tr>
-<td class="navbar-prev"><a class="navbar-prev" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></td>
+<td class="navbar-prev"><a class="navbar-prev" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></td>
<td class="navbar-next"><a class="navbar-next" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></td>
</tr></table></div>
</body>
<li><a class="xref" href="GuideOptionsKeyboard.html" title="Keyboard Options">Keyboard Options</a></li>
<li>Files Options</li>
<li><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a></li>
<li><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></li>
<li><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a></li>
<li><a class="xref" href="GuideOptionsKeyboard.html" title="Keyboard Options">Keyboard Options</a></li>
<li><a class="xref" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></li>
<li><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a></li>
<li><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></li>
<li><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a></li>
<li><a class="xref" href="GuideOptionsKeyboard.html" title="Keyboard Options">Keyboard Options</a></li>
<li><a class="xref" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></li>
<li><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a></li>
<li><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></li>
<li><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a></li>
<li>Keyboard Options</li>
<li><a class="xref" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></li>
<li><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a></li>
<li><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></li>
<li><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a></li>
<li><a class="xref" href="GuideOptionsKeyboard.html" title="Keyboard Options">Keyboard Options</a></li>
<li><a class="xref" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></li>
<li><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a></li>
<li><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></li>
<li><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a></li>
<span class="label">11.6. </span><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a>
</li>
<li>
-<span class="label">11.7. </span><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a>
+<span class="label">11.7. </span><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a>
</li>
<li>
-<span class="label">11.8. </span><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a>
+<span class="label">11.8. </span><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a>
</li>
<li>
-<span class="label">11.9. </span><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a>
+<span class="label">11.9. </span><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a>
</li>
<li>
-<span class="label">11.10. </span><a class="xref" href="GuideOptionsToolbar.html" title="Toolbar">Toolbar</a>
+<span class="label">11.10. </span><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a>
+</li>
+<li>
+<span class="label">11.11. </span><a class="xref" href="GuideOptionsToolbar.html" title="Toolbar">Toolbar</a>
</li>
</ul></div>
</div></div>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Metadata</title>
<link rel="previous" href="GuideOptionsFiltering.html" title="Files Options">
-<link rel="next" href="GuideOptionsColor.html" title="Color management options">
+<link rel="next" href="GuideOptionsKeywords.html" title="Keywords">
<link rel="top" href="GuideIndex.html" title="The Geeqie User Manual">
<style type="text/css">
<body>
<div class="navbar navbar-top"><table class="navbar"><tr>
<td class="navbar-prev"><a class="navbar-prev" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></td>
-<td class="navbar-next"><a class="navbar-next" href="GuideOptionsColor.html" title="Color management options">Color management options</a></td>
+<td class="navbar-next"><a class="navbar-next" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></td>
</tr></table></div>
<div class="sidebar"><div class="sidenav"><div class="autotoc"><ul>
<li><a href="GuideIndex-info.html" title="About This Document">About This Document</a></li>
<li><a class="xref" href="GuideOptionsKeyboard.html" title="Keyboard Options">Keyboard Options</a></li>
<li><a class="xref" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></li>
<li>Metadata</li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a></li>
<li><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></li>
<li><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a></li>
</div></div>
<div class="navbar navbar-bottom"><table class="navbar"><tr>
<td class="navbar-prev"><a class="navbar-prev" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></td>
-<td class="navbar-next"><a class="navbar-next" href="GuideOptionsColor.html" title="Color management options">Color management options</a></td>
+<td class="navbar-next"><a class="navbar-next" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></td>
</tr></table></div>
</body>
</html>
<li><a class="xref" href="GuideOptionsKeyboard.html" title="Keyboard Options">Keyboard Options</a></li>
<li><a class="xref" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></li>
<li><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a></li>
<li>Stereo image management</li>
<li><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a></li>
<li><a class="xref" href="GuideOptionsKeyboard.html" title="Keyboard Options">Keyboard Options</a></li>
<li><a class="xref" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></li>
<li><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a></li>
<li><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></li>
<li><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a></li>
<li><a class="xref" href="GuideOptionsKeyboard.html" title="Keyboard Options">Keyboard Options</a></li>
<li><a class="xref" href="GuideOptionsFiltering.html" title="Files Options">Files Options</a></li>
<li><a class="xref" href="GuideOptionsMetadata.html" title="Metadata">Metadata</a></li>
+<li><a class="xref" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a></li>
<li><a class="xref" href="GuideOptionsColor.html" title="Color management options">Color management options</a></li>
<li><a class="xref" href="GuideOptionsStereo.html" title="Stereo image management">Stereo image management</a></li>
<li><a class="xref" href="GuideOptionsBehavior.html" title="Behavior Options">Behavior Options</a></li>
<span class="label">3.1.4. </span><a class="xref" href="GuideSidebarsInfo.html#Keywords" title="Keywords">Keywords</a>
</li>
<li>
-<span class="label">3.1.5. </span><a class="xref" href="GuideSidebarsInfo.html#Listpanes-ExifFileinfoCopyrightLocationandGPS" title="List panes">List panes</a>
+<span class="label">3.1.5. </span><a class="xref" href="GuideSidebarsInfo.html#KeywordAutocompletion" title="Keyword Autocompletion">Keyword Autocompletion</a>
</li>
<li>
-<span class="label">3.1.6. </span><a class="xref" href="GuideSidebarsInfo.html#GPSMap" title="Map Display">Map Display</a>
+<span class="label">3.1.6. </span><a class="xref" href="GuideSidebarsInfo.html#Listpanes-ExifFileinfoCopyrightLocationandGPS" title="List panes">List panes</a>
+</li>
+<li>
+<span class="label">3.1.7. </span><a class="xref" href="GuideSidebarsInfo.html#GPSMap" title="Map Display">Map Display</a>
</li>
</ul></div>
<div class="division section">
<p class="para block"></p>
</div>
<div class="division section">
-<a name="Listpanes-ExifFileinfoCopyrightLocationandGPS"></a><div class="header"><h2 class="section title"><span class="title"><a name="titleExif"></a><span class="label">3.1.5. </span>List panes</span></h2></div>
+<a name="KeywordAutocompletion"></a><div class="header"><h2 class="section title"><span class="title"><a name="titleKeywordAutocompletion"></a><span class="label">3.1.5. </span>Keyword Autocompletion</span></h2></div>
+<p class="para block block-first">
+ The text box at the bottom of the keywords pane is used for autocompletion. Any keywords typed into the standard keyword box or the autocompletion box will be remembered as candidates for future autocompletion.
+ <p class="para block block-first"></p>
+ Frequently used sets of keywords can be entered as comma-delimited lists.
+ <p class="para block"></p>
+ The list of keywords used for autocompletion can be edited on the
+ <a class="link" href="GuideOptionsKeywords.html" title="Keywords">Keywords</a>
+ tab of the Preferences dialog.
+ <p class="para block"></p>
+ The menu action "Keyword autocomplete", set to
+ <span class="code" dir="ltr">Alt + K</span>
+ by default, will shift the keyboard focus to the autocomplete box. Pressing
+ <span class="code" dir="ltr">Alt + K</span>
+ a second time will shift the keyboard focus back to the previous object.
+ </p>
+<p class="para block"></p>
+</div>
+<div class="division section">
+<a name="Listpanes-ExifFileinfoCopyrightLocationandGPS"></a><div class="header"><h2 class="section title"><span class="title"><a name="titleExif"></a><span class="label">3.1.6. </span>List panes</span></h2></div>
<p class="para block block-first">
There are five list panes, whose contents can be configured to display Exif, XMP or IPTC metadata tags. The five panes are:
<div class="block list itemizedlist"><ul class="itemizedlist">
<p class="para block"></p>
</div>
<div class="division section">
-<a name="GPSMap"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">3.1.6. </span>Map Display</span></h2></div>
+<a name="GPSMap"></a><div class="header"><h2 class="section title"><span class="title"><span class="label">3.1.7. </span>Map Display</span></h2></div>
<p class="para block block-first">
Geeqie can display maps created by the
<a class="ulink" href="https://www.openstreetmap.org" title="https://www.openstreetmap.org">openstreetmap.org</a>