labplot  2.8.2
About: LabPlot is an application for plotting and analysis of 2D and 3D functions and data. It is a complete rewrite of LabPlot1 and lacks in the first release a lot of features available in the predecessor. On the other hand, the GUI and the usability is more superior.
  Fossies Dox: labplot-2.8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

DatapickerImage.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  File : DatapickerImage.cpp
3  Project : LabPlot
4  Description : Worksheet for Datapicker
5  --------------------------------------------------------------------
6  Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com)
7  Copyright : (C) 2015-2019 by Alexander Semke (alexander.semke@web.de)
8 
9  ***************************************************************************/
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  * This program is distributed in the hope that it will be useful, *
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20  * GNU General Public License for more details. *
21  * *
22  * You should have received a copy of the GNU General Public License *
23  * along with this program; if not, write to the Free Software *
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
25  * Boston, MA 02110-1301 USA *
26  * *
27  ***************************************************************************/
28 
29 #include "DatapickerImage.h"
30 #include "DatapickerImagePrivate.h"
39 #include "backend/lib/trace.h"
40 
41 #include <QDesktopWidget>
42 #include <QGraphicsScene>
43 #include <QMenu>
44 #include <QPrinter>
45 #include <QPrintDialog>
46 #include <QPrintPreviewDialog>
47 
48 #include <KConfig>
49 #include <KConfigGroup>
50 #include <KLocalizedString>
51 
52 /**
53  * \class DatapickerImage
54  * \brief container to open image/plot.
55  *
56  * Top-level container for DatapickerPoint.
57  *
58  * * \ingroup datapicker
59  */
60 DatapickerImage::DatapickerImage(const QString& name, bool loading) :
62  foregroundBins( new int[ImageEditor::colorAttributeMax(ColorAttributes::Foreground) + 1]),
63  hueBins( new int[ImageEditor::colorAttributeMax(ColorAttributes::Hue) + 1]),
64  saturationBins( new int[ImageEditor::colorAttributeMax(ColorAttributes::Saturation) + 1]),
65  valueBins( new int[ImageEditor::colorAttributeMax(ColorAttributes::Value) + 1]),
66  intensityBins( new int[ImageEditor::colorAttributeMax(ColorAttributes::Intensity) + 1]),
67  d(new DatapickerImagePrivate(this)),
68  m_segments(new Segments(this)) {
69 
70  if (!loading)
71  init();
72 }
73 
75  delete [] hueBins;
76  delete [] saturationBins;
77  delete [] valueBins;
78  delete [] intensityBins;
79  delete [] foregroundBins;
80  delete m_segments;
81  delete d;
82 }
83 
85  KConfig config;
86  KConfigGroup group = config.group( "DatapickerImage" );
87 
88  //general properties
89  d->fileName = group.readEntry("FileName", QString());
90  d->rotationAngle = group.readEntry("RotationAngle", 0.0);
91  d->minSegmentLength = group.readEntry("MinSegmentLength", 30);
92  d->pointSeparation = group.readEntry("PointSeparation", 30);
93  d->axisPoints.type = (DatapickerImage::GraphType) group.readEntry("GraphType", static_cast<int>(DatapickerImage::GraphType::Cartesian));
94  d->axisPoints.ternaryScale = group.readEntry("TernaryScale", 1);
95 
96  //edit image settings
98  d->settings.foregroundThresholdHigh = group.readEntry("ForegroundThresholdHigh", 90);
99  d->settings.foregroundThresholdLow = group.readEntry("ForegroundThresholdLow", 30);
100  d->settings.hueThresholdHigh = group.readEntry("HueThresholdHigh", 360);
101  d->settings.hueThresholdLow = group.readEntry("HueThresholdLow", 0);
102  d->settings.intensityThresholdHigh = group.readEntry("IntensityThresholdHigh", 100);
103  d->settings.intensityThresholdLow = group.readEntry("IntensityThresholdLow", 20);
104  d->settings.saturationThresholdHigh = group.readEntry("SaturationThresholdHigh", 100);
105  d->settings.saturationThresholdLow = group.readEntry("SaturationThresholdLow", 30);
106  d->settings.valueThresholdHigh = group.readEntry("ValueThresholdHigh", 90);
107  d->settings.valueThresholdLow = group.readEntry("ValueThresholdLow", 30);
108 
109  // reference point symbol properties
110  d->pointStyle = (Symbol::Style)group.readEntry("PointStyle", (int)Symbol::Style::Cross);
111  d->pointSize = group.readEntry("Size", Worksheet::convertToSceneUnits(7, Worksheet::Unit::Point));
112  d->pointRotationAngle = group.readEntry("Rotation", 0.0);
113  d->pointOpacity = group.readEntry("Opacity", 1.0);
114  d->pointBrush.setStyle( (Qt::BrushStyle)group.readEntry("FillingStyle", (int)Qt::NoBrush) );
115  d->pointBrush.setColor( group.readEntry("FillingColor", QColor(Qt::black)) );
116  d->pointPen.setStyle( (Qt::PenStyle)group.readEntry("BorderStyle", (int)Qt::SolidLine) );
117  d->pointPen.setColor( group.readEntry("BorderColor", QColor(Qt::red)) );
118  d->pointPen.setWidthF( group.readEntry("BorderWidth", Worksheet::convertToSceneUnits(1, Worksheet::Unit::Point)) );
119  d->pointVisibility = group.readEntry("PointVisibility", true);
120 }
121 
122 /*!
123  Returns an icon to be used in the project explorer.
124 */
125 QIcon DatapickerImage::icon() const {
126  return QIcon::fromTheme("image-x-generic");
127 }
128 
129 /*!
130  Return a new context menu
131 */
133  QMenu* menu = new QMenu(nullptr);
134  emit requestProjectContextMenu(menu);
135  return menu;
136 }
137 
139  emit requestProjectContextMenu(menu);
140 }
141 
142 //! Construct a primary view on me.
143 /**
144  * This method may be called multiple times during the life time of an Aspect, or it might not get
145  * called at all. Aspects must not depend on the existence of a view for their operation.
146  */
147 QWidget* DatapickerImage::view() const {
148  if (!m_partView) {
149  m_view = new DatapickerImageView(const_cast<DatapickerImage *>(this));
150  m_partView = m_view;
152  }
153  return m_partView;
154 }
155 
157  auto* dlg = new ExportWorksheetDialog(m_view);
158  dlg->setFileName(name());
159  bool ret;
160  if ( (ret = (dlg->exec() == QDialog::Accepted)) ) {
161  const QString path = dlg->path();
162  const WorksheetView::ExportFormat format = dlg->exportFormat();
163  const int resolution = dlg->exportResolution();
164 
165  WAIT_CURSOR;
166  m_view->exportToFile(path, format, resolution);
167  RESET_CURSOR;
168  }
169  delete dlg;
170  return ret;
171 }
172 
174  QPrinter printer;
175  auto* dlg = new QPrintDialog(&printer, m_view);
176  bool ret;
177  dlg->setWindowTitle(i18nc("@title:window", "Print Datapicker Image"));
178  if ( (ret = (dlg->exec() == QDialog::Accepted)) )
179  m_view->print(&printer);
180 
181  delete dlg;
182  return ret;
183 }
184 
186  auto* dlg = new QPrintPreviewDialog(m_view);
187  connect(dlg, &QPrintPreviewDialog::paintRequested, m_view, &DatapickerImageView::print);
188  return dlg->exec();
189 }
190 
191 /*!
192  Selects or deselects the Datapicker/DatapickerImage in the project explorer.
193  This function is called in \c DatapickerImageView.
194  The DatapickerImage gets deselected if there are selected items in the view,
195  and selected if there are no selected items in the view.
196 */
198  if (b)
199  emit childAspectSelectedInView(this);
200  else
201  emit childAspectDeselectedInView(this);
202 }
203 
206 }
207 
208 QGraphicsScene* DatapickerImage::scene() const {
209  return d->m_scene;
210 }
211 
213  return d->m_scene->sceneRect();
214 }
215 
217  d->plotImageType = type;
219  d->discretize();
220 
221  emit requestUpdate();
222 }
223 
225  return d->plotImageType;
226 }
227 
228 /* =============================== getter methods for background options ================================= */
229 CLASS_D_READER_IMPL(DatapickerImage, QString, fileName, fileName)
232 BASIC_D_READER_IMPL(DatapickerImage, float, rotationAngle, rotationAngle)
233 BASIC_D_READER_IMPL(DatapickerImage, DatapickerImage::PointsType, plotPointsType, plotPointsType)
234 BASIC_D_READER_IMPL(DatapickerImage, int, pointSeparation, pointSeparation)
235 BASIC_D_READER_IMPL(DatapickerImage, int, minSegmentLength, minSegmentLength)
236 BASIC_D_READER_IMPL(DatapickerImage, Symbol::Style, pointStyle, pointStyle)
237 BASIC_D_READER_IMPL(DatapickerImage, qreal, pointOpacity, pointOpacity)
238 BASIC_D_READER_IMPL(DatapickerImage, qreal, pointRotationAngle, pointRotationAngle)
239 BASIC_D_READER_IMPL(DatapickerImage, qreal, pointSize, pointSize)
240 CLASS_D_READER_IMPL(DatapickerImage, QBrush, pointBrush, pointBrush)
241 CLASS_D_READER_IMPL(DatapickerImage, QPen, pointPen, pointPen)
242 BASIC_D_READER_IMPL(DatapickerImage, bool, pointVisibility, pointVisibility)
243 /* ============================ setter methods and undo commands for background options ================= */
244 STD_SETTER_CMD_IMPL_F_S(DatapickerImage, SetFileName, QString, fileName, updateFileName)
245 void DatapickerImage::setFileName(const QString& fileName) {
246  if (fileName!= d->fileName) {
247  beginMacro(i18n("%1: upload new image", name()));
248  exec(new DatapickerImageSetFileNameCmd(d, fileName, ki18n("%1: upload image")));
249  endMacro();
250  }
251 }
252 
253 STD_SETTER_CMD_IMPL_S(DatapickerImage, SetRotationAngle, float, rotationAngle)
254 void DatapickerImage::setRotationAngle(float angle) {
255  if (angle != d->rotationAngle)
256  exec(new DatapickerImageSetRotationAngleCmd(d, angle, ki18n("%1: set rotation angle")));
257 }
258 
260 void DatapickerImage::setAxisPoints(const DatapickerImage::ReferencePoints& points) {
261  if (memcmp(&points, &d->axisPoints, sizeof(points)) != 0)
262  exec(new DatapickerImageSetAxisPointsCmd(d, points, ki18n("%1: set Axis points")));
263 }
264 
266 void DatapickerImage::setSettings(const DatapickerImage::EditorSettings& editorSettings) {
267  if (memcmp(&editorSettings, &d->settings, sizeof(editorSettings)) != 0)
268  exec(new DatapickerImageSetSettingsCmd(d, editorSettings, ki18n("%1: set editor settings")));
269 }
270 
271 STD_SETTER_CMD_IMPL_F_S(DatapickerImage, SetMinSegmentLength, int, minSegmentLength, makeSegments)
272 void DatapickerImage::setminSegmentLength(const int value) {
273  if (d->minSegmentLength != value)
274  exec(new DatapickerImageSetMinSegmentLengthCmd(d, value, ki18n("%1: set minimum segment length"))); ;
275 }
276 
277 STD_SETTER_CMD_IMPL_F_S(DatapickerImage, SetPointStyle, Symbol::Style, pointStyle, retransform)
278 void DatapickerImage::setPointStyle(Symbol::Style newStyle) {
279  if (newStyle != d->pointStyle)
280  exec(new DatapickerImageSetPointStyleCmd(d, newStyle, ki18n("%1: set point's style")));
281 }
282 
283 STD_SETTER_CMD_IMPL_F_S(DatapickerImage, SetPointSize, qreal, pointSize, retransform)
284 void DatapickerImage::setPointSize(qreal value) {
285  if (!qFuzzyCompare(1 + value, 1 + d->pointSize))
286  exec(new DatapickerImageSetPointSizeCmd(d, value, ki18n("%1: set point's size")));
287 }
288 
289 STD_SETTER_CMD_IMPL_F_S(DatapickerImage, SetPointRotationAngle, qreal, pointRotationAngle, retransform)
290 void DatapickerImage::setPointRotationAngle(qreal angle) {
291  if (!qFuzzyCompare(1 + angle, 1 + d->pointRotationAngle))
292  exec(new DatapickerImageSetPointRotationAngleCmd(d, angle, ki18n("%1: rotate point")));
293 }
294 
295 STD_SETTER_CMD_IMPL_F_S(DatapickerImage, SetPointBrush, QBrush, pointBrush, retransform)
296 void DatapickerImage::setPointBrush(const QBrush& newBrush) {
297  if (newBrush != d->pointBrush)
298  exec(new DatapickerImageSetPointBrushCmd(d, newBrush, ki18n("%1: set point's filling")));
299 }
300 
301 STD_SETTER_CMD_IMPL_F_S(DatapickerImage, SetPointPen, QPen, pointPen, retransform)
302 void DatapickerImage::setPointPen(const QPen &newPen) {
303  if (newPen != d->pointPen)
304  exec(new DatapickerImageSetPointPenCmd(d, newPen, ki18n("%1: set outline style")));
305 }
306 
307 STD_SETTER_CMD_IMPL_F_S(DatapickerImage, SetPointOpacity, qreal, pointOpacity, retransform)
308 void DatapickerImage::setPointOpacity(qreal newOpacity) {
309  if (newOpacity != d->pointOpacity)
310  exec(new DatapickerImageSetPointOpacityCmd(d, newOpacity, ki18n("%1: set point's opacity")));
311 }
312 
313 STD_SETTER_CMD_IMPL_F_S(DatapickerImage, SetPointVisibility, bool, pointVisibility, retransform)
314 void DatapickerImage::setPointVisibility(const bool on) {
315  if (on != d->pointVisibility)
316  exec(new DatapickerImageSetPointVisibilityCmd(d, on, on ? ki18n("%1: set visible") : ki18n("%1: set invisible")));
317 }
318 
319 void DatapickerImage::setPrinting(bool on) const {
321  for (auto* point : points)
322  point->setPrinting(on);
323 }
324 
325 void DatapickerImage::setPlotPointsType(const PointsType pointsType) {
326  if (d->plotPointsType == pointsType)
327  return;
328 
329  d->plotPointsType = pointsType;
330 
331  if (pointsType == DatapickerImage::PointsType::AxisPoints) {
332  //clear image
333  auto points = children<DatapickerPoint>(ChildIndexFlag::IncludeHidden);
334  if (!points.isEmpty()) {
335  beginMacro(i18n("%1: remove all axis points", name()));
336 
337  for (auto* point : points)
338  point->remove();
339  endMacro();
340  }
342  } else if (pointsType == DatapickerImage::PointsType::CurvePoints)
344  else if (pointsType == DatapickerImage::PointsType::SegmentPoints) {
345  d->makeSegments();
347  }
348 }
349 
350 void DatapickerImage::setPointSeparation(const int value) {
351  d->pointSeparation = value;
352 }
353 
354 //##############################################################################
355 //###################### Private implementation ###############################
356 //##############################################################################
358  pageRect(0, 0, 1000, 1000),
359  m_scene(new QGraphicsScene(pageRect)) {
360 }
361 
363  return q->name();
364 }
365 
368  for (auto* point : points)
369  point->retransform();
370 }
371 
372 bool DatapickerImagePrivate::uploadImage(const QString& address) {
373  bool rc = q->originalPlotImage.load(address);
374  if (rc) {
375  //convert the image to 32bit-format if this is not the case yet
376  QImage::Format format = q->originalPlotImage.format();
377  if (format != QImage::Format_RGB32 && format != QImage::Format_ARGB32 && format != QImage::Format_ARGB32_Premultiplied)
378  q->originalPlotImage = q->originalPlotImage.convertToFormat(QImage::Format_RGB32);
379 
382  //upload Histogram
388  discretize();
389 
390  //resize the screen
391  double w = Worksheet::convertToSceneUnits(q->originalPlotImage.width(), Worksheet::Unit::Inch)/QApplication::desktop()->physicalDpiX();
392  double h = Worksheet::convertToSceneUnits(q->originalPlotImage.height(), Worksheet::Unit::Inch)/QApplication::desktop()->physicalDpiX();
393  m_scene->setSceneRect(0, 0, w, h);
394  q->isLoaded = true;
395  }
396  return rc;
397 }
398 
400  PERFTRACE("DatapickerImagePrivate::discretize()");
402  return;
403 
405 
407  emit q->requestUpdate();
408  else
409  makeSegments();
410 }
411 
414  return;
415 
416  PERFTRACE("DatapickerImagePrivate::makeSegments()");
419  emit q->requestUpdate();
420 }
421 
423  delete m_scene;
424 }
425 
427  WAIT_CURSOR;
428  q->isLoaded = false;
429  const QString& address = fileName.trimmed();
430 
431  if (!address.isEmpty()) {
432  if (uploadImage(address))
433  fileName = address;
434  } else {
435  //hide segments if they are visible
437  }
438 
440  if (!points.isEmpty()) {
441  for (auto* point : points)
442  point->remove();
443  }
444 
445  emit q->requestUpdate();
446  emit q->requestUpdateActions();
447  RESET_CURSOR;
448 }
449 
450 //##############################################################################
451 //################## Serialization/Deserialization ###########################
452 //##############################################################################
453 
454 //! Save as XML
455 void DatapickerImage::save(QXmlStreamWriter* writer) const {
456  writer->writeStartElement( "datapickerImage" );
457  writeBasicAttributes(writer);
458 
459  //general properties
460  writer->writeStartElement( "general" );
461  writer->writeAttribute( "fileName", d->fileName );
462  writer->writeAttribute( "plotPointsType", QString::number(static_cast<int>(d->plotPointsType)) );
463  writer->writeEndElement();
464 
465  writer->writeStartElement( "axisPoint" );
466  writer->writeAttribute( "graphType", QString::number(static_cast<int>(d->axisPoints.type)) );
467  writer->writeAttribute( "ternaryScale", QString::number(d->axisPoints.ternaryScale) );
468  writer->writeAttribute( "axisPointLogicalX1", QString::number(d->axisPoints.logicalPos[0].x()) );
469  writer->writeAttribute( "axisPointLogicalY1", QString::number(d->axisPoints.logicalPos[0].y()) );
470  writer->writeAttribute( "axisPointLogicalX2", QString::number(d->axisPoints.logicalPos[1].x()) );
471  writer->writeAttribute( "axisPointLogicalY2", QString::number(d->axisPoints.logicalPos[1].y()) );
472  writer->writeAttribute( "axisPointLogicalX3", QString::number(d->axisPoints.logicalPos[2].x()) );
473  writer->writeAttribute( "axisPointLogicalY3", QString::number(d->axisPoints.logicalPos[2].y()) );
474  writer->writeAttribute( "axisPointLogicalZ1", QString::number(d->axisPoints.logicalPos[0].z()) );
475  writer->writeAttribute( "axisPointLogicalZ2", QString::number(d->axisPoints.logicalPos[1].z()) );
476  writer->writeAttribute( "axisPointLogicalZ3", QString::number(d->axisPoints.logicalPos[2].z()) );
477  writer->writeAttribute( "axisPointSceneX1", QString::number(d->axisPoints.scenePos[0].x()) );
478  writer->writeAttribute( "axisPointSceneY1", QString::number(d->axisPoints.scenePos[0].y()) );
479  writer->writeAttribute( "axisPointSceneX2", QString::number(d->axisPoints.scenePos[1].x()) );
480  writer->writeAttribute( "axisPointSceneY2", QString::number(d->axisPoints.scenePos[1].y()) );
481  writer->writeAttribute( "axisPointSceneX3", QString::number(d->axisPoints.scenePos[2].x()) );
482  writer->writeAttribute( "axisPointSceneY3", QString::number(d->axisPoints.scenePos[2].y()) );
483  writer->writeEndElement();
484 
485  //editor and segment settings
486  writer->writeStartElement( "editorSettings" );
487  writer->writeAttribute( "plotImageType", QString::number(static_cast<int>(d->plotImageType)) );
488  writer->writeAttribute( "rotationAngle", QString::number(d->rotationAngle) );
489  writer->writeAttribute( "minSegmentLength", QString::number(d->minSegmentLength) );
490  writer->writeAttribute( "pointSeparation", QString::number(d->pointSeparation) );
491  writer->writeAttribute( "foregroundThresholdHigh", QString::number(d->settings.foregroundThresholdHigh) );
492  writer->writeAttribute( "foregroundThresholdLow", QString::number(d->settings.foregroundThresholdLow) );
493  writer->writeAttribute( "hueThresholdHigh", QString::number(d->settings.hueThresholdHigh) );
494  writer->writeAttribute( "hueThresholdLow", QString::number(d->settings.hueThresholdLow) );
495  writer->writeAttribute( "intensityThresholdHigh", QString::number(d->settings.intensityThresholdHigh) );
496  writer->writeAttribute( "intensityThresholdLow", QString::number(d->settings.intensityThresholdLow) );
497  writer->writeAttribute( "saturationThresholdHigh", QString::number(d->settings.saturationThresholdHigh) );
498  writer->writeAttribute( "saturationThresholdLow", QString::number(d->settings.saturationThresholdLow) );
499  writer->writeAttribute( "valueThresholdHigh", QString::number(d->settings.valueThresholdHigh) );
500  writer->writeAttribute( "valueThresholdLow", QString::number(d->settings.valueThresholdLow) );
501  writer->writeEndElement();
502 
503  //symbol properties
504  writer->writeStartElement( "symbolProperties" );
505  writer->writeAttribute( "pointRotationAngle", QString::number(d->pointRotationAngle) );
506  writer->writeAttribute( "pointOpacity", QString::number(d->pointOpacity) );
507  writer->writeAttribute( "pointSize", QString::number(d->pointSize) );
508  writer->writeAttribute( "pointStyle", QString::number(static_cast<int>(d->pointStyle)) );
509  writer->writeAttribute( "pointVisibility", QString::number(d->pointVisibility) );
512  writer->writeEndElement();
513 
514  //serialize all children
515  for (auto* child : children<AbstractAspect>(ChildIndexFlag::IncludeHidden))
516  child->save(writer);
517 
518  writer->writeEndElement();
519 }
520 
521 //! Load from XML
522 bool DatapickerImage::load(XmlStreamReader* reader, bool preview) {
523  if (!readBasicAttributes(reader))
524  return false;
525 
526  KLocalizedString attributeWarning = ki18n("Attribute '%1' missing or empty, default value is used");
527  QXmlStreamAttributes attribs;
528  QString str;
529 
530  while (!reader->atEnd()) {
531  reader->readNext();
532  if (reader->isEndElement() && reader->name() == "datapickerImage")
533  break;
534 
535  if (!reader->isStartElement())
536  continue;
537 
538  if (!preview && reader->name() == "general") {
539  attribs = reader->attributes();
540 
541  str = attribs.value("fileName").toString();
542  d->fileName = str;
543 
544  READ_INT_VALUE("plotPointsType", plotPointsType, DatapickerImage::PointsType);
545  } else if (!preview && reader->name() == "axisPoint") {
546  attribs = reader->attributes();
547 
548  READ_INT_VALUE("graphType", axisPoints.type, DatapickerImage::GraphType);
549  READ_INT_VALUE("ternaryScale", axisPoints.ternaryScale, int);
550 
551  str = attribs.value("axisPointLogicalX1").toString();
552  if (str.isEmpty())
553  reader->raiseWarning(attributeWarning.subs("axisPointLogicalX1").toString());
554  else
555  d->axisPoints.logicalPos[0].setX(str.toDouble());
556 
557  str = attribs.value("axisPointLogicalY1").toString();
558  if (str.isEmpty())
559  reader->raiseWarning(attributeWarning.subs("axisPointLogicalY1").toString());
560  else
561  d->axisPoints.logicalPos[0].setY(str.toDouble());
562 
563  str = attribs.value("axisPointLogicalZ1").toString();
564  if (str.isEmpty())
565  reader->raiseWarning(attributeWarning.subs("axisPointLogicalZ1").toString());
566  else
567  d->axisPoints.logicalPos[0].setZ(str.toDouble());
568 
569  str = attribs.value("axisPointLogicalX2").toString();
570  if (str.isEmpty())
571  reader->raiseWarning(attributeWarning.subs("axisPointLogicalX2").toString());
572  else
573  d->axisPoints.logicalPos[1].setX(str.toDouble());
574 
575  str = attribs.value("axisPointLogicalY2").toString();
576  if (str.isEmpty())
577  reader->raiseWarning(attributeWarning.subs("axisPointLogicalY2").toString());
578  else
579  d->axisPoints.logicalPos[1].setY(str.toDouble());
580 
581  str = attribs.value("axisPointLogicalZ2").toString();
582  if (str.isEmpty())
583  reader->raiseWarning(attributeWarning.subs("axisPointLogicalZ2").toString());
584  else
585  d->axisPoints.logicalPos[1].setZ(str.toDouble());
586 
587  str = attribs.value("axisPointLogicalX3").toString();
588  if (str.isEmpty())
589  reader->raiseWarning(attributeWarning.subs("axisPointLogicalX3").toString());
590  else
591  d->axisPoints.logicalPos[2].setX(str.toDouble());
592 
593  str = attribs.value("axisPointLogicalY3").toString();
594  if (str.isEmpty())
595  reader->raiseWarning(attributeWarning.subs("axisPointLogicalY3").toString());
596  else
597  d->axisPoints.logicalPos[2].setY(str.toDouble());
598 
599  str = attribs.value("axisPointLogicalZ3").toString();
600  if (str.isEmpty())
601  reader->raiseWarning(attributeWarning.subs("axisPointLogicalZ3").toString());
602  else
603  d->axisPoints.logicalPos[2].setZ(str.toDouble());
604 
605  str = attribs.value("axisPointSceneX1").toString();
606  if (str.isEmpty())
607  reader->raiseWarning(attributeWarning.subs("axisPointSceneX1").toString());
608  else
609  d->axisPoints.scenePos[0].setX(str.toDouble());
610 
611  str = attribs.value("axisPointSceneY1").toString();
612  if (str.isEmpty())
613  reader->raiseWarning(attributeWarning.subs("axisPointSceneY1").toString());
614  else
615  d->axisPoints.scenePos[0].setY(str.toDouble());
616 
617  str = attribs.value("axisPointSceneX2").toString();
618  if (str.isEmpty())
619  reader->raiseWarning(attributeWarning.subs("axisPointSceneX2").toString());
620  else
621  d->axisPoints.scenePos[1].setX(str.toDouble());
622 
623  str = attribs.value("axisPointSceneY2").toString();
624  if (str.isEmpty())
625  reader->raiseWarning(attributeWarning.subs("axisPointSceneY2").toString());
626  else
627  d->axisPoints.scenePos[1].setY(str.toDouble());
628 
629  str = attribs.value("axisPointSceneX3").toString();
630  if (str.isEmpty())
631  reader->raiseWarning(attributeWarning.subs("axisPointSceneX3").toString());
632  else
633  d->axisPoints.scenePos[2].setX(str.toDouble());
634 
635  str = attribs.value("axisPointSceneY3").toString();
636  if (str.isEmpty())
637  reader->raiseWarning(attributeWarning.subs("axisPointSceneY3").toString());
638  else
639  d->axisPoints.scenePos[2].setY(str.toDouble());
640 
641  } else if (!preview && reader->name() == "editorSettings") {
642  attribs = reader->attributes();
643 
645  READ_DOUBLE_VALUE("rotationAngle", rotationAngle);
646  READ_INT_VALUE("minSegmentLength", minSegmentLength, int);
647  READ_INT_VALUE("pointSeparation", pointSeparation, int);
648  READ_INT_VALUE("foregroundThresholdHigh", settings.foregroundThresholdHigh, int);
649  READ_INT_VALUE("foregroundThresholdLow", settings.foregroundThresholdLow, int);
650  READ_INT_VALUE("hueThresholdHigh", settings.hueThresholdHigh, int);
651  READ_INT_VALUE("hueThresholdLow", settings.hueThresholdLow, int);
652  READ_INT_VALUE("intensityThresholdHigh", settings.intensityThresholdHigh, int);
653  READ_INT_VALUE("intensityThresholdLow", settings.intensityThresholdLow, int);
654  READ_INT_VALUE("saturationThresholdHigh", settings.saturationThresholdHigh, int);
655  READ_INT_VALUE("saturationThresholdLow", settings.saturationThresholdLow, int);
656  READ_INT_VALUE("valueThresholdHigh", settings.valueThresholdHigh, int);
657  READ_INT_VALUE("valueThresholdLow", settings.valueThresholdLow, int);
658  } else if (!preview && reader->name() == "symbolProperties") {
659  attribs = reader->attributes();
660 
661  READ_DOUBLE_VALUE("pointRotationAngle", pointRotationAngle);
662  READ_DOUBLE_VALUE("pointOpacity", pointOpacity);
663  READ_DOUBLE_VALUE("pointSize", pointSize);
664  READ_INT_VALUE("pointStyle", pointStyle, Symbol::Style);
665  READ_INT_VALUE("pointVisibility", pointVisibility, bool);
667  READ_QPEN(d->pointPen);
668  } else if (reader->name() == "datapickerPoint") {
669  auto* datapickerPoint = new DatapickerPoint(QString());
670  datapickerPoint->setHidden(true);
671  if (!datapickerPoint->load(reader, preview)) {
672  delete datapickerPoint;
673  return false;
674  } else
675  addChild(datapickerPoint);
676  } else { // unknown element
677  reader->raiseWarning(i18n("unknown element '%1'", reader->name().toString()));
678  if (!reader->skipToEndElement()) return false;
679  }
680  }
681 
682  d->uploadImage(d->fileName);
683  d->retransform();
684  return true;
685 }
AspectType
static const QRgb black
Definition: ImageEditor.cpp:38
AspectType type() const
@ Recursive
Recursively handle all descendents, not just immediate children.
@ IncludeHidden
Include aspects marked as "hidden" in numbering or listing children.
void addChild(AbstractAspect *)
Add the given Aspect to my list of children.
void childAspectSelectedInView(const AbstractAspect *)
void childAspectDeselectedInView(const AbstractAspect *)
void remove()
Remove me from my parent's list of children.
QString name() const
void statusInfo(const QString &)
Emitted whenever some aspect in the tree wants to give status information to the user.
void writeBasicAttributes(QXmlStreamWriter *) const
Save name and creation time to XML.
T * child(int index, ChildIndexFlags flags={}) const
AbstractAspect * parentAspect() const
Return my parent Aspect or 0 if I currently don't have one.
void beginMacro(const QString &text)
Begin an undo stack macro (series of commands)
virtual QString path() const
Return the path that leads from the top-most Aspect (usually a Project) to me.
void exec(QUndoCommand *)
Execute the given command, pushing it on the undoStack() if available.
QVector< AbstractAspect * > children(AspectType type, ChildIndexFlags flags={}) const
bool readBasicAttributes(XmlStreamReader *)
Load name and creation time from XML.
void endMacro()
End the current undo stack macro.
Base class of Aspects with MDI windows as views (AspectParts).
Definition: AbstractPart.h:36
QWidget * m_partView
Definition: AbstractPart.h:65
DatapickerImagePrivate(DatapickerImage *)
DatapickerImage::EditorSettings settings
DatapickerImage::ReferencePoints axisPoints
DatapickerImage::PointsType plotPointsType
DatapickerImage *const q
DatapickerImage::PlotImageType plotImageType
bool uploadImage(const QString &)
Datapicker/DatapickerImage view.
void exportToFile(const QString &, const WorksheetView::ExportFormat, const int)
void statusInfo(const QString &)
container to open image/plot.
QWidget * view() const override
Construct a primary view on me.
void requestUpdate()
bool printPreview() const override
void setSelectedInView(const bool)
bool load(XmlStreamReader *, bool preview) override
Load from XML.
DatapickerImage::PlotImageType plotImageType()
DatapickerImagePrivate *const d
void requestProjectContextMenu(QMenu *)
bool printView() override
Segments * m_segments
QIcon icon() const override
DatapickerImageView * m_view
void setPlotImageType(const DatapickerImage::PlotImageType)
void setSegmentsHoverEvent(const bool)
void save(QXmlStreamWriter *) const override
Save as XML.
void requestUpdateActions()
QGraphicsScene * scene() const
~DatapickerImage() override
bool exportView() const override
DatapickerImage(const QString &name, bool loading=false)
QRectF pageRect() const
void setPrinting(bool) const
QMenu * createContextMenu() override
void setPrinting(bool)
Dialog for exporting a worksheet to a file.
static QRgb findBackgroundColor(const QImage *)
static void discretize(QImage *, QImage *, const DatapickerImage::EditorSettings &, QColor)
static void uploadHistogram(int *, QImage *, QColor, DatapickerImage::ColorAttributes)
container to open image/plot.
Definition: Segments.h:36
void setAcceptHoverEvents(bool)
Definition: Segments.cpp:197
void setSegmentsVisible(bool)
Definition: Segments.cpp:192
void makeSegments(QImage &)
Definition: Segments.cpp:54
Style
Definition: Symbol.h:38
static double convertToSceneUnits(const double value, const Worksheet::Unit unit)
Definition: Worksheet.cpp:113
XML stream parser that supports errors as well as warnings. This class also adds line and column numb...
void raiseWarning(const QString &)
#define WAIT_CURSOR
Definition: macros.h:63
#define READ_DOUBLE_VALUE(name, var)
Definition: macros.h:475
#define CLASS_D_READER_IMPL(classname, type, method, var)
Definition: macros.h:148
#define RESET_CURSOR
Definition: macros.h:64
#define STD_SETTER_CMD_IMPL_S(class_name, cmd_name, value_type, field_name)
Definition: macros.h:207
#define STD_SETTER_CMD_IMPL_F_S(class_name, cmd_name, value_type, field_name, finalize_method)
Definition: macros.h:215
#define READ_INT_VALUE(name, var, type)
Definition: macros.h:468
#define READ_QPEN(pen)
Definition: macros.h:324
#define WRITE_QPEN(pen)
Definition: macros.h:315
#define READ_QBRUSH(brush)
Definition: macros.h:418
#define BASIC_D_READER_IMPL(classname, type, method, var)
Definition: macros.h:121
#define WRITE_QBRUSH(brush)
Definition: macros.h:410
#define i18n(m)
Definition: nsl_common.h:38
#define PERFTRACE(msg)
Definition: trace.h:57