File indexing completed on 2024-06-23 05:49:18

0001 /*
0002     This file is part of the Kasten Framework, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2009 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "viewareasplitcontroller.hpp"
0010 
0011 // Kasten gui
0012 #include <Kasten/AbstractGroupedViews>
0013 #include <Kasten/ViewAreaSplitable>
0014 #include <Kasten/AbstractViewArea>
0015 #include <Kasten/ViewManager>
0016 // KF
0017 #include <KXMLGUIClient>
0018 #include <KActionCollection>
0019 #include <KLocalizedString>
0020 // Qt
0021 #include <QAction>
0022 
0023 namespace Kasten {
0024 
0025 ViewAreaSplitController::ViewAreaSplitController(ViewManager* viewManager, AbstractGroupedViews* groupedViews, KXMLGUIClient* guiClient)
0026     : mViewManager(viewManager)
0027     , mGroupedViews(groupedViews)
0028 {
0029     mViewAreaSplitable = mGroupedViews ? qobject_cast<If::ViewAreaSplitable*>(mGroupedViews) : nullptr;
0030     if (mViewAreaSplitable) {
0031         connect(mGroupedViews, SIGNAL(viewAreaFocusChanged(Kasten::AbstractViewArea*)),
0032                 SLOT(onViewAreaFocusChanged(Kasten::AbstractViewArea*)));
0033         connect(mGroupedViews, SIGNAL(viewAreasAdded(QVector<Kasten::AbstractViewArea*>)),
0034                 SLOT(onViewAreasChanged()));
0035         connect(mGroupedViews, SIGNAL(viewAreasRemoved(QVector<Kasten::AbstractViewArea*>)),
0036                 SLOT(onViewAreasChanged()));
0037     }
0038 
0039     KActionCollection* actionCollection = guiClient->actionCollection();
0040 
0041     mSplitVerticallyAction = new QAction(QIcon::fromTheme(QStringLiteral("view-split-left-right")),
0042                                          i18nc("@action:inmenu", "Split Vertically"), this);
0043     mSplitVerticallyAction->setObjectName(QStringLiteral("view_area_split_vertically"));
0044     actionCollection->setDefaultShortcut(mSplitVerticallyAction, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_L));
0045     mSplitVerticallyAction->setEnabled(mViewAreaSplitable != nullptr);
0046     connect(mSplitVerticallyAction, &QAction::triggered,
0047             this, &ViewAreaSplitController::splitVertically);
0048 
0049     mSplitHorizontallyAction = new QAction(QIcon::fromTheme(QStringLiteral("view-split-top-bottom")),
0050                                 i18nc("@action:inmenu", "Split Horizontal"), this);
0051     mSplitHorizontallyAction->setObjectName(QStringLiteral("view_area_split_horizontally"));
0052     actionCollection->setDefaultShortcut(mSplitHorizontallyAction, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_T));
0053     mSplitHorizontallyAction->setEnabled(mViewAreaSplitable != nullptr);
0054     connect(mSplitHorizontallyAction, &QAction::triggered,
0055             this, &ViewAreaSplitController::splitHorizontally);
0056 
0057     mCloseAction = new QAction(QIcon::fromTheme(QStringLiteral("view-close")),
0058                                 i18nc("@action:inmenu", "Close View Area"), this);
0059     mCloseAction->setObjectName(QStringLiteral("view_area_close"));
0060     actionCollection->setDefaultShortcut(mCloseAction, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_R));
0061     connect(mCloseAction, &QAction::triggered,
0062             this, &ViewAreaSplitController::close);
0063 
0064     actionCollection->addActions({
0065         mSplitVerticallyAction,
0066         mSplitHorizontallyAction,
0067         mCloseAction,
0068     });
0069 
0070     onViewAreaFocusChanged(mViewAreaSplitable ? mViewAreaSplitable->viewAreaFocus() : nullptr);
0071     onViewAreasChanged();
0072 }
0073 
0074 void ViewAreaSplitController::setTargetModel(AbstractModel* model)
0075 {
0076     Q_UNUSED(model)
0077 }
0078 
0079 void ViewAreaSplitController::splitVertically()
0080 {
0081     splitViewArea(Qt::Vertical);
0082 }
0083 
0084 void ViewAreaSplitController::splitHorizontally()
0085 {
0086     splitViewArea(Qt::Horizontal);
0087 }
0088 
0089 void ViewAreaSplitController::close()
0090 {
0091     mViewAreaSplitable->closeViewArea(mCurrentViewArea);
0092 }
0093 
0094 void ViewAreaSplitController::splitViewArea(Qt::Orientation orientation)
0095 {
0096     AbstractView* currentView = mCurrentViewArea->viewFocus();
0097 
0098     mViewAreaSplitable->splitViewArea(mCurrentViewArea, orientation);
0099 
0100     // TODO: ideal would be a new view which copies the existing one
0101     // and starts visually where the old one stops after the resize
0102     const Qt::Alignment alignment = (orientation == Qt::Horizontal) ? Qt::AlignBottom : Qt::AlignRight;
0103     mViewManager->createCopyOfView(currentView, alignment);
0104 }
0105 
0106 void ViewAreaSplitController::onViewAreaFocusChanged(AbstractViewArea* viewArea)
0107 {
0108     if (mCurrentViewArea) {
0109         mCurrentViewArea->disconnect(this);
0110     }
0111 
0112     // TODO: how to handle single view areas? examples, signals?
0113     mCurrentViewArea = qobject_cast<AbstractGroupedViews*>(viewArea);
0114 
0115     if (mCurrentViewArea) {
0116         connect(mCurrentViewArea, &AbstractGroupedViews::added,
0117                 this, &ViewAreaSplitController::onViewsChanged);
0118         connect(mCurrentViewArea, &AbstractGroupedViews::removing,
0119                 this, &ViewAreaSplitController::onViewsChanged);
0120     }
0121     onViewsChanged();
0122 }
0123 
0124 void ViewAreaSplitController::onViewAreasChanged()
0125 {
0126     const bool hasMultipleViewArea = mViewAreaSplitable ? (mViewAreaSplitable->viewAreasCount() > 1) : false;
0127 
0128     mCloseAction->setEnabled(hasMultipleViewArea);
0129 }
0130 
0131 void ViewAreaSplitController::onViewsChanged()
0132 {
0133     const bool hasViews = mCurrentViewArea ? (mCurrentViewArea->viewCount() > 0) : false;
0134 
0135     mSplitVerticallyAction->setEnabled(hasViews);
0136     mSplitHorizontallyAction->setEnabled(hasViews);
0137 }
0138 
0139 }
0140 
0141 #include "moc_viewareasplitcontroller.cpp"