Engauge Digitizer  2
GraphicsScene.cpp
1 #include "CallbackSceneUpdateAfterCommand.h"
2 #include "Curve.h"
3 #include "CurvesGraphs.h"
4 #include "CurveStyles.h"
5 #include "DataKey.h"
6 #include "EngaugeAssert.h"
7 #include "EnumsToQt.h"
8 #include "GraphicsItemType.h"
9 #include "GraphicsPoint.h"
10 #include "GraphicsPointFactory.h"
11 #include "GraphicsScene.h"
12 #include "Logger.h"
13 #include "MainWindow.h"
14 #include "Point.h"
15 #include "PointStyle.h"
16 #include <QApplication>
17 #include <QGraphicsItem>
18 #include "QtToString.h"
19 #include "Transformation.h"
20 
22  QGraphicsScene(mainWindow)
23 {
24 }
25 
26 void GraphicsScene::addTemporaryPoint (const QString &identifier,
27  GraphicsPoint *point)
28 {
29  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::addTemporaryPoint"
30  << " identifer=" << identifier.toLatin1().data();
31 
32  m_graphicsLinesForCurves.addPoint (AXIS_CURVE_NAME,
33  identifier,
35  *point);
36 }
37 
38 GraphicsPoint *GraphicsScene::createPoint (const QString &identifier,
39  const PointStyle &pointStyle,
40  const QPointF &posScreen)
41 {
42  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::createPoint"
43  << " identifier=" << identifier.toLatin1().data();
44 
45  // Ordinal value is initially computed as one plus the max ordinal seen so far. This initial ordinal value will be overridden if the
46  // cordinates determine the ordinal values.
47  //
48  // This is an N-squared algorithm and may be worth replacing later
49  GraphicsPointFactory pointFactory;
50  GraphicsPoint *point = pointFactory.createPoint (*this,
51  identifier,
52  posScreen,
53  pointStyle);
54 
55  point->setToolTip (identifier);
56  point->setData (DATA_KEY_GRAPHICS_ITEM_TYPE, GRAPHICS_ITEM_TYPE_POINT);
57 
58  return point;
59 }
60 
61 QString GraphicsScene::dumpCursors () const
62 {
63  QString cursorOverride = (QApplication::overrideCursor () != 0) ?
64  QtCursorToString (QApplication::overrideCursor ()->shape ()) :
65  "<null>";
66  QString cursorImage = QtCursorToString (image()->cursor().shape ());
67 
68  QString dump = QString ("overrideCursor=%1 imageCursor=%2")
69  .arg (cursorOverride)
70  .arg (cursorImage);
71 
72  return dump;
73 }
74 
75 const QGraphicsPixmapItem *GraphicsScene::image () const
76 {
77  // Loop through items in scene to find the image
78  QList<QGraphicsItem*> items = QGraphicsScene::items();
79  QList<QGraphicsItem*>::iterator itr;
80  for (itr = items.begin(); itr != items.end(); itr++) {
81 
82  QGraphicsItem* item = *itr;
83  if (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt () == GRAPHICS_ITEM_TYPE_IMAGE) {
84 
85  return (QGraphicsPixmapItem *) item;
86  }
87  }
88 
89  ENGAUGE_ASSERT (false);
90  return 0;
91 }
92 
94 {
95  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::positionHasChangedPointIdentifiers";
96 
97  QStringList movedIds;
98 
99  const QList<QGraphicsItem*> &items = QGraphicsScene::items();
100  QList<QGraphicsItem*>::const_iterator itr;
101  for (itr = items.begin(); itr != items.end(); itr++) {
102 
103  const QGraphicsItem *item = *itr;
104 
105  // Skip the image and only keep the Points
106  bool isPoint = (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt () == GRAPHICS_ITEM_TYPE_POINT);
107  if (isPoint) {
108 
109  QString identifier = item->data (DATA_KEY_IDENTIFIER).toString ();
110  bool positionHasChanged = item->data (DATA_KEY_POSITION_HAS_CHANGED).toBool ();
111 
112  LOG4CPP_DEBUG_S ((*mainCat)) << "GraphicsScene::positionHasChangedPointIdentifiers"
113  << " identifier=" << identifier.toLatin1().data()
114  << " positionHasChanged=" << (positionHasChanged ? "yes" : "no");
115 
116  if (isPoint && positionHasChanged) {
117 
118  // Add Point to the list
119  movedIds << item->data(DATA_KEY_IDENTIFIER).toString ();
120 
121  }
122  }
123  }
124 
125  return movedIds;
126 }
127 
128 void GraphicsScene::printStream (QString indentation,
129  QTextStream &str)
130 {
131  m_graphicsLinesForCurves.printStream (indentation,
132  str);
133 }
134 
135 void GraphicsScene::removePoint (const QString &identifier)
136 {
137  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::removePoint identifier=" << identifier.toLatin1().data();
138 
139  m_graphicsLinesForCurves.removePoint (identifier);
140 }
141 
143 {
144  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::removeTemporaryPointIfExists";
145 
146  m_graphicsLinesForCurves.removeTemporaryPointIfExists ();
147 }
148 
150 {
151  // LOG4CPP_INFO_S is below
152 
153  int itemsBefore = items().count();
154 
155  m_graphicsLinesForCurves.resetOnLoad();
156 
157  int itemsAfter = items().count();
158 
159  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::resetOnLoad"
160  << " itemsBefore=" << itemsBefore
161  << " itemsAfter=" << itemsAfter;
162 }
163 
165 {
166  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::resetPositionHasChangedFlags";
167 
168  QList<QGraphicsItem*> itms = items ();
169  QList<QGraphicsItem*>::const_iterator itr;
170  for (itr = itms.begin (); itr != itms.end (); itr++) {
171 
172  QGraphicsItem *item = *itr;
173  item->setData (DATA_KEY_POSITION_HAS_CHANGED, false);
174  }
175 }
176 
178 {
179  const QList<QGraphicsItem*> &items = QGraphicsScene::selectedItems();
180 
181  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::selectedPointIdentifiers"
182  << " selectedItems=" << items.count();
183 
184  QStringList selectedIds;
185  QList<QGraphicsItem*>::const_iterator itr;
186  for (itr = items.begin(); itr != items.end(); itr++) {
187 
188  const QGraphicsItem* item = *itr;
189 
190  // Skip the image and only keep the Points
191  bool isPoint = (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt () == GRAPHICS_ITEM_TYPE_POINT);
192  if (isPoint) {
193 
194  // Add Point to the list
195  selectedIds << item->data(DATA_KEY_IDENTIFIER).toString ();
196 
197  }
198  }
199 
200  return selectedIds;
201 }
202 
204  bool showAll,
205  const QString &curveNameWanted)
206 {
207  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::showCurves"
208  << " show=" << (show ? "true" : "false")
209  << " showAll=" << (showAll ? "true" : "false")
210  << " curve=" << curveNameWanted.toLatin1().data();
211 
212  const QList<QGraphicsItem*> &items = QGraphicsScene::items();
213  QList<QGraphicsItem*>::const_iterator itr;
214  for (itr = items.begin(); itr != items.end(); itr++) {
215 
216  QGraphicsItem* item = *itr;
217 
218  // Skip the image and only process the Points
219  bool isPoint = (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt () == GRAPHICS_ITEM_TYPE_POINT);
220  bool isCurve = (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt () == GRAPHICS_ITEM_TYPE_LINE);
221 
222  if (isPoint || isCurve) {
223 
224  bool showThis = show;
225  if (show && !showAll) {
226  QString identifier = item->data (DATA_KEY_IDENTIFIER).toString ();
227 
228  if (isPoint) {
229 
230  QString curveNameGot = Point::curveNameFromPointIdentifier (identifier);
231  showThis = (curveNameWanted == curveNameGot);
232 
233  } else {
234 
235  showThis = (curveNameWanted == identifier);
236 
237  }
238  }
239 
240  item->setVisible (showThis);
241 
242  }
243  }
244 }
245 
247 {
248  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::updateAfterCommand";
249 
250  updateCurves (cmdMediator);
251 
252  // Update the points
253  updatePointMembership (cmdMediator);
254 }
255 
256 void GraphicsScene::updateCurves (CmdMediator &cmdMediator)
257 {
258  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::updateCurves";
259 
260  // Desired curve names include both axes and graph curve names
261  QStringList curveNames;
262  curveNames << AXIS_CURVE_NAME;
263  curveNames << cmdMediator.document().curvesGraphsNames();
264 
265  m_graphicsLinesForCurves.addRemoveCurves (*this,
266  curveNames);
267 }
268 
269 void GraphicsScene::updateCurveStyles (const CurveStyles &modelCurveStyles)
270 {
271  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::updateCurveStyles";
272 
273  m_graphicsLinesForCurves.updateCurveStyles (modelCurveStyles);
274 }
275 
277  const Transformation &transformation)
278 {
279  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::updateGraphicsLinesToMatchGraphicsPoints";
280 
281  if (transformation.transformIsDefined()) {
282 
283  // Ordinals must be updated to reflect reordering that may have resulted from dragging points
284  m_graphicsLinesForCurves.updatePointOrdinalsAfterDrag (curveStyles,
285  transformation);
286 
287  // Recompute the lines one time for efficiency
288  m_graphicsLinesForCurves.updateGraphicsLinesToMatchGraphicsPoints (curveStyles);
289  }
290 }
291 
292 void GraphicsScene::updatePointMembership (CmdMediator &cmdMediator)
293 {
294  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::updatePointMembership";
295 
296  CallbackSceneUpdateAfterCommand ftor (m_graphicsLinesForCurves,
297  *this,
298  cmdMediator.document ());
299  Functor2wRet<const QString &, const Point &, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
301 
302  // First pass:
303  // 1) Mark all points as Not Wanted (this is done while creating the map)
304  m_graphicsLinesForCurves.lineMembershipReset ();
305 
306  // Next pass:
307  // 1) Existing points that are found in the map are marked as Wanted
308  // 2) Add new points that were just created in the Document. The new points are marked as Wanted
309  cmdMediator.iterateThroughCurvePointsAxes (ftorWithCallback);
310  cmdMediator.iterateThroughCurvesPointsGraphs (ftorWithCallback);
311 
312  // Next pass:
313  // 1) Remove points that were just removed from the Document
314  m_graphicsLinesForCurves.lineMembershipPurge (cmdMediator.document().modelCurveStyles());
315 }
void updateGraphicsLinesToMatchGraphicsPoints(const CurveStyles &modelCurveStyles, const Transformation &transformation)
A mouse move has just occurred so move the selected points, since they were dragged.
void lineMembershipPurge(const CurveStyles &curveStyles)
Mark the end of addPoint calls. Remove stale lines, insert missing lines, and draw the graphics lines...
void removePoint(const QString &identifier)
Remove the specified point. The act of deleting it will automatically remove it from the GraphicsScen...
static QString curveNameFromPointIdentifier(const QString &pointIdentifier)
Parse the curve name from the specified point identifier. This does the opposite of uniqueIdentifierG...
Definition: Point.cpp:202
Factor for generating GraphicsPointAbstractBase class objects.
Callback for updating the QGraphicsItems in the scene after a command may have modified Points in Cur...
void updateAfterCommand(CmdMediator &cmdMediator)
Update the Points and their Curves after executing a command.
void printStream(QString indentation, QTextStream &str)
Debugging method that supports print method of this class and printStream method of some other class(...
void removePoint(const QString &identifier)
Remove specified point. This aborts if the point does not exist.
GraphicsScene(MainWindow *mainWindow)
Single constructor.
Model for DlgSettingsCurveProperties and CmdSettingsCurveProperties.
Definition: CurveStyles.h:16
void addPoint(const QString &curveName, const QString &pointIdentifier, double ordinal, GraphicsPoint &point)
Add new point.
void lineMembershipReset()
Mark points as unwanted. Afterwards, lineMembershipPurge gets called.
QStringList selectedPointIdentifiers() const
Return a list of identifiers for the currently selected points.
GraphicsPoint * createPoint(QGraphicsScene &scene, const QString &identifier, const QPointF &posScreen, const PointStyle &pointStyle)
Create circle or polygon point according to the PointStyle.
void removeTemporaryPointIfExists()
Remove temporary point if it exists.
void setData(int key, const QVariant &data)
Proxy method for QGraphicsItem::setData.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Definition: CmdMediator.cpp:61
CallbackSearchReturn callback(const QString &, const Point &point)
Callback method.
void updatePointOrdinalsAfterDrag(const CurveStyles &curveStyles, const Transformation &transformation)
See GraphicsScene::updateOrdinalsAfterDrag.
void updateGraphicsLinesToMatchGraphicsPoints(const CurveStyles &curveStyles)
Calls to moveLinesWithDraggedPoint have finished so update the lines correspondingly.
Affine transformation between screen and graph coordinates, based on digitized axis points...
Details for a specific Point.
Definition: PointStyle.h:14
QStringList positionHasChangedPointIdentifiers() const
Return a list of identifiers for the points that have moved since the last call to resetPositionHasCh...
CurveStyles modelCurveStyles() const
Get method for CurveStyles.
Definition: Document.cpp:452
static double UNDEFINED_ORDINAL()
Get method for undefined ordinal constant.
Definition: Point.h:117
void resetPositionHasChangedFlags()
Reset positionHasChanged flag for all items. Typically this is done as part of mousePressEvent.
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
Graphics item for drawing a circular or polygonal Point.
Definition: GraphicsPoint.h:33
void updateCurveStyles(const CurveStyles &modelCurveStyles)
Update curve styles after settings changed.
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
Definition: Document.cpp:317
void removeTemporaryPointIfExists()
Remove temporary point if it exists.
bool transformIsDefined() const
Transform is defined when at least three axis points have been digitized.
void resetOnLoad()
Reset, when loading a document after the first, to same state that first document was at when loaded...
Command queue stack.
Definition: CmdMediator.h:16
void addTemporaryPoint(const QString &identifier, GraphicsPoint *point)
Add one temporary point to m_graphicsLinesForCurves. Non-temporary points are handled by the updateLi...
void updateCurveStyles(const CurveStyles &modelCurveStyles)
Update the curve style for every curve.
GraphicsPoint * createPoint(const QString &identifier, const PointStyle &pointStyle, const QPointF &posScreen)
Create one QGraphicsItem-based object that represents one Point. It is NOT added to m_graphicsLinesFo...
QVariant data(int key) const
Proxy method for QGraphicsItem::data.
void iterateThroughCurvesPointsGraphs(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for all the graphs curves.
Definition: CmdMediator.cpp:86
void iterateThroughCurvePointsAxes(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for the single axes curve.
Definition: CmdMediator.cpp:76
void setToolTip(const QString &toolTip)
Proxy method for QGraphicsItem::setToolTip.
void resetOnLoad()
Reset, when loading a document after the first, to same state that first document was at when loaded...
void addRemoveCurves(GraphicsScene &scene, const QStringList &curveNames)
Add new curves and remove expired curves to match the specified list.
void showCurves(bool show, bool showAll=false, const QString &curveName="")
Show or hide all Curves (if showAll is true) or just the selected Curve (if showAll is false);...
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:60