File indexing completed on 2024-04-21 05:45:43

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Emmanuel Pescosta <emmanuelpescosta099@gmail.com>
0003  * SPDX-FileCopyrightText: 2020 Felix Ernst <felixernst@kde.org>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #ifndef DOLPHIN_TAB_PAGE_H
0009 #define DOLPHIN_TAB_PAGE_H
0010 
0011 #include "global.h"
0012 
0013 #include <QPointer>
0014 #include <QSplitter>
0015 #include <QUrl>
0016 #include <QWidget>
0017 
0018 class DolphinNavigatorsWidgetAction;
0019 class DolphinViewContainer;
0020 class QVariantAnimation;
0021 class KFileItemList;
0022 class DolphinTabPageSplitter;
0023 
0024 class DolphinTabPage : public QWidget
0025 {
0026     Q_OBJECT
0027 
0028 public:
0029     explicit DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl = QUrl(), QWidget *parent = nullptr);
0030 
0031     /**
0032      * @return True if primary view is the active view in this tab.
0033      */
0034     bool primaryViewActive() const;
0035 
0036     /**
0037      * @return True if split view is enabled.
0038      */
0039     bool splitViewEnabled() const;
0040 
0041     /**
0042      * Enables or disables the split view mode.
0043      *
0044      * @param enabled      If true, creates a secondary viewContainer in this tab.
0045      *                     Otherwise deletes it.
0046      * @param animated     Decides whether the effects of this method call should
0047      *                     happen instantly or be transitioned to smoothly.
0048      * @param secondaryUrl If \p enabled is true, the new viewContainer will be opened at this
0049      *                     parameter. The default value will set the Url of the new viewContainer
0050      *                     to be the same as the existing one.
0051      */
0052     void setSplitViewEnabled(bool enabled, Animated animated, const QUrl &secondaryUrl = QUrl());
0053 
0054     /**
0055      * @return The primary view container.
0056      */
0057     DolphinViewContainer *primaryViewContainer() const;
0058 
0059     /**
0060      * @return The secondary view container, can be 0 if split view is disabled.
0061      */
0062     DolphinViewContainer *secondaryViewContainer() const;
0063 
0064     /**
0065      * @return DolphinViewContainer of the active view
0066      */
0067     DolphinViewContainer *activeViewContainer() const;
0068 
0069     /**
0070      * @return DolphinViewContainer of the inactive view
0071      * if split view is enabled, or nullptr otherwise.
0072      */
0073     DolphinViewContainer *inactiveViewContainer() const;
0074 
0075     /**
0076      * Returns the selected items. The list is empty if no item has been
0077      * selected.
0078      */
0079     KFileItemList selectedItems() const;
0080 
0081     /**
0082      * Returns the number of selected items (this is faster than
0083      * invoking selectedItems().count()).
0084      */
0085     int selectedItemsCount() const;
0086 
0087     /**
0088      * Connects a navigatorsWidget to this. It will be connected to the DolphinViewContainers
0089      * managed by this tab. For alignment purposes this will from now on notify the
0090      * navigatorsWidget when this tab or its viewContainers are resized.
0091      */
0092     void connectNavigators(DolphinNavigatorsWidgetAction *navigatorsWidget);
0093 
0094     /**
0095      * Makes it so this tab and its DolphinViewContainers aren't controlled by any
0096      * UrlNavigators anymore.
0097      */
0098     void disconnectNavigators();
0099 
0100     void insertNavigatorsWidget(DolphinNavigatorsWidgetAction *navigatorsWidget);
0101 
0102     /**
0103      * Marks the items indicated by \p urls to get selected after the
0104      * directory DolphinView::url() has been loaded. Note that nothing
0105      * gets selected if no loading of a directory has been triggered
0106      * by DolphinView::setUrl() or DolphinView::reload().
0107      */
0108     void markUrlsAsSelected(const QList<QUrl> &urls);
0109 
0110     /**
0111      * Marks the item indicated by \p url to be scrolled to and as the
0112      * current item after directory DolphinView::url() has been loaded.
0113      */
0114     void markUrlAsCurrent(const QUrl &url);
0115 
0116     /**
0117      * Refreshes the views of the main window by recreating them according to
0118      * the given Dolphin settings.
0119      */
0120     void refreshViews();
0121 
0122     /**
0123      * Saves all tab related properties (urls, splitter layout, ...).
0124      *
0125      * @return A byte-array which contains all properties.
0126      */
0127     QByteArray saveState() const;
0128 
0129     /**
0130      * Restores all tab related properties (urls, splitter layout, ...) from
0131      * the given \a state.
0132      */
0133     void restoreState(const QByteArray &state);
0134 
0135     /**
0136      * Set whether the tab page is active
0137      *
0138      */
0139     void setActive(bool active);
0140 
0141     void switchActiveView();
0142 
0143 Q_SIGNALS:
0144     void activeViewChanged(DolphinViewContainer *viewContainer);
0145     void activeViewUrlChanged(const QUrl &url);
0146     void splitterMoved(int pos, int index);
0147 
0148 private Q_SLOTS:
0149     /**
0150      * Deletes all zombie viewContainers that were used for the animation
0151      * and resets the minimum size of the others to a sane value.
0152      */
0153     void slotAnimationFinished();
0154 
0155     /**
0156      * This method is called for every frame of the m_expandViewAnimation.
0157      */
0158     void slotAnimationValueChanged(const QVariant &value);
0159 
0160     /**
0161      * Handles the view activated event.
0162      *
0163      * It sets the previous active view to inactive, updates the current
0164      * active view type and triggers the activeViewChanged event.
0165      */
0166     void slotViewActivated();
0167 
0168     /**
0169      * Handles the view url redirection event.
0170      *
0171      * It emits the activeViewUrlChanged signal with the url \a newUrl.
0172      */
0173     void slotViewUrlRedirection(const QUrl &oldUrl, const QUrl &newUrl);
0174 
0175 private:
0176     /**
0177      * Creates a new view container and does the default initialization.
0178      */
0179     DolphinViewContainer *createViewContainer(const QUrl &url) const;
0180 
0181     /**
0182      * Starts an animation that transitions between split view mode states.
0183      *
0184      * One of the viewContainers is always being expanded when toggling so
0185      * this method can animate both opening and closing of viewContainers.
0186      * @param expandingContainer The container that will increase in size
0187      *                           over the course of the animation.
0188      */
0189     void startExpandViewAnimation(DolphinViewContainer *expandingContainer);
0190 
0191 private:
0192     DolphinTabPageSplitter *m_splitter;
0193 
0194     QPointer<DolphinNavigatorsWidgetAction> m_navigatorsWidget;
0195     QPointer<DolphinViewContainer> m_primaryViewContainer;
0196     QPointer<DolphinViewContainer> m_secondaryViewContainer;
0197 
0198     DolphinViewContainer *m_expandingContainer;
0199     QPointer<QVariantAnimation> m_expandViewAnimation;
0200 
0201     bool m_primaryViewActive;
0202     bool m_splitViewEnabled;
0203     bool m_active;
0204 };
0205 
0206 class DolphinTabPageSplitterHandle : public QSplitterHandle
0207 {
0208     Q_OBJECT
0209 
0210 public:
0211     explicit DolphinTabPageSplitterHandle(Qt::Orientation orientation, QSplitter *parent);
0212 
0213 protected:
0214     bool event(QEvent *event) override;
0215 
0216 private:
0217     void resetSplitterSizes();
0218 
0219     // Sometimes QSplitterHandle doesn't receive MouseButtonDblClick event.
0220     // We can detect that MouseButtonDblClick event should have been
0221     // received if we receive two MouseButtonRelease events in a row.
0222     bool m_mouseReleaseWasReceived;
0223 };
0224 
0225 class DolphinTabPageSplitter : public QSplitter
0226 {
0227     Q_OBJECT
0228 
0229 public:
0230     explicit DolphinTabPageSplitter(Qt::Orientation orientation, QWidget *parent);
0231 
0232 protected:
0233     QSplitterHandle *createHandle() override;
0234 };
0235 
0236 #endif // DOLPHIN_TAB_PAGE_H