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 "CmdMediator.h"
8 #include "CoordUnitsDate.h"
9 #include "CoordUnitsTime.h"
10 #include "DocumentModelCoords.h"
11 #include "DocumentSerialize.h"
12 #include "EngaugeAssert.h"
13 #include "Logger.h"
14 #include <QObject>
15 #include <QTextStream>
16 #include "QtToString.h"
17 #include <QXmlStreamWriter>
18 #include "Xml.h"
19
20 const double PI = 3.1415926535;
21 const double TWO_PI = 2.0 * PI;
22
23 // Zero default for origin radius, which is usually wanted for COORD_SCALE_LINEAR, it is illegal
24 // for COORD_SCALE_LOG (for which 1.0 is probably preferred as the default. Note linear is more common than log
25 const double DEFAULT_ORIGIN_RADIUS_LINEAR = 0.0;
26
DocumentModelCoords()27 DocumentModelCoords::DocumentModelCoords() :
28 m_coordsType (COORDS_TYPE_CARTESIAN),
29 m_originRadius (DEFAULT_ORIGIN_RADIUS_LINEAR),
30 m_coordScaleXTheta (COORD_SCALE_LINEAR),
31 m_coordScaleYRadius (COORD_SCALE_LINEAR),
32 m_coordUnitsX (COORD_UNITS_NON_POLAR_THETA_NUMBER),
33 m_coordUnitsY (COORD_UNITS_NON_POLAR_THETA_NUMBER),
34 m_coordUnitsTheta (COORD_UNITS_POLAR_THETA_DEGREES),
35 m_coordUnitsRadius (COORD_UNITS_NON_POLAR_THETA_NUMBER),
36 m_coordUnitsDate (COORD_UNITS_DATE_YEAR_MONTH_DAY),
37 m_coordUnitsTime (COORD_UNITS_TIME_HOUR_MINUTE_SECOND)
38 {
39 }
40
DocumentModelCoords(const Document & document)41 DocumentModelCoords::DocumentModelCoords(const Document &document) :
42 m_coordsType (document.modelCoords().coordsType()),
43 m_originRadius(document.modelCoords().originRadius()),
44 m_coordScaleXTheta(document.modelCoords().coordScaleXTheta()),
45 m_coordScaleYRadius(document.modelCoords().coordScaleYRadius()),
46 m_coordUnitsX(document.modelCoords().coordUnitsX()),
47 m_coordUnitsY(document.modelCoords().coordUnitsY()),
48 m_coordUnitsTheta(document.modelCoords().coordUnitsTheta()),
49 m_coordUnitsRadius(document.modelCoords().coordUnitsRadius()),
50 m_coordUnitsDate(document.modelCoords().coordUnitsDate()),
51 m_coordUnitsTime(document.modelCoords().coordUnitsTime())
52 {
53 }
54
DocumentModelCoords(const DocumentModelCoords & other)55 DocumentModelCoords::DocumentModelCoords(const DocumentModelCoords &other) :
56 m_coordsType (other.coordsType ()),
57 m_originRadius (other.originRadius ()),
58 m_coordScaleXTheta (other.coordScaleXTheta()),
59 m_coordScaleYRadius (other.coordScaleYRadius ()),
60 m_coordUnitsX (other.coordUnitsX()),
61 m_coordUnitsY (other.coordUnitsY()),
62 m_coordUnitsTheta (other.coordUnitsTheta ()),
63 m_coordUnitsRadius (other.coordUnitsRadius ()),
64 m_coordUnitsDate (other.coordUnitsDate ()),
65 m_coordUnitsTime (other.coordUnitsTime ())
66 {
67 }
68
operator =(const DocumentModelCoords & other)69 DocumentModelCoords &DocumentModelCoords::operator=(const DocumentModelCoords &other)
70 {
71 m_coordsType = other.coordsType();
72 m_originRadius = other.originRadius();
73 m_coordScaleXTheta = other.coordScaleXTheta();
74 m_coordScaleYRadius = other.coordScaleYRadius();
75 m_coordUnitsX = other.coordUnitsX();
76 m_coordUnitsY = other.coordUnitsY();
77 m_coordUnitsTheta = other.coordUnitsTheta();
78 m_coordUnitsRadius = other.coordUnitsRadius();
79 m_coordUnitsDate = other.coordUnitsDate();
80 m_coordUnitsTime = other.coordUnitsTime();
81
82 return *this;
83 }
84
coordScaleXTheta() const85 CoordScale DocumentModelCoords::coordScaleXTheta () const
86 {
87 return m_coordScaleXTheta;
88 }
89
coordScaleYRadius() const90 CoordScale DocumentModelCoords::coordScaleYRadius () const
91 {
92 return m_coordScaleYRadius;
93 }
94
coordsType() const95 CoordsType DocumentModelCoords::coordsType () const
96 {
97 return m_coordsType;
98 }
99
coordUnitsDate() const100 CoordUnitsDate DocumentModelCoords::coordUnitsDate() const
101 {
102 return m_coordUnitsDate;
103 }
104
coordUnitsRadius() const105 CoordUnitsNonPolarTheta DocumentModelCoords::coordUnitsRadius() const
106 {
107 return m_coordUnitsRadius;
108 }
109
coordUnitsTheta() const110 CoordUnitsPolarTheta DocumentModelCoords::coordUnitsTheta() const
111 {
112 return m_coordUnitsTheta;
113 }
114
coordUnitsTime() const115 CoordUnitsTime DocumentModelCoords::coordUnitsTime() const
116 {
117 return m_coordUnitsTime;
118 }
119
coordUnitsX() const120 CoordUnitsNonPolarTheta DocumentModelCoords::coordUnitsX() const
121 {
122 return m_coordUnitsX;
123 }
124
coordUnitsY() const125 CoordUnitsNonPolarTheta DocumentModelCoords::coordUnitsY() const
126 {
127 return m_coordUnitsY;
128 }
129
loadXml(QXmlStreamReader & reader)130 void DocumentModelCoords::loadXml(QXmlStreamReader &reader)
131 {
132 LOG4CPP_INFO_S ((*mainCat)) << "DocumentModelCoords::loadXml";
133
134 bool success = true;
135
136 QXmlStreamAttributes attributes = reader.attributes();
137
138 if (attributes.hasAttribute(DOCUMENT_SERIALIZE_COORDS_TYPE) &&
139 attributes.hasAttribute(DOCUMENT_SERIALIZE_COORDS_ORIGIN_RADIUS) &&
140 attributes.hasAttribute(DOCUMENT_SERIALIZE_COORDS_SCALE_X_THETA) &&
141 attributes.hasAttribute(DOCUMENT_SERIALIZE_COORDS_SCALE_Y_RADIUS) &&
142 attributes.hasAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_X) &&
143 attributes.hasAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_Y) &&
144 attributes.hasAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_THETA) &&
145 attributes.hasAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_RADIUS) &&
146 attributes.hasAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_DATE) &&
147 attributes.hasAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_TIME)) {
148
149 setCoordsType (static_cast<CoordsType> (attributes.value(DOCUMENT_SERIALIZE_COORDS_TYPE).toInt()));
150 setOriginRadius (attributes.value(DOCUMENT_SERIALIZE_COORDS_ORIGIN_RADIUS).toDouble());
151 setCoordScaleXTheta (static_cast<CoordScale> (attributes.value(DOCUMENT_SERIALIZE_COORDS_SCALE_X_THETA).toInt()));
152 setCoordScaleYRadius (static_cast<CoordScale> (attributes.value(DOCUMENT_SERIALIZE_COORDS_SCALE_Y_RADIUS).toInt()));
153 setCoordUnitsX (static_cast<CoordUnitsNonPolarTheta> (attributes.value(DOCUMENT_SERIALIZE_COORDS_UNITS_X).toInt()));
154 setCoordUnitsY (static_cast<CoordUnitsNonPolarTheta> (attributes.value(DOCUMENT_SERIALIZE_COORDS_UNITS_Y).toInt()));
155 setCoordUnitsTheta (static_cast<CoordUnitsPolarTheta> (attributes.value(DOCUMENT_SERIALIZE_COORDS_UNITS_THETA).toInt()));
156 setCoordUnitsRadius (static_cast<CoordUnitsNonPolarTheta> (attributes.value(DOCUMENT_SERIALIZE_COORDS_UNITS_RADIUS).toInt()));
157 setCoordUnitsDate (static_cast<CoordUnitsDate> (attributes.value(DOCUMENT_SERIALIZE_COORDS_UNITS_DATE).toInt()));
158 setCoordUnitsTime (static_cast<CoordUnitsTime> (attributes.value(DOCUMENT_SERIALIZE_COORDS_UNITS_TIME).toInt()));
159
160 // Read until end of this subtree
161 while ((reader.tokenType() != QXmlStreamReader::EndElement) ||
162 (reader.name() != DOCUMENT_SERIALIZE_COORDS)){
163 loadNextFromReader(reader);
164 if (reader.atEnd()) {
165 success = false;
166 break;
167 }
168 }
169 }
170
171 if (!success) {
172 reader.raiseError (QObject::tr ("Cannot read coordinates data"));
173 }
174 }
175
originRadius() const176 double DocumentModelCoords::originRadius() const
177 {
178 return m_originRadius;
179 }
180
printStream(QString indentation,QTextStream & str) const181 void DocumentModelCoords::printStream(QString indentation,
182 QTextStream &str) const
183 {
184 str << indentation << "DocumentModelCoords\n";
185
186 indentation += INDENTATION_DELTA;
187
188 str << indentation << "coordsType=" << coordsTypeToString (m_coordsType) << "\n";
189 str << indentation << "originRadius=" << m_originRadius << "\n";
190 str << indentation << "coordScaleXTheta=" << coordScaleToString (m_coordScaleXTheta) << "\n";
191 str << indentation << "coordScaleYRadius=" << coordScaleToString (m_coordScaleYRadius) << "\n";
192 str << indentation << "coordUnitsX=" << coordUnitsNonPolarThetaToString (m_coordUnitsX) << "\n";
193 str << indentation << "coordUnitsY=" << coordUnitsNonPolarThetaToString (m_coordUnitsY) << "\n";
194 str << indentation << "coordUnitsTheta=" << coordUnitsPolarThetaToString (m_coordUnitsTheta) << "\n";
195 str << indentation << "coordUnitsRadius=" << coordUnitsNonPolarThetaToString (m_coordUnitsRadius) << "\n";
196 str << indentation << "coordUnitsDate=" << coordUnitsDateToString (m_coordUnitsDate) << "\n";
197 str << indentation << "coordUnitsTime=" << coordUnitsTimeToString (m_coordUnitsTime) << "\n";
198 }
199
saveXml(QXmlStreamWriter & writer) const200 void DocumentModelCoords::saveXml(QXmlStreamWriter &writer) const
201 {
202 LOG4CPP_INFO_S ((*mainCat)) << "DocumentModelCoords::saveXml";
203
204 writer.writeStartElement(DOCUMENT_SERIALIZE_COORDS);
205 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_TYPE, QString::number (m_coordsType));
206 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_TYPE_STRING, coordsTypeToString (m_coordsType));
207 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_ORIGIN_RADIUS, QString::number (m_originRadius));
208 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_SCALE_X_THETA, QString::number (m_coordScaleXTheta));
209 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_SCALE_X_THETA_STRING, coordScaleToString (m_coordScaleXTheta));
210 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_SCALE_Y_RADIUS, QString::number (m_coordScaleYRadius));
211 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_SCALE_Y_RADIUS_STRING, coordScaleToString (m_coordScaleYRadius));
212 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_X, QString::number (m_coordUnitsX));
213 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_X_STRING, coordUnitsNonPolarThetaToString (m_coordUnitsX));
214 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_Y, QString::number (m_coordUnitsY));
215 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_Y_STRING, coordUnitsNonPolarThetaToString (m_coordUnitsY));
216 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_THETA, QString::number (m_coordUnitsTheta));
217 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_THETA_STRING, coordUnitsPolarThetaToString (m_coordUnitsTheta));
218 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_RADIUS, QString::number (m_coordUnitsRadius));
219 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_RADIUS_STRING, coordUnitsNonPolarThetaToString (m_coordUnitsRadius));
220 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_DATE, QString::number (m_coordUnitsDate));
221 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_DATE_STRING, coordUnitsDateToString (m_coordUnitsDate));
222 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_TIME, QString::number (m_coordUnitsTime));
223 writer.writeAttribute(DOCUMENT_SERIALIZE_COORDS_UNITS_TIME_STRING, coordUnitsTimeToString (m_coordUnitsTime));
224 writer.writeEndElement();
225 }
226
setCoordScaleXTheta(CoordScale coordScale)227 void DocumentModelCoords::setCoordScaleXTheta (CoordScale coordScale)
228 {
229 m_coordScaleXTheta = coordScale;
230 }
231
setCoordScaleYRadius(CoordScale coordScale)232 void DocumentModelCoords::setCoordScaleYRadius (CoordScale coordScale)
233 {
234 m_coordScaleYRadius = coordScale;
235 }
236
setCoordsType(CoordsType coordsType)237 void DocumentModelCoords::setCoordsType (CoordsType coordsType)
238 {
239 m_coordsType = coordsType;
240 }
241
setCoordUnitsDate(CoordUnitsDate coordUnits)242 void DocumentModelCoords::setCoordUnitsDate(CoordUnitsDate coordUnits)
243 {
244 m_coordUnitsDate = coordUnits;
245 }
246
setCoordUnitsRadius(CoordUnitsNonPolarTheta coordUnits)247 void DocumentModelCoords::setCoordUnitsRadius (CoordUnitsNonPolarTheta coordUnits)
248 {
249 m_coordUnitsRadius = coordUnits;
250 }
251
setCoordUnitsTheta(CoordUnitsPolarTheta coordUnits)252 void DocumentModelCoords::setCoordUnitsTheta (CoordUnitsPolarTheta coordUnits)
253 {
254 m_coordUnitsTheta = coordUnits;
255 }
256
setCoordUnitsTime(CoordUnitsTime coordUnits)257 void DocumentModelCoords::setCoordUnitsTime(CoordUnitsTime coordUnits)
258 {
259 m_coordUnitsTime = coordUnits;
260 }
261
setCoordUnitsX(CoordUnitsNonPolarTheta coordUnits)262 void DocumentModelCoords::setCoordUnitsX (CoordUnitsNonPolarTheta coordUnits)
263 {
264 m_coordUnitsX = coordUnits;
265 }
266
setCoordUnitsY(CoordUnitsNonPolarTheta coordUnits)267 void DocumentModelCoords::setCoordUnitsY (CoordUnitsNonPolarTheta coordUnits)
268 {
269 m_coordUnitsY = coordUnits;
270 }
271
setOriginRadius(double originRadius)272 void DocumentModelCoords::setOriginRadius(double originRadius)
273 {
274 m_originRadius = originRadius;
275 }
276
thetaPeriod() const277 double DocumentModelCoords::thetaPeriod () const
278 {
279 switch (m_coordUnitsTheta) {
280 case COORD_UNITS_POLAR_THETA_DEGREES:
281 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
282 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
283 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
284 return 360;
285
286 case COORD_UNITS_POLAR_THETA_GRADIANS:
287 return 400;
288
289 case COORD_UNITS_POLAR_THETA_RADIANS:
290 return TWO_PI;
291
292 case COORD_UNITS_POLAR_THETA_TURNS:
293 return 1;
294
295 default:
296 break;
297 }
298
299 LOG4CPP_ERROR_S ((*mainCat)) << "DocumentModelCoords::thetaPeriod";
300
301 ENGAUGE_ASSERT(false);
302 return 0;
303 }
304