Use single binding_ids keybinding array instead of individual

arrays for core keybindings. This allows the keybinding IDs to be
merged into one enum; the order of keybindings is now just the
order they are added to each group. Keybindings can be reordered
without breaking the plugin ABI but groups must stay the same.



git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@5120 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Nick Treleaven 2010-08-10 12:43:30 +00:00
parent 608c484655
commit 0c4b7a2ab0
5 changed files with 216 additions and 332 deletions

View File

@ -1,3 +1,13 @@
2010-08-10 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
* src/keybindings.c, src/keybindings.h, src/prefs.c, src/plugindata.h:
Use single binding_ids keybinding array instead of individual
arrays for core keybindings. This allows the keybinding IDs to be
merged into one enum; the order of keybindings is now just the
order they are added to each group. Keybindings can be reordered
without breaking the plugin ABI but groups must stay the same.
2010-08-05 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* src/ui_utils.c, src/ui_utils.h:

View File

@ -24,7 +24,7 @@
/**
* @file keybindings.h
* Configurable keyboard shortcuts.
* - keybindings_send_command() mimics a built-in keybinding.
* - keybindings_send_command() mimics a built-in keybinding action.
* - @ref GeanyKeyGroupID lists groups of built-in keybindings.
* @see plugin_set_key_group().
**/
@ -65,12 +65,15 @@
GPtrArray *keybinding_groups; /* array of GeanyKeyGroup pointers */
/* keyfile group name for non-plugin KB groups */
const gchar keybindings_keyfile_group_name[] = "Bindings";
static const gchar keybindings_keyfile_group_name[] = "Bindings";
/* core keybindings */
static GeanyKeyBinding binding_ids[GEANY_KEYS_COUNT];
static GtkAccelGroup *kb_accel_group = NULL;
static const gboolean swap_alt_tab_order = FALSE;
const gsize MAX_MRU_DOCS = 20;
static const gsize MAX_MRU_DOCS = 20;
static GQueue *mru_docs = NULL;
static guint mru_pos = 0;
@ -125,9 +128,13 @@ static void add_popup_menu_accels(void);
* @since 0.19. */
GeanyKeyBinding *keybindings_get_item(GeanyKeyGroup *group, gsize key_id)
{
g_assert(key_id < group->count);
return &group->keys[key_id];
if (group->plugin)
{
g_assert(key_id < group->plugin_key_count);
return &group->plugin_keys[key_id];
}
g_assert(key_id < GEANY_KEYS_COUNT);
return &binding_ids[key_id];
}
@ -149,7 +156,12 @@ GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
GeanyKeyCallback callback, guint key, GdkModifierType mod,
const gchar *kf_name, const gchar *label, GtkWidget *menu_item)
{
GeanyKeyBinding *kb = keybindings_get_item(group, key_id);
GeanyKeyBinding *kb;
g_assert(group->name);
kb = keybindings_get_item(group, key_id);
g_assert(!kb->name);
g_ptr_array_add(group->key_items, kb);
if (group->plugin)
{
@ -159,7 +171,7 @@ GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
}
else
{
/* we don't touch them unless group->plugin is set, cast is safe */
/* we don't touch these strings unless group->plugin is set, const cast is safe */
kb->name = (gchar *)kf_name;
kb->label = (gchar *)label;
}
@ -167,21 +179,21 @@ GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
kb->mods = mod;
kb->callback = callback;
kb->menu_item = menu_item;
kb->id = key_id;
return kb;
}
static GeanyKeyGroup *add_kb_group(GeanyKeyGroup *group,
const gchar *name, const gchar *label, gsize count, GeanyKeyBinding *keys,
GeanyKeyGroupCallback callback)
const gchar *name, const gchar *label, GeanyKeyGroupCallback callback, gboolean plugin)
{
g_ptr_array_add(keybinding_groups, group);
group->name = name;
group->label = label;
group->count = count;
group->keys = keys;
group->callback = callback;
group->plugin = plugin;
group->key_items = g_ptr_array_new();
return group;
}
@ -191,16 +203,11 @@ static GeanyKeyGroup *add_kb_group(GeanyKeyGroup *group,
ui_lookup_widget(main_widgets.window, G_STRINGIFY(widget_name))
/* Expansion for group_id = FILE:
* static GeanyKeyBinding FILE_keys[GEANY_KEYS_FILE_COUNT]; */
#define DECLARE_KEYS(group_id) \
static GeanyKeyBinding group_id ## _keys[GEANY_KEYS_ ## group_id ## _COUNT]
/* Expansion for group_id = FILE:
* add_kb_group(&groups[GEANY_KEY_GROUP_FILE], NULL, _("File menu"),
* GEANY_KEYS_FILE_COUNT, FILE_keys, callback); */
* add_kb_group(&groups[GEANY_KEY_GROUP_FILE],
* keybindings_keyfile_group_name, _("File menu"), callback); */
#define ADD_KB_GROUP(group_id, label, callback) \
add_kb_group(&groups[GEANY_KEY_GROUP_ ## group_id], keybindings_keyfile_group_name, label, \
GEANY_KEYS_ ## group_id ## _COUNT, group_id ## _keys, callback)
add_kb_group(&groups[GEANY_KEY_GROUP_ ## group_id],\
keybindings_keyfile_group_name, label, callback, FALSE)
/* Init all fields of keys with default values.
* The menu_item field is always the main menu item, popup menu accelerators are
@ -209,23 +216,6 @@ static void init_default_kb(void)
{
static GeanyKeyGroup groups[GEANY_KEY_GROUP_COUNT];
GeanyKeyGroup *group;
DECLARE_KEYS(FILE);
DECLARE_KEYS(PROJECT);
DECLARE_KEYS(EDITOR);
DECLARE_KEYS(CLIPBOARD);
DECLARE_KEYS(SELECT);
DECLARE_KEYS(FORMAT);
DECLARE_KEYS(INSERT);
DECLARE_KEYS(SETTINGS);
DECLARE_KEYS(SEARCH);
DECLARE_KEYS(GOTO);
DECLARE_KEYS(VIEW);
DECLARE_KEYS(FOCUS);
DECLARE_KEYS(NOTEBOOK);
DECLARE_KEYS(DOCUMENT);
DECLARE_KEYS(BUILD);
DECLARE_KEYS(TOOLS);
DECLARE_KEYS(HELP);
group = ADD_KB_GROUP(FILE, _("File"), cb_func_file_action);
@ -477,6 +467,7 @@ static void init_default_kb(void)
group = ADD_KB_GROUP(FOCUS, _("Focus"), cb_func_switch_action);
/* TODO rearrange these keybindings */
keybindings_set_item(group, GEANY_KEYS_FOCUS_EDITOR, NULL,
GDK_F2, 0, "switch_editor", _("Switch to Editor"), NULL);
keybindings_set_item(group, GEANY_KEYS_FOCUS_SCRIBBLE, NULL,
@ -621,12 +612,11 @@ void keybindings_init(void)
g_signal_connect(geany_object, "document-close",
G_CALLBACK(on_document_close), NULL);
memset(binding_ids, 0, sizeof binding_ids);
keybinding_groups = g_ptr_array_sized_new(GEANY_KEY_GROUP_COUNT);
kb_accel_group = gtk_accel_group_new();
init_default_kb();
gtk_window_add_accel_group(GTK_WINDOW(main_widgets.window), kb_accel_group);
g_signal_connect(main_widgets.window, "key-press-event", G_CALLBACK(on_key_press_event), NULL);
@ -643,15 +633,10 @@ static void keybindings_foreach(KBItemCallback cb, gpointer user_data)
GeanyKeyGroup *group;
GeanyKeyBinding *kb;
for (g = 0; g < keybinding_groups->len; g++)
foreach_ptr_array(group, g, keybinding_groups)
{
group = g_ptr_array_index(keybinding_groups, g);
for (i = 0; i < group->count; i++)
{
kb = &group->keys[i];
foreach_ptr_array(kb, i, group->key_items)
cb(group, kb, user_data);
}
}
}
@ -711,7 +696,7 @@ void keybindings_load_keyfile(void)
static void add_menu_accel(GeanyKeyGroup *group, guint kb_id, GtkWidget *menuitem)
{
GeanyKeyBinding *kb = &group->keys[kb_id];
GeanyKeyBinding *kb = keybindings_get_item(group, kb_id);
if (kb->key != 0)
gtk_widget_add_accelerator(menuitem, "activate", kb_accel_group,
@ -795,6 +780,12 @@ void keybindings_write_to_file(void)
void keybindings_free(void)
{
GeanyKeyGroup *group;
gsize g;
foreach_ptr_array(group, g, keybinding_groups)
keybindings_free_group(group);
g_ptr_array_free(keybinding_groups, TRUE);
g_queue_free(mru_docs);
}
@ -816,24 +807,20 @@ static void fill_shortcut_labels_treeview(GtkWidget *tree)
store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, PANGO_TYPE_WEIGHT);
for (g = 0; g < keybinding_groups->len; g++)
foreach_ptr_array(group, g, keybinding_groups)
{
group = g_ptr_array_index(keybinding_groups, g);
if (g > 0)
{
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, -1);
}
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, 0, group->label, 2, PANGO_WEIGHT_BOLD, -1);
for (i = 0; i < group->count; i++)
foreach_ptr_array(kb, i, group->key_items)
{
gchar *shortcut, *label;
kb = &group->keys[i];
label = keybindings_get_label(kb);
shortcut = gtk_accelerator_get_label(kb->key, kb->mods);
@ -844,7 +831,6 @@ static void fill_shortcut_labels_treeview(GtkWidget *tree)
g_free(label);
}
}
gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
g_object_unref(store);
}
@ -1082,6 +1068,8 @@ static gboolean set_sensitive(gpointer widget)
static gboolean check_vte(GdkModifierType state, guint keyval)
{
guint i;
GeanyKeyBinding *kb;
GeanyKeyGroup *group;
GtkWidget *widget;
if (! vc->enable_bash_keys)
@ -1095,10 +1083,9 @@ static gboolean check_vte(GdkModifierType state, guint keyval)
return FALSE;
/* make focus commands override any bash commands */
for (i = 0; i < GEANY_KEYS_FOCUS_COUNT; i++)
group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_FOCUS);
foreach_ptr_array(kb, i, group->key_items)
{
GeanyKeyBinding *kb = keybindings_lookup_item(GEANY_KEY_GROUP_FOCUS, i);
if (state == kb->mods && keyval == kb->key)
return FALSE;
}
@ -1179,19 +1166,16 @@ const GeanyKeyBinding *keybindings_check_event(GdkEventKey *ev, gint *group_id,
if (keyval >= GDK_KP_Space && keyval < GDK_KP_Equal)
keyval = key_kp_translate(keyval);
for (g = 0; g < keybinding_groups->len; g++)
foreach_ptr_array(group, g, keybinding_groups)
{
group = g_ptr_array_index(keybinding_groups, g);
for (i = 0; i < group->count; i++)
foreach_ptr_array(kb, i, group->key_items)
{
kb = &group->keys[i];
if (keyval == kb->key && state == kb->mods)
{
if (group_id != NULL)
*group_id = g;
if (binding_id != NULL)
*binding_id = i;
*binding_id = kb->id;
return kb;
}
}
@ -1236,24 +1220,21 @@ static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *ev, gpointer
if (check_menu_key(doc, keyval, state, ev->time))
return TRUE;
for (g = 0; g < keybinding_groups->len; g++)
foreach_ptr_array(group, g, keybinding_groups)
{
group = g_ptr_array_index(keybinding_groups, g);
for (i = 0; i < group->count; i++)
foreach_ptr_array(kb, i, group->key_items)
{
kb = &group->keys[i];
if (keyval == kb->key && state == kb->mods)
{
/* call the corresponding callback function for this shortcut */
if (kb->callback)
{
kb->callback(i);
kb->callback(kb->id);
return TRUE;
}
else if (group->callback)
{
if (group->callback(i))
if (group->callback(kb->id))
return TRUE;
else
continue; /* not handled */
@ -1301,16 +1282,14 @@ GeanyKeyBinding *keybindings_lookup_item(guint group_id, guint key_id)
group = g_ptr_array_index(keybinding_groups, group_id);
g_return_val_if_fail(group, NULL);
g_return_val_if_fail(key_id < group->count, NULL);
return &group->keys[key_id];
return keybindings_get_item(group, key_id);
}
/** Mimics a (built-in only) keybinding action.
* Example: @code keybindings_send_command(GEANY_KEY_GROUP_FILE, GEANY_KEYS_FILE_OPEN); @endcode
* @param group_id The index for the key group that contains the @a key_id keybinding.
* @param key_id The keybinding command index. */
* @param group_id @ref GeanyKeyGroupID keybinding group index that contains the @a key_id keybinding.
* @param key_id @ref GeanyKeyBindingID keybinding index. */
void keybindings_send_command(guint group_id, guint key_id)
{
GeanyKeyBinding *kb;
@ -2624,7 +2603,7 @@ void keybindings_update_combo(GeanyKeyBinding *kb, guint key, GdkModifierType mo
}
/* used for plugins */
/* used for plugins, can be called repeatedly. */
GeanyKeyGroup *keybindings_set_group(GeanyKeyGroup *group, const gchar *section_name,
const gchar *label, gsize count, GeanyKeyGroupCallback callback)
{
@ -2635,33 +2614,33 @@ GeanyKeyGroup *keybindings_set_group(GeanyKeyGroup *group, const gchar *section_
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 = g_new0(GeanyKeyGroup, 1);
add_kb_group(group, section_name, label, callback, TRUE);
}
group->plugin = TRUE;
add_kb_group(group, section_name, label, count, group->keys, callback);
g_free(group->plugin_keys);
group->plugin_keys = g_new0(GeanyKeyBinding, count);
group->plugin_key_count = count;
g_ptr_array_set_size(group->key_items, 0);
return group;
}
/* used for plugins */
void keybindings_free_group(GeanyKeyGroup *group)
{
GeanyKeyBinding *kb;
g_assert(group->plugin);
g_ptr_array_free(group->key_items, TRUE);
foreach_c_array(kb, group->keys, group->count)
if (group->plugin)
{
g_free(kb->name);
g_free(kb->label);
foreach_c_array(kb, group->plugin_keys, group->plugin_key_count)
{
g_free(kb->name);
g_free(kb->label);
}
g_free(group->plugin_keys);
g_ptr_array_remove_fast(keybinding_groups, group);
g_free(group);
}
g_free(group->keys);
g_ptr_array_remove_fast(keybinding_groups, group);
g_free(group);
}

View File

@ -41,6 +41,7 @@ typedef struct GeanyKeyBinding
* (preferred). @see plugin_set_key_group(). */
GeanyKeyCallback callback;
GtkWidget *menu_item; /**< Optional widget to set an accelerator for, or @c NULL */
guint id;
}
GeanyKeyBinding;
@ -60,74 +61,62 @@ 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 */
GeanyKeyGroupCallback callback; /* use this or individual keybinding callbacks */
gboolean plugin; /* used by plugin */
GPtrArray *key_items; /* pointers to GeanyKeyBinding structs */
gsize plugin_key_count; /* number of keybindings the group holds */
GeanyKeyBinding *plugin_keys; /* array of GeanyKeyBinding structs */
};
#endif
extern GPtrArray *keybinding_groups; /* array of GeanyKeyGroup pointers */
extern const gchar keybindings_keyfile_group_name[];
/* Note: we don't need to break the plugin ABI when appending keybinding or keygroup IDs,
* just make sure to insert immediately before the _COUNT item, so
* the existing enum values stay the same. */
/* Note: we don't need to increment the plugin ABI when appending keybindings or keygroups,
* just make sure to only insert keybindings/groups immediately before the _COUNT item, so
* the existing enum values stay the same.
* The _COUNT item should not be used by plugins, as it may well change. */
/** Keybinding group IDs */
/** Keybinding group IDs for use with keybindings_send_command(). */
/* Groups must be added in this order. */
enum GeanyKeyGroupID
{
GEANY_KEY_GROUP_FILE, /**< Group for @ref GeanyKeysFileID. */
GEANY_KEY_GROUP_PROJECT, /**< Group for @ref GeanyKeysProjectID. */
GEANY_KEY_GROUP_EDITOR, /**< Group for @ref GeanyKeysEditorID. */
GEANY_KEY_GROUP_CLIPBOARD, /**< Group for @ref GeanyKeysClipboardID. */
GEANY_KEY_GROUP_SELECT, /**< Group for @ref GeanyKeysSelectID. */
GEANY_KEY_GROUP_FORMAT, /**< Group for @ref GeanyKeysFormatID. */
GEANY_KEY_GROUP_INSERT, /**< Group for @ref GeanyKeysInsertID. */
GEANY_KEY_GROUP_SETTINGS, /**< Group for @ref GeanyKeysSettingsID. */
GEANY_KEY_GROUP_SEARCH, /**< Group for @ref GeanyKeysSearchID. */
GEANY_KEY_GROUP_GOTO, /**< Group for @ref GeanyKeysGoToID. */
GEANY_KEY_GROUP_VIEW, /**< Group for @ref GeanyKeysViewID. */
GEANY_KEY_GROUP_FOCUS, /**< Group for @ref GeanyKeysFocusID. */
GEANY_KEY_GROUP_NOTEBOOK, /**< Group for @ref GeanyKeysNotebookTabID. */
GEANY_KEY_GROUP_DOCUMENT, /**< Group for @ref GeanyKeysDocumentID. */
GEANY_KEY_GROUP_BUILD, /**< Group for @ref GeanyKeysBuildID. */
GEANY_KEY_GROUP_TOOLS, /**< Group for @ref GeanyKeysToolsID. */
GEANY_KEY_GROUP_HELP, /**< Group for @ref GeanyKeysHelpID. */
GEANY_KEY_GROUP_COUNT
GEANY_KEY_GROUP_FILE, /**< Group. */
GEANY_KEY_GROUP_PROJECT, /**< Group. */
GEANY_KEY_GROUP_EDITOR, /**< Group. */
GEANY_KEY_GROUP_CLIPBOARD, /**< Group. */
GEANY_KEY_GROUP_SELECT, /**< Group. */
GEANY_KEY_GROUP_FORMAT, /**< Group. */
GEANY_KEY_GROUP_INSERT, /**< Group. */
GEANY_KEY_GROUP_SETTINGS, /**< Group. */
GEANY_KEY_GROUP_SEARCH, /**< Group. */
GEANY_KEY_GROUP_GOTO, /**< Group. */
GEANY_KEY_GROUP_VIEW, /**< Group. */
GEANY_KEY_GROUP_FOCUS, /**< Group. */
GEANY_KEY_GROUP_NOTEBOOK, /**< Group. */
GEANY_KEY_GROUP_DOCUMENT, /**< Group. */
GEANY_KEY_GROUP_BUILD, /**< Group. */
GEANY_KEY_GROUP_TOOLS, /**< Group. */
GEANY_KEY_GROUP_HELP, /**< Group. */
GEANY_KEY_GROUP_COUNT /* must not be used by plugins */
};
/** File group keybinding command IDs */
enum GeanyKeysFileID
{
GEANY_KEYS_FILE_NEW, /**< Keybinding. */
GEANY_KEYS_FILE_OPEN, /**< Keybinding. */
GEANY_KEYS_FILE_OPENSELECTED, /**< Keybinding. */
GEANY_KEYS_FILE_SAVE, /**< Keybinding. */
GEANY_KEYS_FILE_SAVEAS, /**< Keybinding. */
GEANY_KEYS_FILE_SAVEALL, /**< Keybinding. */
GEANY_KEYS_FILE_PRINT, /**< Keybinding. */
GEANY_KEYS_FILE_CLOSE, /**< Keybinding. */
GEANY_KEYS_FILE_CLOSEALL, /**< Keybinding. */
GEANY_KEYS_FILE_RELOAD, /**< Keybinding. */
GEANY_KEYS_FILE_OPENLASTTAB, /**< Keybinding. */
GEANY_KEYS_FILE_COUNT
};
/** Project group keybinding command IDs */
enum GeanyKeysProjectID
{
GEANY_KEYS_PROJECT_PROPERTIES, /**< Keybinding. */
GEANY_KEYS_PROJECT_COUNT
};
/** Editor group keybinding command IDs */
enum GeanyKeysEditorID
/** Keybinding command IDs for use with keybindings_send_command(). */
/* These IDs are used to lookup a keybinding; keybindings can be added in any order. */
enum GeanyKeyBindingID
{
GEANY_KEYS_FILE_NEW, /**< Keybinding. */
GEANY_KEYS_FILE_OPEN, /**< Keybinding. */
GEANY_KEYS_FILE_OPENSELECTED, /**< Keybinding. */
GEANY_KEYS_FILE_SAVE, /**< Keybinding. */
GEANY_KEYS_FILE_SAVEAS, /**< Keybinding. */
GEANY_KEYS_FILE_SAVEALL, /**< Keybinding. */
GEANY_KEYS_FILE_PRINT, /**< Keybinding. */
GEANY_KEYS_FILE_CLOSE, /**< Keybinding. */
GEANY_KEYS_FILE_CLOSEALL, /**< Keybinding. */
GEANY_KEYS_FILE_RELOAD, /**< Keybinding. */
GEANY_KEYS_FILE_OPENLASTTAB, /**< Keybinding. */
GEANY_KEYS_PROJECT_PROPERTIES, /**< Keybinding. */
GEANY_KEYS_EDITOR_UNDO, /**< Keybinding. */
GEANY_KEYS_EDITOR_REDO, /**< Keybinding. */
GEANY_KEYS_EDITOR_DELETELINE, /**< Keybinding. */
@ -147,36 +136,17 @@ enum GeanyKeysEditorID
GEANY_KEYS_EDITOR_WORDPARTCOMPLETION, /**< Keybinding. */
GEANY_KEYS_EDITOR_MOVELINEUP, /**< Keybinding. */
GEANY_KEYS_EDITOR_MOVELINEDOWN, /**< Keybinding. */
GEANY_KEYS_EDITOR_COUNT
};
/** Clipboard group keybinding command IDs */
enum GeanyKeysClipboardID
{
GEANY_KEYS_CLIPBOARD_CUT, /**< Keybinding. */
GEANY_KEYS_CLIPBOARD_COPY, /**< Keybinding. */
GEANY_KEYS_CLIPBOARD_PASTE, /**< Keybinding. */
GEANY_KEYS_CLIPBOARD_CUTLINE, /**< Keybinding. */
GEANY_KEYS_CLIPBOARD_COPYLINE, /**< Keybinding. */
GEANY_KEYS_CLIPBOARD_COUNT
};
/** Select group keybinding command IDs */
enum GeanyKeysSelectID
{
GEANY_KEYS_SELECT_ALL, /**< Keybinding. */
GEANY_KEYS_SELECT_WORD, /**< Keybinding. */
GEANY_KEYS_SELECT_LINE, /**< Keybinding. */
GEANY_KEYS_SELECT_PARAGRAPH, /**< Keybinding. */
GEANY_KEYS_SELECT_WORDPARTLEFT, /**< Keybinding. */
GEANY_KEYS_SELECT_WORDPARTRIGHT, /**< Keybinding. */
GEANY_KEYS_SELECT_COUNT
};
/** Format group keybinding command IDs */
enum GeanyKeysFormatID
{
GEANY_KEYS_CLIPBOARD_CUT, /**< Keybinding. */
GEANY_KEYS_CLIPBOARD_COPY, /**< Keybinding. */
GEANY_KEYS_CLIPBOARD_PASTE, /**< Keybinding. */
GEANY_KEYS_CLIPBOARD_CUTLINE, /**< Keybinding. */
GEANY_KEYS_CLIPBOARD_COPYLINE, /**< Keybinding. */
GEANY_KEYS_SELECT_ALL, /**< Keybinding. */
GEANY_KEYS_SELECT_WORD, /**< Keybinding. */
GEANY_KEYS_SELECT_LINE, /**< Keybinding. */
GEANY_KEYS_SELECT_PARAGRAPH, /**< Keybinding. */
GEANY_KEYS_SELECT_WORDPARTLEFT, /**< Keybinding. */
GEANY_KEYS_SELECT_WORDPARTRIGHT, /**< Keybinding. */
GEANY_KEYS_FORMAT_TOGGLECASE, /**< Keybinding. */
GEANY_KEYS_FORMAT_COMMENTLINETOGGLE, /**< Keybinding. */
GEANY_KEYS_FORMAT_COMMENTLINE, /**< Keybinding. */
@ -191,96 +161,53 @@ enum GeanyKeysFormatID
GEANY_KEYS_FORMAT_SENDTOCMD3, /**< Keybinding. */
GEANY_KEYS_FORMAT_SENDTOVTE, /**< Keybinding. */
GEANY_KEYS_FORMAT_REFLOWPARAGRAPH, /**< Keybinding. */
GEANY_KEYS_FORMAT_COUNT
};
/** Insert group keybinding command IDs */
enum GeanyKeysInsertID
{
GEANY_KEYS_INSERT_DATE, /**< Keybinding. */
GEANY_KEYS_INSERT_ALTWHITESPACE, /**< Keybinding. */
GEANY_KEYS_INSERT_COUNT
};
/** Settings group keybinding command IDs */
enum GeanyKeysSettingsID
{
GEANY_KEYS_SETTINGS_PREFERENCES, /**< Keybinding. */
GEANY_KEYS_SETTINGS_PLUGINPREFERENCES, /**< Keybinding. */
GEANY_KEYS_SETTINGS_COUNT
};
/** Search group keybinding command IDs */
enum GeanyKeysSearchID
{
GEANY_KEYS_SEARCH_FIND, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDNEXT, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDPREVIOUS, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDINFILES, /**< Keybinding. */
GEANY_KEYS_SEARCH_REPLACE, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDNEXTSEL, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDPREVSEL, /**< Keybinding. */
GEANY_KEYS_SEARCH_NEXTMESSAGE, /**< Keybinding. */
GEANY_KEYS_SEARCH_PREVIOUSMESSAGE, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDUSAGE, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDDOCUMENTUSAGE, /**< Keybinding. */
GEANY_KEYS_SEARCH_MARKALL, /**< Keybinding. */
GEANY_KEYS_SEARCH_COUNT
};
/** Go To group keybinding command IDs */
enum GeanyKeysGoToID
{
GEANY_KEYS_GOTO_FORWARD, /**< Keybinding. */
GEANY_KEYS_GOTO_BACK, /**< Keybinding. */
GEANY_KEYS_GOTO_LINE, /**< Keybinding. */
GEANY_KEYS_GOTO_LINESTART, /**< Keybinding. */
GEANY_KEYS_GOTO_LINEEND, /**< Keybinding. */
GEANY_KEYS_GOTO_MATCHINGBRACE, /**< Keybinding. */
GEANY_KEYS_GOTO_TOGGLEMARKER, /**< Keybinding. */
GEANY_KEYS_GOTO_NEXTMARKER, /**< Keybinding. */
GEANY_KEYS_GOTO_PREVIOUSMARKER, /**< Keybinding. */
GEANY_KEYS_GOTO_PREVWORDPART, /**< Keybinding. */
GEANY_KEYS_GOTO_NEXTWORDPART, /**< Keybinding. */
GEANY_KEYS_GOTO_TAGDEFINITION, /**< Keybinding. */
GEANY_KEYS_GOTO_TAGDECLARATION, /**< Keybinding. */
GEANY_KEYS_GOTO_LINEENDVISUAL, /**< Keybinding. */
GEANY_KEYS_GOTO_COUNT
};
/** View group keybinding command IDs */
enum GeanyKeysViewID
{
GEANY_KEYS_VIEW_TOGGLEALL, /**< Keybinding. */
GEANY_KEYS_VIEW_FULLSCREEN, /**< Keybinding. */
GEANY_KEYS_VIEW_MESSAGEWINDOW, /**< Keybinding. */
GEANY_KEYS_VIEW_SIDEBAR, /**< Keybinding. */
GEANY_KEYS_VIEW_ZOOMIN, /**< Keybinding. */
GEANY_KEYS_VIEW_ZOOMOUT, /**< Keybinding. */
GEANY_KEYS_VIEW_ZOOMRESET, /**< Keybinding. */
GEANY_KEYS_VIEW_COUNT
};
/** Focus group keybinding command IDs */
/* TODO when the plugin ABI get increased the next time, rearrange these keybindings */
enum GeanyKeysFocusID
{
GEANY_KEYS_FOCUS_EDITOR, /**< Keybinding. */
GEANY_KEYS_FOCUS_SCRIBBLE, /**< Keybinding. */
GEANY_KEYS_FOCUS_VTE, /**< Keybinding. */
GEANY_KEYS_FOCUS_SEARCHBAR, /**< Keybinding. */
GEANY_KEYS_FOCUS_SIDEBAR, /**< Keybinding. */
GEANY_KEYS_FOCUS_COMPILER, /**< Keybinding. */
GEANY_KEYS_FOCUS_MESSAGES, /**< Keybinding. */
GEANY_KEYS_FOCUS_MESSAGE_WINDOW, /**< Keybinding. */
GEANY_KEYS_FOCUS_SIDEBAR_DOCUMENT_LIST, /**< Keybinding. */
GEANY_KEYS_FOCUS_SIDEBAR_SYMBOL_LIST, /**< Keybinding. */
GEANY_KEYS_FOCUS_COUNT
};
/** Notebook Tab group keybinding command IDs */
enum GeanyKeysNotebookTabID
{
GEANY_KEYS_INSERT_DATE, /**< Keybinding. */
GEANY_KEYS_INSERT_ALTWHITESPACE, /**< Keybinding. */
GEANY_KEYS_SETTINGS_PREFERENCES, /**< Keybinding. */
GEANY_KEYS_SETTINGS_PLUGINPREFERENCES, /**< Keybinding. */
GEANY_KEYS_SEARCH_FIND, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDNEXT, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDPREVIOUS, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDINFILES, /**< Keybinding. */
GEANY_KEYS_SEARCH_REPLACE, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDNEXTSEL, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDPREVSEL, /**< Keybinding. */
GEANY_KEYS_SEARCH_NEXTMESSAGE, /**< Keybinding. */
GEANY_KEYS_SEARCH_PREVIOUSMESSAGE, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDUSAGE, /**< Keybinding. */
GEANY_KEYS_SEARCH_FINDDOCUMENTUSAGE, /**< Keybinding. */
GEANY_KEYS_SEARCH_MARKALL, /**< Keybinding. */
GEANY_KEYS_GOTO_FORWARD, /**< Keybinding. */
GEANY_KEYS_GOTO_BACK, /**< Keybinding. */
GEANY_KEYS_GOTO_LINE, /**< Keybinding. */
GEANY_KEYS_GOTO_LINESTART, /**< Keybinding. */
GEANY_KEYS_GOTO_LINEEND, /**< Keybinding. */
GEANY_KEYS_GOTO_MATCHINGBRACE, /**< Keybinding. */
GEANY_KEYS_GOTO_TOGGLEMARKER, /**< Keybinding. */
GEANY_KEYS_GOTO_NEXTMARKER, /**< Keybinding. */
GEANY_KEYS_GOTO_PREVIOUSMARKER, /**< Keybinding. */
GEANY_KEYS_GOTO_PREVWORDPART, /**< Keybinding. */
GEANY_KEYS_GOTO_NEXTWORDPART, /**< Keybinding. */
GEANY_KEYS_GOTO_TAGDEFINITION, /**< Keybinding. */
GEANY_KEYS_GOTO_TAGDECLARATION, /**< Keybinding. */
GEANY_KEYS_GOTO_LINEENDVISUAL, /**< Keybinding. */
GEANY_KEYS_VIEW_TOGGLEALL, /**< Keybinding. */
GEANY_KEYS_VIEW_FULLSCREEN, /**< Keybinding. */
GEANY_KEYS_VIEW_MESSAGEWINDOW, /**< Keybinding. */
GEANY_KEYS_VIEW_SIDEBAR, /**< Keybinding. */
GEANY_KEYS_VIEW_ZOOMIN, /**< Keybinding. */
GEANY_KEYS_VIEW_ZOOMOUT, /**< Keybinding. */
GEANY_KEYS_VIEW_ZOOMRESET, /**< Keybinding. */
GEANY_KEYS_FOCUS_EDITOR, /**< Keybinding. */
GEANY_KEYS_FOCUS_SCRIBBLE, /**< Keybinding. */
GEANY_KEYS_FOCUS_VTE, /**< Keybinding. */
GEANY_KEYS_FOCUS_SEARCHBAR, /**< Keybinding. */
GEANY_KEYS_FOCUS_SIDEBAR, /**< Keybinding. */
GEANY_KEYS_FOCUS_COMPILER, /**< Keybinding. */
GEANY_KEYS_FOCUS_MESSAGES, /**< Keybinding. */
GEANY_KEYS_FOCUS_MESSAGE_WINDOW, /**< Keybinding. */
GEANY_KEYS_FOCUS_SIDEBAR_DOCUMENT_LIST, /**< Keybinding. */
GEANY_KEYS_FOCUS_SIDEBAR_SYMBOL_LIST, /**< Keybinding. */
GEANY_KEYS_NOTEBOOK_SWITCHTABLEFT, /**< Keybinding. */
GEANY_KEYS_NOTEBOOK_SWITCHTABRIGHT, /**< Keybinding. */
GEANY_KEYS_NOTEBOOK_SWITCHTABLASTUSED, /**< Keybinding. */
@ -288,52 +215,28 @@ enum GeanyKeysNotebookTabID
GEANY_KEYS_NOTEBOOK_MOVETABRIGHT, /**< Keybinding. */
GEANY_KEYS_NOTEBOOK_MOVETABFIRST, /**< Keybinding. */
GEANY_KEYS_NOTEBOOK_MOVETABLAST, /**< Keybinding. */
GEANY_KEYS_NOTEBOOK_COUNT
};
/** Document group keybinding command IDs */
enum GeanyKeysDocumentID
{
GEANY_KEYS_DOCUMENT_REPLACETABS, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_REPLACESPACES, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_TOGGLEFOLD, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_FOLDALL, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_UNFOLDALL, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_RELOADTAGLIST, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_LINEWRAP, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_LINEBREAK, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_REMOVE_MARKERS, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_REMOVE_ERROR_INDICATORS, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_COUNT
};
/** Build group keybinding command IDs */
enum GeanyKeysBuildID
{
GEANY_KEYS_BUILD_COMPILE, /**< Keybinding. */
GEANY_KEYS_BUILD_LINK, /**< Keybinding. */
GEANY_KEYS_BUILD_MAKE, /**< Keybinding. */
GEANY_KEYS_BUILD_MAKEOWNTARGET, /**< Keybinding. */
GEANY_KEYS_BUILD_MAKEOBJECT, /**< Keybinding. */
GEANY_KEYS_BUILD_NEXTERROR, /**< Keybinding. */
GEANY_KEYS_BUILD_PREVIOUSERROR, /**< Keybinding. */
GEANY_KEYS_BUILD_RUN, /**< Keybinding. */
GEANY_KEYS_BUILD_OPTIONS, /**< Keybinding. */
GEANY_KEYS_BUILD_COUNT
};
/** Tools group keybinding command IDs */
enum GeanyKeysToolsID
{
GEANY_KEYS_TOOLS_OPENCOLORCHOOSER, /**< Keybinding. */
GEANY_KEYS_TOOLS_COUNT
};
/** Help group keybinding command IDs */
enum GeanyKeysHelpID
{
GEANY_KEYS_HELP_HELP, /**< Keybinding. */
GEANY_KEYS_HELP_COUNT
GEANY_KEYS_DOCUMENT_REPLACETABS, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_REPLACESPACES, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_TOGGLEFOLD, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_FOLDALL, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_UNFOLDALL, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_RELOADTAGLIST, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_LINEWRAP, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_LINEBREAK, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_REMOVE_MARKERS, /**< Keybinding. */
GEANY_KEYS_DOCUMENT_REMOVE_ERROR_INDICATORS, /**< Keybinding. */
GEANY_KEYS_BUILD_COMPILE, /**< Keybinding. */
GEANY_KEYS_BUILD_LINK, /**< Keybinding. */
GEANY_KEYS_BUILD_MAKE, /**< Keybinding. */
GEANY_KEYS_BUILD_MAKEOWNTARGET, /**< Keybinding. */
GEANY_KEYS_BUILD_MAKEOBJECT, /**< Keybinding. */
GEANY_KEYS_BUILD_NEXTERROR, /**< Keybinding. */
GEANY_KEYS_BUILD_PREVIOUSERROR, /**< Keybinding. */
GEANY_KEYS_BUILD_RUN, /**< Keybinding. */
GEANY_KEYS_BUILD_OPTIONS, /**< Keybinding. */
GEANY_KEYS_TOOLS_OPENCOLORCHOOSER, /**< Keybinding. */
GEANY_KEYS_HELP_HELP, /**< Keybinding. */
GEANY_KEYS_COUNT /* must not be used by plugins */
};

View File

@ -50,13 +50,13 @@
enum {
/** The Application Programming Interface (API) version, incremented
* whenever any plugin data types are modified or appended to. */
GEANY_API_VERSION = 191,
GEANY_API_VERSION = 192,
/** The Application Binary Interface (ABI) version, incremented whenever
* existing fields in the plugin data types have to be changed or reordered. */
/* This should usually stay the same if fields are only appended, assuming only pointers to
* structs and not structs themselves are declared by plugins. */
GEANY_ABI_VERSION = 66
GEANY_ABI_VERSION = 67
};
/** Defines a function to check the plugin is safe to load.

View File

@ -303,23 +303,19 @@ static void kb_init(void)
if (store == NULL)
kb_init_tree();
for (g = 0; g < keybinding_groups->len; g++)
foreach_ptr_array(group, g, keybinding_groups)
{
group = g_ptr_array_index(keybinding_groups, g);
gtk_tree_store_append(store, &parent, NULL);
gtk_tree_store_set(store, &parent, KB_TREE_ACTION, group->label,
KB_TREE_INDEX, g, -1);
for (i = 0; i < group->count; i++)
foreach_ptr_array(kb, i, group->key_items)
{
kb = &group->keys[i];
label = keybindings_get_label(kb);
key_string = gtk_accelerator_name(kb->key, kb->mods);
gtk_tree_store_append(store, &iter, &parent);
gtk_tree_store_set(store, &iter, KB_TREE_ACTION, label,
KB_TREE_SHORTCUT, key_string, KB_TREE_INDEX, i, -1);
KB_TREE_SHORTCUT, key_string, KB_TREE_INDEX, kb->id, -1);
g_free(key_string);
g_free(label);
}
@ -1311,7 +1307,6 @@ static void kb_dialog_response_cb(GtkWidget *dialog, gint response, G_GNUC_UNUSE
GeanyKeyBinding *kb;
kb = kb_lookup_kb_from_iter(GTK_TREE_MODEL(store), &g_iter);
gtk_accelerator_parse(gtk_label_get_text(GTK_LABEL(dialog_label)), &lkey, &lmods);
if (kb_find_duplicate(dialog, kb, lkey, lmods, gtk_label_get_text(GTK_LABEL(dialog_label))))
@ -1375,22 +1370,19 @@ static gboolean kb_find_duplicate(GtkWidget *parent, GeanyKeyBinding *search_kb,
guint key, GdkModifierType mods, const gchar *action)
{
gsize g, i;
GeanyKeyGroup *group;
GeanyKeyBinding *kb;
/* allow duplicate if there is no key combination */
if (key == 0 && mods == 0)
return FALSE;
for (g = 0; g < keybinding_groups->len; g++)
foreach_ptr_array(group, g, keybinding_groups)
{
GeanyKeyGroup *group = g_ptr_array_index(keybinding_groups, g);
for (i = 0; i < group->count; i++)
foreach_ptr_array(kb, i, group->key_items)
{
GeanyKeyBinding *keys = group->keys;
GeanyKeyBinding *kb = &keys[i];
/* search another item with the same key,
* but don't search the key we're looking for keys[idx] */
* but don't search the key we're looking for(!) */
if (kb->key == key && kb->mods == mods
&& ! (kb->key == search_kb->key && kb->mods == search_kb->mods))
{
@ -1408,7 +1400,7 @@ static gboolean kb_find_duplicate(GtkWidget *parent, GeanyKeyBinding *search_kb,
if (ret == GTK_RESPONSE_YES)
{
keybindings_update_combo(kb, 0, 0);
kb_clear_tree_shortcut(g, i);
kb_clear_tree_shortcut(g, kb->id);
/* carry on looking for other duplicates if overriding */
continue;
}