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  qDeleteAll (m_states);
57 }
58 
60 {
61  return m_states [m_currentState]->activeCurve ();
62 }
63 
65  QUndoCommand *cmd)
66 {
67  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::appendNewCmd";
68 
69  cmdMediator->push (cmd);
70 }
71 
72 bool DigitizeStateContext::canPaste (const Transformation &transformation,
73  const QSize &size) const
74 {
75  return m_states [m_currentState]->canPaste (transformation,
76  size);
77 }
78 
79 void DigitizeStateContext::completeRequestedStateTransitionIfExists (CmdMediator *cmdMediator)
80 {
81  if (m_currentState != m_requestedState) {
82 
83  // A transition is waiting so perform it
84 
85  if (m_currentState != NUM_DIGITIZE_STATES) {
86 
87  // This is not the first state so close the previous state
88  m_states [m_currentState]->end ();
89  }
90 
91  // Start the new state
92  DigitizeState previousState = m_currentState;
93  m_currentState = m_requestedState;
94  m_states [m_requestedState]->begin (cmdMediator,
95  previousState);
96 
97  // If transition was triggered from inside the state machine then MainWindow controls need to be set accordingly
98  // as if user had clicked on a digitize button
100  }
101 }
102 
104  const QString &pointIdentifier)
105 {
106  m_states [m_currentState]->handleContextMenuEventAxis (cmdMediator,
107  pointIdentifier);
108 }
109 
111  const QStringList &pointIdentifiers)
112 {
113  m_states [m_currentState]->handleContextMenuEventGraph (cmdMediator,
114  pointIdentifiers);
115 }
116 
118 {
119  m_states [m_currentState]->handleCurveChange(cmdMediator);
120 }
121 
123  Qt::Key key,
124  bool atLeastOneSelectedItem)
125 {
126  m_states [m_currentState]->handleKeyPress (cmdMediator,
127  key,
128  atLeastOneSelectedItem);
129 
130  completeRequestedStateTransitionIfExists(cmdMediator);
131 
132 }
133 
135  QPointF pos)
136 {
137  m_states [m_currentState]->handleMouseMove (cmdMediator,
138  pos);
139 
140  completeRequestedStateTransitionIfExists(cmdMediator);
141 
142 }
143 
145  QPointF pos)
146 {
147  m_states [m_currentState]->handleMousePress (cmdMediator,
148  pos);
149 
150  completeRequestedStateTransitionIfExists(cmdMediator);
151 
152 }
153 
155  QPointF pos)
156 {
157  m_states [m_currentState]->handleMouseRelease (cmdMediator,
158  pos);
159 
160  completeRequestedStateTransitionIfExists(cmdMediator);
161 }
162 
164 {
165  return m_isGnuplot;
166 }
167 
169 {
170  return m_mainWindow;
171 }
172 
174 {
175  return m_mainWindow;
176 }
177 
178 void DigitizeStateContext::requestDelayedStateTransition (DigitizeState digitizeState)
179 {
180  m_requestedState = digitizeState;
181 }
182 
184  DigitizeState digitizeState)
185 {
186  m_requestedState = digitizeState;
187  completeRequestedStateTransitionIfExists(cmdMediator);
188 }
189 
191 {
192  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::resetOnLoad";
193 
194  // Reset current state. At this point, the current state is DIGITIZE_STATE_EMPTY when opening the first document
195  // so for consistency we always reset it so succeeding documents work the same way
196  if (m_currentState != DIGITIZE_STATE_EMPTY) {
197  m_requestedState = DIGITIZE_STATE_EMPTY;
198  completeRequestedStateTransitionIfExists(cmdMediator);
199  }
200 }
201 
203 {
204  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::setCursor";
205 
206  ENGAUGE_ASSERT(m_currentState < m_states.count());
207 
208  m_states [m_currentState]->setCursor (cmdMediator);
209 }
210 
211 void DigitizeStateContext::setDragMode (QGraphicsView::DragMode dragMode)
212 {
213  LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateContext::setDragMode";
214 
215  if (m_imageIsLoaded) {
216  m_view.setDragMode (dragMode);
217  }
218 }
219 
221  bool imageIsLoaded)
222 {
223  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::setImageIsLoaded";
224 
225  m_imageIsLoaded = imageIsLoaded;
226  setCursor (cmdMediator);
227 }
228 
230 {
231  ENGAUGE_ASSERT (m_currentState != NUM_DIGITIZE_STATES);
232 
233  return m_states [m_currentState]->state();
234 }
235 
237 {
238  ENGAUGE_ASSERT (m_currentState != NUM_DIGITIZE_STATES);
239 
240  m_states [m_currentState]->updateAfterPointAddition ();
241 }
242 
244  const DocumentModelDigitizeCurve &modelDigitizeCurve)
245 {
246  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::updateModelDigitizeCurve";
247 
248  ENGAUGE_ASSERT(m_currentState < m_states.count());
249 
250  m_states [m_currentState]->updateModelDigitizeCurve (cmdMediator,
251  modelDigitizeCurve);
252 }
253 
255 {
256  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateContext::updateModelSegments";
257 
258  ENGAUGE_ASSERT(m_currentState < m_states.count());
259 
260  m_states [m_currentState]->updateModelSegments (modelSegments);
261 }
262 
264 {
265  return m_view;
266 }
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:350
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:91
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.