Engauge Digitizer  2
DigitizeStateContext.cpp
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"
9 #include "DigitizeStateColorPicker.h"
10 #include "DigitizeStateContext.h"
11 #include "DigitizeStateCurve.h"
12 #include "DigitizeStateEmpty.h"
13 #include "DigitizeStatePointMatch.h"
14 #include "DigitizeStateScale.h"
15 #include "DigitizeStateSegment.h"
16 #include "DigitizeStateSelect.h"
17 #include "DocumentModelSegments.h"
18 #include "EngaugeAssert.h"
19 #include "GraphicsScene.h"
20 #include "GraphicsView.h"
21 #include "Logger.h"
22 #include "MainWindow.h"
23 #include <QCursor>
24 #include <QGraphicsScene>
25 #include <QGraphicsView>
26 #include <QSize>
27 #include "QtToString.h"
28 #include "Transformation.h"
29 
31  QGraphicsView &view,
32  bool isGnuplot) :
33  m_mainWindow (mainWindow),
34  m_view (view),
35  m_imageIsLoaded (false),
36  m_isGnuplot (isGnuplot)
37 {
38  // These states follow the same order as the DigitizeState enumeration
39  m_states.insert (DIGITIZE_STATE_AXIS , new DigitizeStateAxis (*this));
40  m_states.insert (DIGITIZE_STATE_COLOR_PICKER, new DigitizeStateColorPicker (*this));
41  m_states.insert (DIGITIZE_STATE_CURVE , new DigitizeStateCurve (*this));
42  m_states.insert (DIGITIZE_STATE_EMPTY , new DigitizeStateEmpty (*this));
43  m_states.insert (DIGITIZE_STATE_POINT_MATCH , new DigitizeStatePointMatch (*this));
44  m_states.insert (DIGITIZE_STATE_SEGMENT , new DigitizeStateSegment (*this));
45  m_states.insert (DIGITIZE_STATE_SELECT , new DigitizeStateSelect (*this));
46  m_states.insert (DIGITIZE_STATE_SCALE , new DigitizeStateScale (*this)); // Out of order since added later
47  ENGAUGE_ASSERT (m_states.size () == NUM_DIGITIZE_STATES);
48 
49  m_currentState = NUM_DIGITIZE_STATES; // Value that forces a transition right away
51  DIGITIZE_STATE_EMPTY);
52 }
53 
54 DigitizeStateContext::~DigitizeStateContext()
55 {
56 }
57 
59 {
60  return m_states [m_currentState]->activeCurve ();
61 }
62 
64  QUndoCommand *cmd)
65 {
66  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::appendNewCmd";
67 
68  cmdMediator->push (cmd);
69 }
70 
71 bool DigitizeStateContext::canPaste (const Transformation &transformation,
72  const QSize &size) const
73 {
74  return m_states [m_currentState]->canPaste (transformation,
75  size);
76 }
77 
78 void DigitizeStateContext::completeRequestedStateTransitionIfExists (CmdMediator *cmdMediator)
79 {
80  if (m_currentState != m_requestedState) {
81 
82  // A transition is waiting so perform it
83 
84  if (m_currentState != NUM_DIGITIZE_STATES) {
85 
86  // This is not the first state so close the previous state
87  m_states [m_currentState]->end ();
88  }
89 
90  // Start the new state
91  DigitizeState previousState = m_currentState;
92  m_currentState = m_requestedState;
93  m_states [m_requestedState]->begin (cmdMediator,
94  previousState);
95 
96  // If transition was triggered from inside the state machine then MainWindow controls need to be set accordingly
97  // as if user had clicked on a digitize button
99  }
100 }
101 
103  const QString &pointIdentifier)
104 {
105  m_states [m_currentState]->handleContextMenuEventAxis (cmdMediator,
106  pointIdentifier);
107 }
108 
110  const QStringList &pointIdentifiers)
111 {
112  m_states [m_currentState]->handleContextMenuEventGraph (cmdMediator,
113  pointIdentifiers);
114 }
115 
117 {
118  m_states [m_currentState]->handleCurveChange(cmdMediator);
119 }
120 
122  Qt::Key key,
123  bool atLeastOneSelectedItem)
124 {
125  m_states [m_currentState]->handleKeyPress (cmdMediator,
126  key,
127  atLeastOneSelectedItem);
128 
129  completeRequestedStateTransitionIfExists(cmdMediator);
130 
131 }
132 
134  QPointF pos)
135 {
136  m_states [m_currentState]->handleMouseMove (cmdMediator,
137  pos);
138 
139  completeRequestedStateTransitionIfExists(cmdMediator);
140 
141 }
142 
144  QPointF pos)
145 {
146  m_states [m_currentState]->handleMousePress (cmdMediator,
147  pos);
148 
149  completeRequestedStateTransitionIfExists(cmdMediator);
150 
151 }
152 
154  QPointF pos)
155 {
156  m_states [m_currentState]->handleMouseRelease (cmdMediator,
157  pos);
158 
159  completeRequestedStateTransitionIfExists(cmdMediator);
160 }
161 
163 {
164  return m_isGnuplot;
165 }
166 
168 {
169  return m_mainWindow;
170 }
171 
173 {
174  return m_mainWindow;
175 }
176 
177 void DigitizeStateContext::requestDelayedStateTransition (DigitizeState digitizeState)
178 {
179  m_requestedState = digitizeState;
180 }
181 
183  DigitizeState digitizeState)
184 {
185  m_requestedState = digitizeState;
186  completeRequestedStateTransitionIfExists(cmdMediator);
187 }
188 
190 {
191  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::resetOnLoad";
192 
193  // Reset current state. At this point, the current state is DIGITIZE_STATE_EMPTY when opening the first document
194  // so for consistency we always reset it so succeeding documents work the same way
195  if (m_currentState != DIGITIZE_STATE_EMPTY) {
196  m_requestedState = DIGITIZE_STATE_EMPTY;
197  completeRequestedStateTransitionIfExists(cmdMediator);
198  }
199 }
200 
202 {
203  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::setCursor";
204 
205  ENGAUGE_ASSERT(m_currentState < m_states.count());
206 
207  m_states [m_currentState]->setCursor (cmdMediator);
208 }
209 
210 void DigitizeStateContext::setDragMode (QGraphicsView::DragMode dragMode)
211 {
212  LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateContext::setDragMode";
213 
214  if (m_imageIsLoaded) {
215  m_view.setDragMode (dragMode);
216  }
217 }
218 
220  bool imageIsLoaded)
221 {
222  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::setImageIsLoaded";
223 
224  m_imageIsLoaded = imageIsLoaded;
225  setCursor (cmdMediator);
226 }
227 
229 {
230  ENGAUGE_ASSERT (m_currentState != NUM_DIGITIZE_STATES);
231 
232  return m_states [m_currentState]->state();
233 }
234 
236 {
237  ENGAUGE_ASSERT (m_currentState != NUM_DIGITIZE_STATES);
238 
239  m_states [m_currentState]->updateAfterPointAddition ();
240 }
241 
243  const DocumentModelDigitizeCurve &modelDigitizeCurve)
244 {
245  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::updateModelDigitizeCurve";
246 
247  ENGAUGE_ASSERT(m_currentState < m_states.count());
248 
249  m_states [m_currentState]->updateModelDigitizeCurve (cmdMediator,
250  modelDigitizeCurve);
251 }
252 
254 {
255  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::updateModelSegments";
256 
257  ENGAUGE_ASSERT(m_currentState < m_states.count());
258 
259  m_states [m_currentState]->updateModelSegments (modelSegments);
260 }
261 
263 {
264  return m_view;
265 }
void requestDelayedStateTransition(DigitizeState digitizeState)
Initiate state transition to be performed later, when DigitizeState is off the stack.
void updateAfterPointAddition()
Update the graphics attributes.
void resetOnLoad(CmdMediator *cmdMediator)
Resetting makes re-initializes for documents after the first.
Digitizing state for creating the scale bar.
void updateDigitizeStateIfSoftwareTriggered(DigitizeState digitizeState)
After software-triggered state transition, this method manually triggers the action as if user had cl...
void setDragMode(QGraphicsView::DragMode dragMode)
Set QGraphicsView drag mode (in m_view). Called from DigitizeStateAbstractBase subclasses.
void updateModelDigitizeCurve(CmdMediator *cmdMediator, const DocumentModelDigitizeCurve &modelDigitizeCurve)
Update the digitize curve settings.
void handleContextMenuEventAxis(CmdMediator *cmdMediator, const QString &pointIdentifier)
See DigitizeStateAbstractBase::handleContextMenuEventAxis.
void setCursor(CmdMediator *cmdMediator)
Set cursor after asking state for the new cursor shape.
Digitizing state for selecting a color for DigitizeStateSegment.
void handleCurveChange(CmdMediator *cmdMediator)
See DigitizeStateAbstractBase::handleCurveChange.
void handleContextMenuEventGraph(CmdMediator *cmdMediator, const QStringList &pointIdentifiers)
See DigitizeStateAbstractBase::handleContextMenuEventGraph.
QString state() const
State name for debugging.
bool isGnuplot() const
Get method for gnuplot flag.
QString activeCurve() const
Curve name for active Curve. This can include AXIS_CURVE_NAME, and empty string.
Digitizing state before a Document has been created. In this state, the cursor is Qt::ArrowCursor...
CmdMediator * cmdMediator()
Accessor for commands to process the Document.
Definition: MainWindow.cpp:337
void handleKeyPress(CmdMediator *cmdMediator, Qt::Key key, bool atLeastOneSelectedItem)
See DigitizeStateAbstractBase::handleKeyPress.
MainWindow & mainWindow()
Reference to the MainWindow, without const.
void setImageIsLoaded(CmdMediator *cmdMediator, bool imageIsLoaded)
Set the image so QGraphicsView cursor and drag mode are accessible.
Digitizing state for matching Curve Points, one at a time.
Model for DlgSettingsDigitizeCurve and CmdSettingsDigitizeCurve.
Affine transformation between screen and graph coordinates, based on digitized axis points...
Digitizing state for selecting one or more Points in the Document.
void appendNewCmd(CmdMediator *cmdMediator, QUndoCommand *cmd)
Append just-created QUndoCommand to command stack. This is called from DigitizeStateAbstractBase subc...
DigitizeStateContext(MainWindow &mainWindow, QGraphicsView &view, bool isGnuplot)
Single constructor.
void updateModelSegments(const DocumentModelSegments &modelSegments)
Update the segments given the new settings.
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...
void handleMouseMove(CmdMediator *cmdMediator, QPointF pos)
See DigitizeStateAbstractBase::handleMouseMove.
void handleMouseRelease(CmdMediator *cmdMediator, QPointF pos)
See DigitizeStateAbstractBase::handleMouseRelease.
Command queue stack.
Definition: CmdMediator.h:23
Model for DlgSettingsSegments and CmdSettingsSegments.
Digitizing state for creating Curve Points, one at a time.
QGraphicsView & view()
QGraphicsView for use by DigitizeStateAbstractBase subclasses.
void handleMousePress(CmdMediator *cmdMediator, QPointF pos)
See DigitizeStateAbstractBase::handleMousePress.
Digitizing state for creating multiple Points along a highlighted segment.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:89
Digitizing state for digitizing one axis point at a time.
void requestImmediateStateTransition(CmdMediator *cmdMediator, DigitizeState digitizeState)
Perform immediate state transition. Called from outside state machine.