Engauge Digitizer  2
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"
10 #include "DigitizeStateContext.h"
11 #include "DigitizeStateCurve.h"
12 #include "DigitizeStateEmpty.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
52 }
53 
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 
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.
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
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.
DigitizeState
Set of possible states of Digitize toolbar.
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.
log4cpp::Category * mainCat
Definition: Logger.cpp:14
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
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) define ENGAUGE...
Definition: EngaugeAssert.h:20
#define LOG4CPP_DEBUG_S(logger)
Definition: convenience.h:20
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.