Engauge Digitizer  2
 All Classes Files Functions Variables Enumerations Enumerator Friends Pages
CurvesGraphs.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 "Curve.h"
8 #include "CurvesGraphs.h"
9 #include "CurveStyles.h"
10 #include "DocumentSerialize.h"
11 #include "EngaugeAssert.h"
12 #include "Logger.h"
13 #include "Point.h"
14 #include <qdebug.h>
15 #include <QTextStream>
16 #include <QXmlStreamWriter>
17 #include "Transformation.h"
18 #include "Xml.h"
19 
20 CurvesGraphs::CurvesGraphs()
21 {
22 }
23 
25 {
26  m_curvesGraphs.push_back (curve);
27 }
28 
29 void CurvesGraphs::addPoint (const Point &point)
30 {
31  QString curveName = Point::curveNameFromPointIdentifier (point.identifier());
32 
33  Curve *curve = curveForCurveName (curveName);
34  curve->addPoint (point);
35 }
36 
37 Curve *CurvesGraphs::curveForCurveName (const QString &curveName)
38 {
39  // Search for curve with matching name
40  CurveList::iterator itr;
41  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
42 
43  Curve &curve = *itr;
44  if (curveName == curve.curveName ()) {
45  return &curve;
46  }
47  }
48 
49  return 0;
50 }
51 
52 const Curve *CurvesGraphs::curveForCurveName (const QString &curveName) const
53 {
54  // Search for curve with matching name
55  CurveList::const_iterator itr;
56  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
57 
58  const Curve &curve = *itr;
59  if (curveName == curve.curveName ()) {
60  return &curve;
61  }
62  }
63 
64  return 0;
65 }
66 
67 QStringList CurvesGraphs::curvesGraphsNames () const
68 {
69  QStringList names;
70 
71  CurveList::const_iterator itr;
72  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
73 
74  const Curve &curve = *itr;
75  names << curve.curveName ();
76  }
77 
78  return names;
79 }
80 
81 int CurvesGraphs::curvesGraphsNumPoints (const QString &curveName) const
82 {
83  // Search for curve with matching name
84  CurveList::const_iterator itr;
85  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
86 
87  const Curve &curve = *itr;
88  if (curve.curveName () == curveName) {
89  return curve.numPoints ();
90  }
91  }
92 
93  return 0;
94 }
95 
96 void CurvesGraphs::iterateThroughCurvePoints (const QString &curveNameWanted,
97  const Functor2wRet<const QString &, const Point &, CallbackSearchReturn> &ftorWithCallback)
98 {
99  // Search for curve with matching name
100  CurveList::const_iterator itr;
101  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
102 
103  const Curve &curve = *itr;
104  if (curve.curveName () == curveNameWanted) {
105 
106  curve.iterateThroughCurvePoints (ftorWithCallback);
107  return;
108  }
109  }
110 
111  ENGAUGE_ASSERT (false);
112 }
113 
114 void CurvesGraphs::iterateThroughCurveSegments (const QString &curveNameWanted,
115  const Functor2wRet<const Point &, const Point &, CallbackSearchReturn> &ftorWithCallback) const
116 {
117  // Search for curve with matching name
118  CurveList::const_iterator itr;
119  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
120 
121  const Curve &curve = *itr;
122  if (curve.curveName () == curveNameWanted) {
123 
124  curve.iterateThroughCurveSegments (ftorWithCallback);
125  return;
126  }
127  }
128 
129  ENGAUGE_ASSERT (false);
130 }
131 
132 void CurvesGraphs::iterateThroughCurvesPoints (const Functor2wRet<const QString &, const Point &, CallbackSearchReturn> &ftorWithCallback)
133 {
134  CurveList::const_iterator itr;
135  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
136 
137  const Curve &curve = *itr;
138  curve.iterateThroughCurvePoints (ftorWithCallback);
139  }
140 }
141 
142 void CurvesGraphs::iterateThroughCurvesPoints (const Functor2wRet<const QString &, const Point &, CallbackSearchReturn> &ftorWithCallback) const
143 {
144  CurveList::const_iterator itr;
145  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
146 
147  const Curve &curve = *itr;
148  curve.iterateThroughCurvePoints (ftorWithCallback);
149  }
150 }
151 
152 void CurvesGraphs::loadPreVersion6(QDataStream &str)
153 {
154  LOG4CPP_INFO_S ((*mainCat)) << "CurvesGraphs::loadPreVersion6";
155 
156  int i;
157 
158  // Remove previous Curves. There is a DEFAULT_GRAPH_CURVE_NAME by default
159  m_curvesGraphs.clear();
160 
161  qint32 numberCurvesGraphs;
162  str >> numberCurvesGraphs;
163  for (i = 0; i < numberCurvesGraphs; i++) {
164  Curve curve (str);
165  m_curvesGraphs.append (curve);
166  }
167 
168  qint32 numberCurvesMeasures;
169  str >> numberCurvesMeasures;
170  for (i = 0; i < numberCurvesMeasures; i++) {
171  Curve curve (str);
172 
173  // Measures get dropped on the floor
174  }
175 }
176 
177 void CurvesGraphs::loadXml(QXmlStreamReader &reader)
178 {
179  LOG4CPP_INFO_S ((*mainCat)) << "CurvesGraphs::loadXml";
180 
181  bool success = true;
182 
183  // Remove previous Curves. There is a DEFAULT_GRAPH_CURVE_NAME by default
184  m_curvesGraphs.clear();
185 
186  // Read until end of this subtree
187  while ((reader.tokenType() != QXmlStreamReader::EndElement) ||
188  (reader.name() != DOCUMENT_SERIALIZE_CURVES_GRAPHS)){
189 
190  loadNextFromReader(reader);
191  if (reader.atEnd()) {
192  success = false;
193  break;
194  }
195 
196  if ((reader.tokenType() == QXmlStreamReader::StartElement) &&
197  (reader.name () == DOCUMENT_SERIALIZE_CURVE)) {
198 
199  Curve curve (reader);
200 
201  // Version 6 of Engauge let users create multiple curves with the same name. Reading a file with duplicate
202  // curve names can result in crashes and/or corruption, so we deconflict duplicate curve names here
203  QString DUPLICATE = QString ("-%1").arg (QObject::tr ("DUPLICATE"));
204  QString curveName = curve.curveName();
205  while (curvesGraphsNames().contains (curveName)) {
206  curveName += DUPLICATE;
207  }
208  curve.setCurveName (curveName); // No effect if curve name was not a duplicate
209 
210  // Add the curve
211  m_curvesGraphs.push_back (curve);
212 
213  }
214  }
215 
216  if (!success) {
217  reader.raiseError (QObject::tr ("Cannot read graph curves data"));
218  }
219 }
220 
222 {
223  return m_curvesGraphs.count ();
224 }
225 
226 void CurvesGraphs::printStream (QString indentation,
227  QTextStream &str) const
228 {
229  str << indentation << "CurvesGraphs\n";
230 
231  indentation += INDENTATION_DELTA;
232 
233  CurveList::const_iterator itr;
234  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
235 
236  const Curve &curve = *itr;
237  curve.printStream (indentation,
238  str);
239  }
240 }
241 
242 void CurvesGraphs::removePoint (const QString &pointIdentifier)
243 {
244  QString curveName = Point::curveNameFromPointIdentifier(pointIdentifier);
245 
246  Curve *curve = curveForCurveName (curveName);
247  curve->removePoint (pointIdentifier);
248 }
249 
250 void CurvesGraphs::saveXml(QXmlStreamWriter &writer) const
251 {
252  LOG4CPP_INFO_S ((*mainCat)) << "CurvesGraphs::saveXml";
253 
254  writer.writeStartElement(DOCUMENT_SERIALIZE_CURVES_GRAPHS);
255 
256  CurveList::const_iterator itr;
257  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
258 
259  const Curve &curve = *itr;
260  curve.saveXml (writer);
261  }
262 
263  writer.writeEndElement();
264 }
265 
267 {
268  LOG4CPP_INFO_S ((*mainCat)) << "CurvesGraphs::updatePointOrdinals";
269 
270  CurveList::iterator itr;
271  for (itr = m_curvesGraphs.begin (); itr != m_curvesGraphs.end (); itr++) {
272 
273  Curve &curve = *itr;
274  curve.updatePointOrdinals (transformation);
275  }
276 }
void removePoint(const QString &identifier)
Perform the opposite of addPointAtEnd.
Definition: Curve.cpp:452
static QString curveNameFromPointIdentifier(const QString &pointIdentifier)
Parse the curve name from the specified point identifier. This does the opposite of uniqueIdentifierG...
Definition: Point.cpp:227
void saveXml(QXmlStreamWriter &writer) const
Serialize curves.
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
void loadXml(QXmlStreamReader &reader)
Load from serialized xml post-version 5 file.
void iterateThroughCurveSegments(const QString &curveNameWanted, const Functor2wRet< const Point &, const Point &, CallbackSearchReturn > &ftorWithCallback) const
Apply functor to segments on the specified axis or graph Curve.
Curve * curveForCurveName(const QString &curveName)
Return the axis or graph curve for the specified curve name.
int numCurves() const
Current number of graphs curves.
int numPoints() const
Number of points.
Definition: Curve.cpp:374
void updatePointOrdinals(const Transformation &transformation)
See CurveGraphs::updatePointOrdinals.
Definition: Curve.cpp:510
void addGraphCurveAtEnd(Curve curve)
Append new graph Curve to end of Curve list.
void iterateThroughCurvesPoints(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
Apply functor to Points on all of the Curves.
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition: Point.h:23
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
Definition: Curve.cpp:432
QString identifier() const
Unique identifier for a specific Point.
Definition: Point.cpp:256
Affine transformation between screen and graph coordinates, based on digitized axis points...
void addPoint(const Point &point)
Append new Point to the specified Curve.
void iterateThroughCurvePoints(const QString &curveNameWanted, const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
Apply functor to Points in the specified axis or graph Curve.
void iterateThroughCurvePoints(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback) const
Apply functor to Points on Curve.
Definition: Curve.cpp:243
void setCurveName(const QString &curveName)
Change the curve name.
Definition: Curve.cpp:493
int curvesGraphsNumPoints(const QString &curveName) const
Point count.
Container for one set of digitized Points.
Definition: Curve.h:32
void updatePointOrdinals(const Transformation &transformation)
Update point ordinals to be consistent with their CurveStyle and x/theta coordinate.
void loadPreVersion6(QDataStream &str)
Load from serialized binary pre-version 6 file.
QStringList curvesGraphsNames() const
List of graph curve names.
void removePoint(const QString &pointIdentifier)
Remove the Point from its Curve.
void iterateThroughCurveSegments(const Functor2wRet< const Point &, const Point &, CallbackSearchReturn > &ftorWithCallback) const
Apply functor to successive Points, as line segments, on Curve. This could be a bit slow...
Definition: Curve.cpp:258
void saveXml(QXmlStreamWriter &writer) const
Serialize curve.
Definition: Curve.cpp:465
QString curveName() const
Name of this Curve.
Definition: Curve.cpp:134