1 /***************************************************************************
2  *   Copyright (C) 2015 Hendrik Vennekate                                  *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
18  ***************************************************************************/
19 #include "reactionarrowaction.h"
20 #include "arrow.h"
21 #include "molscene.h"
22 #include "commands.h"
23 #include <QDebug>
24 #include <QGraphicsSceneMouseEvent>
25 
26 namespace Molsketch {
27 
28   class reactionArrowAction::privateData
29   {
30   public:
privateData(QObject * parent)31     privateData(QObject* parent)
32 #define ARROWACTION(NAME,DESCRIPTION,ICON) NAME(new QAction(QIcon(":images/" ICON ".svg"), tr(DESCRIPTION), parent))
33       : ARROWACTION(normalArrow, "Single arrow", "simplearrow"),
34         ARROWACTION(doubleArrow, "Double arrow", "doublearrow"),
35         ARROWACTION(hookArrow, "Half arrow", "halfarrow"),
36         currentArrow(0)
37     {}
~privateData()38     ~privateData()
39     {
40     }
41     QAction *normalArrow,
42     *doubleArrow,
43     *hookArrow ;
44     Arrow* currentArrow ;
45     QPointF mousePressPosition;
46   };
47 
reactionArrowAction(MolScene * scene)48   reactionArrowAction::reactionArrowAction(MolScene *scene)
49     : multiAction(scene),
50       d(new privateData(this))
51   {
52     setText(tr("Arrow"));
53     addSubAction(d->normalArrow) ;
54     addSubAction(d->doubleArrow) ;
55     addSubAction(d->hookArrow) ;
56   }
57 
~reactionArrowAction()58   reactionArrowAction::~reactionArrowAction()
59   {
60     delete d ;
61   }
62 
mousePressEvent(QGraphicsSceneMouseEvent * event)63   void reactionArrowAction::mousePressEvent(QGraphicsSceneMouseEvent *event)
64   {
65     if (event->button() != Qt::LeftButton) return ;
66     if (event->modifiers() != Qt::NoModifier) return ;
67     event->accept();
68     if (d->currentArrow) delete d->currentArrow ;
69     d->currentArrow = new Arrow() ;
70     if (activeSubAction() == d->doubleArrow)
71       d->currentArrow->setArrowType(Arrow::LowerForward
72                                     | Arrow::UpperForward
73                                     | Arrow::LowerBackward
74                                     | Arrow::UpperBackward);
75     if (activeSubAction() == d->hookArrow)
76       d->currentArrow->setArrowType(Arrow::UpperBackward);
77     d->mousePressPosition = event->scenePos();
78     d->currentArrow->setCoordinates(QVector<QPointF>(2, d->mousePressPosition)) ;
79     scene()->addItem(d->currentArrow) ;
80     scene()->update(d->currentArrow->boundingRect());
81   }
82 
mouseMoveEvent(QGraphicsSceneMouseEvent * event)83   void reactionArrowAction::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
84   {
85     if (!d->currentArrow) return ;
86     event->accept();
87     d->currentArrow->setPoints(
88           makePolygon(QLineF(
89                         d->mousePressPosition, // TODO event->buttonDownScenePos
90                         event->scenePos())));
91     scene()->update(d->currentArrow->boundingRect());
92   }
93 
mouseReleaseEvent(QGraphicsSceneMouseEvent * event)94   void reactionArrowAction::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
95   {
96     if (!d->currentArrow) return ;
97     Commands::ItemAction::addItemToScene(d->currentArrow, scene(), tr("draw arrow")) ;
98     d->currentArrow = 0 ;
99     event->accept();
100   }
101 
makePolygon(const QLineF & line)102   QPolygonF reactionArrowAction::makePolygon(const QLineF &line)
103   {
104     return QPolygonF() << scene()->snapToGrid(line.p1())
105                        << scene()->snapToGrid(line.p2()) ;
106   }
107 
108 } // namespace
109