SF.net SVN: geany: [1734] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Mon Jul 23 15:41:09 UTC 2007


Revision: 1734
          http://geany.svn.sourceforge.net/geany/?rev=1734&view=rev
Author:   ntrel
Date:     2007-07-23 08:41:08 -0700 (Mon, 23 Jul 2007)

Log Message:
-----------
Convert 'Insert Special HTML Characters' tool into a plugin;
keybinding support will be added later.
Add plugin functions for inserting text into the current document.
Add plugin support for disabling a menu item when no documents are
open.
Destroy plugin_fields->menu_item on unloading if set by a plugin.
Use G_MODULE_BIND_LOCAL for plugins to prevent symbol shadowing by
other modules, and to help detect unresolved symbols at loading time.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/HACKING
    trunk/geany.glade
    trunk/plugins/Makefile.am
    trunk/src/callbacks.c
    trunk/src/callbacks.h
    trunk/src/interface.c
    trunk/src/keybindings.c
    trunk/src/plugindata.h
    trunk/src/plugins.c
    trunk/src/plugins.h
    trunk/src/tools.c
    trunk/src/tools.h
    trunk/src/ui_utils.c

Added Paths:
-----------
    trunk/plugins/htmlchars.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/ChangeLog	2007-07-23 15:41:08 UTC (rev 1734)
@@ -1,3 +1,19 @@
+2007-07-23  Nick Treleaven  <nick.treleaven at btinternet.com>
+
+ * plugins/htmlchars.c, plugins/Makefile.am, src/interface.c,
+   src/keybindings.c, src/tools.c, src/tools.h, src/plugindata.h,
+   src/callbacks.c, src/callbacks.h, src/plugins.c, src/plugins.h,
+   src/ui_utils.c, HACKING, geany.glade:
+   Convert 'Insert Special HTML Characters' tool into a plugin;
+   keybinding support will be added later.
+   Add plugin functions for inserting text into the current document.
+   Add plugin support for disabling a menu item when no documents are
+   open.
+   Destroy plugin_fields->menu_item on unloading if set by a plugin.
+   Use G_MODULE_BIND_LOCAL for plugins to prevent symbol shadowing by
+   other modules, and to help detect unresolved symbols at loading time.
+
+
 2007-07-23  Enrico Tröger  <enrico.troeger at uvena.de>
 
  * src/symbols.c: Adjust symbol list icon path on Windows.

Modified: trunk/HACKING
===================================================================
--- trunk/HACKING	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/HACKING	2007-07-23 15:41:08 UTC (rev 1734)
@@ -67,11 +67,11 @@
 Some of these notes below are brief (or maybe incomplete) - please contact
 the mailing list for more information.
 
-Adding a file foo.[hc] in src/
-------------------------------
-Add foo.c, foo.h to SRCS in src/Makefile.am.
-Add foo.o to OBJS in src/makefile.win32.
-Add src/foo.c to po/POTFILES.in (for string translation).
+Adding a file foo.[hc] in src/ or plugins/
+------------------------------------------
+Add foo.c, foo.h to SRCS in path/Makefile.am.
+Add foo.o to OBJS in path/makefile.win32.
+Add path/foo.c to po/POTFILES.in (for string translation).
 
 Adding a filetype
 -----------------
@@ -107,8 +107,8 @@
 PLUGINS
 =======
 
+src/plugindata.h contains the plugin API data types and some notes.
 See plugins/demoplugin.c for a very basic example plugin.
-src/plugindata.h contains the plugin API data types.
 src/plugins.c loads and unloads plugins.
 
 Loading a plugin from GDB

Modified: trunk/geany.glade
===================================================================
--- trunk/geany.glade	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/geany.glade	2007-07-23 15:41:08 UTC (rev 1734)
@@ -58,7 +58,7 @@
 		      <property name="use_underline">True</property>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1901">
+			<widget class="GtkImage" id="image1920">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-new</property>
 			  <property name="icon_size">1</property>
@@ -148,7 +148,7 @@
 		      <signal name="activate" handler="on_save_all1_activate" last_modification_time="Thu, 02 Jun 2005 14:15:30 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1902">
+			<widget class="GtkImage" id="image1921">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-save</property>
 			  <property name="icon_size">1</property>
@@ -169,7 +169,7 @@
 		      <signal name="activate" handler="on_toolbutton23_clicked" last_modification_time="Mon, 24 Jul 2006 19:26:04 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1903">
+			<widget class="GtkImage" id="image1922">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-revert-to-saved</property>
 			  <property name="icon_size">1</property>
@@ -189,7 +189,7 @@
 		      <property name="use_underline">True</property>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1904">
+			<widget class="GtkImage" id="image1923">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-revert-to-saved</property>
 			  <property name="icon_size">1</property>
@@ -285,7 +285,7 @@
 		      <signal name="activate" handler="on_close_all1_activate" last_modification_time="Thu, 02 Jun 2005 14:15:30 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1905">
+			<widget class="GtkImage" id="image1924">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-close</property>
 			  <property name="icon_size">1</property>
@@ -493,7 +493,7 @@
 			      <signal name="activate" handler="on_menu_increase_indent1_activate" last_modification_time="Tue, 01 Aug 2006 10:28:54 GMT"/>
 
 			      <child internal-child="image">
-				<widget class="GtkImage" id="image1906">
+				<widget class="GtkImage" id="image1925">
 				  <property name="visible">True</property>
 				  <property name="stock">gtk-indent</property>
 				  <property name="icon_size">1</property>
@@ -514,7 +514,7 @@
 			      <signal name="activate" handler="on_menu_decrease_indent1_activate" last_modification_time="Tue, 01 Aug 2006 10:28:54 GMT"/>
 
 			      <child internal-child="image">
-				<widget class="GtkImage" id="image1907">
+				<widget class="GtkImage" id="image1926">
 				  <property name="visible">True</property>
 				  <property name="stock">gtk-unindent</property>
 				  <property name="icon_size">1</property>
@@ -570,7 +570,7 @@
 		      <property name="use_underline">True</property>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1908">
+			<widget class="GtkImage" id="image1927">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-add</property>
 			  <property name="icon_size">1</property>
@@ -602,7 +602,7 @@
 		      <property name="use_underline">True</property>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1909">
+			<widget class="GtkImage" id="image1928">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-add</property>
 			  <property name="icon_size">1</property>
@@ -687,7 +687,7 @@
 		      <property name="use_underline">True</property>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1910">
+			<widget class="GtkImage" id="image1929">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-add</property>
 			  <property name="icon_size">1</property>
@@ -784,7 +784,7 @@
 		      <signal name="activate" handler="on_replace1_activate" last_modification_time="Sun, 23 Oct 2005 13:22:36 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1911">
+			<widget class="GtkImage" id="image1930">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-find-and-replace</property>
 			  <property name="icon_size">1</property>
@@ -850,7 +850,7 @@
 		      <signal name="activate" handler="on_go_to_line1_activate" last_modification_time="Tue, 23 May 2006 17:10:49 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1912">
+			<widget class="GtkImage" id="image1931">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-jump-to</property>
 			  <property name="icon_size">1</property>
@@ -885,7 +885,7 @@
 		      <signal name="activate" handler="on_change_font1_activate" last_modification_time="Fri, 22 Apr 2005 18:58:45 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1913">
+			<widget class="GtkImage" id="image1932">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-select-font</property>
 			  <property name="icon_size">1</property>
@@ -1245,7 +1245,7 @@
 		      <signal name="activate" handler="on_project_new1_activate" last_modification_time="Thu, 18 Jan 2007 22:16:24 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1914">
+			<widget class="GtkImage" id="image1933">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-new</property>
 			  <property name="icon_size">1</property>
@@ -1266,7 +1266,7 @@
 		      <signal name="activate" handler="on_project_open1_activate" last_modification_time="Mon, 15 Jan 2007 17:34:17 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1915">
+			<widget class="GtkImage" id="image1934">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-open</property>
 			  <property name="icon_size">1</property>
@@ -1287,7 +1287,7 @@
 		      <signal name="activate" handler="on_project_close1_activate" last_modification_time="Mon, 15 Jan 2007 17:34:17 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1916">
+			<widget class="GtkImage" id="image1935">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-close</property>
 			  <property name="icon_size">1</property>
@@ -1345,7 +1345,7 @@
 		      <signal name="activate" handler="on_show_color_chooser1_activate" last_modification_time="Wed, 22 Jun 2005 18:10:21 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1917">
+			<widget class="GtkImage" id="image1936">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-select-color</property>
 			  <property name="icon_size">1</property>
@@ -1367,15 +1367,6 @@
 		      <signal name="activate" handler="on_count_words1_activate" last_modification_time="Mon, 06 Jun 2005 11:49:24 GMT"/>
 		    </widget>
 		  </child>
-
-		  <child>
-		    <widget class="GtkMenuItem" id="menu_insert_special_chars1">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Insert Special HTML Characters</property>
-		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="on_menu_insert_special_chars1_activate" last_modification_time="Tue, 12 Dec 2006 22:03:01 GMT"/>
-		    </widget>
-		  </child>
 		</widget>
 	      </child>
 	    </widget>
@@ -1398,7 +1389,7 @@
 		      <signal name="activate" handler="on_help1_activate" last_modification_time="Sun, 24 Jul 2005 15:23:11 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image1918">
+			<widget class="GtkImage" id="image1937">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-help</property>
 			  <property name="icon_size">1</property>

Modified: trunk/plugins/Makefile.am
===================================================================
--- trunk/plugins/Makefile.am	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/plugins/Makefile.am	2007-07-23 15:41:08 UTC (rev 1734)
@@ -13,13 +13,15 @@
 
 demoplugin_la_LDFLAGS    = -module -avoid-version
 classbuilder_la_LDFLAGS  = -module -avoid-version
+htmlchars_la_LDFLAGS     = -module -avoid-version
 
 if PLUGINS
 
 # Plugins to be installed
 plugin_LTLIBRARIES = \
 	demoplugin.la \
-	classbuilder.la
+	classbuilder.la \
+	htmlchars.la
 
 # Plugins not to be installed
 #noinst_LTLIBRARIES = \
@@ -27,9 +29,11 @@
 
 demoplugin_la_SOURCES    = demoplugin.c
 classbuilder_la_SOURCES  = classbuilder.c
