[geany/geany-plugins] 8932d2: Merge pull request #481 from eht16/issue445_markall_single_click

Enrico Tröger git-noreply at xxxxx
Sun Sep 11 09:11:31 UTC 2016


Branch:      refs/heads/master
Author:      Enrico Tröger <enrico.troeger at uvena.de>
Committer:   GitHub <noreply at github.com>
Date:        Sun, 11 Sep 2016 09:11:31 UTC
Commit:      8932d2e92865a887757163dfc4d3af5e2bfd1d64
             https://github.com/geany/geany-plugins/commit/8932d2e92865a887757163dfc4d3af5e2bfd1d64

Log Message:
-----------
Merge pull request #481 from eht16/issue445_markall_single_click

Addons: Implement deselect with single click


Modified Paths:
--------------
    addons/src/addons.c
    addons/src/ao_markword.c
    addons/src/ao_markword.h

Modified: addons/src/addons.c
45 lines changed, 40 insertions(+), 5 deletions(-)
===================================================================
@@ -77,6 +77,7 @@ typedef struct
 	gboolean enable_systray;
 	gboolean enable_bookmarklist;
 	gboolean enable_markword;
+	gboolean enable_markword_single_click_deselect;
 	gboolean enable_xmltagging;
 	gboolean enable_enclose_words;
 	gboolean enable_enclose_words_auto;
@@ -175,7 +176,6 @@ gboolean ao_editor_notify_cb(GObject *object, GeanyEditor *editor,
 							 SCNotification *nt, gpointer data)
 {
 	ao_bookmark_list_update_marker(ao_info->bookmarklist, editor, nt);
-	ao_mark_word_check(ao_info->markword, editor, nt);
 
 	return FALSE;
 }
@@ -204,6 +204,7 @@ static void ao_document_open_cb(GObject *obj, GeanyDocument *doc, gpointer data)
 	g_return_if_fail(doc != NULL && doc->is_valid);
 
 	ao_tasks_update(ao_info->tasks, doc);
+	ao_mark_document_open(ao_info->markword, doc);
 }
 
 
@@ -212,6 +213,7 @@ static void ao_document_close_cb(GObject *obj, GeanyDocument *doc, gpointer data
 	g_return_if_fail(doc != NULL && doc->is_valid);
 
 	ao_tasks_remove(ao_info->tasks, doc);
+	ao_mark_document_close(ao_info->markword, doc);
 }
 
 
@@ -280,6 +282,8 @@ void plugin_init(GeanyData *data)
 		"addons", "enable_bookmarklist", FALSE);
 	ao_info->enable_markword = utils_get_setting_boolean(config,
 		"addons", "enable_markword", FALSE);
+	ao_info->enable_markword_single_click_deselect = utils_get_setting_boolean(config,
+		"addons", "enable_markword_single_click_deselect", FALSE);
 	ao_info->strip_trailing_blank_lines = utils_get_setting_boolean(config,
 		"addons", "strip_trailing_blank_lines", FALSE);
 	ao_info->enable_xmltagging = utils_get_setting_boolean(config, "addons",
@@ -295,7 +299,8 @@ void plugin_init(GeanyData *data)
 	ao_info->openuri = ao_open_uri_new(ao_info->enable_openuri);
 	ao_info->systray = ao_systray_new(ao_info->enable_systray);
 	ao_info->bookmarklist = ao_bookmark_list_new(ao_info->enable_bookmarklist);
-	ao_info->markword = ao_mark_word_new(ao_info->enable_markword);
+	ao_info->markword = ao_mark_word_new(ao_info->enable_markword,
+		ao_info->enable_markword_single_click_deselect);
 	ao_info->tasks = ao_tasks_new(ao_info->enable_tasks,
 						ao_info->tasks_token_list, ao_info->tasks_scan_all_documents);
 	ao_info->copyfilepath = ao_copy_file_path_new();
@@ -332,6 +337,15 @@ static void ao_configure_tasks_toggled_cb(GtkToggleButton *togglebutton, gpointe
 }
 
 
+static void ao_configure_markword_toggled_cb(GtkToggleButton *togglebutton, gpointer data)
+{
+	gboolean sens = gtk_toggle_button_get_active(togglebutton);
+
+	gtk_widget_set_sensitive(g_object_get_data(
+		G_OBJECT(data), "check_markword_single_click_deselect"), sens);
+}
+
+
 static void ao_configure_doclist_toggled_cb(GtkToggleButton *togglebutton, gpointer data)
 {
 	gboolean sens = gtk_toggle_button_get_active(togglebutton);
@@ -379,6 +393,8 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 			g_object_get_data(G_OBJECT(dialog), "check_bookmarklist"))));
 		ao_info->enable_markword = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
 			g_object_get_data(G_OBJECT(dialog), "check_markword"))));
