File indexing completed on 2024-03-24 17:22:47

0001 /*
0002  * SPDX-FileCopyrightText: 2007 Peter Penz <peter.penz19@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef DOLPHINVIEWCONTAINER_H
0008 #define DOLPHINVIEWCONTAINER_H
0009 
0010 #include "config-dolphin.h"
0011 #include "dolphinurlnavigator.h"
0012 #include "selectionmode/bottombar.h"
0013 #include "views/dolphinview.h"
0014 
0015 #include <KFileItem>
0016 #include <KIO/Job>
0017 #include <KUrlNavigator>
0018 
0019 #include <QElapsedTimer>
0020 #include <QPushButton>
0021 #include <QWidget>
0022 
0023 class FilterBar;
0024 class KMessageWidget;
0025 class QAction;
0026 class QGridLayout;
0027 class QUrl;
0028 class DolphinSearchBox;
0029 class DolphinStatusBar;
0030 namespace SelectionMode
0031 {
0032 class TopBar;
0033 }
0034 
0035 /**
0036  * @short Represents a view for the directory content
0037  *        including the navigation bar, filter bar and status bar.
0038  *
0039  * View modes for icons, compact and details are supported. Currently
0040  * Dolphin allows to have up to two views inside the main window.
0041  *
0042  * @see DolphinView
0043  * @see FilterBar
0044  * @see KUrlNavigator
0045  * @see DolphinStatusBar
0046  */
0047 class DolphinViewContainer : public QWidget
0048 {
0049     Q_OBJECT
0050 
0051 public:
0052     enum MessageType { Information, Warning, Error };
0053 
0054     DolphinViewContainer(const QUrl &url, QWidget *parent);
0055     ~DolphinViewContainer() override;
0056 
0057     /**
0058      * Returns the current active URL, where all actions are applied.
0059      * The URL navigator is synchronized with this URL.
0060      */
0061     QUrl url() const;
0062     KFileItem rootItem() const;
0063 
0064     /**
0065      * If \a active is true, the view container will marked as active. The active
0066      * view container is defined as view where all actions are applied to.
0067      */
0068     void setActive(bool active);
0069     bool isActive() const;
0070 
0071     /**
0072      * If \a grab is set to true, the container automatically grabs the focus
0073      * as soon as the URL has been changed. Per default the grabbing
0074      * of the focus is enabled.
0075      */
0076     void setAutoGrabFocus(bool grab);
0077     bool autoGrabFocus() const;
0078 
0079     QString currentSearchText() const;
0080 
0081     const DolphinStatusBar *statusBar() const;
0082     DolphinStatusBar *statusBar();
0083 
0084     /**
0085      * @return  An UrlNavigator that is controlling this view
0086      *          or nullptr if there is none.
0087      * @see connectUrlNavigator()
0088      * @see disconnectUrlNavigator()
0089      *
0090      * Use urlNavigatorInternalWithHistory() if you want to access the history.
0091      * @see urlNavigatorInternalWithHistory()
0092      */
0093     const DolphinUrlNavigator *urlNavigator() const;
0094     /**
0095      * @return  An UrlNavigator that is controlling this view
0096      *          or nullptr if there is none.
0097      * @see connectUrlNavigator()
0098      * @see disconnectUrlNavigator()
0099      *
0100      * Use urlNavigatorInternalWithHistory() if you want to access the history.
0101      * @see urlNavigatorInternalWithHistory()
0102      */
0103     DolphinUrlNavigator *urlNavigator();
0104 
0105     /**
0106      * @return An UrlNavigator that contains this view's history.
0107      * Use urlNavigator() instead when not accessing the history.
0108      */
0109     const DolphinUrlNavigator *urlNavigatorInternalWithHistory() const;
0110     /**
0111      * @return An UrlNavigator that contains this view's history.
0112      * Use urlNavigator() instead when not accessing the history.
0113      */
0114     DolphinUrlNavigator *urlNavigatorInternalWithHistory();
0115 
0116     const DolphinView *view() const;
0117     DolphinView *view();
0118 
0119     /**
0120      * @param urlNavigator  The UrlNavigator that is supposed to control
0121      *                      this view.
0122      */
0123     void connectUrlNavigator(DolphinUrlNavigator *urlNavigator);
0124 
0125     /**
0126      * Disconnects the navigator that is currently controlling the view.
0127      * This method completely reverses connectUrlNavigator().
0128      */
0129     void disconnectUrlNavigator();
0130 
0131     /**
0132      * Sets a selection mode that is useful for quick and easy selecting or deselecting of files.
0133      * This method is the central authority about enabling or disabling selection mode:
0134      * All other classes that want to enable or disable selection mode should trigger a call of this method.
0135      *
0136      * This method sets the selection mode for the view of this viewContainer and sets the visibility of the
0137      * selection mode top and bottom bar which also belong to this viewContainer.
0138      *
0139      * @param enabled           Whether to enable or disable selection mode.
0140      * @param actionCollection  The collection of actions from which the actions on the bottom bar are retrieved.
0141      * @param bottomBarContents The contents the bar is supposed to show after this call.
0142      */
0143     void setSelectionModeEnabled(bool enabled,
0144                                  KActionCollection *actionCollection = nullptr,
0145                                  SelectionMode::BottomBar::Contents bottomBarContents = SelectionMode::BottomBar::Contents::GeneralContents);
0146     /** @see setSelectionModeEnabled() */
0147     bool isSelectionModeEnabled() const;
0148 
0149     /**
0150      * Shows the message \msg with the given type non-modal above
0151      * the view-content.
0152      */
0153     void showMessage(const QString &msg, MessageType type);
0154 
0155     /**
0156      * Refreshes the view container to get synchronized with the (updated) Dolphin settings.
0157      */
0158     void readSettings();
0159 
0160     /** Returns true, if the filter bar is visible. */
0161     bool isFilterBarVisible() const;
0162 
0163     /** Returns true if the search mode is enabled. */
0164     bool isSearchModeEnabled() const;
0165 
0166     /**
0167      * @return Text that should be used for the current URL when creating
0168      *         a new place.
0169      */
0170     QString placesText() const;
0171 
0172     /**
0173      * Reload the view of this container. This will also hide messages in a messagewidget.
0174      */
0175     void reload();
0176 
0177     /**
0178      * @return Returns a Caption suitable for display in the window title.
0179      * It is calculated depending on GeneralSettings::showFullPathInTitlebar().
0180      * If it's false, it calls caption().
0181      */
0182     QString captionWindowTitle() const;
0183 
0184     /**
0185      * @return Returns a Caption suitable for display to the user. It is
0186      * calculated depending on settings, if a search is active and other
0187      * factors.
0188      */
0189     QString caption() const;
0190 
0191     /**
0192      * Disable/enable the behavior of "select child when moving to parent folder"
0193      * offered by KUrlNavigator.
0194      *
0195      * See KUrlNavigator::urlSelectionRequested
0196      */
0197     void disableUrlNavigatorSelectionRequests();
0198     void enableUrlNavigatorSelectionRequests();
0199     void clearFilterBar();
0200 
0201 public Q_SLOTS:
0202     /**
0203      * Sets the current active URL, where all actions are applied. The
0204      * URL navigator is synchronized with this URL. The signals
0205      * KUrlNavigator::urlChanged() and KUrlNavigator::historyChanged()
0206      * are emitted.
0207      * @see DolphinViewContainer::urlNavigator()
0208      */
0209     void setUrl(const QUrl &url);
0210 
0211     /**
0212      * Popups the filter bar above the status bar if \a visible is true.
0213      * It \a visible is true, it is assured that the filter bar gains
0214      * the keyboard focus.
0215      */
0216     void setFilterBarVisible(bool visible);
0217 
0218     /**
0219      * Enables the search mode, if \p enabled is true. In the search mode the URL navigator
0220      * will be hidden and replaced by a line editor that allows to enter a search term.
0221      */
0222     void setSearchModeEnabled(bool enabled);
0223 
0224     /** Used to notify the m_selectionModeBottomBar that there is no other ViewContainer in the tab. */
0225     void slotSplitTabDisabled();
0226 
0227 Q_SIGNALS:
0228     /**
0229      * Is emitted whenever the filter bar has changed its visibility state.
0230      */
0231     void showFilterBarChanged(bool shown);
0232     /**
0233      * Is emitted whenever the search mode has changed its state.
0234      */
0235     void searchModeEnabledChanged(bool enabled);
0236 
0237     void selectionModeChanged(bool enabled);
0238 
0239     /**
0240      * Is emitted when the write state of the folder has been changed. The application
0241      * should disable all actions like "Create New..." that depend on the write
0242      * state.
0243      */
0244     void writeStateChanged(bool isFolderWritable);
0245 
0246     /**
0247      * Is emitted when the Caption has been changed.
0248      * @see DolphinViewContainer::caption()
0249      */
0250     void captionChanged();
0251 
0252     /**
0253      * Is emitted if a new tab should be opened in the background for the URL \a url.
0254      */
0255     void tabRequested(const QUrl &url);
0256 
0257     /**
0258      * Is emitted if a new tab should be opened for the URL \a url and set as active.
0259      */
0260     void activeTabRequested(const QUrl &url);
0261 
0262 private Q_SLOTS:
0263     /**
0264      * Updates the number of items (= number of files + number of
0265      * directories) in the statusbar. If files are selected, the number
0266      * of selected files and the sum of the filesize is shown. The update
0267      * is done asynchronously, as getting the sum of the
0268      * filesizes can be an expensive operation.
0269      * Unless a previous OperationCompletedMessage was set very shortly before
0270      * calling this method, it will be overwritten (see DolphinStatusBar::setMessage).
0271      * Previous ErrorMessages however are always preserved.
0272      */
0273     void delayedStatusBarUpdate();
0274 
0275     /**
0276      * Is invoked by DolphinViewContainer::delayedStatusBarUpdate() and
0277      * updates the status bar synchronously.
0278      */
0279     void updateStatusBar();
0280 
0281     void updateDirectoryLoadingProgress(int percent);
0282 
0283     void updateDirectorySortingProgress(int percent);
0284 
0285     /**
0286      * Updates the statusbar to show an undetermined progress with the correct
0287      * context information whether a searching or a directory loading is done.
0288      */
0289     void slotDirectoryLoadingStarted();
0290 
0291     /**
0292      * Assures that the viewport position is restored and updates the
0293      * statusbar to reflect the current content.
0294      */
0295     void slotDirectoryLoadingCompleted();
0296 
0297     /**
0298      * Updates the statusbar to show, that the directory loading has
0299      * been canceled.
0300      */
0301     void slotDirectoryLoadingCanceled();
0302 
0303     /**
0304      * Is called if the URL set by DolphinView::setUrl() represents
0305      * a file and not a directory. Takes care to activate the file.
0306      */
0307     void slotUrlIsFileError(const QUrl &url);
0308 
0309     /**
0310      * Handles clicking on an item. If the item is a directory, the
0311      * directory is opened in the view. If the item is a file, the file
0312      * gets started by the corresponding application.
0313      */
0314     void slotItemActivated(const KFileItem &item);
0315 
0316     /**
0317      * Handles activation of multiple files. The files get started by
0318      * the corresponding applications.
0319      */
0320     void slotItemsActivated(const KFileItemList &items);
0321 
0322     /**
0323      * Handles middle click of file. It opens the file passed using the second application associated with the file's mimetype.
0324      */
0325     void slotfileMiddleClickActivated(const KFileItem &item);
0326 
0327     /**
0328      * Shows the information for the item \a item inside the statusbar. If the
0329      * item is null, the default statusbar information is shown.
0330      */
0331     void showItemInfo(const KFileItem &item);
0332 
0333     void closeFilterBar();
0334 
0335     /**
0336      * Filters the currently shown items by \a nameFilter. All items
0337      * which contain the given filter string will be shown.
0338      */
0339     void setNameFilter(const QString &nameFilter);
0340 
0341     /**
0342      * Marks the view container as active
0343      * (see DolphinViewContainer::setActive()).
0344      */
0345     void activate();
0346 
0347     /**
0348      * Is invoked if the signal urlAboutToBeChanged() from the URL navigator
0349      * is emitted. Tries to save the view-state.
0350      */
0351     void slotUrlNavigatorLocationAboutToBeChanged(const QUrl &url);
0352 
0353     /**
0354      * Restores the current view to show \a url and assures
0355      * that the root URL of the view is respected.
0356      */
0357     void slotUrlNavigatorLocationChanged(const QUrl &url);
0358 
0359     /**
0360      * @see KUrlNavigator::urlSelectionRequested
0361      */
0362     void slotUrlSelectionRequested(const QUrl &url);
0363 
0364     /**
0365      * Is invoked when a redirection is done and changes the
0366      * URL of the URL navigator to \a newUrl without triggering
0367      * a reloading of the directory.
0368      */
0369     void redirect(const QUrl &oldUrl, const QUrl &newUrl);
0370 
0371     /** Requests the focus for the view \a m_view. */
0372     void requestFocus();
0373 
0374     /**
0375      * Gets the search URL from the searchbox and starts searching.
0376      */
0377     void startSearching();
0378     void openSearchBox();
0379     void closeSearchBox();
0380 
0381     /**
0382      * Stops the loading of a directory. Is connected with the "stopPressed" signal
0383      * from the statusbar.
0384      */
0385     void stopDirectoryLoading();
0386 
0387     void slotStatusBarZoomLevelChanged(int zoomLevel);
0388 
0389     /**
0390      * Slot that calls showMessage(msg, Error).
0391      */
0392     void showErrorMessage(const QString &msg);
0393 
0394     /**
0395      * Is invoked when a KFilePlacesModel has been changed
0396      * @see DolphinPlacesModelSingleton::instance().placesModel()
0397      */
0398     void slotPlacesModelChanged();
0399 
0400     void slotHiddenFilesShownChanged(bool showHiddenFiles);
0401     void slotSortHiddenLastChanged(bool hiddenLast);
0402     void slotCurrentDirectoryRemoved();
0403 
0404     void slotOpenUrlFinished(KJob *job);
0405 
0406 private:
0407     /**
0408      * @return True if the URL protocol is a search URL (e. g. baloosearch:// or filenamesearch://).
0409      */
0410     bool isSearchUrl(const QUrl &url) const;
0411 
0412     /**
0413      * Saves the state of the current view: contents position,
0414      * root URL, ...
0415      */
0416     void saveViewState();
0417 
0418     /**
0419      * Restores the state of the current view iff the URL navigator contains a
0420      * non-empty location state.
0421      */
0422     void tryRestoreViewState();
0423 
0424     /**
0425      * @return Path of nearest existing ancestor directory.
0426      */
0427     QString getNearestExistingAncestorOfPath(const QString &path) const;
0428 
0429 private:
0430     QGridLayout *m_topLayout;
0431 
0432     /**
0433      * The internal UrlNavigator which is never visible to the user.
0434      * m_urlNavigator is used even when another UrlNavigator is controlling
0435      * the view to keep track of this object's history.
0436      */
0437     std::unique_ptr<DolphinUrlNavigator> m_urlNavigator;
0438 
0439     /**
0440      * The UrlNavigator that is currently connected to the view.
0441      * This is a nullptr if no UrlNavigator is connected.
0442      * Otherwise it's one of the UrlNavigators visible in the toolbar.
0443      */
0444     QPointer<DolphinUrlNavigator> m_urlNavigatorConnected;
0445 
0446     DolphinSearchBox *m_searchBox;
0447     bool m_searchModeEnabled;
0448 
0449     KMessageWidget *m_messageWidget;
0450 
0451     /// A bar shown at the top of the view to signify that selection mode is currently active.
0452     SelectionMode::TopBar *m_selectionModeTopBar;
0453 
0454     DolphinView *m_view;
0455 
0456     FilterBar *m_filterBar;
0457 
0458     /// A bar shown at the bottom of the view whose contents depend on what the user is currently doing.
0459     SelectionMode::BottomBar *m_selectionModeBottomBar;
0460 
0461     DolphinStatusBar *m_statusBar;
0462     QTimer *m_statusBarTimer; // Triggers a delayed update
0463     QElapsedTimer m_statusBarTimestamp; // Time in ms since last update
0464     bool m_autoGrabFocus;
0465     /**
0466      * The visual state to be applied to the next UrlNavigator that gets
0467      * connected to this ViewContainer.
0468      */
0469     std::unique_ptr<DolphinUrlNavigator::VisualState> m_urlNavigatorVisualState;
0470 };
0471 
0472 #endif // DOLPHINVIEWCONTAINER_H