File indexing completed on 2024-05-12 03:48:25
0001 /* 0002 File : DatapickerView.cpp 0003 Project : LabPlot 0004 Description : View class for Datapicker 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2015 Ankit Wagadre <wagadre.ankit@gmail.com> 0007 SPDX-FileCopyrightText: 2015-2021 Alexander Semke <alexander.semke@web.de> 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #include "DatapickerView.h" 0013 #include "backend/datapicker/Datapicker.h" 0014 #include "backend/datapicker/DatapickerCurve.h" 0015 #include "backend/datapicker/DatapickerImage.h" 0016 #include "backend/lib/macros.h" 0017 #include "backend/spreadsheet/Spreadsheet.h" 0018 #include "commonfrontend/datapicker/DatapickerImageView.h" 0019 #include "commonfrontend/workbook/WorkbookView.h" 0020 0021 #include <QHBoxLayout> 0022 #include <QMenu> 0023 #include <QTabBar> 0024 #include <QTabWidget> 0025 0026 #include <KLocalizedString> 0027 0028 /*! 0029 \class DatapickerView 0030 \brief View class for Datapicker 0031 0032 \ingroup commonfrontend 0033 */ 0034 DatapickerView::DatapickerView(Datapicker* datapicker) 0035 : QWidget() 0036 , m_tabWidget(new QTabWidget(this)) 0037 , m_datapicker(datapicker) { 0038 m_tabWidget->setTabPosition(QTabWidget::South); 0039 m_tabWidget->setTabShape(QTabWidget::Rounded); 0040 // m_tabWidget->setMovable(true); 0041 m_tabWidget->setContextMenuPolicy(Qt::CustomContextMenu); 0042 0043 auto* layout = new QHBoxLayout(this); 0044 layout->setContentsMargins(0, 0, 0, 0); 0045 layout->addWidget(m_tabWidget); 0046 0047 // add tab for each children view 0048 m_initializing = true; 0049 for (const auto* aspect : m_datapicker->children<AbstractAspect>(AbstractAspect::ChildIndexFlag::IncludeHidden)) { 0050 handleAspectAdded(aspect); 0051 for (const auto* child : aspect->children<AbstractAspect>()) 0052 handleAspectAdded(child); 0053 } 0054 m_initializing = false; 0055 0056 if (!m_datapicker->isLoading()) { 0057 const auto& size = m_datapicker->image()->view()->size(); 0058 resize(size.width() * 1.1, size.height() * 1.1); 0059 } 0060 0061 // SIGNALs/SLOTs 0062 connect(m_datapicker, &Datapicker::aspectDescriptionChanged, this, &DatapickerView::handleDescriptionChanged); 0063 connect(m_datapicker, &Datapicker::childAspectAdded, this, &DatapickerView::handleAspectAdded); 0064 connect(m_datapicker, &Datapicker::childAspectAboutToBeRemoved, this, &DatapickerView::handleAspectAboutToBeRemoved); 0065 connect(m_datapicker, &Datapicker::datapickerItemSelected, this, &DatapickerView::itemSelected); 0066 0067 connect(m_tabWidget, &QTabWidget::currentChanged, this, &DatapickerView::tabChanged); 0068 connect(m_tabWidget, &QTabWidget::customContextMenuRequested, this, &DatapickerView::showTabContextMenu); 0069 connect(m_tabWidget->tabBar(), &QTabBar::tabMoved, this, &DatapickerView::tabMoved); 0070 } 0071 0072 DatapickerView::~DatapickerView() { 0073 // delete all children views here, its own view will be deleted in ~AbstractPart() 0074 for (const auto* aspect : m_datapicker->children<AbstractAspect>(AbstractAspect::ChildIndexFlag::IncludeHidden)) { 0075 for (const auto* child : aspect->children<AbstractAspect>()) { 0076 const auto* part = dynamic_cast<const AbstractPart*>(child); 0077 if (part) 0078 part->deleteView(); 0079 } 0080 const auto* part = dynamic_cast<const AbstractPart*>(aspect); 0081 if (part) 0082 part->deleteView(); 0083 } 0084 } 0085 0086 void DatapickerView::fillToolBar(QToolBar* toolBar) { 0087 auto* view = static_cast<DatapickerImageView*>(m_datapicker->image()->view()); 0088 view->fillToolBar(toolBar); 0089 } 0090 0091 void DatapickerView::createContextMenu(QMenu* menu) const { 0092 Q_ASSERT(menu); 0093 m_datapicker->image()->createContextMenu(menu); 0094 } 0095 0096 int DatapickerView::currentIndex() const { 0097 return m_tabWidget->currentIndex(); 0098 } 0099 0100 // ############################################################################## 0101 // ######################### Private slots #################################### 0102 // ############################################################################## 0103 /*! 0104 called when the current tab was changed. Propagates the selection of \c Spreadsheet 0105 or of a \c DatapickerImage object to \c Datapicker. 0106 */ 0107 void DatapickerView::tabChanged(int index) { 0108 if (m_initializing || index == -1) 0109 return; 0110 0111 m_datapicker->setChildSelectedInView(lastSelectedIndex, false); 0112 m_datapicker->setChildSelectedInView(index, true); 0113 lastSelectedIndex = index; 0114 } 0115 0116 void DatapickerView::tabMoved(int /*from*/, int /*to*/) { 0117 // TODO: 0118 // AbstractAspect* aspect = m_datapicker->child<AbstractAspect>(to); 0119 // if (aspect) { 0120 // m_tabMoving = true; 0121 // AbstractAspect* sibling = m_datapicker->child<AbstractAspect>(from); 0122 // qDebug()<<"insert: " << to << " " << aspect->name() << ", " << from << " " << sibling->name(); 0123 // aspect->remove(); 0124 // m_datapicker->insertChildBefore(aspect, sibling); 0125 // qDebug()<<"inserted"; 0126 // m_tabMoving = false; 0127 // } 0128 } 0129 0130 void DatapickerView::itemSelected(int index) { 0131 m_initializing = true; 0132 m_tabWidget->setCurrentIndex(index); 0133 m_initializing = false; 0134 } 0135 0136 void DatapickerView::showTabContextMenu(QPoint point) { 0137 QMenu* menu = nullptr; 0138 auto* aspect = m_datapicker->child<AbstractAspect>(m_tabWidget->currentIndex(), AbstractAspect::ChildIndexFlag::IncludeHidden); 0139 auto* spreadsheet = dynamic_cast<Spreadsheet*>(aspect); 0140 if (spreadsheet) { 0141 menu = spreadsheet->createContextMenu(); 0142 } else { 0143 auto* image = dynamic_cast<DatapickerImage*>(aspect); 0144 if (image) 0145 menu = image->createContextMenu(); 0146 } 0147 0148 if (menu) 0149 menu->exec(m_tabWidget->mapToGlobal(point)); 0150 } 0151 0152 /*! 0153 * handle the renames of child aspects to adjust the names of the tabs accordingly. 0154 */ 0155 void DatapickerView::handleDescriptionChanged(const AbstractAspect* aspect) { 0156 // nothing to do if the parent itself was renamed, we only need to handle curves and data spreadsheets. 0157 if (aspect == m_datapicker || aspect == m_datapicker->image()) 0158 return; 0159 0160 // determine the child that was changed and adjust the name of the corresponding tab widget 0161 int index = -1; 0162 QString name; 0163 if (aspect->parentAspect() == m_datapicker) { 0164 // datapicker curve was renamed 0165 index = m_datapicker->indexOfChild<AbstractAspect>(aspect, AbstractAspect::ChildIndexFlag::IncludeHidden); 0166 if (index != -1) 0167 name = aspect->name() + QStringLiteral(": ") + aspect->children<Spreadsheet>().constFirst()->name(); 0168 } else { 0169 // data spreadsheet was renamed or one of its columns, which is not relevant here 0170 index = m_datapicker->indexOfChild<AbstractAspect>(aspect->parentAspect(), AbstractAspect::ChildIndexFlag::IncludeHidden); 0171 if (index != -1) 0172 name = aspect->parentAspect()->name() + QStringLiteral(": ") + aspect->name(); 0173 } 0174 0175 if (index != -1) 0176 m_tabWidget->setTabText(index, name); 0177 } 0178 0179 void DatapickerView::handleAspectAdded(const AbstractAspect* aspect) { 0180 int index = 0; 0181 QString name; 0182 const AbstractPart* part = dynamic_cast<const DatapickerImage*>(aspect); 0183 if (part) { 0184 name = aspect->name(); 0185 } else if (dynamic_cast<const DatapickerCurve*>(aspect)) { 0186 index = m_datapicker->indexOfChild<AbstractAspect>(aspect, AbstractAspect::ChildIndexFlag::IncludeHidden); 0187 const auto* spreadsheet = static_cast<const Spreadsheet*>(aspect->child<AbstractAspect>(0)); 0188 part = spreadsheet; 0189 name = aspect->name() + QStringLiteral(": ") + spreadsheet->name(); 0190 } else 0191 return; 0192 0193 m_tabWidget->insertTab(index, part->view(), name); 0194 m_tabWidget->setTabIcon(m_tabWidget->count(), aspect->icon()); 0195 } 0196 0197 void DatapickerView::handleAspectAboutToBeRemoved(const AbstractAspect* aspect) { 0198 const auto* curve = dynamic_cast<const DatapickerCurve*>(aspect); 0199 if (curve) { 0200 int index = m_datapicker->indexOfChild<AbstractAspect>(aspect, AbstractAspect::ChildIndexFlag::IncludeHidden); 0201 m_tabWidget->removeTab(index); 0202 } 0203 }