SF.net SVN: geany: [2315] branches/plugin-keybindings

ntrel at users.sourceforge.net ntrel at xxxxx
Fri Mar 7 18:00:22 UTC 2008


Revision: 2315
          http://geany.svn.sourceforge.net/geany/?rev=2315&view=rev
Author:   ntrel
Date:     2008-03-07 10:00:22 -0800 (Fri, 07 Mar 2008)

Log Message:
-----------
Add support for plugin keybindings using the PLUGIN_KEY_GROUP()
macro. Note: plugin keybindings are not yet loaded from the keyfile.
Add a plugin keybinding for 'Insert Special HTML Characters'.

Modified Paths:
--------------
    branches/plugin-keybindings/ChangeLog
    branches/plugin-keybindings/doc/plugins.dox
    branches/plugin-keybindings/plugins/htmlchars.c
    branches/plugin-keybindings/src/keybindings.c
    branches/plugin-keybindings/src/keybindings.h
    branches/plugin-keybindings/src/plugindata.h
    branches/plugin-keybindings/src/plugins.c

Modified: branches/plugin-keybindings/ChangeLog
===================================================================
--- branches/plugin-keybindings/ChangeLog	2008-03-07 17:24:36 UTC (rev 2314)
+++ branches/plugin-keybindings/ChangeLog	2008-03-07 18:00:22 UTC (rev 2315)
@@ -1,3 +1,22 @@
+2008-03-07  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/keybindings.h:
+   Add documentation for keybindings structs.
+ * src/keybindings.c:
+   Allow plugins to use keybindings_lookup_item().
+ * src/keybindings.c, src/keybindings.h, src/plugindata.h,
+   src/plugins.c, doc/plugins.dox, plugins/htmlchars.c:
+   Add support for plugin keybindings using the PLUGIN_KEY_GROUP()
+   macro. Note: plugin keybindings are not yet loaded from the keyfile.
+   Add a plugin keybinding for 'Insert Special HTML Characters'.
+
+
+2008-03-04  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/build.c, src/keybindings.c:
+   Re-enable setting menu accelerators.
+
+
 2008-03-03  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
 
  * src/prefs.c:
@@ -7,8 +26,6 @@
    Re-enable focus commands in the VTE.
    Re-enable snippets completion.
    Re-enable Keyboard Shortcuts dialog.
- * src/build.c, src/keybindings.c:
-   Re-enable setting menu accelerators.
 
 
 2008-02-29  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>

Modified: branches/plugin-keybindings/doc/plugins.dox
===================================================================
--- branches/plugin-keybindings/doc/plugins.dox	2008-03-07 17:24:36 UTC (rev 2314)
+++ branches/plugin-keybindings/doc/plugins.dox	2008-03-07 18:00:22 UTC (rev 2315)
@@ -49,10 +49,10 @@
  *  are optional, i.e. they can be omitted, others are required and must be defined.
  *
  *  - @code version_check() @endcode
- * 	  Use VERSION_CHECK() macro instead. Required by Geany.
+ * 	  Use the VERSION_CHECK() macro instead. Required by Geany.
  *
  *  - @code PluginInfo* info() @endcode
- * 	  Use PLUGIN_INFO() macro to define it. Required by Geany.
+ * 	  Use the PLUGIN_INFO() macro to define it. Required by Geany.
  *
  *  - @code GeanyData* geany_data @endcode
  * 	  Geany owned fields and functions.
@@ -64,6 +64,9 @@
  * 	  An array for connecting GeanyObject events, which should be terminated with
  * 	  {NULL, NULL, FALSE, NULL}. See @link signals Signal documentation @endlink.
  *
+ *  - @code KeyBindingGroup plugin_key_group[1] @endcode
+ * 	  Use the PLUGIN_KEY_GROUP() macro to define it.
+ *
  *  - @code void configure(GtkWidget *parent) @endcode
  * 	  Called when the plugin should show a configure dialog to let the user set some basic
  *    plugin configuration. Optionally, can be omitted when not needed.
