]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphinnavigatorswidgetaction.h
Fix various typos
[dolphin.git] / src / dolphinnavigatorswidgetaction.h
1 /*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2020 Felix Ernst <fe.a.ernst@gmail.com>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7
8 #ifndef DOLPHINNAVIGATORSWIDGETACTION_H
9 #define DOLPHINNAVIGATORSWIDGETACTION_H
10
11 #include "dolphinurlnavigator.h"
12
13 #include <QPointer>
14 #include <QSplitter>
15 #include <QTimer>
16 #include <QWidgetAction>
17
18 #include <memory>
19
20 class KXmlGuiWindow;
21 class QPushButton;
22
23 /**
24 * @brief QWidgetAction that allows to use DolphinUrlNavigators in a toolbar.
25 *
26 * This class is mainly a container that manages up to two DolphinUrlNavigator objects so they
27 * can be added to a toolbar. It also deals with alignment.
28 *
29 * The structure of the defaultWidget() of this QWidgetAction is as follows:
30 * - A QSplitter manages up to two sides which each correspond to one DolphinViewContainer.
31 * The secondary side only exists for split view and is created by
32 * createSecondaryUrlNavigator() when necessary.
33 * - Each side is a QWidget which I call NavigatorWidget with a QHBoxLayout.
34 * - Each NavigatorWidget consists an UrlNavigator, an emptyTrashButton, a
35 * networkFolderButton, and spacing.
36 * - Only the primary navigatorWidget has leading spacing. Both have trailing spacing.
37 * The spacing is there to align the UrlNavigator with its DolphinViewContainer.
38 */
39 class DolphinNavigatorsWidgetAction : public QWidgetAction
40 {
41 Q_OBJECT
42
43 public:
44 DolphinNavigatorsWidgetAction(QWidget *parent = nullptr);
45
46 /**
47 * Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers.
48 * This can only work nicely if up-to-date geometry of ViewContainers is cached so
49 * followViewContainersGeometry() has to have been called at least once before.
50 */
51 void adjustSpacing();
52
53 /**
54 * The secondary UrlNavigator is only created on-demand. Such an action is not necessary
55 * for the primary UrlNavigator which is created preemptively.
56 *
57 * This method should preferably only be called when:
58 * - Split view is activated in the active tab
59 * OR
60 * - A switch to a tab that is already in split view mode is occurring
61 */
62 void createSecondaryUrlNavigator();
63
64 /**
65 * Notify this widget of changes in geometry of the ViewContainers it tries to be
66 * aligned with.
67 */
68 void followViewContainersGeometry(QWidget *primaryViewContainer,
69 QWidget *secondaryViewContainer = nullptr);
70
71 bool isInToolbar() const;
72
73 /**
74 * @return the primary UrlNavigator.
75 */
76 DolphinUrlNavigator *primaryUrlNavigator() const;
77 /**
78 * @return the secondary UrlNavigator and nullptr if it doesn't exist.
79 */
80 DolphinUrlNavigator *secondaryUrlNavigator() const;
81
82 /**
83 * Change the visibility of the secondary UrlNavigator including spacing.
84 * @param visible Setting this to false will completely hide the secondary side of this
85 * WidgetAction's QSplitter making the QSplitter effectively disappear.
86 */
87 void setSecondaryNavigatorVisible(bool visible);
88
89 protected:
90 /**
91 * There should always ever be one navigatorsWidget for this action so
92 * this method always returns the same widget and reparents it.
93 * You normally don't have to use this method directly because
94 * QWidgetAction::requestWidget() is used to obtain the navigatorsWidget
95 * and to steal it from wherever it was prior.
96 * @param parent the new parent of the navigatorsWidget.
97 */
98 QWidget *createWidget(QWidget *parent) override;
99
100 /** @see QWidgetAction::deleteWidget() */
101 void deleteWidget(QWidget *widget) override;
102
103 private:
104 /**
105 * In Left-to-right languages the Primary side will be the left one.
106 */
107 enum Side {
108 Primary,
109 Secondary
110 };
111 /**
112 * Used to create the navigatorWidgets for both sides of the QSplitter.
113 */
114 QWidget *createNavigatorWidget(Side side) const;
115
116 /**
117 * Used to retrieve the emptyTrashButtons for the navigatorWidgets on both sides.
118 */
119 QPushButton *emptyTrashButton(Side side);
120
121 /**
122 * Creates a new empty trash button.
123 * @param urlNavigator Only when this UrlNavigator shows the trash directory
124 * will the button be visible.
125 * @param parent Aside from the usual QObject deletion mechanisms,
126 * this parameter influences the positioning of dialog windows
127 * pertaining to this trash button.
128 */
129 QPushButton *newEmptyTrashButton(const DolphinUrlNavigator *urlNavigator, QWidget *parent) const;
130
131 /**
132 * Used to retrieve the networkFolderButtons for the navigatorWidgets on
133 * both sides.
134 */
135 QPushButton *networkFolderButton(Side side);
136
137 /**
138 * Creates a new add "network folder" button.
139 * @param urlNavigator Only when this UrlNavigator shows the remote directory
140 * will the button be visible.
141 * @param parent The object that should be the button's parent.
142 */
143 QPushButton *newNetworkFolderButton(const DolphinUrlNavigator *urlNavigator, QWidget *parent) const;
144
145 enum Position {
146 Leading,
147 Trailing
148 };
149 /**
150 * Used to retrieve both the leading and trailing spacing for the navigatorWidgets
151 * on both sides. A secondary leading spacing does not exist.
152 */
153 QWidget *spacing(Side side, Position position) const;
154
155 /**
156 * Sets this action's text depending on the amount of visible UrlNavigators.
157 */
158 void updateText();
159
160 /**
161 * The defaultWidget() of this QWidgetAction.
162 */
163 std::unique_ptr<QSplitter> m_splitter;
164
165 /**
166 * adjustSpacing() has to be called slightly later than when urlChanged is emitted.
167 * This timer bridges that time.
168 */
169 std::unique_ptr<QTimer> m_adjustSpacingTimer;
170
171 /**
172 * Extracts the geometry information needed by adjustSpacing() from
173 * ViewContainers. They are also monitored for size changes which
174 * will lead to adjustSpacing() calls.
175 */
176 class ViewGeometriesHelper : public QObject
177 {
178 public:
179 /**
180 * @param navigatorsWidget The QWidget of the navigatorsWidgetAction.
181 * @param navigatorsWidgetAction is only used to call adjustSpacing() whenever that is
182 * deemed necessary.
183 */
184 ViewGeometriesHelper(QWidget *navigatorsWidget, DolphinNavigatorsWidgetAction *navigatorsWidgetAction);
185
186 /**
187 * Calls m_navigatorsWidgetAction::adjustSpacing() when a watched object is resized.
188 */
189 bool eventFilter(QObject *watched, QEvent *event) override;
190
191 /**
192 * Sets the ViewContainers whose geometry is obtained when viewGeometries() is called.
193 */
194 void setViewContainers(QWidget *primaryViewContainer,
195 QWidget *secondaryViewContainer = nullptr);
196
197 struct Geometries {
198 int globalXOfNavigatorsWidget;
199 int globalXOfPrimary;
200 int widthOfPrimary;
201 int globalXOfSecondary;
202 int widthOfSecondary;
203 };
204 /**
205 * @return a Geometries struct that contains values adjustSpacing() requires.
206 */
207 Geometries viewGeometries();
208
209 private:
210 QWidget *m_navigatorsWidget;
211 /** Is only used to call adjustSpacing() whenever that is deemed necessary. */
212 DolphinNavigatorsWidgetAction *m_navigatorsWidgetAction;
213
214 QPointer<QWidget> m_primaryViewContainer;
215 QPointer<QWidget> m_secondaryViewContainer;
216 };
217
218 ViewGeometriesHelper m_viewGeometriesHelper;
219
220 /**
221 * Used to check if the window has been resized.
222 * @see ViewGeometriesHelper::eventFilter() for why this is needed.
223 */
224 int m_previousWindowWidth = -1;
225 };
226
227 #endif // DOLPHINNAVIGATORSWIDGETACTION_H