File indexing completed on 2024-05-19 15:01:19

0001 /***************************************************************************
0002     File                 : AbstractPart.cpp
0003     Project              : LabPlot
0004     Description          : Base class of Aspects with MDI windows as views.
0005     --------------------------------------------------------------------
0006     Copyright            : (C) 2008 Knut Franke (knut.franke@gmx.de)
0007     Copyright            : (C) 2012 Alexander Semke (alexander.semke@web.de)
0008 
0009  ***************************************************************************/
0010 
0011 /***************************************************************************
0012  *                                                                         *
0013  *  This program is free software; you can redistribute it and/or modify   *
0014  *  it under the terms of the GNU General Public License as published by   *
0015  *  the Free Software Foundation; either version 2 of the License, or      *
0016  *  (at your option) any later version.                                    *
0017  *                                                                         *
0018  *  This program is distributed in the hope that it will be useful,        *
0019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0021  *  GNU General Public License for more details.                           *
0022  *                                                                         *
0023  *   You should have received a copy of the GNU General Public License     *
0024  *   along with this program; if not, write to the Free Software           *
0025  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0026  *   Boston, MA  02110-1301  USA                                           *
0027  *                                                                         *
0028  ***************************************************************************/
0029 
0030 #include "backend/core/AbstractPart.h"
0031 #include "backend/core/Workbook.h"
0032 #include "backend/datapicker/Datapicker.h"
0033 #include "backend/datapicker/DatapickerCurve.h"
0034 #include "backend/datasources/LiveDataSource.h"
0035 #include "backend/matrix/Matrix.h"
0036 #include "backend/spreadsheet/Spreadsheet.h"
0037 #include "commonfrontend/core/PartMdiView.h"
0038 #ifdef HAVE_MQTT
0039 #include "backend/datasources/MQTTTopic.h"
0040 #endif
0041 
0042 #include <QMenu>
0043 #include <QStyle>
0044 
0045 #include <KLocalizedString>
0046 
0047 /**
0048  * \class AbstractPart
0049  * \brief Base class of Aspects with MDI windows as views (AspectParts).
0050  */
0051 AbstractPart::AbstractPart(const QString& name, AspectType type)
0052     : AbstractAspect(name, type) {
0053 }
0054 
0055 AbstractPart::~AbstractPart() {
0056     if (m_mdiWindow)
0057         delete m_mdiWindow;
0058 }
0059 
0060 /**
0061  * \fn QWidget *AbstractPart::view() const
0062  * \brief Construct a primary view on me.
0063  *
0064  * The caller receives ownership of the view.
0065  *
0066  * This method may be called multiple times during the life time of a Part, or it might not get
0067  * called at all. Parts must not depend on the existence of a view for their operation.
0068  */
0069 
0070 /**
0071  * \brief Wrap the view() into a PartMdiView.
0072  *
0073  * A new view is only created the first time this method is called;
0074  * after that, a pointer to the pre-existing view is returned.
0075  */
0076 PartMdiView* AbstractPart::mdiSubWindow() const {
0077     if (!m_mdiWindow)
0078         m_mdiWindow = new PartMdiView(const_cast<AbstractPart*>(this));
0079 
0080     return m_mdiWindow;
0081 }
0082 
0083 bool AbstractPart::hasMdiSubWindow() const {
0084     return m_mdiWindow;
0085 }
0086 
0087 /*!
0088  * this function is called when PartMdiView, the mdi-subwindow-wrapper of the actual view,
0089  * is closed (=deleted) in MainWindow. Makes sure that the view also gets deleted.
0090  */
0091 void AbstractPart::deleteView() const {
0092     //if the parent is a Workbook or Datapicker, the actual view was already deleted when QTabWidget was deleted.
0093     //here just set the pointer to 0.
0094     if (dynamic_cast<const Workbook*>(parentAspect()) || dynamic_cast<const Datapicker*>(parentAspect())
0095             || dynamic_cast<const Datapicker*>(parentAspect()->parentAspect())) {
0096         m_partView = nullptr;
0097         return;
0098     }
0099 
0100     if (m_partView) {
0101         delete m_partView;
0102         m_partView = nullptr;
0103         m_mdiWindow = nullptr;
0104     }
0105 }
0106 
0107 /**
0108  * \brief Return AbstractAspect::createContextMenu() plus operations on the primary view.
0109  */
0110 QMenu* AbstractPart::createContextMenu() {
0111     QMenu* menu = AbstractAspect::createContextMenu();
0112     Q_ASSERT(menu);
0113     menu->addSeparator();
0114 
0115     if (m_mdiWindow) {
0116         if ( (dynamic_cast<Spreadsheet*>(this) || dynamic_cast<Matrix*>(this))
0117             && !dynamic_cast<const LiveDataSource*>(this)
0118 #ifdef HAVE_MQTT
0119             && !dynamic_cast<const MQTTTopic*>(this)
0120 #endif
0121         ) {
0122             QMenu* subMenu = new QMenu(i18n("Import Data"), menu);
0123             subMenu->addAction(QIcon::fromTheme("document-import"), i18n("From File"), this, SIGNAL(importFromFileRequested()));
0124             subMenu->addAction(QIcon::fromTheme("document-import"), i18n("From SQL Database"), this, SIGNAL(importFromSQLDatabaseRequested()));
0125             menu->addMenu(subMenu);
0126             menu->addSeparator();
0127         }
0128 
0129         menu->addAction(QIcon::fromTheme("document-export-database"), i18n("Export"), this, SIGNAL(exportRequested()));
0130         menu->addAction(QIcon::fromTheme("document-print"), i18n("Print"), this, SIGNAL(printRequested()));
0131         menu->addAction(QIcon::fromTheme("document-print-preview"), i18n("Print Preview"), this, SIGNAL(printPreviewRequested()));
0132         menu->addSeparator();
0133 
0134         const QStyle *widget_style = m_mdiWindow->style();
0135         if (m_mdiWindow->windowState() & (Qt::WindowMinimized | Qt::WindowMaximized)) {
0136             QAction* action = menu->addAction(i18n("&Restore"), m_mdiWindow, SLOT(showNormal()));
0137             action->setIcon(widget_style->standardIcon(QStyle::SP_TitleBarNormalButton));
0138         }
0139 
0140         if (!(m_mdiWindow->windowState() & Qt::WindowMinimized))    {
0141             QAction* action = menu->addAction(i18n("Mi&nimize"), m_mdiWindow, SLOT(showMinimized()));
0142             action->setIcon(widget_style->standardIcon(QStyle::SP_TitleBarMinButton));
0143         }
0144 
0145         if (!(m_mdiWindow->windowState() & Qt::WindowMaximized))    {
0146             QAction* action = menu->addAction(i18n("Ma&ximize"), m_mdiWindow, SLOT(showMaximized()));
0147             action->setIcon(widget_style->standardIcon(QStyle::SP_TitleBarMaxButton));
0148         }
0149     } else {
0150         //data spreadsheets in the datapicker curves cannot be hidden/minimized, don't show this menu entry
0151         if ( !(dynamic_cast<const Spreadsheet*>(this) && dynamic_cast<const DatapickerCurve*>(this->parentAspect())) )
0152             menu->addAction(i18n("Show"), this, SIGNAL(showRequested()));
0153     }
0154 
0155     return menu;
0156 }
0157 
0158 bool AbstractPart::isDraggable() const {
0159     //TODO: moving workbook children doesn't work at the moment, don't allow to move it for now
0160     if ((type() == AspectType::Spreadsheet || type() == AspectType::Matrix)
0161         && parentAspect()->type() == AspectType::Workbook)
0162         return false;
0163     else
0164         return true;
0165 }
0166 
0167 QVector<AspectType> AbstractPart::dropableOn() const {
0168     return QVector<AspectType>{AspectType::Folder, AspectType::Project};
0169 }