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 // (C) 2010 Underground Software
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/17/2010 Added this text. :-)
17 #include "rs_dialogfactory.h"
21 Commands * Commands::uniqueInstance = NULL;
24 * Constructor. Initiates main command dictionary.
28 // This is NOT necessary; we don't anything out of the hash
29 // mainCommands.setAutoDelete(true);
30 // shortCommands.setAutoDelete(true);
33 mainCommands.insert(tr("point"), new RS2::ActionType(RS2::ActionDrawPoint));
34 shortCommands.insert(tr("po"), new RS2::ActionType(RS2::ActionDrawPoint));
36 mainCommands.insert(tr("line"), new RS2::ActionType(RS2::ActionDrawLine));
37 shortCommands.insert(tr("ln"), new RS2::ActionType(RS2::ActionDrawLine));
38 shortCommands.insert(tr("l"), new RS2::ActionType(RS2::ActionDrawLine));
40 mainCommands.insert(tr("polyline"), new RS2::ActionType(RS2::ActionDrawPolyline));
42 mainCommands.insert(tr("offset"), new RS2::ActionType(RS2::ActionDrawLineParallel));
43 shortCommands.insert(tr("o", "offset"), new RS2::ActionType(RS2::ActionDrawLineParallel));
44 mainCommands.insert(tr("parallel"), new RS2::ActionType(RS2::ActionDrawLineParallel));
45 shortCommands.insert(tr("par", "parallel"), new RS2::ActionType(RS2::ActionDrawLineParallel));
47 mainCommands.insert(tr("arc"), new RS2::ActionType(RS2::ActionDrawArc3P));
48 shortCommands.insert(tr("a"), new RS2::ActionType(RS2::ActionDrawArc3P));
50 mainCommands.insert(tr("circle"), new RS2::ActionType(RS2::ActionDrawCircle));
51 shortCommands.insert(tr("ci"), new RS2::ActionType(RS2::ActionDrawCircle));
53 mainCommands.insert(tr("rectangle"), new RS2::ActionType(RS2::ActionDrawLineRectangle));
54 shortCommands.insert(tr("rec"), new RS2::ActionType(RS2::ActionDrawLineRectangle));
55 shortCommands.insert(tr("rectang"), new RS2::ActionType(RS2::ActionDrawLineRectangle));
57 mainCommands.insert(tr("polyline"), new RS2::ActionType(RS2::ActionDrawPolyline));
59 mainCommands.insert(tr("text"), new RS2::ActionType(RS2::ActionDrawText));
62 mainCommands.insert(tr("regen"), new RS2::ActionType(RS2::ActionZoomRedraw));
63 shortCommands.insert(tr("rg", "zoom - redraw"), new RS2::ActionType(RS2::ActionZoomRedraw));
64 shortCommands.insert(tr("zr", "zoom - redraw"), new RS2::ActionType(RS2::ActionZoomRedraw));
66 mainCommands.insert(tr("zw", "zoom - window"), new RS2::ActionType(RS2::ActionZoomWindow));
68 mainCommands.insert(tr("za", "zoom - auto"), new RS2::ActionType(RS2::ActionZoomAuto));
70 mainCommands.insert(tr("zp", "zoom - pan"), new RS2::ActionType(RS2::ActionZoomPan));
72 mainCommands.insert(tr("zv", "zoom - previous"), new RS2::ActionType(RS2::ActionZoomPrevious));
75 mainCommands.insert(tr("undo"), new RS2::ActionType(RS2::ActionEditUndo));
76 shortCommands.insert(tr("u", "undo"), new RS2::ActionType(RS2::ActionEditUndo));
78 mainCommands.insert(tr("redo"), new RS2::ActionType(RS2::ActionEditRedo));
79 shortCommands.insert(tr("r"), new RS2::ActionType(RS2::ActionEditRedo));
82 mainCommands.insert(tr("dimregen"), new RS2::ActionType(RS2::ActionToolRegenerateDimensions));
85 // Destructor needed to clean up memory used by the hash
88 while (!mainCommands.isEmpty())
90 RS2::ActionType * value = *mainCommands.begin();
91 mainCommands.erase(mainCommands.begin());
95 while (!shortCommands.isEmpty())
97 RS2::ActionType * value = *shortCommands.begin();
98 shortCommands.erase(shortCommands.begin());
105 * @return Instance to the unique commands object.
107 Commands * Commands::instance()
109 if (uniqueInstance == NULL)
110 uniqueInstance = new Commands();
112 return uniqueInstance;
116 * Tries to complete the given command (e.g. when tab is pressed).
118 QStringList Commands::complete(const QString & cmd)
121 Q3DictIterator<QWidget> i(dict);
122 while (i.current() != 0) {
123 do_something(i.currentKey(), i.current());
127 Here's the equivalent QHashIterator loop:
129 QHashIterator<QString, QWidget *> i(hash);
130 while (i.hasNext()) {
131 i.next(); // must come first
132 do_something(i.key(), i.value());
136 Q3DictIterator<RS2::ActionType> it(mainCommands);
139 for(; it.current(); ++it)
141 //cout << it.currentKey() << ": " << it.current()->text() << endl;
142 if (it.currentKey().startsWith(cmd))
143 ret << it.currentKey();
150 QHashIterator<QString, RS2::ActionType *> it(mainCommands);
155 it.next(); // MUST come before access
157 if (it.key().startsWith(cmd))
168 * @return Command for triggering the given action in the currently chosen
169 * language for commands.
171 * @param action ID of the action who's command will be returned.
172 * @param num Number of the command. There might be multiple commands
173 * for the same action (e.g. 'line' and 'l')
175 * @return The translated command.
177 RS2::ActionType Commands::cmdToAction(const QString & cmd)
179 QString c = cmd.toLower();
180 QString full = cmd; // full command defaults to given command
181 RS2::ActionType ret = RS2::ActionNone;
184 // RS2::ActionType * retPtr = mainCommands[cmd];
185 RS2::ActionType * retPtr = mainCommands.value(cmd);
191 // retPtr = shortCommands[cmd];
192 retPtr = shortCommands.value(cmd);
198 // find full command to confirm to user:
199 // Q3DictIterator<RS2::ActionType> it(mainCommands);
200 QHashIterator<QString, RS2::ActionType *> it(mainCommands);
202 // for(; it.current(); ++it)
205 it.next(); // MUST come before access
207 // if (*it.current() == ret)
208 if (*it.value() == ret)
210 if (RS_DialogFactory::instance() != NULL)
212 //if (RS_DIALOGFACTORY!=NULL) {
213 RS_DEBUG->print("Commands::cmdToAction: commandMessage");
214 //RS_DIALOGFACTORY->commandMessage(tr("Command: %1")
216 RS_DialogFactory::instance()->commandMessage(tr("Command: %1").arg(full));
217 RS_DEBUG->print("Commands::cmdToAction: commandMessage: ok");
221 RS_DEBUG->print("Commands::cmdToAction: dialog factory instance is NULL");
231 * Gets the action for the given keycode. A keycode is a sequence
232 * of key-strokes that is entered like hotkeys.
234 RS2::ActionType Commands::keycodeToAction(const QString & code)
236 QString c = code.toLower();
237 RS2::ActionType ret = RS2::ActionNone;
240 if (c == tr("po", "point"))
241 ret = RS2::ActionDrawPoint;
242 else if (c == tr("li", "line"))
243 ret = RS2::ActionDrawLine;
244 else if (c == tr("pa", "parallel"))
245 ret = RS2::ActionDrawLine;
246 else if (c == tr("re", "rectangle"))
247 ret = RS2::ActionDrawLineRectangle;
248 else if (c == tr("rp", "regular polygon"))
249 ret = RS2::ActionDrawLinePolygon;
250 else if (c == tr("ci", "circle"))
251 ret = RS2::ActionDrawCircle;
252 else if (c == tr("c2", "2 point circle"))
253 ret = RS2::ActionDrawCircle2P;
254 else if (c == tr("c3", "3 point circle"))
255 ret = RS2::ActionDrawCircle3P;
256 else if (c == tr("ar", "arc"))
257 ret = RS2::ActionDrawArc;
258 else if (c == tr("a3", "3 point arc"))
259 ret = RS2::ActionDrawArc3P;
260 else if (c == tr("ep", "ellipse"))
261 ret = RS2::ActionDrawEllipseAxis;
262 else if (c == tr("tx", "text") || c == tr("mt", "text"))
263 ret = RS2::ActionDrawText;
266 else if (c == tr("da", "dimension - aligned"))
267 ret = RS2::ActionDimAligned;
268 else if (c == tr("dh", "dimension - horizontal"))
269 ret = RS2::ActionDimLinearHor;
270 else if (c == tr("dv", "dimension - vertical"))
271 ret = RS2::ActionDimLinearVer;
272 else if (c == tr("dr", "dimension - linear"))
273 ret = RS2::ActionDimLinear;
274 else if (c == tr("ld", "dimension - leader"))
275 ret = RS2::ActionDimLeader;
278 else if (c == tr("rd", "redraw"))
279 ret = RS2::ActionZoomRedraw;
280 else if (c == tr("zw", "zoom - window"))
281 ret = RS2::ActionZoomWindow;
282 else if (c == tr("za", "zoom - auto"))
283 ret = RS2::ActionZoomAuto;
284 else if (c == tr("zi", "zoom - in"))
285 ret = RS2::ActionZoomIn;
286 else if (c == tr("zo", "zoom - out"))
287 ret = RS2::ActionZoomOut;
288 else if (c == tr("zp", "zoom - pan"))
289 ret = RS2::ActionZoomPan;
290 else if (c == tr("zv", "zoom - previous"))
291 ret = RS2::ActionZoomPrevious;
294 else if (c == tr("os", "snap - none"))
295 ret = RS2::ActionSnapFree;
296 else if (c == tr("sg", "snap - grid"))
297 ret = RS2::ActionSnapGrid;
298 else if (c == tr("se", "snap - end"))
299 ret = RS2::ActionSnapEndpoint;
300 else if (c == tr("si", "snap - intersection"))
301 ret = RS2::ActionSnapIntersection;
302 else if (c == tr("sn", "snap - center"))
303 ret = RS2::ActionSnapCenter;
304 else if (c == tr("sm", "snap - middle"))
305 ret = RS2::ActionSnapMiddle;
306 else if (c == tr("sn", "snap - nearest"))
307 ret = RS2::ActionSnapMiddle;
308 else if (c == tr("np", "snap - nearest point"))
309 ret = RS2::ActionSnapOnEntity;
312 else if (c == tr("fr*", "layers - freeze all"))
313 ret = RS2::ActionLayersFreezeAll;
314 else if (c == tr("th*", "layers - defreeze all"))
315 ret = RS2::ActionLayersDefreezeAll;
318 else if (c == tr("tn", "Deselect all"))
319 ret = RS2::ActionDeselectAll;
322 else if (c == tr("ch", "modify - bevel (chamfer)"))
323 ret = RS2::ActionModifyBevel;
324 else if (c == tr("tm", "modify - multi trim (extend)"))
325 ret = RS2::ActionModifyTrim2;
326 else if (c == tr("xt", "modify - trim (extend)"))
327 ret = RS2::ActionModifyTrim;
328 else if (c == tr("rm", "modify - trim"))
329 ret = RS2::ActionModifyTrim;
330 else if (c == tr("mv", "modify - move"))
331 ret = RS2::ActionModifyMove;
332 else if (c == tr("mi", "modify - mirror"))
333 ret = RS2::ActionModifyMirror;
334 else if (c == tr("ro", "modify - rotate"))
335 ret = RS2::ActionModifyRotate;
336 else if (c == tr("sz", "modify - scale"))
337 ret = RS2::ActionModifyMove;
338 else if (c == tr("ss", "modify - stretch"))
339 ret = RS2::ActionModifyStretch;
340 else if (c == tr("er", "modify - delete (erase)"))
341 ret = RS2::ActionModifyDelete;
342 else if (c == tr("oo", "modify - undo (oops)"))
343 ret = RS2::ActionEditUndo;
344 else if (c == tr("uu", "modify - redo"))
345 ret = RS2::ActionEditRedo;
346 else if (c == tr("xp", "modify - explode") || c == tr("ex", "modify - explode"))
347 ret = RS2::ActionBlocksExplode;
353 * @return translated command for the given English command.
355 QString Commands::command(const QString & cmd)
359 else if (cmd == "close")
361 else if (cmd == "chord length")
362 return tr("chord length");
363 else if (cmd == "columns")
364 return tr("columns");
365 else if (cmd == "columnspacing")
366 return tr("columnspacing");
367 else if (cmd == "factor")
369 else if (cmd == "length")
371 else if (cmd == "length1")
372 return tr("length1");
373 else if (cmd == "length2")
374 return tr("length2");
375 else if (cmd == "number")
377 else if (cmd == "radius")
379 else if (cmd == "rows")
381 else if (cmd == "rowspacing")
382 return tr("rowspacing");
383 else if (cmd == "text")
385 else if (cmd == "through")
386 return tr("through");
387 else if (cmd == "trim")
389 else if (cmd == "undo")
392 // RS_DEBUG->print(RS_Debug::D_WARNING, "Commands::command: command '%s' unknown", cmd.latin1());
393 RS_DEBUG->print(RS_Debug::D_WARNING, "Commands::command: command '%s' unknown", cmd.toLatin1().data());
398 * Checks if the given string 'str' matches the given command 'cmd' for action
401 * @param cmd The command we want to check for (e.g. 'angle').
402 * @param action The action which wants to know.
403 * @param str The string typically entered by the user.
405 bool Commands::checkCommand(const QString & cmd, const QString & str, RS2::ActionType /*action*/)
407 QString strl = str.toLower();
411 if (strl == tr("angle") || strl == tr("ang", "angle") || strl == tr("a", "angle"))
414 else if (cmd == "center")
416 if (strl == tr("center") || strl == tr("cen", "center") || strl == tr("c", "center"))
419 else if (cmd == "chord length")
421 if (strl == tr("length", "chord length") || strl == tr("l", "chord length"))
424 else if (cmd == "close")
426 if (strl == tr("close") || strl == tr("c", "close"))
429 else if (cmd == "columns")
431 if (strl == tr("columns") || strl == tr("cols", "columns") || strl == tr("c", "columns"))
434 else if (cmd == "columnspacing")
436 if (strl == tr("columnspacing", "columnspacing for inserts")
437 || strl == tr("colspacing", "columnspacing for inserts")
438 || strl == tr("cs", "columnspacing for inserts"))
441 else if (cmd == "factor")
443 if (strl == tr("factor") || strl == tr("fact", "factor") || strl == tr("f", "factor"))
446 else if (cmd == "help")
448 if (strl == tr("help") || strl == tr("?", "help"))
451 else if (cmd == "length")
453 if (strl == tr("length", "length") || strl == tr("len", "length") || strl == tr("l", "length"))
456 else if (cmd == "length1")
458 if (strl == tr("length1", "length1") || strl == tr("len1", "length1")
459 || strl == tr("l1", "length1"))
462 else if (cmd == "length2")
464 if (strl == tr("length2", "length2") || strl == tr("len2", "length2")
465 || strl == tr("l2", "length2"))
468 else if (cmd == "number")
470 if (strl == tr("number") || strl == tr("num", "number") || strl == tr("n", "number"))
473 else if (cmd == "radius")
475 if (strl == tr("radius") || strl == tr("r", "radius"))
478 else if (cmd == "reversed")
480 if (strl == tr("reversed", "reversed arc") || strl == tr("rev", "reversed arc")
481 || strl == tr("r", "reversed arc"))
484 else if (cmd == "rows")
486 if (strl == tr("rows") || strl == tr("r", "rows"))
489 else if (cmd == "rowspacing")
491 if (strl == tr("rowspacing", "rowspacing for inserts")
492 || strl == tr("rs", "rowspacing for inserts"))
495 else if (cmd == "text")
497 if (strl == tr("text") || strl == tr("t", "text"))
500 else if (cmd == "through")
502 if (strl == tr("through") || strl == tr("t", "through"))
505 else if (cmd == "undo")
507 if (strl == tr("undo") || strl == tr("u", "undo"))
515 * @return the local translation for "Commands available:".
517 QString Commands::msgAvailableCommands()
519 return tr("Available commands:");