1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2
3 /* AbiSource Program Utilities
4 * Copyright (C) 1998 AbiSource, Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA.
20 */
21
22
23
24
25 #include <ctype.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "ut_assert.h"
31 #include "ut_debugmsg.h"
32 #include "ut_types.h"
33 #include "ev_EditMethod.h"
34 #include "ev_EditBinding.h"
35 #include "ev_NamedVirtualKey.h"
36
37
38 /*****************************************************************/
39 /*****************************************************************/
40
EV_EditBinding(EV_EditBindingMap * pebm)41 EV_EditBinding::EV_EditBinding(EV_EditBindingMap * pebm)
42 {
43 m_ebt = EV_EBT_PREFIX;
44 u.m_pebm = pebm;
45 }
46
EV_EditBinding(EV_EditMethod * pem)47 EV_EditBinding::EV_EditBinding(EV_EditMethod * pem)
48 {
49 m_ebt = EV_EBT_METHOD;
50 u.m_pem = pem;
51 }
52
getMap(void) const53 EV_EditBindingMap * EV_EditBinding::getMap(void) const
54 {
55 UT_ASSERT(m_ebt == EV_EBT_PREFIX);
56 return u.m_pebm;
57 }
58
getMethod(void) const59 EV_EditMethod * EV_EditBinding::getMethod(void) const
60 {
61 UT_ASSERT(m_ebt == EV_EBT_METHOD);
62 return u.m_pem;
63 }
64
65 /*****************************************************************/
66 /*****************************************************************/
67
68 class ABI_EXPORT ev_EB_MouseTable
69 {
70 public:
ev_EB_MouseTable()71 ev_EB_MouseTable()
72 {
73 reset();
74 };
75
reset()76 void reset()
77 {
78 memset(m_peb,0,sizeof(m_peb));
79 }
80
~ev_EB_MouseTable()81 ~ev_EB_MouseTable()
82 {
83 for (UT_uint32 i=0; i < EV_COUNT_EMO; i++)
84 for (UT_uint32 j=0; j < EV_COUNT_EMS; j++)
85 for (UT_uint32 k=0; k< EV_COUNT_EMC; k++)
86 if (m_peb[i][j][k])
87 delete m_peb[i][j][k];
88 }
89
90 EV_EditBinding * m_peb[EV_COUNT_EMO][EV_COUNT_EMS][EV_COUNT_EMC];
91 };
92
93 class ABI_EXPORT ev_EB_NVK_Table
94 {
95 public:
ev_EB_NVK_Table()96 ev_EB_NVK_Table()
97 {
98 reset();
99 };
reset()100 void reset()
101 {
102 memset(m_peb,0,sizeof(m_peb));
103 }
~ev_EB_NVK_Table()104 ~ev_EB_NVK_Table()
105 {
106 for (UT_sint32 i=0; i < static_cast<UT_sint32>(EV_COUNT_NVK); i++)
107 for (UT_sint32 j=0; j < EV_COUNT_EMS; j++)
108 if (m_peb[i][j])
109 delete m_peb[i][j];
110 }
111
112 EV_EditBinding * m_peb[EV_COUNT_NVK][EV_COUNT_EMS];
113 };
114
115 class ABI_EXPORT ev_EB_Char_Table
116 {
117 public:
ev_EB_Char_Table()118 ev_EB_Char_Table()
119 {
120 reset();
121 };
reset()122 void reset()
123 {
124 memset(m_peb,0,sizeof(m_peb));
125 }
~ev_EB_Char_Table()126 ~ev_EB_Char_Table()
127 {
128 for (UT_sint32 i=0; i < 256; i++)
129 for (UT_sint32 j=0; j < EV_COUNT_EMS_NoShift; j++)
130 if (m_peb[i][j])
131 delete m_peb[i][j];
132 }
133
134
135 // TODO Note[1] we currently limit the range on regular (non-nvk)
136 // TODO Note[1] keys to 256. This is probably OK for Latin1, but
137 // TODO Note[1] will probably need to be re-addressed later.
138
139 EV_EditBinding * m_peb[256][EV_COUNT_EMS_NoShift];
140 };
141
142 /*****************************************************************/
143 /*****************************************************************/
144
EV_EditBindingMap(EV_EditMethodContainer * pemc)145 EV_EditBindingMap::EV_EditBindingMap(EV_EditMethodContainer * pemc):
146 m_iLastMouseNo(0)
147 {
148 UT_ASSERT(pemc);
149 m_pemc = pemc;
150 UT_sint32 i = 0;
151 for (i=0; i<EV_COUNT_EMB; i++)
152 {
153 m_pebMT[i] = (ev_EB_MouseTable*) NULL;
154 }
155 m_pebNVK = (ev_EB_NVK_Table*) NULL;
156 m_pebChar = (ev_EB_Char_Table*) NULL;
157 }
158
~EV_EditBindingMap()159 EV_EditBindingMap::~EV_EditBindingMap()
160 {
161 UT_sint32 i = 0;
162 for (i=0; i<EV_COUNT_EMB; i++)
163 {
164 if (m_pebMT[i])
165 delete m_pebMT[i];
166 }
167
168 if (m_pebNVK)
169 delete m_pebNVK;
170
171 if (m_pebChar)
172 delete m_pebChar;
173 }
174
MakeMouseEditBits(UT_uint32 button,UT_uint32 op,UT_uint32 mod,UT_uint32 context)175 static EV_EditBits MakeMouseEditBits( UT_uint32 button, UT_uint32 op, UT_uint32 mod, UT_uint32 context )
176 {
177 EV_EditBits eb = 0;
178 switch (button) {
179 case 0: eb |= EV_EMB_BUTTON0; break;
180 case 1: eb |= EV_EMB_BUTTON1; break;
181 case 2: eb |= EV_EMB_BUTTON2; break;
182 case 3: eb |= EV_EMB_BUTTON3; break;
183 case 4: eb |= EV_EMB_BUTTON4; break;
184 case 5: eb |= EV_EMB_BUTTON5; break;
185 default: UT_ASSERT(UT_SHOULD_NOT_HAPPEN); break;
186 }
187 eb |= EV_EMO_FromNumber( op+1 );
188 eb |= EV_EMS_FromNumber( mod );
189 switch (context) {
190 case 0: eb |= EV_EMC_UNKNOWN; break;
191 case 1: eb |= EV_EMC_TEXT; break;
192 case 2: eb |= EV_EMC_LEFTOFTEXT; break;
193 case 3: eb |= EV_EMC_MISSPELLEDTEXT; break;
194 case 4: eb |= EV_EMC_IMAGE; break;
195 case 5: eb |= EV_EMC_IMAGESIZE; break;
196 case 6: eb |= EV_EMC_FIELD; break;
197 case 7: eb |= EV_EMC_HYPERLINK; break;
198 case 8: eb |= EV_EMC_RIGHTOFTEXT; break;
199 case 9: eb |= EV_EMC_REVISION; break;
200 case 10: eb |= EV_EMC_VLINE; break;
201 case 11: eb |= EV_EMC_HLINE; break;
202 case 12: eb |= EV_EMC_FRAME; break;
203 case 13: eb |= EV_EMC_VISUALTEXTDRAG; break;
204 case 14: eb |= EV_EMC_TOPCELL; break;
205 case 15: eb |= EV_EMC_TOC; break;
206 case 16: eb |= EV_EMC_POSOBJECT; break;
207 case 17: eb |= EV_EMC_MATH; break;
208 case 18: eb |= EV_EMC_EMBED; break;
209 default: UT_ASSERT(UT_SHOULD_NOT_HAPPEN); break;
210 }
211 return eb;
212 }
213
MakeNVKEditBits(UT_uint32 mod,UT_uint32 nvk)214 static EV_EditBits MakeNVKEditBits( UT_uint32 mod, UT_uint32 nvk )
215 {
216 return EV_EMS_FromNumberNoShift(mod) | nvk | EV_EKP_NAMEDKEY;
217 }
218
MakeKeyPressEditBits(UT_uint32 mod,UT_uint32 key)219 static EV_EditBits MakeKeyPressEditBits( UT_uint32 mod, UT_uint32 key )
220 {
221 return EV_EMS_FromNumberNoShift(mod) | key | EV_EKP_PRESS;
222 }
223
getAll(std::map<EV_EditBits,const char * > & map)224 void EV_EditBindingMap::getAll( std::map<EV_EditBits,const char*>& map )
225 {
226 // loop through mouse contexts
227 if (m_pebMT) {
228 for (UT_uint32 button=0; button<sizeof(m_pebMT)/sizeof(m_pebMT[0]); ++button) {
229 if (m_pebMT[button]) {
230 for (UT_uint32 op=0; op<sizeof(m_pebMT[0]->m_peb)/sizeof(m_pebMT[0]->m_peb[0]); ++op) {
231 for (UT_uint32 mod=0; mod<sizeof(m_pebMT[0]->m_peb[0])/sizeof(m_pebMT[0]->m_peb[0][0]); ++mod) {
232 for (UT_uint32 context=0; context<sizeof(m_pebMT[0]->m_peb[0][0])/sizeof(m_pebMT[0]->m_peb[0][0][0]); ++context) {
233 EV_EditBinding* binding = m_pebMT[button]->m_peb[op][mod][context];
234 if (binding && binding->getType()==EV_EBT_METHOD) {
235 map.insert(
236 std::map<EV_EditBits,const char*>::value_type(
237 MakeMouseEditBits( button, op, mod, context ),
238 binding->getMethod()->getName() )
239 );
240 }
241 }
242 }
243 }
244 }
245 }
246 }
247
248 // loop through NVK's
249 if (m_pebNVK) {
250 for (UT_uint32 nvk=0; nvk<sizeof(m_pebNVK->m_peb)/sizeof(m_pebNVK->m_peb[0]); ++nvk) {
251 for (UT_uint32 mod=0; mod<sizeof(m_pebNVK->m_peb[0])/sizeof(m_pebNVK->m_peb[0][0]); ++mod) {
252 EV_EditBinding* binding = m_pebNVK->m_peb[nvk][mod];
253 if (binding && binding->getType()==EV_EBT_METHOD) {
254 map.insert(
255 std::map<EV_EditBits,const char*>::value_type(
256 MakeNVKEditBits( mod, nvk ),
257 binding->getMethod()->getName() )
258 );
259 }
260 }
261 }
262 }
263
264 // loop through keypresses
265 if (m_pebChar) {
266 for (UT_uint32 key=0; key<sizeof(m_pebChar->m_peb)/sizeof(m_pebChar->m_peb[0]); ++key) {
267 for (UT_uint32 mod=0; mod<sizeof(m_pebChar->m_peb[0])/sizeof(m_pebChar->m_peb[0][0]); ++mod) {
268 EV_EditBinding* binding = m_pebChar->m_peb[key][mod];
269 if (binding && binding->getType()==EV_EBT_METHOD) {
270 map.insert(
271 std::map<EV_EditBits,const char*>::value_type(
272 MakeKeyPressEditBits( mod, key ),
273 binding->getMethod()->getName() )
274 );
275 }
276 }
277 }
278 }
279 }
280
findEditBits(const char * szMethodName,std::vector<EV_EditBits> & list)281 void EV_EditBindingMap::findEditBits( const char* szMethodName, std::vector<EV_EditBits>& list )
282 {
283 // first check if we even know the specified method
284 EV_EditMethod* method = m_pemc->findEditMethodByName( szMethodName );
285 if (method) {
286
287 // search in mouse contexts
288 if (m_pebMT) {
289 for (UT_uint32 button=0; button<sizeof(m_pebMT)/sizeof(m_pebMT[0]); ++button) {
290 if (m_pebMT[button]) {
291 for (UT_uint32 op=0; op<sizeof(m_pebMT[0]->m_peb)/sizeof(m_pebMT[0]->m_peb[0]); ++op) {
292 for (UT_uint32 mod=0; mod<sizeof(m_pebMT[0]->m_peb[0])/sizeof(m_pebMT[0]->m_peb[0][0]); ++mod) {
293 for (UT_uint32 context=0; context<sizeof(m_pebMT[0]->m_peb[0][0])/sizeof(m_pebMT[0]->m_peb[0][0][0]); ++context) {
294 if (bindingUsesMethod( m_pebMT[button]->m_peb[op][mod][context], method )) {
295 list.push_back( MakeMouseEditBits( button, op, mod, context ) );
296 }
297 }
298 }
299 }
300 }
301 }
302 }
303
304 // search in NVK's
305 if (m_pebNVK) {
306 for (UT_uint32 nvk=0; nvk<sizeof(m_pebNVK->m_peb)/sizeof(m_pebNVK->m_peb[0]); ++nvk) {
307 for (UT_uint32 mod=0; mod<sizeof(m_pebNVK->m_peb[0])/sizeof(m_pebNVK->m_peb[0][0]); ++mod) {
308 if (bindingUsesMethod( m_pebNVK->m_peb[nvk][mod], method )) {
309 list.push_back( MakeNVKEditBits( mod, nvk ) );
310 }
311 }
312 }
313 }
314
315 // search in keypresses
316 if (m_pebChar) {
317 for (UT_uint32 key=0; key<sizeof(m_pebChar->m_peb)/sizeof(m_pebChar->m_peb[0]); ++key) {
318 for (UT_uint32 mod=0; mod<sizeof(m_pebChar->m_peb[0])/sizeof(m_pebChar->m_peb[0][0]); ++mod) {
319 if (bindingUsesMethod( m_pebChar->m_peb[key][mod], method )) {
320 list.push_back( MakeKeyPressEditBits( mod, key ) );
321 }
322 }
323 }
324 }
325 }
326 }
327
bindingUsesMethod(EV_EditBinding * binding,EV_EditMethod * method)328 bool EV_EditBindingMap::bindingUsesMethod( EV_EditBinding* binding, EV_EditMethod* method )
329 {
330 return binding && binding->getType()==EV_EBT_METHOD && binding->getMethod()==method;
331 }
332
findEditBinding(EV_EditBits eb)333 EV_EditBinding * EV_EditBindingMap::findEditBinding(EV_EditBits eb)
334 {
335 // this handles keyboard (nvk and char) and mouse.
336
337 if (EV_IsMouse(eb)) // mouse
338 {
339 UT_uint32 n_emb = EV_EMB_ToNumber(eb)-1;
340 xxx_UT_DEBUGMSG(("is mouse %d binding number %d \n",eb,n_emb));
341 //
342 // Handle the case of accidently middle clicking during a
343 // mouse wheel scroll.
344 //
345 if((n_emb == 2) && ((m_iLastMouseNo == 4) || (m_iLastMouseNo == 5)))
346 {
347 n_emb = m_iLastMouseNo;
348 }
349 m_iLastMouseNo = n_emb;
350 class ev_EB_MouseTable * p = m_pebMT[n_emb];
351 if (!p)
352 return 0; // no bindings of anykind for this mouse button
353 UT_uint32 n_emo = EV_EMO_ToNumber(eb)-1;
354 UT_uint32 n_ems = EV_EMS_ToNumber(eb);
355 UT_uint32 n_emc = EV_EMC_ToNumber(eb);
356 return p->m_peb[n_emo][n_ems][n_emc];
357
358 }
359 else if (EV_IsKeyboard(eb)) // a keyevent, find out what kind
360 {
361 if (eb & EV_EKP_NAMEDKEY) // a NVK
362 {
363 if (!m_pebNVK)
364 return 0; // no bindings of anykind for nvk keys
365
366 UT_uint32 n_nvk = EV_NVK_ToNumber(eb);
367 UT_uint32 n_ems = EV_EMS_ToNumber(eb);
368 return m_pebNVK->m_peb[n_nvk][n_ems];
369 }
370 else // not a NVK -- regular char
371 {
372 if (!m_pebChar)
373 return 0; // no bindings of anykind for non-nvk keys
374
375 UT_uint32 n_evk = EV_EVK_ToNumber(eb);
376 if (n_evk >= 256)
377 {
378 if ( n_evk >= 256 && (n_evk - 65280) < 256)
379 n_evk -= 65280; // quick fix
380 else
381 {
382 n_evk = 'a';
383 /* in hopes that there will be
384 'insertData' method assigned to
385 plain 'a'
386 */
387 }
388 };
389
390 UT_uint32 n_ems = EV_EMS_ToNumberNoShift(eb);
391 return m_pebChar->m_peb[n_evk][n_ems];
392 }
393 }
394 UT_ASSERT(0);
395 return 0;
396 }
397
setBinding(EV_EditBits eb,const char * szMethodName)398 bool EV_EditBindingMap::setBinding(EV_EditBits eb, const char * szMethodName)
399 {
400 EV_EditMethod * pem = m_pemc->findEditMethodByName(szMethodName);
401 if (!pem)
402 {
403 if(strcmp(szMethodName,"NULL") == 0)
404 {
405 EV_EditBinding * ev = NULL;
406 return setBinding(eb,ev);
407 }
408 UT_DEBUGMSG(("Unknown method name [%s] in binding table.\n",szMethodName));
409 UT_ASSERT(pem); // TODO remove this and find a better way of doing a spelling-check...
410 return false;
411 }
412
413 EV_EditBinding * peb = new EV_EditBinding(pem);
414 if (!peb)
415 return false;
416
417 return setBinding(eb,peb);
418 }
419
setBinding(EV_EditBits eb,EV_EditBinding * peb)420 bool EV_EditBindingMap::setBinding(EV_EditBits eb, EV_EditBinding * peb)
421 {
422 // this handles keyboard (nvk and char) and mouse.
423 // return false if the given location is already bound.
424
425 if (EV_IsMouse(eb)) // mouse
426 {
427 UT_uint32 n_emb = EV_EMB_ToNumber(eb)-1;
428 class ev_EB_MouseTable * p = m_pebMT[n_emb];
429 if (!p)
430 {
431 m_pebMT[n_emb] = new ev_EB_MouseTable();
432 p = m_pebMT[n_emb];
433 if (!p) {
434 delete peb;
435 return false;
436 }
437 }
438 UT_uint32 n_emo = EV_EMO_ToNumber(eb)-1;
439 UT_uint32 n_ems = EV_EMS_ToNumber(eb);
440 UT_uint32 n_emc = EV_EMC_ToNumber(eb);
441 if (p->m_peb[n_emo][n_ems][n_emc]) {
442 delete peb;
443 return false;
444 }
445 p->m_peb[n_emo][n_ems][n_emc] = peb;
446 return true;
447 }
448 else if (EV_IsKeyboard(eb)) // a keyevent, find out what kind
449 {
450 if (eb & EV_EKP_NAMEDKEY) // nvk
451 {
452 if (!m_pebNVK)
453 {
454 m_pebNVK = new ev_EB_NVK_Table();
455 if (!m_pebNVK) {
456 delete peb;
457 return false;
458 }
459 }
460 UT_uint32 n_nvk = EV_NVK_ToNumber(eb);
461 UT_uint32 n_ems = EV_EMS_ToNumber(eb);
462 if (m_pebNVK->m_peb[n_nvk][n_ems]) {
463 delete peb;
464 return false;
465 }
466 m_pebNVK->m_peb[n_nvk][n_ems] = peb;
467 return true;
468 }
469 else // a non-nvk -- regular char
470 {
471 if (!m_pebChar)
472 {
473 m_pebChar = new ev_EB_Char_Table();
474 if (!m_pebChar) {
475 delete peb;
476 return false;
477 }
478 }
479 UT_uint32 n_evk = EV_EVK_ToNumber(eb);
480 UT_ASSERT(n_evk < 256); // TODO see note [1] above.
481 UT_uint32 n_ems = EV_EMS_ToNumberNoShift(eb);
482 if (m_pebChar->m_peb[n_evk][n_ems])
483 {
484 UT_DEBUGMSG(("Removing and Deleting previous keybinding %p \n",m_pebChar->m_peb[n_evk][n_ems]));
485 delete m_pebChar->m_peb[n_evk][n_ems];
486 }
487 m_pebChar->m_peb[n_evk][n_ems] = peb;
488 return true;
489 }
490 }
491 delete peb;
492 UT_ASSERT(0);
493 return 0;
494 }
495
removeBinding(EV_EditBits eb)496 bool EV_EditBindingMap::removeBinding(EV_EditBits eb)
497 {
498 // this handles keyboard (nvk and char) and mouse.
499 // remove the binding from the map.
500 // return true if binding updated.
501 // we do not g_free the unreferenced binding.
502
503 if (EV_IsMouse(eb)) // mouse
504 {
505 UT_uint32 n_emb = EV_EMB_ToNumber(eb)-1;
506 class ev_EB_MouseTable * p = m_pebMT[n_emb];
507 if (!p)
508 return false;
509 UT_uint32 n_emo = EV_EMO_ToNumber(eb)-1;
510 UT_uint32 n_ems = EV_EMS_ToNumber(eb);
511 UT_uint32 n_emc = EV_EMC_ToNumber(eb);
512 p->m_peb[n_emo][n_ems][n_emc] = 0;
513 return true;
514 }
515 else if (EV_IsKeyboard(eb)) // a keyevent, find out what kind
516 {
517 if (eb & EV_EKP_NAMEDKEY) // nvk
518 {
519 if (!m_pebNVK)
520 return false;
521 UT_uint32 n_nvk = EV_NVK_ToNumber(eb);
522 UT_uint32 n_ems = EV_EMS_ToNumber(eb);
523 m_pebNVK->m_peb[n_nvk][n_ems] = 0;
524 return true;
525 }
526 else // a non-nvk -- regular char
527 {
528 if (!m_pebChar)
529 return false;
530 UT_uint32 n_evk = EV_EVK_ToNumber(eb);
531 UT_ASSERT(n_evk < 256); // TODO see note [1] above.
532 UT_uint32 n_ems = EV_EMS_ToNumberNoShift(eb);
533 m_pebChar->m_peb[n_evk][n_ems] = 0;
534 return true;
535 }
536 }
537 UT_ASSERT(0);
538 return 0;
539 }
540
resetAll()541 void EV_EditBindingMap::resetAll()
542 {
543 // NOTE: this to me seems like a memory leak,
544 // but since removeBinding is so seemingly easy with leaking
545 // memory as well, I just copy it's MO.
546 for (size_t i=0; i<sizeof(m_pebMT)/sizeof(m_pebMT[0]); ++i) {
547 m_pebMT[i]->reset();
548 }
549 m_pebNVK->reset();
550 m_pebChar->reset();
551 }
552
getShortcutFor(const EV_EditMethod * pEM) const553 const char * EV_EditBindingMap::getShortcutFor(const EV_EditMethod * pEM) const
554 {
555 UT_ASSERT(pEM);
556 if(!m_pebChar)
557 return NULL;
558 // lookup the keyboard shortcut bound to pEM, if any
559
560 EV_EditModifierState ems = 0;
561 EV_EditBinding * pEB;
562 UT_sint32 i, j;
563 char shortcut = 0;
564
565 // search characters first
566 bool bChar = false;
567
568 /* we lookup the table in decreasing order to be able to catch lowercase
569 BEFORE uppercase. Uppercase = Shift modifier. That is the rule */
570 if (m_pebChar)
571 {
572 for (i=255; (i >= 0) && !bChar; i--)
573 {
574 for (j=0; j < EV_COUNT_EMS_NoShift; j++)
575 {
576 if (m_pebChar->m_peb[i][j])
577 {
578 // only check non-null entries
579 pEB = m_pebChar->m_peb[i][j];
580
581 if ((pEB->getType() == EV_EBT_METHOD) &&
582 (pEB->getMethod() == pEM))
583 {
584 // bingo
585 bChar = true;
586 shortcut = i;
587
588 ems = EV_EMS_FromNumberNoShift(j);
589 break;
590 }
591 }
592 }
593 }
594 }
595
596 bool bNVK = false;
597
598 if (!bChar && m_pebNVK)
599 {
600 // then search NVKs
601 for (i=0; (i < static_cast<UT_sint32>(EV_COUNT_NVK)) && !bNVK; i++)
602 {
603 for (j=0; j < EV_COUNT_EMS; j++)
604 {
605 if (m_pebNVK->m_peb[i][j])
606 {
607 // only check non-null entries
608 pEB = m_pebNVK->m_peb[i][j];
609
610 if ((pEB->getType() == EV_EBT_METHOD) &&
611 (pEB->getMethod() == pEM))
612 {
613 // bingo
614 bNVK = true;
615 shortcut = i;
616
617 ems = EV_EMS_FromNumber(j);
618 break;
619 }
620 }
621 }
622 }
623 }
624
625
626 if (!bChar && !bNVK)
627 return (const char *) NULL;
628
629 // translate into displayable string
630 static char buf[128];
631 memset(buf,0,G_N_ELEMENTS(buf));
632
633 if (ems&EV_EMS_CONTROL)
634 strcat(buf, "Ctrl+");
635
636 if (ems&EV_EMS_SHIFT)
637 strcat(buf, "Shift+");
638
639 if (ems&EV_EMS_ALT)
640 strcat(buf, "Alt+");
641
642 if (bChar)
643 {
644 if ((shortcut >= 'A') && (shortcut <= 'Z')) {
645 /* always return an uppercase letter for the shortcut, unlike the mapper do */
646 if (!(ems&EV_EMS_SHIFT)) {
647 strcat(buf, "Shift+");
648 }
649 }
650 else
651 shortcut = toupper (shortcut);
652
653 int len = strlen(buf);
654 buf[len] = shortcut;
655 }
656 else
657 {
658 // translate NVK
659 const char * szNVK = (const char *) NULL;
660
661 // TODO: look these up from table, rather than switch
662 switch(EV_NamedKey(shortcut))
663 {
664 case EV_NVK_DELETE:
665 szNVK = "Del";
666 break;
667
668 case EV_NVK_F1:
669 szNVK = "F1";
670 break;
671
672 case EV_NVK_F3:
673 szNVK = "F3";
674 break;
675
676 case EV_NVK_F4:
677 szNVK = "F4";
678 break;
679
680 case EV_NVK_F7:
681 szNVK = "F7";
682 break;
683
684 case EV_NVK_F10:
685 szNVK = "F10";
686 break;
687
688 case EV_NVK_F11:
689 szNVK = "F11";
690 break;
691
692 case EV_NVK_F12:
693 szNVK = "F12";
694 break;
695
696 default:
697 szNVK = "unmapped NVK";
698 break;
699 }
700
701 strcat(buf, szNVK);
702 }
703
704 return buf;
705 }
706
parseEditBinding(void)707 bool EV_EditBindingMap::parseEditBinding(void /*const char * szAscii*/)
708 {
709 /* TODO here we import a binding from a primitive ascii format
710 ** TODO or XML syntax.
711 */
712 /*
713 The Ascii format is close to the definition in wp/ap/xp/ap_LB_Default.cpp
714 Lines beginning with "//" are comments
715
716 Each CR seperated lines define a set of bindings for a single mouse context or
717 key stroke. Entries are seperated by commas. In creating the context, several
718 modifiers can be used. Control, Alt, Shift, Control-Alt (C, A, S )
719
720 The first token of each line determines whether the defintion is for mouse context (mse), Named Virtual Key (nvk), or keystroke (key).
721
722 The definition of each set of bindings are always in the following order for
723 mouse contexts.
724
725 Up to to 6 buttons are available for the mouse. (B0, B1, B2, B3, B4, B5, B6)
726 The follow contexts are available:
727
728 Short cut C++ enum
729 ========= =========
730 CU EV_EMC_UNKNOWN
731 CT EV_EMC_TEXT
732 CM EV_EMC_MISSPELLEDTEXT
733 CL EV_EMC_LEFTOFTEXT
734 CR EV_EMC_RIGHTOFTEXT
735 CI EV_EMC_IMAGE
736 CZ EV_EMC_IMAGESIZE
737 CF EV_EMC_FIELD
738 CH EV_EMC_HYPERLINK
739 CV EV_EMC_REVISION
740 CTV EV_EMC_VLINE
741 CTH EV_EMC_HLINE
742 CTF EV_EMC_FRAME
743 CVD EV_EMC_VISUALTEXTDRAG
744 CTC EV_EMC_TOPCELL
745 CTO EV_EMC_TOC
746 CPO EV_EMC_POSOBJECT
747 CMA EV_EMC_MATH
748 CEM EV_EMC_EMBED
749
750 mse, Button, context, click, dblclick, drag, dbldrag, release, double release
751
752 The first 3 entries describe the combination of buttons and context, the six entries that follow are the names of the EditMethods that called for each invocation of the mouse button and context.
753
754 So some examples are:
755
756 mse, B0, CU , , , cursorDefault, , ,
757 mse, B0, CEM , , , btn0InlineImage , ,
758 mse, B1, CVD , cutVisualText, copyVisualText, dragVisualText, dragVisualText, dragVisualText, pasteVisualText
759 mse, B1, CVD C ,copyVisualText,cutVisualText,dragVisualText,dragVisualText, pasteVisualText,pasteVisualText
760
761 //
762 // mse/NVK/Key
763 // NVK, Key Name, No modifier, S, C, S C,A , A S, A C, A C S
764 //
765 NVK, EV_NVK_BACKSPACE, delLeft,delLeft,delBOW, , , , ,
766 //
767 // key, Key Value, No modifier, C, A, A C
768 //
769 key, 0x41, insertData, selectAll, ,
770 */
771
772 return false;
773 }
774