Code

cleanup: Remove some commented-out code.
[inkscape.git] / src / shortcuts.cpp
1 #define __SP_SHORTCUTS_C__
3 /** \file
4  * Keyboard shortcut processing.
5  */
6 /*
7  * Authors:
8  *   Lauris Kaplinski <lauris@kaplinski.com>
9  *   MenTaLguY <mental@rydia.net>
10  *   bulia byak <buliabyak@users.sf.net>
11  *   Peter Moulder <pmoulder@mail.csse.monash.edu.au>
12  *
13  * Copyright (C) 2005  Monash University
14  * Copyright (C) 2005  MenTaLguY <mental@rydia.net>
15  *
16  * You may redistribute and/or modify this file under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2 of the License, or (at your
18  * option) any later version.
19  */
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
25 #include <gdk/gdkkeys.h>
26 #include <gdk/gdkkeysyms.h>
28 #include "helper/action.h"
29 #include "shortcuts.h"
30 #include "verbs.h"
31 #include "xml/node-iterators.h"
32 #include "xml/repr.h"
34 using namespace Inkscape;
36 static void sp_shortcut_set(unsigned int const shortcut, Inkscape::Verb *const verb, bool const is_primary);
38 static void set_shortcuts_xml(XML::Document const *doc);
40 /* Returns true if action was performed */
42 bool
43 sp_shortcut_invoke(unsigned int shortcut, Inkscape::UI::View::View *view)
44 {
45     Inkscape::Verb *verb = sp_shortcut_get_verb(shortcut);
46     if (verb) {
47         SPAction *action = verb->get_action(view);
48         if (action) {
49             sp_action_perform(action, NULL);
50             return true;
51         }
52     }
53     return false;
54 }
56 static GHashTable *verbs = NULL;
57 static GHashTable *primary_shortcuts = NULL;
59 extern char const shortcuts_default_xml[];
61 static void
62 sp_shortcut_init()
63 {
64     verbs = g_hash_table_new(NULL, NULL);
65     primary_shortcuts = g_hash_table_new(NULL, NULL);
67     XML::Document *shortcuts=sp_repr_read_mem(shortcuts_default_xml, strlen(shortcuts_default_xml), NULL);
68     if (shortcuts) {
69         set_shortcuts_xml(shortcuts);
70         GC::release(shortcuts);
71     } else {
72         g_error("Unable to parse default shortcuts");
73     }
74 }
76 static void set_shortcuts_xml(XML::Document const *doc) {
77     XML::Node const *root=doc->root();
78     g_return_if_fail(!strcmp(root->name(), "keybindings"));
79     XML::NodeConstSiblingIterator iter=root->firstChild();
80     for ( ; iter ; ++iter ) {
81         bool is_primary;
83         if (!strcmp(iter->name(), "primary")) {
84             is_primary = true;
85         } else if (!strcmp(iter->name(), "secondary")) {
86             is_primary = false;
87         } else {
88             g_warning("Unknown key binding type %s", iter->name());
89             continue;
90         }
92         gchar const *verb_name=iter->attribute("verb");
93         if (!verb_name) {
94             g_warning("Missing verb name for shortcut");
95             continue;
96         }
98         gchar const *keyval_name=iter->attribute("keyval");
99         if (!keyval_name) {
100             g_warning("Missing keyval for %s", verb_name);
101             continue;
102         }
103         guint keyval=gdk_keyval_from_name(keyval_name);
104         if (keyval == GDK_VoidSymbol) {
105             g_warning("Unknown keyval %s for %s", keyval_name, verb_name);
106             continue;
107         }
109         guint modifiers=0;
111         gchar const *modifiers_string=iter->attribute("modifiers");
112         if (modifiers_string) {
113             gchar const *iter=modifiers_string;
114             while (*iter) {
115                 size_t length=strcspn(iter, ",");
116                 gchar *mod=g_strndup(iter, length);
117                 if (!strcmp(mod, "control")) {
118                     modifiers |= SP_SHORTCUT_CONTROL_MASK;
119                 } else if (!strcmp(mod, "shift")) {
120                     modifiers |= SP_SHORTCUT_SHIFT_MASK;
121                 } else if (!strcmp(mod, "alt")) {
122                     modifiers |= SP_SHORTCUT_ALT_MASK;
123                 } else {
124                     g_warning("Unknown modifier %s for %s", mod, verb_name);
125                 }
126                 g_free(mod);
127                 iter += length;
128                 if (*iter) iter++;
129             }
130         }
132         sp_shortcut_set(keyval | modifiers,
133                         Inkscape::Verb::getbyid(verb_name),
134                         is_primary);
135     }
138 /**
139  * Adds a keyboard shortcut for the given verb.
140  * (Removes any existing binding for the given shortcut, including appropriately
141  * adjusting sp_shortcut_get_primary if necessary.)
142  *
143  * \param is_primary True iff this is the shortcut to be written in menu items or buttons.
144  *
145  * \post sp_shortcut_get_verb(shortcut) == verb.
146  * \post !is_primary or sp_shortcut_get_primary(verb) == shortcut.
147  */
148 static void
149 sp_shortcut_set(unsigned int const shortcut, Inkscape::Verb *const verb, bool const is_primary)
151     if (!verbs) sp_shortcut_init();
153     Inkscape::Verb *old_verb = (Inkscape::Verb *)(g_hash_table_lookup(verbs, GINT_TO_POINTER(shortcut)));
154     g_hash_table_insert(verbs, GINT_TO_POINTER(shortcut), (gpointer)(verb));
156     /* Maintain the invariant that sp_shortcut_get_primary(v) returns either 0 or a valid shortcut for v. */
157     if (old_verb && old_verb != verb) {
158         unsigned int const old_primary = (unsigned int)GPOINTER_TO_INT(g_hash_table_lookup(primary_shortcuts, (gpointer)old_verb));
160         if (old_primary == shortcut) {
161             g_hash_table_insert(primary_shortcuts, (gpointer)old_verb, GINT_TO_POINTER(0));
162         }
163     }
165     if (is_primary) {
166         g_hash_table_insert(primary_shortcuts, (gpointer)(verb), GINT_TO_POINTER(shortcut));
167     }
170 Inkscape::Verb *
171 sp_shortcut_get_verb(unsigned int shortcut)
173     if (!verbs) sp_shortcut_init();
174     return (Inkscape::Verb *)(g_hash_table_lookup(verbs, GINT_TO_POINTER(shortcut)));
177 unsigned int
178 sp_shortcut_get_primary(Inkscape::Verb *verb)
180     if (!primary_shortcuts) sp_shortcut_init();
181     return (unsigned int)GPOINTER_TO_INT(g_hash_table_lookup(primary_shortcuts,
182                                                              (gpointer)(verb)));
186 /*
187   Local Variables:
188   mode:c++
189   c-file-style:"stroustrup"
190   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
191   indent-tabs-mode:nil
192   fill-column:99
193   End:
194 */
195 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :