changeset 2752:829c6cb08dd9

Mnemonic text for marks The marks check boxes at the top of the file pane have tooltips that may be used to describe each mark. The text can be modified by right-click.
author Colin Clark <colin.clark@cclark.uk>
date Sun, 06 May 2018 16:55:11 +0100
parents 59db4be809a8
children 9ab20f827272
files doc/docbook/GuideImageMarks.xml src/options.c src/options.h src/rcfile.c src/view_file/view_file.c
diffstat 5 files changed, 164 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/doc/docbook/GuideImageMarks.xml	Sun May 06 09:40:30 2018 +0100
+++ b/doc/docbook/GuideImageMarks.xml	Sun May 06 16:55:11 2018 +0100
@@ -17,6 +17,7 @@
     <guimenu>Show Marks</guimenu>
     menu has been selected, each image will have a set of 10 check-boxes displayed adjacent to it in the file pane in both icon and list mode. In addition a set of 10 check-boxes will be shown at the top of the files pane. Clicking any of these will filter the displayed list.
   </para>
+  <para>Moving the mouse over any of the check-boxes at the top of the files pane will show mnemonic text for that mark. The text can be modified by right-clicking on the check box.</para>
   <para>
     If the
     <link linkend="InformationandhistogramOverlay" endterm="titleInformationandhistogramOverlay" />