@@ -84,7 +87,7 @@
  *
  *  To use plugin signals in Geany, you simply create a GeanyCallback array, list the signals
  *  you want to listen to and create the appropiate signal callbacks for each signal.
- *  @note The GeanyCallback array has be ended with a final NULL entry.
+ *  @note The GeanyCallback array has to be ended with a final NULL entry.
  *
  *  The following code demonstrates how to use signals in Geany plugins. The code can be inserted
  *  in your plugin code at any desired position.
@@ -193,7 +196,7 @@
  *  @section intro Introduction
  *
  *  Since Geany 0.12 there is a plugin interface to extend Geany's functionality and
- *  add new features. This %document gives a briefly overview about how to add new
+ *  add new features. This %document gives a brief overview about how to add new
  *  plugins by writing a simple "Hello World" plugin in C.
  *
  *

Modified: branches/plugin-keybindings/plugins/htmlchars.c
===================================================================
--- branches/plugin-keybindings/plugins/htmlchars.c	2008-03-07 17:24:36 UTC (rev 2314)
+++ branches/plugin-keybindings/plugins/htmlchars.c	2008-03-07 18:00:22 UTC (rev 2315)
@@ -28,6 +28,7 @@
 #include "support.h"
 #include "plugindata.h"
 #include "document.h"
+#include "keybindings.h"
 #include "pluginmacros.h"
 
 
@@ -41,8 +42,18 @@
 	_("The Geany developer team"))
 
 
+/* Keybinding(s) */
 enum
 {
+	KB_INSERT_HTML_CHARS,
+	KB_COUNT
+};
+
+PLUGIN_KEY_GROUP(html_chars, KB_COUNT)
+
+
+enum
+{
 	COLUMN_CHARACTER,
 	COLUMN_HTML_NAME,
 	N_COLUMNS
@@ -503,13 +514,39 @@
 }
 
 
+static void kb_activate(G_GNUC_UNUSED guint key_id)
+{
+	item_activate(NULL, NULL);
+}
+
+
+/* simple convenience function to fill a KeyBinding struct item */
+static void add_kb(KeyBindingGroup *group, gsize kb_id,
+		KBCallback func, guint key, GdkModifierType mod,
+		const gchar *name, const gchar *label)
+{
+	KeyBinding *kb;
+
+	g_assert(kb_id < group->count);
+
+	kb = &group->keys[kb_id];
+
+	kb->name = name;
+	kb->label = label;
+	kb->key = key;
+	kb->mods = mod;
+	kb->cb_func = func;
+}
+
+
 /* Called by Geany to initialize the plugin */
 void init(GeanyData *data)
 {
 	GtkWidget *demo_item;
+	const gchar *menu_text = _("_Insert Special HTML Characters");
 
 	/* Add an item to the Tools menu */
-	demo_item = gtk_menu_item_new_with_mnemonic(_("_Insert Special HTML Characters"));
+	demo_item = gtk_menu_item_new_with_mnemonic(menu_text);
 	gtk_widget_show(demo_item);
 	gtk_container_add(GTK_CONTAINER(geany_data->tools_menu), demo_item);
 	g_signal_connect(G_OBJECT(demo_item), "activate", G_CALLBACK(item_activate), NULL);
@@ -517,6 +554,10 @@
 	/* disable menu_item when there are no documents open */
 	plugin_fields->menu_item = demo_item;
 	plugin_fields->flags = PLUGIN_IS_DOCUMENT_SENSITIVE;
+
+	/* setup keybindings */
+	add_kb(plugin_key_group, KB_INSERT_HTML_CHARS, kb_activate,
+		0, 0, "insert_html_chars", menu_text);
 }
 
 

Modified: branches/plugin-keybindings/src/keybindings.c
===================================================================
--- branches/plugin-keybindings/src/keybindings.c	2008-03-07 17:24:36 UTC (rev 2314)
+++ branches/plugin-keybindings/src/keybindings.c	2008-03-07 18:00:22 UTC (rev 2315)
@@ -78,7 +78,6 @@
 static void cb_func_reloadtaglist(guint key_id);
 
 static void cb_func_menu_opencolorchooser(guint key_id);
