]> Shamusworld >> Repos - architektonas/blob - src/mainapp/commands.cpp
In the middle of chasing down MDI not activating bug, renaming of Graphic to
[architektonas] / src / mainapp / commands.cpp
1 // commands.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
9 //
10 // JLH = James L. Hammons <jlhamm@acm.org>
11 //
12 // Who  When        What
13 // ---  ----------  -----------------------------------------------------------
14 // JLH  05/17/2010  Added this text. :-)
15 //
16
17 #include "commands.h"
18
19 #include "dialogfactory.h"
20 #include "debug.h"
21
22 // Class variable
23 /*static*/ Commands * Commands::uniqueInstance = NULL;
24
25 /**
26  * Constructor. Initiates main command dictionary.
27  */
28 Commands::Commands()
29 {
30         // This is NOT necessary; we don't take anything out of the hash
31 //      mainCommands.setAutoDelete(true);
32 //      shortCommands.setAutoDelete(true);
33
34         // draw:
35         mainCommands.insert(tr("point"), new RS2::ActionType(RS2::ActionDrawPoint));
36         shortCommands.insert(tr("po"), new RS2::ActionType(RS2::ActionDrawPoint));
37
38         mainCommands.insert(tr("line"), new RS2::ActionType(RS2::ActionDrawLine));
39         shortCommands.insert(tr("ln"), new RS2::ActionType(RS2::ActionDrawLine));
40         shortCommands.insert(tr("l"), new RS2::ActionType(RS2::ActionDrawLine));
41
42         mainCommands.insert(tr("polyline"), new RS2::ActionType(RS2::ActionDrawPolyline));
43
44         mainCommands.insert(tr("offset"), new RS2::ActionType(RS2::ActionDrawLineParallel));
45         shortCommands.insert(tr("o", "offset"), new RS2::ActionType(RS2::ActionDrawLineParallel));
46         mainCommands.insert(tr("parallel"), new RS2::ActionType(RS2::ActionDrawLineParallel));
47         shortCommands.insert(tr("par", "parallel"), new RS2::ActionType(RS2::ActionDrawLineParallel));
48
49         mainCommands.insert(tr("arc"), new RS2::ActionType(RS2::ActionDrawArc3P));
50         shortCommands.insert(tr("a"), new RS2::ActionType(RS2::ActionDrawArc3P));
51
52         mainCommands.insert(tr("circle"), new RS2::ActionType(RS2::ActionDrawCircle));
53         shortCommands.insert(tr("ci"), new RS2::ActionType(RS2::ActionDrawCircle));
54
55         mainCommands.insert(tr("rectangle"), new RS2::ActionType(RS2::ActionDrawLineRectangle));
56         shortCommands.insert(tr("rec"), new RS2::ActionType(RS2::ActionDrawLineRectangle));
57         shortCommands.insert(tr("rectang"), new RS2::ActionType(RS2::ActionDrawLineRectangle));
58
59         mainCommands.insert(tr("polyline"), new RS2::ActionType(RS2::ActionDrawPolyline));
60
61         mainCommands.insert(tr("text"), new RS2::ActionType(RS2::ActionDrawText));
62
63         // zoom:
64         mainCommands.insert(tr("regen"), new RS2::ActionType(RS2::ActionZoomRedraw));
65         shortCommands.insert(tr("rg", "zoom - redraw"), new RS2::ActionType(RS2::ActionZoomRedraw));
66         shortCommands.insert(tr("zr", "zoom - redraw"), new RS2::ActionType(RS2::ActionZoomRedraw));
67
68         mainCommands.insert(tr("zw", "zoom - window"), new RS2::ActionType(RS2::ActionZoomWindow));
69
70         mainCommands.insert(tr("za", "zoom - auto"), new RS2::ActionType(RS2::ActionZoomAuto));
71
72         mainCommands.insert(tr("zp", "zoom - pan"), new RS2::ActionType(RS2::ActionZoomPan));
73
74         mainCommands.insert(tr("zv", "zoom - previous"), new RS2::ActionType(RS2::ActionZoomPrevious));
75
76         // edit:
77         mainCommands.insert(tr("undo"), new RS2::ActionType(RS2::ActionEditUndo));
78         shortCommands.insert(tr("u", "undo"), new RS2::ActionType(RS2::ActionEditUndo));
79
80         mainCommands.insert(tr("redo"), new RS2::ActionType(RS2::ActionEditRedo));
81         shortCommands.insert(tr("r"), new RS2::ActionType(RS2::ActionEditRedo));
82
83         // tools:
84         mainCommands.insert(tr("dimregen"), new RS2::ActionType(RS2::ActionToolRegenerateDimensions));
85 }
86
87 // Destructor needed to clean up memory used by the hash
88 Commands::~Commands()
89 {
90         while (!mainCommands.isEmpty())
91         {
92                 RS2::ActionType * value = *mainCommands.begin();
93                 mainCommands.erase(mainCommands.begin());
94                 delete value;
95         }
96
97         while (!shortCommands.isEmpty())
98         {
99                 RS2::ActionType * value = *shortCommands.begin();
100                 shortCommands.erase(shortCommands.begin());
101                 delete value;
102         }
103 }
104
105 // Class method
106 /**
107  * @return Instance to the unique commands object.
108  */
109 Commands * Commands::instance()
110 {
111         if (uniqueInstance == NULL)
112                 uniqueInstance = new Commands();
113
114         return uniqueInstance;
115 }
116
117 /**
118  * Tries to complete the given command (e.g. when tab is pressed).
119  */
120 QStringList Commands::complete(const QString & cmd)
121 {
122 /*
123  Q3DictIterator<QWidget> i(dict);
124  while (i.current() != 0) {
125      do_something(i.currentKey(), i.current());
126      ++i;
127  }
128
129 Here's the equivalent QHashIterator loop:
130
131  QHashIterator<QString, QWidget *> i(hash);
132  while (i.hasNext()) {
133      i.next();                   // must come first
134      do_something(i.key(), i.value());
135  }
136 */
137 #if 0
138         Q3DictIterator<RS2::ActionType> it(mainCommands);
139         QStringList ret;
140
141         for(; it.current(); ++it)
142         {
143         //cout << it.currentKey() << ": " << it.current()->text() << endl;
144                 if (it.currentKey().startsWith(cmd))
145                         ret << it.currentKey();
146         }
147
148         ret.sort();
149
150         return ret;
151 #else
152         QHashIterator<QString, RS2::ActionType *> it(mainCommands);
153         QStringList ret;
154
155         while (it.hasNext())
156         {
157                 it.next();                                                              // MUST come before access
158
159                 if (it.key().startsWith(cmd))
160                         ret << it.key();
161         }
162
163         ret.sort();
164
165         return ret;
166 #endif
167 }
168
169 /**
170  * @return Command for triggering the given action in the currently chosen
171  * language for commands.
172  *
173  * @param action ID of the action who's command will be returned.
174  * @param num Number of the command. There might be multiple commands
175  *            for the same action (e.g. 'line' and 'l')
176  *
177  * @return The translated command.
178  */
179 RS2::ActionType Commands::cmdToAction(const QString & cmd)
180 {
181     QString c = cmd.toLower();
182     QString full = cmd;          // full command defaults to given command
183     RS2::ActionType ret = RS2::ActionNone;
184
185         // find command:
186 //      RS2::ActionType * retPtr = mainCommands[cmd];
187         RS2::ActionType * retPtr = mainCommands.value(cmd);
188
189         if (retPtr != NULL)
190                 ret = *retPtr;
191         else
192         {
193 //              retPtr = shortCommands[cmd];
194                 retPtr = shortCommands.value(cmd);
195
196                 if (retPtr != NULL)
197                         ret = *retPtr;
198         }
199
200         // find full command to confirm to user:
201 //      Q3DictIterator<RS2::ActionType> it(mainCommands);
202         QHashIterator<QString, RS2::ActionType *> it(mainCommands);
203
204 //      for(; it.current(); ++it)
205         while (it.hasNext())
206         {
207                 it.next();                                                              // MUST come before access
208
209 //              if (*it.current() == ret)
210                 if (*it.value() == ret)
211                 {
212                         if (DialogFactory::instance() != NULL)
213                         {
214                                 //if (DIALOGFACTORY!=NULL) {
215                                 DEBUG->print("Commands::cmdToAction: commandMessage");
216                                         //DIALOGFACTORY->commandMessage(tr("Command: %1")
217                                         //      .arg(full));
218                                 DialogFactory::instance()->commandMessage(tr("Command: %1").arg(full));
219                                 DEBUG->print("Commands::cmdToAction: commandMessage: ok");
220                                 //}
221                         }
222                         else
223                                 DEBUG->print("Commands::cmdToAction: dialog factory instance is NULL");
224
225                         break;
226                 }
227         }
228
229         return ret;
230 }
231
232 /**
233  * Gets the action for the given keycode. A keycode is a sequence
234  * of key-strokes that is entered like hotkeys.
235  */
236 RS2::ActionType Commands::keycodeToAction(const QString & code)
237 {
238         QString c = code.toLower();
239         RS2::ActionType ret = RS2::ActionNone;
240
241         // draw:
242         if (c == tr("po", "point"))
243                 ret = RS2::ActionDrawPoint;
244         else if (c == tr("li", "line"))
245                 ret = RS2::ActionDrawLine;
246         else if (c == tr("pa", "parallel"))
247                 ret = RS2::ActionDrawLine;
248         else if (c == tr("re", "rectangle"))
249                 ret = RS2::ActionDrawLineRectangle;
250         else if (c == tr("rp", "regular polygon"))
251                 ret = RS2::ActionDrawLinePolygon;
252         else if (c == tr("ci", "circle"))
253                 ret = RS2::ActionDrawCircle;
254         else if (c == tr("c2", "2 point circle"))
255                 ret = RS2::ActionDrawCircle2P;
256         else if (c == tr("c3", "3 point circle"))
257                 ret = RS2::ActionDrawCircle3P;
258         else if (c == tr("ar", "arc"))
259                 ret = RS2::ActionDrawArc;
260         else if (c == tr("a3", "3 point arc"))
261                 ret = RS2::ActionDrawArc3P;
262         else if (c == tr("ep", "ellipse"))
263                 ret = RS2::ActionDrawEllipseAxis;
264         else if (c == tr("tx", "text") || c == tr("mt", "text"))
265                 ret = RS2::ActionDrawText;
266
267         // dimensions:
268         else if (c == tr("da", "dimension - aligned"))
269                 ret = RS2::ActionDimAligned;
270         else if (c == tr("dh", "dimension - horizontal"))
271                 ret = RS2::ActionDimLinearHor;
272         else if (c == tr("dv", "dimension - vertical"))
273                 ret = RS2::ActionDimLinearVer;
274         else if (c == tr("dr", "dimension - linear"))
275                 ret = RS2::ActionDimLinear;
276         else if (c == tr("ld", "dimension - leader"))
277                 ret = RS2::ActionDimLeader;
278
279         // zoom:
280         else if (c == tr("rd", "redraw"))
281                 ret = RS2::ActionZoomRedraw;
282         else if (c == tr("zw", "zoom - window"))
283                 ret = RS2::ActionZoomWindow;
284         else if (c == tr("za", "zoom - auto"))
285                 ret = RS2::ActionZoomAuto;
286         else if (c == tr("zi", "zoom - in"))
287                 ret = RS2::ActionZoomIn;
288         else if (c == tr("zo", "zoom - out"))
289                 ret = RS2::ActionZoomOut;
290         else if (c == tr("zp", "zoom - pan"))
291                 ret = RS2::ActionZoomPan;
292         else if (c == tr("zv", "zoom - previous"))
293                 ret = RS2::ActionZoomPrevious;
294
295         // snap:
296         else if (c == tr("os", "snap - none"))
297                 ret = RS2::ActionSnapFree;
298         else if (c == tr("sg", "snap - grid"))
299                 ret = RS2::ActionSnapGrid;
300         else if (c == tr("se", "snap - end"))
301                 ret = RS2::ActionSnapEndpoint;
302         else if (c == tr("si", "snap - intersection"))
303                 ret = RS2::ActionSnapIntersection;
304         else if (c == tr("sn", "snap - center"))
305                 ret = RS2::ActionSnapCenter;
306         else if (c == tr("sm", "snap - middle"))
307                 ret = RS2::ActionSnapMiddle;
308         else if (c == tr("sn", "snap - nearest"))
309                 ret = RS2::ActionSnapMiddle;
310         else if (c == tr("np", "snap - nearest point"))
311                 ret = RS2::ActionSnapOnEntity;
312
313         // layer:
314         else if (c == tr("fr*", "layers - freeze all"))
315                 ret = RS2::ActionLayersFreezeAll;
316         else if (c == tr("th*", "layers - defreeze all"))
317                 ret = RS2::ActionLayersDefreezeAll;
318
319         // selection:
320         else if (c == tr("tn", "Deselect all"))
321                 ret = RS2::ActionDeselectAll;
322
323         // modify:
324         else if (c == tr("ch", "modify - bevel (chamfer)"))
325                 ret = RS2::ActionModifyBevel;
326         else if (c == tr("tm", "modify - multi trim (extend)"))
327                 ret = RS2::ActionModifyTrim2;
328         else if (c == tr("xt", "modify - trim (extend)"))
329                 ret = RS2::ActionModifyTrim;
330         else if (c == tr("rm", "modify - trim"))
331                 ret = RS2::ActionModifyTrim;
332         else if (c == tr("mv", "modify - move"))
333                 ret = RS2::ActionModifyMove;
334         else if (c == tr("mi", "modify - mirror"))
335                 ret = RS2::ActionModifyMirror;
336         else if (c == tr("ro", "modify - rotate"))
337                 ret = RS2::ActionModifyRotate;
338         else if (c == tr("sz", "modify - scale"))
339                 ret = RS2::ActionModifyMove;
340         else if (c == tr("ss", "modify - stretch"))
341                 ret = RS2::ActionModifyStretch;
342         else if (c == tr("er", "modify - delete (erase)"))
343                 ret = RS2::ActionModifyDelete;
344         else if (c == tr("oo", "modify - undo (oops)"))
345                 ret = RS2::ActionEditUndo;
346         else if (c == tr("uu", "modify - redo"))
347                 ret = RS2::ActionEditRedo;
348         else if (c == tr("xp", "modify - explode") || c == tr("ex", "modify - explode"))
349                 ret = RS2::ActionBlocksExplode;
350
351         return ret;
352 }
353
354 /**
355  * @return translated command for the given English command.
356  */
357 QString Commands::command(const QString & cmd)
358 {
359         if (cmd == "angle")
360                 return tr("angle");
361         else if (cmd == "close")
362                 return tr("close");
363         else if (cmd == "chord length")
364                 return tr("chord length");
365         else if (cmd == "columns")
366                 return tr("columns");
367         else if (cmd == "columnspacing")
368                 return tr("columnspacing");
369         else if (cmd == "factor")
370                 return tr("factor");
371         else if (cmd == "length")
372                 return tr("length");
373         else if (cmd == "length1")
374                 return tr("length1");
375         else if (cmd == "length2")
376                 return tr("length2");
377         else if (cmd == "number")
378                 return tr("number");
379         else if (cmd == "radius")
380                 return tr("radius");
381         else if (cmd == "rows")
382                 return tr("rows");
383         else if (cmd == "rowspacing")
384                 return tr("rowspacing");
385         else if (cmd == "text")
386                 return tr("text");
387         else if (cmd == "through")
388                 return tr("through");
389         else if (cmd == "trim")
390                 return tr("trim");
391         else if (cmd == "undo")
392                 return tr("undo");
393
394 //      DEBUG->print(Debug::D_WARNING, "Commands::command: command '%s' unknown", cmd.latin1());
395         DEBUG->print(Debug::D_WARNING, "Commands::command: command '%s' unknown", cmd.toLatin1().data());
396         return "";
397 }
398
399 /**
400  * Checks if the given string 'str' matches the given command 'cmd' for action
401  * 'action'.
402  *
403  * @param cmd The command we want to check for (e.g. 'angle').
404  * @param action The action which wants to know.
405  * @param str The string typically entered by the user.
406  */
407 bool Commands::checkCommand(const QString & cmd, const QString & str, RS2::ActionType /*action*/)
408 {
409         QString strl = str.toLower();
410
411         if (cmd == "angle")
412         {
413                 if (strl == tr("angle") || strl == tr("ang", "angle") || strl == tr("a", "angle"))
414                         return true;
415         }
416         else if (cmd == "center")
417         {
418                 if (strl == tr("center") || strl == tr("cen", "center") || strl == tr("c", "center"))
419                         return true;
420         }
421         else if (cmd == "chord length")
422         {
423                 if (strl == tr("length", "chord length") || strl == tr("l", "chord length"))
424                         return true;
425         }
426         else if (cmd == "close")
427         {
428                 if (strl == tr("close") || strl == tr("c", "close"))
429                         return true;
430         }
431         else if (cmd == "columns")
432         {
433                 if (strl == tr("columns") || strl == tr("cols", "columns") || strl == tr("c", "columns"))
434                         return true;
435         }
436         else if (cmd == "columnspacing")
437         {
438                 if (strl == tr("columnspacing", "columnspacing for inserts")
439                         || strl == tr("colspacing", "columnspacing for inserts")
440                         || strl == tr("cs", "columnspacing for inserts"))
441                         return true;
442         }
443         else if (cmd == "factor")
444         {
445                 if (strl == tr("factor") || strl == tr("fact", "factor") || strl == tr("f", "factor"))
446                         return true;
447         }
448         else if (cmd == "help")
449         {
450                 if (strl == tr("help") || strl == tr("?", "help"))
451                         return true;
452         }
453         else if (cmd == "length")
454         {
455                 if (strl == tr("length", "length") || strl == tr("len", "length") || strl == tr("l", "length"))
456                         return true;
457         }
458         else if (cmd == "length1")
459         {
460                 if (strl == tr("length1", "length1") || strl == tr("len1", "length1")
461                         || strl == tr("l1", "length1"))
462                         return true;
463         }
464         else if (cmd == "length2")
465         {
466                 if (strl == tr("length2", "length2") || strl == tr("len2", "length2")
467                         || strl == tr("l2", "length2"))
468                         return true;
469         }
470         else if (cmd == "number")
471         {
472                 if (strl == tr("number") || strl == tr("num", "number") || strl == tr("n", "number"))
473                         return true;
474         }
475         else if (cmd == "radius")
476         {
477                 if (strl == tr("radius") || strl == tr("r", "radius"))
478                         return true;
479         }
480         else if (cmd == "reversed")
481         {
482                 if (strl == tr("reversed", "reversed arc") || strl == tr("rev", "reversed arc")
483                         || strl == tr("r", "reversed arc"))
484                         return true;
485         }
486         else if (cmd == "rows")
487         {
488                 if (strl == tr("rows") || strl == tr("r", "rows"))
489                         return true;
490         }
491         else if (cmd == "rowspacing")
492         {
493                 if (strl == tr("rowspacing", "rowspacing for inserts")
494                         || strl == tr("rs", "rowspacing for inserts"))
495                         return true;
496         }
497         else if (cmd == "text")
498         {
499                 if (strl == tr("text") || strl == tr("t", "text"))
500                         return true;
501         }
502         else if (cmd == "through")
503         {
504                 if (strl == tr("through") || strl == tr("t", "through"))
505                         return true;
506         }
507         else if (cmd == "undo")
508         {
509                 if (strl == tr("undo") || strl == tr("u", "undo"))
510                         return true;
511         }
512
513         return false;
514 }
515
516 /**
517  * @return the local translation for "Commands available:".
518  */
519 QString Commands::msgAvailableCommands()
520 {
521         return tr("Available commands:");
522 }