File indexing completed on 2024-05-12 15:26:41
0001 /*************************************************************************** 0002 File : DatapickerCurve.cpp 0003 Project : LabPlot 0004 Description : container for Curve-Point and Datasheet/Spreadsheet 0005 of datapicker 0006 -------------------------------------------------------------------- 0007 Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com) 0008 Copyright : (C) 2015-2019 Alexander Semke (alexander.semke@web.de) 0009 ***************************************************************************/ 0010 /*************************************************************************** 0011 * * 0012 * This program is free software; you can redistribute it and/or modify * 0013 * it under the terms of the GNU General Public License as published by * 0014 * the Free Software Foundation; either version 2 of the License, or * 0015 * (at your option) any later version. * 0016 * * 0017 * This program is distributed in the hope that it will be useful, * 0018 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0020 * GNU General Public License for more details. * 0021 * * 0022 * You should have received a copy of the GNU General Public License * 0023 * along with this program; if not, write to the Free Software * 0024 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0025 * Boston, MA 02110-1301 USA * 0026 * * 0027 ***************************************************************************/ 0028 0029 #include "DatapickerCurve.h" 0030 #include "backend/datapicker/DatapickerCurvePrivate.h" 0031 #include "backend/datapicker/Datapicker.h" 0032 #include "backend/datapicker/DatapickerPoint.h" 0033 #include "backend/lib/commandtemplates.h" 0034 #include "backend/lib/XmlStreamReader.h" 0035 #include "backend/spreadsheet/Spreadsheet.h" 0036 #include "backend/worksheet/Worksheet.h" 0037 0038 #include <QIcon> 0039 #include <QVector3D> 0040 0041 #include <KConfig> 0042 #include <KLocalizedString> 0043 #include <KConfigGroup> 0044 0045 /** 0046 * \class DatapickerCurve 0047 * \brief Top-level container for Curve-Point and Datasheet/Spreadsheet of datapicker. 0048 * \ingroup backend 0049 */ 0050 0051 DatapickerCurve::DatapickerCurve(const QString &name) 0052 : AbstractAspect(name, AspectType::DatapickerCurve), d_ptr(new DatapickerCurvePrivate(this)) { 0053 0054 init(); 0055 } 0056 0057 DatapickerCurve::DatapickerCurve(const QString &name, DatapickerCurvePrivate *dd) 0058 : AbstractAspect(name, AspectType::DatapickerCurve), d_ptr(dd) { 0059 0060 init(); 0061 } 0062 0063 DatapickerCurve::~DatapickerCurve() { 0064 delete d_ptr; 0065 } 0066 0067 void DatapickerCurve::init() { 0068 Q_D(DatapickerCurve); 0069 0070 KConfig config; 0071 KConfigGroup group; 0072 group = config.group("DatapickerCurve"); 0073 d->curveErrorTypes.x = (ErrorType) group.readEntry("CurveErrorType_X", static_cast<int>(ErrorType::NoError)); 0074 d->curveErrorTypes.y = (ErrorType) group.readEntry("CurveErrorType_Y", static_cast<int>(ErrorType::NoError)); 0075 0076 // point properties 0077 d->pointStyle = (Symbol::Style)group.readEntry("PointStyle", static_cast<int>(Symbol::Style::Cross)); 0078 d->pointSize = group.readEntry("Size", Worksheet::convertToSceneUnits(7, Worksheet::Unit::Point)); 0079 d->pointRotationAngle = group.readEntry("Rotation", 0.0); 0080 d->pointOpacity = group.readEntry("Opacity", 1.0); 0081 d->pointBrush.setStyle( (Qt::BrushStyle)group.readEntry("FillingStyle", (int)Qt::NoBrush) ); 0082 d->pointBrush.setColor( group.readEntry("FillingColor", QColor(Qt::black)) ); 0083 d->pointPen.setStyle( (Qt::PenStyle)group.readEntry("BorderStyle", (int)Qt::SolidLine) ); 0084 d->pointPen.setColor( group.readEntry("BorderColor", QColor(Qt::red)) ); 0085 d->pointPen.setWidthF( group.readEntry("BorderWidth", Worksheet::convertToSceneUnits(1, Worksheet::Unit::Point)) ); 0086 d->pointErrorBarSize = group.readEntry("ErrorBarSize", Worksheet::convertToSceneUnits(8, Worksheet::Unit::Point)); 0087 d->pointErrorBarBrush.setStyle( (Qt::BrushStyle)group.readEntry("ErrorBarFillingStyle", (int)Qt::NoBrush) ); 0088 d->pointErrorBarBrush.setColor( group.readEntry("ErrorBarFillingColor", QColor(Qt::black)) ); 0089 d->pointErrorBarPen.setStyle( (Qt::PenStyle)group.readEntry("ErrorBarBorderStyle", (int)Qt::SolidLine) ); 0090 d->pointErrorBarPen.setColor( group.readEntry("ErrorBarBorderColor", QColor(Qt::black)) ); 0091 d->pointErrorBarPen.setWidthF( group.readEntry("ErrorBarBorderWidth", Worksheet::convertToSceneUnits(1, Worksheet::Unit::Point)) ); 0092 d->pointVisibility = group.readEntry("PointVisibility", true); 0093 } 0094 0095 /*! 0096 Returns an icon to be used in the project explorer. 0097 */ 0098 QIcon DatapickerCurve::icon() const { 0099 return QIcon::fromTheme("labplot-xy-curve"); 0100 } 0101 0102 Column* DatapickerCurve::appendColumn(const QString& name) { 0103 Column* col = new Column(i18n("Column"), AbstractColumn::ColumnMode::Numeric); 0104 col->insertRows(0, m_datasheet->rowCount()); 0105 col->setName(name); 0106 m_datasheet->addChild(col); 0107 0108 return col; 0109 } 0110 0111 //############################################################################## 0112 //########################## getter methods ################################## 0113 //############################################################################## 0114 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, DatapickerCurve::Errors, curveErrorTypes, curveErrorTypes) 0115 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, Symbol::Style, pointStyle, pointStyle) 0116 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, qreal, pointOpacity, pointOpacity) 0117 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, qreal, pointRotationAngle, pointRotationAngle) 0118 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, qreal, pointSize, pointSize) 0119 CLASS_SHARED_D_READER_IMPL(DatapickerCurve, QBrush, pointBrush, pointBrush) 0120 CLASS_SHARED_D_READER_IMPL(DatapickerCurve, QPen, pointPen, pointPen) 0121 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, qreal, pointErrorBarSize, pointErrorBarSize) 0122 CLASS_SHARED_D_READER_IMPL(DatapickerCurve, QBrush, pointErrorBarBrush, pointErrorBarBrush) 0123 CLASS_SHARED_D_READER_IMPL(DatapickerCurve, QPen, pointErrorBarPen, pointErrorBarPen) 0124 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, bool, pointVisibility, pointVisibility) 0125 0126 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, AbstractColumn*, posXColumn, posXColumn) 0127 QString& DatapickerCurve::posXColumnPath() const { 0128 return d_ptr->posXColumnPath; 0129 } 0130 0131 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, AbstractColumn*, posYColumn, posYColumn) 0132 QString& DatapickerCurve::posYColumnPath() const { 0133 return d_ptr->posYColumnPath; 0134 } 0135 0136 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, AbstractColumn*, posZColumn, posZColumn) 0137 QString& DatapickerCurve::posZColumnPath() const { 0138 return d_ptr->posZColumnPath; 0139 } 0140 0141 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, AbstractColumn*, plusDeltaXColumn, plusDeltaXColumn) 0142 QString& DatapickerCurve::plusDeltaXColumnPath() const { 0143 return d_ptr->plusDeltaXColumnPath; 0144 } 0145 0146 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, AbstractColumn*, minusDeltaXColumn, minusDeltaXColumn) 0147 QString& DatapickerCurve::minusDeltaXColumnPath() const { 0148 return d_ptr->minusDeltaXColumnPath; 0149 } 0150 0151 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, AbstractColumn*, plusDeltaYColumn, plusDeltaYColumn) 0152 QString& DatapickerCurve::plusDeltaYColumnPath() const { 0153 return d_ptr->plusDeltaYColumnPath; 0154 } 0155 0156 BASIC_SHARED_D_READER_IMPL(DatapickerCurve, AbstractColumn*, minusDeltaYColumn, minusDeltaYColumn) 0157 QString& DatapickerCurve::minusDeltaYColumnPath() const { 0158 return d_ptr->minusDeltaYColumnPath; 0159 } 0160 0161 //############################################################################## 0162 //######################### setter methods ################################### 0163 //############################################################################## 0164 void DatapickerCurve::addDatasheet(DatapickerImage::GraphType type) { 0165 Q_D(DatapickerCurve); 0166 0167 m_datasheet = new Spreadsheet(i18n("Data")); 0168 addChild(m_datasheet); 0169 QString xLabel('x'); 0170 QString yLabel('y'); 0171 0172 if (type == DatapickerImage::GraphType::PolarInDegree) { 0173 xLabel = QLatin1String("r"); 0174 yLabel = QLatin1String("y(deg)"); 0175 } else if (type == DatapickerImage::GraphType::PolarInRadians) { 0176 xLabel = QLatin1String("r"); 0177 yLabel = QLatin1String("y(rad)"); 0178 } else if (type == DatapickerImage::GraphType::LogarithmicX) { 0179 xLabel = QLatin1String("log(x)"); 0180 yLabel = QLatin1String("y"); 0181 } else if (type == DatapickerImage::GraphType::LogarithmicY) { 0182 xLabel = QLatin1String("x"); 0183 yLabel = QLatin1String("log(y)"); 0184 } 0185 0186 if (type == DatapickerImage::GraphType::Ternary) 0187 d->posZColumn = appendColumn(i18n("c")); 0188 0189 d->posXColumn = m_datasheet->column(0); 0190 d->posXColumn->setName(xLabel); 0191 0192 d->posYColumn = m_datasheet->column(1); 0193 d->posYColumn->setName(yLabel); 0194 } 0195 0196 STD_SETTER_CMD_IMPL_S(DatapickerCurve, SetCurveErrorTypes, DatapickerCurve::Errors, curveErrorTypes) 0197 void DatapickerCurve::setCurveErrorTypes(const DatapickerCurve::Errors errors) { 0198 Q_D(DatapickerCurve); 0199 if (d->curveErrorTypes.x != errors.x || d->curveErrorTypes.y != errors.y) { 0200 beginMacro(i18n("%1: set xy-error type", name())); 0201 exec(new DatapickerCurveSetCurveErrorTypesCmd(d, errors, ki18n("%1: set xy-error type"))); 0202 0203 if ( errors.x != ErrorType::NoError && !d->plusDeltaXColumn ) 0204 setPlusDeltaXColumn(appendColumn(QLatin1String("+delta_x"))); 0205 else if ( d->plusDeltaXColumn && errors.x ==ErrorType:: NoError ) { 0206 d->plusDeltaXColumn->remove(); 0207 d->plusDeltaXColumn = nullptr; 0208 } 0209 0210 if ( errors.x == ErrorType::AsymmetricError && !d->minusDeltaXColumn ) 0211 setMinusDeltaXColumn(appendColumn(QLatin1String("-delta_x"))); 0212 else if ( d->minusDeltaXColumn && errors.x != ErrorType::AsymmetricError ) { 0213 d->minusDeltaXColumn->remove(); 0214 d->minusDeltaXColumn = nullptr; 0215 } 0216 0217 if ( errors.y != ErrorType::NoError && !d->plusDeltaYColumn ) 0218 setPlusDeltaYColumn(appendColumn(QLatin1String("+delta_y"))); 0219 else if ( d->plusDeltaYColumn && errors.y == ErrorType::NoError ) { 0220 d->plusDeltaYColumn->remove(); 0221 d->plusDeltaYColumn = nullptr; 0222 } 0223 0224 if ( errors.y == ErrorType::AsymmetricError && !d->minusDeltaYColumn ) 0225 setMinusDeltaYColumn(appendColumn(QLatin1String("-delta_y"))); 0226 else if ( d->minusDeltaYColumn && errors.y != ErrorType::AsymmetricError ) { 0227 d->minusDeltaYColumn->remove(); 0228 d->minusDeltaYColumn = nullptr; 0229 } 0230 0231 endMacro(); 0232 } 0233 } 0234 0235 STD_SETTER_CMD_IMPL_S(DatapickerCurve, SetPosXColumn, AbstractColumn*, posXColumn) 0236 void DatapickerCurve::setPosXColumn(AbstractColumn* column) { 0237 Q_D(DatapickerCurve); 0238 if (d->posXColumn != column) 0239 exec(new DatapickerCurveSetPosXColumnCmd(d, column, ki18n("%1: set position X column"))); 0240 } 0241 0242 STD_SETTER_CMD_IMPL_S(DatapickerCurve, SetPosYColumn, AbstractColumn*, posYColumn) 0243 void DatapickerCurve::setPosYColumn(AbstractColumn* column) { 0244 Q_D(DatapickerCurve); 0245 if (d->posYColumn != column) 0246 exec(new DatapickerCurveSetPosYColumnCmd(d, column, ki18n("%1: set position Y column"))); 0247 } 0248 0249 STD_SETTER_CMD_IMPL_S(DatapickerCurve, SetPosZColumn, AbstractColumn*, posZColumn) 0250 void DatapickerCurve::setPosZColumn(AbstractColumn* column) { 0251 Q_D(DatapickerCurve); 0252 if (d->posZColumn != column) 0253 exec(new DatapickerCurveSetPosZColumnCmd(d, column, ki18n("%1: set position Z column"))); 0254 } 0255 0256 STD_SETTER_CMD_IMPL_S(DatapickerCurve, SetPlusDeltaXColumn, AbstractColumn*, plusDeltaXColumn) 0257 void DatapickerCurve::setPlusDeltaXColumn(AbstractColumn* column) { 0258 Q_D(DatapickerCurve); 0259 if (d->plusDeltaXColumn != column) 0260 exec(new DatapickerCurveSetPlusDeltaXColumnCmd(d, column, ki18n("%1: set +delta_X column"))); 0261 } 0262 0263 STD_SETTER_CMD_IMPL_S(DatapickerCurve, SetMinusDeltaXColumn, AbstractColumn*, minusDeltaXColumn) 0264 void DatapickerCurve::setMinusDeltaXColumn(AbstractColumn* column) { 0265 Q_D(DatapickerCurve); 0266 if (d->minusDeltaXColumn != column) 0267 exec(new DatapickerCurveSetMinusDeltaXColumnCmd(d, column, ki18n("%1: set -delta_X column"))); 0268 } 0269 0270 STD_SETTER_CMD_IMPL_S(DatapickerCurve, SetPlusDeltaYColumn, AbstractColumn*, plusDeltaYColumn) 0271 void DatapickerCurve::setPlusDeltaYColumn(AbstractColumn* column) { 0272 Q_D(DatapickerCurve); 0273 if (d->plusDeltaYColumn != column) 0274 exec(new DatapickerCurveSetPlusDeltaYColumnCmd(d, column, ki18n("%1: set +delta_Y column"))); 0275 } 0276 0277 STD_SETTER_CMD_IMPL_S(DatapickerCurve, SetMinusDeltaYColumn, AbstractColumn*, minusDeltaYColumn) 0278 void DatapickerCurve::setMinusDeltaYColumn(AbstractColumn* column) { 0279 Q_D(DatapickerCurve); 0280 if (d->minusDeltaYColumn != column) 0281 exec(new DatapickerCurveSetMinusDeltaYColumnCmd(d, column, ki18n("%1: set -delta_Y column"))); 0282 } 0283 0284 STD_SETTER_CMD_IMPL_F_S(DatapickerCurve, SetPointStyle, Symbol::Style, pointStyle, retransform) 0285 void DatapickerCurve::setPointStyle(Symbol::Style newStyle) { 0286 Q_D(DatapickerCurve); 0287 if (newStyle != d->pointStyle) 0288 exec(new DatapickerCurveSetPointStyleCmd(d, newStyle, ki18n("%1: set point's style"))); 0289 } 0290 0291 STD_SETTER_CMD_IMPL_F_S(DatapickerCurve, SetPointSize, qreal, pointSize, retransform) 0292 void DatapickerCurve::setPointSize(qreal value) { 0293 Q_D(DatapickerCurve); 0294 if (!qFuzzyCompare(1 + value, 1 + d->pointSize)) 0295 exec(new DatapickerCurveSetPointSizeCmd(d, value, ki18n("%1: set point's size"))); 0296 } 0297 0298 STD_SETTER_CMD_IMPL_F_S(DatapickerCurve, SetPointRotationAngle, qreal, pointRotationAngle, retransform) 0299 void DatapickerCurve::setPointRotationAngle(qreal angle) { 0300 Q_D(DatapickerCurve); 0301 if (!qFuzzyCompare(1 + angle, 1 + d->pointRotationAngle)) 0302 exec(new DatapickerCurveSetPointRotationAngleCmd(d, angle, ki18n("%1: rotate point"))); 0303 } 0304 0305 STD_SETTER_CMD_IMPL_F_S(DatapickerCurve, SetPointBrush, QBrush, pointBrush, retransform) 0306 void DatapickerCurve::setPointBrush(const QBrush& newBrush) { 0307 Q_D(DatapickerCurve); 0308 if (newBrush != d->pointBrush) 0309 exec(new DatapickerCurveSetPointBrushCmd(d, newBrush, ki18n("%1: set point's filling"))); 0310 } 0311 0312 STD_SETTER_CMD_IMPL_F_S(DatapickerCurve, SetPointPen, QPen, pointPen, retransform) 0313 void DatapickerCurve::setPointPen(const QPen &newPen) { 0314 Q_D(DatapickerCurve); 0315 if (newPen != d->pointPen) 0316 exec(new DatapickerCurveSetPointPenCmd(d, newPen, ki18n("%1: set outline style"))); 0317 } 0318 0319 STD_SETTER_CMD_IMPL_F_S(DatapickerCurve, SetPointOpacity, qreal, pointOpacity, retransform) 0320 void DatapickerCurve::setPointOpacity(qreal newOpacity) { 0321 Q_D(DatapickerCurve); 0322 if (newOpacity != d->pointOpacity) 0323 exec(new DatapickerCurveSetPointOpacityCmd(d, newOpacity, ki18n("%1: set point's opacity"))); 0324 } 0325 0326 STD_SETTER_CMD_IMPL_F_S(DatapickerCurve, SetPointErrorBarSize, qreal, pointErrorBarSize, retransform) 0327 void DatapickerCurve::setPointErrorBarSize(qreal size) { 0328 Q_D(DatapickerCurve); 0329 if (size != d->pointErrorBarSize) 0330 exec(new DatapickerCurveSetPointErrorBarSizeCmd(d, size, ki18n("%1: set error bar size"))); 0331 } 0332 0333 STD_SETTER_CMD_IMPL_F_S(DatapickerCurve, SetPointErrorBarBrush, QBrush, pointErrorBarBrush, retransform) 0334 void DatapickerCurve::setPointErrorBarBrush(const QBrush &brush) { 0335 Q_D(DatapickerCurve); 0336 if (brush != d->pointErrorBarBrush) 0337 exec(new DatapickerCurveSetPointErrorBarBrushCmd(d, brush, ki18n("%1: set error bar filling"))); 0338 } 0339 0340 STD_SETTER_CMD_IMPL_F_S(DatapickerCurve, SetPointErrorBarPen, QPen, pointErrorBarPen, retransform) 0341 void DatapickerCurve::setPointErrorBarPen(const QPen &pen) { 0342 Q_D(DatapickerCurve); 0343 if (pen != d->pointErrorBarPen) 0344 exec(new DatapickerCurveSetPointErrorBarPenCmd(d, pen, ki18n("%1: set error bar outline style"))); 0345 } 0346 0347 STD_SETTER_CMD_IMPL_F_S(DatapickerCurve, SetPointVisibility, bool, pointVisibility, retransform) 0348 void DatapickerCurve::setPointVisibility(bool on) { 0349 Q_D(DatapickerCurve); 0350 if (on != d->pointVisibility) 0351 exec(new DatapickerCurveSetPointVisibilityCmd(d, on, on ? ki18n("%1: set visible") : ki18n("%1: set invisible"))); 0352 } 0353 0354 void DatapickerCurve::setPrinting(bool on) { 0355 for (auto* point : children<DatapickerPoint>(AbstractAspect::ChildIndexFlag::IncludeHidden)) 0356 point->setPrinting(on); 0357 } 0358 0359 /*! 0360 Selects or deselects the Datapicker/Curve in the project explorer. 0361 This function is called in \c DatapickerImageView. 0362 */ 0363 void DatapickerCurve::setSelectedInView(bool b) { 0364 if (b) 0365 emit childAspectSelectedInView(this); 0366 else 0367 emit childAspectDeselectedInView(this); 0368 } 0369 //############################################################################## 0370 //###### SLOTs for changes triggered via QActions in the context menu ######## 0371 //############################################################################## 0372 void DatapickerCurve::updatePoints() { 0373 for (auto* point : children<DatapickerPoint>(ChildIndexFlag::IncludeHidden)) 0374 updatePoint(point); 0375 } 0376 0377 /*! 0378 Update datasheet for corresponding curve-point, 0379 it is called every time whenever there is any change in position 0380 of curve-point or its error-bar so keep it undo unaware 0381 no need to create extra entry in undo stack 0382 */ 0383 void DatapickerCurve::updatePoint(const DatapickerPoint* point) { 0384 Q_D(DatapickerCurve); 0385 0386 //TODO: this check shouldn't be required. 0387 //redesign the retransform()-call in load() to avoid it. 0388 if (!parentAspect()) 0389 return; 0390 0391 auto* datapicker = static_cast<Datapicker*>(parentAspect()); 0392 int row = indexOfChild<DatapickerPoint>(point, ChildIndexFlag::IncludeHidden); 0393 QVector3D data = datapicker->mapSceneToLogical(point->position()); 0394 0395 if (d->posXColumn) 0396 d->posXColumn->setValueAt(row, data.x()); 0397 0398 if (d->posYColumn) 0399 d->posYColumn->setValueAt(row, data.y()); 0400 0401 if (d->posZColumn) 0402 d->posZColumn->setValueAt(row, data.y()); 0403 0404 if (d->plusDeltaXColumn) { 0405 data = datapicker->mapSceneLengthToLogical(QPointF(point->plusDeltaXPos().x(), 0)); 0406 d->plusDeltaXColumn->setValueAt(row, qAbs(data.x())); 0407 } 0408 0409 if (d->minusDeltaXColumn) { 0410 data = datapicker->mapSceneLengthToLogical(QPointF(point->minusDeltaXPos().x(), 0)); 0411 d->minusDeltaXColumn->setValueAt(row, qAbs(data.x())); 0412 } 0413 0414 if (d->plusDeltaYColumn) { 0415 data = datapicker->mapSceneLengthToLogical(QPointF(0, point->plusDeltaYPos().y())); 0416 d->plusDeltaYColumn->setValueAt(row, qAbs(data.y())); 0417 } 0418 0419 if (d->minusDeltaYColumn) { 0420 data = datapicker->mapSceneLengthToLogical(QPointF(0, point->minusDeltaYPos().y())); 0421 d->minusDeltaYColumn->setValueAt(row, qAbs(data.y())); 0422 } 0423 } 0424 0425 //############################################################################## 0426 //####################### Private implementation ############################### 0427 //############################################################################## 0428 DatapickerCurvePrivate::DatapickerCurvePrivate(DatapickerCurve *curve) : q(curve) { 0429 } 0430 0431 QString DatapickerCurvePrivate::name() const { 0432 return q->name(); 0433 } 0434 0435 void DatapickerCurvePrivate::retransform() { 0436 auto points = q->children<DatapickerPoint>(AbstractAspect::ChildIndexFlag::IncludeHidden); 0437 for (auto* point : points) 0438 point->retransform(); 0439 } 0440 0441 //############################################################################## 0442 //################## Serialization/Deserialization ########################### 0443 //############################################################################## 0444 //! Save as XML 0445 void DatapickerCurve::save(QXmlStreamWriter* writer) const { 0446 Q_D(const DatapickerCurve); 0447 0448 writer->writeStartElement("datapickerCurve"); 0449 writeBasicAttributes(writer); 0450 writeCommentElement(writer); 0451 0452 //general 0453 writer->writeStartElement("general"); 0454 WRITE_COLUMN(d->posXColumn, posXColumn); 0455 WRITE_COLUMN(d->posYColumn, posYColumn); 0456 WRITE_COLUMN(d->posZColumn, posZColumn); 0457 WRITE_COLUMN(d->plusDeltaXColumn, plusDeltaXColumn); 0458 WRITE_COLUMN(d->minusDeltaXColumn, minusDeltaXColumn); 0459 WRITE_COLUMN(d->plusDeltaYColumn, plusDeltaYColumn); 0460 WRITE_COLUMN(d->minusDeltaYColumn, minusDeltaYColumn); 0461 writer->writeAttribute( "curveErrorType_X", QString::number(static_cast<int>(d->curveErrorTypes.x)) ); 0462 writer->writeAttribute( "curveErrorType_Y", QString::number(static_cast<int>(d->curveErrorTypes.y)) ); 0463 writer->writeEndElement(); 0464 0465 //symbol properties 0466 writer->writeStartElement("symbolProperties"); 0467 writer->writeAttribute( "pointRotationAngle", QString::number(d->pointRotationAngle) ); 0468 writer->writeAttribute( "pointOpacity", QString::number(d->pointOpacity) ); 0469 writer->writeAttribute( "pointSize", QString::number(d->pointSize) ); 0470 writer->writeAttribute( "pointStyle", QString::number(static_cast<int>(d->pointStyle)) ); 0471 writer->writeAttribute( "pointVisibility", QString::number(d->pointVisibility) ); 0472 WRITE_QBRUSH(d->pointBrush); 0473 WRITE_QPEN(d->pointPen); 0474 writer->writeEndElement(); 0475 0476 //error bar properties 0477 writer->writeStartElement("errorBarProperties"); 0478 writer->writeAttribute( "pointErrorBarSize", QString::number(d->pointErrorBarSize) ); 0479 WRITE_QBRUSH(d->pointErrorBarBrush); 0480 WRITE_QPEN(d->pointErrorBarPen); 0481 writer->writeEndElement(); 0482 0483 //serialize all children 0484 for (auto* child : children<AbstractAspect>(ChildIndexFlag::IncludeHidden)) 0485 child->save(writer); 0486 0487 writer->writeEndElement(); // close section 0488 } 0489 0490 //! Load from XML 0491 bool DatapickerCurve::load(XmlStreamReader* reader, bool preview) { 0492 Q_D(DatapickerCurve); 0493 0494 if (!readBasicAttributes(reader)) 0495 return false; 0496 0497 KLocalizedString attributeWarning = ki18n("Attribute '%1' missing or empty, default value is used"); 0498 QXmlStreamAttributes attribs; 0499 QString str; 0500 0501 while (!reader->atEnd()) { 0502 reader->readNext(); 0503 if (reader->isEndElement() && reader->name() == "datapickerCurve") 0504 break; 0505 0506 if (!reader->isStartElement()) 0507 continue; 0508 0509 if (reader->name() == "comment") { 0510 if (!readCommentElement(reader)) return false; 0511 } else if (!preview && reader->name() == "general") { 0512 attribs = reader->attributes(); 0513 0514 READ_INT_VALUE("curveErrorType_X", curveErrorTypes.x, ErrorType); 0515 READ_INT_VALUE("curveErrorType_Y", curveErrorTypes.y, ErrorType); 0516 0517 READ_COLUMN(posXColumn); 0518 READ_COLUMN(posYColumn); 0519 READ_COLUMN(posZColumn); 0520 READ_COLUMN(plusDeltaXColumn); 0521 READ_COLUMN(minusDeltaXColumn); 0522 READ_COLUMN(plusDeltaYColumn); 0523 READ_COLUMN(minusDeltaYColumn); 0524 } else if (!preview && reader->name() == "symbolProperties") { 0525 attribs = reader->attributes(); 0526 0527 READ_DOUBLE_VALUE("pointRotationAngle", pointRotationAngle); 0528 READ_DOUBLE_VALUE("pointOpacity", pointOpacity); 0529 READ_DOUBLE_VALUE("pointSize", pointSize); 0530 READ_INT_VALUE("pointStyle", pointStyle, Symbol::Style); 0531 READ_INT_VALUE("pointVisibility", pointVisibility, bool); 0532 0533 READ_QBRUSH(d->pointBrush); 0534 READ_QPEN(d->pointPen); 0535 } else if (!preview && reader->name() == "errorBarProperties") { 0536 attribs = reader->attributes(); 0537 0538 READ_DOUBLE_VALUE("pointErrorBarSize", pointErrorBarSize); 0539 READ_QBRUSH(d->pointErrorBarBrush); 0540 READ_QPEN(d->pointErrorBarPen); 0541 } else if (reader->name() == "datapickerPoint") { 0542 auto* curvePoint = new DatapickerPoint(QString()); 0543 curvePoint->setHidden(true); 0544 if (!curvePoint->load(reader, preview)) { 0545 delete curvePoint; 0546 return false; 0547 } else { 0548 addChild(curvePoint); 0549 curvePoint->initErrorBar(curveErrorTypes()); 0550 } 0551 } else if (reader->name() == "spreadsheet") { 0552 Spreadsheet* datasheet = new Spreadsheet("spreadsheet", true); 0553 if (!datasheet->load(reader, preview)) { 0554 delete datasheet; 0555 return false; 0556 } else { 0557 addChild(datasheet); 0558 m_datasheet = datasheet; 0559 } 0560 } else { // unknown element 0561 reader->raiseWarning(i18n("unknown element '%1'", reader->name().toString())); 0562 if (!reader->skipToEndElement()) return false; 0563 } 0564 } 0565 0566 d->retransform(); 0567 return true; 0568 }