File indexing completed on 2024-05-12 03:48:30
0001 /* 0002 File : WorkbookView.cpp 0003 Project : LabPlot 0004 Description : View class for Workbook 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2015-2020 Alexander Semke <alexander.semke@web.de> 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "WorkbookView.h" 0011 #include "backend/core/AbstractAspect.h" 0012 #include "backend/core/AbstractPart.h" 0013 #include "backend/core/Workbook.h" 0014 #include "backend/lib/macros.h" 0015 #include "backend/matrix/Matrix.h" 0016 #include "backend/spreadsheet/Spreadsheet.h" 0017 0018 #include <QHBoxLayout> 0019 #include <QMenu> 0020 #include <QTabBar> 0021 #include <QTabWidget> 0022 0023 #include <KLocalizedString> 0024 0025 /*! 0026 \class WorkbookView 0027 \brief View class for Workbook 0028 0029 \ingroup commonfrontend 0030 */ 0031 WorkbookView::WorkbookView(Workbook* workbook) 0032 : QWidget() 0033 , m_tabWidget(new QTabWidget(this)) 0034 , m_workbook(workbook) { 0035 m_tabWidget->setTabPosition(QTabWidget::South); 0036 m_tabWidget->setTabShape(QTabWidget::Rounded); 0037 // m_tabWidget->setMovable(true); 0038 m_tabWidget->setContextMenuPolicy(Qt::CustomContextMenu); 0039 m_tabWidget->setMinimumSize(200, 200); 0040 0041 auto* layout = new QHBoxLayout(this); 0042 layout->setContentsMargins(0, 0, 0, 0); 0043 layout->addWidget(m_tabWidget); 0044 0045 // add tab for each children view 0046 m_initializing = true; 0047 for (const auto* aspect : m_workbook->children<AbstractAspect>()) 0048 handleAspectAdded(aspect); 0049 m_initializing = false; 0050 0051 // Actions 0052 action_add_spreadsheet = new QAction(QIcon::fromTheme(QStringLiteral("labplot-spreadsheet")), i18n("Spreadsheet"), this); 0053 action_add_matrix = new QAction(QIcon::fromTheme(QStringLiteral("labplot-matrix")), i18n("Matrix"), this); 0054 connect(action_add_spreadsheet, &QAction::triggered, this, &WorkbookView::addSpreadsheet); 0055 connect(action_add_matrix, &QAction::triggered, this, &WorkbookView::addMatrix); 0056 0057 // SIGNALs/SLOTs 0058 connect(m_workbook, &Workbook::aspectDescriptionChanged, this, &WorkbookView::handleDescriptionChanged); 0059 connect(m_workbook, &Workbook::childAspectAdded, this, &WorkbookView::handleAspectAdded); 0060 connect(m_workbook, &Workbook::childAspectAboutToBeRemoved, this, &WorkbookView::handleAspectAboutToBeRemoved); 0061 connect(m_workbook, &Workbook::requestProjectContextMenu, this, &WorkbookView::createContextMenu); 0062 connect(m_workbook, &Workbook::workbookItemSelected, this, &WorkbookView::itemSelected); 0063 0064 connect(m_tabWidget, &QTabWidget::currentChanged, this, &WorkbookView::tabChanged); 0065 connect(m_tabWidget, &QTabWidget::customContextMenuRequested, this, &WorkbookView::showTabContextMenu); 0066 // connect(m_tabWidget->tabBar(), &QTabBar::tabMoved, this, &WorkbookView::tabMoved); 0067 } 0068 0069 WorkbookView::~WorkbookView() { 0070 // no need to react on currentChanged() in TabWidget when views are deleted 0071 disconnect(m_tabWidget, nullptr, nullptr, nullptr); 0072 0073 // delete all children views here, its own view will be deleted in ~AbstractPart() 0074 for (const auto* part : m_workbook->children<AbstractPart>()) 0075 part->deleteView(); 0076 } 0077 0078 int WorkbookView::currentIndex() const { 0079 return m_tabWidget->currentIndex(); 0080 } 0081 0082 // ############################################################################## 0083 // ######################### Private slots #################################### 0084 // ############################################################################## 0085 /*! 0086 called when the current tab was changed. Propagates the selection of \c Spreadsheet 0087 or of a \c Matrix object to \c Workbook. 0088 */ 0089 void WorkbookView::tabChanged(int index) { 0090 CONDITIONAL_RETURN_NO_LOCK; 0091 0092 if (index == -1) 0093 return; 0094 0095 m_workbook->setChildSelectedInView(lastSelectedIndex, false); 0096 m_workbook->setChildSelectedInView(index, true); 0097 lastSelectedIndex = index; 0098 } 0099 0100 void WorkbookView::tabMoved(int /*from*/, int /*to*/) { 0101 // TODO: 0102 // AbstractAspect* aspect = m_workbook->child<AbstractAspect>(to); 0103 // if (aspect) { 0104 // m_tabMoving = true; 0105 // AbstractAspect* sibling = m_workbook->child<AbstractAspect>(from); 0106 // qDebug()<<"insert: " << to << " " << aspect->name() << ", " << from << " " << sibling->name(); 0107 // aspect->remove(); 0108 // m_workbook->insertChildBefore(aspect, sibling); 0109 // qDebug()<<"inserted"; 0110 // m_tabMoving = false; 0111 // } 0112 } 0113 0114 void WorkbookView::itemSelected(int index) { 0115 m_tabWidget->setCurrentIndex(index); 0116 } 0117 0118 /*! 0119 * Populates the menu \c menu with the spreadsheet and spreadsheet view relevant actions. 0120 * The menu is used 0121 * - as the context menu in WorkbookView 0122 * - as the "spreadsheet menu" in the main menu-bar (called form MainWin) 0123 * - as a part of the spreadsheet context menu in project explorer 0124 */ 0125 void WorkbookView::createContextMenu(QMenu* menu) const { 0126 Q_ASSERT(menu); 0127 0128 QAction* firstAction = nullptr; 0129 // if we're populating the context menu for the project explorer, then 0130 // there're already actions available there. Skip the first title-action 0131 // and insert the action at the beginning of the menu. 0132 if (menu->actions().size() > 1) 0133 firstAction = menu->actions().at(1); 0134 0135 auto* addNewMenu = new QMenu(i18n("Add New"), const_cast<WorkbookView*>(this)); 0136 addNewMenu->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); 0137 addNewMenu->addAction(action_add_spreadsheet); 0138 addNewMenu->addAction(action_add_matrix); 0139 menu->insertMenu(firstAction, addNewMenu); 0140 menu->insertSeparator(firstAction); 0141 } 0142 0143 void WorkbookView::showTabContextMenu(QPoint point) { 0144 QMenu* menu = nullptr; 0145 auto* aspect = m_workbook->child<AbstractAspect>(m_tabWidget->currentIndex()); 0146 auto* spreadsheet = dynamic_cast<Spreadsheet*>(aspect); 0147 if (spreadsheet) { 0148 menu = spreadsheet->createContextMenu(); 0149 } else { 0150 Matrix* matrix = dynamic_cast<Matrix*>(aspect); 0151 if (matrix) 0152 menu = matrix->createContextMenu(); 0153 } 0154 0155 if (menu) 0156 menu->exec(m_tabWidget->mapToGlobal(point)); 0157 } 0158 0159 void WorkbookView::addMatrix() { 0160 Matrix* matrix = new Matrix(i18n("Matrix")); 0161 m_workbook->addChild(matrix); 0162 } 0163 0164 void WorkbookView::addSpreadsheet() { 0165 auto* spreadsheet = new Spreadsheet(i18n("Spreadsheet")); 0166 m_workbook->addChild(spreadsheet); 0167 } 0168 0169 void WorkbookView::handleDescriptionChanged(const AbstractAspect* aspect) { 0170 int index = m_workbook->indexOfChild<AbstractAspect>(aspect); 0171 if (index != -1 && index < m_tabWidget->count()) 0172 m_tabWidget->setTabText(index, aspect->name()); 0173 } 0174 0175 void WorkbookView::handleAspectAdded(const AbstractAspect* aspect) { 0176 const auto* part = dynamic_cast<const AbstractPart*>(aspect); 0177 if (!part) 0178 return; 0179 0180 int index = m_workbook->indexOfChild<AbstractAspect>(aspect); 0181 m_tabWidget->insertTab(index, part->view(), aspect->name()); 0182 m_tabWidget->setCurrentIndex(index); 0183 m_tabWidget->setTabIcon(m_tabWidget->count(), aspect->icon()); 0184 this->tabChanged(index); 0185 } 0186 0187 void WorkbookView::handleAspectAboutToBeRemoved(const AbstractAspect* aspect) { 0188 int index = m_workbook->indexOfChild<AbstractAspect>(aspect); 0189 m_tabWidget->removeTab(index); 0190 }