Kaydet (Commit) 747d2d2b authored tarafından Nick Treleaven's avatar Nick Treleaven

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'.


git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/branches/plugin-keybindings@2315 ea778897-0a13-0410-b9d1-a72fbfd435f5
üst 5e952cc7
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>
......
......@@ -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 @@ GeanyCallback geany_callbacks[] =
* @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.
*
*
......
......@@ -28,6 +28,7 @@
#include "support.h"
#include "plugindata.h"
#include "document.h"
#include "keybindings.h"
#include "pluginmacros.h"
......@@ -41,6 +42,16 @@ PLUGIN_INFO(_("HTML Characters"), _("Inserts HTML character entities like '&amp;
_("The Geany developer team"))
/* Keybinding(s) */
enum
{
KB_INSERT_HTML_CHARS,
KB_COUNT
};
PLUGIN_KEY_GROUP(html_chars, KB_COUNT)
enum
{
COLUMN_CHARACTER,
......@@ -503,13 +514,39 @@ item_activate(GtkMenuItem *menuitem, gpointer gdata)
}
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 @@ void init(GeanyData *data)
/* 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);
}
......
......@@ -78,7 +78,6 @@ static void cb_func_menu_unfoldall(guint key_id);
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 @@ static void init_default_kb(void)
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 @@ static void add_menu_accels()
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 @@ static void cb_func_menu_insert_date(G_GNUC_UNUSED guint key_id)
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();
......
......@@ -164,7 +164,6 @@ enum
enum
{
GEANY_KEYS_MENU_OPENCOLORCHOOSER,
GEANY_KEYS_MENU_INSERTSPECIALCHARS,
GEANY_KEYS_TOOLS_COUNT
};
......
......@@ -43,7 +43,7 @@ static const gint api_version = 46;
* 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 @@ PluginInfo;
}
/** 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
{
......
......@@ -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);
......@@ -357,6 +358,15 @@ is_active_plugin(const gchar *name)
}
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)
{
......@@ -375,6 +385,11 @@ plugin_init(Plugin *plugin)
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 @@ plugin_unload(Plugin *plugin)
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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment