]> git.lyx.org Git - lyx.git/blob - src/kbsequence.C
John's Layout Tabular UI improvements and Martins fixes to clearing the
[lyx.git] / src / kbsequence.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *      
6  *           Copyright 1995 Matthias Ettrich
7  *           Copyright 1995-2001 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12 //#include <cstring>
13 #include <X11/Xlib.h>
14
15 #include "gettext.h"
16
17 #ifdef __GNUG__
18 #pragma implementation
19 #endif
20
21 #include "kbsequence.h"
22 #include "kbmap.h"
23 #include "debug.h"
24
25 using std::endl;
26
27 // The only modifiers that we handle. We want to throw away things
28 // like NumLock.
29 enum { ModsMask = ShiftMask | ControlMask | Mod1Mask };
30
31
32 kb_action kb_sequence::addkey(unsigned int key, unsigned int mod, unsigned int nmod)
33 {
34         // adding a key to a deleted sequence
35         // starts a new sequence
36         if (deleted_) {
37                 deleted_ = false;
38                 length_ = 0;
39                 sequence.clear();
40                 modifiers.clear();
41         }
42
43         modifiers.push_back(mod + (nmod << 16));
44         sequence.push_back(key);
45         ++length_;
46
47         if (curmap) {
48                 return curmap->lookup(key, mod, this);
49         }
50         
51         return LFUN_UNKNOWN_ACTION;
52 }
53
54
55 string::size_type kb_sequence::parse(string const & s)
56 {
57         if (s.empty()) return 1;
58
59         string::size_type i = 0;
60         unsigned int mod = 0;
61         unsigned int nmod = 0;
62         while (i < s.length()) {
63                 if (s[i] == ' ')
64                         ++i;
65                 if (i >= s.length())
66                         break;
67                 
68                 if (i + 1 < s.length() && s[i + 1] == '-') {
69                         switch (s[i]) {
70                         case 's': case 'S':
71                                 mod |= ShiftMask;
72                                 i += 2;
73                                 continue;
74                         case 'c': case 'C':
75                                 mod |= ControlMask;
76                                 i += 2;
77                                 continue;
78                         case 'm': case 'M':
79                                 mod |= Mod1Mask;
80                                 i += 2;
81                                 continue;
82                         default:
83                                 return i + 1;
84                         }
85                 } else if (i + 2 < s.length() && s[i] == '~'
86                            && s[i + 2] == '-') {
87                         switch (s[i + 1]) {
88                         case 's': case 'S':
89                                 nmod |= ShiftMask;
90                                 i += 3;
91                                 continue;
92                         case 'c': case 'C':
93                                 nmod |= ControlMask;
94                                 i += 3;
95                                 continue;
96                         case 'm': case 'M':
97                                 nmod |= Mod1Mask;
98                                 i += 3;
99                                 continue;
100                         default:
101                                 return i + 2;
102                         }
103                 } else {
104                         string tbuf;
105                         string::size_type j = i;
106                         for (; j < s.length() && s[j] != ' '; ++j)
107                                 tbuf += s[j];    // (!!!check bounds :-)
108                         
109                         KeySym key = XStringToKeysym(tbuf.c_str());
110                         if (key == NoSymbol) {
111                                 lyxerr[Debug::KBMAP]
112                                         << "kbmap.C: No such keysym: "
113                                         << tbuf << endl;
114                                 return j;
115                         }
116                         i = j;
117                         
118                         addkey(key, mod, nmod);
119                         mod = 0;
120                 }
121         }
122         
123         // empty sequence?
124         if (!length_)
125                 return 0;
126
127         // everything is fine
128         return string::npos;
129 }
130
131
132 string const kb_sequence::print() const
133 {
134         string buf;
135
136         if (deleted_)
137                 return buf;
138         
139         for (std::vector<unsigned int>::size_type i = 0; i < length_; ++i) {
140                 buf += kb_keymap::printKeysym(sequence[i], modifiers[i] & 0xffff);
141
142                 // append a blank
143                 if (i + 1 < length_) {
144                         buf += ' ';
145                 }
146         }
147         return buf;
148 }
149
150
151 string const kb_sequence::printOptions() const
152 {
153         string buf;
154
155         buf += print();
156
157         if (!curmap)
158                 return buf;
159
160         buf += _("   options: ");
161         buf += curmap->print();
162         return buf;
163 }
164
165
166 void kb_sequence::mark_deleted()
167 {
168         deleted_ = true;
169 }
170
171
172 unsigned int kb_sequence::getsym() const
173 {
174         if (length_ == 0) return NoSymbol;
175         return sequence[length_ - 1];
176 }
177
178
179 char kb_sequence::getiso() const
180 {
181         unsigned int const c = getsym();
182
183         lyxerr[Debug::KBMAP] << "Raw keysym: "
184                              << std::hex << c << std::dec << endl;
185         lyxerr[Debug::KBMAP] << "byte 3: "
186                              << std::hex << (c & 0xff00) << std::dec
187                              << endl;
188         return kb_keymap::getiso(c);
189 }
190
191
192 void kb_sequence::reset()
193 {
194         mark_deleted();
195         curmap = stdmap;
196 }
197
198 void kb_sequence::clear()
199 {
200         length_ = 0;
201         reset();
202 }