Now that the geany-plugins has been converted to Git, I thought I'd post
this patch that adds the feature I've been working on (wrapping text with
characters) to the Addons plugin.  Any chance of it being added?

And I've never really used Git before too, so please let me know if the
patch is incorrectly made or something.

Cheers
Alex
From e0027703185c7952d9d5e8d4f9477c542c73f6a6 Mon Sep 17 00:00:00 2001
From: Alex M <3m.me...@gmail.com>
Date: Sat, 10 Dec 2011 17:40:16 -0500
Subject: [PATCH] Adds "wrap words" feature to Addons plugin.

---
 addons/src/Makefile.am    |    4 +-
 addons/src/addons.c       |   48 +++++++-
 addons/src/ao_wrapwords.c |  300 +++++++++++++++++++++++++++++++++++++++++++++
 addons/src/ao_wrapwords.h |   28 ++++
 4 files changed, 376 insertions(+), 4 deletions(-)
 create mode 100644 addons/src/ao_wrapwords.c
 create mode 100644 addons/src/ao_wrapwords.h

diff --git a/addons/src/Makefile.am b/addons/src/Makefile.am
index 2a386d5..eabb6e8 100644
--- a/addons/src/Makefile.am
+++ b/addons/src/Makefile.am
@@ -16,6 +16,7 @@ addons_la_SOURCES = \
 	ao_markword.h \
 	ao_tasks.h \
 	ao_xmltagging.h \
+	ao_wrapwords.h \
 	addons.c \
 	ao_blanklines.c \
 	ao_doclist.c \
@@ -24,7 +25,8 @@ addons_la_SOURCES = \
 	ao_bookmarklist.c \
 	ao_markword.c \
 	ao_tasks.c \
-	ao_xmltagging.c
+	ao_xmltagging.c \
+	ao_wrapwords.c
 
 addons_la_LIBADD = $(COMMONLIBS)
 
diff --git a/addons/src/addons.c b/addons/src/addons.c
index 73a5840..93c81d0 100644
--- a/addons/src/addons.c
+++ b/addons/src/addons.c
@@ -37,7 +37,7 @@
 #include "ao_markword.h"
 #include "ao_tasks.h"
 #include "ao_xmltagging.h"
-
+#include "ao_wrapwords.h"
 
 
 GeanyPlugin		*geany_plugin;
@@ -77,6 +77,8 @@ typedef struct
 	gboolean enable_bookmarklist;
 	gboolean enable_markword;
 	gboolean enable_xmltagging;
+	gboolean enable_wrapwords;
+	gboolean enable_wrapwords_auto;
 	gboolean strip_trailing_blank_lines;
 
 	gchar *tasks_token_list;
@@ -271,6 +273,10 @@ void plugin_init(GeanyData *data)
 		"addons", "strip_trailing_blank_lines", FALSE);
 	ao_info->enable_xmltagging = utils_get_setting_boolean(config, "addons",
 		"enable_xmltagging", FALSE);
+	ao_info->enable_wrapwords = utils_get_setting_boolean(config, "addons",
+		"enable_wrapwords", FALSE);
+	ao_info->enable_wrapwords_auto = utils_get_setting_boolean(config, "addons",
+		"enable_wrapwords_auto", FALSE);
 
 	plugin_module_make_resident(geany_plugin);
 
@@ -283,9 +289,9 @@ void plugin_init(GeanyData *data)
 						ao_info->tasks_token_list, ao_info->tasks_scan_all_documents);
 
 	ao_blanklines_set_enable(ao_info->strip_trailing_blank_lines);
-
+	
 	/* setup keybindings */
-	key_group = plugin_set_key_group(geany_plugin, "addons", KB_COUNT, NULL);
+	key_group = plugin_set_key_group(geany_plugin, "addons", KB_COUNT+8, NULL);
 	keybindings_set_item(key_group, KB_FOCUS_BOOKMARK_LIST, kb_bmlist_activate,
 		0, 0, "focus_bookmark_list", _("Focus Bookmark List"), NULL);
 	keybindings_set_item(key_group, KB_FOCUS_TASKS, kb_tasks_activate,
@@ -295,6 +301,9 @@ void plugin_init(GeanyData *data)
 	keybindings_set_item(key_group, KB_XMLTAGGING, kb_ao_xmltagging,
 		0, 0, "xml_tagging", _("Run XML tagging"), NULL);
 
+	ao_wrapwords_init(ao_info->config_file, key_group);
+	ao_wrapwords_set_enabled (ao_info->enable_wrapwords, ao_info->enable_wrapwords_auto);
+
 	g_key_file_free(config);
 }
 
