Engauge Digitizer  2
 All Classes Files Functions Variables Enumerations Enumerator Friends Pages
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  return 0;
90 }
91 
93 {
94  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::positionHasChangedPointIdentifiers";
95 
96  QStringList movedIds;
97 
98  const QList<QGraphicsItem*> &items = QGraphicsScene::items();
99  QList<QGraphicsItem*>::const_iterator itr;
100  for (itr = items.begin(); itr != items.end(); itr++) {
101 
102  const QGraphicsItem *item = *itr;
103 
104  // Skip the image and only keep the Points
105  bool isPoint = (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt () == GRAPHICS_ITEM_TYPE_POINT);
106  if (isPoint) {
107 
108  QString identifier = item->data (DATA_KEY_IDENTIFIER).toString ();
109  bool positionHasChanged = item->data (DATA_KEY_POSITION_HAS_CHANGED).toBool ();
110 
111  LOG4CPP_DEBUG_S ((*mainCat)) << "GraphicsScene::positionHasChangedPointIdentifiers"
112  << " identifier=" << identifier.toLatin1().data()
113  << " positionHasChanged=" << (positionHasChanged ? "yes" : "no");
114 
115  if (isPoint && positionHasChanged) {
116 
117  // Add Point to the list
118  movedIds << item->data(DATA_KEY_IDENTIFIER).toString ();
119 
120  }
121  }
122  }
123 
124  return movedIds;
125 }
126 
127 void GraphicsScene::printStream (QString indentation,
128  QTextStream &str)
129 {
130  m_graphicsLinesForCurves.printStream (indentation,
131  str);
132 }
133 
134 void GraphicsScene::removePoint (const QString &identifier)
135 {
136  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::removePoint identifier=" << identifier.toLatin1().data();
137 
138  m_graphicsLinesForCurves.removePoint (identifier);
139 }
140 
142 {
143  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::removeTemporaryPointIfExists";
144 
145  m_graphicsLinesForCurves.removeTemporaryPointIfExists ();
146 }
147 
149 {
150  // LOG4CPP_INFO_S is below
151 
152  int itemsBefore = items().count();
153 
154  m_graphicsLinesForCurves.resetOnLoad();
155 
156  int itemsAfter = items().count();
157 
158  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::resetOnLoad"
159  << " itemsBefore=" << itemsBefore
160  << " itemsAfter=" << itemsAfter;
161 }
162 
164 {
165  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::resetPositionHasChangedFlags";
166 
167  QList<QGraphicsItem*> itms = items ();
168  QList<QGraphicsItem*>::const_iterator itr;
169  for (itr = itms.begin (); itr != itms.end (); itr++) {
170 
171  QGraphicsItem *item = *itr;
172  item->setData (DATA_KEY_POSITION_HAS_CHANGED, false);
173  }
174 }
175 
177 {
178  const QList<QGraphicsItem*> &items = QGraphicsScene::selectedItems();
179 
180  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::selectedPointIdentifiers"
181  << " selectedItems=" << items.count();
182 
183  QStringList selectedIds;
184  QList<QGraphicsItem*>::const_iterator itr;
185  for (itr = items.begin(); itr != items.end(); itr++) {
186 
187  const QGraphicsItem* item = *itr;
188 
189  // Skip the image and only keep the Points
190  bool isPoint = (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt () == GRAPHICS_ITEM_TYPE_POINT);
191  if (isPoint) {
192 
193  // Add Point to the list
194  selectedIds << item->data(DATA_KEY_IDENTIFIER).toString ();
195 
196  }
197  }
198 
199  return selectedIds;
200 }
201 
203  bool showAll,
204  const QString &curveNameWanted)
205 {
206  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::showCurves"
207  << " show=" << (show ? "true" : "false")
208  << " showAll=" << (showAll ? "true" : "false")
209  << " curve=" << curveNameWanted.toLatin1().data();
210 
211  const QList<QGraphicsItem*> &items = QGraphicsScene::items();
212  QList<QGraphicsItem*>::const_iterator itr;
213  for (itr = items.begin(); itr != items.end(); itr++) {
214 
215  QGraphicsItem* item = *itr;
216 
217  // Skip the image and only process the Points
218  bool isPoint = (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt () == GRAPHICS_ITEM_TYPE_POINT);
219  bool isCurve = (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt () == GRAPHICS_ITEM_TYPE_LINE);
220 
221  if (isPoint || isCurve) {
222 
223  bool showThis = show;
224  if (show && !showAll) {
225  QString identifier = item->data (DATA_KEY_IDENTIFIER).toString ();
226 
227  if (isPoint) {
228 
229  QString curveNameGot = Point::curveNameFromPointIdentifier (identifier);
230  showThis = (curveNameWanted == curveNameGot);
231 
232  } else {
233 
234  showThis = (curveNameWanted == identifier);
235 
236  }
237  }
238 
239  item->setVisible (showThis);
240 
241  }
242  }
243 }
244 
246 {
247  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::updateAfterCommand";
248 
249  updateCurves (cmdMediator);
250 
251  // Update the points
252  updatePointMembership (cmdMediator);
253 }
254 
255 void GraphicsScene::updateCurves (CmdMediator &cmdMediator)
256 {
257  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::updateCurves";
258 
259  // Desired curve names include both axes and graph curve names
260  QStringList curveNames;
261  curveNames << AXIS_CURVE_NAME;
262  curveNames << cmdMediator.document().curvesGraphsNames();
263 
264  m_graphicsLinesForCurves.addRemoveCurves (*this,
265  curveNames);
266 }
267 
268 void GraphicsScene::updateCurveStyles (const CurveStyles &modelCurveStyles)
269 {
270  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::updateCurveStyles";
271 
272  m_graphicsLinesForCurves.updateCurveStyles (modelCurveStyles);
273 }
274 
276  const Transformation &transformation)
277 {
278  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::updateGraphicsLinesToMatchGraphicsPoints";
279 
280  if (transformation.transformIsDefined()) {
281 
282  // Ordinals must be updated to reflect reordering that may have resulted from dragging points
283  m_graphicsLinesForCurves.updatePointOrdinalsAfterDrag (curveStyles,
284  transformation);
285 
286  // Recompute the lines one time for efficiency
287  m_graphicsLinesForCurves.updateGraphicsLinesToMatchGraphicsPoints (curveStyles);
288  }
289 }
290 
291 void GraphicsScene::updatePointMembership (CmdMediator &cmdMediator)
292 {
293  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsScene::updatePointMembership";
294 
295  CallbackSceneUpdateAfterCommand ftor (m_graphicsLinesForCurves,
296  *this,
297  cmdMediator.document ());
298  Functor2wRet<const QString &, const Point &, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
300 
301  // First pass:
302  // 1) Mark all points as Not Wanted (this is done while creating the map)
303  m_graphicsLinesForCurves.lineMembershipReset ();
304 
305  // Next pass:
306  // 1) Existing points that are found in the map are marked as Wanted
307  // 2) Add new points that were just created in the Document. The new points are marked as Wanted
308  cmdMediator.iterateThroughCurvePointsAxes (ftorWithCallback);
309  cmdMediator.iterateThroughCurvesPointsGraphs (ftorWithCallback);
310 
311  // Next pass:
312  // 1) Remove points that were just removed from the Document
313  m_graphicsLinesForCurves.lineMembershipPurge (cmdMediator.document().modelCurveStyles());
314 }
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:204
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:657
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:299
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:66