Engauge Digitizer 2
Loading...
Searching...
No Matches
DigitizeStateContext.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
7#include "CmdMediator.h"
8#include "DigitizeStateAxis.h"
11#include "DigitizeStateCurve.h"
12#include "DigitizeStateEmpty.h"
15#include "DigitizeStateScale.h"
17#include "DigitizeStateSelect.h"
19#include "EngaugeAssert.h"
20#include "GraphicsScene.h"
21#include "GraphicsView.h"
22#include "Logger.h"
23#include "MainWindow.h"
24#include <QCursor>
25#include <QGraphicsScene>
26#include <QGraphicsView>
27#include <QSize>
28#include "QtToString.h"
29#include "Transformation.h"
30
32 QGraphicsView &view,
33 bool isGnuplot) :
34 m_mainWindow (mainWindow),
35 m_view (view),
36 m_imageIsLoaded (false),
37 m_isGnuplot (isGnuplot)
38{
39 // These states follow the same order as the DigitizeState enumeration
40 m_states.insert (DIGITIZE_STATE_AXIS , new DigitizeStateAxis (*this));
41 m_states.insert (DIGITIZE_STATE_COLOR_PICKER, new DigitizeStateColorPicker (*this));
42 m_states.insert (DIGITIZE_STATE_CURVE , new DigitizeStateCurve (*this));
43 m_states.insert (DIGITIZE_STATE_EMPTY , new DigitizeStateEmpty (*this));
44 m_states.insert (DIGITIZE_STATE_POINT_MATCH , new DigitizeStatePointMatch (*this));
45 m_states.insert (DIGITIZE_STATE_SEGMENT , new DigitizeStateSegment (*this));
46 m_states.insert (DIGITIZE_STATE_SELECT , new DigitizeStateSelect (*this));
47 m_states.insert (DIGITIZE_STATE_SCALE , new DigitizeStateScale (*this)); // Out of order since added later
48 m_states.insert (DIGITIZE_STATE_GUIDELINE , new DigitizeStateGuideline (*this)); // Out of order since added later
49 ENGAUGE_ASSERT (m_states.size () == NUM_DIGITIZE_STATES);
50
51 m_currentState = NUM_DIGITIZE_STATES; // Value that forces a transition right away
54}
55
57{
58 qDeleteAll (m_states);
59}
60
62{
63 return m_states [m_currentState]->activeCurve ();
64}
65
67 QUndoCommand *cmd)
68{
69 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::appendNewCmd";
70
71 cmdMediator->push (cmd);
72}
73
75 const QSize &size) const
76{
77 return m_states [m_currentState]->canPaste (transformation,
78 size);
79}
80
81void DigitizeStateContext::completeRequestedStateTransitionIfExists (CmdMediator *cmdMediator)
82{
83 if (m_currentState != m_requestedState) {
84
85 // A transition is waiting so perform it
86
87 if (m_currentState != NUM_DIGITIZE_STATES) {
88
89 // This is not the first state so close the previous state
90 m_states [m_currentState]->end ();
91 }
92
93 // Start the new state
94 DigitizeState previousState = m_currentState;
95 m_currentState = m_requestedState;
96 m_states [m_requestedState]->begin (cmdMediator,
97 previousState);
98
99 // If transition was triggered from inside the state machine then MainWindow controls need to be set accordingly
100 // as if user had clicked on a digitize button
102 }
103}
104
105DigitizeState DigitizeStateContext::digitizeState () const
106{
107 return m_currentState;
108}
109
111{
112 return m_states [m_currentState]->guidelinesAreSelectable();
113}
114
116 const QString &pointIdentifier)
117{
118 m_states [m_currentState]->handleContextMenuEventAxis (cmdMediator,
119 pointIdentifier);
120}
121
123 const QStringList &pointIdentifiers)
124{
125 m_states [m_currentState]->handleContextMenuEventGraph (cmdMediator,
126 pointIdentifiers);
127}
128
130{
131 m_states [m_currentState]->handleCurveChange(cmdMediator);
132}
133
135 Qt::Key key,
136 bool atLeastOneSelectedItem)
137{
138 m_states [m_currentState]->handleKeyPress (cmdMediator,
139 key,
140 atLeastOneSelectedItem);
141
142 completeRequestedStateTransitionIfExists(cmdMediator);
143
144}
145
147 QPointF pos)
148{
149 m_states [m_currentState]->handleMouseMove (cmdMediator,
150 pos);
151
152 completeRequestedStateTransitionIfExists(cmdMediator);
153
154}
155
157 QPointF pos)
158{
159 m_states [m_currentState]->handleMousePress (cmdMediator,
160 pos);
161
162 completeRequestedStateTransitionIfExists(cmdMediator);
163
164}
165
167 QPointF pos)
168{
169 m_states [m_currentState]->handleMouseRelease (cmdMediator,
170 pos);
171
172 completeRequestedStateTransitionIfExists(cmdMediator);
173}
174
176{
177 return m_isGnuplot;
178}
179
181{
182 return m_mainWindow;
183}
184
186{
187 return m_mainWindow;
188}
189
191{
192 m_requestedState = digitizeState;
193}
194
196 DigitizeState digitizeState)
197{
198 m_requestedState = digitizeState;
199 completeRequestedStateTransitionIfExists(cmdMediator);
200}
201
203{
204 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::resetOnLoad";
205
206 // Reset current state. At this point, the current state is DIGITIZE_STATE_EMPTY when opening the first document
207 // so for consistency we always reset it so succeeding documents work the same way
208 if (m_currentState != DIGITIZE_STATE_EMPTY) {
209 m_requestedState = DIGITIZE_STATE_EMPTY;
210 completeRequestedStateTransitionIfExists(cmdMediator);
211 }
212}
213
215{
216 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::setCursor";
217
218 ENGAUGE_ASSERT(m_currentState < m_states.count());
219
220 m_states [m_currentState]->setCursor (cmdMediator);
221}
222
223void DigitizeStateContext::setDragMode (QGraphicsView::DragMode dragMode)
224{
225 LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateContext::setDragMode";
226
227 if (m_imageIsLoaded) {
228 m_view.setDragMode (dragMode);
229 }
230}
231
233 bool imageIsLoaded)
234{
235 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::setImageIsLoaded";
236
237 m_imageIsLoaded = imageIsLoaded;
238 setCursor (cmdMediator);
239}
240
242{
243 ENGAUGE_ASSERT (m_currentState != NUM_DIGITIZE_STATES);
244
245 return m_states [m_currentState]->state();
246}
247
249{
250 ENGAUGE_ASSERT (m_currentState != NUM_DIGITIZE_STATES);
251
252 m_states [m_currentState]->updateAfterPointAddition ();
253}
254
256 const DocumentModelDigitizeCurve &modelDigitizeCurve)
257{
258 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::updateModelDigitizeCurve";
259
260 ENGAUGE_ASSERT(m_currentState < m_states.count());
261
262 m_states [m_currentState]->updateModelDigitizeCurve (cmdMediator,
263 modelDigitizeCurve);
264}
265
267{
268 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::updateModelSegments";
269
270 ENGAUGE_ASSERT(m_currentState < m_states.count());
271
272 m_states [m_currentState]->updateModelSegments (modelSegments);
273}
274
276{
277 return m_view;
278}
DigitizeState
Set of possible states of Digitize toolbar.
@ DIGITIZE_STATE_POINT_MATCH
@ DIGITIZE_STATE_SELECT
@ DIGITIZE_STATE_COLOR_PICKER
@ DIGITIZE_STATE_GUIDELINE
@ NUM_DIGITIZE_STATES
@ DIGITIZE_STATE_CURVE
@ DIGITIZE_STATE_SCALE
@ DIGITIZE_STATE_SEGMENT
@ DIGITIZE_STATE_AXIS
@ DIGITIZE_STATE_EMPTY
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT.
log4cpp::Category * mainCat
Definition Logger.cpp:14
Command queue stack.
Definition CmdMediator.h:24
Digitizing state for digitizing one axis point at a time.
Digitizing state for selecting a color for DigitizeStateSegment.
QString state() const
State name for debugging.
bool isGnuplot() const
Get method for gnuplot flag.
void resetOnLoad(CmdMediator *cmdMediator)
Resetting makes re-initializes for documents after the first.
void handleMouseRelease(CmdMediator *cmdMediator, QPointF pos)
See DigitizeStateAbstractBase::handleMouseRelease.
bool canPaste(const Transformation &transformation, const QSize &viewSize) const
Return true if there is good data in the clipboard for pasting, and that operation is compatible with...
DigitizeStateContext(MainWindow &mainWindow, QGraphicsView &view, bool isGnuplot)
Single constructor.
void handleMouseMove(CmdMediator *cmdMediator, QPointF pos)
See DigitizeStateAbstractBase::handleMouseMove.
void requestImmediateStateTransition(CmdMediator *cmdMediator, DigitizeState digitizeState)
Perform immediate state transition. Called from outside state machine.
void updateModelDigitizeCurve(CmdMediator *cmdMediator, const DocumentModelDigitizeCurve &modelDigitizeCurve)
Update the digitize curve settings.
void handleContextMenuEventGraph(CmdMediator *cmdMediator, const QStringList &pointIdentifiers)
See DigitizeStateAbstractBase::handleContextMenuEventGraph.
void setDragMode(QGraphicsView::DragMode dragMode)
Set QGraphicsView drag mode (in m_view). Called from DigitizeStateAbstractBase subclasses.
void handleMousePress(CmdMediator *cmdMediator, QPointF pos)
See DigitizeStateAbstractBase::handleMousePress.
void appendNewCmd(CmdMediator *cmdMediator, QUndoCommand *cmd)
Append just-created QUndoCommand to command stack. This is called from DigitizeStateAbstractBase subc...
void setCursor(CmdMediator *cmdMediator)
Set cursor after asking state for the new cursor shape.
void setImageIsLoaded(CmdMediator *cmdMediator, bool imageIsLoaded)
Set the image so QGraphicsView cursor and drag mode are accessible.
QString activeCurve() const
Curve name for active Curve. This can include AXIS_CURVE_NAME, and empty string.
void handleKeyPress(CmdMediator *cmdMediator, Qt::Key key, bool atLeastOneSelectedItem)
See DigitizeStateAbstractBase::handleKeyPress.
void updateModelSegments(const DocumentModelSegments &modelSegments)
Update the segments given the new settings.
bool guidelinesAreSelectable() const
Enable/disable guidelines according to state.
void requestDelayedStateTransition(DigitizeState digitizeState)
Initiate state transition to be performed later, when DigitizeState is off the stack.
void updateAfterPointAddition()
Update the graphics attributes.
QGraphicsView & view()
QGraphicsView for use by DigitizeStateAbstractBase subclasses.
void handleCurveChange(CmdMediator *cmdMediator)
See DigitizeStateAbstractBase::handleCurveChange.
MainWindow & mainWindow()
Reference to the MainWindow, without const.
void handleContextMenuEventAxis(CmdMediator *cmdMediator, const QString &pointIdentifier)
See DigitizeStateAbstractBase::handleContextMenuEventAxis.
friend class MainWindow
For CmdAbstract constructor only, via MainWindow, we offer the state to friend class MainWindow.
Digitizing state for creating Curve Points, one at a time.
Digitizing state before a Document has been created. In this state, the cursor is Qt::ArrowCursor.
Digitizing state for creating, moving and removing guidelines.
Digitizing state for matching Curve Points, one at a time.
Digitizing state for creating the scale bar.
Digitizing state for creating multiple Points along a highlighted segment.
Digitizing state for selecting one or more Points in the Document.
Model for DlgSettingsDigitizeCurve and CmdSettingsDigitizeCurve.
Model for DlgSettingsSegments and CmdSettingsSegments.
void updateDigitizeStateIfSoftwareTriggered(DigitizeState digitizeState)
After software-triggered state transition, this method manually triggers the action as if user had cl...
Affine transformation between screen and graph coordinates, based on digitized axis points.
#define LOG4CPP_INFO_S(logger)
Definition convenience.h:18
#define LOG4CPP_DEBUG_S(logger)
Definition convenience.h:20