--- a/src/options.c	Sun May 06 09:40:30 2018 +0100
+++ b/src/options.c	Sun May 06 16:55:11 2018 +0100
@@ -34,6 +34,8 @@
 
 ConfOptions *init_options(ConfOptions *options)
 {
+	gint i;
+
 	if (!options) options = g_new0(ConfOptions, 1);
 
 	options->collections.rectangular_selection = FALSE;
@@ -80,6 +82,10 @@
 	options->fullscreen.screen = -1;
 
 	options->marks_save = TRUE;
+	for (i = 0; i < FILEDATA_MARKS_SIZE; i++)
+		{
+		options->marks_tooltips[i] = g_strdup_printf("%s%d", _("Mark "), i + 1);
+		}
 
 	memset(&options->image.border_color, 0, sizeof(options->image.border_color));
 	memset(&options->image.alpha_color_1, 0, sizeof(options->image.alpha_color_1));
--- a/src/options.h	Sun May 06 09:40:30 2018 +0100
+++ b/src/options.h	Sun May 06 16:55:11 2018 +0100
@@ -62,6 +62,7 @@
 	gint log_window_lines;
 
 	gboolean marks_save;		// save marks on exit
+	gchar *marks_tooltips[FILEDATA_MARKS_SIZE];
 
 	/* info sidebar component heights */
 	struct {
--- a/src/rcfile.c	Sun May 06 09:40:30 2018 +0100
+++ b/src/rcfile.c	Sun May 06 16:55:11 2018 +0100
@@ -512,6 +512,22 @@
 	WRITE_NL(); WRITE_STRING("</color_profiles>");
 }
 
+static void write_marks_tooltips(GString *outstr, gint indent)
+{
+	gint i;
+
+	WRITE_NL(); WRITE_STRING("<marks_tooltips>");
+	indent++;
+	for (i = 0; i < FILEDATA_MARKS_SIZE; i++)
+		{
+		WRITE_NL();
+		write_char_option(outstr, indent, "<tooltip text", options->marks_tooltips[i]);
+		WRITE_STRING("/>");
+		}
+	indent--;
+	WRITE_NL(); WRITE_STRING("</marks_tooltips>");
+}
+
 
 /*
  *-----------------------------------------------------------------------------
@@ -566,6 +582,9 @@
 	filter_write_list(outstr, indent);
 
 	WRITE_SEPARATOR();
+	write_marks_tooltips(outstr, indent);
+
+	WRITE_SEPARATOR();
 	keyword_tree_write_config(outstr, indent);
 	indent--;
 	WRITE_NL(); WRITE_STRING("</global>\n");
@@ -831,7 +850,22 @@
 
 }
 
+static void options_load_marks_tooltips(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
+{
+	gint i = GPOINTER_TO_INT(data);
+	if (i < 0 || i >= FILEDATA_MARKS_SIZE) return;
+	while (*attribute_names)
+		{
+		const gchar *option = *attribute_names++;
+		const gchar *value = *attribute_values++;
+		if (READ_CHAR_FULL("text",  options->marks_tooltips[i])) continue;
 
+		log_printf("unkown attribute %s = %s\n", option, value);
+		}
+	i++;
+	options_parse_func_set_data(parser_data, GINT_TO_POINTER(i));
+
+}
 
 /*
  *-----------------------------------------------------------------------------
@@ -878,6 +912,20 @@
 		}
 }
 
+static void options_parse_marks_tooltips(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
+{
+	if (g_ascii_strcasecmp(element_name, "tooltip") == 0)
+		{
+		options_load_marks_tooltips(parser_data, context, element_name, attribute_names, attribute_values, data, error);
+		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+		}
+	else
+		{
+		log_printf("unexpected in <profile>: <%s>\n", element_name);
+		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+		}
+}
+
 static void options_parse_filter(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
 {
 	if (g_ascii_strcasecmp(element_name, "file_type") == 0)
@@ -948,6 +996,11 @@
 		{
 		options_parse_func_push(parser_data, options_parse_filter, options_parse_filter_end, NULL);
 		}
+	else if (g_ascii_strcasecmp(element_name, "marks_tooltips") == 0)
+		{
+		options_load_marks_tooltips(parser_data, context, element_name, attribute_names, attribute_values, data, error);
+		options_parse_func_push(parser_data, options_parse_marks_tooltips, NULL, NULL);
+		}
 	else if (g_ascii_strcasecmp(element_name, "keyword_tree") == 0)
 		{
 		if (!keyword_tree) keyword_tree_new();
--- a/src/view_file/view_file.c	Sun May 06 09:40:30 2018 +0100
+++ b/src/view_file/view_file.c	Sun May 06 16:55:11 2018 +0100
@@ -30,9 +30,11 @@
 #include "thumb.h"
 #include "ui_menu.h"
 #include "ui_fileops.h"
+#include "ui_misc.h"
 #include "utilops.h"
 #include "view_file/view_file_list.h"
 #include "view_file/view_file_icon.h"
+#include "window.h"
 
 /*
  *-----------------------------------------------------------------------------
@@ -706,6 +708,104 @@
 	vf_refresh_idle(vf);
 }
 
+typedef struct _MarksTextEntry MarksTextEntry;
+struct _MarksTextEntry {
+	GenericDialog *gd;
+	gint mark_no;
+	GtkWidget *edit_widget;
+	gchar *text_entry;
+	GtkWidget *parent;
+};
+
+static void vf_marks_tooltip_cancel_cb(GenericDialog *gd, gpointer data)
+{
+	MarksTextEntry *mte = data;
+
+	g_free(mte->text_entry);
+	generic_dialog_close(gd);
+}
+
+static void vf_marks_tooltip_ok_cb(GenericDialog *gd, gpointer data)
+{
+	MarksTextEntry *mte = data;
+
+	g_free(options->marks_tooltips[mte->mark_no]);
+	options->marks_tooltips[mte->mark_no] = g_strdup(gtk_entry_get_text(GTK_ENTRY(mte->edit_widget)));
+
+	gtk_widget_set_tooltip_text(mte->parent, options->marks_tooltips[mte->mark_no]);
+
+	g_free(mte->text_entry);
+	generic_dialog_close(gd);
+}
+
+void vf_marks_filter_on_icon_press(GtkEntry *entry, GtkEntryIconPosition pos,
+									GdkEvent *event, gpointer userdata)
+{
+	MarksTextEntry *mte = userdata;
+
+	g_free(mte->text_entry);
+	mte->text_entry = g_strdup("");
+	gtk_entry_set_text(GTK_ENTRY(mte->edit_widget), "");
+}
+
+static void vf_marks_tooltip_help_cb(GenericDialog *gd, gpointer data)
+{
+	help_window_show("GuideImageMarks.html");
+}
+
+static gboolean vf_marks_tooltip_cb(GtkWidget *widget,
+										GdkEventButton *event,
+										gpointer user_data)
+{
+	GtkWidget *table;
+	gint i = GPOINTER_TO_INT(user_data);
+	MarksTextEntry *mte;
+
+	if (event->button == MOUSE_BUTTON_RIGHT)
+		{
+		mte = g_new0(MarksTextEntry, 1);
+		mte->mark_no = i;
+		mte->text_entry = g_strdup(options->marks_tooltips[i]);
+		mte->parent = widget;
+
+		mte->gd = generic_dialog_new(_("Mark text"), "mark_text",
+						widget, FALSE,
+						vf_marks_tooltip_cancel_cb, mte);
+		generic_dialog_add_message(mte->gd, GTK_STOCK_DIALOG_QUESTION, _("Set mark text"),
+					    _("This will set or clear the mark text."), FALSE);
+		generic_dialog_add_button(mte->gd, GTK_STOCK_OK, NULL,
+							vf_marks_tooltip_ok_cb, TRUE);
+		generic_dialog_add_button(mte->gd, GTK_STOCK_HELP, NULL,
+						vf_marks_tooltip_help_cb, FALSE);
+
+		table = pref_table_new(mte->gd->vbox, 3, 1, FALSE, TRUE);
+		pref_table_label(table, 0, 0, g_strdup_printf("%s%d", _("Mark "), mte->mark_no + 1), 1.0);
+		mte->edit_widget = gtk_entry_new();
+		gtk_widget_set_size_request(mte->edit_widget, 300, -1);
+		if (mte->text_entry)
+			{
+			gtk_entry_set_text(GTK_ENTRY(mte->edit_widget), mte->text_entry);
+			}
+		gtk_table_attach_defaults(GTK_TABLE(table), mte->edit_widget, 1, 2, 0, 1);
+		generic_dialog_attach_default(mte->gd, mte->edit_widget);
+
+		gtk_entry_set_icon_from_stock(GTK_ENTRY(mte->edit_widget),
+							GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
+		gtk_entry_set_icon_tooltip_text (GTK_ENTRY(mte->edit_widget),
+							GTK_ENTRY_ICON_SECONDARY, "Clear");
+		g_signal_connect(GTK_ENTRY(mte->edit_widget), "icon-press",
+							G_CALLBACK(vf_marks_filter_on_icon_press), mte);
+
+		gtk_widget_show(mte->edit_widget);
+		gtk_widget_grab_focus(mte->edit_widget);
+		gtk_widget_show(GTK_WIDGET(mte->gd->dialog));
+
+		return TRUE;
+		}
+
+	return FALSE;
+}
+
 
 static GtkWidget *vf_marks_filter_init(ViewFile *vf)
 {
@@ -720,6 +820,9 @@
 		gtk_box_pack_start(GTK_BOX(hbox), check, FALSE, FALSE, 0);
 		g_signal_connect(G_OBJECT(check), "toggled",
 			 G_CALLBACK(vf_marks_filter_toggle_cb), vf);
+		g_signal_connect(G_OBJECT(check), "button_press_event",
+			 G_CALLBACK(vf_marks_tooltip_cb), GINT_TO_POINTER(i));
+		gtk_widget_set_tooltip_text(check, options->marks_tooltips[i]);
 
 		gtk_widget_show(check);
 		vf->filter_check[i] = check;