@@ -359,6 +368,12 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 			g_object_get_data(G_OBJECT(dialog), "check_blanklines"))));
 		ao_info->enable_xmltagging = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
 			g_object_get_data(G_OBJECT(dialog), "check_xmltagging"))));
+		ao_info->enable_wrapwords = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+			g_object_get_data(G_OBJECT(dialog), "check_wrapwords"))));
+		ao_info->enable_wrapwords_auto = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+			g_object_get_data(G_OBJECT(dialog), "check_wrapwords_auto"))));
+			
+		ao_wrapwords_set_enabled (ao_info->enable_wrapwords, ao_info->enable_wrapwords_auto);
 
 		g_key_file_load_from_file(config, ao_info->config_file, G_KEY_FILE_NONE, NULL);
 		g_key_file_set_boolean(config, "addons",
@@ -377,6 +392,10 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 		  ao_info->strip_trailing_blank_lines);
 		g_key_file_set_boolean(config, "addons", "enable_xmltagging",
 			ao_info->enable_xmltagging);
+		g_key_file_set_boolean(config, "addons", "enable_wrapwords",
+			ao_info->enable_wrapwords);
+		g_key_file_set_boolean(config, "addons", "enable_wrapwords_auto",
+			ao_info->enable_wrapwords_auto);
 
 		g_object_set(ao_info->doclist, "enable-doclist", ao_info->enable_doclist, NULL);
 		g_object_set(ao_info->doclist, "sort-mode", ao_info->doclist_sort_mode, NULL);
@@ -418,6 +437,7 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
 	GtkWidget *check_bookmarklist, *check_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_wrapwords, *check_wrapwords_auto, *wrapwords_config_button, *wrapwords_hbox;
 
 	vbox = gtk_vbox_new(FALSE, 6);
 
@@ -536,6 +556,25 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_xmltagging),
 		ao_info->enable_xmltagging);
 	gtk_box_pack_start(GTK_BOX(vbox), check_xmltagging, FALSE, FALSE, 3);
+	
+	check_wrapwords = gtk_check_button_new_with_label(
+		_("Wrap selection on configurable keybindings"));
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_wrapwords),
+		ao_info->enable_wrapwords);
+	
+	wrapwords_config_button = gtk_button_new_with_label ("Configure wrap pairs");
+	g_signal_connect(wrapwords_config_button, "clicked", G_CALLBACK(ao_wrapwords_config), dialog);
+	wrapwords_hbox = gtk_hbox_new(FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(wrapwords_hbox), check_wrapwords, FALSE, FALSE, 3);
+	gtk_box_pack_start(GTK_BOX(wrapwords_hbox), wrapwords_config_button, TRUE, TRUE, 3);
+	gtk_box_pack_start(GTK_BOX(vbox), wrapwords_hbox, FALSE, FALSE, 3);
+	
+	check_wrapwords_auto = gtk_check_button_new_with_label(
+		_("Wrap selection automatically (without having to press a keybinding)"));
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_wrapwords_auto),
+		ao_info->enable_wrapwords_auto);
+	gtk_box_pack_start(GTK_BOX(vbox), check_wrapwords_auto, FALSE, FALSE, 3);
+
 
 	g_object_set_data(G_OBJECT(dialog), "check_doclist", check_doclist);
 	g_object_set_data(G_OBJECT(dialog), "radio_doclist_name", radio_doclist_name);
@@ -551,6 +590,9 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
 	g_object_set_data(G_OBJECT(dialog), "check_markword", check_markword);
 	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_wrapwords", check_wrapwords);
+	g_object_set_data(G_OBJECT(dialog), "check_wrapwords_auto", check_wrapwords_auto);
+	g_object_set_data(G_OBJECT(dialog), "wrapwords_config_button", wrapwords_config_button);
 	g_signal_connect(dialog, "response", G_CALLBACK(ao_configure_response_cb), NULL);
 
 	ao_configure_tasks_toggled_cb(GTK_TOGGLE_BUTTON(check_tasks), dialog);
