File indexing completed on 2024-05-12 03:47:29
0001 /* 0002 File : DatapickerPoint.cpp 0003 Project : LabPlot 0004 Description : Graphic Item for coordinate points of Datapicker 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2015 Ankit Wagadre <wagadre.ankit@gmail.com> 0007 SPDX-FileCopyrightText: 2015-2021 Alexander Semke <alexander.semke@web.de> 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "DatapickerPoint.h" 0012 #include "DatapickerPointPrivate.h" 0013 #include "backend/datapicker/DatapickerCurve.h" 0014 #include "backend/lib/XmlStreamReader.h" 0015 #include "backend/lib/commandtemplates.h" 0016 #include "backend/worksheet/Worksheet.h" 0017 #include "backend/worksheet/plots/cartesian/Symbol.h" 0018 0019 #include <QGraphicsScene> 0020 #include <QGraphicsSceneMouseEvent> 0021 #include <QMenu> 0022 #include <QPainter> 0023 0024 #include <KConfig> 0025 #include <KConfigGroup> 0026 #include <KLocalizedString> 0027 0028 /** 0029 * \class ErrorBarItem 0030 * \brief A customizable error-bar for DatapickerPoint. 0031 */ 0032 0033 ErrorBarItem::ErrorBarItem(DatapickerPoint* parent, ErrorBarType type) 0034 : QGraphicsRectItem(parent->graphicsItem()) 0035 , barLineItem(new QGraphicsLineItem(parent->graphicsItem())) 0036 , m_type(type) 0037 , m_parentItem(parent) { 0038 setFlag(QGraphicsItem::ItemIsMovable); 0039 setFlag(QGraphicsItem::ItemIsSelectable); 0040 setFlag(QGraphicsItem::ItemSendsGeometryChanges); 0041 initRect(); 0042 setAcceptHoverEvents(true); 0043 } 0044 0045 void ErrorBarItem::initRect() { 0046 QRectF xBarRect(-0.15, -0.5, 0.3, 1); 0047 QRectF yBarRect(-0.5, -0.15, 1, 0.3); 0048 0049 if (m_type == ErrorBarType::PlusDeltaX || m_type == ErrorBarType::MinusDeltaX) 0050 m_rect = xBarRect; 0051 else 0052 m_rect = yBarRect; 0053 } 0054 0055 void ErrorBarItem::setPosition(QPointF position) { 0056 setPos(position); 0057 barLineItem->setLine(0, 0, position.x(), position.y()); 0058 } 0059 0060 void ErrorBarItem::setRectSize(qreal size) { 0061 QTransform matrix; 0062 matrix.scale(size, size); 0063 setRect(matrix.mapRect(m_rect)); 0064 } 0065 0066 void ErrorBarItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { 0067 if (m_type == ErrorBarType::PlusDeltaX) 0068 m_parentItem->setPlusDeltaXPos(pos()); 0069 else if (m_type == ErrorBarType::MinusDeltaX) 0070 m_parentItem->setMinusDeltaXPos(pos()); 0071 else if (m_type == ErrorBarType::PlusDeltaY) 0072 m_parentItem->setPlusDeltaYPos(pos()); 0073 else if (m_type == ErrorBarType::MinusDeltaY) 0074 m_parentItem->setMinusDeltaYPos(pos()); 0075 0076 QGraphicsItem::mouseReleaseEvent(event); 0077 } 0078 0079 void ErrorBarItem::hoverEnterEvent(QGraphicsSceneHoverEvent*) { 0080 if (m_type == ErrorBarType::PlusDeltaX || m_type == ErrorBarType::MinusDeltaX) 0081 setCursor(Qt::SizeHorCursor); 0082 else 0083 setCursor(Qt::SizeVerCursor); 0084 } 0085 0086 QVariant ErrorBarItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value) { 0087 if (change == QGraphicsItem::ItemPositionChange) { 0088 QPointF newPos = value.toPointF(); 0089 if (m_type == ErrorBarType::PlusDeltaX || m_type == ErrorBarType::MinusDeltaX) { 0090 newPos.setY(0); 0091 barLineItem->setLine(0, 0, newPos.x(), 0); 0092 } else { 0093 newPos.setX(0); 0094 barLineItem->setLine(0, 0, 0, newPos.y()); 0095 } 0096 return QGraphicsRectItem::itemChange(change, newPos); 0097 } 0098 0099 return QGraphicsRectItem::itemChange(change, value); 0100 } 0101 0102 /** 0103 * \class Datapicker-Point 0104 * \brief A customizable symbol supports error-bars. 0105 * 0106 * The datapicker-Point is aligned relative to the specified position. 0107 * The position can be either specified by mouse events or by providing the 0108 * x- and y- coordinates in parent's coordinate system, or by specifying one 0109 * of the predefined position flags (\c HorizontalPosition, \c VerticalPosition). 0110 */ 0111 0112 DatapickerPoint::DatapickerPoint(const QString& name) 0113 : AbstractAspect(name, AspectType::DatapickerPoint) 0114 , d_ptr(new DatapickerPointPrivate(this)) { 0115 init(); 0116 } 0117 0118 DatapickerPoint::DatapickerPoint(const QString& name, DatapickerPointPrivate* dd) 0119 : AbstractAspect(name, AspectType::DatapickerPoint) 0120 , d_ptr(dd) { 0121 init(); 0122 } 0123 0124 // no need to delete the d-pointer here - it inherits from QGraphicsItem 0125 // and is deleted during the cleanup in QGraphicsScene 0126 DatapickerPoint::~DatapickerPoint() = default; 0127 0128 void DatapickerPoint::init() { 0129 Q_D(DatapickerPoint); 0130 0131 KConfig config; 0132 KConfigGroup group; 0133 group = config.group(QStringLiteral("DatapickerPoint")); 0134 d->position.setX(group.readEntry(QStringLiteral("PositionXValue"), Worksheet::convertToSceneUnits(1, Worksheet::Unit::Centimeter))); 0135 d->position.setY(group.readEntry(QStringLiteral("PositionYValue"), Worksheet::convertToSceneUnits(1, Worksheet::Unit::Centimeter))); 0136 d->plusDeltaXPos = group.readEntry(QStringLiteral("PlusDeltaXPos"), QPointF(30, 0)); 0137 d->minusDeltaXPos = group.readEntry(QStringLiteral("MinusDeltaXPos"), QPointF(-30, 0)); 0138 d->plusDeltaYPos = group.readEntry(QStringLiteral("PlusDeltaYPos"), QPointF(0, -30)); 0139 d->minusDeltaYPos = group.readEntry(QStringLiteral("MinusDeltaYPos"), QPointF(0, 30)); 0140 } 0141 0142 void DatapickerPoint::initErrorBar(DatapickerCurve::Errors errors) { 0143 if (m_errorBarItemList.isEmpty() && errors.x == DatapickerCurve::ErrorType::NoError && errors.y == DatapickerCurve::ErrorType::NoError) 0144 return; // no need to update 0145 m_errorBarItemList.clear(); 0146 if (errors.x != DatapickerCurve::ErrorType::NoError) { 0147 auto* plusDeltaXItem = new ErrorBarItem(this, ErrorBarItem::ErrorBarType::PlusDeltaX); 0148 plusDeltaXItem->setPosition(plusDeltaXPos()); 0149 connect(this, &DatapickerPoint::plusDeltaXPosChanged, plusDeltaXItem, &ErrorBarItem::setPosition); 0150 0151 auto* minusDeltaXItem = new ErrorBarItem(this, ErrorBarItem::ErrorBarType::MinusDeltaX); 0152 minusDeltaXItem->setPosition(minusDeltaXPos()); 0153 connect(this, &DatapickerPoint::minusDeltaXPosChanged, minusDeltaXItem, &ErrorBarItem::setPosition); 0154 0155 m_errorBarItemList << plusDeltaXItem << minusDeltaXItem; 0156 } 0157 0158 if (errors.y != DatapickerCurve::ErrorType::NoError) { 0159 auto* plusDeltaYItem = new ErrorBarItem(this, ErrorBarItem::ErrorBarType::PlusDeltaY); 0160 plusDeltaYItem->setPosition(plusDeltaYPos()); 0161 connect(this, &DatapickerPoint::plusDeltaYPosChanged, plusDeltaYItem, &ErrorBarItem::setPosition); 0162 0163 auto* minusDeltaYItem = new ErrorBarItem(this, ErrorBarItem::ErrorBarType::MinusDeltaY); 0164 minusDeltaYItem->setPosition(minusDeltaYPos()); 0165 connect(this, &DatapickerPoint::minusDeltaYPosChanged, minusDeltaYItem, &ErrorBarItem::setPosition); 0166 0167 m_errorBarItemList << plusDeltaYItem << minusDeltaYItem; 0168 } 0169 0170 retransform(); 0171 } 0172 0173 /*! 0174 Returns an icon to be used in the project explorer. 0175 */ 0176 QIcon DatapickerPoint::icon() const { 0177 return QIcon::fromTheme(QStringLiteral("draw-cross")); 0178 } 0179 0180 QMenu* DatapickerPoint::createContextMenu() { 0181 QMenu* menu = AbstractAspect::createContextMenu(); 0182 return menu; 0183 } 0184 0185 QGraphicsItem* DatapickerPoint::graphicsItem() const { 0186 return d_ptr; 0187 } 0188 0189 void DatapickerPoint::setParentGraphicsItem(QGraphicsItem* item) { 0190 Q_D(DatapickerPoint); 0191 d->setParentItem(item); 0192 } 0193 0194 void DatapickerPoint::retransform() { 0195 Q_D(DatapickerPoint); 0196 d->retransform(); 0197 } 0198 0199 /* ============================ getter methods ================= */ 0200 // point 0201 BASIC_SHARED_D_READER_IMPL(DatapickerPoint, QPointF, position, position) 0202 // error-bar 0203 BASIC_SHARED_D_READER_IMPL(DatapickerPoint, QPointF, plusDeltaXPos, plusDeltaXPos) 0204 BASIC_SHARED_D_READER_IMPL(DatapickerPoint, QPointF, minusDeltaXPos, minusDeltaXPos) 0205 BASIC_SHARED_D_READER_IMPL(DatapickerPoint, QPointF, plusDeltaYPos, plusDeltaYPos) 0206 BASIC_SHARED_D_READER_IMPL(DatapickerPoint, QPointF, minusDeltaYPos, minusDeltaYPos) 0207 0208 /* ============================ setter methods and undo commands ================= */ 0209 STD_SETTER_CMD_IMPL_F_S(DatapickerPoint, SetPosition, QPointF, position, retransform) 0210 void DatapickerPoint::setPosition(QPointF pos) { 0211 Q_D(DatapickerPoint); 0212 if (pos != d->position) 0213 exec(new DatapickerPointSetPositionCmd(d, pos, ki18n("%1: set position"))); 0214 } 0215 0216 STD_SETTER_CMD_IMPL_F_S(DatapickerPoint, SetPlusDeltaXPos, QPointF, plusDeltaXPos, updatePoint) 0217 void DatapickerPoint::setPlusDeltaXPos(QPointF pos) { 0218 Q_D(DatapickerPoint); 0219 if (pos != d->plusDeltaXPos) { 0220 auto* curve = dynamic_cast<DatapickerCurve*>(parentAspect()); 0221 if (!curve) 0222 return; 0223 0224 beginMacro(i18n("%1: set +delta_X position", name())); 0225 if (curve->curveErrorTypes().x == DatapickerCurve::ErrorType::SymmetricError) { 0226 exec(new DatapickerPointSetPlusDeltaXPosCmd(d, pos, ki18n("%1: set +delta X position"))); 0227 setMinusDeltaXPos(QPointF(-std::abs(pos.x()), pos.y())); 0228 } else 0229 exec(new DatapickerPointSetPlusDeltaXPosCmd(d, pos, ki18n("%1: set +delta X position"))); 0230 endMacro(); 0231 } 0232 } 0233 0234 STD_SETTER_CMD_IMPL_F_S(DatapickerPoint, SetMinusDeltaXPos, QPointF, minusDeltaXPos, updatePoint) 0235 void DatapickerPoint::setMinusDeltaXPos(QPointF pos) { 0236 Q_D(DatapickerPoint); 0237 if (pos != d->minusDeltaXPos) { 0238 auto* curve = dynamic_cast<DatapickerCurve*>(parentAspect()); 0239 if (!curve) 0240 return; 0241 0242 beginMacro(i18n("%1: set -delta_X position", name())); 0243 if (curve->curveErrorTypes().x == DatapickerCurve::ErrorType::SymmetricError) { 0244 exec(new DatapickerPointSetMinusDeltaXPosCmd(d, pos, ki18n("%1: set -delta_X position"))); 0245 setPlusDeltaXPos(QPointF(std::abs(pos.x()), pos.y())); 0246 } else 0247 exec(new DatapickerPointSetMinusDeltaXPosCmd(d, pos, ki18n("%1: set -delta_X position"))); 0248 endMacro(); 0249 } 0250 } 0251 0252 STD_SETTER_CMD_IMPL_F_S(DatapickerPoint, SetPlusDeltaYPos, QPointF, plusDeltaYPos, updatePoint) 0253 void DatapickerPoint::setPlusDeltaYPos(QPointF pos) { 0254 Q_D(DatapickerPoint); 0255 if (pos != d->plusDeltaYPos) { 0256 auto* curve = dynamic_cast<DatapickerCurve*>(parentAspect()); 0257 if (!curve) 0258 return; 0259 0260 beginMacro(i18n("%1: set +delta_Y position", name())); 0261 if (curve->curveErrorTypes().y == DatapickerCurve::ErrorType::SymmetricError) { 0262 exec(new DatapickerPointSetPlusDeltaYPosCmd(d, pos, ki18n("%1: set +delta_Y position"))); 0263 setMinusDeltaYPos(QPointF(pos.x(), std::abs(pos.y()))); 0264 } else 0265 exec(new DatapickerPointSetPlusDeltaYPosCmd(d, pos, ki18n("%1: set +delta_Y position"))); 0266 endMacro(); 0267 } 0268 } 0269 0270 STD_SETTER_CMD_IMPL_F_S(DatapickerPoint, SetMinusDeltaYPos, QPointF, minusDeltaYPos, updatePoint) 0271 void DatapickerPoint::setMinusDeltaYPos(QPointF pos) { 0272 Q_D(DatapickerPoint); 0273 if (pos != d->minusDeltaYPos) { 0274 auto* curve = dynamic_cast<DatapickerCurve*>(parentAspect()); 0275 if (!curve) 0276 return; 0277 0278 beginMacro(i18n("%1: set -delta_Y position", name())); 0279 if (curve->curveErrorTypes().y == DatapickerCurve::ErrorType::SymmetricError) { 0280 exec(new DatapickerPointSetMinusDeltaYPosCmd(d, pos, ki18n("%1: set -delta_Y position"))); 0281 setPlusDeltaYPos(QPointF(pos.x(), -std::abs(pos.y()))); 0282 } else 0283 exec(new DatapickerPointSetMinusDeltaYPosCmd(d, pos, ki18n("%1: set -delta_Y position"))); 0284 endMacro(); 0285 } 0286 } 0287 0288 void DatapickerPoint::setPrinting(bool on) { 0289 Q_D(DatapickerPoint); 0290 d->m_printing = on; 0291 } 0292 0293 void DatapickerPoint::setIsReferencePoint(bool value) { 0294 Q_D(DatapickerPoint); 0295 d->isReferencePoint = value; 0296 } 0297 0298 bool DatapickerPoint::isReferencePoint() const { 0299 Q_D(const DatapickerPoint); 0300 return d->isReferencePoint; 0301 } 0302 0303 // ############################################################################## 0304 // ####################### Private implementation ############################### 0305 // ############################################################################## 0306 DatapickerPointPrivate::DatapickerPointPrivate(DatapickerPoint* owner) 0307 : q(owner) { 0308 setFlag(QGraphicsItem::ItemIsMovable); 0309 setFlag(QGraphicsItem::ItemSendsGeometryChanges); 0310 setFlag(QGraphicsItem::ItemIsSelectable); 0311 setAcceptHoverEvents(true); 0312 } 0313 0314 QString DatapickerPointPrivate::name() const { 0315 return q->name(); 0316 } 0317 0318 /*! 0319 calculates the position and the bounding box of the item/point. Called on geometry or properties changes. 0320 */ 0321 void DatapickerPointPrivate::retransform() { 0322 if (q->isLoading()) 0323 return; 0324 0325 setPos(position); 0326 updatePoint(); 0327 0328 updatePropeties(); 0329 0330 QPainterPath path = Symbol::stylePath(pointStyle); 0331 boundingRectangle = path.boundingRect(); 0332 recalcShapeAndBoundingRect(); 0333 retransformErrorBar(); 0334 } 0335 0336 /*! 0337 update color and size of all error-bar. 0338 */ 0339 void DatapickerPointPrivate::retransformErrorBar() { 0340 for (auto* item : q->m_errorBarItemList) { 0341 if (item) { 0342 item->setBrush(errorBarBrush); 0343 item->setPen(errorBarPen); 0344 item->setRectSize(errorBarSize); 0345 } 0346 } 0347 } 0348 0349 /*! 0350 update datasheet on any change in position of Datapicker-Point or it's error-bar. 0351 */ 0352 void DatapickerPointPrivate::updatePoint() { 0353 auto* curve = dynamic_cast<DatapickerCurve*>(q->parentAspect()); 0354 if (curve) 0355 curve->updatePoint(q); 0356 } 0357 0358 void DatapickerPointPrivate::updatePropeties() { 0359 auto* curve = dynamic_cast<DatapickerCurve*>(q->parentAspect()); 0360 auto* image = dynamic_cast<DatapickerImage*>(q->parentAspect()); 0361 if (image) { 0362 rotationAngle = image->symbol()->rotationAngle(); 0363 pointStyle = image->symbol()->style(); 0364 brush = image->symbol()->brush(); 0365 pen = image->symbol()->pen(); 0366 opacity = image->symbol()->opacity(); 0367 size = image->symbol()->size(); 0368 setVisible(image->pointVisibility()); 0369 } else if (curve) { 0370 rotationAngle = curve->symbol()->rotationAngle(); 0371 pointStyle = curve->symbol()->style(); 0372 brush = curve->symbol()->brush(); 0373 pen = curve->symbol()->pen(); 0374 opacity = curve->symbol()->opacity(); 0375 size = curve->symbol()->size(); 0376 errorBarBrush = curve->pointErrorBarBrush(); 0377 errorBarPen = curve->pointErrorBarPen(); 0378 errorBarSize = curve->pointErrorBarSize(); 0379 setVisible(curve->pointVisibility()); 0380 } 0381 } 0382 0383 /*! 0384 Returns the outer bounds of the item as a rectangle. 0385 */ 0386 QRectF DatapickerPointPrivate::boundingRect() const { 0387 return transformedBoundingRectangle; 0388 } 0389 0390 /*! 0391 Returns the shape of this item as a QPainterPath in local coordinates. 0392 */ 0393 QPainterPath DatapickerPointPrivate::shape() const { 0394 return itemShape; 0395 } 0396 0397 /*! 0398 recalculates the outer bounds and the shape of the item. 0399 */ 0400 void DatapickerPointPrivate::recalcShapeAndBoundingRect() { 0401 prepareGeometryChange(); 0402 0403 QTransform matrix; 0404 matrix.scale(size, size); 0405 matrix.rotate(-rotationAngle); 0406 transformedBoundingRectangle = matrix.mapRect(boundingRectangle); 0407 itemShape = QPainterPath(); 0408 itemShape.addRect(transformedBoundingRectangle); 0409 itemShape = WorksheetElement::shapeFromPath(itemShape, pen); 0410 } 0411 0412 void DatapickerPointPrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { 0413 q->setPosition(pos()); 0414 QGraphicsItem::mouseReleaseEvent(event); 0415 } 0416 0417 void DatapickerPointPrivate::hoverEnterEvent(QGraphicsSceneHoverEvent*) { 0418 setCursor(Qt::ArrowCursor); 0419 } 0420 0421 void DatapickerPointPrivate::hoverLeaveEvent(QGraphicsSceneHoverEvent*) { 0422 setCursor(Qt::CrossCursor); 0423 } 0424 0425 QVariant DatapickerPointPrivate::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value) { 0426 if (change == QGraphicsItem::GraphicsItemChange::ItemSelectedHasChanged && value.toBool()) 0427 Q_EMIT q->pointSelected(q); 0428 else if (change == QGraphicsItem::GraphicsItemChange::ItemPositionChange) 0429 Q_EMIT q->positionChanged(value.toPointF()); 0430 return QGraphicsItem::itemChange(change, value); 0431 } 0432 0433 void DatapickerPointPrivate::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget*) { 0434 QPainterPath path = Symbol::stylePath(pointStyle); 0435 QTransform trafo; 0436 trafo.scale(size, size); 0437 path = trafo.map(path); 0438 trafo.reset(); 0439 if (rotationAngle != 0) { 0440 trafo.rotate(-rotationAngle); 0441 path = trafo.map(path); 0442 } 0443 painter->save(); 0444 painter->setPen(pen); 0445 painter->setBrush(brush); 0446 painter->setOpacity(opacity); 0447 painter->drawPath(path); 0448 painter->restore(); 0449 0450 if (isSelected() && !m_printing) { 0451 // TODO: move the initialization of QPen to a parent class later so we don't 0452 // need to create it in every paint() call. 0453 painter->setPen(QPen(QApplication::palette().color(QPalette::Highlight), 1, Qt::SolidLine)); 0454 painter->drawPath(itemShape); 0455 } 0456 } 0457 0458 void DatapickerPointPrivate::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) { 0459 q->createContextMenu()->exec(event->screenPos()); 0460 } 0461 0462 // ############################################################################## 0463 // ################## Serialization/Deserialization ########################### 0464 // ############################################################################## 0465 //! Save as XML 0466 void DatapickerPoint::save(QXmlStreamWriter* writer) const { 0467 Q_D(const DatapickerPoint); 0468 0469 writer->writeStartElement(QStringLiteral("datapickerPoint")); 0470 writeBasicAttributes(writer); 0471 0472 // geometry 0473 writer->writeStartElement(QStringLiteral("geometry")); 0474 writer->writeAttribute(QStringLiteral("x"), QString::number(d->position.x())); 0475 writer->writeAttribute(QStringLiteral("y"), QString::number(d->position.y())); 0476 writer->writeEndElement(); 0477 0478 auto* curve = dynamic_cast<DatapickerCurve*>(parentAspect()); 0479 if (curve && (curve->curveErrorTypes().x != DatapickerCurve::ErrorType::NoError || curve->curveErrorTypes().y != DatapickerCurve::ErrorType::NoError)) { 0480 writer->writeStartElement(QStringLiteral("errorBar")); 0481 writer->writeAttribute(QStringLiteral("plusDeltaXPos_x"), QString::number(d->plusDeltaXPos.x())); 0482 writer->writeAttribute(QStringLiteral("plusDeltaXPos_y"), QString::number(d->plusDeltaXPos.y())); 0483 writer->writeAttribute(QStringLiteral("minusDeltaXPos_x"), QString::number(d->minusDeltaXPos.x())); 0484 writer->writeAttribute(QStringLiteral("minusDeltaXPos_y"), QString::number(d->minusDeltaXPos.y())); 0485 writer->writeAttribute(QStringLiteral("plusDeltaYPos_x"), QString::number(d->plusDeltaYPos.x())); 0486 writer->writeAttribute(QStringLiteral("plusDeltaYPos_y"), QString::number(d->plusDeltaYPos.y())); 0487 writer->writeAttribute(QStringLiteral("minusDeltaYPos_x"), QString::number(d->minusDeltaYPos.x())); 0488 writer->writeAttribute(QStringLiteral("minusDeltaYPos_y"), QString::number(d->minusDeltaYPos.y())); 0489 writer->writeEndElement(); 0490 } 0491 0492 writer->writeEndElement(); // close "DatapickerPoint" section 0493 } 0494 0495 //! Load from XML 0496 bool DatapickerPoint::load(XmlStreamReader* reader, bool preview) { 0497 Q_D(DatapickerPoint); 0498 0499 if (!readBasicAttributes(reader)) 0500 return false; 0501 0502 QXmlStreamAttributes attribs; 0503 QString str; 0504 0505 while (!reader->atEnd()) { 0506 reader->readNext(); 0507 if (reader->isEndElement() && reader->name() == QStringLiteral("datapickerPoint")) 0508 break; 0509 0510 if (!reader->isStartElement()) 0511 continue; 0512 0513 if (!preview && reader->name() == QStringLiteral("geometry")) { 0514 attribs = reader->attributes(); 0515 0516 str = attribs.value(QStringLiteral("x")).toString(); 0517 if (str.isEmpty()) 0518 reader->raiseMissingAttributeWarning(QStringLiteral("x")); 0519 else 0520 d->position.setX(str.toDouble()); 0521 0522 str = attribs.value(QStringLiteral("y")).toString(); 0523 if (str.isEmpty()) 0524 reader->raiseMissingAttributeWarning(QStringLiteral("y")); 0525 else 0526 d->position.setY(str.toDouble()); 0527 } else if (!preview && reader->name() == QStringLiteral("errorBar")) { 0528 attribs = reader->attributes(); 0529 0530 str = attribs.value(QStringLiteral("plusDeltaXPos_x")).toString(); 0531 if (str.isEmpty()) 0532 reader->raiseMissingAttributeWarning(QStringLiteral("plusDeltaXPos_x")); 0533 else 0534 d->plusDeltaXPos.setX(str.toDouble()); 0535 0536 str = attribs.value(QStringLiteral("plusDeltaXPos_y")).toString(); 0537 if (str.isEmpty()) 0538 reader->raiseMissingAttributeWarning(QStringLiteral("plusDeltaXPos_y")); 0539 else 0540 d->plusDeltaXPos.setY(str.toDouble()); 0541 0542 str = attribs.value(QStringLiteral("minusDeltaXPos_x")).toString(); 0543 if (str.isEmpty()) 0544 reader->raiseMissingAttributeWarning(QStringLiteral("minusDeltaXPos_x")); 0545 else 0546 d->minusDeltaXPos.setX(str.toDouble()); 0547 0548 str = attribs.value(QStringLiteral("minusDeltaXPos_y")).toString(); 0549 if (str.isEmpty()) 0550 reader->raiseMissingAttributeWarning(QStringLiteral("minusDeltaXPos_y")); 0551 else 0552 d->minusDeltaXPos.setY(str.toDouble()); 0553 0554 str = attribs.value(QStringLiteral("plusDeltaYPos_x")).toString(); 0555 if (str.isEmpty()) 0556 reader->raiseMissingAttributeWarning(QStringLiteral("plusDeltaYPos_x")); 0557 else 0558 d->plusDeltaYPos.setX(str.toDouble()); 0559 0560 str = attribs.value(QStringLiteral("plusDeltaYPos_y")).toString(); 0561 if (str.isEmpty()) 0562 reader->raiseMissingAttributeWarning(QStringLiteral("plusDeltaYPos_y")); 0563 else 0564 d->plusDeltaYPos.setY(str.toDouble()); 0565 0566 str = attribs.value(QStringLiteral("minusDeltaYPos_x")).toString(); 0567 if (str.isEmpty()) 0568 reader->raiseMissingAttributeWarning(QStringLiteral("minusDeltaYPos_x")); 0569 else 0570 d->minusDeltaYPos.setX(str.toDouble()); 0571 0572 str = attribs.value(QStringLiteral("minusDeltaYPos_y")).toString(); 0573 if (str.isEmpty()) 0574 reader->raiseMissingAttributeWarning(QStringLiteral("minusDeltaYPos_y")); 0575 else 0576 d->minusDeltaYPos.setY(str.toDouble()); 0577 } else { // unknown element 0578 reader->raiseUnknownElementWarning(); 0579 if (!reader->skipToEndElement()) 0580 return false; 0581 } 0582 } 0583 0584 retransform(); 0585 return true; 0586 }