Engauge Digitizer  2
GraphicsLinesForCurve.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 "DataKey.h"
8 #include "EngaugeAssert.h"
9 #include "EnumsToQt.h"
10 #include "GeometryWindow.h"
11 #include "GraphicsItemType.h"
12 #include "GraphicsLinesForCurve.h"
13 #include "GraphicsPoint.h"
14 #include "GraphicsScene.h"
15 #include "LineStyle.h"
16 #include "Logger.h"
17 #include "Point.h"
18 #include "PointStyle.h"
19 #include <QGraphicsItem>
20 #include <QMap>
21 #include <QPainterPath>
22 #include <QPen>
23 #include <QTextStream>
24 #include "QtToString.h"
25 #include "Spline.h"
26 #include "SplineDrawer.h"
27 #include "Transformation.h"
28 #include "ZValues.h"
29 
30 using namespace std;
31 
32 typedef QMap<double, double> XOrThetaToOrdinal;
33 
35  m_curveName (curveName)
36 {
37  setZValue (Z_VALUE_CURVE);
40  setData (DATA_KEY_IDENTIFIER,
41  QVariant (m_curveName));
42 }
43 
45 {
46  OrdinalToGraphicsPoint::iterator itr;
47  for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
48  GraphicsPoint *point = itr.value();
49  delete point;
50  }
51 
52  m_graphicsPoints.clear();
53 }
54 
55 void GraphicsLinesForCurve::addPoint (const QString &pointIdentifier,
56  double ordinal,
57  GraphicsPoint &graphicsPoint)
58 {
59  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::addPoint"
60  << " curve=" << m_curveName.toLatin1().data()
61  << " identifier=" << pointIdentifier.toLatin1().data()
62  << " ordinal=" << ordinal
63  << " pos=" << QPointFToString (graphicsPoint.pos()).toLatin1().data()
64  << " newPointCount=" << (m_graphicsPoints.count() + 1);
65 
66  m_graphicsPoints [ordinal] = &graphicsPoint;
67 }
68 
69 QPainterPath GraphicsLinesForCurve::drawLinesSmooth (const LineStyle &lineStyle,
70  SplineDrawer &splineDrawer,
71  QPainterPath &pathMultiValued,
72  LineStyle &lineMultiValued)
73 {
74  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::drawLinesSmooth"
75  << " curve=" << m_curveName.toLatin1().data();
76 
77  QPainterPath path;
78 
79  // Prepare spline inputs. Note that the ordinal values may not start at 0
80  vector<double> t;
81  vector<SplinePair> xy;
82  OrdinalToGraphicsPoint::const_iterator itr;
83  for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
84 
85  double ordinal = itr.key();
86  const GraphicsPoint *point = itr.value();
87 
88  t.push_back (ordinal);
89  xy.push_back (SplinePair (point->pos ().x(),
90  point->pos ().y()));
91  }
92 
93  // Spline class requires at least one point
94  if (xy.size() > 0) {
95 
96  // Spline through points
97  Spline spline (t, xy);
98 
99  splineDrawer.bindToSpline (lineStyle,
100  m_graphicsPoints.count(),
101  spline);
102 
103  // Create QPainterPath through the points. Loop has one segment per stop point,
104  // with first point handled outside first
105  int segment; // Only incremented after a draw, corresponding to finishing a segment
106  OrdinalToGraphicsPoint::const_iterator itr = m_graphicsPoints.begin();
107 
108  const GraphicsPoint *point = itr.value();
109  path.moveTo (point->pos ());
110  pathMultiValued.moveTo (point->pos ());
111  ++itr;
112 
113  for (segment = 0;
114  itr != m_graphicsPoints.end();
115  segment++, itr++) {
116 
117  const GraphicsPoint *point = itr.value();
118 
119  SplineDrawerOperation operation = splineDrawer.segmentOperation (segment);
120 
121  QPointF p1 (spline.p1 (unsigned (segment)).x(),
122  spline.p1 (unsigned (segment)).y());
123  QPointF p2 (spline.p2 (unsigned (segment)).x(),
124  spline.p2 (unsigned (segment)).y());
125 
126  switch (operation) {
128  {
129  // Show this segment
130  path.cubicTo (p1,
131  p2,
132  point->pos ());
133  }
134  break;
135 
137 
138  // Hide this segment as a regular curve, and show it as the error curve
139  path.moveTo (point->pos ());
140 
141  // Show curveMultiValued instead in what would have been the original curve's path
142  OrdinalToGraphicsPoint::const_iterator itrBefore = itr - 1;
143  const GraphicsPoint *pointBefore = itrBefore.value();
144  pathMultiValued.moveTo (pointBefore->pos ());
145  pathMultiValued.cubicTo (p1,
146  p2,
147  point->pos ());
148  lineMultiValued = lineStyle; // Remember to not use the same line style
149  break;
150 
151  }
152 
153  // Always move to next point for curveMultiValued
154  pathMultiValued.moveTo (point->pos ());
155  }
156  }
157 
158  return path;
159 }
160 
161 QPainterPath GraphicsLinesForCurve::drawLinesStraight (QPainterPath & /* pathMultiValued */)
162 {
163  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::drawLinesStraight"
164  << " curve=" << m_curveName.toLatin1().data();
165 
166  QPainterPath path;
167 
168  // Create QPainterPath through the points
169  bool isFirst = true;
170  OrdinalToGraphicsPoint::const_iterator itr;
171  for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
172 
173  const GraphicsPoint *point = itr.value();
174 
175  if (isFirst) {
176  isFirst = false;
177  path.moveTo (point->pos ());
178  } else {
179  path.lineTo (point->pos ());
180  }
181  }
182 
183  return path;
184 }
185 
186 double GraphicsLinesForCurve::identifierToOrdinal (const QString &identifier) const
187 {
188  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::identifierToOrdinal"
189  << " identifier=" << identifier.toLatin1().data();
190 
191  OrdinalToGraphicsPoint::const_iterator itr;
192  for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
193 
194  const GraphicsPoint *point = itr.value();
195 
196  if (point->data (DATA_KEY_IDENTIFIER) == identifier) {
197  return itr.key();
198  }
199  }
200 
201  ENGAUGE_ASSERT (false);
202 
203  return 0;
204 }
205 
207  SplineDrawer &splineDrawer,
208  QPainterPath &pathMultiValued,
209  LineStyle &lineMultiValued)
210 {
211  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::lineMembershipPurge"
212  << " curve=" << m_curveName.toLatin1().data();
213 
214  OrdinalToGraphicsPoint::iterator itr, itrNext;
215  for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr = itrNext) {
216 
217  itrNext = itr;
218  ++itrNext;
219 
220  GraphicsPoint *point = *itr;
221 
222  if (!point->wanted ()) {
223 
224  double ordinal = itr.key ();
225 
226  delete point;
227  m_graphicsPoints.remove (ordinal);
228  }
229  }
230 
231  // Apply line style
232  QPen pen;
233  if (lineStyle.paletteColor() == COLOR_PALETTE_TRANSPARENT) {
234 
235  pen = QPen (Qt::NoPen);
236 
237  } else {
238 
239  pen = QPen (QBrush (ColorPaletteToQColor (lineStyle.paletteColor())),
240  lineStyle.width());
241 
242  }
243 
244  setPen (pen);
245 
247  splineDrawer,
248  pathMultiValued,
249  lineMultiValued);
250 }
251 
253 {
254  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::lineMembershipReset"
255  << " curve=" << m_curveName.toLatin1().data();
256 
257  OrdinalToGraphicsPoint::iterator itr;
258  for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
259 
260  GraphicsPoint *point = itr.value();
261 
262  point->reset ();
263  }
264 }
265 
266 bool GraphicsLinesForCurve::needOrdinalRenumbering () const
267 {
268  // Ordinals should be 0, 1, ...
269  bool needRenumbering = false;
270  for (int ordinalKeyWanted = 0; ordinalKeyWanted < m_graphicsPoints.count(); ordinalKeyWanted++) {
271 
272  double ordinalKeyGot = m_graphicsPoints.keys().at (ordinalKeyWanted);
273 
274  // Sanity checks
275  ENGAUGE_ASSERT (ordinalKeyGot != Point::UNDEFINED_ORDINAL ());
276 
277  if (ordinalKeyWanted != ordinalKeyGot) {
278  needRenumbering = true;
279  break;
280  }
281  }
282 
283  return needRenumbering;
284 }
285 
286 void GraphicsLinesForCurve::printStream (QString indentation,
287  QTextStream &str) const
288 {
289  DataKey type = static_cast<DataKey> (data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt());
290 
291  str << indentation << "GraphicsLinesForCurve=" << m_curveName
292  << " dataIdentifier=" << data (DATA_KEY_IDENTIFIER).toString().toLatin1().data()
293  << " dataType=" << dataKeyToString (type).toLatin1().data() << "\n";
294 
295  indentation += INDENTATION_DELTA;
296 
297  OrdinalToGraphicsPoint::const_iterator itr;
298  for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
299 
300  double ordinalKey = itr.key();
301  const GraphicsPoint *point = itr.value();
302 
303  point->printStream (indentation,
304  str,
305  ordinalKey);
306  }
307 }
308 
310 {
311  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::removePoint"
312  << " point=" << ordinal
313  << " pointCount=" << m_graphicsPoints.count();
314 
315  ENGAUGE_ASSERT (m_graphicsPoints.contains (ordinal));
316  GraphicsPoint *graphicsPoint = m_graphicsPoints [ordinal];
317 
318  m_graphicsPoints.remove (ordinal);
319 
320  delete graphicsPoint;
321 }
322 
324 {
325  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::removeTemporaryPointIfExists";
326 
327  // Compiler warning about this loop only iterating once is not an issue since there
328  // is never more than one temporary point
329  OrdinalToGraphicsPoint::iterator itr;
330  for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
331 
332  GraphicsPoint *graphicsPoint = itr.value();
333 
334  m_graphicsPoints.remove (itr.key());
335 
336  delete graphicsPoint;
337 
338  break;
339  }
340 }
341 
342 void GraphicsLinesForCurve::renumberOrdinals ()
343 {
344  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::renumberOrdinals";
345 
346  int ordinalKeyWanted;
347 
348  // Ordinals should be 0, 1, and so on. Assigning a list to QMap::keys has no effect, so the
349  // approach is to copy to a temporary list and then copy back
350  QList<GraphicsPoint*> points;
351  for (ordinalKeyWanted = 0; ordinalKeyWanted < m_graphicsPoints.count(); ordinalKeyWanted++) {
352 
353  GraphicsPoint *graphicsPoint = m_graphicsPoints.values().at (ordinalKeyWanted);
354  points << graphicsPoint;
355  }
356 
357  m_graphicsPoints.clear ();
358 
359  for (ordinalKeyWanted = 0; ordinalKeyWanted < points.count(); ordinalKeyWanted++) {
360 
361  GraphicsPoint *graphicsPoint = points.at (ordinalKeyWanted);
362  m_graphicsPoints [ordinalKeyWanted] = graphicsPoint;
363  }
364 }
365 
367  const PointStyle &pointStyle,
368  const Point &point,
369  GeometryWindow *geometryWindow)
370 {
371  LOG4CPP_DEBUG_S ((*mainCat)) << "GraphicsLinesForCurve::updateAfterCommand"
372  << " curve=" << m_curveName.toLatin1().data()
373  << " pointCount=" << m_graphicsPoints.count();
374 
375  GraphicsPoint *graphicsPoint = nullptr;
376  if (m_graphicsPoints.contains (point.ordinal())) {
377 
378  graphicsPoint = m_graphicsPoints [point.ordinal()];
379 
380  // Due to ordinal renumbering, the coordinates may belong to some other point so we override
381  // them for consistent ordinal-position mapping. Updating the identifier also was added for
382  // better logging (i.e. consistency between Document and GraphicsScene dumps), but happened
383  // to fix a bug with the wrong set of points getting deleted from Cut and Delete
384  graphicsPoint->setPos (point.posScreen());
385  graphicsPoint->setData (DATA_KEY_IDENTIFIER, point.identifier());
386 
387  } else {
388 
389  // Point does not exist in scene so create it
390  graphicsPoint = scene.createPoint (point.identifier (),
391  pointStyle,
392  point.posScreen(),
393  geometryWindow);
394  m_graphicsPoints [point.ordinal ()] = graphicsPoint;
395 
396  }
397 
398  // Mark point as wanted
399  ENGAUGE_CHECK_PTR (graphicsPoint);
400  graphicsPoint->setWanted ();
401 }
402 
404 {
405  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::updateCurveStyle";
406 
407  OrdinalToGraphicsPoint::const_iterator itr;
408  for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
409 
410  GraphicsPoint *point = itr.value();
411  point->updateCurveStyle (curveStyle);
412  }
413 }
414 
415 void GraphicsLinesForCurve::updateHighlightOpacity (double highlightOpacity)
416 {
417  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::updateCurveStyle"
418  << " curve=" << m_curveName.toLatin1().data()
419  << " highlightOpacity=" << highlightOpacity;
420 
421  OrdinalToGraphicsPoint::const_iterator itr;
422  for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
423 
424  GraphicsPoint *point = itr.value();
425  point->setHighlightOpacity (highlightOpacity);
426  }
427 }
428 
430  SplineDrawer &splineDrawer,
431  QPainterPath &pathMultiValued,
432  LineStyle &lineMultiValued)
433 {
434  // LOG4CPP_INFO_S is below
435 
436  bool needRenumbering = needOrdinalRenumbering ();
437  if (needRenumbering) {
438 
439  renumberOrdinals();
440 
441  }
442 
443  LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::updateGraphicsLinesToMatchGraphicsPoints"
444  << " numberPoints=" << m_graphicsPoints.count()
445  << " ordinalRenumbering=" << (needRenumbering ? "true" : "false");
446 
447  if (lineStyle.curveConnectAs() != CONNECT_SKIP_FOR_AXIS_CURVE) {
448 
449  // Draw as either straight or smoothed. The function/relation differences were handled already with ordinals. The
450  // Spline algorithm will crash with fewer than three points so it is only called when there are enough points
451  QPainterPath path;
452  if (lineStyle.curveConnectAs() == CONNECT_AS_FUNCTION_STRAIGHT ||
454  m_graphicsPoints.count () < 3) {
455 
456  path = drawLinesStraight (pathMultiValued);
457  } else {
458  path = drawLinesSmooth (lineStyle,
459  splineDrawer,
460  pathMultiValued,
461  lineMultiValued);
462  }
463 
464  setPath (path);
465  }
466 }
467 
469  const Transformation &transformation)
470 {
471  CurveConnectAs curveConnectAs = lineStyle.curveConnectAs();
472 
473  LOG4CPP_DEBUG_S ((*mainCat)) << "GraphicsLinesForCurve::updatePointOrdinalsAfterDrag"
474  << " curve=" << m_curveName.toLatin1().data()
475  << " curveConnectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
476 
477  if (curveConnectAs == CONNECT_AS_FUNCTION_SMOOTH ||
478  curveConnectAs == CONNECT_AS_FUNCTION_STRAIGHT) {
479 
480  // Make sure ordinals are properly ordered
481 
482  // Get a map of x/theta values as keys with point identifiers as the values
483  XOrThetaToOrdinal xOrThetaToOrdinal;
484  OrdinalToGraphicsPoint::iterator itrP;
485  for (itrP = m_graphicsPoints.begin(); itrP != m_graphicsPoints.end(); itrP++) {
486 
487  double ordinal = itrP.key();
488  const GraphicsPoint *point = itrP.value();
489 
490  // Convert screen coordinate to graph coordinates, which gives us x/theta
491  QPointF pointGraph;
492  transformation.transformScreenToRawGraph(point->pos (),
493  pointGraph);
494 
495  xOrThetaToOrdinal [pointGraph.x()] = ordinal;
496  }
497 
498  // Loop through the sorted x/theta values. Since QMap is used, the x/theta keys are sorted
499  OrdinalToGraphicsPoint temporaryList;
500  int ordinalNew = 0;
501  XOrThetaToOrdinal::const_iterator itrX;
502  for (itrX = xOrThetaToOrdinal.begin(); itrX != xOrThetaToOrdinal.end(); itrX++) {
503 
504  double ordinalOld = *itrX;
505  GraphicsPoint *point = m_graphicsPoints [ordinalOld];
506 
507  temporaryList [ordinalNew++] = point;
508  }
509 
510  // Copy from temporary back to original map
511  m_graphicsPoints.clear();
512  for (itrP = temporaryList.begin(); itrP != temporaryList.end(); itrP++) {
513 
514  double ordinal = itrP.key();
515  GraphicsPoint *point = itrP.value();
516 
517  m_graphicsPoints [ordinal] = point;
518  }
519  }
520 }
void lineMembershipReset()
Mark points as unwanted. Afterwards, lineMembershipPurge gets called.
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition: LineStyle.cpp:63
QString dataKeyToString(DataKey dataKey)
Definition: DataKey.cpp:9
Cubic interpolation given independent and dependent value vectors.
Definition: Spline.h:29
QMap< double, double > XOrThetaToOrdinal
void setWanted()
Mark point as wanted. Marking as unwanted is done by the reset function.
QPointF pos() const
Proxy method for QGraphicsItem::pos.
void updateCurveStyle(const CurveStyle &curveStyle)
Update the curve style for this curve.
SplineDrawerOperation
Definition: SplineDrawer.h:17
unsigned int width() const
Width of line.
Definition: LineStyle.cpp:173
void setHighlightOpacity(double highlightOpacity)
Set method for highlight opacity.
const QString INDENTATION_DELTA
QVariant data(int key) const
Proxy method for QGraphicsItem::data.
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition: Point.h:25
Window that displays the geometry information, as a table, for the current curve. ...
void setData(int key, const QVariant &data)
Proxy method for QGraphicsItem::setData.
void setPos(const QPointF pos)
Update the position.
QPointF posScreen() const
Accessor for screen position.
Definition: Point.cpp:404
GraphicsLinesForCurve(const QString &curveName)
Single constructor.
Unique identifier for QGraphicsItem object
Definition: DataKey.h:15
double ordinal(ApplyHasCheck applyHasCheck=KEEP_HAS_CHECK) const
Get method for ordinal. Skip check if copying one instance to another.
Definition: Point.cpp:386
QMap< double, GraphicsPoint * > OrdinalToGraphicsPoint
DataKey
Index values for storing item details in QGraphicsItem using setData/data.
Definition: DataKey.h:13
void updateCurveStyle(const CurveStyle &curveStyle)
Update point and line styles that comprise the curve style.
const int Z_VALUE_CURVE
Definition: ZValues.cpp:10
#define ENGAUGE_CHECK_PTR(ptr)
#endif
Definition: EngaugeAssert.h:27
void updatePointOrdinalsAfterDrag(const LineStyle &lineStyle, const Transformation &transformation)
See GraphicsScene::updateOrdinalsAfterDrag. Pretty much the same steps as Curve::updatePointOrdinals...
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...
QString QPointFToString(const QPointF &pos)
Definition: QtToString.cpp:17
QString identifier() const
Unique identifier for a specific Point.
Definition: Point.cpp:268
ColorPalette paletteColor() const
Line color.
Definition: LineStyle.cpp:128
void lineMembershipPurge(const LineStyle &lineStyle, SplineDrawer &splineDrawer, QPainterPath &pathMultiValued, LineStyle &lineMultiValued)
Mark the end of addPoint calls. Remove stale lines, insert missing lines, and draw the graphics lines...
Affine transformation between screen and graph coordinates, based on digitized axis points...
Details for a specific Point.
Definition: PointStyle.h:20
void removeTemporaryPointIfExists()
Remove temporary point if it exists.
QColor ColorPaletteToQColor(ColorPalette color)
Definition: EnumsToQt.cpp:15
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
static double UNDEFINED_ORDINAL()
Get method for undefined ordinal constant.
Definition: Point.h:134
void printStream(QString indentation, QTextStream &str, double ordinalKey) const
Debugging method that supports print method of this class and printStream method of some other class(...
void updateHighlightOpacity(double highlightOpacity)
Update the highlight opacity value. This may or may not affect the current display immediately depend...
Container for LineStyle and PointStyle for one Curve.
Definition: CurveStyle.h:18
bool wanted() const
Identify point as wanted//unwanted.
CurveConnectAs
void updateAfterCommand(GraphicsScene &scene, const PointStyle &pointStyle, const Point &point, GeometryWindow *geometryWindow)
Update the GraphicsScene with the specified Point from the Document. If it does not exist yet in the ...
Details for a specific Line.
Definition: LineStyle.h:19
Graphics item for drawing a circular or polygonal Point.
Definition: GraphicsPoint.h:43
void bindToSpline(const LineStyle &lineStyle, int numSegments, const Spline &spline)
Analyze each segment in the Spline.
SplineDrawerOperation segmentOperation(int segment) const
Indicate if, and how, segment is to be drawn.
log4cpp::Category * mainCat
Definition: Logger.cpp:14
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.
QString curveConnectAsToString(CurveConnectAs curveConnectAs)
void addPoint(const QString &pointIdentifier, double ordinal, GraphicsPoint &point)
Add new line.
Add point and line handling to generic QGraphicsScene.
Definition: GraphicsScene.h:36
This class takes the output from Spline and uses that to draw the curve in the graphics window...
Definition: SplineDrawer.h:35
void updateGraphicsLinesToMatchGraphicsPoints(const LineStyle &lineStyle, SplineDrawer &splineDrawer, QPainterPath &pathMultiValued, LineStyle &lineMultiValued)
Calls to moveLinesWithDraggedPoint have finished so update the lines correspondingly.
void removePoint(double ordinal)
Remove the specified point. The act of deleting it will automatically remove it from the GraphicsScen...
Single X/Y pair for cubic spline interpolation initialization and calculations.
Definition: SplinePair.h:13
double identifierToOrdinal(const QString &identifier) const
Get ordinal for specified identifier.
#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
void reset()
Mark point as unwanted, and unbind any bound lines.