diff --git a/addons/src/ao_wrapwords.c b/addons/src/ao_wrapwords.c
new file mode 100644
index 0000000..51f8a8e
--- /dev/null
+++ b/addons/src/ao_wrapwords.c
@@ -0,0 +1,300 @@
+/*
+ *			ao_wrapwords.c - this file is part of Addons, a Geany plugin
+ *
+ *			This program is free software; you can redistribute it and/or modify
+ *			it under the terms of the GNU General Public License as published by
+ *			the Free Software Foundation; either version 2 of the License, or
+ *			(at your option) any later version.
+ *
+ *			This program is distributed in the hope that it will be useful,
+ *			but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *			MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+ *			GNU General Public License for more details.
+ *
+ *			You should have received a copy of the GNU General Public License
+ *			along with this program; if not, write to the Free Software
+ *			Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *			MA 02110-1301, USA.
+ */
+
+#include "geanyplugin.h"
+
+#include "addons.h"
+#include "ao_wrapwords.h"
+	
+enum 
+{
+	COLUMN_TITLE,
+	COLUMN_PRIOR_CHAR,
+	COLUMN_END_CHAR,
+	NUM_COLUMNS
+};
+
+void wrap_text_action (guint); 
+gboolean on_key_press (GtkWidget *, GdkEventKey *, gpointer);
+void configure_response (GtkDialog *, gint, gpointer);
+void wrap_chars_changed (GtkCellRendererText *, gchar *, gchar *, gpointer);
+
+gchar *wrap_chars [8];
+gboolean auto_enabled = FALSE;
+gboolean wrap_enabled = FALSE;
+gchar *config_file;
+GtkListStore *chars_list;
+
+/* 
+ * Called when a keybinding associated with the plugin is pressed.  Wraps the selected text in
+ * the characters associated with this keybinding. 
+ */
+
+void wrap_text_action (guint key_id) 
+{
+	if (!wrap_enabled)
+		return;
+		
+	gint selection_end;
+	gchar insert_chars [2] = {0, 0};
+	ScintillaObject *sci_obj = document_get_current ()->editor->sci;
+	
+	if (sci_get_selected_text_length (sci_obj) < 2)
+		return;
+	
+	key_id -= 4;
+	selection_end = sci_get_selection_end (sci_obj);
+	
+	sci_start_undo_action (sci_obj);
+	insert_chars [0] = *wrap_chars [key_id];
+	sci_insert_text (sci_obj, sci_get_selection_start (sci_obj), insert_chars);
+	insert_chars [0] = *(wrap_chars [key_id] + 1);
+	sci_insert_text (sci_obj, selection_end + 1, insert_chars);
+	sci_set_current_position (sci_obj, selection_end + 2, TRUE);
+	sci_end_undo_action (sci_obj);
+}
+
+/*
+ * Captures keypresses, if auto-wrapping automatically wraps selected text when certain
+ * characters are pressed.
+ */
+
+gboolean on_key_press (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
+{
+	gint selection_end;
+	gchar insert_chars [4] = {0, 0, 0, 0};
+	ScintillaObject *sci_obj;
+	
+	if (!auto_enabled)
+		return FALSE;
+
+	sci_obj = document_get_current ()->editor->sci;
+	
+	if (sci_get_selected_text_length (sci_obj) < 2)
+		return FALSE;
+		
+	if (event->keyval == '(')
+	{
+		insert_chars [0] = '(';
+		insert_chars [2] = ')';
+	}
+	else if (event->keyval == '[')
+	{
+		insert_chars [0] = '[';
+		insert_chars [2] = ']';
+	}
+	else if (event->keyval == '{')
+	{
+		insert_chars [0] = '{';
+		insert_chars [2] = '}';
+	}
+	else if (event->keyval == '\'')
+	{
+		insert_chars [0] = '\'';
+		insert_chars [2] = '\'';
+	}
+	else if (event->keyval == '\"')
+	{
+		insert_chars [0] = '\"';
+		insert_chars [2] = '\"';
+	}
+        else if (event->keyval == '`')
+        {
+                insert_chars [0] = '`';
+                insert_chars [2] = '`';
+        }
+	else
+		return FALSE;
+	
+	selection_end = sci_get_selection_end (sci_obj);
+	
+	sci_start_undo_action (sci_obj);
+	sci_insert_text (sci_obj, sci_get_selection_start (sci_obj), insert_chars);
+	sci_insert_text (sci_obj, selection_end + 1, insert_chars+2);
+	sci_set_current_position (sci_obj, selection_end + 2, TRUE);
+	sci_end_undo_action (sci_obj);
+
+	return TRUE;	
+}
+
+/* 
+ * Loads the wrapping characters from the config file and sets keybindings.
+ */
+
+void ao_wrapwords_init (gchar *config_file_name, GeanyKeyGroup *key_group)
+{		
+	GKeyFile *config = g_key_file_new();
+	gchar *key_name = g_malloc0 (6);
+	gint i;
+	
+	config_file = g_strdup (config_file_name);
+	g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
+	
+	g_stpcpy (key_name, "Wrap_x");
+	
+	for (i = 0; i < 8; i++)
+	{
+		key_name [5] = (gchar) (i + '0');
+		wrap_chars [i] = utils_get_setting_string (config, "addons", key_name, "  ");
+		key_name [5] = (gchar) ((i + 1) + '0');
+		keybindings_set_item (key_group, i+4, (GeanyKeyCallback) wrap_text_action, 0, 0, key_name, 
+			key_name, NULL);
+
+	}
+	
+	plugin_signal_connect(geany_plugin, G_OBJECT(geany->main_widgets->window), "key-press-event", 
+			FALSE, G_CALLBACK(on_key_press), NULL);
+		
+	g_free (key_name);
+}
+
+void ao_wrapwords_set_enabled (gboolean enabled_w, gboolean enabled_a)
+{
+	auto_enabled = enabled_a;
+	wrap_enabled = enabled_w;
+}
+
+/* 
+ * Called when the user closes the plugin preferences dialog.  If the user accepted or ok'd,
+ * update the array of wrapping characters and config file with the new wrapping characters 
+ */
+
+void configure_response (GtkDialog *dialog, gint response, gpointer char_tree_view) 
+{
+	GtkTreeIter char_iter;
+	GKeyFile *config = g_key_file_new();
+	gchar *config_data = NULL;
+	gchar *prior_char_str, *end_char_str;
+	gchar *key_name = g_malloc0 (6);
+	gint i;		
+	
+	if (response != GTK_RESPONSE_OK && response != GTK_RESPONSE_ACCEPT)
+		return;
+	
+	gtk_tree_model_get_iter_first (GTK_TREE_MODEL(chars_list), &char_iter);
+	
+	g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
+	
+	g_stpcpy (key_name, "Wrap_x");
+	
+	for (i = 0; i < 8; i++)
+	{
+		key_name [5] = (gchar) (i + '0');
+		
+		gtk_tree_model_get (GTK_TREE_MODEL(chars_list), &char_iter, 
+			COLUMN_PRIOR_CHAR, &prior_char_str, COLUMN_END_CHAR, &end_char_str, -1);
+		*wrap_chars [i] = prior_char_str [0];
+		*(wrap_chars [i] + 1) = end_char_str [0];
+		gtk_tree_model_iter_next (GTK_TREE_MODEL(chars_list), &char_iter);
+		
+		g_key_file_set_string (config, "addons", key_name, wrap_chars [i]);
+	}
+	
+	config_data = g_key_file_to_data (config, NULL, NULL);
+	utils_write_file (config_file, config_data);
+	
+	g_free (prior_char_str);
+	g_free (end_char_str);
+	g_free (config_data);
+	g_free (key_name);
+	g_key_file_free(config);
+}
+
+/* 
+ * When the user changes an entry in the preferences dialog, this updates the list of
+ * wrapping characters with the new entry 
+ */
+
+void wrap_chars_changed (GtkCellRendererText *renderer, gchar *path, gchar *new_char_str, 
+	gpointer column_num)
+{
+	GtkTreeIter chars_iter;
+	gchar new_chars [2] = {0, 0};
+	new_chars [0] = new_char_str [0];
+	gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (chars_list), &chars_iter, path);
+	gtk_list_store_set (chars_list, &chars_iter, GPOINTER_TO_INT (column_num), new_chars, -1);
+}
+
+/*
+ * Dialog box for setting wrap characters
+ */
+
+void ao_wrapwords_config (GtkButton *button, GtkWidget *config_window)
+{	
+	GtkWidget *dialog;
+	GtkWidget *vbox;
+	GtkTreeIter chars_iter;
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *label_column, *char_one_column, *char_two_column;
+	GtkTreeView *chars_tree_view;
+	gchar insert_chars [2] = {0, 0};
+	gchar *title;
+	gint i;
+	
+	dialog = gtk_dialog_new_with_buttons(_("Plugins"), GTK_WINDOW(config_window),
+						GTK_DIALOG_DESTROY_WITH_PARENT, "Accept", GTK_RESPONSE_ACCEPT,
+						"Cancel", GTK_RESPONSE_CANCEL, "OK", GTK_RESPONSE_OK, NULL);
+
+	vbox = ui_dialog_vbox_new (GTK_DIALOG (dialog));
+	chars_list = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+	renderer = gtk_cell_renderer_text_new ();
+	chars_tree_view = (GtkTreeView *) gtk_tree_view_new ();
+	
+	for (i = 0; i < 8; i++)
+	{
+		gtk_list_store_append (chars_list, &chars_iter);
+		title = g_strdup_printf ("Wrap combo %d", i + 1);
+		gtk_list_store_set (chars_list, &chars_iter, COLUMN_TITLE, title, -1);
+		insert_chars [0] = *wrap_chars [i];
+		gtk_list_store_set (chars_list, &chars_iter, COLUMN_PRIOR_CHAR, insert_chars, -1);
+		insert_chars [0] = *(wrap_chars [i] + 1);
+		gtk_list_store_set (chars_list, &chars_iter, COLUMN_END_CHAR, insert_chars, -1);
+	}
+	
+	label_column = gtk_tree_view_column_new_with_attributes ("", renderer, "text", 0, NULL);
+
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (renderer, "editable", TRUE, NULL);
+	char_one_column = gtk_tree_view_column_new_with_attributes ("Opening Character", renderer, 
+		"text", COLUMN_PRIOR_CHAR, NULL);
+	g_signal_connect (renderer, "edited", G_CALLBACK (wrap_chars_changed), 
+		GINT_TO_POINTER (COLUMN_PRIOR_CHAR));	
+	
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (renderer, "editable", TRUE, NULL);
+	char_two_column = gtk_tree_view_column_new_with_attributes ("Closing Character", renderer, 
+		"text", COLUMN_END_CHAR, NULL);
+	g_signal_connect (renderer, "edited", G_CALLBACK (wrap_chars_changed), 
+		GINT_TO_POINTER (COLUMN_END_CHAR));	
+		
+	gtk_tree_view_append_column (chars_tree_view, label_column);
+	gtk_tree_view_append_column (chars_tree_view, char_one_column);
+	gtk_tree_view_append_column (chars_tree_view, char_two_column);
+	
+	gtk_tree_view_set_model (chars_tree_view, GTK_TREE_MODEL (chars_list));
+	gtk_box_pack_start(GTK_BOX(vbox), (GtkWidget *) chars_tree_view, FALSE, FALSE, 3);
+	
+	gtk_widget_show_all (vbox);
+	g_signal_connect (dialog, "response", G_CALLBACK (configure_response), NULL);
+	while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT);
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+
+	g_free (title);
+}
+
diff --git a/addons/src/ao_wrapwords.h b/addons/src/ao_wrapwords.h
new file mode 100644
index 0000000..06f0b9b
--- /dev/null
+++ b/addons/src/ao_wrapwords.h
@@ -0,0 +1,28 @@
+/*
+ *			ao_wrapwords.h - this file is part of Addons, a Geany plugin
+ *
+ *			This program is free software; you can redistribute it and/or modify
+ *			it under the terms of the GNU General Public License as published by
+ *			the Free Software Foundation; either version 2 of the License, or
+ *			(at your option) any later version.
+ *
+ *			This program is distributed in the hope that it will be useful,
+ *			but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *			MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+ *			GNU General Public License for more details.
+ *
+ *			You should have received a copy of the GNU General Public License
+ *			along with this program; if not, write to the Free Software
+ *			Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *			MA 02110-1301, USA.
+ */
+
+#ifndef __AO_WRAPWORDS_H__
+#define __AO_WRAPWORDS_H__
+
+
+void ao_wrapwords_init(gchar *, GeanyKeyGroup *);
+void ao_wrapwords_config(GtkButton *, GtkDialog *);
+void ao_wrapwords_set_enabled(gboolean, gboolean);
+
+#endif
-- 
1.7.7.4

_______________________________________________
Geany-devel mailing list
Geany-devel@uvena.de
https://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel

Reply via email to