File indexing completed on 2024-04-28 09:40:57

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      * @return Whether any of the tab pages has @p url opened
0074      * in their primary or secondary view.
0075      */
0076     bool isUrlOpen(const QUrl &url) const;
0077 
0078     /**
0079      * @return Whether the item with @p url can be found in any view only by switching
0080      * between already open tabs and scrolling in their primary or secondary view.
0081      */
0082     bool isItemVisibleInAnyView(const QUrl &urlOfItem) const;
0083 
0084 Q_SIGNALS:
0085     /**
0086      * Is emitted when the active view has been changed, by changing the current
0087      * tab or by activating another view when split view is enabled in the current
0088      * tab.
0089      */
0090     void activeViewChanged(DolphinViewContainer *viewContainer);
0091 
0092     /**
0093      * Is emitted when the number of open tabs has changed (e.g. by opening or
0094      * closing a tab)
0095      */
0096     void tabCountChanged(int count);
0097 
0098     /**
0099      * Is emitted when a tab has been closed.
0100      */
0101     void rememberClosedTab(const QUrl &url, const QByteArray &state);
0102 
0103     /**
0104      * Is emitted when the url of the current tab has been changed. This signal
0105      * is also emitted when the active view has been changed.
0106      */
0107     void currentUrlChanged(const QUrl &url);
0108 
0109 public Q_SLOTS:
0110     /**
0111      * Opens a new view with the current URL that is part of a tab and activates
0112      * the tab.
0113      */
0114     void openNewActivatedTab();
0115 
0116     /**
0117      * Opens a new tab showing the  URL \a primaryUrl and the optional URL
0118      * \a secondaryUrl and activates the tab.
0119      */
0120     void openNewActivatedTab(const QUrl &primaryUrl, const QUrl &secondaryUrl = QUrl());
0121 
0122     /**
0123      * Opens a new tab in the background showing the URL \a primaryUrl and the
0124      * optional URL \a secondaryUrl.
0125      */
0126     void openNewTab(const QUrl &primaryUrl,
0127                     const QUrl &secondaryUrl = QUrl(),
0128                     DolphinTabWidget::NewTabPosition position = DolphinTabWidget::NewTabPosition::FollowSetting);
0129 
0130     /**
0131      * Opens each directory in \p dirs in a separate tab unless it is already open.
0132      * If \a splitView is set, 2 directories are collected within one tab.
0133      * \pre \a dirs must contain at least one url.
0134      */
0135     void openDirectories(const QList<QUrl> &dirs, bool splitView);
0136 
0137     /**
0138      * Opens the directories which contain the files \p files and selects all files.
0139      * If \a splitView is set, 2 directories are collected within one tab.
0140      * \pre \a files must contain at least one url.
0141      */
0142     void openFiles(const QList<QUrl> &files, bool splitView);
0143 
0144     /**
0145      * Closes the currently active tab.
0146      */
0147     void closeTab();
0148 
0149     /**
0150      * Closes the tab with the index \a index and activates the tab with index - 1.
0151      */
0152     void closeTab(const int index);
0153 
0154     /**
0155      * Activates the tab with the index \a index.
0156      */
0157     void activateTab(const int index);
0158 
0159     /**
0160      * Activates the last tab in the tab bar.
0161      */
0162     void activateLastTab();
0163 
0164     /**
0165      * Activates the next tab in the tab bar.
0166      * If the current active tab is the last tab, it activates the first tab.
0167      */
0168     void activateNextTab();
0169 
0170     /**
0171      * Activates the previous tab in the tab bar.
0172      * If the current active tab is the first tab, it activates the last tab.
0173      */
0174     void activatePrevTab();
0175 
0176     /**
0177      * Is called when the user wants to reopen a previously closed tab from
0178      * the recent tabs menu.
0179      */
0180     void restoreClosedTab(const QByteArray &state);
0181 
0182     /** Copies all selected items to the inactive view. */
0183     void copyToInactiveSplitView();
0184 
0185     /** Moves all selected items to the inactive view. */
0186     void moveToInactiveSplitView();
0187 
0188 private Q_SLOTS:
0189     /**
0190      * Opens the tab with the index \a index in a new Dolphin instance and closes
0191      * this tab.
0192      */
0193     void detachTab(int index);
0194 
0195     /**
0196      * Opens a new tab showing the url from tab at the given \a index and
0197      * activates the tab.
0198      */
0199     void openNewActivatedTab(int index);
0200 
0201     /**
0202      * Is connected to the KTabBar signal receivedDropEvent.
0203      * Allows dragging and dropping files onto tabs.
0204      */
0205     void tabDropEvent(int tab, QDropEvent *event);
0206 
0207     /**
0208      * The active view url of a tab has been changed so update the text and the
0209      * icon of the corresponding tab.
0210      */
0211     void tabUrlChanged(const QUrl &url);
0212 
0213     void currentTabChanged(int index);
0214 
0215 protected:
0216     void tabInserted(int index) override;
0217     void tabRemoved(int index) override;
0218 
0219 private:
0220     /**
0221      * @param tabPage The tab page to get the name of
0222      * @return The name of the tab page
0223      */
0224     QString tabName(DolphinTabPage *tabPage) const;
0225 
0226     struct ViewIndex {
0227         const int tabIndex;
0228         const bool isInPrimaryView;
0229     };
0230 
0231     /**
0232      * Getter for a view container.
0233      * @param viewIndex specifies the tab and the view within that tab.
0234      * @return the view container specified in @p viewIndex or nullptr if it doesn't exist.
0235      */
0236     DolphinViewContainer *viewContainerAt(ViewIndex viewIndex) const;
0237 
0238     /**
0239      * Makes the view container specified in @p viewIndex become the active view container within this tab widget.
0240      * @param viewIndex Specifies the tab to activate and the view container within the tab to activate.
0241      * @return the freshly activated view container or nullptr if there is no view container at @p viewIndex.
0242      */
0243     DolphinViewContainer *activateViewContainerAt(ViewIndex viewIndex);
0244 
0245     /**
0246      * Get the position of the view within this widget that is open at @p directory.
0247      * @param directory The URL of the directory we want to find.
0248      * @return a small struct containing the tab index of the view and whether it is
0249      * in the primary view. A std::nullopt is returned if there is no view open for @p directory.
0250      */
0251     const std::optional<const ViewIndex> viewOpenAtDirectory(const QUrl &directory) const;
0252 
0253     /**
0254      * Get the position of the view within this widget that has @p item in the view.
0255      * This means that the item can be seen by the user in that view when scrolled to the right position.
0256      * If the view has folders expanded and @p item is one of them, the view will also be returned.
0257      * @param item The URL of the item 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 that has @p item visible anywhere.
0260      */
0261     const std::optional<const ViewIndex> viewShowingItem(const QUrl &item) const;
0262 
0263 private:
0264     QPointer<DolphinTabPage> m_lastViewedTab;
0265     QPointer<DolphinNavigatorsWidgetAction> m_navigatorsWidget;
0266 };
0267 
0268 #endif