+		ao_info->enable_markword_single_click_deselect = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+			g_object_get_data(G_OBJECT(dialog), "check_markword_single_click_deselect"))));
 		ao_info->strip_trailing_blank_lines = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
 			g_object_get_data(G_OBJECT(dialog), "check_blanklines"))));
 		ao_info->enable_xmltagging = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
@@ -403,6 +419,8 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 		g_key_file_set_boolean(config, "addons", "enable_bookmarklist",
 			ao_info->enable_bookmarklist);
 		g_key_file_set_boolean(config, "addons", "enable_markword", ao_info->enable_markword);
+		g_key_file_set_boolean(config, "addons", "enable_markword_single_click_deselect",
+			ao_info->enable_markword_single_click_deselect);
 		g_key_file_set_boolean(config, "addons", "strip_trailing_blank_lines",
 		  ao_info->strip_trailing_blank_lines);
 		g_key_file_set_boolean(config, "addons", "enable_xmltagging",
@@ -418,7 +436,10 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 		g_object_set(ao_info->systray, "enable-systray", ao_info->enable_systray, NULL);
 		g_object_set(ao_info->bookmarklist, "enable-bookmarklist",
 			ao_info->enable_bookmarklist, NULL);
-		g_object_set(ao_info->markword, "enable-markword", ao_info->enable_markword, NULL);
+		g_object_set(ao_info->markword,
+			"enable-markword", ao_info->enable_markword,
+			"enable-single-click-deselect", ao_info->enable_markword_single_click_deselect,
+			NULL);
 		g_object_set(ao_info->tasks,
 			"enable-tasks", ao_info->enable_tasks,
 			"scan-all-documents", ao_info->tasks_scan_all_documents,
@@ -449,7 +470,8 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
 	GtkWidget *vbox, *check_openuri, *check_tasks, *check_systray;
 	GtkWidget *check_doclist, *vbox_doclist, *frame_doclist;
 	GtkWidget *radio_doclist_name, *radio_doclist_tab_order, *radio_doclist_tab_order_reversed;
-	GtkWidget *check_bookmarklist, *check_markword, *frame_tasks, *vbox_tasks;
+	GtkWidget *check_bookmarklist, *check_markword, *check_markword_single_click_deselect;
+	GtkWidget *frame_markword, *frame_tasks, *vbox_tasks;
 	GtkWidget *check_tasks_scan_mode, *entry_tasks_tokens, *label_tasks_tokens, *tokens_hbox;
 	GtkWidget *check_blanklines, *check_xmltagging;
 	GtkWidget *check_enclose_words, *check_enclose_words_auto, *enclose_words_config_button, *enclose_words_hbox;
@@ -557,7 +579,17 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
 		_("Mark all occurrences of a word when double-clicking it"));
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_markword),
 		ao_info->enable_markword);
-	gtk_box_pack_start(GTK_BOX(vbox), check_markword, FALSE, FALSE, 3);
+	g_signal_connect(check_markword, "toggled", G_CALLBACK(ao_configure_markword_toggled_cb), dialog);
+
+	check_markword_single_click_deselect = gtk_check_button_new_with_label(
+		_("Deselect a previous highlight by single click"));
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_markword_single_click_deselect),
+		ao_info->enable_markword_single_click_deselect);
+
+	frame_markword = gtk_frame_new(NULL);
+	gtk_frame_set_label_widget(GTK_FRAME(frame_markword), check_markword);
+	gtk_container_add(GTK_CONTAINER(frame_markword), check_markword_single_click_deselect);
+	gtk_box_pack_start(GTK_BOX(vbox), frame_markword, FALSE, FALSE, 3);
 
 	check_blanklines = gtk_check_button_new_with_label(
 		_("Strip trailing blank lines"));
