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
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 05/28/2010 Added this text. :-)
17 // This is only used by the GraphicView class...
19 #include "eventhandler.h"
21 #include "actioninterface.h"
22 #include "commandevent.h"
24 #include "dialogfactory.h"
25 #include "graphicview.h"
26 #include "mathextra.h"
31 EventHandler::EventHandler()://GraphicView * graphicView)
32 defaultAction(NULL), actionIndex(-1), coordinateInputEnabled(true)
34 // this->graphicView = graphicView;
37 for(int i=0; i<RS_MAXACTIONS; i++)
38 currentActions[i] = NULL;
40 // coordinateInputEnabled = true;
41 // defaultAction = NULL;
47 EventHandler::~EventHandler()
49 DEBUG->print("EventHandler::~EventHandler");
53 defaultAction->finish();
60 DEBUG->print("EventHandler::~EventHandler: Deleting all actions..");
62 for(int i=0; i<RS_MAXACTIONS; ++i)
64 if (currentActions[i] != NULL)
66 currentActions[i]->setFinished();
67 //delete currentActions[i];
68 //currentActions[i] = NULL;
73 DEBUG->print("EventHandler::~EventHandler: Deleting all actions..: OK");
74 DEBUG->print("EventHandler::~EventHandler: OK");
78 * Go back in current action.
80 void EventHandler::Back()
82 QMouseEvent e(QEvent::MouseButtonRelease, QPoint(0, 0), Qt::RightButton, Qt::RightButton,
84 MouseReleaseEvent(&e);
88 * Go enter pressed event for current action.
90 void EventHandler::Enter()
92 // QKeyEvent e(QEvent::KeyPress, Qt::Key_Enter, '\n', 0);
93 QKeyEvent e(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier, "\n", false, 0);
98 * Called by GraphicView
100 void EventHandler::MousePressEvent(QMouseEvent * e)
102 if (actionIndex >= 0 && currentActions[actionIndex] != NULL)
104 currentActions[actionIndex]->mousePressEvent(e);
111 defaultAction->mousePressEvent(e);
116 DEBUG->print("currently no action defined");
123 * Called by GraphicView
125 void EventHandler::MouseReleaseEvent(QMouseEvent * e)
127 if (actionIndex >= 0 && currentActions[actionIndex] != NULL
128 && !currentActions[actionIndex]->isFinished())
130 DEBUG->print("call action %s", currentActions[actionIndex]->getName().toLatin1().data());
131 currentActions[actionIndex]->mouseReleaseEvent(e);
133 // Clean up actions - one might be finished now
140 defaultAction->mouseReleaseEvent(e);
147 * Called by GraphicView
149 void EventHandler::MouseMoveEvent(QMouseEvent * e)
151 if (actionIndex >= 0 && currentActions[actionIndex]
152 && !currentActions[actionIndex]->isFinished())
154 currentActions[actionIndex]->mouseMoveEvent(e);
161 defaultAction->mouseMoveEvent(e);
166 //DEBUG->print("currently no action defined");
171 Small problem with this approach: Resumes can happen before suspend actions!
172 This can wreak havoc with things like snapper/preview states and the like...
174 Actually, this stuff seems to be pretty useless. Not sure what is accomplished
175 by this crap. The only thing I can think of is that it would cause a preview
176 to be removed if the mouse goes out of the drawing window, could be a legit
177 purpose but this seems too retarded for that. Why wouldn't you just code that
178 into GraphicView itself and be done with it?
181 * Called by GraphicView
183 void EventHandler::MouseLeaveEvent()
186 if (actionIndex >= 0 && currentActions[actionIndex]
187 && !currentActions[actionIndex]->isFinished())
189 currentActions[actionIndex]->suspend();
194 defaultAction->suspend();
195 //DEBUG->print("currently no action defined");
201 * Called by GraphicView
203 void EventHandler::MouseEnterEvent()
206 if (actionIndex >= 0 && currentActions[actionIndex]
207 && !currentActions[actionIndex]->isFinished())
209 currentActions[actionIndex]->resume();
214 defaultAction->resume();
220 * Called by GraphicView
222 void EventHandler::KeyPressEvent(QKeyEvent * e)
224 if (actionIndex >= 0 && currentActions[actionIndex]
225 && !currentActions[actionIndex]->isFinished())
227 currentActions[actionIndex]->keyPressEvent(e);
232 defaultAction->keyPressEvent(e);
236 //DEBUG->print("currently no action defined");
241 * Called by GraphicView
243 void EventHandler::KeyReleaseEvent(QKeyEvent * e)
245 if (actionIndex >= 0 && currentActions[actionIndex]
246 && !currentActions[actionIndex]->isFinished())
248 currentActions[actionIndex]->keyReleaseEvent(e);
253 defaultAction->keyReleaseEvent(e);
257 //DEBUG->print("currently no action defined");
262 * Handles command line events.
264 void EventHandler::HandleCommandEvent(GraphicView * graphicView, CommandEvent * e)
266 DEBUG->print("EventHandler::commandEvent");
267 QString cmd = e->getCommand();
269 if (coordinateInputEnabled)
271 if (!e->isAccepted())
273 // handle absolute cartesian coordinate input:
274 if (cmd.contains(',') && cmd.at(0) != '@')
276 if (actionIndex >= 0 && currentActions[actionIndex] != NULL
277 && !currentActions[actionIndex]->isFinished())
279 int commaPos = cmd.indexOf(',');
280 DEBUG->print("EventHandler::commandEvent: 001");
282 DEBUG->print("EventHandler::commandEvent: 002");
283 double x = Math::eval(cmd.left(commaPos), &ok1);
284 DEBUG->print("EventHandler::commandEvent: 003a");
285 double y = Math::eval(cmd.mid(commaPos + 1), &ok2);
286 DEBUG->print("EventHandler::commandEvent: 004");
290 DEBUG->print("EventHandler::commandEvent: 006");
292 currentActions[actionIndex]->coordinateEvent(&ce);
297 DIALOGFACTORY->commandMessage("Expression Syntax Error");
305 // handle relative cartesian coordinate input:
306 if (!e->isAccepted())
308 if (cmd.contains(',') && cmd.at(0) == '@')
310 if (actionIndex >= 0 && currentActions[actionIndex] != NULL
311 && !currentActions[actionIndex]->isFinished())
313 int commaPos = cmd.indexOf(',');
315 double x = Math::eval(cmd.mid(1, commaPos - 1), &ok1);
316 double y = Math::eval(cmd.mid(commaPos + 1), &ok2);
320 Vector ce(Vector(x,y) + graphicView->getRelativeZero());
321 currentActions[actionIndex]->coordinateEvent(&ce);
326 DIALOGFACTORY->commandMessage("Expression Syntax Error");
334 // handle absolute polar coordinate input:
335 if (!e->isAccepted())
337 if (cmd.contains('<') && cmd.at(0) != '@')
339 if (actionIndex >= 0 && currentActions[actionIndex] != NULL
340 && !currentActions[actionIndex]->isFinished())
342 int commaPos = cmd.indexOf('<');
344 double r = Math::eval(cmd.left(commaPos), &ok1);
345 double a = Math::eval(cmd.mid(commaPos + 1), &ok2);
350 pos.setPolar(r,Math::deg2rad(a));
351 currentActions[actionIndex]->coordinateEvent(&pos);
356 DIALOGFACTORY->commandMessage("Expression Syntax Error");
364 // handle relative polar coordinate input:
365 if (!e->isAccepted())
367 if (cmd.contains('<') && cmd.at(0) == '@')
369 if (actionIndex >= 0 && currentActions[actionIndex] !=NULL
370 && !currentActions[actionIndex]->isFinished())
372 int commaPos = cmd.indexOf('<');
374 double r = Math::eval(cmd.mid(1, commaPos - 1), &ok1);
375 double a = Math::eval(cmd.mid(commaPos + 1), &ok2);
380 pos.setPolar(r,Math::deg2rad(a));
381 Vector ce(pos + graphicView->getRelativeZero());
382 currentActions[actionIndex]->coordinateEvent(&ce);
387 DIALOGFACTORY->commandMessage("Expression Syntax Error");
396 // Send command event directly to current action:
397 if (!e->isAccepted())
399 if (actionIndex >= 0 && currentActions[actionIndex]
400 && !currentActions[actionIndex]->isFinished())
402 currentActions[actionIndex]->commandEvent(e);
408 defaultAction->commandEvent(e);
412 DEBUG->print("EventHandler::commandEvent: OK");
416 * Enables coordinate input in the command line.
418 void EventHandler::EnableCoordinateInput()
420 coordinateInputEnabled = true;
424 * Enables coordinate input in the command line.
426 void EventHandler::DisableCoordinateInput()
428 coordinateInputEnabled = false;
432 * @return Current action.
434 ActionInterface * EventHandler::GetCurrentAction()
436 if (actionIndex >= 0 && currentActions[actionIndex]
437 && !currentActions[actionIndex]->isFinished())
438 return currentActions[actionIndex];
440 return defaultAction;
444 * @return The current default action.
446 ActionInterface * EventHandler::GetDefaultAction()
448 return defaultAction;
452 * Sets the default action.
454 void EventHandler::SetDefaultAction(ActionInterface * action)
458 defaultAction->finish();
459 delete defaultAction;
460 defaultAction = NULL;
463 defaultAction = action;
467 * Sets the current action.
469 void EventHandler::SetCurrentAction(ActionInterface * action)
471 DEBUG->print("EventHandler::setCurrentAction");
476 // Predecessor of the new action or NULL:
477 ActionInterface * predecessor = NULL;
479 // Suspend current action:
480 if (actionIndex >= 0 && currentActions[actionIndex]
481 && !currentActions[actionIndex]->isFinished())
483 predecessor = currentActions[actionIndex];
484 predecessor->suspend();
485 predecessor->hideOptions();
491 predecessor = defaultAction;
492 predecessor->suspend();
493 predecessor->hideOptions();
497 // Forget about the oldest action and make space for the new action:
498 if (actionIndex == RS_MAXACTIONS - 1)
500 // Delete oldest action if necessary (usually never happens):
501 if (currentActions[0])
503 currentActions[0]->finish();
504 delete currentActions[0];
505 currentActions[0] = NULL;
508 // Move up actionstack (optimize):
509 for(int i=0; i<RS_MAXACTIONS-1; ++i)
510 currentActions[i] = currentActions[i + 1];
512 else if (actionIndex < RS_MAXACTIONS - 1)
515 // Set current action:
516 currentActions[actionIndex] = action;
517 DEBUG->print("EventHandler::setCurrentAction: current action is: %s",
518 currentActions[actionIndex]->getName().toLatin1().data());
520 // Initialisation of our new action:
521 DEBUG->print("EventHandler::setCurrentAction: init current action");
525 if (action->isFinished() == false)
527 DEBUG->print("EventHandler::setCurrentAction: show options");
528 currentActions[actionIndex]->showOptions();
529 DEBUG->print("EventHandler::setCurrentAction: set predecessor");
530 action->setPredecessor(predecessor);
533 DEBUG->print("EventHandler::setCurrentAction: cleaning up..");
536 DEBUG->print("EventHandler::setCurrentAction: debugging actions");
538 DEBUG->print("GraphicView::setCurrentAction: OK");
542 * Kills all running selection actions. Called when a selection action
543 * is launched to reduce confusion.
545 void EventHandler::KillSelectActions()
547 for(int c=0; c<RS_MAXACTIONS; ++c)
549 if (currentActions[c])
551 if (currentActions[c]->rtti() == RS2::ActionSelectSingle
552 || currentActions[c]->rtti() == RS2::ActionSelectContour
553 || currentActions[c]->rtti() == RS2::ActionSelectWindow
554 || currentActions[c]->rtti() == RS2::ActionSelectIntersected
555 || currentActions[c]->rtti() == RS2::ActionSelectLayer)
556 currentActions[c]->finish();
562 * Kills all running actions. Called when a window is closed.
563 * Actually: It does NOTHING
565 void EventHandler::KillAllActions()
568 for (int c=0; c<RS_MAXACTIONS; ++c) {
569 if (currentActions[c]!=NULL) {
570 currentActions[c]->finish();
578 * @return true if there is at least one action in the action stack.
580 bool EventHandler::HasAction()
582 if (actionIndex != -1 || defaultAction)
589 * Garbage collector for actions.
591 void EventHandler::CleanUp()
593 DEBUG->print("EventHandler::cleanUp");
595 int oldIndex = 0; // old index
596 int newIndex = 0; // new index
597 int resume = 0; // index of action to resume
598 bool doResume = false; // do we need to resume an action
605 // Search first used action (oldIndex)
606 while (currentActions[oldIndex] == NULL && oldIndex < RS_MAXACTIONS)
609 // Delete action if it is finished
610 if (oldIndex < RS_MAXACTIONS && currentActions[oldIndex] != NULL
611 && currentActions[oldIndex]->isFinished())
613 delete currentActions[oldIndex];
614 currentActions[oldIndex] = NULL;
618 // Move a running action up in the stack
619 if (oldIndex < RS_MAXACTIONS && currentActions[oldIndex] != NULL)
621 if (newIndex != oldIndex)
623 currentActions[newIndex] = currentActions[oldIndex];
625 currentActions[oldIndex] = NULL;
629 if (oldIndex < RS_MAXACTIONS)
633 actionIndex = newIndex;
635 if (newIndex < RS_MAXACTIONS - 1)
639 while (oldIndex < RS_MAXACTIONS);
643 // Resume last used action:
646 if (currentActions[resume] && !currentActions[resume]->isFinished())
648 currentActions[resume]->resume();
649 currentActions[resume]->showOptions();
655 defaultAction->resume();
656 defaultAction->showOptions();
661 DEBUG->print("EventHandler::cleanUp: OK");
664 void EventHandler::DebugActions()
668 for(int c=0; c<RS_MAXACTIONS; ++c)
670 if (c == actionIndex)
671 DEBUG->print("Current");
673 if (currentActions[c])
674 DEBUG->print("Action %03d: %s [%s]",
675 c, currentActions[c]->getName().toLatin1().data(),
676 currentActions[c]->isFinished() ? "finished" : "active");
678 DEBUG->print("Action %03d: NULL", c);