+htmlchars_la_SOURCES     = htmlchars.c
 
 demoplugin_la_LIBADD    = $(GTK_LIBS)
 classbuilder_la_LIBADD  = $(GTK_LIBS)
+htmlchars_la_LIBADD     = $(GTK_LIBS)
 
 endif # PLUGINS
 

Added: trunk/plugins/htmlchars.c
===================================================================
--- trunk/plugins/htmlchars.c	                        (rev 0)
+++ trunk/plugins/htmlchars.c	2007-07-23 15:41:08 UTC (rev 1734)
@@ -0,0 +1,536 @@
+/*
+ *      htmlchars.c - this file is part of Geany, a fast and lightweight IDE
+ *
+ *      Copyright 2006-2007 Enrico Tröger <enrico.troeger at uvena.de>
+ *      Copyright 2007 Nick Treleaven <nick.treleaven at btinternet.com>
+ *
+ *      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.
+ *
+ * $Id$
+ */
+
+/* HTML Characters plugin (Inserts HTML character entities like '&') */
+
+#include "geany.h"
+#include "support.h"
+#include "plugindata.h"
+#include "document.h"
+
+
+PluginFields *plugin_fields;
+
+static PluginData *plugin_data;
+
+#define doc_array	plugin_data->doc_array
+// can't use document as a macro because it's currently a typename
+#define documents	plugin_data->document
+#define scintilla	plugin_data->sci
+#define ui			plugin_data->ui
+
+
+VERSION_CHECK(5)
+
+PLUGIN_INFO(_("HTML Characters"), _("Inserts HTML character entities like '&'."))
+
+
+enum
+{
+	COLUMN_CHARACTER,
+	COLUMN_HTML_NAME,
+	N_COLUMNS
+};
+
+
+static GtkWidget *sc_dialog = NULL;
+static GtkTreeStore *sc_store = NULL;
+static GtkTreeView *sc_tree = NULL;
+
+static void sc_on_tools_show_dialog_insert_special_chars_response
+		(GtkDialog *dialog, gint response, gpointer user_data);
+static void sc_on_tree_row_activated
+		(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer user_data);
+static void sc_fill_store(GtkTreeStore *store);
+static gboolean sc_insert(GtkTreeModel *model, GtkTreeIter *iter);
+
+
+static void tools_show_dialog_insert_special_chars()
+{
+	if (sc_dialog == NULL)
+	{
+		gint height;
+		GtkCellRenderer *renderer;
+		GtkTreeViewColumn *column;
+		GtkWidget *swin, *vbox, *label;
+
+		sc_dialog = gtk_dialog_new_with_buttons(
+					_("Special Characters"), GTK_WINDOW(plugin_data->app->window),
+					GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+					_("_Insert"), GTK_RESPONSE_OK, NULL);
+		vbox = ui->dialog_vbox_new(GTK_DIALOG(sc_dialog));
+		gtk_box_set_spacing(GTK_BOX(vbox), 6);
+		gtk_widget_set_name(sc_dialog, "GeanyDialog");
+
+		height = GEANY_WINDOW_MINIMAL_HEIGHT;
+		gtk_window_set_default_size(GTK_WINDOW(sc_dialog), height * 0.8, height);
+		gtk_dialog_set_default_response(GTK_DIALOG(sc_dialog), GTK_RESPONSE_CANCEL);
+
+		label = gtk_label_new(_("Choose a special character from the list below and double click on it or use the button to insert it at the current cursor position."));
+		gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+		gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+		gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+
+		sc_tree = GTK_TREE_VIEW(gtk_tree_view_new());
+
+		sc_store = gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
+		gtk_tree_view_set_model(GTK_TREE_VIEW(sc_tree),
+								GTK_TREE_MODEL(sc_store));
+
+		renderer = gtk_cell_renderer_text_new();
+		column = gtk_tree_view_column_new_with_attributes(
+								_("Character"), renderer, "text", COLUMN_CHARACTER, NULL);
+		gtk_tree_view_column_set_resizable(column, TRUE);
+		gtk_tree_view_append_column(GTK_TREE_VIEW(sc_tree), column);
+
+		renderer = gtk_cell_renderer_text_new();
+		column = gtk_tree_view_column_new_with_attributes(
+								_("HTML (name)"), renderer, "text", COLUMN_HTML_NAME, NULL);
+		gtk_tree_view_column_set_resizable(column, TRUE);
+		gtk_tree_view_append_column(GTK_TREE_VIEW(sc_tree), column);
+
+		swin = gtk_scrolled_window_new(NULL, NULL);
+		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC,
+			GTK_POLICY_AUTOMATIC);
+		gtk_scrolled_window_add_with_viewport(
+					GTK_SCROLLED_WINDOW(swin), GTK_WIDGET(sc_tree));
+
+		gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0);
+
+		g_signal_connect((gpointer) sc_tree, "row-activated",
+					G_CALLBACK(sc_on_tree_row_activated), NULL);
+
+		g_signal_connect((gpointer) sc_dialog, "response",
+					G_CALLBACK(sc_on_tools_show_dialog_insert_special_chars_response), NULL);
+
+		g_signal_connect((gpointer) sc_dialog, "delete_event",
+					G_CALLBACK(gtk_widget_hide_on_delete), NULL);
+
+		sc_fill_store(sc_store);
+
+		//gtk_tree_view_expand_all(special_characters_tree);
+		gtk_tree_view_set_search_column(sc_tree, COLUMN_HTML_NAME);
+	}
+	gtk_widget_show_all(sc_dialog);
+}
+
+
+// fill the tree model with data
+/// TODO move this in a file and make it extendable for more data types
+static void sc_fill_store(GtkTreeStore *store)
+{
+	GtkTreeIter iter;
+	GtkTreeIter *parent_iter = NULL;
+	guint i;
+
+	gchar *chars[][2] =
+		{
+			{ _("HTML characters"), NULL },
+			{ "\"", """ },
+			{ "&", "&" },
+			{ "<", "<" },
+			{ ">", ">" },
+
+			{ _("ISO 8859-1 characters"), NULL },
+			{ " ", " " },
+			{ "¡", "¡" },
+			{ "¢", "¢" },
+			{ "£", "£" },
+			{ "¤", "¤" },
+			{ "¥", "¥" },
+			{ "¦", "¦" },
+			{ "§", "§" },
+			{ "¨", "¨" },
+			{ "©", "©" },
+			{ "®", "®" },
+			{ "«", "«" },
+			{ "»", "»" },
+			{ "¬", "¬" },
+			{ " ", "­" },
+			{ "¯", "¯" },
+			{ "°", "°" },
+			{ "±", "±" },
+			{ "¹", "&sup1;" },
+			{ "²", "&sup2;" },
+			{ "³", "&sup3;" },
+			{ "¼", "&frac14;" },
+			{ "½", "&frac12;" },
+			{ "¾", "&frac34;" },
+			{ "×", "×" },
+			{ "÷", "÷" },
+			{ "´", "´" },
+			{ "µ", "µ" },
+			{ "¶", "¶" },
+			{ "·", "·" },
+			{ "¸", "¸" },
+			{ "ª", "ª" },
+			{ "º", "º" },
+			{ "¿", "¿" },
+			{ "À", "À" },
+			{ "Á", "Á" },
+			{ "Â", "Â" },
+			{ "Ã", "Ã" },
+			{ "Ä", "Ä" },
+			{ "Å", "Å" },
+			{ "Æ", "Æ" },
+			{ "Ç", "Ç" },
+			{ "È", "È" },
+			{ "É", "É" },
+			{ "Ê", "Ê" },
+			{ "Ë", "Ë" },
+			{ "Ì", "Ì" },
+			{ "Í", "Í" },
+			{ "Î", "Î" },
+			{ "Ï", "Ï" },
+			{ "Ð", "Ð" },
+			{ "Ñ", "Ñ" },
+			{ "Ò", "Ò" },
+			{ "Ó", "Ó" },
+			{ "Ô", "Ô" },
+			{ "Õ", "Õ" },
+			{ "Ö", "Ö" },
+			{ "Ø", "Ø" },
+			{ "Ù", "Ù" },
+			{ "Ú", "Ú" },
+			{ "Û", "Û" },
+			{ "Ü", "Ü" },
+			{ "Ý", "Ý" },
+			{ "Þ", "Þ" },
+			{ "ß", "ß" },
+			{ "à", "à" },
+			{ "á", "á" },
+			{ "â", "â" },
+			{ "ã", "ã" },
+			{ "ä", "ä" },
+			{ "å", "å" },
+			{ "æ", "æ" },
+			{ "ç", "ç" },
+			{ "è", "è" },
+			{ "é", "é" },
+			{ "ê", "ê" },
+			{ "ë", "ë" },
+			{ "ì", "ì" },
+			{ "í", "í" },
+			{ "î", "î" },
+			{ "ï", "ï" },
+			{ "ð", "ð" },
+			{ "ñ", "ñ" },
+			{ "ò", "ò" },
+			{ "ó", "ó" },
+			{ "ô", "ô" },
+			{ "õ", "õ" },
+			{ "ö", "ö" },
+			{ "ø", "ø" },
+			{ "ù", "ù" },
+			{ "ú", "ú" },
+			{ "û", "û" },
+			{ "ü", "ü" },
+			{ "ý", "ý" },
+			{ "þ", "þ" },
+			{ "ÿ", "ÿ" },
+
+			{ _("Greek characters"), NULL },
+			{ "Α", "Α" },
+			{ "α", "α" },
+			{ "Β", "Β" },
+			{ "β", "β" },
+			{ "Γ", "Γ" },
+			{ "γ", "γ" },
+			{ "Δ", "Δ" },
+			{ "δ", "Δ" },
+			{ "δ", "δ" },
+			{ "Ε", "Ε" },
+			{ "ε", "ε" },
+			{ "Ζ", "Ζ" },
+			{ "ζ", "ζ" },
+			{ "Η", "Η" },
+			{ "η", "η" },
+			{ "Θ", "Θ" },
+			{ "θ", "θ" },
+			{ "Ι", "Ι" },
+			{ "ι", "ι" },
+			{ "Κ", "Κ" },
+			{ "κ", "κ" },
+			{ "Λ", "Λ" },
+			{ "λ", "λ" },
+			{ "Μ", "Μ" },
+			{ "μ", "μ" },
+			{ "Ν", "Ν" },
+			{ "ν", "ν" },
+			{ "Ξ", "Ξ" },
+			{ "ξ", "ξ" },
+			{ "Ο", "Ο" },
+			{ "ο", "ο" },
+			{ "Π", "Π" },
+			{ "π", "π" },
+			{ "Ρ", "Ρ" },
+			{ "ρ", "ρ" },
+			{ "Σ", "Σ" },
+			{ "ς", "ς" },
+			{ "σ", "σ" },
+			{ "Τ", "Τ" },
+			{ "τ", "τ" },
+			{ "Υ", "Υ" },
+			{ "υ", "υ" },
+			{ "Φ", "Φ" },
+			{ "φ", "φ" },
+			{ "Χ", "Χ" },
+			{ "χ", "χ" },
+			{ "Ψ", "Ψ" },
+			{ "ψ", "ψ" },
+			{ "Ω", "Ω" },
+			{ "ω", "ω" },
+			{ "ϑ", "ϑ" },
+			{ "ϒ", "ϒ" },
+			{ "ϖ", "ϖ" },
+
+			{ _("Mathematical characters"), NULL },
+			{ "∀", "∀" },
+			{ "∂", "∂" },
+			{ "∃", "∃" },
+			{ "∅", "∅" },
+			{ "∇", "∇" },
+			{ "∈", "∈" },
+			{ "∉", "∉" },
+			{ "∋", "∋" },
+			{ "∏", "∏" },
+			{ "∑", "∑" },
+			{ "−", "−" },
+			{ "∗", "∗" },
+			{ "√", "√" },
+			{ "∝", "∝" },
+			{ "∞", "∞" },
+			{ "∠", "∠" },
+			{ "∧", "∧" },
+			{ "∨", "∨" },
+			{ "∩", "∩" },
+			{ "∪", "∪" },
+			{ "∫", "∫" },
+			{ "∴", "&there4;" },
+			{ "∼", "∼" },
+			{ "≅", "≅" },
+			{ "≈", "≈" },
+			{ "≠", "≠" },
+			{ "≡", "≡" },
+			{ "≤", "≤" },
+			{ "≥", "≥" },
+			{ "⊂", "⊂" },
+			{ "⊃", "⊃" },
+			{ "⊄", "⊄" },
+			{ "⊆", "⊆" },
+			{ "⊇", "⊇" },
+			{ "⊕", "⊕" },
+			{ "⊗", "⊗" },
+			{ "⊥", "⊥" },
+			{ "⋅", "⋅" },
+			{ "◊", "◊" },
+
+			{ _("Technical characters"), NULL },
+			{ "⌈", "⌈" },
+			{ "⌉", "⌉" },
+			{ "⌊", "⌊" },
+			{ "⌋", "⌋" },
+			{ "〈", "⟨" },
+			{ "〉", "⟩" },
+
+			{ _("Arrow characters"), NULL },
+			{ "←", "←" },
+			{ "↑", "↑" },
+			{ "→", "→" },
+			{ "↓", "↓" },
+			{ "↔", "↔" },
+			{ "↵", "↵" },
+			{ "⇐", "⇐" },
+			{ "⇑", "⇑" },
+			{ "⇒", "⇒" },
+			{ "⇓", "⇓" },
+			{ "⇔", "⇔" },
+
+			{ _("Punctuation characters"), NULL },
+			{ "–", "–" },
+			{ "—", "—" },
+			{ "‘", "‘" },
+			{ "’", "’" },
+			{ "‚", "‚" },
+			{ "“", "“" },
+			{ "”", "”" },
+			{ "„", "„" },
+			{ "†", "†" },
+			{ "‡", "‡" },
+			{ "…", "…" },
+			{ "‰", "‰" },
+			{ "‹", "‹" },
+			{ "›", "›" },
+
+			{ _("Miscellaneous characters"), NULL },
+			{ "•", "•" },
+			{ "′", "′" },
+			{ "″", "″" },
+			{ "‾", "‾" },
+			{ "⁄", "⁄" },
+			{ "℘", "℘" },
+			{ "ℑ", "ℑ" },
+			{ "ℜ", "ℜ" },
+			{ "™", "™" },
+			{ "€", "€" },
+			{ "ℵ", "ℵ" },
+			{ "♠", "♠" },
+			{ "♣", "♣" },
+			{ "♥", "♥" },
+			{ "♦", "♦" },
+			{ "Œ", "Œ" },
+			{ "œ", "œ" },
+			{ "Š", "Š" },
+			{ "š", "š" },
+			{ "Ÿ", "Ÿ" },
+			{ "ƒ", "ƒ" },
+		};
+
+	for (i = 0; i < G_N_ELEMENTS(chars); i++)
+	{
+		if (chars[i][1] == NULL)
+		{	// add a category
+			gtk_tree_store_append(store, &iter, NULL);
+			gtk_tree_store_set(store, &iter, COLUMN_CHARACTER, chars[i][0], -1);
+			if (parent_iter != NULL) gtk_tree_iter_free(parent_iter);
+			parent_iter = gtk_tree_iter_copy(&iter);
+		}
+		else
+		{	// add child to parent_iter
+			gtk_tree_store_append(store, &iter, parent_iter);
+			gtk_tree_store_set(store, &iter, COLUMN_CHARACTER, chars[i][0],
+											 COLUMN_HTML_NAME, chars[i][1], -1);
+		}
+	}
+}
+
+
+/* just inserts the HTML_NAME coloumn of the selected row at current position
+ * returns only TRUE if a valid selection(i.e. no category) could be found */
+static gboolean sc_insert(GtkTreeModel *model, GtkTreeIter *iter)
+{
+	gint idx = documents->get_cur_idx();
+	gboolean result = FALSE;
+
+	if (DOC_IDX_VALID(idx))
+	{
+		gchar *str;
+		gint pos = scintilla->get_current_position(doc_list[idx].sci);
+
+		gtk_tree_model_get(model, iter, COLUMN_HTML_NAME, &str, -1);
+		if (str && *str)
+		{
+			scintilla->insert_text(doc_list[idx].sci, pos, str);
+			g_free(str);
+			result = TRUE;
+		}
+	}
+	return result;
+}
+
+
+static void sc_on_tools_show_dialog_insert_special_chars_response(GtkDialog *dialog, gint response,
+														gpointer user_data)
+{
+	if (response == GTK_RESPONSE_OK)
+	{
+		GtkTreeSelection *selection;
+		GtkTreeModel *model;
+		GtkTreeIter iter;
+
+		selection = gtk_tree_view_get_selection(sc_tree);
+
+		if (gtk_tree_selection_get_selected(selection, &model, &iter))
+		{
+			// only hide dialog if selection was not a category
+			if (sc_insert(model, &iter))
+				gtk_widget_hide(GTK_WIDGET(dialog));
+		}
+	}
+	else
+		gtk_widget_hide(GTK_WIDGET(dialog));
+}
+
+
+static void sc_on_tree_row_activated(GtkTreeView *treeview, GtkTreePath *path,
+											  GtkTreeViewColumn *col, gpointer user_data)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model = GTK_TREE_MODEL(sc_store);
+
+	if (gtk_tree_model_get_iter(model, &iter, path))
+	{
+		// only hide dialog if selection was not a category
+		if (sc_insert(model, &iter))
+			gtk_widget_hide(sc_dialog);
+		else
+		{	// double click on a category to toggle the expand or collapse it
+			if (gtk_tree_view_row_expanded(sc_tree, path))
+				gtk_tree_view_collapse_row(sc_tree, path);
+			else
+				gtk_tree_view_expand_row(sc_tree, path, FALSE);
+		}
+	}
+}
+
+
+/* Callback when the menu item is clicked */
+static void
+item_activate(GtkMenuItem *menuitem, gpointer gdata)
+{
+	// refuse opening the dialog if we don't have an active tab
+	gint idx = documents->get_cur_idx();
+
+	if (idx == -1 || ! doc_list[idx].is_valid) return;
+
+	tools_show_dialog_insert_special_chars();
+}
+
+
+/* Called by Geany to initialize the plugin */
+void init(PluginData *data)
+{
+	GtkWidget *demo_item;
+
+	plugin_data = data;	// keep a pointer to the main application fields & functions
+
+	// Add an item to the Tools menu
+	demo_item = gtk_menu_item_new_with_mnemonic(_("_Insert Special HTML Characters"));
+	gtk_widget_show(demo_item);
+	gtk_container_add(GTK_CONTAINER(plugin_data->tools_menu), demo_item);
+	g_signal_connect(G_OBJECT(demo_item), "activate", G_CALLBACK(item_activate), NULL);
+
+	// let Geany remove the menu item when the plugin is unloaded
+	plugin_fields->menu_item = demo_item;
+	plugin_fields->flags = PLUGIN_IS_DOCUMENT_SENSITIVE;
+}
+
+
+/* Destroy static widgets */
+void cleanup()
+{
+	gtk_widget_destroy(sc_dialog);
+}
+
+


Property changes on: trunk/plugins/htmlchars.c
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Modified: trunk/src/callbacks.c
===================================================================
--- trunk/src/callbacks.c	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/src/callbacks.c	2007-07-23 15:41:08 UTC (rev 1734)
@@ -1828,18 +1828,6 @@
 
 
 void
-on_menu_insert_special_chars1_activate (GtkMenuItem     *menuitem,
-                                        gpointer         user_data)
-{
-	// refuse opening the dialog if we don't have an active tab
-	gint idx = document_get_cur_idx();
-	if (idx == -1 || ! doc_list[idx].is_valid) return;
-
-	tools_show_dialog_insert_special_chars();
-}
-
-
-void
 on_menu_comments_multiline_activate    (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {

Modified: trunk/src/callbacks.h
===================================================================
--- trunk/src/callbacks.h	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/src/callbacks.h	2007-07-23 15:41:08 UTC (rev 1734)
@@ -499,10 +499,6 @@
 
 
 void
-on_menu_insert_special_chars1_activate (GtkMenuItem     *menuitem,
-                                        gpointer         user_data);
-
-void
 on_menu_comments_multiline_activate    (GtkMenuItem     *menuitem,
                                         gpointer         user_data);
 

Modified: trunk/src/interface.c
===================================================================
--- trunk/src/interface.c	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/src/interface.c	2007-07-23 15:41:08 UTC (rev 1734)
@@ -37,7 +37,7 @@
   GtkWidget *file1_menu;
   GtkWidget *menu_new1;
   GtkWidget *menu_new_with_template1;
-  GtkWidget *image1901;
+  GtkWidget *image1920;
   GtkWidget *menu_new_with_template1_menu;
   GtkWidget *invisible2;
   GtkWidget *separator12;
@@ -48,11 +48,11 @@
   GtkWidget *menu_save1;
   GtkWidget *menu_save_as1;
   GtkWidget *menu_save_all1;
-  GtkWidget *image1902;
+  GtkWidget *image1921;
   GtkWidget *menu_reload1;
-  GtkWidget *image1903;
+  GtkWidget *image1922;
   GtkWidget *menu_reload_as1;
-  GtkWidget *image1904;
+  GtkWidget *image1923;
   GtkWidget *menu_reload_as1_menu;
   GtkWidget *invisible7;
   GtkWidget *separator21;
@@ -64,7 +64,7 @@
   GtkWidget *separator14;
   GtkWidget *menu_close1;
   GtkWidget *menu_close_all1;
-  GtkWidget *image1905;
+  GtkWidget *image1924;
   GtkWidget *menu_separatormenuitem1;
   GtkWidget *menu_quit1;
   GtkWidget *edit1;
@@ -90,20 +90,20 @@
   GtkWidget *menu_duplicate_line1;
   GtkWidget *separator29;
   GtkWidget *menu_increase_indent1;
-  GtkWidget *image1906;
+  GtkWidget *image1925;
   GtkWidget *menu_decrease_indent1;
-  GtkWidget *image1907;
+  GtkWidget *image1926;
   GtkWidget *separator37;
   GtkWidget *send_selection_to2;
   GtkWidget *send_selection_to2_menu;
   GtkWidget *invisible13;
   GtkWidget *separator18;
   GtkWidget *insert_include2;
-  GtkWidget *image1908;
+  GtkWidget *image1927;
   GtkWidget *insert_include2_menu;
   GtkWidget *invisible4;
   GtkWidget *add_comments1;
-  GtkWidget *image1909;
+  GtkWidget *image1928;
   GtkWidget *add_comments1_menu;
   GtkWidget *menu_add_changelog_entry1;
   GtkWidget *insert_file_header1;
@@ -112,7 +112,7 @@
   GtkWidget *insert_gpl_notice2;
   GtkWidget *insert_bsd_license_notice2;
   GtkWidget *insert_date1;
-  GtkWidget *image1910;
+  GtkWidget *image1929;
   GtkWidget *insert_date1_menu;
   GtkWidget *invisible8;
   GtkWidget *separator9;
@@ -124,7 +124,7 @@
   GtkWidget *find_previous1;
   GtkWidget *find_in_files1;
   GtkWidget *replace1;
-  GtkWidget *image1911;
+  GtkWidget *image1930;
   GtkWidget *separator33;
   GtkWidget *find_nextsel1;
   GtkWidget *find_prevsel1;
@@ -132,11 +132,11 @@
   GtkWidget *next_message1;
   GtkWidget *separator32;
   GtkWidget *go_to_line1;
-  GtkWidget *image1912;
+  GtkWidget *image1931;
   GtkWidget *menu_view1;
   GtkWidget *menu_view1_menu;
   GtkWidget *menu_change_font1;
-  GtkWidget *image1913;
+  GtkWidget *image1932;
   GtkWidget *menu_separator4;
   GtkWidget *menu_toggle_all_additional_widgets1;
   GtkWidget *menu_fullscreen1;
@@ -179,24 +179,23 @@
   GtkWidget *menu_project1;
   GtkWidget *menu_project1_menu;
   GtkWidget *project_new1;
-  GtkWidget *image1914;
+  GtkWidget *image1933;
   GtkWidget *project_open1;
-  GtkWidget *image1915;
+  GtkWidget *image1934;
   GtkWidget *project_close1;
-  GtkWidget *image1916;
+  GtkWidget *image1935;
   GtkWidget *separator34;
   GtkWidget *project_properties1;
   GtkWidget *menu_build1;
   GtkWidget *tools1;
   GtkWidget *tools1_menu;
   GtkWidget *menu_choose_color1;
-  GtkWidget *image1917;
+  GtkWidget *image1936;
   GtkWidget *menu_count_words1;
-  GtkWidget *menu_insert_special_chars1;
   GtkWidget *menu_help1;
   GtkWidget *menu_help1_menu;
   GtkWidget *help1;
-  GtkWidget *image1918;
+  GtkWidget *image1937;
   GtkWidget *keyboard_shortcuts1;
   GtkWidget *website1;
   GtkWidget *separator16;
@@ -296,9 +295,9 @@
   gtk_widget_show (menu_new_with_template1);
   gtk_container_add (GTK_CONTAINER (file1_menu), menu_new_with_template1);
 
-  image1901 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1901);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_new_with_template1), image1901);
+  image1920 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1920);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_new_with_template1), image1920);
 
   menu_new_with_template1_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_new_with_template1), menu_new_with_template1_menu);
@@ -341,25 +340,25 @@
   gtk_container_add (GTK_CONTAINER (file1_menu), menu_save_all1);
   gtk_tooltips_set_tip (tooltips, menu_save_all1, _("Saves all open files"), NULL);
 
-  image1902 = gtk_image_new_from_stock ("gtk-save", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1902);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_save_all1), image1902);
+  image1921 = gtk_image_new_from_stock ("gtk-save", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1921);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_save_all1), image1921);
 
   menu_reload1 = gtk_image_menu_item_new_with_mnemonic (_("_Reload"));
   gtk_widget_show (menu_reload1);
   gtk_container_add (GTK_CONTAINER (file1_menu), menu_reload1);
 
-  image1903 = gtk_image_new_from_stock ("gtk-revert-to-saved", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1903);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_reload1), image1903);
+  image1922 = gtk_image_new_from_stock ("gtk-revert-to-saved", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1922);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_reload1), image1922);
 
   menu_reload_as1 = gtk_image_menu_item_new_with_mnemonic (_("R_eload As"));
   gtk_widget_show (menu_reload_as1);
   gtk_container_add (GTK_CONTAINER (file1_menu), menu_reload_as1);
 
-  image1904 = gtk_image_new_from_stock ("gtk-revert-to-saved", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1904);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_reload_as1), image1904);
+  image1923 = gtk_image_new_from_stock ("gtk-revert-to-saved", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1923);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_reload_as1), image1923);
 
   menu_reload_as1_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_reload_as1), menu_reload_as1_menu);
@@ -410,9 +409,9 @@
   gtk_container_add (GTK_CONTAINER (file1_menu), menu_close_all1);
   gtk_tooltips_set_tip (tooltips, menu_close_all1, _("Closes all open files"), NULL);
 
-  image1905 = gtk_image_new_from_stock ("gtk-close", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1905);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_close_all1), image1905);
+  image1924 = gtk_image_new_from_stock ("gtk-close", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1924);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_close_all1), image1924);
 
   menu_separatormenuitem1 = gtk_separator_menu_item_new ();
   gtk_widget_show (menu_separatormenuitem1);
@@ -520,17 +519,17 @@
   gtk_widget_show (menu_increase_indent1);
   gtk_container_add (GTK_CONTAINER (menu_format1_menu), menu_increase_indent1);
 
-  image1906 = gtk_image_new_from_stock ("gtk-indent", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1906);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_increase_indent1), image1906);
+  image1925 = gtk_image_new_from_stock ("gtk-indent", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1925);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_increase_indent1), image1925);
 
   menu_decrease_indent1 = gtk_image_menu_item_new_with_mnemonic (_("_Decrease Indent"));
   gtk_widget_show (menu_decrease_indent1);
   gtk_container_add (GTK_CONTAINER (menu_format1_menu), menu_decrease_indent1);
 
-  image1907 = gtk_image_new_from_stock ("gtk-unindent", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1907);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_decrease_indent1), image1907);
+  image1926 = gtk_image_new_from_stock ("gtk-unindent", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1926);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_decrease_indent1), image1926);
 
   separator37 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator37);
@@ -556,9 +555,9 @@
   gtk_widget_show (insert_include2);
   gtk_container_add (GTK_CONTAINER (edit1_menu), insert_include2);
 
-  image1908 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1908);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (insert_include2), image1908);
+  image1927 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1927);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (insert_include2), image1927);
 
   insert_include2_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (insert_include2), insert_include2_menu);
@@ -570,9 +569,9 @@
   gtk_widget_show (add_comments1);
   gtk_container_add (GTK_CONTAINER (edit1_menu), add_comments1);
 
-  image1909 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1909);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (add_comments1), image1909);
+  image1928 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1928);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (add_comments1), image1928);
 
   add_comments1_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (add_comments1), add_comments1_menu);
@@ -611,9 +610,9 @@
   gtk_widget_show (insert_date1);
   gtk_container_add (GTK_CONTAINER (edit1_menu), insert_date1);
 
-  image1910 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1910);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (insert_date1), image1910);
+  image1929 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1929);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (insert_date1), image1929);
 
   insert_date1_menu = gtk_menu_new ();
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (insert_date1), insert_date1_menu);
@@ -657,9 +656,9 @@
   gtk_widget_show (replace1);
   gtk_container_add (GTK_CONTAINER (search1_menu), replace1);
 
-  image1911 = gtk_image_new_from_stock ("gtk-find-and-replace", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1911);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (replace1), image1911);
+  image1930 = gtk_image_new_from_stock ("gtk-find-and-replace", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1930);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (replace1), image1930);
 
   separator33 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator33);
@@ -692,9 +691,9 @@
   gtk_widget_show (go_to_line1);
   gtk_container_add (GTK_CONTAINER (search1_menu), go_to_line1);
 
-  image1912 = gtk_image_new_from_stock ("gtk-jump-to", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1912);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (go_to_line1), image1912);
+  image1931 = gtk_image_new_from_stock ("gtk-jump-to", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1931);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (go_to_line1), image1931);
 
   menu_view1 = gtk_menu_item_new_with_mnemonic (_("_View"));
   gtk_widget_show (menu_view1);
@@ -708,9 +707,9 @@
   gtk_container_add (GTK_CONTAINER (menu_view1_menu), menu_change_font1);
   gtk_tooltips_set_tip (tooltips, menu_change_font1, _("Change the default font"), NULL);
 
-  image1913 = gtk_image_new_from_stock ("gtk-select-font", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1913);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_change_font1), image1913);
+  image1932 = gtk_image_new_from_stock ("gtk-select-font", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1932);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_change_font1), image1932);
 
   menu_separator4 = gtk_separator_menu_item_new ();
   gtk_widget_show (menu_separator4);
@@ -898,25 +897,25 @@
   gtk_widget_show (project_new1);
   gtk_container_add (GTK_CONTAINER (menu_project1_menu), project_new1);
 
-  image1914 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1914);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (project_new1), image1914);
+  image1933 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1933);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (project_new1), image1933);
 
   project_open1 = gtk_image_menu_item_new_with_mnemonic (_("_Open"));
   gtk_widget_show (project_open1);
   gtk_container_add (GTK_CONTAINER (menu_project1_menu), project_open1);
 
-  image1915 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1915);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (project_open1), image1915);
+  image1934 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1934);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (project_open1), image1934);
 
   project_close1 = gtk_image_menu_item_new_with_mnemonic (_("_Close"));
   gtk_widget_show (project_close1);
   gtk_container_add (GTK_CONTAINER (menu_project1_menu), project_close1);
 
-  image1916 = gtk_image_new_from_stock ("gtk-close", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1916);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (project_close1), image1916);
+  image1935 = gtk_image_new_from_stock ("gtk-close", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1935);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (project_close1), image1935);
 
   separator34 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator34);
@@ -943,19 +942,15 @@
   gtk_container_add (GTK_CONTAINER (tools1_menu), menu_choose_color1);
   gtk_tooltips_set_tip (tooltips, menu_choose_color1, _("Open a color chooser dialog, to interactively pick colors from a palette."), NULL);
 
-  image1917 = gtk_image_new_from_stock ("gtk-select-color", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1917);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_choose_color1), image1917);
+  image1936 = gtk_image_new_from_stock ("gtk-select-color", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1936);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_choose_color1), image1936);
 
   menu_count_words1 = gtk_menu_item_new_with_mnemonic (_("_Word Count"));
   gtk_widget_show (menu_count_words1);
   gtk_container_add (GTK_CONTAINER (tools1_menu), menu_count_words1);
   gtk_tooltips_set_tip (tooltips, menu_count_words1, _("Counts the words and characters in the current selection or the whole document"), NULL);
 
-  menu_insert_special_chars1 = gtk_menu_item_new_with_mnemonic (_("_Insert Special HTML Characters"));
-  gtk_widget_show (menu_insert_special_chars1);
-  gtk_container_add (GTK_CONTAINER (tools1_menu), menu_insert_special_chars1);
-
   menu_help1 = gtk_menu_item_new_with_mnemonic (_("_Help"));
   gtk_widget_show (menu_help1);
   gtk_container_add (GTK_CONTAINER (menubar1), menu_help1);
@@ -967,9 +962,9 @@
   gtk_widget_show (help1);
   gtk_container_add (GTK_CONTAINER (menu_help1_menu), help1);
 
-  image1918 = gtk_image_new_from_stock ("gtk-help", GTK_ICON_SIZE_MENU);
-  gtk_widget_show (image1918);
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (help1), image1918);
+  image1937 = gtk_image_new_from_stock ("gtk-help", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image1937);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (help1), image1937);
 
   keyboard_shortcuts1 = gtk_menu_item_new_with_mnemonic (_("_Keyboard Shortcuts"));
   gtk_widget_show (keyboard_shortcuts1);
@@ -1510,9 +1505,6 @@
   g_signal_connect ((gpointer) menu_count_words1, "activate",
                     G_CALLBACK (on_count_words1_activate),
                     NULL);
-  g_signal_connect ((gpointer) menu_insert_special_chars1, "activate",
-                    G_CALLBACK (on_menu_insert_special_chars1_activate),
-                    NULL);
   g_signal_connect ((gpointer) help1, "activate",
                     G_CALLBACK (on_help1_activate),
                     NULL);
@@ -1616,7 +1608,7 @@
   GLADE_HOOKUP_OBJECT (window1, file1_menu, "file1_menu");
   GLADE_HOOKUP_OBJECT (window1, menu_new1, "menu_new1");
   GLADE_HOOKUP_OBJECT (window1, menu_new_with_template1, "menu_new_with_template1");
-  GLADE_HOOKUP_OBJECT (window1, image1901, "image1901");
+  GLADE_HOOKUP_OBJECT (window1, image1920, "image1920");
   GLADE_HOOKUP_OBJECT (window1, menu_new_with_template1_menu, "menu_new_with_template1_menu");
   GLADE_HOOKUP_OBJECT (window1, invisible2, "invisible2");
   GLADE_HOOKUP_OBJECT (window1, separator12, "separator12");
@@ -1627,11 +1619,11 @@
   GLADE_HOOKUP_OBJECT (window1, menu_save1, "menu_save1");
   GLADE_HOOKUP_OBJECT (window1, menu_save_as1, "menu_save_as1");
   GLADE_HOOKUP_OBJECT (window1, menu_save_all1, "menu_save_all1");
-  GLADE_HOOKUP_OBJECT (window1, image1902, "image1902");
+  GLADE_HOOKUP_OBJECT (window1, image1921, "image1921");
   GLADE_HOOKUP_OBJECT (window1, menu_reload1, "menu_reload1");
-  GLADE_HOOKUP_OBJECT (window1, image1903, "image1903");
+  GLADE_HOOKUP_OBJECT (window1, image1922, "image1922");
   GLADE_HOOKUP_OBJECT (window1, menu_reload_as1, "menu_reload_as1");
-  GLADE_HOOKUP_OBJECT (window1, image1904, "image1904");
+  GLADE_HOOKUP_OBJECT (window1, image1923, "image1923");
   GLADE_HOOKUP_OBJECT (window1, menu_reload_as1_menu, "menu_reload_as1_menu");
   GLADE_HOOKUP_OBJECT (window1, invisible7, "invisible7");
   GLADE_HOOKUP_OBJECT (window1, separator21, "separator21");
@@ -1643,7 +1635,7 @@
   GLADE_HOOKUP_OBJECT (window1, separator14, "separator14");
   GLADE_HOOKUP_OBJECT (window1, menu_close1, "menu_close1");
   GLADE_HOOKUP_OBJECT (window1, menu_close_all1, "menu_close_all1");
-  GLADE_HOOKUP_OBJECT (window1, image1905, "image1905");
+  GLADE_HOOKUP_OBJECT (window1, image1924, "image1924");
   GLADE_HOOKUP_OBJECT (window1, menu_separatormenuitem1, "menu_separatormenuitem1");
   GLADE_HOOKUP_OBJECT (window1, menu_quit1, "menu_quit1");
   GLADE_HOOKUP_OBJECT (window1, edit1, "edit1");
@@ -1669,20 +1661,20 @@
   GLADE_HOOKUP_OBJECT (window1, menu_duplicate_line1, "menu_duplicate_line1");
   GLADE_HOOKUP_OBJECT (window1, separator29, "separator29");
   GLADE_HOOKUP_OBJECT (window1, menu_increase_indent1, "menu_increase_indent1");
-  GLADE_HOOKUP_OBJECT (window1, image1906, "image1906");
+  GLADE_HOOKUP_OBJECT (window1, image1925, "image1925");
   GLADE_HOOKUP_OBJECT (window1, menu_decrease_indent1, "menu_decrease_indent1");
-  GLADE_HOOKUP_OBJECT (window1, image1907, "image1907");
+  GLADE_HOOKUP_OBJECT (window1, image1926, "image1926");
   GLADE_HOOKUP_OBJECT (window1, separator37, "separator37");
   GLADE_HOOKUP_OBJECT (window1, send_selection_to2, "send_selection_to2");
   GLADE_HOOKUP_OBJECT (window1, send_selection_to2_menu, "send_selection_to2_menu");
   GLADE_HOOKUP_OBJECT (window1, invisible13, "invisible13");
   GLADE_HOOKUP_OBJECT (window1, separator18, "separator18");
   GLADE_HOOKUP_OBJECT (window1, insert_include2, "insert_include2");
-  GLADE_HOOKUP_OBJECT (window1, image1908, "image1908");
+  GLADE_HOOKUP_OBJECT (window1, image1927, "image1927");
   GLADE_HOOKUP_OBJECT (window1, insert_include2_menu, "insert_include2_menu");
   GLADE_HOOKUP_OBJECT (window1, invisible4, "invisible4");
   GLADE_HOOKUP_OBJECT (window1, add_comments1, "add_comments1");
-  GLADE_HOOKUP_OBJECT (window1, image1909, "image1909");
+  GLADE_HOOKUP_OBJECT (window1, image1928, "image1928");
   GLADE_HOOKUP_OBJECT (window1, add_comments1_menu, "add_comments1_menu");
   GLADE_HOOKUP_OBJECT (window1, menu_add_changelog_entry1, "menu_add_changelog_entry1");
   GLADE_HOOKUP_OBJECT (window1, insert_file_header1, "insert_file_header1");
@@ -1691,7 +1683,7 @@
   GLADE_HOOKUP_OBJECT (window1, insert_gpl_notice2, "insert_gpl_notice2");
   GLADE_HOOKUP_OBJECT (window1, insert_bsd_license_notice2, "insert_bsd_license_notice2");
   GLADE_HOOKUP_OBJECT (window1, insert_date1, "insert_date1");
-  GLADE_HOOKUP_OBJECT (window1, image1910, "image1910");
+  GLADE_HOOKUP_OBJECT (window1, image1929, "image1929");
   GLADE_HOOKUP_OBJECT (window1, insert_date1_menu, "insert_date1_menu");
   GLADE_HOOKUP_OBJECT (window1, invisible8, "invisible8");
   GLADE_HOOKUP_OBJECT (window1, separator9, "separator9");
@@ -1703,7 +1695,7 @@
   GLADE_HOOKUP_OBJECT (window1, find_previous1, "find_previous1");
   GLADE_HOOKUP_OBJECT (window1, find_in_files1, "find_in_files1");
   GLADE_HOOKUP_OBJECT (window1, replace1, "replace1");
-  GLADE_HOOKUP_OBJECT (window1, image1911, "image1911");
+  GLADE_HOOKUP_OBJECT (window1, image1930, "image1930");
   GLADE_HOOKUP_OBJECT (window1, separator33, "separator33");
   GLADE_HOOKUP_OBJECT (window1, find_nextsel1, "find_nextsel1");
   GLADE_HOOKUP_OBJECT (window1, find_prevsel1, "find_prevsel1");
@@ -1711,11 +1703,11 @@
   GLADE_HOOKUP_OBJECT (window1, next_message1, "next_message1");
   GLADE_HOOKUP_OBJECT (window1, separator32, "separator32");
   GLADE_HOOKUP_OBJECT (window1, go_to_line1, "go_to_line1");
-  GLADE_HOOKUP_OBJECT (window1, image1912, "image1912");
+  GLADE_HOOKUP_OBJECT (window1, image1931, "image1931");
   GLADE_HOOKUP_OBJECT (window1, menu_view1, "menu_view1");
   GLADE_HOOKUP_OBJECT (window1, menu_view1_menu, "menu_view1_menu");
   GLADE_HOOKUP_OBJECT (window1, menu_change_font1, "menu_change_font1");
-  GLADE_HOOKUP_OBJECT (window1, image1913, "image1913");
+  GLADE_HOOKUP_OBJECT (window1, image1932, "image1932");
   GLADE_HOOKUP_OBJECT (window1, menu_separator4, "menu_separator4");
   GLADE_HOOKUP_OBJECT (window1, menu_toggle_all_additional_widgets1, "menu_toggle_all_additional_widgets1");
   GLADE_HOOKUP_OBJECT (window1, menu_fullscreen1, "menu_fullscreen1");
@@ -1757,24 +1749,23 @@
   GLADE_HOOKUP_OBJECT (window1, menu_project1, "menu_project1");
   GLADE_HOOKUP_OBJECT (window1, menu_project1_menu, "menu_project1_menu");
   GLADE_HOOKUP_OBJECT (window1, project_new1, "project_new1");
-  GLADE_HOOKUP_OBJECT (window1, image1914, "image1914");
+  GLADE_HOOKUP_OBJECT (window1, image1933, "image1933");
   GLADE_HOOKUP_OBJECT (window1, project_open1, "project_open1");
-  GLADE_HOOKUP_OBJECT (window1, image1915, "image1915");
+  GLADE_HOOKUP_OBJECT (window1, image1934, "image1934");
   GLADE_HOOKUP_OBJECT (window1, project_close1, "project_close1");
-  GLADE_HOOKUP_OBJECT (window1, image1916, "image1916");
+  GLADE_HOOKUP_OBJECT (window1, image1935, "image1935");
   GLADE_HOOKUP_OBJECT (window1, separator34, "separator34");
   GLADE_HOOKUP_OBJECT (window1, project_properties1, "project_properties1");
   GLADE_HOOKUP_OBJECT (window1, menu_build1, "menu_build1");
   GLADE_HOOKUP_OBJECT (window1, tools1, "tools1");
   GLADE_HOOKUP_OBJECT (window1, tools1_menu, "tools1_menu");
   GLADE_HOOKUP_OBJECT (window1, menu_choose_color1, "menu_choose_color1");
-  GLADE_HOOKUP_OBJECT (window1, image1917, "image1917");
+  GLADE_HOOKUP_OBJECT (window1, image1936, "image1936");
   GLADE_HOOKUP_OBJECT (window1, menu_count_words1, "menu_count_words1");
-  GLADE_HOOKUP_OBJECT (window1, menu_insert_special_chars1, "menu_insert_special_chars1");
   GLADE_HOOKUP_OBJECT (window1, menu_help1, "menu_help1");
   GLADE_HOOKUP_OBJECT (window1, menu_help1_menu, "menu_help1_menu");
   GLADE_HOOKUP_OBJECT (window1, help1, "help1");
-  GLADE_HOOKUP_OBJECT (window1, image1918, "image1918");
+  GLADE_HOOKUP_OBJECT (window1, image1937, "image1937");
   GLADE_HOOKUP_OBJECT (window1, keyboard_shortcuts1, "keyboard_shortcuts1");
   GLADE_HOOKUP_OBJECT (window1, website1, "website1");
   GLADE_HOOKUP_OBJECT (window1, separator16, "separator16");

Modified: trunk/src/keybindings.c
===================================================================
--- trunk/src/keybindings.c	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/src/keybindings.c	2007-07-23 15:41:08 UTC (rev 1734)
@@ -409,7 +409,7 @@
 	GEANY_ADD_ACCEL(GEANY_KEYS_MENU_REPLACETABS, menu_replace_tabs);
 	GEANY_ADD_ACCEL(GEANY_KEYS_MENU_FOLDALL, menu_fold_all1);
 	GEANY_ADD_ACCEL(GEANY_KEYS_MENU_UNFOLDALL, menu_unfold_all1);
-	GEANY_ADD_ACCEL(GEANY_KEYS_MENU_INSERTSPECIALCHARS, menu_insert_special_chars1);
+	//~ GEANY_ADD_ACCEL(GEANY_KEYS_MENU_INSERTSPECIALCHARS, menu_insert_special_chars1);
 	GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_TOLOWERCASE, menu_to_lower_case2);
 	GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_TOUPPERCASE, menu_to_upper_case2);
 	GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_COMMENTLINE, menu_comment_line1);
@@ -1206,7 +1206,8 @@
 
 static void cb_func_menu_insert_specialchars(G_GNUC_UNUSED guint key_id)
 {
-	on_menu_insert_special_chars1_activate(NULL, NULL);
+	// TODO: add plugin keybinding support
+	//~ on_menu_insert_special_chars1_activate(NULL, NULL);
 }
 
 static void cb_func_nav_back(G_GNUC_UNUSED guint key_id)

Modified: trunk/src/plugindata.h
===================================================================
--- trunk/src/plugindata.h	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/src/plugindata.h	2007-07-23 15:41:08 UTC (rev 1734)
@@ -25,9 +25,29 @@
 #ifndef PLUGIN_H
 #define PLUGIN_H
 
+/**
+ * Public symbols supported:
+ *
+ * version_check()
+ * 	Use VERSION_CHECK() macro instead. Required by Geany.
+ *
+ * PluginInfo* info()
+ * 	Use PLUGIN_INFO() macro to define it. Required by Geany.
+ *
+ * PluginFields* plugin_fields
+ * 	Plugin owned fields, including flags.
+ *
+ * void init(PluginData *data)
+ * 	Called after loading the plugin.
+ *
+ * void cleanup()
+ * 	Called before unloading the plugin.
+ */
+
+
 /* The API version should be incremented whenever any plugin data types below are
  * modified. */
-static const gint api_version = 4;
+static const gint api_version = 5;
 
 /* The ABI version should be incremented whenever existing fields in the plugin
  * data types below have to be changed or reordered. It should stay the same if fields
@@ -68,6 +88,21 @@
 	}
 
 
+typedef enum
+{
+	PLUGIN_IS_DOCUMENT_SENSITIVE	= 1 << 0	// if menu_item should be disabled when there are no documents
+}
+PluginFlags;
+
+/* Fields set and owned by the plugin */
+typedef struct PluginFields
+{
+	PluginFlags	flags;
+	GtkWidget	*menu_item;	// (optional) widget to be destroyed after unloading the plugin
+}
+PluginFields;
+
+
 typedef struct DocumentFuncs	DocumentFuncs;
 typedef struct ScintillaFuncs	ScintillaFuncs;
 typedef struct TemplateFuncs	TemplateFuncs;
@@ -80,10 +115,8 @@
  * making changes. */
 typedef struct PluginData
 {
-	MyApp	*app;	// Geany application data fields
-
+	MyApp		*app;	// Geany application data fields
 	GtkWidget	*tools_menu;	// Almost all plugins should add menu items to the Tools menu only
-
 	GArray		*doc_array;	// array of document pointers
 
 	DocumentFuncs	*document;
@@ -103,6 +136,7 @@
 struct DocumentFuncs
 {
 	gint (*new_file) (const gchar *filename, struct filetype *ft);
+	gint (*get_cur_idx) ();
 };
 
 struct _ScintillaObject;
@@ -110,6 +144,8 @@
 struct ScintillaFuncs
 {
 	void	(*set_text) (struct _ScintillaObject *sci, const gchar *text);
+	void	(*insert_text) (struct _ScintillaObject *sci, gint pos, const gchar *text);
+	gint	(*get_current_position) (struct _ScintillaObject *sci);
 };
 
 struct TemplateFuncs

Modified: trunk/src/plugins.c
===================================================================
--- trunk/src/plugins.c	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/src/plugins.c	2007-07-23 15:41:08 UTC (rev 1734)
@@ -40,13 +40,14 @@
 
 typedef struct Plugin
 {
-	GModule *module;
-	gchar	*filename;		// plugin filename (/path/libname.so)
-	PluginData data;
+	GModule 	*module;
+	gchar		*filename;		// plugin filename (/path/libname.so)
+	PluginData		data;
+	PluginFields	fields;
 
-	PluginInfo* (*info) ();	/* Returns plugin name, description */
-	void (*init) (PluginData *data);	/* Called when the plugin is enabled */
-	void (*cleanup) ();		/* Called when the plugin is disabled or when Geany exits */
+	PluginInfo*	(*info) ();	/* Returns plugin name, description */
+	void	(*init) (PluginData *data);	/* Called when the plugin is enabled */
+	void	(*cleanup) ();		/* Called when the plugin is disabled or when Geany exits */
 }
 Plugin;
 
@@ -54,11 +55,14 @@
 
 
 static DocumentFuncs doc_funcs = {
-	&document_new_file
+	&document_new_file,
+	&document_get_cur_idx
 };
 
 static ScintillaFuncs sci_funcs = {
-	&sci_set_text
+	&sci_set_text,
+	&sci_insert_text,
+	&sci_get_current_position
 };
 
 static TemplateFuncs template_funcs = {
@@ -145,14 +149,17 @@
 	Plugin *plugin;
 	GModule *module;
 	PluginInfo* (*info)();
+	PluginFields **plugin_fields;
 
 	g_return_val_if_fail(fname, NULL);
 	g_return_val_if_fail(g_module_supported(), NULL);
 
 	/* Don't use G_MODULE_BIND_LAZY otherwise we can get unresolved symbols at runtime,
-	 * causing a segfault.
-	 * Without that flag the module will safely fail to load. */
-	module = g_module_open(fname, 0);
+	 * causing a segfault. Without that flag the module will safely fail to load.
+	 * G_MODULE_BIND_LOCAL also helps find undefined symbols e.g. app when it would
+	 * otherwise not be detected due to the shadowing of Geany's app variable.
+	 * Also without G_MODULE_BIND_LOCAL calling info() in a plugin will be shadowed. */
+	module = g_module_open(fname, G_MODULE_BIND_LOCAL);
 	if (! module)
 	{
 		g_warning("%s", g_module_error());
@@ -194,12 +201,22 @@
 
 	init_plugin_data(&plugin->data);
 
+	g_module_symbol(module, "plugin_fields", (void *) &plugin_fields);
+	if (plugin_fields)
+		*plugin_fields = &plugin->fields;
+
 	g_module_symbol(module, "init", (void *) &plugin->init);
 	g_module_symbol(module, "cleanup", (void *) &plugin->cleanup);
 
 	if (plugin->init)
 		plugin->init(&plugin->data);
 
+	if (plugin->fields.flags & PLUGIN_IS_DOCUMENT_SENSITIVE)
+	{
+		gboolean enable = gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)) ? TRUE : FALSE;
+		gtk_widget_set_sensitive(plugin->fields.menu_item, enable);
+	}
+
 	geany_debug("Loaded:   %s (%s)", fname,
 		NVL(plugin->info()->name, "<Unknown>"));
 	return plugin;
@@ -215,6 +232,11 @@
 	if (plugin->cleanup)
 		plugin->cleanup();
 
+	if (plugin->fields.menu_item != NULL)
+	{
+		gtk_widget_destroy(plugin->fields.menu_item);
+	}
+
 	if (! g_module_close(plugin->module))
 		g_warning("%s: %s", plugin->filename, g_module_error());
 	else
@@ -265,4 +287,17 @@
 }
 
 
+void plugins_update_document_sensitive(gboolean enabled)
+{
+	GList *item;
+
+	for (item = plugin_list; item != NULL; item = g_list_next(item))
+	{
+		Plugin *plugin = item->data;
+
+		if (plugin->fields.flags & PLUGIN_IS_DOCUMENT_SENSITIVE)
+			gtk_widget_set_sensitive(plugin->fields.menu_item, enabled);
+	}
+}
+
 #endif

Modified: trunk/src/plugins.h
===================================================================
--- trunk/src/plugins.h	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/src/plugins.h	2007-07-23 15:41:08 UTC (rev 1734)
@@ -32,6 +32,9 @@
 
 void plugins_free();
 
+
+void plugins_update_document_sensitive(gboolean enabled);
+
 #endif
 
 #endif

Modified: trunk/src/tools.c
===================================================================
--- trunk/src/tools.c	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/src/tools.c	2007-07-23 15:41:08 UTC (rev 1734)
@@ -49,454 +49,6 @@
 #include "templates.h"
 
 
-enum
-{
-	COLUMN_CHARACTER,
-	COLUMN_HTML_NAME,
-	N_COLUMNS
-};
-
-static GtkWidget *sc_dialog = NULL;
-static GtkTreeStore *sc_store = NULL;
-static GtkTreeView *sc_tree = NULL;
-
-static void sc_on_tools_show_dialog_insert_special_chars_response
-		(GtkDialog *dialog, gint response, gpointer user_data);
-static void sc_on_tree_row_activated
-		(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer user_data);
-static void sc_fill_store(GtkTreeStore *store);
-static gboolean sc_insert(GtkTreeModel *model, GtkTreeIter *iter);
-
-
-void tools_show_dialog_insert_special_chars()
-{
-	if (sc_dialog == NULL)
-	{
-		gint height;
-		GtkCellRenderer *renderer;
-		GtkTreeViewColumn *column;
-		GtkWidget *swin, *vbox, *label;
-
-		sc_dialog = gtk_dialog_new_with_buttons(
-					_("Special Characters"), GTK_WINDOW(app->window),
-					GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-					_("_Insert"), GTK_RESPONSE_OK, NULL);
-		vbox = ui_dialog_vbox_new(GTK_DIALOG(sc_dialog));
-		gtk_box_set_spacing(GTK_BOX(vbox), 6);
-		gtk_widget_set_name(sc_dialog, "GeanyDialog");
-
-		height = GEANY_WINDOW_MINIMAL_HEIGHT;
-		gtk_window_set_default_size(GTK_WINDOW(sc_dialog), height * 0.8, height);
-		gtk_dialog_set_default_response(GTK_DIALOG(sc_dialog), GTK_RESPONSE_CANCEL);
-
-		label = gtk_label_new(_("Choose a special character from the list below and double click on it or use the button to insert it at the current cursor position."));
-		gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
-		gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-		gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
-
-		sc_tree = GTK_TREE_VIEW(gtk_tree_view_new());
-
-		sc_store = gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
-		gtk_tree_view_set_model(GTK_TREE_VIEW(sc_tree),
-								GTK_TREE_MODEL(sc_store));
-
-		renderer = gtk_cell_renderer_text_new();
-		column = gtk_tree_view_column_new_with_attributes(
-								_("Character"), renderer, "text", COLUMN_CHARACTER, NULL);
-		gtk_tree_view_column_set_resizable(column, TRUE);
-		gtk_tree_view_append_column(GTK_TREE_VIEW(sc_tree), column);
-
-		renderer = gtk_cell_renderer_text_new();
-		column = gtk_tree_view_column_new_with_attributes(
-								_("HTML (name)"), renderer, "text", COLUMN_HTML_NAME, NULL);
-		gtk_tree_view_column_set_resizable(column, TRUE);
-		gtk_tree_view_append_column(GTK_TREE_VIEW(sc_tree), column);
-
-		swin = gtk_scrolled_window_new(NULL, NULL);
-		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC,
-			GTK_POLICY_AUTOMATIC);
-		gtk_scrolled_window_add_with_viewport(
-					GTK_SCROLLED_WINDOW(swin), GTK_WIDGET(sc_tree));
-
-		gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0);
-
-		g_signal_connect((gpointer) sc_tree, "row-activated",
-					G_CALLBACK(sc_on_tree_row_activated), NULL);
-
-		g_signal_connect((gpointer) sc_dialog, "response",
-					G_CALLBACK(sc_on_tools_show_dialog_insert_special_chars_response), NULL);
-
-		g_signal_connect((gpointer) sc_dialog, "delete_event",
-					G_CALLBACK(gtk_widget_hide_on_delete), NULL);
-
-		sc_fill_store(sc_store);
-
-		//gtk_tree_view_expand_all(special_characters_tree);
-		gtk_tree_view_set_search_column(sc_tree, COLUMN_HTML_NAME);
-	}
-	gtk_widget_show_all(sc_dialog);
-}
-
-
-// fill the tree model with data
-/// TODO move this in a file and make it extendable for more data types
-static void sc_fill_store(GtkTreeStore *store)
-{
-	GtkTreeIter iter;
-	GtkTreeIter *parent_iter = NULL;
-	guint i;
-
-	gchar *chars[][2] =
-		{
-			{ _("HTML characters"), NULL },
-			{ "\"", """ },
-			{ "&", "&" },
-			{ "<", "<" },
-			{ ">", ">" },
-
-			{ _("ISO 8859-1 characters"), NULL },
-			{ " ", " " },
-			{ "¡", "¡" },
-			{ "¢", "¢" },
-			{ "£", "£" },
-			{ "¤", "¤" },
-			{ "¥", "¥" },
-			{ "¦", "¦" },
-			{ "§", "§" },
-			{ "¨", "¨" },
-			{ "©", "©" },
-			{ "®", "®" },
-			{ "«", "«" },
-			{ "»", "»" },
-			{ "¬", "¬" },
-			{ " ", "­" },
-			{ "¯", "¯" },
-			{ "°", "°" },
-			{ "±", "±" },
-			{ "¹", "&sup1;" },
-			{ "²", "&sup2;" },
-			{ "³", "&sup3;" },
-			{ "¼", "&frac14;" },
-			{ "½", "&frac12;" },
-			{ "¾", "&frac34;" },
-			{ "×", "×" },
-			{ "÷", "÷" },
-			{ "´", "´" },
-			{ "µ", "µ" },
-			{ "¶", "¶" },
-			{ "·", "·" },
-			{ "¸", "¸" },
-			{ "ª", "ª" },
-			{ "º", "º" },
-			{ "¿", "¿" },
-			{ "À", "À" },
-			{ "Á", "Á" },
-			{ "Â", "Â" },
-			{ "Ã", "Ã" },
-			{ "Ä", "Ä" },
-			{ "Å", "Å" },
-			{ "Æ", "Æ" },
-			{ "Ç", "Ç" },
-			{ "È", "È" },
-			{ "É", "É" },
-			{ "Ê", "Ê" },
-			{ "Ë", "Ë" },
-			{ "Ì", "Ì" },
-			{ "Í", "Í" },
-			{ "Î", "Î" },
-			{ "Ï", "Ï" },
-			{ "Ð", "Ð" },
-			{ "Ñ", "Ñ" },
-			{ "Ò", "Ò" },
-			{ "Ó", "Ó" },
-			{ "Ô", "Ô" },
-			{ "Õ", "Õ" },
-			{ "Ö", "Ö" },
-			{ "Ø", "Ø" },
-			{ "Ù", "Ù" },
-			{ "Ú", "Ú" },
-			{ "Û", "Û" },
-			{ "Ü", "Ü" },
-			{ "Ý", "Ý" },
-			{ "Þ", "Þ" },
-			{ "ß", "ß" },
-			{ "à", "à" },
-			{ "á", "á" },
-			{ "â", "â" },
-			{ "ã", "ã" },
-			{ "ä", "ä" },
-			{ "å", "å" },
-			{ "æ", "æ" },
-			{ "ç", "ç" },
-			{ "è", "è" },
-			{ "é", "é" },
-			{ "ê", "ê" },
-			{ "ë", "ë" },
-			{ "ì", "ì" },
-			{ "í", "í" },
-			{ "î", "î" },
-			{ "ï", "ï" },
-			{ "ð", "ð" },
-			{ "ñ", "ñ" },
-			{ "ò", "ò" },
-			{ "ó", "ó" },
-			{ "ô", "ô" },
-			{ "õ", "õ" },
-			{ "ö", "ö" },
-			{ "ø", "ø" },
-			{ "ù", "ù" },
-			{ "ú", "ú" },
-			{ "û", "û" },
-			{ "ü", "ü" },
-			{ "ý", "ý" },
-			{ "þ", "þ" },
-			{ "ÿ", "ÿ" },
-
-			{ _("Greek characters"), NULL },
-			{ "Α", "Α" },
-			{ "α", "α" },
-			{ "Β", "Β" },
-			{ "β", "β" },
-			{ "Γ", "Γ" },
-			{ "γ", "γ" },
-			{ "Δ", "Δ" },
-			{ "δ", "Δ" },
-			{ "δ", "δ" },
-			{ "Ε", "Ε" },
-			{ "ε", "ε" },
-			{ "Ζ", "Ζ" },
-			{ "ζ", "ζ" },
-			{ "Η", "Η" },
-			{ "η", "η" },
-			{ "Θ", "Θ" },
-			{ "θ", "θ" },
-			{ "Ι", "Ι" },
-			{ "ι", "ι" },
-			{ "Κ", "Κ" },
-			{ "κ", "κ" },
-			{ "Λ", "Λ" },
-			{ "λ", "λ" },
-			{ "Μ", "Μ" },
-			{ "μ", "μ" },
-			{ "Ν", "Ν" },
-			{ "ν", "ν" },
-			{ "Ξ", "Ξ" },
-			{ "ξ", "ξ" },
-			{ "Ο", "Ο" },
-			{ "ο", "ο" },
-			{ "Π", "Π" },
-			{ "π", "π" },
-			{ "Ρ", "Ρ" },
-			{ "ρ", "ρ" },
-			{ "Σ", "Σ" },
-			{ "ς", "ς" },
-			{ "σ", "σ" },
-			{ "Τ", "Τ" },
-			{ "τ", "τ" },
-			{ "Υ", "Υ" },
-			{ "υ", "υ" },
-			{ "Φ", "Φ" },
-			{ "φ", "φ" },
-			{ "Χ", "Χ" },
-			{ "χ", "χ" },
-			{ "Ψ", "Ψ" },
-			{ "ψ", "ψ" },
-			{ "Ω", "Ω" },
-			{ "ω", "ω" },
-			{ "ϑ", "ϑ" },
-			{ "ϒ", "ϒ" },
-			{ "ϖ", "ϖ" },
-
-			{ _("Mathematical characters"), NULL },
-			{ "∀", "∀" },
-			{ "∂", "∂" },
-			{ "∃", "∃" },
-			{ "∅", "∅" },
-			{ "∇", "∇" },
-			{ "∈", "∈" },
-			{ "∉", "∉" },
-			{ "∋", "∋" },
-			{ "∏", "∏" },
-			{ "∑", "∑" },
-			{ "−", "−" },
-			{ "∗", "∗" },
-			{ "√", "√" },
-			{ "∝", "∝" },
-			{ "∞", "∞" },
-			{ "∠", "∠" },
-			{ "∧", "∧" },
-			{ "∨", "∨" },
-			{ "∩", "∩" },
-			{ "∪", "∪" },
-			{ "∫", "∫" },
-			{ "∴", "&there4;" },
-			{ "∼", "∼" },
-			{ "≅", "≅" },
-			{ "≈", "≈" },
-			{ "≠", "≠" },
-			{ "≡", "≡" },
-			{ "≤", "≤" },
-			{ "≥", "≥" },
-			{ "⊂", "⊂" },
-			{ "⊃", "⊃" },
-			{ "⊄", "⊄" },
-			{ "⊆", "⊆" },
-			{ "⊇", "⊇" },
-			{ "⊕", "⊕" },
-			{ "⊗", "⊗" },
-			{ "⊥", "⊥" },
-			{ "⋅", "⋅" },
-			{ "◊", "◊" },
-
-			{ _("Technical characters"), NULL },
-			{ "⌈", "⌈" },
-			{ "⌉", "⌉" },
-			{ "⌊", "⌊" },
-			{ "⌋", "⌋" },
-			{ "〈", "⟨" },
-			{ "〉", "⟩" },
-
-			{ _("Arrow characters"), NULL },
-			{ "←", "←" },
-			{ "↑", "↑" },
-			{ "→", "→" },
-			{ "↓", "↓" },
-			{ "↔", "↔" },
-			{ "↵", "↵" },
-			{ "⇐", "⇐" },
-			{ "⇑", "⇑" },
-			{ "⇒", "⇒" },
-			{ "⇓", "⇓" },
-			{ "⇔", "⇔" },
-
-			{ _("Punctuation characters"), NULL },
-			{ "–", "–" },
-			{ "—", "—" },
-			{ "‘", "‘" },
-			{ "’", "’" },
-			{ "‚", "‚" },
-			{ "“", "“" },
-			{ "”", "”" },
-			{ "„", "„" },
-			{ "†", "†" },
-			{ "‡", "‡" },
-			{ "…", "…" },
-			{ "‰", "‰" },
-			{ "‹", "‹" },
-			{ "›", "›" },
-
-			{ _("Miscellaneous characters"), NULL },
-			{ "•", "•" },
-			{ "′", "′" },
-			{ "″", "″" },
-			{ "‾", "‾" },
-			{ "⁄", "⁄" },
-			{ "℘", "℘" },
-			{ "ℑ", "ℑ" },
-			{ "ℜ", "ℜ" },
-			{ "™", "™" },
-			{ "€", "€" },
-			{ "ℵ", "ℵ" },
-			{ "♠", "♠" },
-			{ "♣", "♣" },
-			{ "♥", "♥" },
-			{ "♦", "♦" },
-			{ "Œ", "Œ" },
-			{ "œ", "œ" },
-			{ "Š", "Š" },
-			{ "š", "š" },
-			{ "Ÿ", "Ÿ" },
-			{ "ƒ", "ƒ" },
-		};
-
-	for (i = 0; i < G_N_ELEMENTS(chars); i++)
-	{
-		if (chars[i][1] == NULL)
-		{	// add a category
-			gtk_tree_store_append(store, &iter, NULL);
-			gtk_tree_store_set(store, &iter, COLUMN_CHARACTER, chars[i][0], -1);
-			if (parent_iter != NULL) gtk_tree_iter_free(parent_iter);
-			parent_iter = gtk_tree_iter_copy(&iter);
-		}
-		else
-		{	// add child to parent_iter
-			gtk_tree_store_append(store, &iter, parent_iter);
-			gtk_tree_store_set(store, &iter, COLUMN_CHARACTER, chars[i][0],
-											 COLUMN_HTML_NAME, chars[i][1], -1);
-		}
-	}
-}
-
-
-/* just inserts the HTML_NAME coloumn of the selected row at current position
- * returns only TRUE if a valid selection(i.e. no category) could be found */
-static gboolean sc_insert(GtkTreeModel *model, GtkTreeIter *iter)
-{
-	gint idx = document_get_cur_idx();
-	gboolean result = FALSE;
-
-	if (DOC_IDX_VALID(idx))
-	{
-		gchar *str;
-		gint pos = sci_get_current_position(doc_list[idx].sci);
-
-		gtk_tree_model_get(model, iter, COLUMN_HTML_NAME, &str, -1);
-		if (str && *str)
-		{
-			sci_insert_text(doc_list[idx].sci, pos, str);
-			g_free(str);
-			result = TRUE;
-		}
-	}
-	return result;
-}
-
-
-static void sc_on_tools_show_dialog_insert_special_chars_response(GtkDialog *dialog, gint response,
-														gpointer user_data)
-{
-	if (response == GTK_RESPONSE_OK)
-	{
-		GtkTreeSelection *selection;
-		GtkTreeModel *model;
-		GtkTreeIter iter;
-
-		selection = gtk_tree_view_get_selection(sc_tree);
-
-		if (gtk_tree_selection_get_selected(selection, &model, &iter))
-		{
-			// only hide dialog if selection was not a category
-			if (sc_insert(model, &iter))
-				gtk_widget_hide(GTK_WIDGET(dialog));
-		}
-	}
-	else
-		gtk_widget_hide(GTK_WIDGET(dialog));
-}
-
-
-static void sc_on_tree_row_activated(GtkTreeView *treeview, GtkTreePath *path,
-											  GtkTreeViewColumn *col, gpointer user_data)
-{
-	GtkTreeIter iter;
-	GtkTreeModel *model = GTK_TREE_MODEL(sc_store);
-
-	if (gtk_tree_model_get_iter(model, &iter, path))
-	{
-		// only hide dialog if selection was not a category
-		if (sc_insert(model, &iter))
-			gtk_widget_hide(sc_dialog);
-		else
-		{	// double click on a category to toggle the expand or collapse it
-			if (gtk_tree_view_row_expanded(sc_tree, path))
-				gtk_tree_view_collapse_row(sc_tree, path);
-			else
-				gtk_tree_view_expand_row(sc_tree, path, FALSE);
-		}
-	}
-}
-
-
 /* custom commands code*/
 struct cc_dialog
 {

Modified: trunk/src/tools.h
===================================================================
--- trunk/src/tools.h	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/src/tools.h	2007-07-23 15:41:08 UTC (rev 1734)
@@ -25,8 +25,6 @@
 #ifndef GEANY_TOOLS_H
 #define GEANY_TOOLS_H 1
 
-void tools_show_dialog_insert_special_chars();
-
 void tools_create_insert_custom_command_menu_items();
 
 void tools_execute_custom_command(gint idx, const gchar *command);

Modified: trunk/src/ui_utils.c
===================================================================
--- trunk/src/ui_utils.c	2007-07-23 09:26:05 UTC (rev 1733)
+++ trunk/src/ui_utils.c	2007-07-23 15:41:08 UTC (rev 1734)
@@ -42,11 +42,12 @@
 #include "win32.h"
 #include "project.h"
 #include "editor.h"
+#include "plugins.h"
 
 
 static struct
 {
-	GtkWidget *document_buttons[39];	// widgets only sensitive when there is at least one document
+	GtkWidget *document_buttons[38];	// widgets only sensitive when there is at least one document
 }
 widgets;
 
@@ -553,7 +554,6 @@
 	widgets.document_buttons[35] = lookup_widget(app->window, "insert_date1");
 	widgets.document_buttons[36] = lookup_widget(app->window, "menu_format1");
 	widgets.document_buttons[37] = lookup_widget(app->window, "menu_open_selected_file1");
-	widgets.document_buttons[38] = lookup_widget(app->window, "menu_insert_special_chars1");
 }
 
 
@@ -564,6 +564,8 @@
 
 	for (i = 0; i < G_N_ELEMENTS(widgets.document_buttons); i++)
 		gtk_widget_set_sensitive(widgets.document_buttons[i], enable);
+
+	plugins_update_document_sensitive(enable);
 }
 
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list