File indexing completed on 2024-05-12 11:41:17
0001 /* 0002 File : GuiObserver.cpp 0003 Project : LabPlot 0004 Description : GUI observer 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2010-2023 Alexander Semke <alexander.semke@web.de> 0007 SPDX-FileCopyrightText: 2015-2018 Stefan Gerlach <stefan.gerlach@uni.kn> 0008 SPDX-FileCopyrightText: 2016 Garvit Khatri <garvitdelhi@gmail.com> 0009 0010 SPDX-License-Identifier: GPL-2.0-or-later 0011 */ 0012 0013 #include "kdefrontend/GuiObserver.h" 0014 #include "backend/core/AbstractAspect.h" 0015 #include "backend/core/AspectTreeModel.h" 0016 #include "backend/datasources/LiveDataSource.h" 0017 #include "backend/matrix/Matrix.h" 0018 #include "backend/spreadsheet/Spreadsheet.h" 0019 #include "backend/spreadsheet/StatisticsSpreadsheet.h" 0020 #include "backend/worksheet/Image.h" 0021 #include "backend/worksheet/InfoElement.h" 0022 #include "backend/worksheet/TextLabel.h" 0023 #include "backend/worksheet/Worksheet.h" 0024 #include "backend/worksheet/plots/cartesian/Axis.h" 0025 #include "backend/worksheet/plots/cartesian/BarPlot.h" 0026 #include "backend/worksheet/plots/cartesian/BoxPlot.h" 0027 #include "backend/worksheet/plots/cartesian/CartesianPlot.h" 0028 #include "backend/worksheet/plots/cartesian/CartesianPlotLegend.h" 0029 #include "backend/worksheet/plots/cartesian/CustomPoint.h" 0030 #include "backend/worksheet/plots/cartesian/Histogram.h" 0031 #include "backend/worksheet/plots/cartesian/KDEPlot.h" 0032 #include "backend/worksheet/plots/cartesian/QQPlot.h" 0033 #include "backend/worksheet/plots/cartesian/ReferenceLine.h" 0034 #include "backend/worksheet/plots/cartesian/XYCurve.h" 0035 #ifdef HAVE_CANTOR_LIBS 0036 #include "backend/cantorWorksheet/CantorWorksheet.h" 0037 #endif 0038 #ifdef HAVE_MQTT 0039 #include "backend/datasources/MQTTClient.h" 0040 #include "backend/datasources/MQTTSubscription.h" 0041 #include "backend/datasources/MQTTTopic.h" 0042 #endif 0043 #include "backend/core/Project.h" 0044 #include "backend/datapicker/Datapicker.h" 0045 #include "backend/datapicker/DatapickerCurve.h" 0046 #include "backend/datapicker/DatapickerImage.h" 0047 #include "commonfrontend/ProjectExplorer.h" 0048 #include "kdefrontend/MainWin.h" 0049 #include "kdefrontend/dockwidgets/AspectDock.h" 0050 #include "kdefrontend/dockwidgets/AxisDock.h" 0051 #include "kdefrontend/dockwidgets/BarPlotDock.h" 0052 #include "kdefrontend/dockwidgets/BoxPlotDock.h" 0053 #include "kdefrontend/dockwidgets/CartesianPlotDock.h" 0054 #include "kdefrontend/dockwidgets/CartesianPlotLegendDock.h" 0055 #include "kdefrontend/dockwidgets/ColumnDock.h" 0056 #include "kdefrontend/dockwidgets/CursorDock.h" 0057 #include "kdefrontend/dockwidgets/CustomPointDock.h" 0058 #include "kdefrontend/dockwidgets/HistogramDock.h" 0059 #include "kdefrontend/dockwidgets/ImageDock.h" 0060 #include "kdefrontend/dockwidgets/InfoElementDock.h" 0061 #include "kdefrontend/dockwidgets/KDEPlotDock.h" 0062 #include "kdefrontend/dockwidgets/LiveDataDock.h" 0063 #include "kdefrontend/dockwidgets/LollipopPlotDock.h" 0064 #include "kdefrontend/dockwidgets/MatrixDock.h" 0065 #include "kdefrontend/dockwidgets/NoteDock.h" 0066 #include "kdefrontend/dockwidgets/ProjectDock.h" 0067 #include "kdefrontend/dockwidgets/QQPlotDock.h" 0068 #include "kdefrontend/dockwidgets/ReferenceLineDock.h" 0069 #include "kdefrontend/dockwidgets/ReferenceRangeDock.h" 0070 #include "kdefrontend/dockwidgets/SpreadsheetDock.h" 0071 #include "kdefrontend/dockwidgets/StatisticsSpreadsheetDock.h" 0072 #include "kdefrontend/dockwidgets/WorksheetDock.h" 0073 #include "kdefrontend/dockwidgets/XYConvolutionCurveDock.h" 0074 #include "kdefrontend/dockwidgets/XYCorrelationCurveDock.h" 0075 #include "kdefrontend/dockwidgets/XYCurveDock.h" 0076 #include "kdefrontend/dockwidgets/XYDataReductionCurveDock.h" 0077 #include "kdefrontend/dockwidgets/XYDifferentiationCurveDock.h" 0078 #include "kdefrontend/dockwidgets/XYEquationCurveDock.h" 0079 #include "kdefrontend/dockwidgets/XYFitCurveDock.h" 0080 #include "kdefrontend/dockwidgets/XYFourierFilterCurveDock.h" 0081 #include "kdefrontend/dockwidgets/XYFourierTransformCurveDock.h" 0082 #include "kdefrontend/dockwidgets/XYHilbertTransformCurveDock.h" 0083 #include "kdefrontend/dockwidgets/XYIntegrationCurveDock.h" 0084 #include "kdefrontend/dockwidgets/XYInterpolationCurveDock.h" 0085 #include "kdefrontend/dockwidgets/XYSmoothCurveDock.h" 0086 #ifdef HAVE_CANTOR_LIBS 0087 #include "kdefrontend/dockwidgets/CantorWorksheetDock.h" 0088 #endif 0089 #include "kdefrontend/widgets/DatapickerCurveWidget.h" 0090 #include "kdefrontend/widgets/DatapickerImageWidget.h" 0091 #include "kdefrontend/widgets/LabelWidget.h" 0092 0093 #include <DockWidget.h> 0094 #include <KLocalizedString> 0095 #include <QStackedWidget> 0096 #include <QStatusBar> 0097 #include <QToolBar> 0098 0099 /*! 0100 \class GuiObserver 0101 \brief The GUI observer looks for the selection changes in the main window 0102 and shows/hides the correspondings dock widgets, toolbars etc. 0103 This class is intended to simplify (or not to overload) the code in MainWin. 0104 0105 \ingroup kdefrontend 0106 */ 0107 0108 QVector<BaseDock*> initializedDocks; 0109 0110 namespace GuiObserverHelper { 0111 0112 template<class T> 0113 bool raiseDock(T*& dock, QStackedWidget* parent) { 0114 Q_ASSERT(parent); 0115 DEBUG(Q_FUNC_INFO << ", number of stacked widgets = " << parent->count()) 0116 0117 const bool generated = !dock; 0118 if (generated) { 0119 dock = new T(parent); 0120 initializedDocks << dock; 0121 parent->addWidget(dock); 0122 } 0123 0124 // see https://wiki.qt.io/Technical_FAQ#How_can_I_get_a_QStackedWidget_to_automatically_switch_size_depending_on_the_content_of_the_page 0125 if (parent->currentWidget()) 0126 parent->currentWidget()->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); 0127 parent->setCurrentWidget(dock); 0128 parent->currentWidget()->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0129 0130 // scroll the scroll area up to the top 0131 if (parent->parent() && parent->parent()->parent()) { 0132 auto* scrollArea = dynamic_cast<QScrollArea*>(parent->parent()->parent()); 0133 if (scrollArea) 0134 scrollArea->ensureVisible(0, 0); 0135 } 0136 return generated; 0137 } 0138 0139 template<class T> 0140 void raiseDockConnect(T*& dock, QStatusBar* statusBar, QStackedWidget* parent) { 0141 if (raiseDock(dock, parent)) 0142 QObject::connect(dock, &T::info, [=](const QString& text) { 0143 statusBar->showMessage(text); 0144 }); 0145 } 0146 0147 template<class T> 0148 void raiseDockSetupConnect(T*& dock, QStatusBar* statusBar, QStackedWidget* parent) { 0149 if (raiseDock(dock, parent)) { 0150 dock->setupGeneral(); 0151 QObject::connect(dock, &T::info, [=](const QString& text) { 0152 statusBar->showMessage(text); 0153 }); 0154 } 0155 } 0156 0157 template<class T> 0158 QList<T*> castList(const QList<AbstractAspect*>& selectedAspects) { 0159 QList<T*> list; 0160 for (auto* aspect : selectedAspects) 0161 list << static_cast<T*>(aspect); 0162 return list; 0163 } 0164 0165 } // namespace GuiObserverHelper 0166 0167 using namespace GuiObserverHelper; 0168 0169 GuiObserver::GuiObserver(MainWin* mainWin) 0170 : m_mainWindow(mainWin) { 0171 connect(mainWin->m_projectExplorer, &ProjectExplorer::selectedAspectsChanged, this, &GuiObserver::selectedAspectsChanged); 0172 connect(mainWin->m_projectExplorer, &ProjectExplorer::hiddenAspectSelected, this, &GuiObserver::hiddenAspectSelected); 0173 } 0174 0175 GuiObserver::~GuiObserver() { 0176 while (!initializedDocks.isEmpty()) 0177 delete initializedDocks.takeLast(); 0178 } 0179 0180 /*! 0181 called on selection changes in the project explorer. 0182 Determines the type of the currently selected objects (aspects) 0183 and activates the corresponding dockwidgets, toolbars etc. 0184 */ 0185 void GuiObserver::selectedAspectsChanged(const QList<AbstractAspect*>& selectedAspects) { 0186 auto clearDock = [&]() { 0187 if (m_mainWindow->stackedWidget->currentWidget()) 0188 m_mainWindow->stackedWidget->currentWidget()->hide(); 0189 0190 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties")); 0191 }; 0192 0193 if (selectedAspects.isEmpty() || selectedAspects.front() == nullptr) { 0194 clearDock(); 0195 return; 0196 } 0197 0198 const AspectType type{selectedAspects.front()->type()}; 0199 DEBUG(Q_FUNC_INFO << ", type: " << STDSTRING(AbstractAspect::typeName(type))) 0200 0201 // update cursor dock 0202 if (m_mainWindow->cursorWidget) { 0203 if (type == AspectType::Worksheet) { 0204 auto* worksheet = static_cast<Worksheet*>(selectedAspects.front()); 0205 m_mainWindow->cursorWidget->setWorksheet(worksheet); 0206 } else { 0207 auto* parent = selectedAspects.front()->parent(AspectType::Worksheet); 0208 if (parent) { 0209 auto* worksheet = static_cast<Worksheet*>(parent); 0210 m_mainWindow->cursorWidget->setWorksheet(worksheet); 0211 } 0212 } 0213 } 0214 0215 // Check, whether objects of different types were selected. 0216 // Don't show any dock widgets in this case. 0217 for (const auto* aspect : selectedAspects) { 0218 if (aspect->type() != type) { 0219 clearDock(); 0220 return; 0221 } 0222 } 0223 0224 switch (type) { 0225 case AspectType::Spreadsheet: 0226 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Spreadsheet")); 0227 raiseDockConnect(m_spreadsheetDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0228 m_spreadsheetDock->setSpreadsheets(castList<Spreadsheet>(selectedAspects)); 0229 break; 0230 case AspectType::StatisticsSpreadsheet: 0231 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Column Statistics")); 0232 raiseDockConnect(m_statisticsSpreadsheetDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0233 m_statisticsSpreadsheetDock->setSpreadsheets(castList<StatisticsSpreadsheet>(selectedAspects)); 0234 break; 0235 case AspectType::Column: { 0236 #ifdef HAVE_CANTOR_LIBS 0237 auto* casParent = dynamic_cast<CantorWorksheet*>(selectedAspects.first()->parentAspect()); 0238 if (casParent) { 0239 // a column from a CAS-worksheets was selected, show the dock widget for the CAS worksheet 0240 raiseDockConnect(m_cantorWorksheetDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0241 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window %1 is a Cantor backend", "%1 Worksheet", casParent->backendName())); 0242 m_cantorWorksheetDock->setCantorWorksheets(QList<CantorWorksheet*>{casParent}); 0243 } else 0244 #endif 0245 { 0246 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Column")); 0247 raiseDockConnect(m_columnDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0248 m_columnDock->setColumns(castList<Column>(selectedAspects)); 0249 } 0250 break; 0251 } 0252 case AspectType::Matrix: 0253 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Matrix")); 0254 raiseDockConnect(m_matrixDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0255 m_matrixDock->setMatrices(castList<Matrix>(selectedAspects)); 0256 break; 0257 case AspectType::Worksheet: { 0258 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Worksheet")); 0259 raiseDockConnect(m_worksheetDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0260 m_worksheetDock->setWorksheets(castList<Worksheet>(selectedAspects)); 0261 break; 0262 } 0263 case AspectType::CartesianPlot: { 0264 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Plot Area")); 0265 raiseDockConnect(m_cartesianPlotDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0266 m_cartesianPlotDock->setPlots(castList<CartesianPlot>(selectedAspects)); 0267 break; 0268 } 0269 case AspectType::CartesianPlotLegend: 0270 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Legend")); 0271 raiseDockConnect(m_cartesianPlotLegendDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0272 m_cartesianPlotLegendDock->setLegends(castList<CartesianPlotLegend>(selectedAspects)); 0273 break; 0274 case AspectType::Axis: 0275 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Axis")); 0276 raiseDockConnect(m_axisDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0277 m_axisDock->setAxes(castList<Axis>(selectedAspects)); 0278 break; 0279 case AspectType::XYCurve: 0280 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: XY-Curve")); 0281 raiseDockSetupConnect(m_xyCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0282 m_xyCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0283 break; 0284 case AspectType::XYEquationCurve: 0285 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: XY-Equation")); 0286 raiseDockSetupConnect(m_xyEquationCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0287 m_xyEquationCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0288 break; 0289 case AspectType::XYDataReductionCurve: 0290 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Data Reduction")); 0291 if (!m_xyDataReductionCurveDock) { 0292 m_xyDataReductionCurveDock = new XYDataReductionCurveDock(m_mainWindow->stackedWidget, m_mainWindow->statusBar()); 0293 m_xyDataReductionCurveDock->setupGeneral(); 0294 connect(m_xyDataReductionCurveDock, &XYDataReductionCurveDock::info, [&](const QString& text) { 0295 m_mainWindow->statusBar()->showMessage(text); 0296 }); 0297 m_mainWindow->stackedWidget->addWidget(m_xyDataReductionCurveDock); 0298 } 0299 0300 initializedDocks << m_xyDataReductionCurveDock; 0301 m_xyDataReductionCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0302 0303 m_mainWindow->stackedWidget->setCurrentWidget(m_xyDataReductionCurveDock); 0304 break; 0305 case AspectType::XYDifferentiationCurve: 0306 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Differentiation")); 0307 raiseDockSetupConnect(m_xyDifferentiationCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0308 m_xyDifferentiationCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0309 break; 0310 case AspectType::XYIntegrationCurve: 0311 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Integration")); 0312 raiseDockSetupConnect(m_xyIntegrationCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0313 m_xyIntegrationCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0314 break; 0315 case AspectType::XYInterpolationCurve: 0316 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Interpolation")); 0317 raiseDockSetupConnect(m_xyInterpolationCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0318 m_xyInterpolationCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0319 break; 0320 case AspectType::XYSmoothCurve: 0321 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Smoothing")); 0322 raiseDockSetupConnect(m_xySmoothCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0323 m_xySmoothCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0324 break; 0325 case AspectType::XYFitCurve: 0326 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Fit")); 0327 raiseDockSetupConnect(m_xyFitCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0328 m_xyFitCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0329 break; 0330 case AspectType::XYFourierTransformCurve: 0331 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Fourier Transform")); 0332 raiseDockSetupConnect(m_xyFourierTransformCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0333 m_xyFourierTransformCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0334 break; 0335 case AspectType::XYHilbertTransformCurve: 0336 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Hilbert Transform")); 0337 raiseDockSetupConnect(m_xyHilbertTransformCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0338 m_xyHilbertTransformCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0339 break; 0340 case AspectType::XYFourierFilterCurve: 0341 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Fourier Filter")); 0342 raiseDockSetupConnect(m_xyFourierFilterCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0343 m_xyFourierFilterCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0344 break; 0345 case AspectType::XYConvolutionCurve: 0346 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Convolution/Deconvolution")); 0347 raiseDockSetupConnect(m_xyConvolutionCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0348 m_xyConvolutionCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0349 break; 0350 case AspectType::XYCorrelationCurve: 0351 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Auto-/Cross-Correlation")); 0352 raiseDockSetupConnect(m_xyCorrelationCurveDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0353 m_xyCorrelationCurveDock->setCurves(castList<XYCurve>(selectedAspects)); 0354 break; 0355 case AspectType::Histogram: 0356 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Histogram")); 0357 raiseDockConnect(m_histogramDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0358 m_histogramDock->setCurves(castList<Histogram>(selectedAspects)); 0359 break; 0360 case AspectType::BarPlot: 0361 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Bar Plot")); 0362 raiseDock(m_barPlotDock, m_mainWindow->stackedWidget); 0363 m_barPlotDock->setBarPlots(castList<BarPlot>(selectedAspects)); 0364 break; 0365 case AspectType::LollipopPlot: 0366 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Lollipop Plot")); 0367 raiseDock(m_lollipopPlotDock, m_mainWindow->stackedWidget); 0368 m_lollipopPlotDock->setPlots(castList<LollipopPlot>(selectedAspects)); 0369 break; 0370 case AspectType::BoxPlot: 0371 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Box Plot")); 0372 raiseDock(m_boxPlotDock, m_mainWindow->stackedWidget); 0373 m_boxPlotDock->setBoxPlots(castList<BoxPlot>(selectedAspects)); 0374 break; 0375 case AspectType::KDEPlot: 0376 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "KDE Plot")); 0377 raiseDock(m_kdePlotDock, m_mainWindow->stackedWidget); 0378 m_kdePlotDock->setPlots(castList<KDEPlot>(selectedAspects)); 0379 break; 0380 case AspectType::QQPlot: 0381 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Q-Q Plot")); 0382 raiseDock(m_qqPlotDock, m_mainWindow->stackedWidget); 0383 m_qqPlotDock->setPlots(castList<QQPlot>(selectedAspects)); 0384 break; 0385 case AspectType::TextLabel: 0386 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Text Label")); 0387 raiseDock(m_textLabelDock, m_mainWindow->stackedWidget); 0388 m_textLabelDock->setLabels(castList<TextLabel>(selectedAspects)); 0389 break; 0390 case AspectType::Image: 0391 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Image")); 0392 raiseDock(m_imageDock, m_mainWindow->stackedWidget); 0393 m_imageDock->setImages(castList<Image>(selectedAspects)); 0394 break; 0395 case AspectType::CustomPoint: 0396 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Custom Point")); 0397 raiseDock(m_customPointDock, m_mainWindow->stackedWidget); 0398 m_customPointDock->setPoints(castList<CustomPoint>(selectedAspects)); 0399 break; 0400 case AspectType::ReferenceLine: 0401 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Reference Line")); 0402 raiseDock(m_referenceLineDock, m_mainWindow->stackedWidget); 0403 m_referenceLineDock->setReferenceLines(castList<ReferenceLine>(selectedAspects)); 0404 break; 0405 case AspectType::ReferenceRange: 0406 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Reference Range")); 0407 raiseDock(m_referenceRangeDock, m_mainWindow->stackedWidget); 0408 m_referenceRangeDock->setReferenceRanges(castList<ReferenceRange>(selectedAspects)); 0409 break; 0410 case AspectType::DatapickerCurve: 0411 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Datapicker Curve")); 0412 raiseDock(m_datapickerCurveDock, m_mainWindow->stackedWidget); 0413 m_datapickerCurveDock->setCurves(castList<DatapickerCurve>(selectedAspects)); 0414 break; 0415 case AspectType::Datapicker: 0416 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Data Extractor")); 0417 raiseDock(m_datapickerImageDock, m_mainWindow->stackedWidget); 0418 { 0419 QList<DatapickerImage*> list; 0420 for (auto* aspect : selectedAspects) 0421 list << static_cast<Datapicker*>(aspect)->image(); 0422 m_datapickerImageDock->setImages(list); 0423 } 0424 break; 0425 case AspectType::Project: 0426 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Project")); 0427 raiseDock(m_projectDock, m_mainWindow->stackedWidget); 0428 m_projectDock->setProject(m_mainWindow->m_project); 0429 break; 0430 case AspectType::CantorWorksheet: 0431 #ifdef HAVE_CANTOR_LIBS 0432 raiseDockConnect(m_cantorWorksheetDock, m_mainWindow->statusBar(), m_mainWindow->stackedWidget); 0433 { 0434 auto list = castList<CantorWorksheet>(selectedAspects); 0435 if (list.size() == 1) 0436 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window %1 is a Cantor backend", "%1 Notebook", list.first()->backendName())); 0437 else 0438 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Notebook")); 0439 m_cantorWorksheetDock->setCantorWorksheets(list); 0440 } 0441 #endif 0442 break; 0443 case AspectType::Note: 0444 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Notes")); 0445 raiseDock(m_notesDock, m_mainWindow->stackedWidget); 0446 m_notesDock->setNotesList(castList<Note>(selectedAspects)); 0447 break; 0448 case AspectType::InfoElement: { 0449 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Info Element")); 0450 raiseDock(m_infoElementDock, m_mainWindow->stackedWidget); 0451 m_infoElementDock->setInfoElements(castList<InfoElement>(selectedAspects)); 0452 break; 0453 } 0454 case AspectType::MQTTClient: 0455 #ifdef HAVE_MQTT 0456 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: MQTT Data Source")); 0457 raiseDock(m_liveDataDock, m_mainWindow->stackedWidget); 0458 m_liveDataDock->setMQTTClient(static_cast<MQTTClient*>(selectedAspects.first())); 0459 #endif 0460 break; 0461 case AspectType::MQTTSubscription: 0462 #ifdef HAVE_MQTT 0463 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: MQTT Data Source")); 0464 raiseDock(m_liveDataDock, m_mainWindow->stackedWidget); 0465 m_liveDataDock->setMQTTClient(static_cast<MQTTSubscription*>(selectedAspects.first())->mqttClient()); 0466 #endif 0467 break; 0468 case AspectType::MQTTTopic: 0469 #ifdef HAVE_MQTT 0470 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: MQTT Data Source")); 0471 raiseDock(m_liveDataDock, m_mainWindow->stackedWidget); 0472 m_liveDataDock->setMQTTClient(static_cast<MQTTTopic*>(selectedAspects.first())->mqttClient()); 0473 #endif 0474 break; 0475 case AspectType::LiveDataSource: 0476 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Live Data Source")); 0477 raiseDock(m_liveDataDock, m_mainWindow->stackedWidget); 0478 m_liveDataDock->setLiveDataSource(static_cast<LiveDataSource*>(selectedAspects.first())); 0479 break; 0480 case AspectType::AbstractAspect: 0481 case AspectType::AbstractColumn: 0482 case AspectType::AbstractDataSource: 0483 case AspectType::AbstractFilter: 0484 case AspectType::AbstractPart: 0485 case AspectType::AbstractPlot: 0486 case AspectType::ColumnStringIO: 0487 case AspectType::DatapickerImage: 0488 case AspectType::DatapickerPoint: 0489 case AspectType::Folder: 0490 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Folder")); 0491 raiseDock(m_aspectDock, m_mainWindow->stackedWidget); 0492 m_aspectDock->setAspects(selectedAspects); 0493 break; 0494 case AspectType::PlotArea: 0495 case AspectType::SimpleFilterColumn: 0496 case AspectType::Workbook: 0497 m_mainWindow->m_propertiesDock->setWindowTitle(i18nc("@title:window", "Properties: Workbook")); 0498 raiseDock(m_aspectDock, m_mainWindow->stackedWidget); 0499 m_aspectDock->setAspects(selectedAspects); 0500 break; 0501 case AspectType::WorksheetElement: 0502 case AspectType::WorksheetElementContainer: 0503 case AspectType::WorksheetElementGroup: 0504 case AspectType::XYAnalysisCurve: 0505 clearDock(); 0506 return; 0507 } 0508 0509 m_mainWindow->stackedWidget->currentWidget()->show(); 0510 } 0511 0512 /*! 0513 handles the selection of a hidden aspect \c aspect in the view (relevant for WorksheetView only at the moment). 0514 Currently, a hidden aspect can only be a plot title lable or an axis label. 0515 -> Activate the corresponding DockWidget and make the title tab current. 0516 */ 0517 void GuiObserver::hiddenAspectSelected(const AbstractAspect* aspect) { 0518 const AbstractAspect* parent = aspect->parentAspect(); 0519 if (!parent) 0520 return; 0521 0522 switch (static_cast<quint64>(parent->type())) { // cast the enum to turn off warnings about unhandled cases 0523 case static_cast<quint64>(AspectType::Axis): 0524 if (!m_axisDock) { 0525 m_axisDock = new AxisDock(m_mainWindow->stackedWidget); 0526 initializedDocks << m_axisDock; 0527 m_mainWindow->stackedWidget->addWidget(m_axisDock); 0528 } 0529 m_axisDock->activateTitleTab(); 0530 break; 0531 case static_cast<quint64>(AspectType::CartesianPlot): 0532 if (!m_cartesianPlotDock) { 0533 m_cartesianPlotDock = new CartesianPlotDock(m_mainWindow->stackedWidget); 0534 initializedDocks << m_cartesianPlotDock; 0535 m_mainWindow->stackedWidget->addWidget(m_cartesianPlotDock); 0536 } 0537 m_cartesianPlotDock->activateTitleTab(); 0538 break; 0539 case static_cast<quint64>(AspectType::CartesianPlotLegend): 0540 if (!m_cartesianPlotLegendDock) { 0541 m_cartesianPlotLegendDock = new CartesianPlotLegendDock(m_mainWindow->stackedWidget); 0542 initializedDocks << m_cartesianPlotLegendDock; 0543 m_mainWindow->stackedWidget->addWidget(m_cartesianPlotLegendDock); 0544 } 0545 m_cartesianPlotLegendDock->activateTitleTab(); 0546 break; 0547 default: 0548 break; 0549 } 0550 }