Engauge Digitizer  2
DigitizeStateSegment.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 "CmdAddPointsGraph.h"
8 #include "DigitizeStateContext.h"
9 #include "DigitizeStateSegment.h"
10 #include "EngaugeAssert.h"
11 #include "Logger.h"
12 #include "MainWindow.h"
13 #include "OrdinalGenerator.h"
14 #include <QGraphicsPixmapItem>
15 #include <QGraphicsScene>
16 #include <QImage>
17 #include <QSize>
18 #include "Segment.h"
19 #include "SegmentFactory.h"
20 #include "Transformation.h"
21 
24 {
25 }
26 
27 DigitizeStateSegment::~DigitizeStateSegment ()
28 {
29 }
30 
32 {
34 }
35 
37  DigitizeState /* previousState */)
38 {
39  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::begin";
40 
41  m_cmdMediator = cmdMediator; // Save for slotMouseClickOnSegment
42 
43  setCursor(cmdMediator);
44  context().setDragMode(QGraphicsView::NoDrag);
46 
47  handleCurveChange(cmdMediator);
48 }
49 
50 bool DigitizeStateSegment::canPaste (const Transformation &transformation,
51  const QSize &viewSize) const
52 {
53  return canPasteProtected (transformation,
54  viewSize);
55 }
56 
57 QCursor DigitizeStateSegment::cursor(CmdMediator * /* cmdMediator */) const
58 {
59  LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateSegment::cursor";
60 
61  return QCursor (Qt::ArrowCursor);
62 }
63 
65 {
66  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::end";
67 
68  GraphicsScene &scene = context().mainWindow().scene();
69  SegmentFactory segmentFactory ((QGraphicsScene &) scene,
70  context().isGnuplot());
71 
72  segmentFactory.clearSegments(m_segments);
73 }
74 
76  const QString &pointIdentifier)
77 {
78  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::handleContextMenuEventAxis "
79  << " point=" << pointIdentifier.toLatin1 ().data ();
80 }
81 
83  const QStringList &pointIdentifiers)
84 {
85  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment ::handleContextMenuEventGraph "
86  << "points=" << pointIdentifiers.join(",").toLatin1 ().data ();
87 }
88 
90 {
91  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::handleCurveChange";
92 
93  QImage img = context().mainWindow().imageFiltered();
94 
95  GraphicsScene &scene = context().mainWindow().scene();
96  SegmentFactory segmentFactory ((QGraphicsScene &) scene,
97  context().isGnuplot());
98 
99  segmentFactory.clearSegments (m_segments);
100 
101  // Create new segments
102  segmentFactory.makeSegments (img,
103  cmdMediator->document().modelSegments(),
104  m_segments);
105 
106  // Connect signals of the new segments
107  QList<Segment*>::iterator itr;
108  for (itr = m_segments.begin(); itr != m_segments.end(); itr++) {
109  Segment *segment = *itr;
110 
111  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::handleCurveChange"
112  << " lines=" << segment->lineCount();
113 
114  connect (segment, SIGNAL (signalMouseClickOnSegment (QPointF)), this, SLOT (slotMouseClickOnSegment (QPointF)));
115  }
116 }
117 
119  Qt::Key key,
120  bool /* atLeastOneSelectedItem */)
121 {
122  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::handleKeyPress"
123  << " key=" << QKeySequence (key).toString ().toLatin1 ().data ();
124 }
125 
127  QPointF /* posScreen */)
128 {
129 // LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateSegment::handleMouseMove";
130 }
131 
133  QPointF /* posScreen */)
134 {
135  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::handleMousePress";
136 }
137 
139  QPointF /* posScreen */)
140 {
141  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::handleMouseRelease";
142 }
143 
144 Segment *DigitizeStateSegment::segmentFromSegmentStart (const QPointF &posSegmentStart) const
145 {
146  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::segmentFromSegmentStart"
147  << " segments=" << m_segments.count();
148 
149  QList<Segment*>::const_iterator itr;
150  for (itr = m_segments.begin(); itr != m_segments.end(); itr++) {
151  Segment *segment = *itr;
152 
153  if (segment->firstPoint() == posSegmentStart) {
154 
155  return segment;
156  }
157  }
158 
159  LOG4CPP_ERROR_S ((*mainCat)) << "DigitizeStateSegment::segmentFromSegmentStart";
160  ENGAUGE_ASSERT (false);
161  return 0;
162 }
163 
165 {
166  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::slotMouseClickOnSegment";
167 
168  Segment *segment = segmentFromSegmentStart (posSegmentStart);
169 
170  // Create single-entry list that is expected by SegmentFactory
171  QList<Segment*> segments;
172  segments.push_back (segment);
173 
174  // Generate point coordinates. Nothing is created in the GraphicsScene at this point
175  GraphicsScene &scene = context().mainWindow().scene();
176  SegmentFactory segmentFactory ((QGraphicsScene &) scene,
177  context().isGnuplot());
178 
179  QList<QPoint> points = segmentFactory.fillPoints (m_cmdMediator->document().modelSegments(),
180  segments);
181 
182  // Create one ordinal for each point
183  OrdinalGenerator ordinalGenerator;
184  Document &document = m_cmdMediator->document ();
185  const Transformation &transformation = context ().mainWindow ().transformation();
186  QList<double> ordinals;
187  QList<QPoint>::iterator itr;
188  for (itr = points.begin(); itr != points.end(); itr++) {
189 
190  QPoint point = *itr;
191  ordinals << ordinalGenerator.generateCurvePointOrdinal(document,
192  transformation,
193  point,
194  activeCurve ());
195  }
196 
197  // Create command to add points
198  QUndoCommand *cmd = new CmdAddPointsGraph (context ().mainWindow(),
199  document,
200  context ().mainWindow().selectedGraphCurve(),
201  points,
202  ordinals);
203  context().appendNewCmd(m_cmdMediator,
204  cmd);
205 }
206 
208 {
209  return "DigitizeStateSegment";
210 }
211 
213 {
214  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::updateAfterPointAddition";
215 }
216 
218  const DocumentModelDigitizeCurve & /*modelDigitizeCurve */)
219 {
220  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::updateModelDigitizeCurve";
221 }
222 
224 {
225  LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateSegment::updateModelSegments";
226 
227  QList<Segment*>::const_iterator itr;
228  for (itr = m_segments.begin(); itr != m_segments.end(); itr++) {
229  Segment *segment = *itr;
230 
231  segment->updateModelSegment (modelSegments);
232  }
233 }
QImage imageFiltered() const
Background image that has been filtered for the current curve. This asserts if a curve-specific image...
virtual void updateAfterPointAddition()
Update graphics attributes after possible new points. This is useful for highlight opacity...
void setDragMode(QGraphicsView::DragMode dragMode)
Set QGraphicsView drag mode (in m_view). Called from DigitizeStateAbstractBase subclasses.
virtual void handleMousePress(CmdMediator *cmdMediator, QPointF posScreen)
Handle a mouse press that was intercepted earlier.
bool canPasteProtected(const Transformation &transformation, const QSize &viewSize) const
Protected version of canPaste method. Some, but not all, leaf classes use this method.
virtual void updateModelSegments(const DocumentModelSegments &modelSegments)
Update the segments given the new settings.
virtual void handleContextMenuEventAxis(CmdMediator *cmdMediator, const QString &pointIdentifier)
Handle a right click, on an axis point, that was intercepted earlier.
void updateViewsOfSettings(const QString &activeCurve)
Update curve-specific view of settings. Private version gets active curve name from DigitizeStateCont...
virtual QCursor cursor(CmdMediator *cmdMediator) const
Returns the state-specific cursor shape.
virtual void handleMouseMove(CmdMediator *cmdMediator, QPointF posScreen)
Handle a mouse move. This is part of an experiment to see if augmenting the cursor in Point Match mod...
virtual void updateModelDigitizeCurve(CmdMediator *cmdMediator, const DocumentModelDigitizeCurve &modelDigitizeCurve)
Update the digitize curve settings.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Definition: CmdMediator.cpp:72
QList< QPoint > fillPoints(const DocumentModelSegments &modelSegments, QList< Segment *> segments)
Return segment fill points for all segments, for previewing.
virtual QString activeCurve() const
Name of the active Curve. This can include AXIS_CURVE_NAME.
DigitizeStateContext & context()
Reference to the DigitizeStateContext that contains all the DigitizeStateAbstractBase subclasses...
void makeSegments(const QImage &imageFiltered, const DocumentModelSegments &modelSegments, QList< Segment *> &segments, bool useDlg=true)
Main entry point for creating all Segments for the filtered image.
MainWindow & mainWindow()
Reference to the MainWindow, without const.
Transformation transformation() const
Return read-only copy of transformation.
Factory class for Segment objects.
virtual void handleCurveChange(CmdMediator *cmdMediator)
Handle the selection of a new curve. At a minimum, DigitizeStateSegment will generate a new set of Se...
Model for DlgSettingsDigitizeCurve and CmdSettingsDigitizeCurve.
Affine transformation between screen and graph coordinates, based on digitized axis points...
GraphicsScene & scene()
Scene container for the QImage and QGraphicsItems.
void clearSegments(QList< Segment *> &segments)
Remove the segments created by makeSegments.
void setCursor(CmdMediator *cmdMediator)
Update the cursor according to the current state.
Container for all DigitizeStateAbstractBase subclasses. This functions as the context class in a stan...
void appendNewCmd(CmdMediator *cmdMediator, QUndoCommand *cmd)
Append just-created QUndoCommand to command stack. This is called from DigitizeStateAbstractBase subc...
virtual void end()
Method that is called at the exact moment a state is exited. Typically called just before begin for t...
DocumentModelSegments modelSegments() const
Get method for DocumentModelSegments.
Definition: Document.cpp:745
Command for adding one or more graph points. This is for Segment Fill mode.
Storage of one imported image and the data attached to that image.
Definition: Document.h:41
Selectable piecewise-defined line that follows a filtered line in the image.
Definition: Segment.h:21
void slotMouseClickOnSegment(QPointF)
Receive signal from Segment that has been clicked on. The CmdMediator from the begin method will be u...
virtual bool canPaste(const Transformation &transformation, const QSize &viewSize) const
Return true if there is good data in the clipboard for pasting, and that is compatible with the curre...
virtual void begin(CmdMediator *cmdMediator, DigitizeState previousState)
Method that is called at the exact moment a state is entered.
virtual void handleContextMenuEventGraph(CmdMediator *cmdMediator, const QStringList &pointIdentifiers)
Handle a right click, on a graph point, that was intercepted earlier.
virtual QString state() const
State name for debugging.
Utility class for generating ordinal numbers.
Command queue stack.
Definition: CmdMediator.h:23
void updateModelSegment(const DocumentModelSegments &modelSegments)
Update this segment given the new settings.
Definition: Segment.cpp:538
int lineCount() const
Get method for number of lines.
Definition: Segment.cpp:384
Model for DlgSettingsSegments and CmdSettingsSegments.
QPointF firstPoint() const
Coordinates of first point in Segment.
Definition: Segment.cpp:285
Base class for all digitizing states. This serves as an interface to DigitizeStateContext.
Add point and line handling to generic QGraphicsScene.
Definition: GraphicsScene.h:33
QString selectedGraphCurve() const
Curve name that is currently selected in m_cmbCurve.
DigitizeStateSegment(DigitizeStateContext &context)
Single constructor.
double generateCurvePointOrdinal(const Document &document, const Transformation &transformation, const QPointF &posScreen, const QString &curveName)
Select ordinal so new point curve passes smoothly through existing points.
virtual void handleMouseRelease(CmdMediator *cmdMediator, QPointF posScreen)
Handle a mouse release that was intercepted earlier.
virtual void handleKeyPress(CmdMediator *cmdMediator, Qt::Key key, bool atLeastOneSelectedItem)
Handle a key press that was intercepted earlier.