Engauge Digitizer 2
Loading...
Searching...
No Matches
DigitizeStateScale.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2017 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 "CmdAddScale.h"
8#include "CmdMediator.h"
9#include "CursorFactory.h"
10#include "DigitizeStateScale.h"
12#include "DlgEditScale.h"
13#include "Document.h"
14#include "EngaugeAssert.h"
15#include "GraphicsPoint.h"
16#include "GraphicsScene.h"
17#include "GraphicsView.h"
18#include "Logger.h"
19#include "MainWindow.h"
20#include "PointStyle.h"
21#include <QCursor>
22#include <QGraphicsLineItem>
23#include <QMessageBox>
24#include "QtToString.h"
25#include "ZValues.h"
26
29 m_temporaryPoint0 (nullptr),
30 m_temporaryPoint1 (nullptr),
31 m_line (nullptr)
32{
33}
34
38
40{
41 return AXIS_CURVE_NAME;
42}
43
45 DigitizeState /* previousState */)
46{
47 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::begin";
48
49 setCursor(cmdMediator);
50 context().setDragMode(QGraphicsView::NoDrag);
52}
53
54bool DigitizeStateScale::canPaste (const Transformation & /* transformation */,
55 const QSize & /* viewSize */) const
56{
57 return false;
58}
59
60QCursor DigitizeStateScale::cursor(CmdMediator *cmdMediator) const
61{
62 LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateScale::cursor";
63
64 CursorFactory cursorFactory;
65 QCursor cursor = cursorFactory.generate (cmdMediator->document().modelDigitizeCurve());
66
67 return cursor;
68}
69
71{
72 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::end";
73}
74
76 const QString &pointIdentifier)
77{
78 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleContextMenuEventAxis "
79 << " point=" << pointIdentifier.toLatin1 ().data ();
80}
81
83 const QStringList &pointIdentifiers)
84{
85 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleContextMenuEventGraph "
86 << "points=" << pointIdentifiers.join(",").toLatin1 ().data ();
87}
88
90{
91 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleCurveChange";
92}
93
95 Qt::Key key,
96 bool /* atLeastOneSelectedItem */)
97{
98 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleKeyPress"
99 << " key=" << QKeySequence (key).toString ().toLatin1 ().data ();
100}
101
103 QPointF posScreen)
104{
105 if (m_temporaryPoint1 != nullptr) {
106
107 LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateScale::handleMouseMove"
108 << " oldPos=" << QPointFToString (m_temporaryPoint1->pos ()).toLatin1().data()
109 << " newPos=" << QPointFToString (posScreen).toLatin1().data();
110
111 m_temporaryPoint1->setPos (posScreen);
112
113 updateLineGeometry();
114 }
115}
116
118 QPointF posScreen)
119{
120 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleMousePress";
121
122 GeometryWindow *NULL_GEOMETRY_WINDOW = nullptr;
123
124 // Create the scale bar to give the user immediate feedback that something was created
125 const Curve &curveAxes = cmdMediator->curveAxes();
126 PointStyle pointStyleAxes = curveAxes.curveStyle().pointStyle();
127 m_pointIdentifier0 = Point::temporaryPointIdentifier();
128 m_pointIdentifier1 = m_pointIdentifier0 + "b";
129 m_temporaryPoint0 = context().mainWindow().scene().createPoint(m_pointIdentifier0,
130 pointStyleAxes,
131 posScreen,
132 NULL_GEOMETRY_WINDOW);
133 m_temporaryPoint1 = context().mainWindow().scene().createPoint(m_pointIdentifier1,
134 pointStyleAxes,
135 posScreen,
136 NULL_GEOMETRY_WINDOW);
137
138 // Subtle stuff happening here. GraphicsPoints by default can receive focus for clicking/dragging,
139 // but for some reason that was causing the dragged second endpoint to jump to the origin the Nth
140 // time that a scale bar was created, for every N>1. So we make the endpoint passive and update
141 // its position manually in handleMouseMove
142 m_temporaryPoint0->setPassive ();
143 m_temporaryPoint1->setPassive ();
144
145 context().mainWindow().scene().addTemporaryScaleBar (m_temporaryPoint0,
146 m_temporaryPoint1,
147 m_pointIdentifier0,
148 m_pointIdentifier1);
149
150 m_line = new QGraphicsLineItem;
151 context().mainWindow().scene().addItem (m_line);
152 m_line->setPen (QColor (Qt::red));
153 m_line->setZValue (Z_VALUE_CURVE);
154 m_line->setVisible (true);
155
156 updateLineGeometry ();
157
158 // Attempts to select an endpoint right here, or after an super short timer interval
159 // failed. That would have been nice for having the click create the scale bar and, while
160 // the mouse was still pressed, selecting an endpoint thus allowing a single click-and-drag to
161 // create the scale bar. We fall back to the less elegant solution (which the user will never
162 // notice) of capturing mouse move events and using those to move an endpoint
163}
164
166 QPointF /* posScreen */)
167{
168 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::handleMouseRelease";
169
170 if (context().mainWindow().transformIsDefined()) {
171
172 QMessageBox::warning (nullptr,
173 QObject::tr ("Engauge Digitizer"),
174 QObject::tr ("The scale bar has been defined, and another is not needed or allowed."));
175
176 removeTemporaryPointsAndLine ();
177
178 } else {
179
180 // Ask user for coordinates
181 DlgEditScale *dlg = new DlgEditScale (context ().mainWindow (),
182 cmdMediator->document().modelCoords(),
183 cmdMediator->document().modelGeneral(),
184 context().mainWindow().modelMainWindow());
185 int rtn = dlg->exec ();
186
187 double scaleLength = dlg->scaleLength ();
188 QPointF posScreen0 = m_temporaryPoint0->pos ();
189 QPointF posScreen1 = m_temporaryPoint1->pos ();
190 delete dlg;
191
192 removeTemporaryPointsAndLine ();
193
194 if (rtn == QDialog::Accepted) {
195
196 // User wants to add this scale point. There are no additional sanity checks to run
197
198 int nextOrdinal0 = cmdMediator->document().nextOrdinalForCurve(AXIS_CURVE_NAME);
199 int nextOrdinal1 = nextOrdinal0 + 1;
200
201 // Create command to add point
202 Document &document = cmdMediator->document ();
203 QUndoCommand *cmd = new CmdAddScale (context ().mainWindow(),
204 document,
205 posScreen0,
206 posScreen1,
207 scaleLength,
208 nextOrdinal0,
209 nextOrdinal1);
210 context().appendNewCmd(cmdMediator,
211 cmd);
212 }
213 }
214}
215
216void DigitizeStateScale::removeTemporaryPointsAndLine ()
217{
218 context().mainWindow().scene().removePoint (m_pointIdentifier0); // Deallocates GraphicsPoint automatically
219 context().mainWindow().scene().removePoint (m_pointIdentifier1); // Deallocates GraphicsPoint automaticall
220 context().mainWindow().scene().removeItem (m_line);
221 delete m_line;
222 m_temporaryPoint0 = nullptr;
223 m_temporaryPoint1 = nullptr;
224 m_line = nullptr;
225}
226
228{
229 return "DigitizeStateScale";
230}
231
233{
234 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::updateAfterPointAddition";
235}
236
237void DigitizeStateScale::updateLineGeometry ()
238{
239 m_line->setLine (m_temporaryPoint0->pos ().x (),
240 m_temporaryPoint0->pos ().y (),
241 m_temporaryPoint1->pos ().x (),
242 m_temporaryPoint1->pos ().y ());
243}
244
246 const DocumentModelDigitizeCurve & /*modelDigitizeCurve */)
247{
248 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::updateModelDigitizeCurve";
249
250 setCursor(cmdMediator);
251}
252
254{
255 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateScale::updateModelSegments";
256}
const QString AXIS_CURVE_NAME
DigitizeState
Set of possible states of Digitize toolbar.
log4cpp::Category * mainCat
Definition Logger.cpp:14
QString QPointFToString(const QPointF &pos)
const int Z_VALUE_CURVE
Definition ZValues.cpp:10
Command for adding one scale point.
Definition CmdAddScale.h:17
Command queue stack.
Definition CmdMediator.h:24
const Curve & curveAxes() const
See Document::curveAxes.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Create standard cross cursor, or custom cursor, according to settings.
QCursor generate(const DocumentModelDigitizeCurve &modelDigitizeCurve) const
Factory method to generate standard or custom cursor.
PointStyle pointStyle() const
Get method for PointStyle.
Container for one set of digitized Points.
Definition Curve.h:34
CurveStyle curveStyle() const
Return the curve style.
Definition Curve.cpp:149
Base class for all digitizing states. This serves as an interface to DigitizeStateContext.
DigitizeStateContext & context()
Reference to the DigitizeStateContext that contains all the DigitizeStateAbstractBase subclasses,...
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 setDragMode(QGraphicsView::DragMode dragMode)
Set QGraphicsView drag mode (in m_view). Called from DigitizeStateAbstractBase subclasses.
void appendNewCmd(CmdMediator *cmdMediator, QUndoCommand *cmd)
Append just-created QUndoCommand to command stack. This is called from DigitizeStateAbstractBase subc...
MainWindow & mainWindow()
Reference to the MainWindow, without const.
virtual void handleCurveChange(CmdMediator *cmdMediator)
Handle the selection of a new curve. At a minimum, DigitizeStateSegment will generate a new set of Se...
virtual void handleContextMenuEventAxis(CmdMediator *cmdMediator, const QString &pointIdentifier)
Handle a right click, on an axis point, that was intercepted earlier.
virtual void begin(CmdMediator *cmdMediator, DigitizeState previousState)
Method that is called at the exact moment a state is entered.
virtual void end()
Method that is called at the exact moment a state is exited. Typically called just before begin for t...
virtual void handleContextMenuEventGraph(CmdMediator *cmdMediator, const QStringList &pointIdentifiers)
Handle a right click, on a graph point, that was intercepted earlier.
virtual QString activeCurve() const
Name of the active Curve. This can include AXIS_CURVE_NAME.
virtual void handleMouseRelease(CmdMediator *cmdMediator, QPointF posScreen)
Handle a mouse release that was intercepted earlier.
virtual void updateAfterPointAddition()
Update graphics attributes after possible new points. This is useful for highlight opacity.
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 updateModelSegments(const DocumentModelSegments &modelSegments)
Update the segments given the new settings.
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.
virtual QCursor cursor(CmdMediator *cmdMediator) const
Returns the state-specific cursor shape.
DigitizeStateScale(DigitizeStateContext &context)
Single constructor.
virtual void handleMousePress(CmdMediator *cmdMediator, QPointF posScreen)
Handle a mouse press that was intercepted earlier.
virtual void handleKeyPress(CmdMediator *cmdMediator, Qt::Key key, bool atLeastOneSelectedItem)
Handle a key press that was intercepted earlier.
virtual QString state() const
State name for debugging.
Dialog box for editing the information of the map scale.
double scaleLength() const
Return the scale bar length specified by the user. Only applies if dialog was accepted.
Model for DlgSettingsDigitizeCurve and CmdSettingsDigitizeCurve.
Model for DlgSettingsSegments and CmdSettingsSegments.
Storage of one imported image and the data attached to that image.
Definition Document.h:42
DocumentModelGeneral modelGeneral() const
Get method for DocumentModelGeneral.
Definition Document.cpp:723
DocumentModelDigitizeCurve modelDigitizeCurve() const
Get method for DocumentModelDigitizeCurve.
Definition Document.cpp:709
int nextOrdinalForCurve(const QString &curveName) const
Default next ordinal value for specified curve.
Definition Document.cpp:765
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition Document.cpp:695
Window that displays the geometry information, as a table, for the current curve.
QPointF pos() const
Proxy method for QGraphicsItem::pos.
void setPassive()
Prevent automatic focus on point (=make it passive) for scale bar so drags can be made to work proper...
void setPos(const QPointF pos)
Update the position.
GraphicsPoint * createPoint(const QString &identifier, const PointStyle &pointStyle, const QPointF &posScreen, GeometryWindow *geometryWindow)
Create one QGraphicsItem-based object that represents one Point. It is NOT added to m_graphicsLinesFo...
void addTemporaryScaleBar(GraphicsPoint *point0, GraphicsPoint *point1, const QString &pointIdentifier0, const QString &pointIdentifier1)
Add temporary scale bar to scene.
void removePoint(const QString &identifier)
Remove specified point. This aborts if the point does not exist.
void updateViewsOfSettings(const QString &activeCurve)
Update curve-specific view of settings. Private version gets active curve name from DigitizeStateCont...
GraphicsScene & scene()
Scene container for the QImage and QGraphicsItems.
Details for a specific Point.
Definition PointStyle.h:21
static QString temporaryPointIdentifier()
Point identifier for temporary point that is used by DigitzeStateAxis.
Definition Point.cpp:519
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