1 /***************************************************************************
2 * Copyright (C) 2014 by Emmanuel Pescosta <emmanuelpescosta099@gmail.com> *
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. *
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. *
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 ***************************************************************************/
20 #include "dolphintabpage.h"
22 #include "dolphin_generalsettings.h"
23 #include "dolphinviewcontainer.h"
26 #include <QVBoxLayout>
28 DolphinTabPage::DolphinTabPage(const QUrl
&primaryUrl
, const QUrl
&secondaryUrl
, QWidget
* parent
) :
30 m_primaryViewActive(true),
31 m_splitViewEnabled(false),
34 QVBoxLayout
* layout
= new QVBoxLayout(this);
35 layout
->setSpacing(0);
36 layout
->setContentsMargins(0, 0, 0, 0);
38 m_splitter
= new QSplitter(Qt::Horizontal
, this);
39 m_splitter
->setChildrenCollapsible(false);
40 layout
->addWidget(m_splitter
);
42 // Create a new primary view
43 m_primaryViewContainer
= createViewContainer(primaryUrl
);
44 connect(m_primaryViewContainer
->view(), &DolphinView::urlChanged
,
45 this, &DolphinTabPage::activeViewUrlChanged
);
46 connect(m_primaryViewContainer
->view(), &DolphinView::redirection
,
47 this, &DolphinTabPage::slotViewUrlRedirection
);
49 m_splitter
->addWidget(m_primaryViewContainer
);
50 m_primaryViewContainer
->show();
52 if (secondaryUrl
.isValid() || GeneralSettings::splitView()) {
53 // Provide a secondary view, if the given secondary url is valid or if the
54 // startup settings are set this way (use the url of the primary view).
55 m_splitViewEnabled
= true;
56 const QUrl
& url
= secondaryUrl
.isValid() ? secondaryUrl
: primaryUrl
;
57 m_secondaryViewContainer
= createViewContainer(url
);
58 m_splitter
->addWidget(m_secondaryViewContainer
);
59 m_secondaryViewContainer
->show();
62 m_primaryViewContainer
->setActive(true);
65 bool DolphinTabPage::primaryViewActive() const
67 return m_primaryViewActive
;
70 bool DolphinTabPage::splitViewEnabled() const
72 return m_splitViewEnabled
;
75 void DolphinTabPage::setSplitViewEnabled(bool enabled
, const QUrl
&secondaryUrl
)
77 if (m_splitViewEnabled
!= enabled
) {
78 m_splitViewEnabled
= enabled
;
81 const QUrl
& url
= (secondaryUrl
.isEmpty()) ? m_primaryViewContainer
->url() : secondaryUrl
;
82 m_secondaryViewContainer
= createViewContainer(url
);
84 const bool placesSelectorVisible
= m_primaryViewContainer
->urlNavigator()->isPlacesSelectorVisible();
85 m_secondaryViewContainer
->urlNavigator()->setPlacesSelectorVisible(placesSelectorVisible
);
87 m_splitter
->addWidget(m_secondaryViewContainer
);
88 m_secondaryViewContainer
->show();
89 m_secondaryViewContainer
->setActive(true);
91 DolphinViewContainer
* view
;
92 if (GeneralSettings::closeActiveSplitView()) {
93 view
= activeViewContainer();
94 if (m_primaryViewActive
) {
95 // If the primary view is active, we have to swap the pointers
96 // because the secondary view will be the new primary view.
97 qSwap(m_primaryViewContainer
, m_secondaryViewContainer
);
98 m_primaryViewActive
= false;
101 view
= m_primaryViewActive
? m_secondaryViewContainer
: m_primaryViewContainer
;
102 if (!m_primaryViewActive
) {
103 // If the secondary view is active, we have to swap the pointers
104 // because the secondary view will be the new primary view.
105 qSwap(m_primaryViewContainer
, m_secondaryViewContainer
);
106 m_primaryViewActive
= true;
109 m_primaryViewContainer
->setActive(true);
116 DolphinViewContainer
* DolphinTabPage::primaryViewContainer() const
118 return m_primaryViewContainer
;
121 DolphinViewContainer
* DolphinTabPage::secondaryViewContainer() const
123 return m_secondaryViewContainer
;
126 DolphinViewContainer
* DolphinTabPage::activeViewContainer() const
128 return m_primaryViewActive
? m_primaryViewContainer
:
129 m_secondaryViewContainer
;
132 KFileItemList
DolphinTabPage::selectedItems() const
134 KFileItemList items
= m_primaryViewContainer
->view()->selectedItems();
135 if (m_splitViewEnabled
) {
136 items
+= m_secondaryViewContainer
->view()->selectedItems();
141 int DolphinTabPage::selectedItemsCount() const
143 int selectedItemsCount
= m_primaryViewContainer
->view()->selectedItemsCount();
144 if (m_splitViewEnabled
) {
145 selectedItemsCount
+= m_secondaryViewContainer
->view()->selectedItemsCount();
147 return selectedItemsCount
;
150 void DolphinTabPage::markUrlsAsSelected(const QList
<QUrl
>& urls
)
152 m_primaryViewContainer
->view()->markUrlsAsSelected(urls
);
153 if (m_splitViewEnabled
) {
154 m_secondaryViewContainer
->view()->markUrlsAsSelected(urls
);
158 void DolphinTabPage::markUrlAsCurrent(const QUrl
& url
)
160 m_primaryViewContainer
->view()->markUrlAsCurrent(url
);
161 if (m_splitViewEnabled
) {
162 m_secondaryViewContainer
->view()->markUrlAsCurrent(url
);
166 void DolphinTabPage::setPlacesSelectorVisible(bool visible
)
168 m_primaryViewContainer
->urlNavigator()->setPlacesSelectorVisible(visible
);
169 if (m_splitViewEnabled
) {
170 m_secondaryViewContainer
->urlNavigator()->setPlacesSelectorVisible(visible
);
174 void DolphinTabPage::refreshViews()
176 m_primaryViewContainer
->readSettings();
177 if (m_splitViewEnabled
) {
178 m_secondaryViewContainer
->readSettings();
182 QByteArray
DolphinTabPage::saveState() const
185 QDataStream
stream(&state
, QIODevice::WriteOnly
);
187 stream
<< quint32(2); // Tab state version
189 stream
<< m_splitViewEnabled
;
191 stream
<< m_primaryViewContainer
->url();
192 stream
<< m_primaryViewContainer
->urlNavigator()->isUrlEditable();
193 m_primaryViewContainer
->view()->saveState(stream
);
195 if (m_splitViewEnabled
) {
196 stream
<< m_secondaryViewContainer
->url();
197 stream
<< m_secondaryViewContainer
->urlNavigator()->isUrlEditable();
198 m_secondaryViewContainer
->view()->saveState(stream
);
201 stream
<< m_primaryViewActive
;
202 stream
<< m_splitter
->saveState();
207 void DolphinTabPage::restoreState(const QByteArray
& state
)
209 if (state
.isEmpty()) {
213 QByteArray sd
= state
;
214 QDataStream
stream(&sd
, QIODevice::ReadOnly
);
216 // Read the version number of the tab state and check if the version is supported.
220 // The version of the tab state isn't supported, we can't restore it.
224 bool isSplitViewEnabled
= false;
225 stream
>> isSplitViewEnabled
;
226 setSplitViewEnabled(isSplitViewEnabled
);
229 stream
>> primaryUrl
;
230 m_primaryViewContainer
->setUrl(primaryUrl
);
231 bool primaryUrlEditable
;
232 stream
>> primaryUrlEditable
;
233 m_primaryViewContainer
->urlNavigator()->setUrlEditable(primaryUrlEditable
);
234 m_primaryViewContainer
->view()->restoreState(stream
);
236 if (isSplitViewEnabled
) {
238 stream
>> secondaryUrl
;
239 m_secondaryViewContainer
->setUrl(secondaryUrl
);
240 bool secondaryUrlEditable
;
241 stream
>> secondaryUrlEditable
;
242 m_secondaryViewContainer
->urlNavigator()->setUrlEditable(secondaryUrlEditable
);
243 m_secondaryViewContainer
->view()->restoreState(stream
);
246 stream
>> m_primaryViewActive
;
247 if (m_primaryViewActive
) {
248 m_primaryViewContainer
->setActive(true);
250 Q_ASSERT(m_splitViewEnabled
);
251 m_secondaryViewContainer
->setActive(true);
254 QByteArray splitterState
;
255 stream
>> splitterState
;
256 m_splitter
->restoreState(splitterState
);
259 void DolphinTabPage::restoreStateV1(const QByteArray
& state
)
261 if (state
.isEmpty()) {
265 QByteArray sd
= state
;
266 QDataStream
stream(&sd
, QIODevice::ReadOnly
);
268 bool isSplitViewEnabled
= false;
269 stream
>> isSplitViewEnabled
;
270 setSplitViewEnabled(isSplitViewEnabled
);
273 stream
>> primaryUrl
;
274 m_primaryViewContainer
->setUrl(primaryUrl
);
275 bool primaryUrlEditable
;
276 stream
>> primaryUrlEditable
;
277 m_primaryViewContainer
->urlNavigator()->setUrlEditable(primaryUrlEditable
);
279 if (isSplitViewEnabled
) {
281 stream
>> secondaryUrl
;
282 m_secondaryViewContainer
->setUrl(secondaryUrl
);
283 bool secondaryUrlEditable
;
284 stream
>> secondaryUrlEditable
;
285 m_secondaryViewContainer
->urlNavigator()->setUrlEditable(secondaryUrlEditable
);
288 stream
>> m_primaryViewActive
;
289 if (m_primaryViewActive
) {
290 m_primaryViewContainer
->setActive(true);
292 Q_ASSERT(m_splitViewEnabled
);
293 m_secondaryViewContainer
->setActive(true);
296 QByteArray splitterState
;
297 stream
>> splitterState
;
298 m_splitter
->restoreState(splitterState
);
301 void DolphinTabPage::setActive(bool active
)
306 // we should bypass changing active view in split mode
307 m_active
= !m_splitViewEnabled
;
309 // we want view to fire activated when goes from false to true
310 activeViewContainer()->setActive(active
);
313 void DolphinTabPage::slotViewActivated()
315 const DolphinView
* oldActiveView
= activeViewContainer()->view();
317 // Set the view, which was active before, to inactive
318 // and update the active view type, if tab is active
320 if (m_splitViewEnabled
) {
321 activeViewContainer()->setActive(false);
322 m_primaryViewActive
= !m_primaryViewActive
;
324 m_primaryViewActive
= true;
325 if (m_secondaryViewContainer
) {
326 m_secondaryViewContainer
->setActive(false);
331 const DolphinView
* newActiveView
= activeViewContainer()->view();
333 if (newActiveView
== oldActiveView
) {
337 disconnect(oldActiveView
, &DolphinView::urlChanged
,
338 this, &DolphinTabPage::activeViewUrlChanged
);
339 disconnect(oldActiveView
, &DolphinView::redirection
,
340 this, &DolphinTabPage::slotViewUrlRedirection
);
341 connect(newActiveView
, &DolphinView::urlChanged
,
342 this, &DolphinTabPage::activeViewUrlChanged
);
343 connect(newActiveView
, &DolphinView::redirection
,
344 this, &DolphinTabPage::slotViewUrlRedirection
);
345 emit
activeViewChanged(activeViewContainer());
346 emit
activeViewUrlChanged(activeViewContainer()->url());
349 void DolphinTabPage::slotViewUrlRedirection(const QUrl
& oldUrl
, const QUrl
& newUrl
)
353 emit
activeViewUrlChanged(newUrl
);
356 void DolphinTabPage::switchActiveView()
358 if (!m_splitViewEnabled
) {
361 if (m_primaryViewActive
) {
362 m_secondaryViewContainer
->setActive(true);
364 m_primaryViewContainer
->setActive(true);
368 DolphinViewContainer
* DolphinTabPage::createViewContainer(const QUrl
& url
) const
370 DolphinViewContainer
* container
= new DolphinViewContainer(url
, m_splitter
);
371 container
->setActive(false);
373 const DolphinView
* view
= container
->view();
374 connect(view
, &DolphinView::activated
,
375 this, &DolphinTabPage::slotViewActivated
);
377 connect(view
, &DolphinView::toggleActiveViewRequested
,
378 this, &DolphinTabPage::switchActiveView
);