]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinnavigatorswidgetaction.h
DolphinStatusbar: Fix background and margins for non-Breeze styles
[dolphin.git] / src / dolphinnavigatorswidgetaction.h
index c1808d68e6a7ddd68d864a9f93d6ffcef0efae28..c9ce4ece2c5682fb44f7a64e799c3c2606f4aa9a 100644 (file)
@@ -1,6 +1,6 @@
 /*
     This file is part of the KDE project
-    SPDX-FileCopyrightText: 2020 Felix Ernst <fe.a.ernst@gmail.com>
+    SPDX-FileCopyrightText: 2020 Felix Ernst <felixernst@kde.org>
 
     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
 */
@@ -10,6 +10,7 @@
 
 #include "dolphinurlnavigator.h"
 
+#include <QPointer>
 #include <QSplitter>
 #include <QTimer>
 #include <QWidgetAction>
@@ -30,7 +31,8 @@ class QPushButton;
  *      The secondary side only exists for split view and is created by
  *      createSecondaryUrlNavigator() when necessary.
  * - Each side is a QWidget which I call NavigatorWidget with a QHBoxLayout.
- * - Each NavigatorWidget consists an UrlNavigator, an emptyTrashButton and spacing.
+ * - Each NavigatorWidget consists an UrlNavigator, an emptyTrashButton, a
+ *   networkFolderButton, and spacing.
  * - Only the primary navigatorWidget has leading spacing. Both have trailing spacing.
  *      The spacing is there to align the UrlNavigator with its DolphinViewContainer.
  */
