]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphintabpage.cpp
Fix crash when restoring a session stored with Dolphin 4.13 or earlier
[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
27 DolphinTabPage::DolphinTabPage(const KUrl& primaryUrl, const KUrl& secondaryUrl, QWidget* parent) :
28 QWidget(parent),
29 m_primaryViewActive(true),
30 m_splitViewEnabled(false)
31 {
32 QVBoxLayout* layout = new QVBoxLayout(this);
33 layout->setSpacing(0);
34 layout->setMargin(0);
35
36 m_splitter = new QSplitter(Qt::Horizontal, this);
37 m_splitter->setChildrenCollapsible(false);
38 layout->addWidget(m_splitter);
39
40 // Create a new primary view
41 m_primaryViewContainer = createViewContainer(primaryUrl);
42 connect(m_primaryViewContainer->view(), SIGNAL(urlChanged(KUrl)),
43 this, SIGNAL(activeViewUrlChanged(KUrl)));
44
45 m_splitter->addWidget(m_primaryViewContainer);
46 m_primaryViewContainer->show();
47
48 if (secondaryUrl.isValid() || GeneralSettings::splitView()) {
49 // Provide a secondary view, if the given secondary url is valid or if the
50 // startup settings are set this way (use the url of the primary view).
51 m_splitViewEnabled = true;
52 const KUrl& url = secondaryUrl.isValid() ? secondaryUrl : primaryUrl;
53 m_secondaryViewContainer = createViewContainer(url);
54 m_splitter->addWidget(m_secondaryViewContainer);
55 m_secondaryViewContainer->show();
56 }
57
58 m_primaryViewContainer->setActive(true);
59 }
60
61 bool DolphinTabPage::primaryViewActive() const
62 {
63 return m_primaryViewActive;
64 }
65
66 bool DolphinTabPage::splitViewEnabled() const
67 {
68 return m_splitViewEnabled;
69 }
70
71 void DolphinTabPage::setSplitViewEnabled(bool enabled)
72 {
73 if (m_splitViewEnabled != enabled) {
74 m_splitViewEnabled = enabled;
75
76 if (enabled) {
77 const KUrl& url = m_primaryViewContainer->url();
78 m_secondaryViewContainer = createViewContainer(url);
79
80 const bool placesSelectorVisible = m_primaryViewContainer->urlNavigator()->isPlacesSelectorVisible();
81 m_secondaryViewContainer->urlNavigator()->setPlacesSelectorVisible(placesSelectorVisible);
82
83 m_splitter->addWidget(m_secondaryViewContainer);
84 m_secondaryViewContainer->show();
85 m_secondaryViewContainer->setActive(true);
86 } else {
87 // Close the view which is active.
88 DolphinViewContainer* view = activeViewContainer();
89 if (m_primaryViewActive) {
90 // If the primary view is active, we have to swap the pointers
91 // because the secondary view will be the new primary view.
92 qSwap(m_primaryViewContainer, m_secondaryViewContainer);
93 }
94 m_primaryViewContainer->setActive(true);
95 view->close();
96 view->deleteLater();
97 }
98 }
99 }
100
101 DolphinViewContainer* DolphinTabPage::primaryViewContainer() const
102 {
103 return m_primaryViewContainer;
104 }
105
106 DolphinViewContainer* DolphinTabPage::secondaryViewContainer() const
107 {
108 return m_secondaryViewContainer;
109 }
110
111 DolphinViewContainer* DolphinTabPage::activeViewContainer() const
112 {
113 return m_primaryViewActive ? m_primaryViewContainer :
114 m_secondaryViewContainer;
115 }
116
117 KFileItemList DolphinTabPage::selectedItems() const
118 {
119 KFileItemList items = m_primaryViewContainer->view()->selectedItems();
120 if (m_splitViewEnabled) {
121 items += m_secondaryViewContainer->view()->selectedItems();
122 }
123 return items;
124 }
125
126 int DolphinTabPage::selectedItemsCount() const
127 {
128 int selectedItemsCount = m_primaryViewContainer->view()->selectedItemsCount();
129 if (m_splitViewEnabled) {
130 selectedItemsCount += m_secondaryViewContainer->view()->selectedItemsCount();
131 }
132 return selectedItemsCount;
133 }
134
135 void DolphinTabPage::markUrlsAsSelected(const QList<KUrl>& urls)
136 {
137 m_primaryViewContainer->view()->markUrlsAsSelected(urls);
138 if (m_splitViewEnabled) {
139 m_secondaryViewContainer->view()->markUrlsAsSelected(urls);
140 }
141 }
142
143 void DolphinTabPage::markUrlAsCurrent(const KUrl& url)
144 {
145 m_primaryViewContainer->view()->markUrlAsCurrent(url);
146 if (m_splitViewEnabled) {
147 m_secondaryViewContainer->view()->markUrlAsCurrent(url);
148 }
149 }
150
151 void DolphinTabPage::setPlacesSelectorVisible(bool visible)
152 {
153 m_primaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible);
154 if (m_splitViewEnabled) {
155 m_secondaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible);
156 }
157 }
158
159 void DolphinTabPage::refreshViews()
160 {
161 m_primaryViewContainer->readSettings();
162 if (m_splitViewEnabled) {
163 m_secondaryViewContainer->readSettings();
164 }
165 }
166
167 QByteArray DolphinTabPage::saveState() const
168 {
169 QByteArray state;
170 QDataStream stream(&state, QIODevice::WriteOnly);
171
172 stream << m_splitViewEnabled;
173
174 stream << m_primaryViewContainer->url();
175 stream << m_primaryViewContainer->urlNavigator()->isUrlEditable();
176
177 if (m_splitViewEnabled) {
178 stream << m_secondaryViewContainer->url();
179 stream << m_secondaryViewContainer->urlNavigator()->isUrlEditable();
180 }
181
182 stream << m_primaryViewActive;
183 stream << m_splitter->saveState();
184
185 return state;
186 }
187
188 void DolphinTabPage::restoreState(const QByteArray& state)
189 {
190 if (state.isEmpty()) {
191 return;
192 }
193
194 QByteArray sd = state;
195 QDataStream stream(&sd, QIODevice::ReadOnly);
196
197 bool isSplitViewEnabled = false;
198 stream >> isSplitViewEnabled;
199 setSplitViewEnabled(isSplitViewEnabled);
200
201 KUrl primaryUrl;
202 stream >> primaryUrl;
203 m_primaryViewContainer->setUrl(primaryUrl);
204 bool primaryUrlEditable;
205 stream >> primaryUrlEditable;
206 m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable);
207
208 if (isSplitViewEnabled) {
209 KUrl secondaryUrl;
210 stream >> secondaryUrl;
211 m_secondaryViewContainer->setUrl(secondaryUrl);
212 bool secondaryUrlEditable;
213 stream >> secondaryUrlEditable;
214 m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable);
215 }
216
217 stream >> m_primaryViewActive;
218 if (m_primaryViewActive) {
219 m_primaryViewContainer->setActive(true);
220 } else {
221 Q_ASSERT(m_splitViewEnabled);
222 m_secondaryViewContainer->setActive(true);
223 }
224
225 QByteArray splitterState;
226 stream >> splitterState;
227 m_splitter->restoreState(splitterState);
228 }
229
230 void DolphinTabPage::slotViewActivated()
231 {
232 const DolphinView* oldActiveView = activeViewContainer()->view();
233
234 // Set the view, which was active before, to inactive
235 // and update the active view type.
236 if (m_splitViewEnabled) {
237 activeViewContainer()->setActive(false);
238 m_primaryViewActive = !m_primaryViewActive;
239 } else {
240 m_primaryViewActive = true;
241 }
242
243 const DolphinView* newActiveView = activeViewContainer()->view();
244
245 if (newActiveView != oldActiveView) {
246 disconnect(oldActiveView, SIGNAL(urlChanged(KUrl)),
247 this, SIGNAL(activeViewUrlChanged(KUrl)));
248 connect(newActiveView, SIGNAL(urlChanged(KUrl)),
249 this, SIGNAL(activeViewUrlChanged(KUrl)));
250 }
251
252 emit activeViewUrlChanged(activeViewContainer()->url());
253 emit activeViewChanged();
254 }
255
256 DolphinViewContainer* DolphinTabPage::createViewContainer(const KUrl& url) const
257 {
258 DolphinViewContainer* container = new DolphinViewContainer(url, m_splitter);
259 container->setActive(false);
260
261 const DolphinView* view = container->view();
262 connect(view, SIGNAL(activated()),
263 this, SLOT(slotViewActivated()));
264
265 return container;
266 }