]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphinnavigatorswidgetaction.h
Show button to open knetattach inline with URL nav on remove:// view
[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 <kio_version.h>
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 (for frameworks >= 5.78), 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 * The secondary UrlNavigator is only created on-demand. Such an action is not necessary
48 * for the primary UrlNavigator which is created preemptively.
49 *
50 * This method should preferably only be called when:
51 * - Split view is activated in the active tab
52 * OR
53 * - A switch to a tab that is already in split view mode is occuring
54 */
55 void createSecondaryUrlNavigator();
56
57 /**
58 * Notify the primary UrlNavigator of changes in geometry of the ViewContainer it tries to be
59 * aligned with. Only call this method if there is no secondary UrlNavigator.
60 */
61 void followViewContainerGeometry(int globalXOfPrimary, int widthOfPrimary);
62 /**
63 * Notify this widget of changes in geometry of the ViewContainers it tries to be
64 * aligned with.
65 */
66 void followViewContainersGeometry(int globalXOfPrimary, int widthOfPrimary,
67 int globalXOfSecondary, int widthOfSecondary);
68
69 bool isInToolbar() const;
70
71 /**
72 * @return the primary UrlNavigator.
73 */
74 DolphinUrlNavigator *primaryUrlNavigator() const;
75 /**
76 * @return the secondary UrlNavigator and nullptr if it doesn't exist.
77 */
78 DolphinUrlNavigator *secondaryUrlNavigator() const;
79
80 /**
81 * Change the visibility of the secondary UrlNavigator including spacing.
82 * @param visible Setting this to false will completely hide the secondary side of this
83 * WidgetAction's QSplitter making the QSplitter effectively disappear.
84 */
85 void setSecondaryNavigatorVisible(bool visible);
86
87 protected:
88 /**
89 * There should always ever be one navigatorsWidget for this action so
90 * this method always returns the same widget and reparents it.
91 * You normally don't have to use this method directly because
92 * QWidgetAction::requestWidget() is used to obtain the navigatorsWidget
93 * and to steal it from whereever it was prior.
94 * @param parent the new parent of the navigatorsWidget.
95 */
96 QWidget *createWidget(QWidget *parent) override;
97
98 /** @see QWidgetAction::deleteWidget() */
99 void deleteWidget(QWidget *widget) override;
100
101 private:
102 /**
103 * Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers.
104 * This can only work nicely if up-to-date geometry of ViewContainers is cached so
105 * followViewContainersGeometry() has to have been called at least once before.
106 */
107 void adjustSpacing();
108
109 /**
110 * In Left-to-right languages the Primary side will be the left one.
111 */
112 enum Side {
113 Primary,
114 Secondary
115 };
116 /**
117 * Used to create the navigatorWidgets for both sides of the QSplitter.
118 */
119 QWidget *createNavigatorWidget(Side side) const;
120
121 /**
122 * Used to retrieve the emptyTrashButtons for the navigatorWidgets on both sides.
123 */
124 QPushButton *emptyTrashButton(Side side);
125
126 /**
127 * Creates a new empty trash button.
128 * @param urlNavigator Only when this UrlNavigator shows the trash directory
129 * will the the button be visible.
130 * @param parent Aside from the usual QObject deletion mechanisms,
131 * this parameter influences the positioning of dialog windows
132 * pertaining to this trash button.
133 */
134 QPushButton *newEmptyTrashButton(const DolphinUrlNavigator *urlNavigator, QWidget *parent) const;
135
136 #if !(KIO_VERSION < QT_VERSION_CHECK(5, 78, 0))
137 /**
138 * Used to retrieve the networkFolderButtons for the navigatorWidgets on
139 * both sides.
140 */
141 QPushButton *networkFolderButton(Side side);
142
143 /**
144 * Creates a new add "network folder" button.
145 * @param urlNavigator Only when this UrlNavigator shows the remote directory
146 * will the button be visible.
147 * @param parent The object that should be the button's parent.
148 */
149 QPushButton *newNetworkFolderButton(const DolphinUrlNavigator *urlNavigator, QWidget *parent) const;
150 #endif
151
152 enum Position {
153 Leading,
154 Trailing
155 };
156 /**
157 * Used to retrieve both the leading and trailing spacing for the navigatorWidgets
158 * on both sides. A secondary leading spacing does not exist.
159 */
160 QWidget *spacing(Side side, Position position) const;
161
162 /**
163 * Sets this action's text depending on the amount of visible UrlNavigators.
164 */
165 void updateText();
166
167 /**
168 * The defaultWidget() of this QWidgetAction.
169 */
170 std::unique_ptr<QSplitter> m_splitter;
171
172 /**
173 * adjustSpacing() has to be called slightly later than when urlChanged is emitted.
174 * This timer bridges that time.
175 */
176 std::unique_ptr<QTimer> m_adjustSpacingTimer;
177
178 // cached values
179 int m_globalXOfSplitter;
180 int m_globalXOfPrimary;
181 int m_widthOfPrimary;
182 int m_globalXOfSecondary;
183 int m_widthOfSecondary;
184 };
185
186 #endif // DOLPHINNAVIGATORSWIDGETACTION_H