@@ -602,6 +634,8 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
 	g_object_set_data(G_OBJECT(dialog), "check_systray", check_systray);
 	g_object_set_data(G_OBJECT(dialog), "check_bookmarklist", check_bookmarklist);
 	g_object_set_data(G_OBJECT(dialog), "check_markword", check_markword);
+	g_object_set_data(G_OBJECT(dialog), "check_markword_single_click_deselect",
+		check_markword_single_click_deselect);
 	g_object_set_data(G_OBJECT(dialog), "check_blanklines", check_blanklines);
 	g_object_set_data(G_OBJECT(dialog), "check_xmltagging", check_xmltagging);
 	g_object_set_data(G_OBJECT(dialog), "check_enclose_words", check_enclose_words);
@@ -610,6 +644,7 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
 	g_signal_connect(dialog, "response", G_CALLBACK(ao_configure_response_cb), NULL);
 
 	ao_configure_tasks_toggled_cb(GTK_TOGGLE_BUTTON(check_tasks), dialog);
+	ao_configure_markword_toggled_cb(GTK_TOGGLE_BUTTON(check_markword), dialog);
 	ao_configure_doclist_toggled_cb(GTK_TOGGLE_BUTTON(check_doclist), dialog);
 
 	gtk_widget_show_all(vbox);


Modified: addons/src/ao_markword.c
94 lines changed, 85 insertions(+), 9 deletions(-)
===================================================================
@@ -32,6 +32,9 @@
 
 typedef struct _AoMarkWordPrivate			AoMarkWordPrivate;
 
+#define DOUBLE_CLICK_DELAY 50
+
+
 #define AO_MARKWORD_GET_PRIVATE(obj)		(G_TYPE_INSTANCE_GET_PRIVATE((obj),\
 			AO_MARKWORD_TYPE, AoMarkWordPrivate))
 
@@ -48,12 +51,16 @@ struct _AoMarkWordClass
 struct _AoMarkWordPrivate
 {
 	gboolean enable_markword;
+	gboolean enable_single_click_deselect;
+
+	guint double_click_timer_id;
 };
 
 enum
 {
 	PROP_0,
-	PROP_ENABLE_MARKWORD
+	PROP_ENABLE_MARKWORD,
+	PROP_ENABLE_MARKWORD_SINGLE_CLICK_DESELECT
 };
 
 
@@ -72,6 +79,9 @@ static void ao_mark_word_set_property(GObject *object, guint prop_id,
 		case PROP_ENABLE_MARKWORD:
 			priv->enable_markword = g_value_get_boolean(value);
 			break;
+		case PROP_ENABLE_MARKWORD_SINGLE_CLICK_DESELECT:
+			priv->enable_single_click_deselect = g_value_get_boolean(value);
+			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 			break;
@@ -96,6 +106,15 @@ static void ao_mark_word_class_init(AoMarkWordClass *klass)
 									"Whether to mark all occurrences of a word when double-clicking it",
 									TRUE,
 									G_PARAM_WRITABLE));
+
+	g_object_class_install_property(g_object_class,
+									PROP_ENABLE_MARKWORD_SINGLE_CLICK_DESELECT,
+									g_param_spec_boolean(
+									"enable-single-click-deselect",
+									"enable-single-click-deselect",
+									"Enable deselecting a previous highlight by single click",
+									TRUE,
+									G_PARAM_WRITABLE));
 }
 
 
@@ -108,28 +127,85 @@ static void ao_mark_word_finalize(GObject *object)
 }
 
 
