File indexing completed on 2024-04-14 15:49:29

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Emmanuel Pescosta <emmanuelpescosta099@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef DOLPHIN_TAB_WIDGET_H
0008 #define DOLPHIN_TAB_WIDGET_H
0009 
0010 #include "dolphinnavigatorswidgetaction.h"
0011 #include "dolphintabpage.h"
0012 
0013 #include <QTabWidget>
0014 #include <QUrl>
0015 
0016 #include <optional>
0017 
0018 class DolphinViewContainer;
0019 class KConfigGroup;
0020 
0021 class DolphinTabWidget : public QTabWidget
0022 {
0023     Q_OBJECT
0024 
0025 public:
0026     /**
0027      * @param navigatorsWidget The navigatorsWidget which is always going to be connected
0028      *                         to the active tabPage.
0029      */
0030     explicit DolphinTabWidget(DolphinNavigatorsWidgetAction *navigatorsWidget, QWidget *parent);
0031 
0032     /**
0033      * Where a newly opened tab should be placed.
0034      */
0035     enum class NewTabPosition {
0036         FollowSetting, ///< Honor openNewTabAfterLastTab setting
0037         AfterCurrent, ///< After the current tab
0038         AtEnd, ///< At the end of the tab bar
0039     };
0040 
0041     /**
0042      * @return Tab page at the current index (can be 0 if tabs count is smaller than 1)
0043      */
0044     DolphinTabPage *currentTabPage() const;
0045 
0046     /**
0047      * @return the next tab page. If the current active tab is the last tab,
0048      * it returns the first tab. If there is only one tab, returns nullptr
0049      */
0050     DolphinTabPage *nextTabPage() const;
0051 
0052     /**
0053      * @return the previous tab page. If the current active tab is the first tab,
0054      * it returns the last tab. If there is only one tab, returns nullptr
0055      */
0056     DolphinTabPage *prevTabPage() const;
0057 
0058     /**
0059      * @return Tab page at the given \a index (can be 0 if the index is out-of-range)
0060      */
0061     DolphinTabPage *tabPageAt(const int index) const;
0062 
0063     void saveProperties(KConfigGroup &group) const;
0064     void readProperties(const KConfigGroup &group);
0065 
0066     /**
0067      * Refreshes the views of the main window by recreating them according to
0068      * the given Dolphin settings.
0069      */
0070     void refreshViews();
0071 
0072     /**
0073      * Update the name of the tab with the index \a index.
0074      */
0075     void updateTabName(int index);
0076 
0077     /**
0078      * @return Whether any of the tab pages has @p url opened
0079      * in their primary or secondary view.
0080      */
0081     bool isUrlOpen(const QUrl &url) const;
0082 
0083     /**
0084      * @return Whether the item with @p url can be found in any view only by switching
0085      * between already open tabs and scrolling in their primary or secondary view.
0086      */
0087     bool isItemVisibleInAnyView(const QUrl &urlOfItem) const;
0088 
0089 Q_SIGNALS:
0090     /**
0091      * Is emitted when the active view has been changed, by changing the current
0092      * tab or by activating another view when split view is enabled in the current
0093      * tab.
0094      */
0095     void activeViewChanged(DolphinViewContainer *viewContainer);
0096 
0097     /**
0098      * Is emitted when the number of open tabs has changed (e.g. by opening or
0099      * closing a tab)
0100      */
0101     void tabCountChanged(int count);
0102 
0103     /**
0104      * Is emitted when a tab has been closed.
0105      */
0106     void rememberClosedTab(const QUrl &url, const QByteArray &state);
0107 
0108     /**
0109      * Is emitted when the url of the current tab has been changed. This signal
0110      * is also emitted when the active view has been changed.
0111      */
0112     void currentUrlChanged(const QUrl &url);
0113 
0114     /**
0115      * Is emitted when the url of any tab has been changed (including the current tab).
0116      */
0117     void urlChanged(const QUrl &url);
0118 
0119 public Q_SLOTS:
0120     /**
0121      * Opens a new view with the current URL that is part of a tab and activates
0122      * the tab.
0123      */
0124     void openNewActivatedTab();
0125 
0126     /**
0127      * Opens a new tab showing the  URL \a primaryUrl and the optional URL
0128      * \a secondaryUrl and activates the tab.
0129      */
0130     void openNewActivatedTab(const QUrl &primaryUrl, const QUrl &secondaryUrl = QUrl());
0131 
0132     /**
0133      * Opens a new tab in the background showing the URL \a primaryUrl and the
0134      * optional URL \a secondaryUrl.
0135      */
0136     void openNewTab(const QUrl &primaryUrl,
0137                     const QUrl &secondaryUrl = QUrl(),
0138                     DolphinTabWidget::NewTabPosition position = DolphinTabWidget::NewTabPosition::FollowSetting);
0139 
0140     /**
0141      * Opens each directory in \p dirs in a separate tab unless it is already open.
0142      * If \a splitView is set, 2 directories are collected within one tab.
0143      * \pre \a dirs must contain at least one url.
0144      */
0145     void openDirectories(const QList<QUrl> &dirs, bool splitView);
0146 
0147     /**
0148      * Opens the directories which contain the files \p files and selects all files.
0149      * If \a splitView is set, 2 directories are collected within one tab.
0150      * \pre \a files must contain at least one url.
0151      */
0152     void openFiles(const QList<QUrl> &files, bool splitView);
0153 
0154     /**
0155      * Closes the currently active tab.
0156      */
0157     void closeTab();
0158 
0159     /**
0160      * Closes the tab with the index \a index and activates the tab with index - 1.
0161      */
0162     void closeTab(const int index);
0163 
0164     /**
0165      * Activates the tab with the index \a index.
0166      */
0167     void activateTab(const int index);
0168 
0169     /**
0170      * Activates the last tab in the tab bar.
0171      */
0172     void activateLastTab();
0173 
0174     /**
0175      * Activates the next tab in the tab bar.
0176      * If the current active tab is the last tab, it activates the first tab.
0177      */
0178     void activateNextTab();
0179 
0180     /**
0181      * Activates the previous tab in the tab bar.
0182      * If the current active tab is the first tab, it activates the last tab.
0183      */
0184     void activatePrevTab();
0185 
0186     /**
0187      * Is called when the user wants to reopen a previously closed tab from
0188      * the recent tabs menu.
0189      */
0190     void restoreClosedTab(const QByteArray &state);
0191 
0192     /** Copies all selected items to the inactive view. */
0193     void copyToInactiveSplitView();
0194 
0195     /** Moves all selected items to the inactive view. */
0196     void moveToInactiveSplitView();
0197 
0198 private Q_SLOTS:
0199     /**
0200      * Opens the tab with the index \a index in a new Dolphin instance and closes
0201      * this tab.
0202      */
0203     void detachTab(int index);
0204 
0205     /**
0206      * Opens a new tab showing the url from tab at the given \a index and
0207      * activates the tab.
0208      */
0209     void openNewActivatedTab(int index);
0210 
0211     /**
0212      * Is connected to the KTabBar signal receivedDropEvent.
0213      * Allows dragging and dropping files onto tabs.
0214      */
0215     void tabDropEvent(int tab, QDropEvent *event);
0216 
0217     /**
0218      * The active view url of a tab has been changed so update the text and the
0219      * icon of the corresponding tab.
0220      */
0221     void tabUrlChanged(const QUrl &url);
0222 
0223     void currentTabChanged(int index);
0224 
0225 protected:
0226     void tabInserted(int index) override;
0227     void tabRemoved(int index) override;
0228 
0229 private:
0230     /**
0231      * @param tabPage The tab page to get the name of
0232      * @return The name of the tab page
0233      */
0234     QString tabName(DolphinTabPage *tabPage) const;
0235 
0236     struct ViewIndex {
0237         const int tabIndex;
0238         const bool isInPrimaryView;
0239     };
0240 
0241     /**
0242      * Getter for a view container.
0243      * @param viewIndex specifies the tab and the view within that tab.
0244      * @return the view container specified in @p viewIndex or nullptr if it doesn't exist.
0245      */
0246     DolphinViewContainer *viewContainerAt(ViewIndex viewIndex) const;
0247 
0248     /**
0249      * Makes the view container specified in @p viewIndex become the active view container within this tab widget.
0250      * @param viewIndex Specifies the tab to activate and the view container within the tab to activate.
0251      * @return the freshly activated view container or nullptr if there is no view container at @p viewIndex.
0252      */
0253     DolphinViewContainer *activateViewContainerAt(ViewIndex viewIndex);
0254 
0255     /**
0256      * Get the position of the view within this widget that is open at @p directory.
0257      * @param directory The URL of the directory we want to find.
0258      * @return a small struct containing the tab index of the view and whether it is
0259      * in the primary view. A std::nullopt is returned if there is no view open for @p directory.
0260      */
0261     const std::optional<const ViewIndex> viewOpenAtDirectory(const QUrl &directory) const;
0262 
0263     /**
0264      * Get the position of the view within this widget that has @p item in the view.
0265      * This means that the item can be seen by the user in that view when scrolled to the right position.
0266      * If the view has folders expanded and @p item is one of them, the view will also be returned.
0267      * @param item The URL of the item we want to find.
0268      * @return a small struct containing the tab index of the view and whether it is
0269      * in the primary view. A std::nullopt is returned if there is no view open that has @p item visible anywhere.
0270      */
0271     const std::optional<const ViewIndex> viewShowingItem(const QUrl &item) const;
0272 
0273 private:
0274     QPointer<DolphinTabPage> m_lastViewedTab;
0275     QPointer<DolphinNavigatorsWidgetAction> m_navigatorsWidget;
0276 };
0277 
0278 #endif