]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphintabpage.cpp
Add the UrlNavigator to the toolbar automatically if needed
[dolphin.git] / src / dolphintabpage.cpp
1 /*
2 * SPDX-FileCopyrightText: 2014 Emmanuel Pescosta <emmanuelpescosta099@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "dolphintabpage.h"
8
9 #include "dolphin_generalsettings.h"
10 #include "dolphinviewcontainer.h"
11
12 #include <QSplitter>
13 #include <QVBoxLayout>
14
15 DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, QWidget* parent) :
16 QWidget(parent),
17 m_primaryViewActive(true),
18 m_splitViewEnabled(false),
19 m_active(true)
20 {
21 QVBoxLayout* layout = new QVBoxLayout(this);
22 layout->setSpacing(0);
23 layout->setContentsMargins(0, 0, 0, 0);
24
25 m_splitter = new QSplitter(Qt::Horizontal, this);
26 m_splitter->setChildrenCollapsible(false);
27 layout->addWidget(m_splitter);
28
29 // Create a new primary view
30 m_primaryViewContainer = createViewContainer(primaryUrl);
31 connect(m_primaryViewContainer->view(), &DolphinView::urlChanged,
32 this, &DolphinTabPage::activeViewUrlChanged);
33 connect(m_primaryViewContainer->view(), &DolphinView::redirection,
34 this, &DolphinTabPage::slotViewUrlRedirection);
35
36 m_splitter->addWidget(m_primaryViewContainer);
37 m_primaryViewContainer->show();
38
39 if (secondaryUrl.isValid() || GeneralSettings::splitView()) {
40 // Provide a secondary view, if the given secondary url is valid or if the
41 // startup settings are set this way (use the url of the primary view).
42 m_splitViewEnabled = true;
43 const QUrl& url = secondaryUrl.isValid() ? secondaryUrl : primaryUrl;
44 m_secondaryViewContainer = createViewContainer(url);
45 m_splitter->addWidget(m_secondaryViewContainer);
46 m_secondaryViewContainer->show();
47 }
48
49 m_primaryViewContainer->setActive(true);
50 }
51
52 bool DolphinTabPage::primaryViewActive() const
53 {
54 return m_primaryViewActive;
55 }
56
57 bool DolphinTabPage::splitViewEnabled() const
58 {
59 return m_splitViewEnabled;
60 }
61
62 void DolphinTabPage::setSplitViewEnabled(bool enabled, const QUrl &secondaryUrl)
63 {
64 if (m_splitViewEnabled != enabled) {
65 m_splitViewEnabled = enabled;
66
67 if (enabled) {
68 const QUrl& url = (secondaryUrl.isEmpty()) ? m_primaryViewContainer->url() : secondaryUrl;
69 m_secondaryViewContainer = createViewContainer(url);
70
71 m_splitter->addWidget(m_secondaryViewContainer);
72 m_secondaryViewContainer->show();
73 m_secondaryViewContainer->setActive(true);
74 } else {
75 DolphinViewContainer* view;
76 if (GeneralSettings::closeActiveSplitView()) {
77 view = activeViewContainer();
78 if (m_primaryViewActive) {
79 // If the primary view is active, we have to swap the pointers
80 // because the secondary view will be the new primary view.
81 qSwap(m_primaryViewContainer, m_secondaryViewContainer);
82 m_primaryViewActive = false;
83 }
84 } else {
85 view = m_primaryViewActive ? m_secondaryViewContainer : m_primaryViewContainer;
86 if (!m_primaryViewActive) {
87 // If the secondary view is active, we have to swap the pointers
88 // because the secondary view will be the new primary view.
89 qSwap(m_primaryViewContainer, m_secondaryViewContainer);
90 m_primaryViewActive = true;
91 }
92 }
93 m_primaryViewContainer->setActive(true);
94 view->close();
95 view->deleteLater();
96 }
97 }
98 }
99
100 DolphinViewContainer* DolphinTabPage::primaryViewContainer() const
101 {
102 return m_primaryViewContainer;
103 }
104
105 DolphinViewContainer* DolphinTabPage::secondaryViewContainer() const
106 {
107 return m_secondaryViewContainer;
108 }
109
110 DolphinViewContainer* DolphinTabPage::activeViewContainer() const
111 {
112 return m_primaryViewActive ? m_primaryViewContainer :
113 m_secondaryViewContainer;
114 }
115
116 KFileItemList DolphinTabPage::selectedItems() const
117 {
118 KFileItemList items = m_primaryViewContainer->view()->selectedItems();
119 if (m_splitViewEnabled) {
120 items += m_secondaryViewContainer->view()->selectedItems();
121 }
122 return items;
123 }
124
125 int DolphinTabPage::selectedItemsCount() const
126 {
127 int selectedItemsCount = m_primaryViewContainer->view()->selectedItemsCount();
128 if (m_splitViewEnabled) {
129 selectedItemsCount += m_secondaryViewContainer->view()->selectedItemsCount();
130 }
131 return selectedItemsCount;
132 }
133
134 void DolphinTabPage::markUrlsAsSelected(const QList<QUrl>& urls)
135 {
136 m_primaryViewContainer->view()->markUrlsAsSelected(urls);
137 if (m_splitViewEnabled) {
138 m_secondaryViewContainer->view()->markUrlsAsSelected(urls);
139 }
140 }
141
142 void DolphinTabPage::markUrlAsCurrent(const QUrl& url)
143 {
144 m_primaryViewContainer->view()->markUrlAsCurrent(url);
145 if (m_splitViewEnabled) {
146 m_secondaryViewContainer->view()->markUrlAsCurrent(url);
147 }
148 }
149
150 void DolphinTabPage::refreshViews()
151 {
152 m_primaryViewContainer->readSettings();
153 if (m_splitViewEnabled) {
154 m_secondaryViewContainer->readSettings();
155 }
156 }
157
158 QByteArray DolphinTabPage::saveState() const
159 {
160 QByteArray state;
161 QDataStream stream(&state, QIODevice::WriteOnly);
162
163 stream << quint32(2); // Tab state version
164
165 stream << m_splitViewEnabled;
166
167 stream << m_primaryViewContainer->url();
168 stream << m_primaryViewContainer->urlNavigatorInternalWithHistory()->isUrlEditable();
169 m_primaryViewContainer->view()->saveState(stream);
170
171 if (m_splitViewEnabled) {
172 stream << m_secondaryViewContainer->url();
173 stream << m_secondaryViewContainer->urlNavigatorInternalWithHistory()->isUrlEditable();
174 m_secondaryViewContainer->view()->saveState(stream);
175 }
176
177 stream << m_primaryViewActive;
178 stream << m_splitter->saveState();
179
180 return state;
181 }
182
183 void DolphinTabPage::restoreState(const QByteArray& state)
184 {
185 if (state.isEmpty()) {
186 return;
187 }
188
189 QByteArray sd = state;
190 QDataStream stream(&sd, QIODevice::ReadOnly);
191
192 // Read the version number of the tab state and check if the version is supported.
193 quint32 version = 0;
194 stream >> version;
195 if (version != 2) {
196 // The version of the tab state isn't supported, we can't restore it.
197 return;
198 }
199
200 bool isSplitViewEnabled = false;
201 stream >> isSplitViewEnabled;
202 setSplitViewEnabled(isSplitViewEnabled);
203
204 QUrl primaryUrl;
205 stream >> primaryUrl;
206 m_primaryViewContainer->setUrl(primaryUrl);
207 bool primaryUrlEditable;
208 stream >> primaryUrlEditable;
209 m_primaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(primaryUrlEditable);
210 m_primaryViewContainer->view()->restoreState(stream);
211
212 if (isSplitViewEnabled) {
213 QUrl secondaryUrl;
214 stream >> secondaryUrl;
215 m_secondaryViewContainer->setUrl(secondaryUrl);
216 bool secondaryUrlEditable;
217 stream >> secondaryUrlEditable;
218 m_secondaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(secondaryUrlEditable);
219 m_secondaryViewContainer->view()->restoreState(stream);
220 }
221
222 stream >> m_primaryViewActive;
223 if (m_primaryViewActive) {
224 m_primaryViewContainer->setActive(true);
225 } else {
226 Q_ASSERT(m_splitViewEnabled);
227 m_secondaryViewContainer->setActive(true);
228 }
229
230 QByteArray splitterState;
231 stream >> splitterState;
232 m_splitter->restoreState(splitterState);
233 }
234
235 void DolphinTabPage::restoreStateV1(const QByteArray& state)
236 {
237 if (state.isEmpty()) {
238 return;
239 }
240
241 QByteArray sd = state;
242 QDataStream stream(&sd, QIODevice::ReadOnly);
243
244 bool isSplitViewEnabled = false;
245 stream >> isSplitViewEnabled;
246 setSplitViewEnabled(isSplitViewEnabled);
247
248 QUrl primaryUrl;
249 stream >> primaryUrl;
250 m_primaryViewContainer->setUrl(primaryUrl);
251 bool primaryUrlEditable;
252 stream >> primaryUrlEditable;
253 m_primaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(primaryUrlEditable);
254
255 if (isSplitViewEnabled) {
256 QUrl secondaryUrl;
257 stream >> secondaryUrl;
258 m_secondaryViewContainer->setUrl(secondaryUrl);
259 bool secondaryUrlEditable;
260 stream >> secondaryUrlEditable;
261 m_secondaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(secondaryUrlEditable);
262 }
263
264 stream >> m_primaryViewActive;
265 if (m_primaryViewActive) {
266 m_primaryViewContainer->setActive(true);
267 } else {
268 Q_ASSERT(m_splitViewEnabled);
269 m_secondaryViewContainer->setActive(true);
270 }
271
272 QByteArray splitterState;
273 stream >> splitterState;
274 m_splitter->restoreState(splitterState);
275 }
276
277 void DolphinTabPage::setActive(bool active)
278 {
279 if (active) {
280 m_active = active;
281 } else {
282 // we should bypass changing active view in split mode
283 m_active = !m_splitViewEnabled;
284 }
285 // we want view to fire activated when goes from false to true
286 activeViewContainer()->setActive(active);
287 }
288
289 void DolphinTabPage::slotViewActivated()
290 {
291 const DolphinView* oldActiveView = activeViewContainer()->view();
292
293 // Set the view, which was active before, to inactive
294 // and update the active view type, if tab is active
295 if (m_active) {
296 if (m_splitViewEnabled) {
297 activeViewContainer()->setActive(false);
298 m_primaryViewActive = !m_primaryViewActive;
299 } else {
300 m_primaryViewActive = true;
301 if (m_secondaryViewContainer) {
302 m_secondaryViewContainer->setActive(false);
303 }
304 }
305 }
306
307 const DolphinView* newActiveView = activeViewContainer()->view();
308
309 if (newActiveView == oldActiveView) {
310 return;
311 }
312
313 disconnect(oldActiveView, &DolphinView::urlChanged,
314 this, &DolphinTabPage::activeViewUrlChanged);
315 disconnect(oldActiveView, &DolphinView::redirection,
316 this, &DolphinTabPage::slotViewUrlRedirection);
317 connect(newActiveView, &DolphinView::urlChanged,
318 this, &DolphinTabPage::activeViewUrlChanged);
319 connect(newActiveView, &DolphinView::redirection,
320 this, &DolphinTabPage::slotViewUrlRedirection);
321 Q_EMIT activeViewChanged(activeViewContainer());
322 Q_EMIT activeViewUrlChanged(activeViewContainer()->url());
323 }
324
325 void DolphinTabPage::slotViewUrlRedirection(const QUrl& oldUrl, const QUrl& newUrl)
326 {
327 Q_UNUSED(oldUrl)
328
329 Q_EMIT activeViewUrlChanged(newUrl);
330 }
331
332 void DolphinTabPage::switchActiveView()
333 {
334 if (!m_splitViewEnabled) {
335 return;
336 }
337 if (m_primaryViewActive) {
338 m_secondaryViewContainer->setActive(true);
339 } else {
340 m_primaryViewContainer->setActive(true);
341 }
342 }
343
344 DolphinViewContainer* DolphinTabPage::createViewContainer(const QUrl& url) const
345 {
346 DolphinViewContainer* container = new DolphinViewContainer(url, m_splitter);
347 container->setActive(false);
348
349 const DolphinView* view = container->view();
350 connect(view, &DolphinView::activated,
351 this, &DolphinTabPage::slotViewActivated);
352
353 connect(view, &DolphinView::toggleActiveViewRequested,
354 this, &DolphinTabPage::switchActiveView);
355
356 return container;
357 }