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)  

Worksheet.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  File : Worksheet.cpp
3  Project : LabPlot
4  Description : Worksheet
5  --------------------------------------------------------------------
6  Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net)
7  Copyright : (C) 2011-2020 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 "Worksheet.h"
30 #include "WorksheetPrivate.h"
31 #include "WorksheetElement.h"
33 #include "backend/core/Project.h"
42 
43 #include <QPrinter>
44 #include <QPrintDialog>
45 #include <QPrintPreviewDialog>
46 #include <QDir>
47 #include <QGraphicsItem>
48 #include <QIcon>
49 
50 #include <KConfig>
51 #include <KConfigGroup>
52 #include <KLocalizedString>
53 #include <KSharedConfig>
54 
55 /**
56  * \class Worksheet
57  * \brief Top-level container for worksheet elements like plot, labels, etc.
58  *
59  * The worksheet is, besides the data containers \c Spreadsheet and \c Matrix, another central part of the application
60  * and provides an area for showing and grouping together different kinds of worksheet objects - plots, labels &etc;
61  *
62  * * \ingroup worksheet
63  */
64 Worksheet::Worksheet(const QString& name, bool loading) : AbstractPart(name, AspectType::Worksheet), d(new WorksheetPrivate(this)) {
68 
69  if (!loading)
70  init();
71 }
72 
74  delete d;
75 }
76 
78  KConfig config;
79  KConfigGroup group = config.group("Worksheet");
80 
81  //size
82  d->scaleContent = group.readEntry("ScaleContent", false);
83  d->useViewSize = group.readEntry("UseViewSize", false);
84  d->pageRect.setX(0);
85  d->pageRect.setY(0);
86  d->pageRect.setWidth(group.readEntry("Width", 1000));
87  d->pageRect.setHeight(group.readEntry("Height", 1000));
88  d->m_scene->setSceneRect(d->pageRect);
89 
90  //background
91  d->backgroundFileName = group.readEntry("BackgroundFileName", QString());
92 
93  //layout
94  d->layout = (Layout) group.readEntry("Layout", static_cast<int>(Layout::VerticalLayout));
95  d->layoutTopMargin = group.readEntry("LayoutTopMargin", convertToSceneUnits(0.5, Unit::Centimeter));
96  d->layoutBottomMargin = group.readEntry("LayoutBottomMargin", convertToSceneUnits(0.5, Unit::Centimeter));
97  d->layoutLeftMargin = group.readEntry("LayoutLeftMargin", convertToSceneUnits(0.5, Unit::Centimeter));
98  d->layoutRightMargin = group.readEntry("LayoutRightMargin", convertToSceneUnits(0.5, Unit::Centimeter));
99  d->layoutVerticalSpacing = group.readEntry("LayoutVerticalSpacing", convertToSceneUnits(0.5, Unit::Centimeter));
100  d->layoutHorizontalSpacing = group.readEntry("LayoutHorizontalSpacing", convertToSceneUnits(0.5, Unit::Centimeter));
101  d->layoutRowCount = group.readEntry("LayoutRowCount", 2);
102  d->layoutColumnCount = group.readEntry("LayoutColumnCount", 2);
103 
104  //default theme
105  KConfigGroup settings = KSharedConfig::openConfig()->group(QLatin1String("Settings_Worksheet"));
106  d->theme = settings.readEntry(QStringLiteral("Theme"), QString());
107  loadTheme(d->theme);
108 }
109 
110 /*!
111  converts from \c unit to the scene units. At the moment, 1 scene unit corresponds to 1/10 mm.
112  */
113 double Worksheet::convertToSceneUnits(const double value, const Worksheet::Unit unit) {
114  switch (unit) {
115  case Unit::Millimeter:
116  return value * 10.0;
117  case Unit::Centimeter:
118  return value * 100.0;
119  case Unit::Inch:
120  return value * 25.4 * 10.;
121  case Unit::Point:
122  return value * 25.4/72. * 10.;
123  }
124 
125  return 0;
126 }
127 
128 /*!
129  converts from the scene units to \c unit . At the moment, 1 scene unit corresponds to 1/10 mm.
130  */
131 double Worksheet::convertFromSceneUnits(const double value, const Worksheet::Unit unit) {
132  switch (unit) {
133  case Unit::Millimeter:
134  return value/10.0;
135  case Unit::Centimeter:
136  return value/100.0;
137  case Unit::Inch:
138  return value/25.4/10.;
139  case Unit::Point:
140  return value/25.4/10.*72.;
141  }
142 
143  return 0;
144 }
145 
146 QIcon Worksheet::icon() const {
147  return QIcon::fromTheme("labplot-worksheet");
148 }
149 
150 /**
151  * Return a new context menu. The caller takes ownership of the menu.
152  */
154  QMenu* menu = AbstractPart::createContextMenu();
155  Q_ASSERT(menu);
156  emit requestProjectContextMenu(menu);
157  return menu;
158 }
159 
160 //! Construct a primary view on me.
161 /**
162  * This method may be called multiple times during the life time of an Aspect, or it might not get
163  * called at all. Aspects must not depend on the existence of a view for their operation.
164  */
165 QWidget* Worksheet::view() const {
166  if (!m_partView) {
167  m_view = new WorksheetView(const_cast<Worksheet*>(this));
168  m_partView = m_view;
172  }
173  return m_partView;
174 }
175 
176 /*!
177  * returns the list of all parent aspects (folders and sub-folders)
178  * together with all the data containers required to plot the data in the worksheet
179  */
181  //add all parent aspects (folders and sub-folders)
183 
184  //traverse all plots and add all data containers they depend on
185  for (const auto* plot : children<AbstractPlot>())
186  aspects << plot->dependsOn();
187 
188  return aspects;
189 }
190 
191 bool Worksheet::exportView() const {
192  auto* dlg = new ExportWorksheetDialog(m_view);
193  dlg->setFileName(name());
194  bool ret;
195  if ( (ret = (dlg->exec() == QDialog::Accepted)) ) {
196  QString path = dlg->path();
197  const WorksheetView::ExportFormat format = dlg->exportFormat();
198  const WorksheetView::ExportArea area = dlg->exportArea();
199  const bool background = dlg->exportBackground();
200  const int resolution = dlg->exportResolution();
201 
202  WAIT_CURSOR;
203  m_view->exportToFile(path, format, area, background, resolution);
204  RESET_CURSOR;
205  }
206  delete dlg;
207  return ret;
208 }
209 
211  QPrinter printer;
212  auto* dlg = new QPrintDialog(&printer, m_view);
213  dlg->setWindowTitle(i18nc("@title:window", "Print Worksheet"));
214  bool ret;
215  if ( (ret = (dlg->exec() == QDialog::Accepted)) )
216  m_view->print(&printer);
217 
218  delete dlg;
219  return ret;
220 }
221 
223  auto* dlg = new QPrintPreviewDialog(m_view);
224  connect(dlg, &QPrintPreviewDialog::paintRequested, m_view, &WorksheetView::print);
225  return dlg->exec();
226 }
227 
229  const auto* addedElement = qobject_cast<const WorksheetElement*>(aspect);
230  if (!addedElement)
231  return;
232 
233  if (aspect->parentAspect() != this)
234  return;
235 
236  //add the GraphicsItem of the added child to the scene
237  QGraphicsItem* item = addedElement->graphicsItem();
238  d->m_scene->addItem(item);
239 
240  const CartesianPlot* plot = dynamic_cast<const CartesianPlot*>(aspect);
241  if (plot) {
252  connect(plot, &CartesianPlot::curveAdded, this, &Worksheet::curveAdded);
256  connect(plot, static_cast<void (CartesianPlot::*)(QPen, QString)>(&CartesianPlot::curveLinePenChanged), this, &Worksheet::updateCurveBackground);
258  auto* p = const_cast<CartesianPlot*>(plot);
259  p->setLocked(d->plotsLocked);
260 
261  cursorModelPlotAdded(p->name());
262  }
263  qreal zVal = 0;
264  for (auto* child : children<WorksheetElement>(ChildIndexFlag::IncludeHidden))
265  child->graphicsItem()->setZValue(zVal++);
266 
267  //if a theme was selected in the worksheet, apply this theme for newly added children
268  if (!d->theme.isEmpty() && !isLoading()) {
269  KConfig config(ThemeHandler::themeFilePath(d->theme), KConfig::SimpleConfig);
270  const_cast<WorksheetElement*>(addedElement)->loadThemeConfig(config);
271  }
272 
273  //recalculated the layout
274  if (!isLoading()) {
276  d->updateLayout(false);
277  }
278 }
279 
281  const auto* removedElement = qobject_cast<const WorksheetElement*>(aspect);
282  if (removedElement) {
283  QGraphicsItem* item = removedElement->graphicsItem();
284  d->m_scene->removeItem(item);
285  }
286 }
287 
288 void Worksheet::handleAspectRemoved(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child) {
289  Q_UNUSED(parent);
290  Q_UNUSED(before);
291 
293  d->updateLayout(false);
294  auto* plot = dynamic_cast<const CartesianPlot*>(child);
295  if (plot)
296  cursorModelPlotRemoved(plot->name());
297 }
298 
299 QGraphicsScene* Worksheet::scene() const {
300  return d->m_scene;
301 }
302 
303 QRectF Worksheet::pageRect() const {
304  return d->m_scene->sceneRect();
305 }
306 
307 /*!
308  this slot is called when a worksheet element is selected in the project explorer.
309  emits \c itemSelected() which forwards this event to the \c WorksheetView
310  in order to select the corresponding \c QGraphicsItem.
311  */
313  auto* element = qobject_cast<WorksheetElement*>(const_cast<AbstractAspect*>(aspect));
314  if (element)
315  emit itemSelected(element->graphicsItem());
316 }
317 
318 /*!
319  this slot is called when a worksheet element is deselected in the project explorer.
320  emits \c itemDeselected() which forwards this event to \c WorksheetView
321  in order to deselect the corresponding \c QGraphicsItem.
322  */
324  auto* element = qobject_cast<WorksheetElement*>(const_cast<AbstractAspect*>(aspect));
325  if (element)
326  emit itemDeselected(element->graphicsItem());
327 }
328 
329 /*!
330  * Emits the signal to select or to deselect the aspect corresponding to \c QGraphicsItem \c item in the project explorer,
331  * if \c selected=true or \c selected=false, respectively.
332  * The signal is handled in \c AspectTreeModel and forwarded to the tree view in \c ProjectExplorer.
333  * This function is called in \c WorksheetView upon selection changes.
334  */
335 void Worksheet::setItemSelectedInView(const QGraphicsItem* item, const bool b) {
336  //determine the corresponding aspect
337  const AbstractAspect* aspect(nullptr);
338  for (const auto* child : children<WorksheetElement>(ChildIndexFlag::IncludeHidden) ) {
339  aspect = this->aspectFromGraphicsItem(child, item);
340  if (aspect)
341  break;
342  }
343 
344  if (!aspect)
345  return;
346 
347  //forward selection/deselection to AbstractTreeModel
348  if (b)
349  emit childAspectSelectedInView(aspect);
350  else
351  emit childAspectDeselectedInView(aspect);
352 }
353 
354 /*!
355  * helper function: checks whether \c aspect or one of its children has the \c GraphicsItem \c item
356  * Returns a pointer to \c WorksheetElement having this item.
357  */
358 WorksheetElement* Worksheet::aspectFromGraphicsItem(const WorksheetElement* aspect, const QGraphicsItem* item) const {
359  if ( aspect->graphicsItem() == item )
360  return const_cast<WorksheetElement*>(aspect);
361  else {
364  if (a)
365  return a;
366  }
367  return nullptr;
368  }
369 }
370 
371 /*!
372  Selects or deselects the worksheet in the project explorer.
373  This function is called in \c WorksheetView.
374  The worksheet gets deselected if there are selected items in the view,
375  and selected if there are no selected items in the view.
376 */
377 void Worksheet::setSelectedInView(const bool b) {
378  if (b)
379  emit childAspectSelectedInView(this);
380  else
381  emit childAspectDeselectedInView(this);
382 }
383 
384 void Worksheet::deleteAspectFromGraphicsItem(const QGraphicsItem* item) {
385  Q_ASSERT(item);
386  //determine the corresponding aspect
387  AbstractAspect* aspect(nullptr);
388  for (const auto* child : children<WorksheetElement>(ChildIndexFlag::IncludeHidden) ) {
389  aspect = this->aspectFromGraphicsItem(child, item);
390  if (aspect)
391  break;
392  }
393 
394  if (!aspect)
395  return;
396 
397  if (aspect->parentAspect())
398  aspect->parentAspect()->removeChild(aspect);
399  else
400  this->removeChild(aspect);
401 }
402 
404  if (m_view)
405  m_view->setIsClosing();
406 }
407 
409  if (m_view)
411 }
412 
413 /*!
414  * \brief Worksheet::getPlotCount
415  * \return number of CartesianPlot's in the Worksheet
416  */
418  return children<CartesianPlot>().length();
419 }
420 
421 /*!
422  * \brief Worksheet::getPlot
423  * \param index Number of plot which should be returned
424  * \return Pointer to the CartesianPlot which was searched with index
425  */
427  auto plots = children<CartesianPlot>();
428  if (plots.length() - 1 >= index)
429  return plots.at(index);
430  return nullptr;
431 }
432 
434  return d->cursorData;
435 }
436 
438  emit requestUpdate();
439 }
440 
442  d->suppressLayoutUpdate = value;
443 }
444 
446  d->updateLayout();
447 }
448 
450  return d->cartesianPlotActionMode;
451 }
452 
454  return d->cartesianPlotCursorMode;
455 }
456 
458  return d->plotsLocked;
459 }
460 
463  return;
464 
466  project()->setChanged(true);
467 }
468 
471  return;
472 
474 
476  d->suppressCursorPosChanged = true;
477  QVector<CartesianPlot*> plots = children<CartesianPlot>();
478  QPointF logicPos;
479  if (!plots.isEmpty()) {
480  for (int i = 0; i < 2; i++) {
481  logicPos = QPointF(plots[0]->cursorPos(i), 0); // y value does not matter
483  }
484  }
485  d->suppressCursorPosChanged = false;
486  }
488  project()->setChanged(true);
489 }
490 
491 void Worksheet::setPlotsLocked(bool lock) {
492  if (d->plotsLocked == lock)
493  return;
494 
495  d->plotsLocked = lock;
496 
497  for (auto* plot: children<CartesianPlot>())
498  plot->setLocked(lock);
499 
500  project()->setChanged(true);
501 }
502 
505 }
506 
509 }
510 
511 /* =============================== getter methods for general options ==================================== */
512 BASIC_D_READER_IMPL(Worksheet, bool, scaleContent, scaleContent)
513 BASIC_D_READER_IMPL(Worksheet, bool, useViewSize, useViewSize)
514 
515 /* =============================== getter methods for background options ================================= */
516 BASIC_D_READER_IMPL(Worksheet, PlotArea::BackgroundType, backgroundType, backgroundType)
517 BASIC_D_READER_IMPL(Worksheet, PlotArea::BackgroundColorStyle, backgroundColorStyle, backgroundColorStyle)
518 BASIC_D_READER_IMPL(Worksheet, PlotArea::BackgroundImageStyle, backgroundImageStyle, backgroundImageStyle)
519 BASIC_D_READER_IMPL(Worksheet, Qt::BrushStyle, backgroundBrushStyle, backgroundBrushStyle)
520 CLASS_D_READER_IMPL(Worksheet, QColor, backgroundFirstColor, backgroundFirstColor)
521 CLASS_D_READER_IMPL(Worksheet, QColor, backgroundSecondColor, backgroundSecondColor)
522 CLASS_D_READER_IMPL(Worksheet, QString, backgroundFileName, backgroundFileName)
523 BASIC_D_READER_IMPL(Worksheet, float, backgroundOpacity, backgroundOpacity)
524 
525 /* =============================== getter methods for layout options ====================================== */
527 BASIC_D_READER_IMPL(Worksheet, float, layoutTopMargin, layoutTopMargin)
528 BASIC_D_READER_IMPL(Worksheet, float, layoutBottomMargin, layoutBottomMargin)
529 BASIC_D_READER_IMPL(Worksheet, float, layoutLeftMargin, layoutLeftMargin)
530 BASIC_D_READER_IMPL(Worksheet, float, layoutRightMargin, layoutRightMargin)
531 BASIC_D_READER_IMPL(Worksheet, float, layoutHorizontalSpacing, layoutHorizontalSpacing)
532 BASIC_D_READER_IMPL(Worksheet, float, layoutVerticalSpacing, layoutVerticalSpacing)
533 BASIC_D_READER_IMPL(Worksheet, int, layoutRowCount, layoutRowCount)
534 BASIC_D_READER_IMPL(Worksheet, int, layoutColumnCount, layoutColumnCount)
535 
536 CLASS_D_READER_IMPL(Worksheet, QString, theme, theme)
537 
538 /* ============================ setter methods and undo commands for general options ===================== */
539 void Worksheet::setUseViewSize(bool useViewSize) {
540  if (useViewSize != d->useViewSize) {
541  d->useViewSize = useViewSize;
542  emit useViewSizeRequested();
543  }
544 }
545 
546 STD_SETTER_CMD_IMPL_S(Worksheet, SetScaleContent, bool, scaleContent)
547 void Worksheet::setScaleContent(bool scaleContent) {
548  if (scaleContent != d->scaleContent)
549  exec(new WorksheetSetScaleContentCmd(d, scaleContent, ki18n("%1: change \"rescale the content\" property")));
550 }
551 
552 /* ============================ setter methods and undo commands for background options ================= */
553 STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundType, PlotArea::BackgroundType, backgroundType, update)
554 void Worksheet::setBackgroundType(PlotArea::BackgroundType type) {
555  if (type != d->backgroundType)
556  exec(new WorksheetSetBackgroundTypeCmd(d, type, ki18n("%1: background type changed")));
557 }
558 
559 STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundColorStyle, PlotArea::BackgroundColorStyle, backgroundColorStyle, update)
560 void Worksheet::setBackgroundColorStyle(PlotArea::BackgroundColorStyle style) {
561  if (style != d->backgroundColorStyle)
562  exec(new WorksheetSetBackgroundColorStyleCmd(d, style, ki18n("%1: background color style changed")));
563 }
564 
565 STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundImageStyle, PlotArea::BackgroundImageStyle, backgroundImageStyle, update)
566 void Worksheet::setBackgroundImageStyle(PlotArea::BackgroundImageStyle style) {
567  if (style != d->backgroundImageStyle)
568  exec(new WorksheetSetBackgroundImageStyleCmd(d, style, ki18n("%1: background image style changed")));
569 }
570 
571 STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundBrushStyle, Qt::BrushStyle, backgroundBrushStyle, update)
572 void Worksheet::setBackgroundBrushStyle(Qt::BrushStyle style) {
573  if (style != d->backgroundBrushStyle)
574  exec(new WorksheetSetBackgroundBrushStyleCmd(d, style, ki18n("%1: background brush style changed")));
575 }
576 
577 STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundFirstColor, QColor, backgroundFirstColor, update)
578 void Worksheet::setBackgroundFirstColor(const QColor &color) {
579  if (color!= d->backgroundFirstColor)
580  exec(new WorksheetSetBackgroundFirstColorCmd(d, color, ki18n("%1: set background first color")));
581 }
582 
583 STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundSecondColor, QColor, backgroundSecondColor, update)
584 void Worksheet::setBackgroundSecondColor(const QColor &color) {
585  if (color!= d->backgroundSecondColor)
586  exec(new WorksheetSetBackgroundSecondColorCmd(d, color, ki18n("%1: set background second color")));
587 }
588 
589 STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundFileName, QString, backgroundFileName, update)
590 void Worksheet::setBackgroundFileName(const QString& fileName) {
591  if (fileName!= d->backgroundFileName)
592  exec(new WorksheetSetBackgroundFileNameCmd(d, fileName, ki18n("%1: set background image")));
593 }
594 
595 STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundOpacity, float, backgroundOpacity, update)
596 void Worksheet::setBackgroundOpacity(float opacity) {
597  if (opacity != d->backgroundOpacity)
598  exec(new WorksheetSetBackgroundOpacityCmd(d, opacity, ki18n("%1: set opacity")));
599 }
600 
601 /* ============================ setter methods and undo commands for layout options ================= */
602 STD_SETTER_CMD_IMPL_F_S(Worksheet, SetLayout, Worksheet::Layout, layout, updateLayout)
603 void Worksheet::setLayout(Worksheet::Layout layout) {
604  if (layout != d->layout) {
605  beginMacro(i18n("%1: set layout", name()));
606  exec(new WorksheetSetLayoutCmd(d, layout, ki18n("%1: set layout")));
607  endMacro();
608  }
609 }
610 
611 STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutTopMargin, float, layoutTopMargin, updateLayout)
612 void Worksheet::setLayoutTopMargin(float margin) {
613  if (margin != d->layoutTopMargin) {
614  beginMacro(i18n("%1: set layout top margin", name()));
615  exec(new WorksheetSetLayoutTopMarginCmd(d, margin, ki18n("%1: set layout top margin")));
616  endMacro();
617  }
618 }
619 
620 STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutBottomMargin, float, layoutBottomMargin, updateLayout)
621 void Worksheet::setLayoutBottomMargin(float margin) {
622  if (margin != d->layoutBottomMargin) {
623  beginMacro(i18n("%1: set layout bottom margin", name()));
624  exec(new WorksheetSetLayoutBottomMarginCmd(d, margin, ki18n("%1: set layout bottom margin")));
625  endMacro();
626  }
627 }
628 
629 STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutLeftMargin, float, layoutLeftMargin, updateLayout)
630 void Worksheet::setLayoutLeftMargin(float margin) {
631  if (margin != d->layoutLeftMargin) {
632  beginMacro(i18n("%1: set layout left margin", name()));
633  exec(new WorksheetSetLayoutLeftMarginCmd(d, margin, ki18n("%1: set layout left margin")));
634  endMacro();
635  }
636 }
637 
638 STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutRightMargin, float, layoutRightMargin, updateLayout)
639 void Worksheet::setLayoutRightMargin(float margin) {
640  if (margin != d->layoutRightMargin) {
641  beginMacro(i18n("%1: set layout right margin", name()));
642  exec(new WorksheetSetLayoutRightMarginCmd(d, margin, ki18n("%1: set layout right margin")));
643  endMacro();
644  }
645 }
646 
647 STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutVerticalSpacing, float, layoutVerticalSpacing, updateLayout)
648 void Worksheet::setLayoutVerticalSpacing(float spacing) {
649  if (spacing != d->layoutVerticalSpacing) {
650  beginMacro(i18n("%1: set layout vertical spacing", name()));
651  exec(new WorksheetSetLayoutVerticalSpacingCmd(d, spacing, ki18n("%1: set layout vertical spacing")));
652  endMacro();
653  }
654 }
655 
656 STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutHorizontalSpacing, float, layoutHorizontalSpacing, updateLayout)
657 void Worksheet::setLayoutHorizontalSpacing(float spacing) {
658  if (spacing != d->layoutHorizontalSpacing) {
659  beginMacro(i18n("%1: set layout horizontal spacing", name()));
660  exec(new WorksheetSetLayoutHorizontalSpacingCmd(d, spacing, ki18n("%1: set layout horizontal spacing")));
661  endMacro();
662  }
663 }
664 
665 STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutRowCount, int, layoutRowCount, updateLayout)
666 void Worksheet::setLayoutRowCount(int count) {
667  if (count != d->layoutRowCount) {
668  beginMacro(i18n("%1: set layout row count", name()));
669  exec(new WorksheetSetLayoutRowCountCmd(d, count, ki18n("%1: set layout row count")));
670  endMacro();
671  }
672 }
673 
674 STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutColumnCount, int, layoutColumnCount, updateLayout)
675 void Worksheet::setLayoutColumnCount(int count) {
676  if (count != d->layoutColumnCount) {
677  beginMacro(i18n("%1: set layout column count", name()));
678  exec(new WorksheetSetLayoutColumnCountCmd(d, count, ki18n("%1: set layout column count")));
679  endMacro();
680  }
681 }
682 
683 class WorksheetSetPageRectCmd : public StandardMacroSetterCmd<Worksheet::Private, QRectF> {
684 public:
685  WorksheetSetPageRectCmd(Worksheet::Private* target, QRectF newValue, const KLocalizedString& description)
686  : StandardMacroSetterCmd<Worksheet::Private, QRectF>(target, &Worksheet::Private::pageRect, newValue, description) {}
687  void finalize() override {
690  }
691  void finalizeUndo() override {
692  m_target->m_scene->setSceneRect(m_target->*m_field);
694  }
695 };
696 
697 void Worksheet::setPageRect(const QRectF& rect) {
698  //don't allow any rectangulars of width/height equal to zero
699  if (qFuzzyCompare(rect.width(), 0.) || qFuzzyCompare(rect.height(), 0.)) {
700  emit pageRectChanged(d->pageRect);
701  return;
702  }
703 
704  if (rect != d->pageRect) {
705  if (!d->useViewSize) {
706  beginMacro(i18n("%1: set page size", name()));
707  exec(new WorksheetSetPageRectCmd(d, rect, ki18n("%1: set page size")));
708  endMacro();
709  } else {
710  d->pageRect = rect;
711  d->updatePageRect();
712  emit pageRectChanged(d->pageRect);
713  }
714  }
715 }
716 
717 void Worksheet::setPrinting(bool on) const {
719  for (auto* child : childElements)
720  child->setPrinting(on);
721 }
722 
723 STD_SETTER_CMD_IMPL_S(Worksheet, SetTheme, QString, theme)
724 void Worksheet::setTheme(const QString& theme) {
725  if (theme != d->theme) {
726  QString info;
727  if (!theme.isEmpty())
728  info = i18n("%1: load theme %2", name(), theme);
729  else
730  info = i18n("%1: load default theme", name());
731  beginMacro(info);
732  exec(new WorksheetSetThemeCmd(d, theme, ki18n("%1: set theme")));
733  loadTheme(theme);
734  endMacro();
735  }
736 }
737 
741  for (auto* plot : plots)
742  plot->mousePressZoomSelectionMode(logicPos);
743  } else {
744  CartesianPlot* plot = static_cast<CartesianPlot*>(QObject::sender());
745  plot->mousePressZoomSelectionMode(logicPos);
746  }
747 }
748 
752  for (auto* plot : plots)
753  plot->mouseReleaseZoomSelectionMode();
754  } else {
755  CartesianPlot* plot = static_cast<CartesianPlot*>(QObject::sender());
757  }
758 }
759 
760 void Worksheet::cartesianPlotMousePressCursorMode(int cursorNumber, QPointF logicPos) {
763  for (auto* plot : plots)
764  plot->mousePressCursorMode(cursorNumber, logicPos);
765  } else {
766  CartesianPlot* plot = static_cast<CartesianPlot*>(QObject::sender());
767  plot->mousePressCursorMode(cursorNumber, logicPos);
768  }
769 
770  cursorPosChanged(cursorNumber, logicPos.x());
771 }
772 
776  for (auto* plot : plots)
777  plot->mouseMoveZoomSelectionMode(logicPos);
778  } else {
779  CartesianPlot* plot = static_cast<CartesianPlot*>(QObject::sender());
780  plot->mouseMoveZoomSelectionMode(logicPos);
781  }
782 }
783 
787  for (auto* plot : plots)
788  plot->mouseHoverZoomSelectionMode(logicPos);
789  } else {
790  CartesianPlot* plot = static_cast<CartesianPlot*>(QObject::sender());
791  plot->mouseHoverZoomSelectionMode(logicPos);
792  }
793 }
794 
798  for (auto* plot : plots)
799  plot->mouseHoverOutsideDataRect();
800  } else {
801  CartesianPlot* plot = static_cast<CartesianPlot*>(QObject::sender());
803  }
804 }
805 
806 void Worksheet::cartesianPlotMouseMoveCursorMode(int cursorNumber, QPointF logicPos) {
809  for (auto* plot : plots)
810  plot->mouseMoveCursorMode(cursorNumber, logicPos);
811  } else {
812  CartesianPlot* plot = static_cast<CartesianPlot*>(QObject::sender());
813  plot->mouseMoveCursorMode(cursorNumber, logicPos);
814  }
815 
816  cursorPosChanged(cursorNumber, logicPos.x());
817 }
818 
819 /*!
820  * \brief Worksheet::cursorPosChanged
821  * Updates the cursor treemodel with the new data
822  * \param xPos: new position of the cursor
823  * It is assumed, that the plots/curves are in the same order than receiving from
824  * the children() function. It's not checked if the names are the same
825  */
826 void Worksheet::cursorPosChanged(int cursorNumber, double xPos) {
828  return;
829 
830  auto* sender = dynamic_cast<CartesianPlot*>(QObject::sender());
831  if (!sender)
832  return;
833 
834  TreeModel* treeModel = cursorModel();
835 
836  // if ApplyActionToSelection, each plot has it's own x value
838  // x values
839  int rowPlot = 1;
840  QModelIndex xName = treeModel->index(0, static_cast<int>(WorksheetPrivate::TreeModelColumn::SIGNALNAME));
841  treeModel->setData(xName, QVariant("X"));
842  double valueCursor[2];
843  for (int i = 0; i < 2; i++) { // need both cursors to calculate diff
844  valueCursor[i] = sender->cursorPos(i);
845  treeModel->setTreeData(QVariant(valueCursor[i]), 0, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0) + i);
846 
847  }
848  treeModel->setTreeData(QVariant(valueCursor[1] - valueCursor[0]), 0, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF));
849 
850  // y values
851  for (int i = 0; i < getPlotCount(); i++) { // i=0 is the x Axis
852 
853  auto* plot = getPlot(i);
854  if (!plot || !plot->isVisible())
855  continue;
856 
857  QModelIndex plotIndex = treeModel->index(rowPlot, static_cast<int>(WorksheetPrivate::TreeModelColumn::PLOTNAME));
858 
859  // curves
860  int rowCurve = 0;
861  for (int j = 0; j < plot->curveCount(); j++) {
862  // assumption: index of signals in model is the same than the index of the signal in the plot
863  bool valueFound;
864 
865  const XYCurve* curve = plot->getCurve(j);
866  if (!curve->isVisible())
867  continue;
868 
869  double value = curve->y(xPos, valueFound);
870  if (cursorNumber == 0) {
871  treeModel->setTreeData(QVariant(value), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0), plotIndex);
872  double valueCursor1 = treeModel->treeData(rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR1), plotIndex).toDouble();
873  treeModel->setTreeData(QVariant(valueCursor1 - value), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), plotIndex);
874  } else {
875  treeModel->setTreeData(QVariant(value), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR1), plotIndex);
876  double valueCursor0 = treeModel->treeData(rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0), plotIndex).toDouble();
877  treeModel->setTreeData(QVariant(value - valueCursor0), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), plotIndex);
878  }
879  rowCurve++;
880  }
881  rowPlot++;
882  }
883  } else { // apply to selection
884  // assumption: plot is visible
885  int rowCount = treeModel->rowCount();
886  for (int i = 0; i < rowCount; i++) {
887  QModelIndex plotIndex = treeModel->index(i, static_cast<int>(WorksheetPrivate::TreeModelColumn::PLOTNAME));
888  if (plotIndex.data().toString().compare(sender->name()) != 0)
889  continue;
890 
891  // x values (first row always exist)
892  treeModel->setTreeData(QVariant("X"), 0, static_cast<int>(WorksheetPrivate::TreeModelColumn::SIGNALNAME), plotIndex);
893  double valueCursor[2];
894  for (int i = 0; i < 2; i++) { // need both cursors to calculate diff
895  valueCursor[i] = sender->cursorPos(i);
896  treeModel->setTreeData(QVariant(valueCursor[i]), 0, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0) + i, plotIndex);
897  }
898  treeModel->setTreeData(QVariant(valueCursor[1]-valueCursor[0]), 0, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), plotIndex);
899 
900  // y values
901  int rowCurve = 1; // first is x value
902  for (int j = 0; j< sender->curveCount(); j++) { // j=0 are the x values
903 
904  const XYCurve* curve = sender->getCurve(j); // -1 because we start with 1 for the x axis
905  if (!curve->isVisible())
906  continue;
907 
908  // assumption: index of signals in model is the same than the index of the signal in the plot
909  bool valueFound;
910 
911  double value = curve->y(xPos, valueFound);
912  if (cursorNumber == 0) {
913  treeModel->setTreeData(QVariant(value), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0), plotIndex);
914  double valueCursor1 = treeModel->treeData(rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR1), plotIndex).toDouble();
915  treeModel->setTreeData(QVariant(valueCursor1 - value), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), plotIndex);
916  } else {
917  treeModel->setTreeData(QVariant(value), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR1), plotIndex);
918  double valueCursor0 = treeModel->treeData(rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0), plotIndex).toDouble();
919  treeModel->setTreeData(QVariant(value - valueCursor0), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), plotIndex);
920  }
921  rowCurve++;
922  }
923  }
924  }
925 }
926 
927 void Worksheet::cursorModelPlotAdded(const QString& name) {
928  Q_UNUSED(name);
929 // TreeModel* treeModel = cursorModel();
930 // int rowCount = treeModel->rowCount();
931 // // add plot at the end
932 // treeModel->insertRows(rowCount, 1); // add empty rows. Then they become filled
933 // treeModel->setTreeData(QVariant(name), rowCount, WorksheetPrivate::TreeModelColumn::PLOTNAME); // rowCount instead of rowCount -1 because first row is the x value
935 }
936 
937 void Worksheet::cursorModelPlotRemoved(const QString& name) {
938  TreeModel* treeModel = cursorModel();
939  int rowCount = treeModel->rowCount();
940 
941  // first is x Axis
942  for (int i = 1; i < rowCount; i++) {
943  QModelIndex plotIndex = treeModel->index(i, static_cast<int>(WorksheetPrivate::TreeModelColumn::PLOTNAME));
944  if (plotIndex.data().toString().compare(name) != 0)
945  continue;
946  treeModel->removeRows(plotIndex.row(), 1);
947  return;
948  }
949 }
950 
954  d->updateCompleteCursorModel = false;
955  }
956 
958 }
959 
961  auto* plot = dynamic_cast<CartesianPlot*>(QObject::sender());
962  if (!plot)
963  return;
964 
965  TreeModel* treeModel = cursorModel();
966  int rowCount = treeModel->rowCount();
967 
968  for (int i = 0; i < rowCount; i++) {
969  QModelIndex plotIndex = treeModel->index(i, static_cast<int>(WorksheetPrivate::TreeModelColumn::PLOTNAME));
970  if (plotIndex.data().toString().compare(plot->name()) != 0)
971  continue;
972 
973  for (int j = 0; j < plot->curveCount(); j++) {
974 
975  if (plot->getCurve(j)->name().compare(curve->name()) != 0)
976  continue;
977 
978  treeModel->setTreeData(QVariant(curve->name()), j, static_cast<int>(WorksheetPrivate::TreeModelColumn::SIGNALNAME), plotIndex);
979 
980  bool valueFound;
981  double valueCursor0 = curve->y(plot->cursorPos(0), valueFound);
982  treeModel->setTreeData(QVariant(valueCursor0), j, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0), plotIndex);
983 
984  double valueCursor1 = curve->y(plot->cursorPos(1), valueFound);
985  treeModel->setTreeData(QVariant(valueCursor1), j, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR1), plotIndex);
986 
987  treeModel->setTreeData(QVariant(valueCursor1-valueCursor0), j, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), plotIndex);
988  break;
989  }
990  break;
991  }
992 }
993 
994 void Worksheet::curveAdded(const XYCurve* curve) {
995  auto* plot = dynamic_cast<CartesianPlot*>(QObject::sender());
996  if (!plot)
997  return;
998 
999  TreeModel* treeModel = cursorModel();
1000  int rowCount = treeModel->rowCount();
1001 
1002  int i = 0;
1003  // first row is the x axis when applied to all plots. Starting at the second row
1005  i = 1;
1006 
1007  for (; i < rowCount; i++) {
1008  QModelIndex plotIndex = treeModel->index(i, static_cast<int>(WorksheetPrivate::TreeModelColumn::PLOTNAME));
1009  if (plotIndex.data().toString().compare(plot->name()) != 0)
1010  continue;
1011  int row = 0;
1012  for (int j = 0; j < plot->curveCount(); j++) {
1013 
1014  if (plot->getCurve(j)->name().compare(curve->name()) != 0) {
1015  if (plot->getCurve(j)->isVisible())
1016  row ++;
1017  continue;
1018  }
1019 
1020  treeModel->insertRow(row, plotIndex);
1021 
1022  treeModel->setTreeData(QVariant(curve->name()), row, static_cast<int>(WorksheetPrivate::TreeModelColumn::SIGNALNAME), plotIndex);
1023  QColor curveColor = curve->linePen().color();
1024  curveColor.setAlpha(50);
1025  treeModel->setTreeData(QVariant(curveColor),row, static_cast<int>(WorksheetPrivate::TreeModelColumn::SIGNALNAME), plotIndex, Qt::BackgroundRole);
1026  bool valueFound;
1027  double valueCursor0 = curve->y(plot->cursorPos(0), valueFound);
1028  treeModel->setTreeData(QVariant(valueCursor0), row, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0), plotIndex);
1029 
1030  double valueCursor1 = curve->y(plot->cursorPos(1), valueFound);
1031  treeModel->setTreeData(QVariant(valueCursor1), row, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR1), plotIndex);
1032 
1033  treeModel->setTreeData(QVariant(valueCursor1-valueCursor0), row, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), plotIndex);
1034  break;
1035  }
1036  break;
1037  }
1038 }
1039 
1040 void Worksheet::curveRemoved(const XYCurve* curve) {
1041 
1042  auto* plot = dynamic_cast<CartesianPlot*>(QObject::sender());
1043  if (!plot)
1044  return;
1045 
1046  TreeModel* treeModel = cursorModel();
1047  int rowCount = treeModel->rowCount();
1048 
1049  for (int i = 0; i < rowCount; i++) {
1050  QModelIndex plotIndex = treeModel->index(i, static_cast<int>(WorksheetPrivate::TreeModelColumn::PLOTNAME));
1051  if (plotIndex.data().toString().compare(plot->name()) != 0)
1052  continue;
1053 
1054  int curveCount = treeModel->rowCount(plotIndex);
1055  for (int j = 0; j < curveCount; j++) {
1056  QModelIndex curveIndex = treeModel->index(j, static_cast<int>(WorksheetPrivate::TreeModelColumn::SIGNALNAME), plotIndex);
1057 
1058  if (curveIndex.data().toString().compare(curve->name()) != 0)
1059  continue;
1060  treeModel->removeRow(j, plotIndex);
1061  break;
1062  }
1063  break;
1064  }
1065 }
1066 
1067 /*!
1068  * Updates the background of the cuves entry in the treeview
1069  * @param pen Pen of the curve
1070  * @param curveName Curve name to find in treemodel
1071  */
1072 void Worksheet::updateCurveBackground(const QPen& pen, const QString& curveName) {
1073  const CartesianPlot* plot = static_cast<const CartesianPlot*>(QObject::sender());
1074  TreeModel* treeModel = cursorModel();
1075  int rowCount = treeModel->rowCount();
1076 
1077  for (int i = 0; i < rowCount; i++) {
1078  QModelIndex plotIndex = treeModel->index(i, static_cast<int>(WorksheetPrivate::TreeModelColumn::PLOTNAME));
1079  if (plotIndex.data().toString().compare(plot->name()) != 0)
1080  continue;
1081 
1082  int curveCount = treeModel->rowCount(plotIndex);
1083  for (int j = 0; j < curveCount; j++) {
1084  QModelIndex curveIndex = treeModel->index(j, static_cast<int>(WorksheetPrivate::TreeModelColumn::SIGNALNAME),
1085  plotIndex);
1086 
1087  if (curveIndex.data().toString().compare(curveName) != 0)
1088  continue;
1089 
1090  QColor curveColor = pen.color();
1091  curveColor.setAlpha(50);
1092  treeModel->setTreeData(QVariant(curveColor), j,
1094  plotIndex, Qt::BackgroundRole);
1095  return;
1096  }
1097  return;
1098  }
1099 }
1100 
1101 /**
1102  * @brief Worksheet::updateCompleteCursorTreeModel
1103  * If the plot or the curve are not available, the plot/curve is not in the treemodel!
1104  */
1106  if (isLoading())
1107  return;
1108 
1109  TreeModel* treeModel = cursorModel();
1110 
1111  if (treeModel->rowCount() > 0)
1112  treeModel->removeRows(0, treeModel->rowCount()); // remove all data
1113 
1114  int plotCount = getPlotCount();
1115  if (plotCount < 1)
1116  return;
1117 
1119  // 1 because of the X data
1120  treeModel->insertRows(0, 1); //, treeModel->index(0,0)); // add empty rows. Then they become filled
1121 
1122  // set X data
1123  QModelIndex xName = treeModel->index(0, static_cast<int>(WorksheetPrivate::TreeModelColumn::SIGNALNAME));
1124  treeModel->setData(xName, QVariant("X"));
1125  auto* plot0 = getPlot(0);
1126  if (plot0) {
1127  double valueCursor[2];
1128  for (int i = 0; i < 2; i++) {
1129  valueCursor[i] = plot0->cursorPos(i);
1130  QModelIndex cursor = treeModel->index(0, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0) + i);
1131 
1132  treeModel->setData(cursor, QVariant(valueCursor[i]));
1133  }
1134  QModelIndex diff = treeModel->index(0, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF));
1135  treeModel->setData(diff, QVariant(valueCursor[1]-valueCursor[0]));
1136  }
1137  } else {
1138  //treeModel->insertRows(0, plotCount, treeModel->index(0,0)); // add empty rows. Then they become filled
1139  }
1140 
1141  // set plot name, y value, background
1142  for (int i = 0; i < plotCount; i++) {
1143  auto* plot = getPlot(i);
1144  QModelIndex plotName;
1145  int addOne = 0;
1146 
1147  if (!plot || !plot->isVisible())
1148  continue;
1149 
1150  // add new entry for the plot
1151  treeModel->insertRows(treeModel->rowCount(), 1); //, treeModel->index(0, 0));
1152 
1153  // add plot name and X row if needed
1155  plotName = treeModel->index(i + 1, static_cast<int>(WorksheetPrivate::TreeModelColumn::PLOTNAME)); // plus one because first row are the x values
1156  treeModel->setData(plotName, QVariant(plot->name()));
1157  } else {
1158  addOne = 1;
1159  plotName = treeModel->index(i, static_cast<int>(WorksheetPrivate::TreeModelColumn::PLOTNAME));
1160  treeModel->setData(plotName, QVariant(plot->name()));
1161  treeModel->insertRows(0, 1, plotName); // one, because the first row are the x values
1162 
1163  QModelIndex xName = treeModel->index(0, static_cast<int>(WorksheetPrivate::TreeModelColumn::SIGNALNAME), plotName);
1164  treeModel->setData(xName, QVariant("X"));
1165  double valueCursor[2];
1166  for (int i = 0; i < 2; i++) {
1167  valueCursor[i] = plot->cursorPos(i);
1168  QModelIndex cursor = treeModel->index(0, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0) + i, plotName);
1169 
1170  treeModel->setData(cursor, QVariant(valueCursor[i]));
1171  }
1172  QModelIndex diff = treeModel->index(0, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), plotName);
1173  treeModel->setData(diff, QVariant(valueCursor[1]-valueCursor[0]));
1174  }
1175 
1176 
1177  int rowCurve = addOne;
1178  for (int j = 0; j < plot->curveCount(); j++) {
1179  double cursorValue[2] = {NAN, NAN};
1180  const XYCurve* curve = plot->getCurve(j);
1181 
1182  if (!curve->isVisible())
1183  continue;
1184 
1185  for (int k = 0; k < 2; k++) {
1186  double xPos = plot->cursorPos(k);
1187  bool valueFound;
1188  cursorValue[k] = curve->y(xPos,valueFound);
1189  }
1190  treeModel->insertRows(rowCurve, 1, plotName);
1191  QColor curveColor = curve->linePen().color();
1192  curveColor.setAlpha(50);
1193  treeModel->setTreeData(QVariant(curveColor), rowCurve, 0, plotName, Qt::BackgroundRole);
1194  treeModel->setTreeData(QVariant(curve->name()), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::SIGNALNAME), plotName);
1195  treeModel->setTreeData(QVariant(cursorValue[0]), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0), plotName);
1196  treeModel->setTreeData(QVariant(cursorValue[1]), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR1), plotName);
1197  treeModel->setTreeData(QVariant(cursorValue[1] - cursorValue[0]), rowCurve, static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), plotName);
1198  rowCurve++;
1199  }
1200  }
1201 }
1202 
1203 //##############################################################################
1204 //###################### Private implementation ###############################
1205 //##############################################################################
1206 WorksheetPrivate::WorksheetPrivate(Worksheet* owner) : q(owner), m_scene(new QGraphicsScene()) {
1207  QStringList headers = {i18n("Curves"), "V1", "V2", "V2-V1"};
1208  cursorData = new TreeModel(headers, nullptr);
1209 }
1210 
1211 QString WorksheetPrivate::name() const {
1212  return q->name();
1213 }
1214 
1215 /*!
1216  * called if the worksheet page (the actual size of worksheet's rectangular) was changed.
1217  * if a layout is active, it is is updated - this adjusts the sizes of the elements in the layout to the new page size.
1218  * if no layout is active and the option "scale content" is active, \c handleResize() is called to adjust zhe properties.
1219  */
1221  if (q->isLoading())
1222  return;
1223 
1224  QRectF oldRect = m_scene->sceneRect();
1225  m_scene->setSceneRect(pageRect);
1226 
1228  updateLayout();
1229  else {
1230  if (scaleContent) {
1231  qreal horizontalRatio = pageRect.width() / oldRect.width();
1232  qreal verticalRatio = pageRect.height() / oldRect.height();
1234  if (useViewSize) {
1235  //don't make the change of the geometry undoable/redoable if the view size is used.
1236  for (auto* elem : childElements) {
1237  elem->setUndoAware(false);
1238  elem->handleResize(horizontalRatio, verticalRatio, true);
1239  elem->setUndoAware(true);
1240  }
1241  } else {
1242 // for (auto* child : childElements)
1243 // child->handleResize(horizontalRatio, verticalRatio, true);
1244  }
1245  }
1246  }
1247 }
1248 
1250  q->update();
1251 }
1252 
1254  delete m_scene;
1255 }
1256 
1257 void WorksheetPrivate::updateLayout(bool undoable) {
1259  return;
1260 
1261  auto list = q->children<WorksheetElementContainer>();
1262  int count = list.count();
1263  if (count == 0)
1264  return;
1265 
1267  for (auto* elem : list)
1268  elem->graphicsItem()->setFlag(QGraphicsItem::ItemIsMovable, true);
1269 
1270  return;
1271  }
1272 
1273  float x = layoutLeftMargin;
1274  float y = layoutTopMargin;
1275  float w, h;
1277  w = m_scene->sceneRect().width() - layoutLeftMargin - layoutRightMargin;
1278  h = (m_scene->sceneRect().height()-layoutTopMargin-layoutBottomMargin- (count-1)*layoutVerticalSpacing)/count;
1279  for (auto* elem : list) {
1280  setContainerRect(elem, x, y, h, w, undoable);
1281  y += h + layoutVerticalSpacing;
1282  }
1284  w = (m_scene->sceneRect().width()-layoutLeftMargin-layoutRightMargin- (count-1)*layoutHorizontalSpacing)/count;
1285  h = m_scene->sceneRect().height() - layoutTopMargin-layoutBottomMargin;
1286  for (auto* elem : list) {
1287  setContainerRect(elem, x, y, h, w, undoable);
1288  x += w + layoutHorizontalSpacing;
1289  }
1290  } else { //GridLayout
1291  //add new rows, if not sufficient
1292  if (count > layoutRowCount*layoutColumnCount) {
1293  layoutRowCount = floor( (float)count/layoutColumnCount + 0.5);
1295  }
1296 
1299  int columnIndex = 0; //counts the columns in a row
1300  for (auto* elem : list) {
1301  setContainerRect(elem, x, y, h, w, undoable);
1302  x += w + layoutHorizontalSpacing;
1303  columnIndex++;
1304  if (columnIndex == layoutColumnCount) {
1305  columnIndex = 0;
1306  x = layoutLeftMargin;
1307  y += h + layoutVerticalSpacing;
1308  }
1309  }
1310  }
1311 }
1312 
1313 void WorksheetPrivate::setContainerRect(WorksheetElementContainer* elem, float x, float y, float h, float w, bool undoable) {
1314  if (useViewSize) {
1315  //when using the view size, no need to put rect changes onto the undo-stack
1316  elem->setUndoAware(false);
1317  elem->setRect(QRectF(x,y,w,h));
1318  elem->setUndoAware(true);
1319  } else {
1320  //don't put rect changed onto the undo-stack if undoable-flag is set to true,
1321  //e.g. when new child is added or removed (the layout and the childrend rects will be updated anyway)
1322  if (!undoable) {
1323  elem->setUndoAware(false);
1324  elem->setRect(QRectF(x,y,w,h));
1325  elem->setUndoAware(true);
1326  } else
1327  elem->setRect(QRectF(x,y,w,h));
1328  }
1329  elem->graphicsItem()->setFlag(QGraphicsItem::ItemIsMovable, false);
1330 }
1331 
1332 //##############################################################################
1333 //################## Serialization/Deserialization ###########################
1334 //##############################################################################
1335 
1336 //! Save as XML
1337 void Worksheet::save(QXmlStreamWriter* writer) const {
1338  writer->writeStartElement( "worksheet" );
1339  writeBasicAttributes(writer);
1340  writeCommentElement(writer);
1341 
1342  //applied theme
1343  if (!d->theme.isEmpty()) {
1344  writer->writeStartElement( "theme" );
1345  writer->writeAttribute("name", d->theme);
1346  writer->writeEndElement();
1347  }
1348 
1349  //geometry
1350  writer->writeStartElement( "geometry" );
1351  QRectF rect = d->m_scene->sceneRect();
1352  writer->writeAttribute( "x", QString::number(rect.x()) );
1353  writer->writeAttribute( "y", QString::number(rect.y()) );
1354  writer->writeAttribute( "width", QString::number(rect.width()) );
1355  writer->writeAttribute( "height", QString::number(rect.height()) );
1356  writer->writeAttribute( "useViewSize", QString::number(d->useViewSize) );
1357  writer->writeEndElement();
1358 
1359  //layout
1360  writer->writeStartElement( "layout" );
1361  writer->writeAttribute( "layout", QString::number(static_cast<int>(d->layout)) );
1362  writer->writeAttribute( "topMargin", QString::number(d->layoutTopMargin) );
1363  writer->writeAttribute( "bottomMargin", QString::number(d->layoutBottomMargin) );
1364  writer->writeAttribute( "leftMargin", QString::number(d->layoutLeftMargin) );
1365  writer->writeAttribute( "rightMargin", QString::number(d->layoutRightMargin) );
1366  writer->writeAttribute( "verticalSpacing", QString::number(d->layoutVerticalSpacing) );
1367  writer->writeAttribute( "horizontalSpacing", QString::number(d->layoutHorizontalSpacing) );
1368  writer->writeAttribute( "columnCount", QString::number(d->layoutColumnCount) );
1369  writer->writeAttribute( "rowCount", QString::number(d->layoutRowCount) );
1370  writer->writeEndElement();
1371 
1372  //background properties
1373  writer->writeStartElement( "background" );
1374  writer->writeAttribute( "type", QString::number(static_cast<int>(d->backgroundType)) );
1375  writer->writeAttribute( "colorStyle", QString::number(static_cast<int>(d->backgroundColorStyle)) );
1376  writer->writeAttribute( "imageStyle", QString::number(static_cast<int>(d->backgroundImageStyle)) );
1377  writer->writeAttribute( "brushStyle", QString::number(d->backgroundBrushStyle) );
1378  writer->writeAttribute( "firstColor_r", QString::number(d->backgroundFirstColor.red()) );
1379  writer->writeAttribute( "firstColor_g", QString::number(d->backgroundFirstColor.green()) );
1380  writer->writeAttribute( "firstColor_b", QString::number(d->backgroundFirstColor.blue()) );
1381  writer->writeAttribute( "secondColor_r", QString::number(d->backgroundSecondColor.red()) );
1382  writer->writeAttribute( "secondColor_g", QString::number(d->backgroundSecondColor.green()) );
1383  writer->writeAttribute( "secondColor_b", QString::number(d->backgroundSecondColor.blue()) );
1384  writer->writeAttribute( "fileName", d->backgroundFileName );
1385  writer->writeAttribute( "opacity", QString::number(d->backgroundOpacity) );
1386  writer->writeEndElement();
1387 
1388  // cartesian properties
1389  writer->writeStartElement( "plotProperties" );
1390  writer->writeAttribute( "plotsLocked", QString::number(d->plotsLocked) );
1391  writer->writeAttribute( "cartesianPlotActionMode", QString::number(static_cast<int>(d->cartesianPlotActionMode)));
1392  writer->writeAttribute( "cartesianPlotCursorMode", QString::number(static_cast<int>(d->cartesianPlotCursorMode)));
1393  writer->writeEndElement();
1394 
1395  //serialize all children
1396  for (auto* child : children<WorksheetElement>(ChildIndexFlag::IncludeHidden))
1397  child->save(writer);
1398 
1399  writer->writeEndElement(); // close "worksheet" section
1400 }
1401 
1402 //! Load from XML
1403 bool Worksheet::load(XmlStreamReader* reader, bool preview) {
1404  if (!readBasicAttributes(reader))
1405  return false;
1406 
1407  //clear the theme that was potentially set in init() in order to correctly load here the worksheets without any theme used
1408  d->theme.clear();
1409 
1410  KLocalizedString attributeWarning = ki18n("Attribute '%1' missing or empty, default value is used");
1411  QXmlStreamAttributes attribs;
1412  QString str;
1413  QRectF rect;
1414 
1415  while (!reader->atEnd()) {
1416  reader->readNext();
1417  if (reader->isEndElement() && reader->name() == "worksheet")
1418  break;
1419 
1420  if (!reader->isStartElement())
1421  continue;
1422 
1423  if (reader->name() == "comment") {
1424  if (!readCommentElement(reader))
1425  return false;
1426  } else if (!preview && reader->name() == "theme") {
1427  attribs = reader->attributes();
1428  d->theme = attribs.value("name").toString();
1429  } else if (!preview && reader->name() == "geometry") {
1430  attribs = reader->attributes();
1431 
1432  str = attribs.value("x").toString();
1433  if (str.isEmpty())
1434  reader->raiseWarning(attributeWarning.subs("x").toString());
1435  else
1436  rect.setX(str.toDouble());
1437 
1438  str = attribs.value("y").toString();
1439  if (str.isEmpty())
1440  reader->raiseWarning(attributeWarning.subs("y").toString());
1441  else
1442  rect.setY(str.toDouble());
1443 
1444  str = attribs.value("width").toString();
1445  if (str.isEmpty())
1446  reader->raiseWarning(attributeWarning.subs("width").toString());
1447  else
1448  rect.setWidth(str.toDouble());
1449 
1450  str = attribs.value("height").toString();
1451  if (str.isEmpty())
1452  reader->raiseWarning(attributeWarning.subs("height").toString());
1453  else
1454  rect.setHeight(str.toDouble());
1455 
1456  READ_INT_VALUE("useViewSize", useViewSize, int);
1457  } else if (!preview && reader->name() == "layout") {
1458  attribs = reader->attributes();
1459 
1460  READ_INT_VALUE("layout", layout, Worksheet::Layout);
1461  READ_DOUBLE_VALUE("topMargin", layoutTopMargin);
1462  READ_DOUBLE_VALUE("bottomMargin", layoutBottomMargin);
1463  READ_DOUBLE_VALUE("leftMargin", layoutLeftMargin);
1464  READ_DOUBLE_VALUE("rightMargin", layoutRightMargin);
1465  READ_DOUBLE_VALUE("verticalSpacing", layoutVerticalSpacing);
1466  READ_DOUBLE_VALUE("horizontalSpacing", layoutHorizontalSpacing);
1467  READ_INT_VALUE("columnCount", layoutColumnCount, int);
1468  READ_INT_VALUE("rowCount", layoutRowCount, int);
1469  } else if (!preview && reader->name() == "background") {
1470  attribs = reader->attributes();
1471 
1472  READ_INT_VALUE("type", backgroundType, PlotArea::BackgroundType);
1473  READ_INT_VALUE("colorStyle", backgroundColorStyle, PlotArea::BackgroundColorStyle);
1474  READ_INT_VALUE("imageStyle", backgroundImageStyle, PlotArea::BackgroundImageStyle);
1475  READ_INT_VALUE("brushStyle", backgroundBrushStyle, Qt::BrushStyle);
1476 
1477  str = attribs.value("firstColor_r").toString();
1478  if (str.isEmpty())
1479  reader->raiseWarning(attributeWarning.subs("firstColor_r").toString());
1480  else
1481  d->backgroundFirstColor.setRed(str.toInt());
1482 
1483  str = attribs.value("firstColor_g").toString();
1484  if (str.isEmpty())
1485  reader->raiseWarning(attributeWarning.subs("firstColor_g").toString());
1486  else
1487  d->backgroundFirstColor.setGreen(str.toInt());
1488 
1489  str = attribs.value("firstColor_b").toString();
1490  if (str.isEmpty())
1491  reader->raiseWarning(attributeWarning.subs("firstColor_b").toString());
1492  else
1493  d->backgroundFirstColor.setBlue(str.toInt());
1494 
1495  str = attribs.value("secondColor_r").toString();
1496  if (str.isEmpty())
1497  reader->raiseWarning(attributeWarning.subs("secondColor_r").toString());
1498  else
1499  d->backgroundSecondColor.setRed(str.toInt());
1500 
1501  str = attribs.value("secondColor_g").toString();
1502  if (str.isEmpty())
1503  reader->raiseWarning(attributeWarning.subs("secondColor_g").toString());
1504  else
1505  d->backgroundSecondColor.setGreen(str.toInt());
1506 
1507  str = attribs.value("secondColor_b").toString();
1508  if (str.isEmpty())
1509  reader->raiseWarning(attributeWarning.subs("secondColor_b").toString());
1510  else
1511  d->backgroundSecondColor.setBlue(str.toInt());
1512 
1513  str = attribs.value("fileName").toString();
1514  d->backgroundFileName = str;
1515 
1516  READ_DOUBLE_VALUE("opacity", backgroundOpacity);
1517  } else if(!preview && reader->name() == "plotProperties") {
1518  attribs = reader->attributes();
1519 
1520  READ_INT_VALUE("plotsLocked", plotsLocked, bool);
1523  } else if (reader->name() == "cartesianPlot") {
1524  CartesianPlot* plot = new CartesianPlot(QString());
1525  plot->setIsLoading(true);
1526  if (!plot->load(reader, preview)) {
1527  delete plot;
1528  return false;
1529  } else
1530  addChildFast(plot);
1531  } else if (reader->name() == "textLabel") {
1532  TextLabel* label = new TextLabel(QString());
1533  if (!label->load(reader, preview)) {
1534  delete label;
1535  return false;
1536  } else
1537  addChildFast(label);
1538  } else if (reader->name() == "image") {
1539  Image* image = new Image(QString());
1540  if (!image->load(reader, preview)) {
1541  delete image;
1542  return false;
1543  } else
1544  addChildFast(image);
1545  } else { // unknown element
1546  reader->raiseWarning(i18n("unknown element '%1'", reader->name().toString()));
1547  if (!reader->skipToEndElement()) return false;
1548  }
1549  }
1550 
1551  if (!preview) {
1552  d->m_scene->setSceneRect(rect);
1553  d->updateLayout();
1555  }
1556 
1557  return true;
1558 }
1559 
1560 //##############################################################################
1561 //######################### Theme management ##################################
1562 //##############################################################################
1563 void Worksheet::loadTheme(const QString& theme) {
1564  KConfigGroup group;
1565  KConfig* config = nullptr;
1566  if (!theme.isEmpty()) {
1567  //load values from the theme config
1568  config = new KConfig(ThemeHandler::themeFilePath(theme), KConfig::SimpleConfig);
1569 
1570  //apply the same background color for Worksheet as for the CartesianPlot
1571  group = config->group("CartesianPlot");
1572 
1573  //load the theme for all the children
1574  const auto& children = this->children<WorksheetElement>(ChildIndexFlag::IncludeHidden);
1575  for (auto* child : children)
1576  child->loadThemeConfig(*config);
1577  } else {
1578  //load default values
1579  config = new KConfig();
1580  group = config->group("Worksheet");
1581  }
1582 
1583  this->setBackgroundType((PlotArea::BackgroundType) group.readEntry("BackgroundType", static_cast<int>(PlotArea::BackgroundType::Color)));
1584  this->setBackgroundColorStyle((PlotArea::BackgroundColorStyle) group.readEntry("BackgroundColorStyle", static_cast<int>(PlotArea::BackgroundColorStyle::SingleColor)));
1585  this->setBackgroundImageStyle((PlotArea::BackgroundImageStyle) group.readEntry("BackgroundImageStyle", static_cast<int>(PlotArea::BackgroundImageStyle::Scaled)));
1586  this->setBackgroundBrushStyle((Qt::BrushStyle) group.readEntry("BackgroundBrushStyle", static_cast<int>(Qt::SolidPattern)));
1587  this->setBackgroundFirstColor(group.readEntry("BackgroundFirstColor", QColor(Qt::white)));
1588  this->setBackgroundSecondColor(group.readEntry("BackgroundSecondColor", QColor(Qt::black)));
1589  this->setBackgroundOpacity(group.readEntry("BackgroundOpacity", 1.0));
1590 
1591  //load the theme for all the children
1592  const auto& children = this->children<WorksheetElement>(ChildIndexFlag::IncludeHidden);
1593  for (auto* child : children)
1594  child->loadThemeConfig(*config);
1595 
1596  delete config;
1597 }
AspectType
static const QRgb white
Definition: ImageEditor.cpp:37
static const QRgb black
Definition: ImageEditor.cpp:38
Base class of all persistent objects in a Project.
void setIsLoading(bool)
AspectType type() const
void setUndoAware(bool)
void aspectAdded(const AbstractAspect *)
Emitted after a new Aspect has been added to the tree.
bool readCommentElement(XmlStreamReader *)
Load comment from an XML element.
@ Recursive
Recursively handle all descendents, not just immediate children.
@ IncludeHidden
Include aspects marked as "hidden" in numbering or listing children.
void aspectDescriptionChanged(const AbstractAspect *)
Emitted after the name, comment or caption spec have changed.
void addChildFast(AbstractAspect *)
Add the given Aspect to my list of children without any checks and without putting this step onto the...
void childAspectSelectedInView(const AbstractAspect *)
AbstractAspect * parent(AspectType type) const
In the parent-child hierarchy, return the first parent of type.
void childAspectDeselectedInView(const AbstractAspect *)
void aspectAboutToBeRemoved(const AbstractAspect *)
Emitted before an aspect is removed from its parent.
QString name() const
const QVector< AbstractAspect * > & children() 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
void aspectRemoved(const AbstractAspect *parent, const AbstractAspect *before, const AbstractAspect *child)
Emitted from the parent after removing a child.
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.
bool isLoading() const
QVector< AbstractAspect * > children(AspectType type, ChildIndexFlags flags={}) const
bool readBasicAttributes(XmlStreamReader *)
Load name and creation time from XML.
void writeCommentElement(QXmlStreamWriter *) const
Save the comment to XML.
virtual QVector< AbstractAspect * > dependsOn() const
void removeChild(AbstractAspect *)
Remove the given Aspect from my list of children.
virtual Project * project()
Return the Project this Aspect belongs to, or 0 if it is currently not part of one.
void endMacro()
End the current undo stack macro.
Base class of Aspects with MDI windows as views (AspectParts).
Definition: AbstractPart.h:36
QMenu * createContextMenu() override
Return AbstractAspect::createContextMenu() plus operations on the primary view.
QWidget * m_partView
Definition: AbstractPart.h:65
A xy-plot.
Definition: CartesianPlot.h:58
void curveLinePenChanged(QPen)
void mouseMoveZoomSelectionModeSignal(QPointF logicPos)
void mouseMoveCursorModeSignal(int cursorNumber, QPointF logicPos)
void curveRemoved(const XYCurve *)
void mouseHoverOutsideDataRect()
void mouseReleaseZoomSelectionMode()
void mousePressCursorMode(int cursorNumber, QPointF logicPos)
bool load(XmlStreamReader *, bool preview) override
Load from XML.
void mouseHoverZoomSelectionModeSignal(QPointF logicalPoint)
void mouseMoveZoomSelectionMode(QPointF logicPos)
void setLocked(bool)
void curveAdded(const XYCurve *)
void curveNameChanged(const AbstractAspect *curve)
void mouseModeChanged(CartesianPlot::MouseMode)
void mouseReleaseZoomSelectionModeSignal()
void mousePressZoomSelectionMode(QPointF logicPos)
void mouseHoverOutsideDataRectSignal()
void mousePressZoomSelectionModeSignal(QPointF logicPos)
void mouseHoverZoomSelectionMode(QPointF logicPos)
void mouseMoveCursorMode(int cursorNumber, QPointF logicPos)
void curveVisibilityChangedSignal()
void curveDataChanged(const XYCurve *)
void mousePressCursorModeSignal(int cursorNumber, QPointF logicPos)
Dialog for exporting a worksheet to a file.
A label supporting rendering of html- and tex-formatted texts.
Definition: Image.h:41
bool load(XmlStreamReader *, bool preview) override
Load from XML.
Definition: Image.cpp:647
BackgroundColorStyle
Definition: PlotArea.h:46
BackgroundImageStyle
Definition: PlotArea.h:48
BackgroundType
Definition: PlotArea.h:45
void setChanged(const bool value=true)
Definition: Project.cpp:193
A label supporting rendering of html- and tex-formatted texts.
Definition: TextLabel.h:44
bool load(XmlStreamReader *, bool preview) override
Load from XML.
Definition: TextLabel.cpp:978
static const QString themeFilePath(const QString &)
The TreeModel class This is an abstract treemodel which can be used by a treeview.
Definition: TreeModel.h:68
bool setTreeData(const QVariant &data, const int row, const int column, const QModelIndex &parent=QModelIndex(), int role=Qt::EditRole)
Definition: TreeModel.cpp:280
bool removeRows(int position, int rows, const QModelIndex &parent=QModelIndex()) override
Definition: TreeModel.cpp:264
bool setData(const QModelIndex &, const QVariant &value, int role=Qt::EditRole) override
Definition: TreeModel.cpp:285
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: TreeModel.cpp:274
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: TreeModel.cpp:204
bool insertRows(int position, int rows, const QModelIndex &parent=QModelIndex()) override
Definition: TreeModel.cpp:227
QVariant treeData(const int row, const int column, const QModelIndex &parent=QModelIndex(), const int role=Qt::EditRole)
Definition: TreeModel.cpp:161
Worksheet element container - parent of multiple elements This class provides the functionality for a...
virtual void setRect(const QRectF &)=0
QGraphicsItem * graphicsItem() const override
Return the graphics item representing this element.
Base class for all Worksheet children.
virtual QGraphicsItem * graphicsItem() const =0
Return the graphics item representing this element.
PlotArea::BackgroundImageStyle backgroundImageStyle
void updateLayout(bool undoable=true)
Definition: Worksheet.cpp:1257
QColor backgroundSecondColor
Worksheet::Layout layout
Qt::BrushStyle backgroundBrushStyle
PlotArea::BackgroundType backgroundType
WorksheetPrivate(Worksheet *)
Definition: Worksheet.cpp:1206
QString backgroundFileName
QString name() const
Definition: Worksheet.cpp:1211
QGraphicsScene * m_scene
TreeModel * cursorData
Worksheet *const q
Worksheet::CartesianPlotActionMode cartesianPlotActionMode
Worksheet::CartesianPlotActionMode cartesianPlotCursorMode
PlotArea::BackgroundColorStyle backgroundColorStyle
void setContainerRect(WorksheetElementContainer *, float x, float y, float h, float w, bool undoable)
Definition: Worksheet.cpp:1313
virtual ~WorksheetPrivate()
Definition: Worksheet.cpp:1253
WorksheetSetPageRectCmd(Worksheet::Private *target, QRectF newValue, const KLocalizedString &description)
Definition: Worksheet.cpp:685
void finalize() override
Definition: Worksheet.cpp:687
void finalizeUndo() override
Definition: Worksheet.cpp:691
Worksheet view.
Definition: WorksheetView.h:51
void statusInfo(const QString &)
void print(QPrinter *)
void exportToFile(const QString &, const ExportFormat, const ExportArea, const bool, const int)
void cartesianPlotMouseModeChangedSlot(CartesianPlot::MouseMode mouseMode)
void propertiesExplorerRequested()
void unregisterShortcuts()
void registerShortcuts()
void suppressSelectionChangedEvent(bool)
Top-level container for worksheet elements like plot, labels, etc.
Definition: Worksheet.h:46
void useViewSizeRequested()
void setCartesianPlotActionMode(CartesianPlotActionMode mode)
Definition: Worksheet.cpp:461
void cartesianPlotMousePressCursorMode(int cursorNumber, QPointF logicPos)
Definition: Worksheet.cpp:760
void cartesianPlotMouseReleaseZoomSelectionMode()
Definition: Worksheet.cpp:749
int getPlotCount()
Worksheet::getPlotCount.
Definition: Worksheet.cpp:417
void updateCurveBackground(const QPen &, const QString &curveName)
Definition: Worksheet.cpp:1072
void setSuppressLayoutUpdate(bool)
Definition: Worksheet.cpp:441
CartesianPlotActionMode cartesianPlotCursorMode()
Definition: Worksheet.cpp:453
QGraphicsScene * scene() const
Definition: Worksheet.cpp:299
void handleAspectAboutToBeRemoved(const AbstractAspect *)
Definition: Worksheet.cpp:280
CartesianPlotActionMode cartesianPlotActionMode()
Definition: Worksheet.cpp:449
QWidget * view() const override
Construct a primary view on me.
Definition: Worksheet.cpp:165
void cartesianPlotMouseModeChanged(CartesianPlot::MouseMode)
void updateLayout()
Definition: Worksheet.cpp:445
~Worksheet() override
Definition: Worksheet.cpp:73
void setIsClosing()
Definition: Worksheet.cpp:403
void cartesianPlotMouseHoverZoomSelectionMode(QPointF logicPos)
Definition: Worksheet.cpp:784
void cursorModelPlotRemoved(const QString &name)
Definition: Worksheet.cpp:937
QMenu * createContextMenu() override
Definition: Worksheet.cpp:153
void curveRemoved(const XYCurve *curve)
Definition: Worksheet.cpp:1040
void cartesianPlotMousePressZoomSelectionMode(QPointF logicPos)
Definition: Worksheet.cpp:738
void setSelectedInView(const bool)
Definition: Worksheet.cpp:377
void setPrinting(bool) const
Definition: Worksheet.cpp:717
void itemSelected(QGraphicsItem *)
void handleAspectAdded(const AbstractAspect *)
Definition: Worksheet.cpp:228
CartesianPlot * getPlot(int index)
Worksheet::getPlot.
Definition: Worksheet.cpp:426
void pageRectChanged(const QRectF &)
bool load(XmlStreamReader *, bool preview) override
Load from XML.
Definition: Worksheet.cpp:1403
static double convertFromSceneUnits(const double value, const Worksheet::Unit unit)
Definition: Worksheet.cpp:131
void cartesianPlotMouseMoveCursorMode(int cursorNumber, QPointF logicPos)
Definition: Worksheet.cpp:806
void setPlotsLocked(bool)
Definition: Worksheet.cpp:491
void save(QXmlStreamWriter *) const override
Save as XML.
Definition: Worksheet.cpp:1337
void itemDeselected(QGraphicsItem *)
void cursorModelPlotAdded(const QString &name)
Definition: Worksheet.cpp:927
void cartesianPlotMouseMoveZoomSelectionMode(QPointF logicPos)
Definition: Worksheet.cpp:773
TreeModel * cursorModel()
Definition: Worksheet.cpp:433
void childDeselected(const AbstractAspect *) override
Definition: Worksheet.cpp:323
void requestProjectContextMenu(QMenu *)
QString theme() const
void init()
Definition: Worksheet.cpp:77
void requestUpdate()
void cartesianPlotMouseModeChangedSlot(CartesianPlot::MouseMode)
Definition: Worksheet.cpp:951
QRectF pageRect() const
Definition: Worksheet.cpp:303
void curveAdded(const XYCurve *curve)
Definition: Worksheet.cpp:994
void setPageRect(const QRectF &)
Definition: Worksheet.cpp:697
void suppressSelectionChangedEvent(bool)
Definition: Worksheet.cpp:408
void deleteAspectFromGraphicsItem(const QGraphicsItem *)
Definition: Worksheet.cpp:384
void curveDataChanged(const XYCurve *curve)
Definition: Worksheet.cpp:960
WorksheetPrivate *const d
Definition: Worksheet.h:153
void setCartesianPlotCursorMode(CartesianPlotActionMode mode)
Definition: Worksheet.cpp:469
bool printPreview() const override
Definition: Worksheet.cpp:222
void setItemSelectedInView(const QGraphicsItem *, const bool)
Definition: Worksheet.cpp:335
void cursorPosChanged(int cursorNumber, double xPos)
Worksheet::cursorPosChanged Updates the cursor treemodel with the new data.
Definition: Worksheet.cpp:826
bool plotsLocked()
Definition: Worksheet.cpp:457
bool exportView() const override
Definition: Worksheet.cpp:191
void registerShortcuts() override
Definition: Worksheet.cpp:503
QIcon icon() const override
Return an icon to be used for decorating my views.
Definition: Worksheet.cpp:146
void updateCompleteCursorTreeModel()
Worksheet::updateCompleteCursorTreeModel If the plot or the curve are not available,...
Definition: Worksheet.cpp:1105
Worksheet(const QString &name, bool loading=false)
Definition: Worksheet.cpp:64
WorksheetView * m_view
Definition: Worksheet.h:154
void cartesianPlotMouseHoverOutsideDataRect()
Definition: Worksheet.cpp:795
void layoutRowCountChanged(int)
void propertiesExplorerRequested()
CartesianPlotActionMode
Definition: Worksheet.h:55
WorksheetElement * aspectFromGraphicsItem(const WorksheetElement *, const QGraphicsItem *) const
Definition: Worksheet.cpp:358
void unregisterShortcuts() override
Definition: Worksheet.cpp:507
static double convertToSceneUnits(const double value, const Worksheet::Unit unit)
Definition: Worksheet.cpp:113
void loadTheme(const QString &)
Definition: Worksheet.cpp:1563
bool printView() override
Definition: Worksheet.cpp:210
void childSelected(const AbstractAspect *) override
Definition: Worksheet.cpp:312
void handleAspectRemoved(const AbstractAspect *parent, const AbstractAspect *before, const AbstractAspect *child)
Definition: Worksheet.cpp:288
QVector< AbstractAspect * > dependsOn() const override
Definition: Worksheet.cpp:180
void update()
Definition: Worksheet.cpp:437
A 2D-curve, provides an interface for editing many properties of the curve.
Definition: XYCurve.h:46
bool isVisible() const override
Return whether the element is (at least) partially visible.
Definition: XYCurve.cpp:216
double y(double x, bool &valueFound) const
Definition: XYCurve.cpp:2132
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 STD_SETTER_CMD_IMPL_M_F_S(class_name, cmd_name, value_type, field_name, finalize_method)
Definition: macros.h:224
#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 BASIC_D_READER_IMPL(classname, type, method, var)
Definition: macros.h:121
#define i18n(m)
Definition: nsl_common.h:38