]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphintabpage.cpp
Merge branch 'master' into frameworks
[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(), SIGNAL(urlChanged(QUrl)),
44 this, SIGNAL(activeViewUrlChanged(QUrl)));
45 connect(m_primaryViewContainer->view(), SIGNAL(redirection(QUrl,QUrl)),
46 this, SLOT(slotViewUrlRedirection(QUrl,QUrl)));
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)
75 {
76 if (m_splitViewEnabled != enabled) {
77 m_splitViewEnabled = enabled;
78
79 if (enabled) {
80 const QUrl& url = m_primaryViewContainer->url();
81 m_secondaryViewContainer = createViewContainer(url);
82
83 const bool placesSelectorVisible = m_primaryViewContainer->urlNavigator()->isPlacesSelectorVisible();
84 m_secondaryViewContainer->urlNavigator()->setPlacesSelectorVisible(placesSelectorVisible);
85
86 m_splitter->addWidget(m_secondaryViewContainer);
87 m_secondaryViewContainer->show();
88 m_secondaryViewContainer->setActive(true);
89 } else {
90 // Close the view which is active.
91 DolphinViewContainer* view = activeViewContainer();
92 if (m_primaryViewActive) {
93 // If the primary view is active, we have to swap the pointers
94 // because the secondary view will be the new primary view.
95 qSwap(m_primaryViewContainer, m_secondaryViewContainer);
96 }
97 m_primaryViewContainer->setActive(true);
98 view->close();
99 view->deleteLater();
100 }
101 }
102 }
103
104 DolphinViewContainer* DolphinTabPage::primaryViewContainer() const
105 {
106 return m_primaryViewContainer;
107 }
108
109 DolphinViewContainer* DolphinTabPage::secondaryViewContainer() const
110 {
111 return m_secondaryViewContainer;
112 }
113
114 DolphinViewContainer* DolphinTabPage::activeViewContainer() const
115 {
116 return m_primaryViewActive ? m_primaryViewContainer :
117 m_secondaryViewContainer;
118 }
119
120 KFileItemList DolphinTabPage::selectedItems() const
121 {
122 KFileItemList items = m_primaryViewContainer->view()->selectedItems();
123 if (m_splitViewEnabled) {
124 items += m_secondaryViewContainer->view()->selectedItems();
125 }
126 return items;
127 }
128
129 int DolphinTabPage::selectedItemsCount() const
130 {
131 int selectedItemsCount = m_primaryViewContainer->view()->selectedItemsCount();
132 if (m_splitViewEnabled) {
133 selectedItemsCount += m_secondaryViewContainer->view()->selectedItemsCount();
134 }
135 return selectedItemsCount;
136 }
137
138 void DolphinTabPage::markUrlsAsSelected(const QList<QUrl>& urls)
139 {
140 m_primaryViewContainer->view()->markUrlsAsSelected(urls);
141 if (m_splitViewEnabled) {
142 m_secondaryViewContainer->view()->markUrlsAsSelected(urls);
143 }
144 }
145
146 void DolphinTabPage::markUrlAsCurrent(const QUrl& url)
147 {
148 m_primaryViewContainer->view()->markUrlAsCurrent(url);
149 if (m_splitViewEnabled) {
150 m_secondaryViewContainer->view()->markUrlAsCurrent(url);
151 }
152 }
153
154 void DolphinTabPage::setPlacesSelectorVisible(bool visible)
155 {
156 m_primaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible);
157 if (m_splitViewEnabled) {
158 m_secondaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible);
159 }
160 }
161
162 void DolphinTabPage::refreshViews()
163 {
164 m_primaryViewContainer->readSettings();
165 if (m_splitViewEnabled) {
166 m_secondaryViewContainer->readSettings();
167 }
168 }
169
170 QByteArray DolphinTabPage::saveState() const
171 {
172 QByteArray state;
173 QDataStream stream(&state, QIODevice::WriteOnly);
174
175 stream << quint32(2); // Tab state version
176
177 stream << m_splitViewEnabled;
178
179 stream << m_primaryViewContainer->url();
180 stream << m_primaryViewContainer->urlNavigator()->isUrlEditable();
181 m_primaryViewContainer->view()->saveState(stream);
182
183 if (m_splitViewEnabled) {
184 stream << m_secondaryViewContainer->url();
185 stream << m_secondaryViewContainer->urlNavigator()->isUrlEditable();
186 m_secondaryViewContainer->view()->saveState(stream);
187 }
188
189 stream << m_primaryViewActive;
190 stream << m_splitter->saveState();
191
192 return state;
193 }
194
195 void DolphinTabPage::restoreState(const QByteArray& state)
196 {
197 if (state.isEmpty()) {
198 return;
199 }
200
201 QByteArray sd = state;
202 QDataStream stream(&sd, QIODevice::ReadOnly);
203
204 // Read the version number of the tab state and check if the version is supported.
205 quint32 version = 0;
206 stream >> version;
207 if (version != 2) {
208 // The version of the tab state isn't supported, we can't restore it.
209 return;
210 }
211
212 bool isSplitViewEnabled = false;
213 stream >> isSplitViewEnabled;
214 setSplitViewEnabled(isSplitViewEnabled);
215
216 QUrl primaryUrl;
217 stream >> primaryUrl;
218 m_primaryViewContainer->setUrl(primaryUrl);
219 bool primaryUrlEditable;
220 stream >> primaryUrlEditable;
221 m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable);
222 m_primaryViewContainer->view()->restoreState(stream);
223
224 if (isSplitViewEnabled) {
225 QUrl secondaryUrl;
226 stream >> secondaryUrl;
227 m_secondaryViewContainer->setUrl(secondaryUrl);
228 bool secondaryUrlEditable;
229 stream >> secondaryUrlEditable;
230 m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable);
231 m_secondaryViewContainer->view()->restoreState(stream);
232 }
233
234 stream >> m_primaryViewActive;
235 if (m_primaryViewActive) {
236 m_primaryViewContainer->setActive(true);
237 } else {
238 Q_ASSERT(m_splitViewEnabled);
239 m_secondaryViewContainer->setActive(true);
240 }
241
242 QByteArray splitterState;
243 stream >> splitterState;
244 m_splitter->restoreState(splitterState);
245 }
246
247 void DolphinTabPage::restoreStateV1(const QByteArray& state)
248 {
249 if (state.isEmpty()) {
250 return;
251 }
252
253 QByteArray sd = state;
254 QDataStream stream(&sd, QIODevice::ReadOnly);
255
256 bool isSplitViewEnabled = false;
257 stream >> isSplitViewEnabled;
258 setSplitViewEnabled(isSplitViewEnabled);
259
260 QUrl primaryUrl;
261 stream >> primaryUrl;
262 m_primaryViewContainer->setUrl(primaryUrl);
263 bool primaryUrlEditable;
264 stream >> primaryUrlEditable;
265 m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable);
266
267 if (isSplitViewEnabled) {
268 QUrl secondaryUrl;
269 stream >> secondaryUrl;
270 m_secondaryViewContainer->setUrl(secondaryUrl);
271 bool secondaryUrlEditable;
272 stream >> secondaryUrlEditable;
273 m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable);
274 }
275
276 stream >> m_primaryViewActive;
277 if (m_primaryViewActive) {
278 m_primaryViewContainer->setActive(true);
279 } else {
280 Q_ASSERT(m_splitViewEnabled);
281 m_secondaryViewContainer->setActive(true);
282 }
283
284 QByteArray splitterState;
285 stream >> splitterState;
286 m_splitter->restoreState(splitterState);
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.
295 if (m_splitViewEnabled) {
296 activeViewContainer()->setActive(false);
297 m_primaryViewActive = !m_primaryViewActive;
298 } else {
299 m_primaryViewActive = true;
300 }
301
302 const DolphinView* newActiveView = activeViewContainer()->view();
303
304 if (newActiveView != oldActiveView) {
305 disconnect(oldActiveView, SIGNAL(urlChanged(QUrl)),
306 this, SIGNAL(activeViewUrlChanged(QUrl)));
307 disconnect(oldActiveView, SIGNAL(redirection(QUrl,QUrl)),
308 this, SLOT(slotViewUrlRedirection(QUrl,QUrl)));
309 connect(newActiveView, SIGNAL(urlChanged(QUrl)),
310 this, SIGNAL(activeViewUrlChanged(QUrl)));
311 connect(newActiveView, SIGNAL(redirection(QUrl,QUrl)),
312 this, SLOT(slotViewUrlRedirection(QUrl,QUrl)));
313 }
314
315 emit activeViewUrlChanged(activeViewContainer()->url());
316 emit activeViewChanged(activeViewContainer());
317 }
318
319 void DolphinTabPage::slotViewUrlRedirection(const QUrl& oldUrl, const QUrl& newUrl)
320 {
321 Q_UNUSED(oldUrl);
322
323 emit activeViewUrlChanged(newUrl);
324 }
325
326 DolphinViewContainer* DolphinTabPage::createViewContainer(const QUrl& url) const
327 {
328 DolphinViewContainer* container = new DolphinViewContainer(url, m_splitter);
329 container->setActive(false);
330
331 const DolphinView* view = container->view();
332 connect(view, SIGNAL(activated()),
333 this, SLOT(slotViewActivated()));
334
335 return container;
336 }