-static void cb_func_menu_insert_specialchars(guint key_id);
 
 static void cb_func_build_action(guint key_id);
 
@@ -289,8 +288,6 @@
 
 	add_kb(group, GEANY_KEYS_MENU_OPENCOLORCHOOSER, cb_func_menu_opencolorchooser,
 		0, 0, "menu_opencolorchooser", _("Show Color Chooser"));
-	add_kb(group, GEANY_KEYS_MENU_INSERTSPECIALCHARS, cb_func_menu_insert_specialchars,
-		0, 0, "menu_insert_specialchars", _("Insert Special HTML Characters"));
 
 	group = ADD_KB_GROUP(HELP, _("Help menu"));
 
@@ -554,7 +551,6 @@
 
 	group = g_ptr_array_index(keybinding_groups, GEANY_KEYGROUP_TOOLS);
 	GEANY_ADD_ACCEL(GEANY_KEYS_MENU_OPENCOLORCHOOSER, menu_choose_color1);
-	/*GEANY_ADD_ACCEL(GEANY_KEYS_MENU_INSERTSPECIALCHARS, menu_insert_special_chars1);*/
 
 	group = g_ptr_array_index(keybinding_groups, GEANY_KEYGROUP_EDITING);
 	GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_TOGGLECASE, menu_toggle_case2);
@@ -1515,12 +1511,6 @@
 	gtk_menu_item_activate(GTK_MENU_ITEM(lookup_widget(app->window, "insert_date_custom1")));
 }
 
-static void cb_func_menu_insert_specialchars(G_GNUC_UNUSED guint key_id)
-{
-	/** 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)
 {
 	navqueue_go_back();

Modified: branches/plugin-keybindings/src/keybindings.h
===================================================================
--- branches/plugin-keybindings/src/keybindings.h	2008-03-07 17:24:36 UTC (rev 2314)
+++ branches/plugin-keybindings/src/keybindings.h	2008-03-07 18:00:22 UTC (rev 2315)
@@ -164,7 +164,6 @@
 enum
 {
 	GEANY_KEYS_MENU_OPENCOLORCHOOSER,
-	GEANY_KEYS_MENU_INSERTSPECIALCHARS,
 	GEANY_KEYS_TOOLS_COUNT
 };
 

Modified: branches/plugin-keybindings/src/plugindata.h
===================================================================
--- branches/plugin-keybindings/src/plugindata.h	2008-03-07 17:24:36 UTC (rev 2314)
+++ branches/plugin-keybindings/src/plugindata.h	2008-03-07 18:00:22 UTC (rev 2315)
@@ -43,7 +43,7 @@
  * are only appended, as this doesn't affect existing fields. */
 static const gint abi_version = 21;
 
-/* This performs runtime checks that try to ensure:
+/** This performs runtime checks that try to ensure:
  * 1. Geany ABI data types are compatible with this plugin.
  * 2. Geany sources provide the required API for this plugin. */
 /* TODO: if possible, the API version should be checked at compile time, not runtime. */
@@ -92,6 +92,27 @@
 	}
 
 