-void ao_mark_word_check(AoMarkWord *bm, GeanyEditor *editor, SCNotification *nt)
+static void clear_marker(void)
+{
+	/* There might be a small risk that the current document is not the one we want
+	 * but this is very unlikely. */
+	GeanyDocument *document = document_get_current();
+	/* clear current search indicators */
+	if (DOC_VALID(document))
+		editor_indicator_clear(document->editor, GEANY_INDICATOR_SEARCH);
+}
+
+
+static gboolean mark_word(gpointer bm)
 {
 	AoMarkWordPrivate *priv = AO_MARKWORD_GET_PRIVATE(bm);
+	keybindings_send_command(GEANY_KEY_GROUP_SEARCH, GEANY_KEYS_SEARCH_MARKALL);
+	/* unset and remove myself */
+	priv->double_click_timer_id = 0;
+	return FALSE;
+}
 
-	if (priv->enable_markword)
+
+static gboolean on_editor_button_press_event(GtkWidget *widget, GdkEventButton *event,
+											 AoMarkWord *bm)
+{
+	if (event->button == 1)
 	{
-		switch (nt->nmhdr.code)
+		AoMarkWordPrivate *priv = AO_MARKWORD_GET_PRIVATE(bm);
+		if (! priv->enable_markword)
+			return FALSE;
+
+		if (event->type == GDK_BUTTON_PRESS)
 		{
-			case SCN_DOUBLECLICK:
-				keybindings_send_command(GEANY_KEY_GROUP_SEARCH, GEANY_KEYS_SEARCH_MARKALL);
-				break;
+			if (priv->enable_single_click_deselect)
+				clear_marker();
+		}
+		else if (event->type == GDK_2BUTTON_PRESS)
+		{
+			if (priv->double_click_timer_id == 0)
+				priv->double_click_timer_id = g_timeout_add(DOUBLE_CLICK_DELAY, mark_word, bm);
 		}
 	}
+	return FALSE;
+}
+
+
+void ao_mark_document_open(AoMarkWord *mw, GeanyDocument *document)
+{
+	g_return_if_fail(DOC_VALID(document));
+
+	plugin_signal_connect(
+		geany_plugin,
+		G_OBJECT(document->editor->sci),
+		"button-press-event",
+		FALSE,
+		G_CALLBACK(on_editor_button_press_event),
+		mw);
+}
+
+
+void ao_mark_document_close(AoMarkWord *mw, GeanyDocument *document)
+{
+	g_return_if_fail(DOC_VALID(document));
+
+	g_signal_handlers_disconnect_by_func(document->editor->sci, on_editor_button_press_event, mw);
 }
 
 
 static void ao_mark_word_init(AoMarkWord *self)
 {
+	AoMarkWordPrivate *priv = AO_MARKWORD_GET_PRIVATE(self);
+	priv->double_click_timer_id = 0;
 }
 
 
-AoMarkWord *ao_mark_word_new(gboolean enable)
+AoMarkWord *ao_mark_word_new(gboolean enable, gboolean single_click_deselect)
 {
-	return g_object_new(AO_MARKWORD_TYPE, "enable-markword", enable, NULL);
+	return g_object_new(
+		AO_MARKWORD_TYPE,
+		"enable-markword", enable,
+		"enable-single-click-deselect", single_click_deselect,
+		NULL);
 }


Modified: addons/src/ao_markword.h
6 lines changed, 3 insertions(+), 3 deletions(-)
===================================================================
@@ -40,9 +40,9 @@ typedef struct _AoMarkWord				AoMarkWord;
 typedef struct _AoMarkWordClass			AoMarkWordClass;
 
 GType			ao_mark_word_get_type		(void);
-AoMarkWord*		ao_mark_word_new			(gboolean enable);
-void			ao_mark_word_check			(AoMarkWord *bm, GeanyEditor *editor,
-											 SCNotification *nt);
+AoMarkWord*		ao_mark_word_new			(gboolean enable, gboolean single_click_deselect);
+void			ao_mark_document_open		(AoMarkWord *mw, GeanyDocument *document);
+void			ao_mark_document_close		(AoMarkWord *mw, GeanyDocument *document);
 
 G_END_DECLS
 



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Plugins-Commits mailing list