1
/****************************************************************************
3
** This file is part of the LibreCAD project, a 2D CAD program
5
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
9
** This file may be distributed and/or modified under the terms of the
10
** GNU General Public License version 2 as published by the Free Software
11
** Foundation and appearing in the file gpl-2.0.txt included in the
12
** packaging of this file.
14
** This program is distributed in the hope that it will be useful,
15
** but WITHOUT ANY WARRANTY; without even the implied warranty of
16
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
** GNU General Public License for more details.
19
** You should have received a copy of the GNU General Public License
20
** along with this program; if not, write to the Free Software
21
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
** This copyright notice MUST APPEAR in all copies of the script!
25
**********************************************************************/
28
#include "rs_eventhandler.h"
30
#include "rs_actioninterface.h"
31
#include "rs_dialogfactory.h"
32
#include "rs_commandevent.h"
37
RS_EventHandler::RS_EventHandler(RS_GraphicView* graphicView) {
38
this->graphicView = graphicView;
40
currentActions.clear();
41
// for (int i=0; i<RS_MAXACTIONS; ++i) {
42
// currentActions[i] = NULL;
44
coordinateInputEnabled = true;
53
RS_EventHandler::~RS_EventHandler() {
54
RS_DEBUG->print("RS_EventHandler::~RS_EventHandler");
55
if (defaultAction!=NULL) {
56
defaultAction->finish();
61
RS_DEBUG->print("RS_EventHandler::~RS_EventHandler: Deleting all actions..");
62
for(int i=0; i< currentActions.size();i++){
63
// currentActions[i]->finish(false);
64
delete currentActions[i];
66
// for (int i=0; i<RS_MAXACTIONS; ++i) {
67
// if (currentActions[i]!=NULL) {
68
// currentActions[i]->setFinished();
72
RS_DEBUG->print("RS_EventHandler::~RS_EventHandler: Deleting all actions..: OK");
73
RS_DEBUG->print("RS_EventHandler::~RS_EventHandler: OK");
78
* Go back in current action.
80
void RS_EventHandler::back() {
81
QMouseEvent e(QEvent::MouseButtonRelease, QPoint(0,0),
82
Qt::RightButton, Qt::RightButton,Qt::NoModifier);
83
mouseReleaseEvent(&e);
89
* Go enter pressed event for current action.
91
void RS_EventHandler::enter() {
92
QKeyEvent e(QEvent::KeyPress, Qt::Key_Enter, 0);
98
* Called by RS_GraphicView
100
void RS_EventHandler::mousePressEvent(QMouseEvent* e) {
102
currentActions.last()->mousePressEvent(e);
105
if (defaultAction!=NULL) {
106
defaultAction->mousePressEvent(e);
109
RS_DEBUG->print("currently no action defined");
118
* Called by RS_GraphicView
120
void RS_EventHandler::mouseReleaseEvent(QMouseEvent* e) {
122
// if (actionIndex>=0 && currentActions[actionIndex]!=NULL &&
123
// !currentActions[actionIndex]->isFinished()) {
124
RS_DEBUG->print("call action %s",
125
currentActions.last()->getName().toLatin1().data());
127
currentActions.last()->mouseReleaseEvent(e);
129
// Clean up actions - one might be finished now
133
if (defaultAction!=NULL) {
134
defaultAction->mouseReleaseEvent(e);
144
* Called by RS_GraphicView
146
void RS_EventHandler::mouseMoveEvent(QMouseEvent* e) {
148
currentActions.last()->mouseMoveEvent(e);
151
if (defaultAction!=NULL) {
152
defaultAction->mouseMoveEvent(e);
157
//RS_DEBUG->print("currently no action defined");
164
* Called by RS_GraphicView
166
void RS_EventHandler::mouseLeaveEvent() {
169
currentActions.last()->suspend();
171
if (defaultAction!=NULL) {
172
defaultAction->suspend();
174
//RS_DEBUG->print("currently no action defined");
181
* Called by RS_GraphicView
183
void RS_EventHandler::mouseEnterEvent() {
186
currentActions.last()->resume();
188
if (defaultAction!=NULL) {
189
defaultAction->resume();
197
* Called by RS_GraphicView
199
void RS_EventHandler::keyPressEvent(QKeyEvent* e) {
202
currentActions.last()->keyPressEvent(e);
204
if (defaultAction!=NULL) {
205
defaultAction->keyPressEvent(e);
211
//RS_DEBUG->print("currently no action defined");
218
* Called by RS_GraphicView
220
void RS_EventHandler::keyReleaseEvent(QKeyEvent* e) {
223
currentActions.last()->keyReleaseEvent(e);
225
if (defaultAction!=NULL) {
226
defaultAction->keyReleaseEvent(e);
231
//RS_DEBUG->print("currently no action defined");
238
* Handles command line events.
240
void RS_EventHandler::commandEvent(RS_CommandEvent* e) {
241
RS_DEBUG->print("RS_EventHandler::commandEvent");
243
QString cmd = e->getCommand();
245
if (coordinateInputEnabled) {
246
if (!e->isAccepted()) {
249
// handle absolute cartesian coordinate input:
250
if (cmd.contains(',') && cmd.at(0)!='@') {
252
int commaPos = cmd.indexOf(',');
253
RS_DEBUG->print("RS_EventHandler::commandEvent: 001");
255
RS_DEBUG->print("RS_EventHandler::commandEvent: 002");
256
double x = RS_Math::eval(cmd.left(commaPos), &ok1);
257
RS_DEBUG->print("RS_EventHandler::commandEvent: 003a");
258
double y = RS_Math::eval(cmd.mid(commaPos+1), &ok2);
259
RS_DEBUG->print("RS_EventHandler::commandEvent: 004");
262
RS_DEBUG->print("RS_EventHandler::commandEvent: 005");
263
RS_CoordinateEvent ce(RS_Vector(x,y));
264
RS_DEBUG->print("RS_EventHandler::commandEvent: 006");
265
currentActions.last()->coordinateEvent(&ce);
267
if (RS_DIALOGFACTORY!=NULL) {
268
RS_DIALOGFACTORY->commandMessage(
269
"Expression Syntax Error");
275
// handle relative cartesian coordinate input:
276
if (!e->isAccepted()) {
277
if (cmd.contains(',') && cmd.at(0)=='@') {
278
int commaPos = cmd.indexOf(',');
280
double x = RS_Math::eval(cmd.mid(1, commaPos-1), &ok1);
281
double y = RS_Math::eval(cmd.mid(commaPos+1), &ok2);
284
RS_CoordinateEvent ce(RS_Vector(x,y) +
285
graphicView->getRelativeZero());
287
currentActions.last()->coordinateEvent(&ce);
288
// currentActions[actionIndex]->coordinateEvent(&ce);
290
if (RS_DIALOGFACTORY!=NULL) {
291
RS_DIALOGFACTORY->commandMessage(
292
"Expression Syntax Error");
299
// handle absolute polar coordinate input:
300
if (!e->isAccepted()) {
301
if (cmd.contains('<') && cmd.at(0)!='@') {
302
int commaPos = cmd.indexOf('<');
304
double r = RS_Math::eval(cmd.left(commaPos), &ok1);
305
double a = RS_Math::eval(cmd.mid(commaPos+1), &ok2);
309
pos.setPolar(r,RS_Math::deg2rad(a));
310
RS_CoordinateEvent ce(pos);
311
currentActions.last()->coordinateEvent(&ce);
313
if (RS_DIALOGFACTORY!=NULL) {
314
RS_DIALOGFACTORY->commandMessage(
315
"Expression Syntax Error");
322
// handle relative polar coordinate input:
323
if (!e->isAccepted()) {
324
if (cmd.contains('<') && cmd.at(0)=='@') {
325
int commaPos = cmd.indexOf('<');
327
double r = RS_Math::eval(cmd.mid(1, commaPos-1), &ok1);
328
double a = RS_Math::eval(cmd.mid(commaPos+1), &ok2);
332
pos.setPolar(r,RS_Math::deg2rad(a));
333
RS_CoordinateEvent ce(pos +
334
graphicView->getRelativeZero());
335
currentActions.last()->coordinateEvent(&ce);
337
if (RS_DIALOGFACTORY!=NULL) {
338
RS_DIALOGFACTORY->commandMessage(
339
"Expression Syntax Error");
346
// send command event directly to current action:
347
if (!e->isAccepted()) {
348
// std::cout<<"RS_EventHandler::commandEvent(RS_CommandEvent* e): sending cmd("<<qPrintable(e->getCommand()) <<") to action: "<<currentActions.last()->rtti()<<std::endl;
349
currentActions.last()->commandEvent(e);
352
//send the command to default action
353
if (defaultAction!=NULL) {
354
defaultAction->commandEvent(e);
357
// do not accept command here. Actions themselves should be responsible to accept commands
362
RS_DEBUG->print("RS_EventHandler::commandEvent: OK");
368
* Enables coordinate input in the command line.
370
void RS_EventHandler::enableCoordinateInput() {
371
coordinateInputEnabled = true;
377
* Enables coordinate input in the command line.
379
void RS_EventHandler::disableCoordinateInput() {
380
coordinateInputEnabled = false;
386
* @return Current action.
388
RS_ActionInterface* RS_EventHandler::getCurrentAction() {
390
return currentActions.last();
392
return defaultAction;
399
* @return The current default action.
401
RS_ActionInterface* RS_EventHandler::getDefaultAction() {
402
return defaultAction;
408
* Sets the default action.
410
void RS_EventHandler::setDefaultAction(RS_ActionInterface* action) {
411
if (defaultAction!=NULL) {
412
defaultAction->finish();
413
delete defaultAction;
414
// defaultAction = NULL;
417
defaultAction = action;
423
* Sets the current action.
425
void RS_EventHandler::setCurrentAction(RS_ActionInterface* action) {
426
RS_DEBUG->print("RS_EventHandler::setCurrentAction");
431
// Predecessor of the new action or NULL:
432
RS_ActionInterface* predecessor = NULL;
434
// Suspend current action:
436
predecessor = currentActions.last();
437
predecessor->suspend();
438
predecessor->hideOptions();
441
if (defaultAction!=NULL) {
442
predecessor = defaultAction;
443
predecessor->suspend();
444
predecessor->hideOptions();
448
// // Forget about the oldest action and make space for the new action:
449
// if (actionIndex==RS_MAXACTIONS-1) {
450
// // delete oldest action if necessary (usually never happens):
451
// if (currentActions[0]!=NULL) {
452
// currentActions[0]->finish();
453
// delete currentActions[0];
454
// currentActions[0] = NULL;
456
// // Move up actionstack (optimize):
457
// for (int i=0; i<RS_MAXACTIONS-1; ++i) {
458
// currentActions[i] = currentActions[i+1];
460
// } else if (actionIndex<RS_MAXACTIONS-1) {
464
// Set current action:
465
currentActions.push_back(action);
466
RS_DEBUG->print("RS_EventHandler::setCurrentAction: current action is: %s",
467
currentActions.last()->getName().toLatin1().data());
469
// Initialisation of our new action:
470
RS_DEBUG->print("RS_EventHandler::setCurrentAction: init current action");
473
if (action->isFinished()==false) {
474
RS_DEBUG->print("RS_EventHandler::setCurrentAction: show options");
475
currentActions.last()->showOptions();
476
RS_DEBUG->print("RS_EventHandler::setCurrentAction: set predecessor");
477
action->setPredecessor(predecessor);
480
RS_DEBUG->print("RS_EventHandler::setCurrentAction: cleaning up..");
483
RS_DEBUG->print("RS_EventHandler::setCurrentAction: debugging actions");
485
RS_DEBUG->print("RS_GraphicView::setCurrentAction: OK");
491
* Kills all running selection actions. Called when a selection action
492
* is launched to reduce confusion.
494
void RS_EventHandler::killSelectActions() {
496
for (auto it=currentActions.begin();it != currentActions.end();){
497
if ((*it)->rtti()==RS2::ActionSelectSingle ||
498
(*it)->rtti()==RS2::ActionSelectContour ||
499
(*it)->rtti()==RS2::ActionSelectWindow ||
500
(*it)->rtti()==RS2::ActionSelectIntersected ||
501
(*it)->rtti()==RS2::ActionSelectLayer) {
502
if( ! (*it)->isFinished()){
506
it= currentActions.erase(it);
516
* Kills all running actions. Called when a window is closed.
518
void RS_EventHandler::killAllActions() {
520
while(currentActions.size()>0){
521
if ( ! currentActions.first()->isFinished() ){
522
currentActions.first()->finish();
524
//need to check the size again after finish(), bug#3451525, 3451415
525
if(currentActions.size()==0) return;
526
delete currentActions.takeFirst();
528
// if(defaultAction->rtti() == RS2::ActionDefault){
531
//cleanup default action, issue#285
532
defaultAction->init(0);
538
* @return true if the action is within currentActions
540
bool RS_EventHandler::isValid(RS_ActionInterface* action){
541
return currentActions.indexOf(action) >= 0;
545
* @return true if there is at least one action in the action stack.
547
bool RS_EventHandler::hasAction() {
549
while(currentActions.size()>0 ) {
550
if(! currentActions.last()->isFinished()){
553
delete currentActions.last();
554
currentActions.pop_back();
562
* Garbage collector for actions.
564
void RS_EventHandler::cleanUp() {
565
RS_DEBUG->print("RS_EventHandler::cleanUp");
567
for (auto it=currentActions.begin();it != currentActions.end();){
569
if( (*it)->isFinished()){
572
it= currentActions.erase(it);
578
currentActions.last()->resume();
579
currentActions.last()->showOptions();
581
if (defaultAction!=NULL) {
582
defaultAction->resume();
583
defaultAction->showOptions();
586
RS_DEBUG->print("RS_EventHandler::cleanUp: OK");
592
* Sets the snap mode for all currently active actions.
594
void RS_EventHandler::setSnapMode(RS_SnapMode sm) {
595
for (auto it=currentActions.begin();it != currentActions.end();it++){
596
if(! (*it)->isFinished()){
597
(*it)->setSnapMode(sm);
601
if (defaultAction!=NULL) {
602
defaultAction->setSnapMode(sm);
608
* Sets the snap restriction for all currently active actions.
610
void RS_EventHandler::setSnapRestriction(RS2::SnapRestriction sr) {
611
for (auto it=currentActions.begin();it != currentActions.end();it++){
612
if(! (*it)->isFinished()){
613
(*it)->setSnapRestriction(sr);
617
if (defaultAction!=NULL) {
618
defaultAction->setSnapRestriction(sr);
623
void RS_EventHandler::debugActions() {
624
// std::cout<<"action queue size=:"<<currentActions.size()<<std::endl;
625
RS_DEBUG->print("---");
626
for(int i=0;i<currentActions.size();i++){
628
if (i == currentActions.size() - 1 ) {
629
RS_DEBUG->print("Current");
631
RS_DEBUG->print("Action %03d: %s [%s]",
632
i, currentActions.at(i)->getName().toLatin1().data(),
633
currentActions.at(i)->isFinished() ? "finished" : "active");