@@ -38,40 +40,34 @@ class DolphinNavigatorsWidgetAction : public QWidgetAction
 {
     Q_OBJECT
 
-    /**
-     * In Left-to-right languages the Primary side will be the left one.
-     */
-    enum Side {
-        Primary,
-        Secondary
-    };
-
 public:
     DolphinNavigatorsWidgetAction(QWidget *parent = nullptr);
 
     /**
-     * Adds this action to the mainWindow's toolbar and saves the change
-     * in the users ui configuration file.
-     * @return true if successful. Otherwise false.
+     * Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers.
+     * This can only work nicely if up-to-date geometry of ViewContainers is cached so
+     * followViewContainersGeometry() has to have been called at least once before.
      */
-    bool addToToolbarAndSave(KXmlGuiWindow *mainWindow);
+    void adjustSpacing();
 
     /**
-     * Different to the primary UrlNavigator, the secondary UrlNavigator is only created on-demand.
+     * The secondary UrlNavigator is only created on-demand. Such an action is not necessary
+     * for the primary UrlNavigator which is created preemptively.
+     *
+     * This method should preferably only be called when:
+     * - Split view is activated in the active tab
+     * OR
+     * - A switch to a tab that is already in split view mode is occurring
      */
     void createSecondaryUrlNavigator();
 
-    /**
-     * Notify the primary UrlNavigator of changes in geometry of the ViewContainer it tries to be
-     * aligned with. Only call this method if there is no secondary UrlNavigator.
-     */
-    void followViewContainerGeometry(int globalXOfPrimary,   int widthOfPrimary);
     /**
      * Notify this widget of changes in geometry of the ViewContainers it tries to be
      * aligned with.
      */
-    void followViewContainersGeometry(int globalXOfPrimary,   int widthOfPrimary,
-                                      int globalXOfSecondary, int widthOfSecondary);
+    void followViewContainersGeometry(QWidget *primaryViewContainer, QWidget *secondaryViewContainer = nullptr);
+
+    bool isInToolbar() const;
 
     /**
      * @return the primary UrlNavigator.
@@ -89,14 +85,32 @@ public:
      */
     void setSecondaryNavigatorVisible(bool visible);
 
+    /**
+     * Sets the background cosmetic of the location bar(s) visible or hidden.
+     * In frameless designs it's better to hide the background.
+     * @param enabled True for showing background cosmetic, false for hiding it.
+     */
+    void setBackgroundEnabled(bool enabled);
+
 protected:
     /**
-     * Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers.
-     * This can only work nicely if up-to-date geometry of ViewContainers is cached so
-     * followViewContainersGeometry() has to have been called at least once before.
+     * There should always ever be one navigatorsWidget for this action so
+     * this method always returns the same widget and reparents it.
+     * You normally don't have to use this method directly because
+     * QWidgetAction::requestWidget() is used to obtain the navigatorsWidget
+     * and to steal it from wherever it was prior.
+     * @param parent the new parent of the navigatorsWidget.
      */
-    void adjustSpacing();
+    QWidget *createWidget(QWidget *parent) override;
+
+    /** @see QWidgetAction::deleteWidget() */
+    void deleteWidget(QWidget *widget) override;
 
+private:
+    /**
+     * In Left-to-right languages the Primary side will be the left one.
+     */
+    enum Side { Primary, Secondary };
     /**
      * Used to create the navigatorWidgets for both sides of the QSplitter.
      */
@@ -110,23 +124,39 @@ protected:
     /**
      * Creates a new empty trash button.
      * @param urlNavigator Only when this UrlNavigator shows the trash directory
-     *                     will the the button be visible.
+     *                     will the button be visible.
      * @param parent       Aside from the usual QObject deletion mechanisms,
      *                     this parameter influences the positioning of dialog windows
      *                     pertaining to this trash button.
      */
     QPushButton *newEmptyTrashButton(const DolphinUrlNavigator *urlNavigator, QWidget *parent) const;
 
-    enum Position {
-        Leading,
-        Trailing
-    };
+    /**
+     * Used to retrieve the networkFolderButtons for the navigatorWidgets on
+     * both sides.
+     */
+    QPushButton *networkFolderButton(Side side);
+
+    /**
+     * Creates a new add "network folder" button.
+     * @param urlNavigator Only when this UrlNavigator shows the remote directory
+     *                     will the button be visible.
+     * @param parent       The object that should be the button's parent.
+     */
+    QPushButton *newNetworkFolderButton(const DolphinUrlNavigator *urlNavigator, QWidget *parent) const;
+
+    enum Position { Leading, Trailing };
     /**
      * Used to retrieve both the leading and trailing spacing for the navigatorWidgets
      * on both sides. A secondary leading spacing does not exist.
      */
     QWidget *spacing(Side side, Position position) const;
 
+    /**
+     * Sets this action's text depending on the amount of visible UrlNavigators.
+     */
+    void updateText();
+
     /**
      * The defaultWidget() of this QWidgetAction.
      */
@@ -138,12 +168,59 @@ protected:
      */
     std::unique_ptr<QTimer> m_adjustSpacingTimer;
 
-    // cached values
-    int m_globalXOfSplitter;
-    int m_globalXOfPrimary;
-    int m_widthOfPrimary;
-    int m_globalXOfSecondary;
-    int m_widthOfSecondary;
+    /**
+     * Extracts the geometry information needed by adjustSpacing() from
+     * ViewContainers. They are also monitored for size changes which
+     * will lead to adjustSpacing() calls.
+     */
+    class ViewGeometriesHelper : public QObject
+    {
+    public:
+        /**
+         * @param navigatorsWidget       The QWidget of the navigatorsWidgetAction.
+         * @param navigatorsWidgetAction is only used to call adjustSpacing() whenever that is
+         *                               deemed necessary.
+         */
+        ViewGeometriesHelper(QWidget *navigatorsWidget, DolphinNavigatorsWidgetAction *navigatorsWidgetAction);
+
+        /**
+         * Calls m_navigatorsWidgetAction::adjustSpacing() when a watched object is resized.
+         */
+        bool eventFilter(QObject *watched, QEvent *event) override;
+
+        /**
+         * Sets the ViewContainers whose geometry is obtained when viewGeometries() is called.
+         */
+        void setViewContainers(QWidget *primaryViewContainer, QWidget *secondaryViewContainer = nullptr);
+
+        struct Geometries {
+            int globalXOfNavigatorsWidget;
+            int globalXOfPrimary;
+            int widthOfPrimary;
+            int globalXOfSecondary;
+            int widthOfSecondary;
+        };
+        /**
+         * @return a Geometries struct that contains values adjustSpacing() requires.
+         */
+        Geometries viewGeometries();
+
+    private:
+        QWidget *m_navigatorsWidget;
+        /** Is only used to call adjustSpacing() whenever that is deemed necessary. */
+        DolphinNavigatorsWidgetAction *m_navigatorsWidgetAction;
+
+        QPointer<QWidget> m_primaryViewContainer;
+        QPointer<QWidget> m_secondaryViewContainer;
+    };
+
+    ViewGeometriesHelper m_viewGeometriesHelper;
+
+    /**
+     * Used to check if the window has been resized.
+     * @see ViewGeometriesHelper::eventFilter() for why this is needed.
+     */
+    int m_previousWindowWidth = -1;
 };
 
 #endif // DOLPHINNAVIGATORSWIDGETACTION_H