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