Remove GeanyKeyGroup struct from the API - plugins should not set

these fields.
Make keybindings_set_item() duplicate the name and label fields
(needed by GeanyLua) and return a keybinding pointer.
Add keybindings_get_item() to the API (in case it's useful).
Move some keybinding code out of plugin source files.



git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@4123 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Nick Treleaven 2009-08-25 16:55:56 +00:00
parent 6eaeaec2c0
commit 43620e7ce4
9 changed files with 132 additions and 75 deletions

View File

@ -2,6 +2,15 @@
* data/filetypes.markdown: * data/filetypes.markdown:
Add filetypes.markdown for configuration (thanks to Jon Strait). Add filetypes.markdown for configuration (thanks to Jon Strait).
* src/build.c, src/keybindings.c, src/keybindings.h, src/plugindata.h,
src/pluginutils.c, src/plugins.c, src/pluginutils.h,
plugins/geanyfunctions.h:
Remove GeanyKeyGroup struct from the API - plugins should not set
these fields.
Make keybindings_set_item() duplicate the name and label fields
(needed by GeanyLua) and return a keybinding pointer.
Add keybindings_get_item() to the API (in case it's useful).
Move some keybinding code out of plugin source files.
2009-08-24 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com> 2009-08-24 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>

View File

@ -254,6 +254,8 @@
geany_functions->p_keybindings->send_command geany_functions->p_keybindings->send_command
#define keybindings_set_item \ #define keybindings_set_item \
geany_functions->p_keybindings->set_item geany_functions->p_keybindings->set_item
#define keybindings_get_item \
geany_functions->p_keybindings->get_item
#define tm_get_real_path \ #define tm_get_real_path \
geany_functions->p_tm->get_real_path geany_functions->p_tm->get_real_path
#define tm_source_file_new \ #define tm_source_file_new \

View File

@ -139,7 +139,7 @@ void build_finalize(void)
static void add_menu_accel(GeanyKeyGroup *group, guint kb_id, static void add_menu_accel(GeanyKeyGroup *group, guint kb_id,
GtkAccelGroup *accel_group, GtkWidget *menuitem) GtkAccelGroup *accel_group, GtkWidget *menuitem)
{ {
GeanyKeyBinding *kb = &group->keys[kb_id]; GeanyKeyBinding *kb = keybindings_get_item(group, kb_id);
if (kb->key != 0) if (kb->key != 0)
gtk_widget_add_accelerator(menuitem, "activate", accel_group, gtk_widget_add_accelerator(menuitem, "activate", accel_group,

View File

@ -25,9 +25,12 @@
* Configurable keyboard shortcuts. * Configurable keyboard shortcuts.
*/ */
#include <gdk/gdkkeysyms.h>
#include "geany.h" #include "geany.h"
#include <gdk/gdkkeysyms.h>
#include <string.h>
#include "keybindings.h" #include "keybindings.h"
#include "support.h" #include "support.h"
#include "utils.h" #include "utils.h"
@ -109,6 +112,19 @@ static void cb_func_move_tab(guint key_id);
static void add_popup_menu_accels(void); static void add_popup_menu_accels(void);
/** Lookup a keybinding item.
* @param group Group.
* @param key_id Keybinding index for the group.
* @return The keybinding.
* @since 0.19. */
GeanyKeyBinding *keybindings_get_item(GeanyKeyGroup *group, gsize key_id)
{
g_assert(key_id < group->count);
return &group->keys[key_id];
}
/* This is used to set default keybindings on startup. /* This is used to set default keybindings on startup.
* Menu accels are set in apply_kb_accel(). */ * Menu accels are set in apply_kb_accel(). */
/** Simple convenience function to fill a GeanyKeyBinding struct item. /** Simple convenience function to fill a GeanyKeyBinding struct item.
@ -117,25 +133,32 @@ static void add_popup_menu_accels(void);
* @param callback Function to call when activated, or @c NULL. * @param callback Function to call when activated, or @c NULL.
* @param key (Lower case) default key, e.g. @c GDK_j, but usually 0 for unset. * @param key (Lower case) default key, e.g. @c GDK_j, but usually 0 for unset.
* @param mod Default modifier, e.g. @c GDK_CONTROL_MASK, but usually 0 for unset. * @param mod Default modifier, e.g. @c GDK_CONTROL_MASK, but usually 0 for unset.
* @param name Key name for the configuration file, such as @c "menu_new". * @param kf_name Key name for the configuration file, such as @c "menu_new".
* @param label Label used in the preferences dialog keybindings tab. * @param label Label used in the preferences dialog keybindings tab.
* @param menu_item Optional widget to set an accelerator for, or @c NULL. */ * @param menu_item Optional widget to set an accelerator for, or @c NULL.
void keybindings_set_item(GeanyKeyGroup *group, gsize key_id, * @return The keybinding - normally this is ignored. */
GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
GeanyKeyCallback callback, guint key, GdkModifierType mod, GeanyKeyCallback callback, guint key, GdkModifierType mod,
gchar *name, gchar *label, GtkWidget *menu_item) gchar *kf_name, gchar *label, GtkWidget *menu_item)
{ {
GeanyKeyBinding *kb; GeanyKeyBinding *kb = keybindings_get_item(group, key_id);
g_assert(key_id < group->count); if (group->plugin)
{
kb = &group->keys[key_id]; /* some plugins e.g. GeanyLua need these fields duplicated */
setptr(kb->name, g_strdup(kf_name));
kb->name = name; setptr(kb->label, g_strdup(label));
kb->label = label; }
else
{
kb->name = kf_name;
kb->label = label;
}
kb->key = key; kb->key = key;
kb->mods = mod; kb->mods = mod;
kb->callback = callback; kb->callback = callback;
kb->menu_item = menu_item; kb->menu_item = menu_item;
return kb;
} }
@ -2271,3 +2294,46 @@ void keybindings_update_combo(GeanyKeyBinding *kb, guint key, GdkModifierType mo
kb->key, kb->mods, GTK_ACCEL_VISIBLE); kb->key, kb->mods, GTK_ACCEL_VISIBLE);
} }
/* used for plugins */
GeanyKeyGroup *keybindings_set_group(GeanyKeyGroup *group, const gchar *section_name,
const gchar *label, gsize count, GeanyKeyGroupCallback callback)
{
g_return_val_if_fail(section_name, NULL);
g_return_val_if_fail(count, NULL);
g_return_val_if_fail(!callback, NULL);
/* prevent conflict with core bindings */
g_return_val_if_fail(!g_str_equal(section_name, keybindings_keyfile_group_name), NULL);
if (!group)
group = g_new0(GeanyKeyGroup, 1);
if (!group->keys || count > group->count)
{
/* allow resizing existing array of keys */
group->keys = g_renew(GeanyKeyBinding, group->keys, count);
memset(group->keys + group->count, 0, (count - group->count) * sizeof(GeanyKeyBinding));
}
group->plugin = TRUE;
add_kb_group(group, section_name, label, count, group->keys);
return group;
}
/* used for plugins */
void keybindings_free_group(GeanyKeyGroup *group)
{
GeanyKeyBinding *kb;
g_assert(group->plugin);
foreach_c_array(kb, group->keys, group->count)
{
g_free(kb->name);
g_free(kb->label);
}
g_free(group->keys);
g_ptr_array_remove_fast(keybinding_groups, group);
g_free(group);
}

View File

@ -34,9 +34,8 @@
/** Function pointer type used for keybinding callbacks. */ /** Function pointer type used for keybinding callbacks. */
typedef void (*GeanyKeyCallback) (guint key_id); typedef void (*GeanyKeyCallback) (guint key_id);
/** Represents a single keybinding action. */ /** Represents a single keybinding action.
/* Note: name and label are not const strings so plugins can set them to malloc'd strings * Use keybindings_set_item() to set. */
* and free them in cleanup(). */
typedef struct GeanyKeyBinding typedef struct GeanyKeyBinding
{ {
guint key; /**< Key value in lower-case, such as @c GDK_a or 0 */ guint key; /**< Key value in lower-case, such as @c GDK_a or 0 */
@ -45,18 +44,22 @@ typedef struct GeanyKeyBinding
gchar *label; /**< Label used in the preferences dialog keybindings tab */ gchar *label; /**< Label used in the preferences dialog keybindings tab */
GeanyKeyCallback callback; /**< Function called when the key combination is pressed, or @c NULL */ GeanyKeyCallback callback; /**< Function called when the key combination is pressed, or @c NULL */
GtkWidget *menu_item; /**< Optional widget to set an accelerator for, or @c NULL */ GtkWidget *menu_item; /**< Optional widget to set an accelerator for, or @c NULL */
} GeanyKeyBinding;
/** A collection of keybindings grouped together. Plugins should not set these fields. */
typedef struct GeanyKeyGroup
{
const gchar *name; /**< Group name used in the configuration file, such as @c "html_chars" */
const gchar *label; /* Group label used in the preferences dialog keybindings tab */
gsize count; /**< The number of keybindings the group holds */
GeanyKeyBinding *keys; /* array of GeanyKeyBinding structs */
} }
GeanyKeyGroup; GeanyKeyBinding;
/** A collection of keybindings grouped together. */
typedef struct GeanyKeyGroup GeanyKeyGroup;
/* Plugins should not set these fields. */
struct GeanyKeyGroup
{
const gchar *name; /* Group name used in the configuration file, such as @c "html_chars" */
const gchar *label; /* Group label used in the preferences dialog keybindings tab */
gsize count; /* number of keybindings the group holds */
GeanyKeyBinding *keys; /* array of GeanyKeyBinding structs */
gboolean plugin; /* used by plugin */
};
extern GPtrArray *keybinding_groups; /* array of GeanyKeyGroup pointers */ extern GPtrArray *keybinding_groups; /* array of GeanyKeyGroup pointers */
@ -318,10 +321,20 @@ void keybindings_load_keyfile(void);
void keybindings_free(void); void keybindings_free(void);
void keybindings_set_item(GeanyKeyGroup *group, gsize key_id, /** Function pointer type used for keybinding group callbacks. */
typedef gboolean (*GeanyKeyGroupCallback) (guint key_id);
GeanyKeyGroup *keybindings_set_group(GeanyKeyGroup *group, const gchar *section_name,
const gchar *label, gsize count, GeanyKeyGroupCallback callback) G_GNUC_WARN_UNUSED_RESULT;
void keybindings_free_group(GeanyKeyGroup *group);
GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
GeanyKeyCallback callback, guint key, GdkModifierType mod, GeanyKeyCallback callback, guint key, GdkModifierType mod,
gchar *name, gchar *label, GtkWidget *menu_item); gchar *name, gchar *label, GtkWidget *menu_item);
GeanyKeyBinding *keybindings_get_item(GeanyKeyGroup *group, gsize key_id);
void keybindings_update_combo(GeanyKeyBinding *kb, guint key, GdkModifierType mods); void keybindings_update_combo(GeanyKeyBinding *kb, guint key, GdkModifierType mods);
void keybindings_send_command(guint group_id, guint key_id); void keybindings_send_command(guint group_id, guint key_id);

View File

@ -50,7 +50,7 @@
enum { enum {
/** The Application Programming Interface (API) version, incremented /** The Application Programming Interface (API) version, incremented
* whenever any plugin data types are modified or appended to. */ * whenever any plugin data types are modified or appended to. */
GEANY_API_VERSION = 152, GEANY_API_VERSION = 153,
/** The Application Binary Interface (ABI) version, incremented whenever /** The Application Binary Interface (ABI) version, incremented whenever
* existing fields in the plugin data types have to be changed or reordered. */ * existing fields in the plugin data types have to be changed or reordered. */
@ -471,9 +471,11 @@ typedef void (*_GeanyKeyCallback) (guint key_id);
typedef struct KeybindingFuncs typedef struct KeybindingFuncs
{ {
void (*send_command) (guint group_id, guint key_id); void (*send_command) (guint group_id, guint key_id);
void (*set_item) (struct GeanyKeyGroup *group, gsize key_id, struct GeanyKeyBinding* (*set_item) (struct GeanyKeyGroup *group, gsize key_id,
_GeanyKeyCallback callback, guint key, GdkModifierType mod, _GeanyKeyCallback callback, guint key, GdkModifierType mod,
gchar *name, gchar *label, GtkWidget *menu_item); gchar *name, gchar *label, GtkWidget *menu_item);
struct GeanyKeyBinding* (*get_item)(struct GeanyKeyGroup *group, gsize key_id);
} }
KeybindingFuncs; KeybindingFuncs;

View File

@ -243,7 +243,8 @@ static EncodingFuncs encoding_funcs = {
static KeybindingFuncs keybindings_funcs = { static KeybindingFuncs keybindings_funcs = {
&keybindings_send_command, &keybindings_send_command,
&keybindings_set_item &keybindings_set_item,
&keybindings_get_item
}; };
static TagManagerFuncs tagmanager_funcs = { static TagManagerFuncs tagmanager_funcs = {
@ -684,11 +685,8 @@ plugin_cleanup(Plugin *plugin)
remove_callbacks(plugin); remove_callbacks(plugin);
if (plugin->key_group) if (plugin->key_group)
{ keybindings_free_group(plugin->key_group);
g_free(plugin->key_group->keys);
g_ptr_array_remove_fast(keybinding_groups, plugin->key_group);
setptr(plugin->key_group, NULL);
}
widget = plugin->toolbar_separator.widget; widget = plugin->toolbar_separator.widget;
if (widget) if (widget)
gtk_widget_destroy(widget); gtk_widget_destroy(widget);

View File

@ -28,8 +28,6 @@
#include "geany.h" #include "geany.h"
#include <string.h>
#include "pluginutils.h" #include "pluginutils.h"
#include "pluginprivate.h" #include "pluginprivate.h"
@ -140,40 +138,11 @@ void plugin_signal_connect(GeanyPlugin *plugin,
GeanyKeyGroup *plugin_set_key_group(GeanyPlugin *plugin, GeanyKeyGroup *plugin_set_key_group(GeanyPlugin *plugin,
const gchar *section_name, gsize count, GeanyKeyGroupCallback callback) const gchar *section_name, gsize count, GeanyKeyGroupCallback callback)
{ {
GeanyKeyGroup *group;
GeanyPluginPrivate *priv = plugin->priv; GeanyPluginPrivate *priv = plugin->priv;
g_return_val_if_fail(section_name, NULL); priv->key_group = keybindings_set_group(priv->key_group, section_name,
g_return_val_if_fail(count, NULL); priv->info.name, count, callback);
g_return_val_if_fail(!callback, NULL); return priv->key_group;
if (!priv->key_group)
priv->key_group = g_new0(GeanyKeyGroup, 1);
group = priv->key_group;
group->name = section_name;
if (!group->keys || count > group->count)
{
group->keys = g_renew(GeanyKeyBinding, group->keys, count);
memset(group->keys + group->count, 0, (count - group->count) * sizeof(GeanyKeyBinding));
}
group->count = count;
if (!NZV(group->name))
{
geany_debug("Plugin \"%s\" has not set the name field for its keybinding group"
" - ignoring all keybindings!",
priv->info.name);
return NULL;
}
/* prevent conflict with core bindings */
g_return_val_if_fail(! g_str_equal(group->name, keybindings_keyfile_group_name), NULL);
group->label = priv->info.name;
g_ptr_array_add(keybinding_groups, group);
return group;
} }

View File

@ -26,7 +26,9 @@
#ifndef PLUGINUTILS_H #ifndef PLUGINUTILS_H
#define PLUGINUTILS_H #define PLUGINUTILS_H
#include "plugindata.h" /* GeanyPlugin */ #include "plugindata.h" /* GeanyPlugin */
#include "keybindings.h" /* GeanyKeyGroupCallback */
void plugin_add_toolbar_item(GeanyPlugin *plugin, GtkToolItem *item); void plugin_add_toolbar_item(GeanyPlugin *plugin, GtkToolItem *item);
@ -36,10 +38,6 @@ void plugin_signal_connect(GeanyPlugin *plugin,
GObject *object, gchar *signal_name, gboolean after, GObject *object, gchar *signal_name, gboolean after,
GCallback callback, gpointer user_data); GCallback callback, gpointer user_data);
/** Function pointer type used for keybinding group callbacks. */
typedef gboolean (*GeanyKeyGroupCallback) (guint key_id);
struct GeanyKeyGroup *plugin_set_key_group(GeanyPlugin *plugin, struct GeanyKeyGroup *plugin_set_key_group(GeanyPlugin *plugin,
const gchar *section_name, gsize count, GeanyKeyGroupCallback callback); const gchar *section_name, gsize count, GeanyKeyGroupCallback callback);