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)  

WorksheetView.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  File : WorksheetView.cpp
3  Project : LabPlot
4  Description : Worksheet view
5  --------------------------------------------------------------------
6  Copyright : (C) 2009-2019 Alexander Semke (alexander.semke@web.de)
7  Copyright : (C) 2016-2018 Stefan-Gerlach (stefan.gerlach@uni.kn)
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  * This program is distributed in the hope that it will be useful, *
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21  * GNU General Public License for more details. *
22  * *
23  * You should have received a copy of the GNU General Public License *
24  * along with this program; if not, write to the Free Software *
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
26  * Boston, MA 02110-1301 USA *
27  * *
28  ***************************************************************************/
31 #include "backend/core/Project.h"
42 #include "backend/lib/trace.h"
43 
44 #include <QApplication>
45 #include <QDesktopWidget>
46 #include <QMdiArea>
47 #include <QMenu>
48 #include <QToolBar>
49 #include <QScreen>
50 #include <QWheelEvent>
51 #include <QPrinter>
52 #include <QSvgGenerator>
53 #include <QImage>
54 #include <QToolButton>
55 #include <QGraphicsOpacityEffect>
56 #include <QTimeLine>
57 #include <QClipboard>
58 #include <QMimeData>
59 #include <QWidgetAction>
60 
61 #include <KColorScheme>
62 #include <KLocalizedString>
63 #include <KMessageBox>
64 #include <KConfigGroup>
65 
66 #ifdef Q_OS_MAC
67 #include "3rdparty/kdmactouchbar/src/kdmactouchbar.h"
68 #endif
69 
70 #include <limits>
71 
72 /**
73  * \class WorksheetView
74  * \brief Worksheet view
75  */
76 
77 /*!
78  Constructur of the class.
79  Creates a view for the Worksheet \c worksheet and initializes the internal model.
80 */
81 WorksheetView::WorksheetView(Worksheet* worksheet) : QGraphicsView(), m_worksheet(worksheet) {
83 
84  setRenderHint(QPainter::Antialiasing);
85  setRubberBandSelectionMode(Qt::ContainsItemBoundingRect);
86  setTransformationAnchor(QGraphicsView::AnchorViewCenter);
87  setResizeAnchor(QGraphicsView::AnchorViewCenter);
88  setMinimumSize(16, 16);
89  setFocusPolicy(Qt::StrongFocus);
90 
91  if (m_worksheet->useViewSize()) {
92  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
93  setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
94  }
95 
96  viewport()->setAttribute( Qt::WA_OpaquePaintEvent );
97  viewport()->setAttribute( Qt::WA_NoSystemBackground );
98  setAcceptDrops(true);
99  setCacheMode(QGraphicsView::CacheBackground);
100 
102 
103  //signal/slot connections
111  connect(scene(), &QGraphicsScene::selectionChanged, this, &WorksheetView::selectionChanged);
112 
113  //resize the view to make the complete scene visible.
114  //no need to resize the view when the project is being opened,
115  //all views will be resized to the stored values at the end
116  if (!m_worksheet->isLoading()) {
117  float w = Worksheet::convertFromSceneUnits(sceneRect().width(), Worksheet::Unit::Inch);
118  float h = Worksheet::convertFromSceneUnits(sceneRect().height(), Worksheet::Unit::Inch);
119  w *= QApplication::desktop()->physicalDpiX();
120  h *= QApplication::desktop()->physicalDpiY();
121  resize(w*1.1, h*1.1);
122  }
123 
124  //rescale to the original size
125  static const qreal hscale = QApplication::desktop()->physicalDpiX()/(Worksheet::convertToSceneUnits(1, Worksheet::Unit::Inch));
126  static const qreal vscale = QApplication::desktop()->physicalDpiY()/(Worksheet::convertToSceneUnits(1, Worksheet::Unit::Inch));
127  setTransform(QTransform::fromScale(hscale, vscale));
128 
130 }
131 
132 /*!
133  * initializes couple of actions that have shortcuts assigned in the constructor as opposed
134  * to other actions in initAction() that are create on demand only if the context menu is requested
135  */
137  selectAllAction = new QAction(QIcon::fromTheme("edit-select-all"), i18n("Select All"), this);
138  this->addAction(selectAllAction);
139  connect(selectAllAction, &QAction::triggered, this, &WorksheetView::selectAllElements);
140 
141  deleteAction = new QAction(QIcon::fromTheme("edit-delete"), i18n("Delete"), this);
142  this->addAction(deleteAction);
143  connect(deleteAction, &QAction::triggered, this, &WorksheetView::deleteElement);
144 
145  backspaceAction = new QAction(this);
146  this->addAction(backspaceAction);
147  connect(backspaceAction, &QAction::triggered, this, &WorksheetView::deleteElement);
148 
149  //Zoom actions
150  zoomInViewAction = new QAction(QIcon::fromTheme("zoom-in"), i18n("Zoom In"), this);
151 
152  zoomOutViewAction = new QAction(QIcon::fromTheme("zoom-out"), i18n("Zoom Out"), this);
153 
154  zoomOriginAction = new QAction(QIcon::fromTheme("zoom-original"), i18n("Original Size"), this);
155 }
156 
158  auto* addNewActionGroup = new QActionGroup(this);
159  auto* zoomActionGroup = new QActionGroup(this);
160  auto* mouseModeActionGroup = new QActionGroup(this);
161  auto* layoutActionGroup = new QActionGroup(this);
162  auto* gridActionGroup = new QActionGroup(this);
163  gridActionGroup->setExclusive(true);
164  auto* magnificationActionGroup = new QActionGroup(this);
165 
166  zoomActionGroup->addAction(zoomInViewAction);
167  zoomActionGroup->addAction(zoomOutViewAction);
168  zoomActionGroup->addAction(zoomOriginAction);
169 
170  zoomFitPageHeightAction = new QAction(QIcon::fromTheme("zoom-fit-height"), i18n("Fit to Height"), zoomActionGroup);
171  zoomFitPageWidthAction = new QAction(QIcon::fromTheme("zoom-fit-width"), i18n("Fit to Width"), zoomActionGroup);
172  zoomFitSelectionAction = new QAction(i18n("Fit to Selection"), zoomActionGroup);
173 
174  // Mouse mode actions
175  selectionModeAction = new QAction(QIcon::fromTheme("labplot-cursor-arrow"), i18n("Select and Edit"), mouseModeActionGroup);
176  selectionModeAction->setCheckable(true);
177 
178  navigationModeAction = new QAction(QIcon::fromTheme("input-mouse"), i18n("Navigate"), mouseModeActionGroup);
179  navigationModeAction->setCheckable(true);
180 
181  zoomSelectionModeAction = new QAction(QIcon::fromTheme("page-zoom"), i18n("Select and Zoom"), mouseModeActionGroup);
182  zoomSelectionModeAction->setCheckable(true);
183 
184  //Magnification actions
185  noMagnificationAction = new QAction(QIcon::fromTheme("labplot-1x-zoom"), i18n("No Magnification"), magnificationActionGroup);
186  noMagnificationAction->setCheckable(true);
187  noMagnificationAction->setChecked(true);
188 
189  twoTimesMagnificationAction = new QAction(QIcon::fromTheme("labplot-2x-zoom"), i18n("2x Magnification"), magnificationActionGroup);
190  twoTimesMagnificationAction->setCheckable(true);
191 
192  threeTimesMagnificationAction = new QAction(QIcon::fromTheme("labplot-3x-zoom"), i18n("3x Magnification"), magnificationActionGroup);
193  threeTimesMagnificationAction->setCheckable(true);
194 
195  fourTimesMagnificationAction = new QAction(QIcon::fromTheme("labplot-4x-zoom"), i18n("4x Magnification"), magnificationActionGroup);
196  fourTimesMagnificationAction->setCheckable(true);
197 
198  fiveTimesMagnificationAction = new QAction(QIcon::fromTheme("labplot-5x-zoom"), i18n("5x Magnification"), magnificationActionGroup);
199  fiveTimesMagnificationAction->setCheckable(true);
200 
201  //TODO implement later "group selection action" where multiple objects can be selected by drawing a rectangular
202 // selectionModeAction = new QAction(QIcon::fromTheme("select-rectangular"), i18n("Selection"), mouseModeActionGroup);
203 // selectionModeAction->setCheckable(true);
204 
205  //"Add new" related actions
206  addCartesianPlot1Action = new QAction(QIcon::fromTheme("labplot-xy-plot-four-axes"), i18n("Box Plot, Four Axes"), addNewActionGroup);
207  addCartesianPlot2Action = new QAction(QIcon::fromTheme("labplot-xy-plot-two-axes"), i18n("Box Plot, Two Axes"), addNewActionGroup);
208  addCartesianPlot3Action = new QAction(QIcon::fromTheme("labplot-xy-plot-two-axes-centered"), i18n("Two Axes, Centered"), addNewActionGroup);
209  addCartesianPlot4Action = new QAction(QIcon::fromTheme("labplot-xy-plot-two-axes-centered-origin"), i18n("Two Axes, Crossing at Origin"), addNewActionGroup);
210  addTextLabelAction = new QAction(QIcon::fromTheme("draw-text"), i18n("Text"), addNewActionGroup);
211  addImageAction = new QAction(QIcon::fromTheme("viewimage"), i18n("Image"), addNewActionGroup);
212 
213  //Layout actions
214  //TODO: the icons labplot-editvlayout and labplot-edithlayout are confusing for the user.
215  //the orientation is visualized as a horizontal or vertical line on the icon, but the user
216  //percieves the two objects (resembles plots on the worksheet) separated by this line much stronger than the line itself.
217  //with this, the two objects separated by a vertical line are percieved to be layed out in a _horizontal_ order and the
218  //same for the vertical line. Because of this we change the icons here. We can rename the icons later in the breeze icon set.
219  verticalLayoutAction = new QAction(QIcon::fromTheme("labplot-edithlayout"), i18n("Vertical Layout"), layoutActionGroup);
220  verticalLayoutAction->setCheckable(true);
221 
222  horizontalLayoutAction = new QAction(QIcon::fromTheme("labplot-editvlayout"), i18n("Horizontal Layout"), layoutActionGroup);
223  horizontalLayoutAction->setCheckable(true);
224 
225  gridLayoutAction = new QAction(QIcon::fromTheme("labplot-editgrid"), i18n("Grid Layout"), layoutActionGroup);
226  gridLayoutAction->setCheckable(true);
227 
228  breakLayoutAction = new QAction(QIcon::fromTheme("labplot-editbreaklayout"), i18n("No Layout"), layoutActionGroup);
229  breakLayoutAction->setEnabled(false);
230 
231  //Grid actions
232  noGridAction = new QAction(i18n("No Grid"), gridActionGroup);
233  noGridAction->setCheckable(true);
234  noGridAction->setChecked(true);
235  noGridAction->setData(static_cast<int>(GridStyle::NoGrid));
236 
237  denseLineGridAction = new QAction(i18n("Dense Line Grid"), gridActionGroup);
238  denseLineGridAction->setCheckable(true);
239 
240  sparseLineGridAction = new QAction(i18n("Sparse Line Grid"), gridActionGroup);
241  sparseLineGridAction->setCheckable(true);
242 
243  denseDotGridAction = new QAction(i18n("Dense Dot Grid"), gridActionGroup);
244  denseDotGridAction->setCheckable(true);
245 
246  sparseDotGridAction = new QAction(i18n("Sparse Dot Grid"), gridActionGroup);
247  sparseDotGridAction->setCheckable(true);
248 
249  customGridAction = new QAction(i18n("Custom Grid"), gridActionGroup);
250  customGridAction->setCheckable(true);
251 
252  snapToGridAction = new QAction(i18n("Snap to Grid"), this);
253  snapToGridAction->setCheckable(true);
254 
255  showPresenterMode = new QAction(QIcon::fromTheme("view-fullscreen"), i18n("Show in Presenter Mode"), this);
256 
257  //check the action corresponding to the currently active layout in worksheet
258  this->layoutChanged(m_worksheet->layout());
259 
260  connect(addNewActionGroup, &QActionGroup::triggered, this, &WorksheetView::addNew);
261  connect(mouseModeActionGroup, &QActionGroup::triggered, this, &WorksheetView::mouseModeChanged);
262  connect(zoomActionGroup, &QActionGroup::triggered, this, &WorksheetView::changeZoom);
263  connect(magnificationActionGroup, &QActionGroup::triggered, this, &WorksheetView::magnificationChanged);
264  connect(layoutActionGroup, &QActionGroup::triggered, this, &WorksheetView::changeLayout);
265  connect(gridActionGroup, &QActionGroup::triggered, this, &WorksheetView::changeGrid);
266  connect(snapToGridAction, &QAction::triggered, this, &WorksheetView::changeSnapToGrid);
267  connect(showPresenterMode, &QAction::triggered, this, &WorksheetView::presenterMode);
268 
269  //worksheet control actions
270  plotsLockedAction = new QAction(i18n("Non-interactive Plots"), this);
271  plotsLockedAction->setToolTip(i18n("If activated, plots on the worksheet don't react on drag and mouse wheel events."));
272  plotsLockedAction->setCheckable(true);
273  plotsLockedAction->setChecked(m_worksheet->plotsLocked());
274  connect(plotsLockedAction, &QAction::triggered, this, &WorksheetView::plotsLockedActionChanged);
275 
276  //action for cartesian plots
277  auto* cartesianPlotActionModeActionGroup = new QActionGroup(this);
278  cartesianPlotActionModeActionGroup->setExclusive(true);
279  cartesianPlotApplyToSelectionAction = new QAction(i18n("Selected Plots"), cartesianPlotActionModeActionGroup);
280  cartesianPlotApplyToSelectionAction->setCheckable(true);
281  cartesianPlotApplyToAllAction = new QAction(i18n("All Plots"), cartesianPlotActionModeActionGroup);
282  cartesianPlotApplyToAllAction->setCheckable(true);
284  connect(cartesianPlotActionModeActionGroup, &QActionGroup::triggered, this, &WorksheetView::cartesianPlotActionModeChanged);
285 
286  // cursor apply to all/selected
287  auto* cartesianPlotActionCursorGroup = new QActionGroup(this);
288  cartesianPlotActionCursorGroup->setExclusive(true);
289  cartesianPlotApplyToSelectionCursor = new QAction(i18n("Selected Plots"), cartesianPlotActionCursorGroup);
290  cartesianPlotApplyToSelectionCursor->setCheckable(true);
291  cartesianPlotApplyToAllCursor = new QAction(i18n("All Plots"), cartesianPlotActionCursorGroup);
292  cartesianPlotApplyToAllCursor->setCheckable(true);
294  connect(cartesianPlotActionCursorGroup, &QActionGroup::triggered, this, &WorksheetView::cartesianPlotCursorModeChanged);
295 
296  auto* cartesianPlotMouseModeActionGroup = new QActionGroup(this);
297  cartesianPlotMouseModeActionGroup->setExclusive(true);
298  cartesianPlotSelectionModeAction = new QAction(QIcon::fromTheme("labplot-cursor-arrow"), i18n("Select and Edit"), cartesianPlotMouseModeActionGroup);
299  cartesianPlotSelectionModeAction->setCheckable(true);
300  cartesianPlotSelectionModeAction->setChecked(true);
301 
302  cartesianPlotZoomSelectionModeAction = new QAction(QIcon::fromTheme("labplot-zoom-select"), i18n("Select Region and Zoom In"), cartesianPlotMouseModeActionGroup);
303  cartesianPlotZoomSelectionModeAction->setCheckable(true);
304 
305  cartesianPlotZoomXSelectionModeAction = new QAction(QIcon::fromTheme("labplot-zoom-select-x"), i18n("Select x-Region and Zoom In"), cartesianPlotMouseModeActionGroup);
306  cartesianPlotZoomXSelectionModeAction->setCheckable(true);
307 
308  cartesianPlotZoomYSelectionModeAction = new QAction(QIcon::fromTheme("labplot-zoom-select-y"), i18n("Select y-Region and Zoom In"), cartesianPlotMouseModeActionGroup);
309  cartesianPlotZoomYSelectionModeAction->setCheckable(true);
310 
311  // TODO: change ICON
312  cartesianPlotCursorModeAction = new QAction(QIcon::fromTheme("debug-execute-from-cursor"), i18n("Cursor"), cartesianPlotMouseModeActionGroup);
313  cartesianPlotCursorModeAction->setCheckable(true);
314 
315  connect(cartesianPlotMouseModeActionGroup, &QActionGroup::triggered, this, &WorksheetView::cartesianPlotMouseModeChanged);
316 
317  auto* cartesianPlotAddNewActionGroup = new QActionGroup(this);
318  addCurveAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("xy-Curve"), cartesianPlotAddNewActionGroup);
319  addHistogramAction = new QAction(QIcon::fromTheme("view-object-histogram-linear"), i18n("Histogram"), cartesianPlotAddNewActionGroup);
320  addEquationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-equation-curve"), i18n("xy-Curve from a Formula"), cartesianPlotAddNewActionGroup);
321  // TODO: no own icons yet
322  addDataOperationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Data Operation"), cartesianPlotAddNewActionGroup);
323 // addDataOperationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-data-operation-curve"), i18n("Data Operation"), cartesianPlotAddNewActionGroup);
324  addDataReductionCurveAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Data Reduction"), cartesianPlotAddNewActionGroup);
325 // addDataReductionCurveAction = new QAction(QIcon::fromTheme("labplot-xy-data-reduction-curve"), i18n("Data Reduction"), cartesianPlotAddNewActionGroup);
326  addDifferentiationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Differentiation"), cartesianPlotAddNewActionGroup);
327 // addDifferentiationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-differentiation-curve"), i18n("Differentiation"), cartesianPlotAddNewActionGroup);
328  addIntegrationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Integration"), cartesianPlotAddNewActionGroup);
329 // addIntegrationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-integration-curve"), i18n("Integration"), cartesianPlotAddNewActionGroup);
330  addConvolutionCurveAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("(De-)Convolution"), cartesianPlotAddNewActionGroup);
331 // addConvolutionCurveAction = new QAction(QIcon::fromTheme("labplot-xy-convolution-curve"), i18n("(De-)Convolution"), cartesianPlotAddNewActionGroup);
332  addCorrelationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Auto-/Cross-Correlation"), cartesianPlotAddNewActionGroup);
333 // addCorrelationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-convolution-curve"), i18n("Auto-/Cross-Correlation"), cartesianPlotAddNewActionGroup);
334  addInterpolationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-interpolation-curve"), i18n("Interpolation"), cartesianPlotAddNewActionGroup);
335  addSmoothCurveAction = new QAction(QIcon::fromTheme("labplot-xy-smoothing-curve"), i18n("Smooth"), cartesianPlotAddNewActionGroup);
336  addFitCurveAction = new QAction(QIcon::fromTheme("labplot-xy-fit-curve"), i18n("Fit"), cartesianPlotAddNewActionGroup);
337  addFourierFilterCurveAction = new QAction(QIcon::fromTheme("labplot-xy-fourier-filter-curve"), i18n("Fourier Filter"), cartesianPlotAddNewActionGroup);
338  addFourierTransformCurveAction = new QAction(QIcon::fromTheme("labplot-xy-fourier-transform-curve"), i18n("Fourier Transform"), cartesianPlotAddNewActionGroup);
339  addLegendAction = new QAction(QIcon::fromTheme("text-field"), i18n("Legend"), cartesianPlotAddNewActionGroup);
340  addHorizontalAxisAction = new QAction(QIcon::fromTheme("labplot-axis-horizontal"), i18n("Horizontal Axis"), cartesianPlotAddNewActionGroup);
341  addVerticalAxisAction = new QAction(QIcon::fromTheme("labplot-axis-vertical"), i18n("Vertical Axis"), cartesianPlotAddNewActionGroup);
342  addPlotTextLabelAction = new QAction(QIcon::fromTheme("draw-text"), i18n("Text"), cartesianPlotAddNewActionGroup);
343  addPlotImageAction = new QAction(QIcon::fromTheme("viewimage"), i18n("Image"), cartesianPlotAddNewActionGroup);
344  addCustomPointAction = new QAction(QIcon::fromTheme("draw-cross"), i18n("Custom Point"), cartesianPlotAddNewActionGroup);
345 
346  // Analysis menu
347  // TODO: no own icons yet
348  addDataOperationAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Data Operation"), cartesianPlotAddNewActionGroup);
349 // addDataOperationAction = new QAction(QIcon::fromTheme("labplot-xy-data-operation-curve"), i18n("Data Operation"), cartesianPlotAddNewActionGroup);
350  addDataReductionAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Data Reduction"), cartesianPlotAddNewActionGroup);
351 // addDataReductionAction = new QAction(QIcon::fromTheme("labplot-xy-data-reduction-curve"), i18n("Data Reduction"), cartesianPlotAddNewActionGroup);
352  addDifferentiationAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Differentiation"), cartesianPlotAddNewActionGroup);
353 // addDifferentiationAction = new QAction(QIcon::fromTheme("labplot-xy-differentiation-curve"), i18n("Differentiation"), cartesianPlotAddNewActionGroup);
354  addIntegrationAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Integration"), cartesianPlotAddNewActionGroup);
355 // addIntegrationAction = new QAction(QIcon::fromTheme("labplot-xy-integration-curve"), i18n("Integration"), cartesianPlotAddNewActionGroup);
356  addConvolutionAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Convolution/Deconvolution"), cartesianPlotAddNewActionGroup);
357 // addConvolutionAction = new QAction(QIcon::fromTheme("labplot-xy-convolution-curve"), i18n("Convolution/Deconvolution"), cartesianPlotAddNewActionGroup);
358  addCorrelationAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("Auto-/Cross-Correlation"), cartesianPlotAddNewActionGroup);
359 // addCorrelationAction = new QAction(QIcon::fromTheme("labplot-xy-correlation-curve"), i18n("Auto-/Cross-Correlation"), cartesianPlotAddNewActionGroup);
360 
361  addInterpolationAction = new QAction(QIcon::fromTheme("labplot-xy-interpolation-curve"), i18n("Interpolation"), cartesianPlotAddNewActionGroup);
362  addSmoothAction = new QAction(QIcon::fromTheme("labplot-xy-smoothing-curve"), i18n("Smooth"), cartesianPlotAddNewActionGroup);
363  addFitAction = new QAction(QIcon::fromTheme("labplot-xy-fit-curve"), i18n("Fit"), cartesianPlotAddNewActionGroup);
364  addFourierFilterAction = new QAction(QIcon::fromTheme("labplot-xy-fourier-filter-curve"), i18n("Fourier Filter"), cartesianPlotAddNewActionGroup);
365  addFourierTransformAction = new QAction(QIcon::fromTheme("labplot-xy-fourier-transform-curve"), i18n("Fourier Transform"), cartesianPlotAddNewActionGroup);
366 
367  connect(cartesianPlotAddNewActionGroup, &QActionGroup::triggered, this, &WorksheetView::cartesianPlotAddNew);
368 
369  auto* cartesianPlotNavigationGroup = new QActionGroup(this);
370  scaleAutoAction = new QAction(QIcon::fromTheme("labplot-auto-scale-all"), i18n("Auto Scale"), cartesianPlotNavigationGroup);
372  scaleAutoXAction = new QAction(QIcon::fromTheme("labplot-auto-scale-x"), i18n("Auto Scale X"), cartesianPlotNavigationGroup);
374  scaleAutoYAction = new QAction(QIcon::fromTheme("labplot-auto-scale-y"), i18n("Auto Scale Y"), cartesianPlotNavigationGroup);
376  zoomInAction = new QAction(QIcon::fromTheme("zoom-in"), i18n("Zoom In"), cartesianPlotNavigationGroup);
377  zoomInAction->setData(static_cast<int>(CartesianPlot::NavigationOperation::ZoomIn));
378  zoomOutAction = new QAction(QIcon::fromTheme("zoom-out"), i18n("Zoom Out"), cartesianPlotNavigationGroup);
380  zoomInXAction = new QAction(QIcon::fromTheme("labplot-zoom-in-x"), i18n("Zoom In X"), cartesianPlotNavigationGroup);
382  zoomOutXAction = new QAction(QIcon::fromTheme("labplot-zoom-out-x"), i18n("Zoom Out X"), cartesianPlotNavigationGroup);
384  zoomInYAction = new QAction(QIcon::fromTheme("labplot-zoom-in-y"), i18n("Zoom In Y"), cartesianPlotNavigationGroup);
386  zoomOutYAction = new QAction(QIcon::fromTheme("labplot-zoom-out-y"), i18n("Zoom Out Y"), cartesianPlotNavigationGroup);
388  shiftLeftXAction = new QAction(QIcon::fromTheme("labplot-shift-left-x"), i18n("Shift Left X"), cartesianPlotNavigationGroup);
390  shiftRightXAction = new QAction(QIcon::fromTheme("labplot-shift-right-x"), i18n("Shift Right X"), cartesianPlotNavigationGroup);
392  shiftUpYAction = new QAction(QIcon::fromTheme("labplot-shift-up-y"), i18n("Shift Up Y"), cartesianPlotNavigationGroup);
394  shiftDownYAction = new QAction(QIcon::fromTheme("labplot-shift-down-y"), i18n("Shift Down Y"), cartesianPlotNavigationGroup);
396 
397  connect(cartesianPlotNavigationGroup, &QActionGroup::triggered, this, &WorksheetView::cartesianPlotNavigationChanged);
398 
399  //set some default values
400  selectionModeAction->setChecked(true);
404 
405  m_actionsInitialized = true;
406 }
407 
410  initActions();
411 
412  m_addNewCartesianPlotMenu = new QMenu(i18n("xy-plot"), this);
417 
418  m_addNewMenu = new QMenu(i18n("Add New"), this);
419  m_addNewMenu->setIcon(QIcon::fromTheme("list-add"));
420  m_addNewMenu->addMenu(m_addNewCartesianPlotMenu)->setIcon(QIcon::fromTheme("office-chart-line"));
421  m_addNewMenu->addSeparator();
422  m_addNewMenu->addAction(addTextLabelAction);
423  m_addNewMenu->addAction(addImageAction);
424 
425  m_viewMouseModeMenu = new QMenu(i18n("Mouse Mode"), this);
426  m_viewMouseModeMenu->setIcon(QIcon::fromTheme("input-mouse"));
430 
431  m_zoomMenu = new QMenu(i18n("Zoom"), this);
432  m_zoomMenu->setIcon(QIcon::fromTheme("zoom-draw"));
433  m_zoomMenu->addAction(zoomInViewAction);
434  m_zoomMenu->addAction(zoomOutViewAction);
435  m_zoomMenu->addAction(zoomOriginAction);
439 
440  m_magnificationMenu = new QMenu(i18n("Magnification"), this);
441  m_magnificationMenu->setIcon(QIcon::fromTheme("zoom-in"));
447 
448  m_layoutMenu = new QMenu(i18n("Layout"), this);
449  m_layoutMenu->setIcon(QIcon::fromTheme("labplot-editbreaklayout"));
452  m_layoutMenu->addAction(gridLayoutAction);
453  m_layoutMenu->addSeparator();
454  m_layoutMenu->addAction(breakLayoutAction);
455 
456  m_gridMenu = new QMenu(i18n("Grid"), this);
457  m_gridMenu->setIcon(QIcon::fromTheme("view-grid"));
458  m_gridMenu->addAction(noGridAction);
459  m_gridMenu->addSeparator();
460  m_gridMenu->addAction(sparseLineGridAction);
461  m_gridMenu->addAction(denseLineGridAction);
462  m_gridMenu->addSeparator();
463  m_gridMenu->addAction(sparseDotGridAction);
464  m_gridMenu->addAction(denseDotGridAction);
465  m_gridMenu->addSeparator();
466  m_gridMenu->addAction(customGridAction);
467  //TODO: implement "snap to grid" and activate this action
468 // m_gridMenu->addSeparator();
469 // m_gridMenu->addAction(snapToGridAction);
470 
471  m_cartesianPlotMenu = new QMenu(i18n("Cartesian Plot"), this);
472  m_cartesianPlotMenu->setIcon(QIcon::fromTheme("office-chart-line"));
473 
474  m_cartesianPlotMouseModeMenu = new QMenu(i18n("Mouse Mode"), this);
475  m_cartesianPlotMouseModeMenu->setIcon(QIcon::fromTheme("input-mouse"));
480  m_cartesianPlotMouseModeMenu->addSeparator();
482  m_cartesianPlotMouseModeMenu->addSeparator();
483 
484  m_cartesianPlotAddNewMenu = new QMenu(i18n("Add New"), this);
485  m_cartesianPlotAddNewMenu->setIcon(QIcon::fromTheme("list-add"));
489  m_cartesianPlotAddNewMenu->addSeparator();
490 
491  m_cartesianPlotAddNewAnalysisMenu = new QMenu(i18n("Analysis Curve"));
493  m_cartesianPlotAddNewAnalysisMenu->addSeparator();
496  m_cartesianPlotAddNewAnalysisMenu->addSeparator();
499  m_cartesianPlotAddNewAnalysisMenu->addSeparator();
502  m_cartesianPlotAddNewAnalysisMenu->addSeparator();
505  m_cartesianPlotAddNewAnalysisMenu->addSeparator();
506 // m_cartesianPlotAddNewAnalysisMenu->addAction(addDataOperationCurveAction);
509 
510  m_cartesianPlotAddNewMenu->addSeparator();
512  m_cartesianPlotAddNewMenu->addSeparator();
515  m_cartesianPlotAddNewMenu->addSeparator();
518  m_cartesianPlotAddNewMenu->addSeparator();
520 
521  m_cartesianPlotZoomMenu = new QMenu(i18n("Zoom/Navigate"), this);
522  m_cartesianPlotZoomMenu->setIcon(QIcon::fromTheme("zoom-draw"));
526  m_cartesianPlotZoomMenu->addSeparator();
529  m_cartesianPlotZoomMenu->addSeparator();
532  m_cartesianPlotZoomMenu->addSeparator();
535  m_cartesianPlotZoomMenu->addSeparator();
538  m_cartesianPlotZoomMenu->addSeparator();
541 
542  m_cartesianPlotActionModeMenu = new QMenu(i18n("Apply Actions to"), this);
543  m_cartesianPlotActionModeMenu->setIcon(QIcon::fromTheme("dialog-ok-apply"));
546 
547  m_cartesianPlotCursorModeMenu = new QMenu(i18n("Apply Cursor to"), this);
550 
552  m_cartesianPlotMenu->addSeparator();
555  m_cartesianPlotMenu->addSeparator();
558  m_cartesianPlotMenu->addSeparator();
560 
561  // Data manipulation menu
562  m_dataManipulationMenu = new QMenu(i18n("Data Manipulation") ,this);
563  m_dataManipulationMenu->setIcon(QIcon::fromTheme("zoom-draw"));
566 
567  //themes menu
568  m_themeMenu = new QMenu(i18n("Apply Theme"), this);
569  m_themeMenu->setIcon(QIcon::fromTheme("color-management"));
570  auto* themeWidget = new ThemesWidget(nullptr);
571  themeWidget->setFixedMode();
573  connect(themeWidget, &ThemesWidget::themeSelected, m_themeMenu, &QMenu::close);
574 
575  auto* widgetAction = new QWidgetAction(this);
576  widgetAction->setDefaultWidget(themeWidget);
577  m_themeMenu->addAction(widgetAction);
578 
579  m_menusInitialized = true;
580 }
581 
582 /*!
583  * Populates the menu \c menu with the worksheet and worksheet view relevant actions.
584  * The menu is used
585  * - as the context menu in WorksheetView
586  * - as the "worksheet menu" in the main menu-bar (called form MainWin)
587  * - as a part of the worksheet context menu in project explorer
588  */
590  Q_ASSERT(menu != nullptr);
591 
592  if (!m_menusInitialized)
593  initMenus();
594 
595  QAction* firstAction = nullptr;
596  // if we're populating the context menu for the project explorer, then
597  //there're already actions available there. Skip the first title-action
598  //and insert the action at the beginning of the menu.
599  if (menu->actions().size() > 1)
600  firstAction = menu->actions().at(1);
601 
602  menu->insertMenu(firstAction, m_addNewMenu);
603  menu->insertSeparator(firstAction);
604  menu->insertMenu(firstAction, m_viewMouseModeMenu);
605  menu->insertMenu(firstAction, m_zoomMenu);
606  menu->insertMenu(firstAction, m_magnificationMenu);
607  menu->insertMenu(firstAction, m_layoutMenu);
608  menu->insertMenu(firstAction, m_gridMenu);
609  menu->insertMenu(firstAction, m_themeMenu);
610  menu->insertSeparator(firstAction);
611  menu->insertAction(firstAction, plotsLockedAction);
612  menu->insertSeparator(firstAction);
613  menu->insertMenu(firstAction, m_cartesianPlotMenu);
614  menu->insertSeparator(firstAction);
615  menu->insertAction(firstAction, showPresenterMode);
616  menu->insertSeparator(firstAction);
617 }
618 
620  Q_ASSERT(menu != nullptr);
621 
622  if (!m_menusInitialized)
623  initMenus();
624 
625  // Data manipulation menu
626 // menu->insertMenu(nullptr, m_dataManipulationMenu);
627 
628  menu->addAction(addFitAction);
629  menu->addSeparator();
630  menu->addAction(addDifferentiationAction);
631  menu->addAction(addIntegrationAction);
632  menu->addSeparator();
633  menu->addAction(addInterpolationAction);
634  menu->addAction(addSmoothAction);
635  menu->addSeparator();
636  menu->addAction(addFourierFilterAction);
637  menu->addAction(addFourierTransformAction);
638  menu->addSeparator();
639  menu->addAction(addConvolutionAction);
640  menu->addAction(addCorrelationAction);
641  menu->addSeparator();
642  menu->addAction(addDataReductionAction);
643 }
644 
645 void WorksheetView::fillToolBar(QToolBar* toolBar) {
646  toolBar->addSeparator();
647  tbNewCartesianPlot = new QToolButton(toolBar);
648  tbNewCartesianPlot->setPopupMode(QToolButton::MenuButtonPopup);
650  tbNewCartesianPlot->setDefaultAction(addCartesianPlot1Action);
651  toolBar->addWidget(tbNewCartesianPlot);
652  toolBar->addAction(addTextLabelAction);
653  toolBar->addAction(addImageAction);
654 
655  toolBar->addSeparator();
656  toolBar->addAction(verticalLayoutAction);
657  toolBar->addAction(horizontalLayoutAction);
658  toolBar->addAction(gridLayoutAction);
659  toolBar->addAction(breakLayoutAction);
660 
661  toolBar->addSeparator();
662  toolBar->addAction(selectionModeAction);
663  toolBar->addAction(navigationModeAction);
664  toolBar->addAction(zoomSelectionModeAction);
665  toolBar->addSeparator();
666  tbZoom = new QToolButton(toolBar);
667  tbZoom->setPopupMode(QToolButton::MenuButtonPopup);
668  tbZoom->setMenu(m_zoomMenu);
669  tbZoom->setDefaultAction(currentZoomAction);
670  toolBar->addWidget(tbZoom);
671 
672  tbMagnification = new QToolButton(toolBar);
673  tbMagnification->setPopupMode(QToolButton::MenuButtonPopup);
675  tbMagnification->setDefaultAction(currentMagnificationAction);
676  toolBar->addWidget(tbMagnification);
677 }
678 
679 #ifdef Q_OS_MAC
680 void WorksheetView::fillTouchBar(KDMacTouchBar* touchBar){
681  //touchBar->addAction(addCartesianPlot1Action);
682  touchBar->addAction(zoomInViewAction);
683  touchBar->addAction(zoomOutViewAction);
684  touchBar->addAction(showPresenterMode);
685 }
686 #endif
687 
689  toolBar->addAction(cartesianPlotSelectionModeAction);
690  toolBar->addAction(cartesianPlotZoomSelectionModeAction);
691  toolBar->addAction(cartesianPlotZoomXSelectionModeAction);
692  toolBar->addAction(cartesianPlotZoomYSelectionModeAction);
693  toolBar->addAction(cartesianPlotCursorModeAction);
694  toolBar->addSeparator();
695  toolBar->addAction(addCurveAction);
696  toolBar->addAction(addHistogramAction);
697  toolBar->addAction(addEquationCurveAction);
698 // don't over-populate the tool bar
699 // toolBar->addAction(addDifferentiationCurveAction);
700 // toolBar->addAction(addIntegrationCurveAction);
701 // toolBar->addAction(addDataOperationCurveAction);
702 // toolBar->addAction(addDataReductionCurveAction);
703 // toolBar->addAction(addInterpolationCurveAction);
704 // toolBar->addAction(addSmoothCurveAction);
705 // toolBar->addAction(addFitCurveAction);
706 // toolBar->addAction(addFourierFilterCurveAction);
707 // toolBar->addAction(addFourierTransformCurveAction);
708 // toolBar->addAction(addConvolutionCurveAction);
709 // toolBar->addAction(addCorrelationCurveAction);
710  toolBar->addSeparator();
711  toolBar->addAction(addLegendAction);
712  toolBar->addSeparator();
713  toolBar->addAction(addHorizontalAxisAction);
714  toolBar->addAction(addVerticalAxisAction);
715  toolBar->addSeparator();
716  toolBar->addAction(addPlotTextLabelAction);
717  toolBar->addAction(addPlotImageAction);
718  toolBar->addSeparator();
719  toolBar->addAction(scaleAutoAction);
720  toolBar->addAction(scaleAutoXAction);
721  toolBar->addAction(scaleAutoYAction);
722  toolBar->addAction(zoomInAction);
723  toolBar->addAction(zoomOutAction);
724  toolBar->addAction(zoomInXAction);
725  toolBar->addAction(zoomOutXAction);
726  toolBar->addAction(zoomInYAction);
727  toolBar->addAction(zoomOutYAction);
728  toolBar->addAction(shiftLeftXAction);
729  toolBar->addAction(shiftRightXAction);
730  toolBar->addAction(shiftUpYAction);
731  toolBar->addAction(shiftDownYAction);
732  toolBar->addSeparator();
733 
735 }
736 
737 void WorksheetView::setScene(QGraphicsScene* scene) {
738  QGraphicsView::setScene(scene);
739 }
740 
742  m_isClosing = true;
743 }
744 
747  cartesianPlotApplyToAllAction->setChecked(true);
748  else
749  cartesianPlotApplyToSelectionAction->setChecked(true);
750 }
751 
754  cartesianPlotApplyToAllCursor->setChecked(true);
755  else
756  cartesianPlotApplyToSelectionCursor->setChecked(true);
757 }
758 
759 void WorksheetView::setPlotLock(bool lock) {
760  plotsLockedAction->setChecked(lock);
761 }
762 
763 void WorksheetView::drawForeground(QPainter* painter, const QRectF& rect) {
765  painter->save();
766  const QRectF& selRect = mapToScene(QRect(m_selectionStart, m_selectionEnd).normalized()).boundingRect();
767  //TODO: don't hardcode for black here, use a a different color depending on the theme of the worksheet/plot under the mouse cursor?
768  painter->setPen(QPen(Qt::black, 5/transform().m11()));
769  painter->drawRect(selRect);
770  painter->setBrush(QApplication::palette().color(QPalette::Highlight));
771  painter->setOpacity(0.2);
772  painter->drawRect(selRect);
773  painter->restore();
774  }
775  QGraphicsView::drawForeground(painter, rect);
776 }
777 
778 void WorksheetView::drawBackgroundItems(QPainter* painter, const QRectF& scene_rect) {
779  // canvas
780  painter->setOpacity(m_worksheet->backgroundOpacity());
781  if (m_worksheet->backgroundType() == PlotArea::BackgroundType::Color) {
782  switch (m_worksheet->backgroundColorStyle()) {
784  painter->setBrush(QBrush(m_worksheet->backgroundFirstColor()));
785  break;
786  }
788  QLinearGradient linearGrad(scene_rect.topLeft(), scene_rect.topRight());
789  linearGrad.setColorAt(0, m_worksheet->backgroundFirstColor());
790  linearGrad.setColorAt(1, m_worksheet->backgroundSecondColor());
791  painter->setBrush(QBrush(linearGrad));
792  break;
793  }
795  QLinearGradient linearGrad(scene_rect.topLeft(), scene_rect.bottomLeft());
796  linearGrad.setColorAt(0, m_worksheet->backgroundFirstColor());
797  linearGrad.setColorAt(1, m_worksheet->backgroundSecondColor());
798  painter->setBrush(QBrush(linearGrad));
799  break;
800  }
802  QLinearGradient linearGrad(scene_rect.topLeft(), scene_rect.bottomRight());
803  linearGrad.setColorAt(0, m_worksheet->backgroundFirstColor());
804  linearGrad.setColorAt(1, m_worksheet->backgroundSecondColor());
805  painter->setBrush(QBrush(linearGrad));
806  break;
807  }
809  QLinearGradient linearGrad(scene_rect.bottomLeft(), scene_rect.topRight());
810  linearGrad.setColorAt(0, m_worksheet->backgroundFirstColor());
811  linearGrad.setColorAt(1, m_worksheet->backgroundSecondColor());
812  painter->setBrush(QBrush(linearGrad));
813  break;
814  }
816  QRadialGradient radialGrad(scene_rect.center(), scene_rect.width()/2);
817  radialGrad.setColorAt(0, m_worksheet->backgroundFirstColor());
818  radialGrad.setColorAt(1, m_worksheet->backgroundSecondColor());
819  painter->setBrush(QBrush(radialGrad));
820  break;
821  }
822  //default:
823  // painter->setBrush(QBrush(m_worksheet->backgroundFirstColor()));
824  }
825  painter->drawRect(scene_rect);
826  } else if (m_worksheet->backgroundType() == PlotArea::BackgroundType::Image) { // background image
827  const QString& backgroundFileName = m_worksheet->backgroundFileName().trimmed();
828  if ( !backgroundFileName.isEmpty() ) {
829  QPixmap pix(backgroundFileName);
830  switch (m_worksheet->backgroundImageStyle()) {
832  pix = pix.scaled(scene_rect.size().toSize(),Qt::KeepAspectRatioByExpanding,Qt::SmoothTransformation);
833  painter->drawPixmap(scene_rect.topLeft(),pix);
834  break;
836  pix = pix.scaled(scene_rect.size().toSize(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
837  painter->drawPixmap(scene_rect.topLeft(),pix);
838  break;
840  pix = pix.scaled(scene_rect.size().toSize(),Qt::KeepAspectRatio,Qt::SmoothTransformation);
841  painter->drawPixmap(scene_rect.topLeft(),pix);
842  break;
844  painter->drawPixmap(QPointF(scene_rect.center().x()-pix.size().width()/2,scene_rect.center().y()-pix.size().height()/2),pix);
845  break;
847  painter->drawTiledPixmap(scene_rect,pix);
848  break;
850  painter->drawTiledPixmap(scene_rect,pix,QPoint(scene_rect.size().width()/2,scene_rect.size().height()/2));
851  break;
852  //default:
853  // painter->drawPixmap(scene_rect.topLeft(),pix);
854  }
855  }
856  } else if (m_worksheet->backgroundType() == PlotArea::BackgroundType::Pattern) { // background pattern
857  painter->setBrush(QBrush(m_worksheet->backgroundFirstColor(),m_worksheet->backgroundBrushStyle()));
858  painter->drawRect(scene_rect);
859  }
860 
861  //grid
863  QColor c = m_gridSettings.color;
864  c.setAlphaF(m_gridSettings.opacity);
865  painter->setPen(c);
866 
867  qreal x, y;
868  qreal left = scene_rect.left();
869  qreal right = scene_rect.right();
870  qreal top = scene_rect.top();
871  qreal bottom = scene_rect.bottom();
872 
874  QLineF line;
875 
876  //horizontal lines
878  while (y < bottom) {
879  line.setLine( left, y, right, y );
880  painter->drawLine(line);
882  }
883 
884  //vertical lines
886  while (x < right) {
887  line.setLine( x, top, x, bottom );
888  painter->drawLine(line);
890  }
891  } else { //DotGrid
893  while (y < bottom) {
894  x = left;// + m_gridSettings.horizontalSpacing;
895  while (x < right) {
897  painter->drawPoint(x, y);
898  }
900  }
901  }
902  }
903 }
904 
905 void WorksheetView::drawBackground(QPainter* painter, const QRectF& rect) {
906  painter->save();
907 
908  //painter->setRenderHint(QPainter::Antialiasing);
909  QRectF scene_rect = sceneRect();
910 
911  if (!m_worksheet->useViewSize()) {
912  // background
913  KColorScheme scheme(QPalette::Active, KColorScheme::Window);
914  const QColor& color = scheme.background().color();
915  if (!scene_rect.contains(rect))
916  painter->fillRect(rect, color);
917 
918  //shadow
919 // int shadowSize = scene_rect.width()*0.02;
920 // QRectF rightShadowRect(scene_rect.right(), scene_rect.top() + shadowSize, shadowSize, scene_rect.height());
921 // QRectF bottomShadowRect(scene_rect.left() + shadowSize, scene_rect.bottom(), scene_rect.width(), shadowSize);
922 //
923 // const QColor& shadeColor = scheme.shade(color, KColorScheme::MidShade);
924 // painter->fillRect(rightShadowRect.intersected(rect), shadeColor);
925 // painter->fillRect(bottomShadowRect.intersected(rect), shadeColor);
926  }
927 
928  drawBackgroundItems(painter, scene_rect);
929 
930  invalidateScene(rect, QGraphicsScene::BackgroundLayer);
931  painter->restore();
932 }
933 
934 bool WorksheetView::isPlotAtPos(QPoint pos) const {
935  bool plot = false;
936  QGraphicsItem* item = itemAt(pos);
937  if (item) {
938  plot = item->data(0).toInt() == static_cast<int>(WorksheetElement::WorksheetElementName::NameCartesianPlot);
939  if (!plot && item->parentItem())
940  plot = item->parentItem()->data(0).toInt() == static_cast<int>(WorksheetElement::WorksheetElementName::NameCartesianPlot);
941  }
942 
943  return plot;
944 }
945 
947  QGraphicsItem* item = itemAt(pos);
948  if (!item)
949  return nullptr;
950 
951  QGraphicsItem* plotItem = nullptr;
952  if (item->data(0).toInt() == static_cast<int>(WorksheetElement::WorksheetElementName::NameCartesianPlot))
953  plotItem = item;
954  else {
955  if (item->parentItem() && item->parentItem()->data(0).toInt() == static_cast<int>(WorksheetElement::WorksheetElementName::NameCartesianPlot))
956  plotItem = item->parentItem();
957  }
958 
959  if (plotItem == nullptr)
960  return nullptr;
961 
962  CartesianPlot* plot = nullptr;
963  for (auto* p : m_worksheet->children<CartesianPlot>()) {
964  if (p->graphicsItem() == plotItem) {
965  plot = p;
966  break;
967  }
968  }
969 
970  return plot;
971 }
972 
973 //##############################################################################
974 //#################################### Events ###############################
975 //##############################################################################
976 void WorksheetView::resizeEvent(QResizeEvent* event) {
977  if (m_isClosing)
978  return;
979 
980  if (m_worksheet->useViewSize())
981  this->processResize();
982 
983  QGraphicsView::resizeEvent(event);
984 }
985 
986 void WorksheetView::wheelEvent(QWheelEvent* event) {
987  //https://wiki.qt.io/Smooth_Zoom_In_QGraphicsView
988  if (m_mouseMode == MouseMode::ZoomSelection || (QApplication::keyboardModifiers() & Qt::ControlModifier)) {
989  int numDegrees = event->delta() / 8;
990  int numSteps = numDegrees / 15; // see QWheelEvent documentation
991  zoom(numSteps);
992  } else
993  QGraphicsView::wheelEvent(event);
994 }
995 
996 void WorksheetView::zoom(int numSteps) {
997  m_numScheduledScalings += numSteps;
998  if (m_numScheduledScalings * numSteps < 0) // if user moved the wheel in another direction, we reset previously scheduled scalings
999  m_numScheduledScalings = numSteps;
1000 
1001  auto* anim = new QTimeLine(350, this);
1002  anim->setUpdateInterval(20);
1003 
1004  connect(anim, &QTimeLine::valueChanged, this, &WorksheetView::scalingTime);
1005  connect(anim, &QTimeLine::finished, this, &WorksheetView::animFinished);
1006  anim->start();
1007 }
1008 
1010  qreal factor = 1.0 + qreal(m_numScheduledScalings) / 300.0;
1011  scale(factor, factor);
1012 }
1013 
1015  if (m_numScheduledScalings > 0)
1017  else
1019  sender()->~QObject();
1020 }
1021 
1022 void WorksheetView::mousePressEvent(QMouseEvent* event) {
1023  //prevent the deselection of items when context menu event
1024  //was triggered (right button click)
1025  if (event->button() == Qt::RightButton) {
1026  event->accept();
1027  return;
1028  }
1029 
1030  if (event->button() == Qt::LeftButton && m_mouseMode == MouseMode::ZoomSelection) {
1031  m_selectionStart = event->pos();
1032  m_selectionEnd = m_selectionStart; //select&zoom'g starts -> reset the end point to the start point
1033  m_selectionBandIsShown = true;
1034  QGraphicsView::mousePressEvent(event);
1035  return;
1036  }
1037 
1038  // select the worksheet in the project explorer if the view was clicked
1039  // and there is no selection currently. We need this for the case when
1040  // there is a single worksheet in the project and we change from the project-node
1041  // in the project explorer to the worksheet-node by clicking the view.
1042  if ( scene()->selectedItems().isEmpty() )
1044 
1045  QGraphicsView::mousePressEvent(event);
1046 }
1047 
1048 void WorksheetView::mouseReleaseEvent(QMouseEvent* event) {
1049  if (event->button() == Qt::LeftButton && m_mouseMode == MouseMode::ZoomSelection) {
1050  m_selectionBandIsShown = false;
1051  viewport()->repaint(QRect(m_selectionStart, m_selectionEnd).normalized());
1052 
1053  //don't zoom if very small region was selected, avoid occasional/unwanted zooming
1054  m_selectionEnd = event->pos();
1055  if ( abs(m_selectionEnd.x() - m_selectionStart.x()) > 20 && abs(m_selectionEnd.y() - m_selectionStart.y()) > 20 )
1056  fitInView(mapToScene(QRect(m_selectionStart, m_selectionEnd).normalized()).boundingRect(), Qt::KeepAspectRatio);
1057  }
1058 
1059  QGraphicsView::mouseReleaseEvent(event);
1060 }
1061 
1064 }
1065 
1066 void WorksheetView::mouseMoveEvent(QMouseEvent* event) {
1068  //check whether there is a cartesian plot under the cursor
1069  //and set the cursor appearance according to the current mouse mode for the cartesian plots
1070  if ( isPlotAtPos(event->pos()) ) {
1072  setCursor(Qt::CrossCursor);
1074  setCursor(Qt::SizeHorCursor);
1076  setCursor(Qt::SizeVerCursor);
1077  } else
1078  setCursor(Qt::ArrowCursor);
1080  setCursor(Qt::ArrowCursor);
1081  else if (m_selectionBandIsShown) {
1082  QRect rect = QRect(m_selectionStart, m_selectionEnd).normalized();
1083  m_selectionEnd = event->pos();
1084  rect = rect.united(QRect(m_selectionStart, m_selectionEnd).normalized());
1085  qreal penWidth = 5/transform().m11();
1086  rect.setX(rect.x()-penWidth);
1087  rect.setY(rect.y()-penWidth);
1088  rect.setHeight(rect.height()+2*penWidth);
1089  rect.setWidth(rect.width()+2*penWidth);
1090  viewport()->repaint(rect);
1091  }
1092 
1093  //show the magnification window
1094  if (magnificationFactor /*&& m_mouseMode == SelectAndEditMode*/) {
1095  if (!m_magnificationWindow) {
1096  m_magnificationWindow = new QGraphicsPixmapItem(nullptr);
1097  m_magnificationWindow->setZValue(std::numeric_limits<int>::max());
1098  scene()->addItem(m_magnificationWindow);
1099  }
1100 
1101  m_magnificationWindow->setVisible(false);
1102 
1103  //copy the part of the view to be shown magnified
1104  QPointF pos = mapToScene(event->pos());
1105  const int size = Worksheet::convertToSceneUnits(2.0, Worksheet::Unit::Centimeter)/transform().m11();
1106 
1107  const QRectF copyRect(pos.x() - size/(2*magnificationFactor), pos.y() - size/(2*magnificationFactor), size/magnificationFactor, size/magnificationFactor);
1108  QPixmap px = grab(mapFromScene(copyRect).boundingRect());
1109  px = px.scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1110 
1111  //draw the bounding rect
1112  QPainter painter(&px);
1113  const QPen pen = QPen(Qt::lightGray, 2/transform().m11());
1114  painter.setPen(pen);
1115  QRect rect = px.rect();
1116  rect.setWidth(rect.width()-pen.widthF()/2);
1117  rect.setHeight(rect.height()-pen.widthF()/2);
1118  painter.drawRect(rect);
1119 
1120  //set the pixmap
1121  m_magnificationWindow->setPixmap(px);
1122  m_magnificationWindow->setPos(pos.x()- px.width()/2, pos.y()- px.height()/2);
1123 
1124  m_magnificationWindow->setVisible(true);
1125  } else if (m_magnificationWindow)
1126  m_magnificationWindow->setVisible(false);
1127 
1128  QGraphicsView::mouseMoveEvent(event);
1129 }
1130 
1131 void WorksheetView::contextMenuEvent(QContextMenuEvent* e) {
1132  if ( (m_magnificationWindow && m_magnificationWindow->isVisible() && items(e->pos()).size() == 1) || !itemAt(e->pos()) ) {
1133  //no item or only the magnification window under the cursor -> show the context menu for the worksheet
1134  QMenu *menu = new QMenu(this);
1135  this->createContextMenu(menu);
1136  menu->exec(QCursor::pos());
1137  } else {
1138  //propagate the event to the scene and graphics items
1139  QGraphicsView::contextMenuEvent(e);
1140  }
1141 }
1142 
1143 void WorksheetView::keyPressEvent(QKeyEvent* event) {
1144  if (event->matches(QKeySequence::Copy)) {
1145  //add here copying of objects
1147  }
1148 
1149  QGraphicsView::keyPressEvent(event);
1150 }
1151 
1152 void WorksheetView::keyReleaseEvent(QKeyEvent* event) {
1153  QGraphicsView::keyReleaseEvent(event);
1154 }
1155 
1156 void WorksheetView::dragEnterEvent(QDragEnterEvent* event) {
1157  //ignore events not related to internal drags of columns etc., e.g. dropping of external files onto LabPlot
1158  const QMimeData* mimeData = event->mimeData();
1159  if (!mimeData) {
1160  event->ignore();
1161  return;
1162  }
1163 
1164  if (mimeData->formats().at(0) != QLatin1String("labplot-dnd")) {
1165  event->ignore();
1166  return;
1167  }
1168 
1169  //select the worksheet in the project explorer and bring the view to the foreground
1171  m_worksheet->mdiSubWindow()->mdiArea()->setActiveSubWindow(m_worksheet->mdiSubWindow());
1172 
1173  event->setAccepted(true);
1174 }
1175 
1176 void WorksheetView::dragMoveEvent(QDragMoveEvent* event) {
1177  // only accept drop events if we have a plot under the cursor where we can drop columns onto
1178  bool plot = isPlotAtPos(event->pos());
1179  event->setAccepted(plot);
1180 }
1181 
1182 void WorksheetView::dropEvent(QDropEvent* event) {
1183  CartesianPlot* plot = plotAt(event->pos());
1184  if (!plot)
1185  return;
1186 
1187  const QMimeData* mimeData = event->mimeData();
1188  plot->processDropEvent(plot->project()->droppedAspects(mimeData));
1189 }
1190 
1191 //##############################################################################
1192 //#################################### SLOTs ################################
1193 //##############################################################################
1195  if (!m_actionsInitialized)
1196  initActions();
1197 
1198  if (m_worksheet->useViewSize()) {
1199  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1200  setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1201  zoomFitPageHeightAction->setVisible(false);
1202  zoomFitPageWidthAction->setVisible(false);
1204  if (tbZoom)
1205  tbZoom->setDefaultAction(zoomInViewAction);
1206 
1207  //determine and set the current view size
1208  this->processResize();
1209  } else {
1210  setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
1211  setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
1212  zoomFitPageHeightAction->setVisible(true);
1213  zoomFitPageWidthAction->setVisible(true);
1214  }
1215 }
1216 
1218  if (size() != sceneRect().size()) {
1219  static const float hscale = QApplication::desktop()->physicalDpiX()/(Worksheet::convertToSceneUnits(1, Worksheet::Unit::Inch));
1220  static const float vscale = QApplication::desktop()->physicalDpiY()/(Worksheet::convertToSceneUnits(1, Worksheet::Unit::Inch));
1221  m_worksheet->setUndoAware(false);
1222  m_worksheet->setPageRect(QRectF(0.0, 0.0, width()/hscale, height()/vscale));
1223  m_worksheet->setUndoAware(true);
1224  }
1225 }
1226 
1228  if (action == zoomInViewAction)
1229  zoom(1);
1230  else if (action == zoomOutViewAction)
1231  zoom(-1);
1232  else if (action == zoomOriginAction) {
1233  static const float hscale = QApplication::desktop()->physicalDpiX()/(Worksheet::convertToSceneUnits(1, Worksheet::Unit::Inch));
1234  static const float vscale = QApplication::desktop()->physicalDpiY()/(Worksheet::convertToSceneUnits(1, Worksheet::Unit::Inch));
1235  setTransform(QTransform::fromScale(hscale, vscale));
1236  } else if (action == zoomFitPageWidthAction) {
1237  float scaleFactor = viewport()->width()/scene()->sceneRect().width();
1238  setTransform(QTransform::fromScale(scaleFactor, scaleFactor));
1239  } else if (action == zoomFitPageHeightAction) {
1240  float scaleFactor = viewport()->height()/scene()->sceneRect().height();
1241  setTransform(QTransform::fromScale(scaleFactor, scaleFactor));
1242  } else if (action == zoomFitSelectionAction)
1243  fitInView(scene()->selectionArea().boundingRect(),Qt::KeepAspectRatio);
1245  if (tbZoom)
1246  tbZoom->setDefaultAction(action);
1247 }
1248 
1251  magnificationFactor = 0;
1252  else if (action == twoTimesMagnificationAction)
1253  magnificationFactor = 2;
1255  magnificationFactor = 3;
1257  magnificationFactor = 4;
1259  magnificationFactor = 5;
1260 
1262  if (tbMagnification)
1263  tbMagnification->setDefaultAction(action);
1264 }
1265 
1267  if (action == selectionModeAction) {
1269  setInteractive(true);
1270  setDragMode(QGraphicsView::NoDrag);
1271  } else if (action == navigationModeAction) {
1273  setInteractive(false);
1274  setDragMode(QGraphicsView::ScrollHandDrag);
1275  } else {
1277  setInteractive(false);
1278  setDragMode(QGraphicsView::NoDrag);
1279  }
1280 }
1281 
1282 //"Add new" related slots
1284  WorksheetElement* aspect = nullptr;
1286  CartesianPlot* plot = new CartesianPlot(i18n("xy-plot"));
1289  aspect = plot;
1290  if (tbNewCartesianPlot)
1291  tbNewCartesianPlot->setDefaultAction(addCartesianPlot1Action);
1292  } else if (action == addCartesianPlot2Action) {
1293  CartesianPlot* plot = new CartesianPlot(i18n("xy-plot"));
1296  aspect = plot;
1297  if (tbNewCartesianPlot)
1298  tbNewCartesianPlot->setDefaultAction(addCartesianPlot2Action);
1299  } else if (action == addCartesianPlot3Action) {
1300  CartesianPlot* plot = new CartesianPlot(i18n("xy-plot"));
1303  aspect = plot;
1304  if (tbNewCartesianPlot)
1305  tbNewCartesianPlot->setDefaultAction(addCartesianPlot3Action);
1306  } else if (action == addCartesianPlot4Action) {
1307  CartesianPlot* plot = new CartesianPlot(i18n("xy-plot"));
1310  aspect = plot;
1311  if (tbNewCartesianPlot)
1312  tbNewCartesianPlot->setDefaultAction(addCartesianPlot4Action);
1313  } else if (action == addTextLabelAction) {
1314  TextLabel* l = new TextLabel(i18n("Text Label"));
1315  l->setText(i18n("Text Label"));
1316  aspect = l;
1317  } else if (action == addImageAction) {
1318  Image* l = new Image(i18n("Image"));
1319  aspect = l;
1320  }
1321  if (!aspect)
1322  return;
1323 
1324  m_worksheet->addChild(aspect);
1325 
1326  //labels and images with their initial positions need to be retransformed
1327  //ater they have gotten a parent
1328  if (aspect->type() == AspectType::TextLabel || aspect->type() == AspectType::Image)
1329  aspect->retransform();
1330 
1332 
1333  if (!m_fadeInTimeLine) {
1334  m_fadeInTimeLine = new QTimeLine(1000, this);
1335  m_fadeInTimeLine->setFrameRange(0, 100);
1336  connect(m_fadeInTimeLine, &QTimeLine::valueChanged, this, &WorksheetView::fadeIn);
1337  }
1338 
1339  //if there is already an element fading in, stop the time line and show the element with the full opacity.
1340  if (m_fadeInTimeLine->state() == QTimeLine::Running) {
1341  m_fadeInTimeLine->stop();
1342  auto* effect = new QGraphicsOpacityEffect();
1343  effect->setOpacity(1);
1344  lastAddedWorksheetElement->graphicsItem()->setGraphicsEffect(effect);
1345  }
1346 
1347  //fade-in the newly added element
1348  lastAddedWorksheetElement = aspect;
1349  auto* effect = new QGraphicsOpacityEffect();
1350  effect->setOpacity(0);
1351  lastAddedWorksheetElement->graphicsItem()->setGraphicsEffect(effect);
1352  m_fadeInTimeLine->start();
1353 }
1354 
1355 /*!
1356  * select all top-level items
1357  */
1359  //deselect all previously selected items since there can be some non top-level items belong them
1361  for (auto* item : m_selectedItems)
1362  m_worksheet->setItemSelectedInView(item, false);
1363 
1364  //select top-level items
1365  for (auto* item : scene()->items()) {
1366  if (!item->parentItem())
1367  item->setSelected(true);
1368  }
1370  this->selectionChanged();
1371 }
1372 
1373 /*!
1374  * deletes selected worksheet elements
1375  */
1377  if (m_selectedItems.isEmpty())
1378  return;
1379 
1380  int rc = KMessageBox::warningYesNo( this, i18np("Do you really want to delete the selected object?", "Do you really want to delete the selected %1 objects?", m_selectedItems.size()),
1381  i18np("Delete selected object", "Delete selected objects", m_selectedItems.size()));
1382 
1383  if (rc == KMessageBox::No)
1384  return;
1385 
1387  m_worksheet->beginMacro(i18n("%1: Remove selected worksheet elements.", m_worksheet->name()));
1388  for (auto* item : m_selectedItems)
1390  m_worksheet->endMacro();
1392 }
1393 
1395  lastAddedWorksheetElement = dynamic_cast<WorksheetElement*>(const_cast<AbstractAspect*>(aspect));
1397  return;
1398 
1399  //FIXME: fading-out doesn't work
1400  //also, the following code collides with undo/redo of the deletion
1401  //of a worksheet element (after redoing the element is not shown with the full opacity
1402  /*
1403  if (!m_fadeOutTimeLine) {
1404  m_fadeOutTimeLine = new QTimeLine(1000, this);
1405  m_fadeOutTimeLine->setFrameRange(0, 100);
1406  connect(m_fadeOutTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(fadeOut(qreal)));
1407  }
1408 
1409  //if there is already an element fading out, stop the time line
1410  if (m_fadeOutTimeLine->state() == QTimeLine::Running)
1411  m_fadeOutTimeLine->stop();
1412 
1413  m_fadeOutTimeLine->start();
1414  */
1415 }
1416 
1417 void WorksheetView::fadeIn(qreal value) {
1418  auto* effect = new QGraphicsOpacityEffect();
1419  effect->setOpacity(value);
1420  lastAddedWorksheetElement->graphicsItem()->setGraphicsEffect(effect);
1421 }
1422 
1423 void WorksheetView::fadeOut(qreal value) {
1424  auto* effect = new QGraphicsOpacityEffect();
1425  effect->setOpacity(1 - value);
1426  lastAddedWorksheetElement->graphicsItem()->setGraphicsEffect(effect);
1427 }
1428 
1429 /*!
1430  * called when one of the layout-actions in WorkseetView was triggered.
1431  * sets the layout in Worksheet and enables/disables the layout actions.
1432  */
1434  if (action == breakLayoutAction) {
1435  verticalLayoutAction->setEnabled(true);
1436  verticalLayoutAction->setChecked(false);
1437 
1438  horizontalLayoutAction->setEnabled(true);
1439  horizontalLayoutAction->setChecked(false);
1440 
1441  gridLayoutAction->setEnabled(true);
1442  gridLayoutAction->setChecked(false);
1443 
1444  breakLayoutAction->setEnabled(false);
1445 
1447  } else {
1448  verticalLayoutAction->setEnabled(false);
1449  horizontalLayoutAction->setEnabled(false);
1450  gridLayoutAction->setEnabled(false);
1451  breakLayoutAction->setEnabled(true);
1452 
1453  if (action == verticalLayoutAction) {
1454  verticalLayoutAction->setChecked(true);
1456  } else if (action == horizontalLayoutAction) {
1457  horizontalLayoutAction->setChecked(true);
1459  } else {
1460  gridLayoutAction->setChecked(true);
1462  }
1463  }
1464 }
1465 
1467  if (action == noGridAction) {
1469  snapToGridAction->setEnabled(false);
1470  } else if (action == sparseLineGridAction) {
1472  m_gridSettings.color = Qt::gray;
1473  m_gridSettings.opacity = 0.7;
1476  } else if (action == denseLineGridAction) {
1478  m_gridSettings.color = Qt::gray;
1479  m_gridSettings.opacity = 0.7;
1482  } else if (action == denseDotGridAction) {
1485  m_gridSettings.opacity = 0.7;
1488  } else if (action == sparseDotGridAction) {
1491  m_gridSettings.opacity = 0.7;
1494  } else if (action == customGridAction) {
1495  auto* dlg = new GridDialog(this);
1496  if (dlg->exec() == QDialog::Accepted)
1497  dlg->save(m_gridSettings);
1498  else
1499  return;
1500  }
1501 
1503  snapToGridAction->setEnabled(false);
1504  else
1505  snapToGridAction->setEnabled(true);
1506 
1507  invalidateScene(sceneRect(), QGraphicsScene::BackgroundLayer);
1508 }
1509 
1510 //TODO
1512 
1513 }
1514 
1515 /*!
1516  * Selects the QGraphicsItem \c item in \c WorksheetView.
1517  * The selection in \c ProjectExplorer is forwarded to \c Worksheet
1518  * and is finally handled here.
1519  */
1520 void WorksheetView::selectItem(QGraphicsItem* item) {
1522  item->setSelected(true);
1523  m_selectedItems<<item;
1526 }
1527 
1528 /*!
1529  * Deselects the \c QGraphicsItem \c item in \c WorksheetView.
1530  * The deselection in \c ProjectExplorer is forwarded to \c Worksheet
1531  * and is finally handled here.
1532  */
1533 void WorksheetView::deselectItem(QGraphicsItem* item) {
1535  item->setSelected(false);
1536  m_selectedItems.removeOne(item);
1539 }
1540 
1541 /*!
1542  * Called on selection changes in the view.
1543  * Determines which items were selected and deselected
1544  * and forwards these changes to \c Worksheet
1545  */
1547  //if the project is being closed, the scene items are being removed and the selection can change.
1548  //don't react on these changes since this can lead crashes (worksheet object is already in the destructor).
1549  if (m_isClosing)
1550  return;
1551 
1553  return;
1554 
1555  QList<QGraphicsItem*> items = scene()->selectedItems();
1556 
1557  //check, whether the previously selected items were deselected now.
1558  //Forward the deselection prior to the selection of new items
1559  //in order to avoid the unwanted multiple selection in project explorer
1560  for (auto* item : m_selectedItems ) {
1561  if ( items.indexOf(item) == -1 )
1562  m_worksheet->setItemSelectedInView(item, false);
1563  }
1564 
1565  //select new items
1566  if (items.isEmpty()) {
1567  //no items selected -> select the worksheet again.
1569 
1570  //if one of the "zoom&select" plot mouse modes was selected before, activate the default "selection mode" again
1571  //since no plots are selected now.
1573  cartesianPlotSelectionModeAction->setChecked(true);
1575  }
1576  } else {
1577  for (const auto* item : items)
1578  m_worksheet->setItemSelectedInView(item, true);
1579 
1580  //items selected -> deselect the worksheet in the project explorer
1581  //prevents unwanted multiple selection with worksheet (if it was selected before)
1583  }
1584 
1585  m_selectedItems = items;
1587 }
1588 
1589 //check whether we have cartesian plots selected and activate/deactivate
1591  if (!m_menusInitialized)
1592  return;
1593 
1594  bool plot = false;
1596  //check whether we have cartesian plots selected
1597  for (auto* item : m_selectedItems) {
1598  //TODO: or if a children of a plot is selected
1599  if (item->data(0).toInt() == static_cast<int>(WorksheetElement::WorksheetElementName::NameCartesianPlot)) {
1600  plot = true;
1601  break;
1602  }
1603  }
1604  } else {
1605  //actions are applied to all available plots -> check whether we have plots
1606  plot = (m_worksheet->children<CartesianPlot>().size() != 0);
1607  }
1608 
1609  cartesianPlotSelectionModeAction->setEnabled(plot);
1610  cartesianPlotZoomSelectionModeAction->setEnabled(plot);
1611  cartesianPlotZoomXSelectionModeAction->setEnabled(plot);
1612  cartesianPlotZoomYSelectionModeAction->setEnabled(plot);
1613  cartesianPlotCursorModeAction->setEnabled(plot);
1614 
1615  m_cartesianPlotAddNewMenu->setEnabled(plot);
1616  m_cartesianPlotZoomMenu->setEnabled(plot);
1617  m_cartesianPlotMouseModeMenu->setEnabled(plot);
1618 
1619  // analysis menu
1620  //TODO: enable also if children of plots are selected
1621 // m_dataManipulationMenu->setEnabled(plot);
1622 // addDataOperationAction->setEnabled(false);
1623  addDataReductionAction->setEnabled(false);
1624  addDifferentiationAction->setEnabled(plot);
1625  addIntegrationAction->setEnabled(plot);
1626  addInterpolationAction->setEnabled(plot);
1627  addSmoothAction->setEnabled(plot);
1628  addFitAction->setEnabled(plot);
1629  addFourierFilterAction->setEnabled(plot);
1630  addFourierTransformAction->setEnabled(plot);
1631  addConvolutionAction->setEnabled(plot);
1632  addCorrelationAction->setEnabled(plot);
1633 }
1634 
1635 void WorksheetView::exportToFile(const QString& path, const ExportFormat format, const ExportArea area, const bool background, const int resolution) {
1636  QRectF sourceRect;
1637 
1638  //determine the rectangular to print
1639  if (area == ExportArea::BoundingBox)
1640  sourceRect = scene()->itemsBoundingRect();
1641  else if (area == ExportArea::Selection) {
1642  //TODO doesn't work: rect = scene()->selectionArea().boundingRect();
1643  for (const auto* item : m_selectedItems)
1644  sourceRect = sourceRect.united( item->mapToScene(item->boundingRect()).boundingRect() );
1645  } else
1646  sourceRect = scene()->sceneRect();
1647 
1648  //print
1649  if (format == ExportFormat::PDF) {
1650  QPrinter printer(QPrinter::HighResolution);
1651  printer.setOutputFormat(QPrinter::PdfFormat);
1652 
1653  printer.setOutputFileName(path);
1655  int h = Worksheet::convertFromSceneUnits(sourceRect.height(), Worksheet::Unit::Millimeter);
1656  printer.setPaperSize( QSizeF(w, h), QPrinter::Millimeter);
1657  printer.setPageMargins(0,0,0,0, QPrinter::Millimeter);
1658  printer.setPrintRange(QPrinter::PageRange);
1659  printer.setCreator(QLatin1String("LabPlot ") + LVERSION);
1660 
1661  QPainter painter(&printer);
1662  painter.setRenderHint(QPainter::Antialiasing);
1663  QRectF targetRect(0, 0, painter.device()->width(),painter.device()->height());
1664  painter.begin(&printer);
1665  exportPaint(&painter, targetRect, sourceRect, background);
1666  painter.end();
1667  } else if (format == ExportFormat::SVG) {
1668  QSvgGenerator generator;
1669  generator.setFileName(path);
1670 // if (!generator.isValid()) {
1671 // RESET_CURSOR;
1672 // QMessageBox::critical(nullptr, i18n("Failed to export"), i18n("Failed to write to '%1'. Please check the path.", path));
1673 // }
1675  int h = Worksheet::convertFromSceneUnits(sourceRect.height(), Worksheet::Unit::Millimeter);
1676  w = w*QApplication::desktop()->physicalDpiX()/25.4;
1677  h = h*QApplication::desktop()->physicalDpiY()/25.4;
1678 
1679  generator.setSize(QSize(w, h));
1680  QRectF targetRect(0, 0, w, h);
1681  generator.setViewBox(targetRect);
1682 
1683  QPainter painter;
1684  painter.begin(&generator);
1685  exportPaint(&painter, targetRect, sourceRect, background);
1686  painter.end();
1687  } else {
1688  //PNG
1689  //TODO add all formats supported by Qt in QImage
1691  int h = Worksheet::convertFromSceneUnits(sourceRect.height(), Worksheet::Unit::Millimeter);
1692  w = w*resolution/25.4;
1693  h = h*resolution/25.4;
1694  QImage image(QSize(w, h), QImage::Format_ARGB32_Premultiplied);
1695  image.fill(Qt::transparent);
1696  QRectF targetRect(0, 0, w, h);
1697 
1698  QPainter painter;
1699  painter.begin(&image);
1700  painter.setRenderHint(QPainter::Antialiasing);
1701  exportPaint(&painter, targetRect, sourceRect, background);
1702  painter.end();
1703 
1704  if (!path.isEmpty()) {
1705  bool rc = image.save(path, "PNG");
1706  if (!rc) {
1707  RESET_CURSOR;
1708  QMessageBox::critical(nullptr, i18n("Failed to export"), i18n("Failed to write to '%1'. Please check the path.", path));
1709  }
1710  } else
1711  QApplication::clipboard()->setImage(image, QClipboard::Clipboard);
1712  }
1713 }
1714 
1716  QRectF sourceRect;
1717 
1718  if (m_selectedItems.size() == 0)
1719  sourceRect = scene()->itemsBoundingRect();
1720  else {
1721  //export selection
1722  for (const auto* item : m_selectedItems)
1723  sourceRect = sourceRect.united( item->mapToScene(item->boundingRect()).boundingRect() );
1724  }
1725 
1727  int h = Worksheet::convertFromSceneUnits(sourceRect.height(), Worksheet::Unit::Millimeter);
1728  w = w*QApplication::desktop()->physicalDpiX()/25.4;
1729  h = h*QApplication::desktop()->physicalDpiY()/25.4;
1730  QImage image(QSize(w, h), QImage::Format_ARGB32_Premultiplied);
1731  image.fill(Qt::transparent);
1732  QRectF targetRect(0, 0, w, h);
1733 
1734  QPainter painter;
1735  painter.begin(&image);
1736  painter.setRenderHint(QPainter::Antialiasing);
1737  exportPaint(&painter, targetRect, sourceRect, true);
1738  painter.end();
1739 
1740  QApplication::clipboard()->setImage(image, QClipboard::Clipboard);
1741 }
1742 
1743 void WorksheetView::exportPaint(QPainter* painter, const QRectF& targetRect, const QRectF& sourceRect, const bool background) {
1744  //draw the background
1745  if (background) {
1746  painter->save();
1747  painter->scale(targetRect.width()/sourceRect.width(), targetRect.height()/sourceRect.height());
1748  drawBackground(painter, sourceRect);
1749  painter->restore();
1750  }
1751 
1752  //draw the scene items
1753  m_worksheet->setPrinting(true);
1754  scene()->render(painter, QRectF(), sourceRect);
1755  m_worksheet->setPrinting(false);
1756 }
1757 
1758 void WorksheetView::print(QPrinter* printer) {
1759  m_worksheet->setPrinting(true);
1760  QPainter painter(printer);
1761  painter.setRenderHint(QPainter::Antialiasing);
1762 
1763  // draw background
1764  QRectF page_rect = printer->pageRect();
1765  QRectF scene_rect = scene()->sceneRect();
1766  float scale = qMax(scene_rect.width()/page_rect.width(),scene_rect.height()/page_rect.height());
1767  drawBackgroundItems(&painter, QRectF(0,0,scene_rect.width()/scale,scene_rect.height()/scale));
1768 
1769  // draw scene
1770  scene()->render(&painter);
1771  m_worksheet->setPrinting(false);
1772 }
1773 
1775  invalidateScene(sceneRect(), QGraphicsScene::BackgroundLayer);
1776 }
1777 
1778 /*!
1779  * called when the layout was changed in Worksheet,
1780  * enables the corresponding action
1781  */
1783  if (layout == Worksheet::Layout::NoLayout) {
1784  verticalLayoutAction->setEnabled(true);
1785  verticalLayoutAction->setChecked(false);
1786 
1787  horizontalLayoutAction->setEnabled(true);
1788  horizontalLayoutAction->setChecked(false);
1789 
1790  gridLayoutAction->setEnabled(true);
1791  gridLayoutAction->setChecked(false);
1792 
1793  breakLayoutAction->setEnabled(false);
1794  } else {
1795  verticalLayoutAction->setEnabled(false);
1796  horizontalLayoutAction->setEnabled(false);
1797  gridLayoutAction->setEnabled(false);
1798  breakLayoutAction->setEnabled(true);
1799 
1800  if (layout == Worksheet::Layout::VerticalLayout)
1801  verticalLayoutAction->setChecked(true);
1802  else if (layout == Worksheet::Layout::HorizontalLayout)
1803  horizontalLayoutAction->setChecked(true);
1804  else
1805  gridLayoutAction->setChecked(true);
1806  }
1807 }
1808 
1811 }
1812 
1814  selectAllAction->setShortcut(Qt::CTRL+Qt::Key_A);
1815  deleteAction->setShortcut(Qt::Key_Delete);
1816  backspaceAction->setShortcut(Qt::Key_Backspace);
1817  zoomInViewAction->setShortcut(Qt::CTRL+Qt::Key_Plus);
1818  zoomOutViewAction->setShortcut(Qt::CTRL+Qt::Key_Minus);
1819  zoomOriginAction->setShortcut(Qt::CTRL+Qt::Key_1);
1820 }
1821 
1823  selectAllAction->setShortcut(QKeySequence());
1824  deleteAction->setShortcut(QKeySequence());
1825  backspaceAction->setShortcut(QKeySequence());
1826  zoomInViewAction->setShortcut(QKeySequence());
1827  zoomOutViewAction->setShortcut(QKeySequence());
1828  zoomOriginAction->setShortcut(QKeySequence());
1829 }
1830 
1831 //##############################################################################
1832 //######################## SLOTs for cartesian plots ########################
1833 //##############################################################################
1837  else
1839 
1841 }
1842 
1846  else
1848 
1850 }
1851 
1853  m_worksheet->setPlotsLocked(checked);
1854 }
1855 
1858  return;
1859 
1870 
1871  for (auto* plot : m_worksheet->children<CartesianPlot>() )
1872  plot->setMouseMode(m_cartesianPlotMouseMode);
1873 }
1874 
1876  if (!m_menusInitialized)
1877  return;
1878 
1880  if (mouseMode == CartesianPlot::MouseMode::Selection)
1881  cartesianPlotSelectionModeAction->setChecked(true);
1882  else if (mouseMode == CartesianPlot::MouseMode::ZoomSelection)
1883  cartesianPlotZoomSelectionModeAction->setChecked(true);
1884  else if (mouseMode == CartesianPlot::MouseMode::ZoomXSelection)
1885  cartesianPlotZoomXSelectionModeAction->setChecked(true);
1886  else if (mouseMode == CartesianPlot::MouseMode::ZoomYSelection)
1887  cartesianPlotZoomYSelectionModeAction->setChecked(true);
1888  else if (mouseMode == CartesianPlot::MouseMode::Cursor)
1889  cartesianPlotCursorModeAction->setChecked(true);
1890  m_suppressMouseModeChange = false;
1891 }
1892 
1896  int selectedPlots = 0;
1897  for (auto* plot : plots) {
1898  if (m_selectedItems.indexOf(plot->graphicsItem()) != -1)
1899  ++selectedPlots;
1900  else {
1901  //current plot is not selected, check if one of its children is selected
1902  auto children = plot->children<WorksheetElement>();
1903  for (auto* child : children) {
1904  if (m_selectedItems.indexOf(child->graphicsItem()) != -1) {
1905  ++selectedPlots;
1906  break;
1907  }
1908  }
1909  }
1910  }
1911 
1912  if (selectedPlots > 1)
1913  m_worksheet->beginMacro(i18n("%1: Add curve to %2 plots", m_worksheet->name(), selectedPlots));
1914 
1915  for (auto* plot : plots) {
1916  if (m_selectedItems.indexOf(plot->graphicsItem()) != -1)
1917  this->cartesianPlotAdd(plot, action);
1918  else {
1919  //current plot is not selected, check if one of its children is selected
1920  auto children = plot->children<WorksheetElement>();
1921  for (auto* child : children) {
1922  if (m_selectedItems.indexOf(child->graphicsItem()) != -1) {
1923  this->cartesianPlotAdd(plot, action);
1924  break;
1925  }
1926  }
1927  }
1928  }
1929 
1930  if (selectedPlots > 1)
1931  m_worksheet->endMacro();
1932  } else {
1933  if (plots.size() > 1)
1934  m_worksheet->beginMacro(i18n("%1: Add curve to %2 plots", m_worksheet->name(), plots.size()));
1935 
1936  for (auto* plot : plots)
1937  this->cartesianPlotAdd(plot, action);
1938 
1939  if (plots.size() > 1)
1940  m_worksheet->endMacro();
1941  }
1942 }
1943 
1945  DEBUG("WorksheetView::cartesianPlotAdd()");
1946  if (action == addCurveAction)
1947  plot->addCurve();
1948  else if (action == addHistogramAction)
1949  plot->addHistogram();
1950  else if (action == addEquationCurveAction)
1951  plot->addEquationCurve();
1952  else if (action == addDataReductionCurveAction)
1953  plot->addDataReductionCurve();
1955  plot->addDifferentiationCurve();
1956  else if (action == addIntegrationCurveAction)
1957  plot->addIntegrationCurve();
1958  else if (action == addInterpolationCurveAction)
1959  plot->addInterpolationCurve();
1960  else if (action == addSmoothCurveAction)
1961  plot->addSmoothCurve();
1962  else if (action == addFitCurveAction)
1963  plot->addFitCurve();
1964  else if (action == addFourierFilterCurveAction)
1965  plot->addFourierFilterCurve();
1967  plot->addFourierTransformCurve();
1968  else if (action == addConvolutionCurveAction)
1969  plot->addConvolutionCurve();
1970  else if (action == addCorrelationCurveAction)
1971  plot->addCorrelationCurve();
1972  else if (action == addLegendAction)
1973  plot->addLegend();
1974  else if (action == addHorizontalAxisAction)
1975  plot->addHorizontalAxis();
1976  else if (action == addVerticalAxisAction)
1977  plot->addVerticalAxis();
1978  else if (action == addPlotTextLabelAction)
1979  plot->addTextLabel();
1980  else if (action == addPlotImageAction)
1981  plot->addImage();
1982  else if (action == addCustomPointAction)
1983  plot->addCustomPoint();
1984 // analysis actions
1985  else if (action == addDataReductionAction)
1986  plot->addDataReductionCurve();
1987  else if (action == addDifferentiationAction)
1988  plot->addDifferentiationCurve();
1989  else if (action == addIntegrationAction)
1990  plot->addIntegrationCurve();
1991  else if (action == addInterpolationAction)
1992  plot->addInterpolationCurve();
1993  else if (action == addSmoothAction)
1994  plot->addSmoothCurve();
1995  else if (action == addFitAction)
1996  plot->addFitCurve();
1997  else if (action == addFourierFilterAction)
1998  plot->addFourierFilterCurve();
1999  else if (action == addFourierTransformAction)
2000  plot->addFourierTransformCurve();
2001  else if (action == addConvolutionAction)
2002  plot->addConvolutionCurve();
2003  else if (action == addCorrelationAction)
2004  plot->addCorrelationCurve();
2005 }
2006 
2010  for (auto* plot : m_worksheet->children<CartesianPlot>() ) {
2011  if (m_selectedItems.indexOf(plot->graphicsItem()) != -1)
2012  plot->navigate(op);
2013  else {
2014  // check if one of the plots childrend is selected. Do the operation there too.
2015  for (auto* child : plot->children<WorksheetElement>()) {
2016  if (m_selectedItems.indexOf(child->graphicsItem()) != -1) {
2017  plot->navigate(op);
2018  break;
2019  }
2020  }
2021  }
2022  }
2023  } else {
2024  for (auto* plot : m_worksheet->children<CartesianPlot>() )
2025  plot->navigate(op);
2026  }
2027 }
2028 
2031 }
2032 
2034  KConfigGroup group = KSharedConfig::openConfig()->group("Settings_Worksheet");
2035 
2036  //show dynamic presenter widget, if enabled
2037  if (group.readEntry("PresenterModeInteractive", false)) {
2038  auto* dynamicPresenterWidget = new DynamicPresenterWidget(m_worksheet);
2039  dynamicPresenterWidget->showFullScreen();
2040  return;
2041  }
2042 
2043  //show static presenter widget (default)
2044  QRectF sourceRect(scene()->sceneRect());
2045 
2047  int h = Worksheet::convertFromSceneUnits(sourceRect.height(), Worksheet::Unit::Millimeter);
2048  w *= QApplication::desktop()->physicalDpiX()/25.4;
2049  h *= QApplication::desktop()->physicalDpiY()/25.4;
2050 
2051  QRectF targetRect(0, 0, w, h);
2052  const QRectF& screenSize = QGuiApplication::primaryScreen()->availableGeometry();;
2053 
2054  if (targetRect.width() > screenSize.width() || ((targetRect.height() > screenSize.height()))) {
2055  const double ratio = qMin(screenSize.width() / targetRect.width(), screenSize.height() / targetRect.height());
2056  targetRect.setWidth(targetRect.width()* ratio);
2057  targetRect.setHeight(targetRect.height() * ratio);
2058  }
2059 
2060  QImage image(QSize(targetRect.width(), targetRect.height()), QImage::Format_ARGB32_Premultiplied);
2061  image.fill(Qt::transparent);
2062  QPainter painter;
2063  painter.begin(&image);
2064  painter.setRenderHint(QPainter::Antialiasing);
2065  exportPaint(&painter, targetRect, sourceRect, true);
2066  painter.end();
2067 
2068  auto* presenterWidget = new PresenterWidget(QPixmap::fromImage(image), m_worksheet->name());
2069  presenterWidget->showFullScreen();
2070 }
static const QRgb black
Definition: ImageEditor.cpp:38
Base class of all persistent objects in a Project.
AspectType type() const
void setUndoAware(bool)
void addChild(AbstractAspect *)
Add the given Aspect to my list of children.
void aspectAboutToBeRemoved(const AbstractAspect *)
Emitted before an aspect is removed from its parent.
QString name() const
void beginMacro(const QString &text)
Begin an undo stack macro (series of commands)
bool isLoading() const
QVector< AbstractAspect * > children(AspectType type, ChildIndexFlags flags={}) const
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.
PartMdiView * mdiSubWindow() const
Wrap the view() into a PartMdiView.
A xy-plot.
Definition: CartesianPlot.h:58
void setType(Type type)
void addHorizontalAxis()
void setMouseMode(MouseMode)
void addIntegrationCurve()
void addCorrelationCurve()
void addFourierTransformCurve()
void addInterpolationCurve()
void addDifferentiationCurve()
void processDropEvent(const QVector< quintptr > &) override
void addConvolutionCurve()
void addFourierFilterCurve()
void addDataReductionCurve()
void addLegend(CartesianPlotLegend *)
A label supporting rendering of html- and tex-formatted texts.
Definition: Image.h:41
QVector< quintptr > droppedAspects(const QMimeData *)
Definition: Project.cpp:360
A label supporting rendering of html- and tex-formatted texts.
Definition: TextLabel.h:44
Widget for showing theme previews and for selecting a theme.
Definition: ThemesWidget.h:34
void themeSelected(const QString &)
Base class for all Worksheet children.
virtual void retransform()=0
Tell the element to newly transform its graphics item into its coordinate system.
virtual QGraphicsItem * graphicsItem() const =0
Return the graphics item representing this element.
QAction * addDifferentiationCurveAction
void changeGrid(QAction *)
QAction * addTextLabelAction
void setPlotLock(bool lock)
QAction * scaleAutoXAction
void resizeEvent(QResizeEvent *) override
void fillCartesianPlotToolBar(QToolBar *)
Worksheet * m_worksheet
QAction * cartesianPlotApplyToAllCursor
QAction * sparseDotGridAction
void mouseMoveEvent(QMouseEvent *) override
QAction * addDataOperationCurveAction
void selectItem(QGraphicsItem *)
WorksheetView(Worksheet *worksheet)
QAction * addEquationCurveAction
QMenu * m_cartesianPlotAddNewAnalysisMenu
void cartesianPlotNavigationChanged(QAction *)
QAction * selectionModeAction
QAction * addPlotImageAction
QAction * threeTimesMagnificationAction
GridSettings m_gridSettings
QAction * addDataReductionAction
Worksheet::CartesianPlotActionMode getCartesianPlotActionMode()
void print(QPrinter *)
QAction * shiftUpYAction
QMenu * m_gridMenu
void cartesianPlotAdd(CartesianPlot *, QAction *)
QAction * addImageAction
void cartesianPlotCursorModeChanged(QAction *)
QAction * noMagnificationAction
void exportToFile(const QString &, const ExportFormat, const ExportArea, const bool, const int)
QPoint m_selectionStart
void magnificationChanged(QAction *)
QAction * shiftLeftXAction
QAction * horizontalLayoutAction
QAction * fourTimesMagnificationAction
void contextMenuEvent(QContextMenuEvent *) override
void exportPaint(QPainter *painter, const QRectF &targetRect, const QRectF &sourceRect, const bool)
QAction * zoomSelectionModeAction
QMenu * m_addNewCartesianPlotMenu
QAction * zoomFitPageWidthAction
QGraphicsPixmapItem * m_magnificationWindow
QAction * zoomInAction
QMenu * m_layoutMenu
void layoutChanged(Worksheet::Layout)
void drawBackground(QPainter *, const QRectF &) override
QAction * selectAllAction
void cartesianPlotActionModeChanged(QAction *)
void keyReleaseEvent(QKeyEvent *) override
void mouseModeChanged(QAction *)
QAction * cartesianPlotApplyToAllAction
QMenu * m_cartesianPlotActionModeMenu
QMenu * m_addNewMenu
bool m_actionsInitialized
QMenu * m_viewMouseModeMenu
void cartesianPlotMouseModeChangedSlot(CartesianPlot::MouseMode mouseMode)
void fadeOut(qreal)
QAction * cartesianPlotZoomXSelectionModeAction
QAction * backspaceAction
void propertiesExplorerRequested()
void selectAllElements()
QAction * verticalLayoutAction
CartesianPlot::MouseMode m_cartesianPlotMouseMode
void initBasicActions()
QAction * cartesianPlotZoomSelectionModeAction
QAction * zoomInYAction
QAction * addConvolutionCurveAction
QMenu * m_cartesianPlotMenu
QAction * addCustomPointAction
bool m_selectionBandIsShown
QMenu * m_cartesianPlotZoomMenu
QAction * zoomOutViewAction
QAction * addCurveAction
void addNew(QAction *)
QAction * addFitCurveAction
QAction * currentMagnificationAction
QAction * addDataReductionCurveAction
QAction * showPresenterMode
void unregisterShortcuts()
QAction * zoomInViewAction
QMenu * m_themeMenu
QAction * addHorizontalAxisAction
QMenu * m_cartesianPlotCursorModeMenu
QAction * cartesianPlotApplyToSelectionAction
void setScene(QGraphicsScene *)
QAction * cartesianPlotCursorModeAction
QTimeLine * m_fadeInTimeLine
QPoint m_selectionEnd
QMenu * m_cartesianPlotAddNewMenu
QAction * addInterpolationAction
QMenu * m_dataManipulationMenu
QAction * addCartesianPlot1Action
QAction * addIntegrationCurveAction
QAction * shiftRightXAction
void keyPressEvent(QKeyEvent *) override
QAction * scaleAutoYAction
void cartesianPlotMouseModeChanged(QAction *)
QAction * addSmoothCurveAction
QAction * breakLayoutAction
QAction * addCartesianPlot2Action
QAction * addVerticalAxisAction
void createAnalysisMenu(QMenu *)
WorksheetElement * lastAddedWorksheetElement
QAction * addFourierFilterCurveAction
QAction * addDataOperationAction
QAction * addCorrelationAction
void fillToolBar(QToolBar *)
void dragEnterEvent(QDragEnterEvent *) override
QAction * plotsLockedAction
void createContextMenu(QMenu *)
void wheelEvent(QWheelEvent *) override
void useViewSizeRequested()
bool m_suppressSelectionChangedEvent
void cartesianPlotAddNew(QAction *)
QAction * addFourierTransformCurveAction
void registerShortcuts()
QAction * zoomInXAction
void changeLayout(QAction *)
QAction * customGridAction
void changeZoom(QAction *)
void handleCartesianPlotActions()
bool isPlotAtPos(QPoint) const
int m_numScheduledScalings
void dragMoveEvent(QDragMoveEvent *) override
QAction * currentZoomAction
QAction * addIntegrationAction
void dropEvent(QDropEvent *) override
QAction * gridLayoutAction
QAction * fiveTimesMagnificationAction
QAction * navigationModeAction
bool m_menusInitialized
QAction * cartesianPlotSelectionModeAction
QAction * denseLineGridAction
QList< QGraphicsItem * > m_selectedItems
QAction * zoomOutYAction
QToolButton * tbMagnification
QAction * cartesianPlotZoomYSelectionModeAction
void mouseReleaseEvent(QMouseEvent *) override
void setCartesianPlotActionMode(Worksheet::CartesianPlotActionMode mode)
QAction * shiftDownYAction
QAction * twoTimesMagnificationAction
void aspectAboutToBeRemoved(const AbstractAspect *)
bool m_suppressMouseModeChange
void exportToClipboard()
void mouseDoubleClickEvent(QMouseEvent *) override
QAction * noGridAction
void drawBackgroundItems(QPainter *, const QRectF &)
void setCartesianPlotCursorMode(Worksheet::CartesianPlotActionMode mode)
QAction * cartesianPlotApplyToSelectionCursor
void deselectItem(QGraphicsItem *)
QAction * addCartesianPlot4Action
CartesianPlot * plotAt(QPoint) const
QAction * denseDotGridAction
QAction * addPlotTextLabelAction
void drawForeground(QPainter *, const QRectF &) override
QAction * addDifferentiationAction
QToolButton * tbNewCartesianPlot
QAction * addConvolutionAction
QAction * zoomFitPageHeightAction
QAction * addCorrelationCurveAction
QMenu * m_cartesianPlotMouseModeMenu
QAction * addFitAction
QAction * addCartesianPlot3Action
QAction * zoomFitSelectionAction
QAction * scaleAutoAction
QMenu * m_zoomMenu
QAction * addInterpolationCurveAction
QAction * snapToGridAction
QAction * addSmoothAction
void mousePressEvent(QMouseEvent *) override
QAction * addLegendAction
QAction * zoomOutAction
QAction * addHistogramAction
QAction * zoomOutXAction
QAction * addFourierFilterAction
void plotsLockedActionChanged(bool checked)
QAction * deleteAction
void suppressSelectionChangedEvent(bool)
MouseMode m_mouseMode
QAction * zoomOriginAction
void fadeIn(qreal)
QAction * sparseLineGridAction
QToolButton * tbZoom
QMenu * m_magnificationMenu
QAction * addFourierTransformAction
Top-level container for worksheet elements like plot, labels, etc.
Definition: Worksheet.h:46
void useViewSizeRequested()
void setCartesianPlotActionMode(CartesianPlotActionMode mode)
Definition: Worksheet.cpp:461
CartesianPlotActionMode cartesianPlotCursorMode()
Definition: Worksheet.cpp:453
QGraphicsScene * scene() const
Definition: Worksheet.cpp:299
CartesianPlotActionMode cartesianPlotActionMode()
Definition: Worksheet.cpp:449
void setSelectedInView(const bool)
Definition: Worksheet.cpp:377
void layoutChanged(Worksheet::Layout)
void setPrinting(bool) const
Definition: Worksheet.cpp:717
void itemSelected(QGraphicsItem *)
static double convertFromSceneUnits(const double value, const Worksheet::Unit unit)
Definition: Worksheet.cpp:131
void setPlotsLocked(bool)
Definition: Worksheet.cpp:491
void itemDeselected(QGraphicsItem *)
void requestProjectContextMenu(QMenu *)
void requestUpdate()
void setPageRect(const QRectF &)
Definition: Worksheet.cpp:697
void deleteAspectFromGraphicsItem(const QGraphicsItem *)
Definition: Worksheet.cpp:384
void setCartesianPlotCursorMode(CartesianPlotActionMode mode)
Definition: Worksheet.cpp:469
void setItemSelectedInView(const QGraphicsItem *, const bool)
Definition: Worksheet.cpp:335
void setTheme(const QString &)
Definition: Worksheet.cpp:724
bool plotsLocked()
Definition: Worksheet.cpp:457
CartesianPlotActionMode
Definition: Worksheet.h:55
static double convertToSceneUnits(const double value, const Worksheet::Unit unit)
Definition: Worksheet.cpp:113
#define RESET_CURSOR
Definition: macros.h:64
#define DEBUG(x)
Definition: macros.h:50
#define i18n(m)
Definition: nsl_common.h:38