+/** Declare and initialise a keybinding group.
+ * @code KeyBindingGroup plugin_key_group[1]; @endcode
+ * You must then set the @c plugin_key_group::keys[] entries for the group in init().
+ * The @c plugin_key_group::label field is set by Geany after @c init()
+ * is called, to the name of the plugin.
+ * @param group_name A unique group name (without quotes) to be used in the
+ * configuration file, such as @c html_chars.
+ * @param key_count	The number of keybindings the group will hold.
+ * @note This is a single element array for implementation reasons,
+ * but you can treat it like a pointer. */
+#define PLUGIN_KEY_GROUP(group_name, key_count) \
+	static KeyBinding plugin_keys[key_count]; \
+	\
+	/* We have to declare plugin_key_group as a single element array.
+	 * Declaring as a pointer to a struct doesn't work with g_module_symbol(). */ \
+	KeyBindingGroup plugin_key_group[1] = \
+	{ \
+		{G_STRINGIFY(group_name), NULL, key_count, plugin_keys} \
+	};
+
+
 /** callback array entry */
 typedef struct GeanyCallback
 {

Modified: branches/plugin-keybindings/src/plugins.c
===================================================================
--- branches/plugin-keybindings/src/plugins.c	2008-03-07 17:24:36 UTC (rev 2314)
+++ branches/plugin-keybindings/src/plugins.c	2008-03-07 18:00:22 UTC (rev 2315)
@@ -66,20 +66,21 @@
 typedef struct Plugin
 {
 	GModule 	*module;
-	gchar		*filename;		/* plugin filename (/path/libname.so) */
+	gchar		*filename;				/* plugin filename (/path/libname.so) */
 	PluginFields	fields;
-	gulong		*signal_ids;		/* signal IDs to disconnect when unloading */
+	gulong		*signal_ids;			/* signal IDs to disconnect when unloading */
 	gsize		signal_ids_len;
+	KeyBindingGroup	*key_group;
 
-	PluginInfo*	(*info) (void);	/* Returns plugin name, description */
+	PluginInfo*	(*info) (void);			/* Returns plugin name, description */
 	void	(*init) (GeanyData *data);	/* Called when the plugin is enabled */
 	void	(*configure) (GtkWidget *parent);	/* plugin configure dialog, optionally */
-	void	(*cleanup) (void);	/* Called when the plugin is disabled or when Geany exits */
+	void	(*cleanup) (void);			/* Called when the plugin is disabled or when Geany exits */
 }
 Plugin;
 
 
-static GList *plugin_list = NULL; /* list of all available, loadable plugins */
+static GList *plugin_list = NULL; 		/* list of all available, loadable plugins */
 static GList *active_plugin_list = NULL; /* list of only actually loaded plugins */
 static GtkWidget *separator = NULL;
 static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data);
@@ -358,6 +359,15 @@
 
 
 static void
+add_kb_group(Plugin *plugin)
+{
+	g_ptr_array_add(keybinding_groups, plugin->key_group);
+
+	plugin->key_group->label = plugin->info()->name;
+}
+
+
+static void
 plugin_init(Plugin *plugin)
 {
 	GeanyCallback *callbacks;
@@ -375,6 +385,11 @@
 	if (callbacks)
 		add_callbacks(plugin, callbacks);
 
+	g_module_symbol(plugin->module, "plugin_key_group",
+		(void *) &plugin->key_group);
+	if (plugin->key_group)
+		add_kb_group(plugin);
+
 	active_plugin_list = g_list_append(active_plugin_list, plugin);
 
 	geany_debug("Loaded:   %s (%s)", plugin->filename,
@@ -483,16 +498,20 @@
 	g_return_if_fail(plugin);
 	g_return_if_fail(plugin->module);
 
-	if (g_list_find(active_plugin_list, plugin))
-	{	/* only do cleanup if the plugin was actually loaded */
-		if (plugin->cleanup)
-			plugin->cleanup();
+	/* only do cleanup if the plugin was actually loaded */
+	if (! g_list_find(active_plugin_list, plugin))
+		return;
 
-		remove_callbacks(plugin);
+	if (plugin->cleanup)
+		plugin->cleanup();
 
-		active_plugin_list = g_list_remove(active_plugin_list, plugin);
-		geany_debug("Unloaded: %s", plugin->filename);
-	}
+	remove_callbacks(plugin);
+
+	if (plugin->key_group)
+		g_ptr_array_remove_fast(keybinding_groups, plugin->key_group);
+
+	active_plugin_list = g_list_remove(active_plugin_list, plugin);
+	geany_debug("Unloaded: %s", plugin->filename);
 }
 
 


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