From 38381bc6a2999b1d8a0b8a6e2b8d703faa0944d9 Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Sun, 10 Aug 2014 18:52:06 +0200 Subject: Implemented DolphinTabWidget class to encapsulate the tab handling from DolphinMainWindow. REVIEW: 119115 --- src/dolphintabpage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/dolphintabpage.cpp') diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 82be6d59c..d1184a9f2 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -246,7 +246,7 @@ void DolphinTabPage::slotViewActivated() } emit activeViewUrlChanged(activeViewContainer()->url()); - emit activeViewChanged(); + emit activeViewChanged(activeViewContainer()); } DolphinViewContainer* DolphinTabPage::createViewContainer(const KUrl& url) const -- cgit v1.3 From 4ed068fffff2343cc0dcd236c38832b7662f8d78 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Tue, 12 Aug 2014 09:08:30 +0200 Subject: Fix crash when restoring a session stored with Dolphin 4.13 or earlier Since DolphinTabPage::saveState() and DolphinTabPage::restoreState(const QByteArray& state) save and restore the state of each tab in a different format than DolphinMainWindow did before the refactoring, we can run into problems: the first time a user logs into a session that has Dolphin 4.14, Dolphin might read session data that does not contain the QByteArray that DolphinTabPage wants to read the data from. In restoreState, isSplitViewEnabled will thus have the value false, and no secondary view will be created. Later on, m_primaryViewActive will also be set to false, but the else branch of the following "if (m_primaryViewActive)" then tries to activate the secondary view, which does not exist -> we get a crash. The easiest solution is to not restore the tab state if no session data in the new format is found. BUG: 338187 REVIEW: 119718 FIXED-IN: 4.14.0 --- src/dolphintabpage.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/dolphintabpage.cpp') diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 82be6d59c..4c49869f7 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -187,6 +187,10 @@ QByteArray DolphinTabPage::saveState() const void DolphinTabPage::restoreState(const QByteArray& state) { + if (state.isEmpty()) { + return; + } + QByteArray sd = state; QDataStream stream(&sd, QIODevice::ReadOnly); -- cgit v1.3 From 39d8fb12c1552ec708b5fc1846d7aa9828329417 Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Wed, 13 Aug 2014 22:06:28 +0200 Subject: React on the redirection signal from DolphinView to properly update the tab and window titles. REVIEW: 119697 BUG: 305721 --- src/dolphinmainwindow.cpp | 37 ++++++++++++++++++------------------- src/dolphinmainwindow.h | 12 ++++++------ src/dolphintabpage.cpp | 13 +++++++++++++ src/dolphintabpage.h | 7 +++++++ src/dolphintabwidget.cpp | 9 ++++++++- src/dolphintabwidget.h | 6 ++++++ 6 files changed, 58 insertions(+), 26 deletions(-) (limited to 'src/dolphintabpage.cpp') diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 588bfda64..95b08af96 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -136,6 +136,8 @@ DolphinMainWindow::DolphinMainWindow() : this, SLOT(activeViewChanged(DolphinViewContainer*))); connect(m_tabWidget, SIGNAL(tabCountChanged(int)), this, SLOT(tabCountChanged(int))); + connect(m_tabWidget, SIGNAL(currentUrlChanged(KUrl)), + this, SLOT(setUrlAsCaption(KUrl))); setCentralWidget(m_tabWidget); setupActions(); @@ -236,7 +238,6 @@ void DolphinMainWindow::changeUrl(const KUrl& url) updatePasteAction(); updateViewActions(); updateGoActions(); - setUrlAsCaption(url); emit urlChanged(url); } @@ -945,8 +946,6 @@ void DolphinMainWindow::activeViewChanged(DolphinViewContainer* viewContainer) updateGoActions(); const KUrl url = viewContainer->url(); - setUrlAsCaption(url); - emit urlChanged(url); } @@ -958,6 +957,22 @@ void DolphinMainWindow::tabCountChanged(int count) actionCollection()->action("activate_prev_tab")->setEnabled(enableTabActions); } +void DolphinMainWindow::setUrlAsCaption(const KUrl& url) +{ + QString caption; + if (!url.isLocalFile()) { + caption.append(url.protocol() + " - "); + if (url.hasHost()) { + caption.append(url.host() + " - "); + } + } + + const QString fileName = url.fileName().isEmpty() ? "/" : url.fileName(); + caption.append(fileName); + + setCaption(caption); +} + void DolphinMainWindow::setupActions() { // setup 'File' menu @@ -1471,22 +1486,6 @@ bool DolphinMainWindow::isKompareInstalled() const return installed; } -void DolphinMainWindow::setUrlAsCaption(const KUrl& url) -{ - QString caption; - if (!url.isLocalFile()) { - caption.append(url.protocol() + " - "); - if (url.hasHost()) { - caption.append(url.host() + " - "); - } - } - - const QString fileName = url.fileName().isEmpty() ? "/" : url.fileName(); - caption.append(fileName); - - setCaption(caption); -} - void DolphinMainWindow::createPanelAction(const KIcon& icon, const QKeySequence& shortcut, QAction* dockAction, diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index 7bce7f13e..9d4c003af 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -429,6 +429,12 @@ private slots: */ void tabCountChanged(int count); + /** + * Sets the window caption to url.fileName() if this is non-empty, + * "/" if the URL is "file:///", and url.protocol() otherwise. + */ + void setUrlAsCaption(const KUrl& url); + private: void setupActions(); void setupDockWidgets(); @@ -464,12 +470,6 @@ private: bool isKompareInstalled() const; - /** - * Sets the window caption to url.fileName() if this is non-empty, - * "/" if the URL is "file:///", and url.protocol() otherwise. - */ - void setUrlAsCaption(const KUrl& url); - /** * Creates an action for showing/hiding a panel, that is accessible * in "Configure toolbars..." and "Configure shortcuts...". This is necessary diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 23e33c958..3d1ba5a3e 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -41,6 +41,8 @@ DolphinTabPage::DolphinTabPage(const KUrl& primaryUrl, const KUrl& secondaryUrl, m_primaryViewContainer = createViewContainer(primaryUrl); connect(m_primaryViewContainer->view(), SIGNAL(urlChanged(KUrl)), this, SIGNAL(activeViewUrlChanged(KUrl))); + connect(m_primaryViewContainer->view(), SIGNAL(redirection(KUrl,KUrl)), + this, SLOT(slotViewUrlRedirection(KUrl,KUrl))); m_splitter->addWidget(m_primaryViewContainer); m_primaryViewContainer->show(); @@ -245,14 +247,25 @@ void DolphinTabPage::slotViewActivated() if (newActiveView != oldActiveView) { disconnect(oldActiveView, SIGNAL(urlChanged(KUrl)), this, SIGNAL(activeViewUrlChanged(KUrl))); + disconnect(oldActiveView, SIGNAL(redirection(KUrl,KUrl)), + this, SLOT(slotViewUrlRedirection(KUrl,KUrl))); connect(newActiveView, SIGNAL(urlChanged(KUrl)), this, SIGNAL(activeViewUrlChanged(KUrl))); + connect(newActiveView, SIGNAL(redirection(KUrl,KUrl)), + this, SLOT(slotViewUrlRedirection(KUrl,KUrl))); } emit activeViewUrlChanged(activeViewContainer()->url()); emit activeViewChanged(activeViewContainer()); } +void DolphinTabPage::slotViewUrlRedirection(const KUrl& oldUrl, const KUrl& newUrl) +{ + Q_UNUSED(oldUrl); + + emit activeViewUrlChanged(newUrl); +} + DolphinViewContainer* DolphinTabPage::createViewContainer(const KUrl& url) const { DolphinViewContainer* container = new DolphinViewContainer(url, m_splitter); diff --git a/src/dolphintabpage.h b/src/dolphintabpage.h index 278524792..de5a58915 100644 --- a/src/dolphintabpage.h +++ b/src/dolphintabpage.h @@ -133,6 +133,13 @@ private slots: */ void slotViewActivated(); + /** + * Handles the view url redirection event. + * + * It emits the activeViewUrlChanged signal with the url \a newUrl. + */ + void slotViewUrlRedirection(const KUrl& oldUrl, const KUrl& newUrl); + private: /** * Creates a new view container and does the default initialization. diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index ea71b4856..76d4b8d48 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -295,12 +295,19 @@ void DolphinTabWidget::tabUrlChanged(const KUrl& url) if (index >= 0) { tabBar()->setTabText(index, tabName(url)); tabBar()->setTabIcon(index, KIcon(KMimeType::iconNameForUrl(url))); + + // Emit the currentUrlChanged signal if the url of the current tab has been changed. + if (index == currentIndex()) { + emit currentUrlChanged(url); + } } } void DolphinTabWidget::currentTabChanged(int index) { - emit activeViewChanged(tabPageAt(index)->activeViewContainer()); + DolphinViewContainer* viewContainer = tabPageAt(index)->activeViewContainer(); + emit activeViewChanged(viewContainer); + emit currentUrlChanged(viewContainer->url()); } void DolphinTabWidget::tabInserted(int index) diff --git a/src/dolphintabwidget.h b/src/dolphintabwidget.h index aaadbc997..98bcd985a 100644 --- a/src/dolphintabwidget.h +++ b/src/dolphintabwidget.h @@ -72,6 +72,12 @@ signals: */ void rememberClosedTab(const KUrl& url, const QByteArray& state); + /** + * Is emitted when the url of the current tab has been changed. This signal + * is also emitted when the active view has been changed. + */ + void currentUrlChanged(const KUrl& url); + public slots: /** * Opens a new view with the current URL that is part of a tab and activates -- cgit v1.3 From 2d2d55f3df09614e6b7cf267771b52a04dcb5e28 Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Wed, 20 Aug 2014 23:06:39 +0200 Subject: Save the view states in addition to the view urls and splitter state in DolphinTabPage. Also added version numbers to view and tab state. REVIEW: 119792 --- src/dolphintabpage.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++ src/dolphintabpage.h | 9 ++++++++ src/dolphintabwidget.cpp | 13 ++++++++--- src/views/dolphinview.cpp | 10 +++++++++ 4 files changed, 85 insertions(+), 3 deletions(-) (limited to 'src/dolphintabpage.cpp') diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 3d1ba5a3e..f7000ea66 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -171,14 +171,18 @@ QByteArray DolphinTabPage::saveState() const QByteArray state; QDataStream stream(&state, QIODevice::WriteOnly); + stream << quint32(2); // Tab state version + stream << m_splitViewEnabled; stream << m_primaryViewContainer->url(); stream << m_primaryViewContainer->urlNavigator()->isUrlEditable(); + m_primaryViewContainer->view()->saveState(stream); if (m_splitViewEnabled) { stream << m_secondaryViewContainer->url(); stream << m_secondaryViewContainer->urlNavigator()->isUrlEditable(); + m_secondaryViewContainer->view()->saveState(stream); } stream << m_primaryViewActive; @@ -196,6 +200,58 @@ void DolphinTabPage::restoreState(const QByteArray& state) QByteArray sd = state; QDataStream stream(&sd, QIODevice::ReadOnly); + // Read the version number of the tab state and check if the version is supported. + quint32 version = 0; + stream >> version; + if (version != 2) { + // The version of the tab state isn't supported, we can't restore it. + return; + } + + bool isSplitViewEnabled = false; + stream >> isSplitViewEnabled; + setSplitViewEnabled(isSplitViewEnabled); + + KUrl primaryUrl; + stream >> primaryUrl; + m_primaryViewContainer->setUrl(primaryUrl); + bool primaryUrlEditable; + stream >> primaryUrlEditable; + m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable); + m_primaryViewContainer->view()->restoreState(stream); + + if (isSplitViewEnabled) { + KUrl secondaryUrl; + stream >> secondaryUrl; + m_secondaryViewContainer->setUrl(secondaryUrl); + bool secondaryUrlEditable; + stream >> secondaryUrlEditable; + m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable); + m_secondaryViewContainer->view()->restoreState(stream); + } + + stream >> m_primaryViewActive; + if (m_primaryViewActive) { + m_primaryViewContainer->setActive(true); + } else { + Q_ASSERT(m_splitViewEnabled); + m_secondaryViewContainer->setActive(true); + } + + QByteArray splitterState; + stream >> splitterState; + m_splitter->restoreState(splitterState); +} + +void DolphinTabPage::restoreStateV1(const QByteArray& state) +{ + if (state.isEmpty()) { + return; + } + + QByteArray sd = state; + QDataStream stream(&sd, QIODevice::ReadOnly); + bool isSplitViewEnabled = false; stream >> isSplitViewEnabled; setSplitViewEnabled(isSplitViewEnabled); diff --git a/src/dolphintabpage.h b/src/dolphintabpage.h index de5a58915..2a406f4a9 100644 --- a/src/dolphintabpage.h +++ b/src/dolphintabpage.h @@ -120,6 +120,15 @@ public: */ void restoreState(const QByteArray& state); + /** + * Restores all tab related properties (urls, splitter layout, ...) from + * the given \a state. + * + * @deprecated The first tab state version has no version number, we keep + * this method to restore old states (<= Dolphin 4.14.x). + */ + void restoreStateV1(const QByteArray& state); + signals: void activeViewChanged(DolphinViewContainer* viewContainer); void activeViewUrlChanged(const KUrl& url); diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index 76d4b8d48..b1b2d858f 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -72,7 +72,7 @@ void DolphinTabWidget::saveProperties(KConfigGroup& group) const for (int i = 0; i < tabCount; ++i) { const DolphinTabPage* tabPage = tabPageAt(i); - group.writeEntry("Tab " % QString::number(i), tabPage->saveState()); + group.writeEntry("Tab Data " % QString::number(i), tabPage->saveState()); } } @@ -83,8 +83,15 @@ void DolphinTabWidget::readProperties(const KConfigGroup& group) if (i >= count()) { openNewActivatedTab(); } - const QByteArray state = group.readEntry("Tab " % QString::number(i), QByteArray()); - tabPageAt(i)->restoreState(state); + if (group.hasKey("Tab Data " % QString::number(i))) { + // Tab state created with Dolphin > 4.14.x + const QByteArray state = group.readEntry("Tab Data " % QString::number(i), QByteArray()); + tabPageAt(i)->restoreState(state); + } else { + // Tab state created with Dolphin <= 4.14.x + const QByteArray state = group.readEntry("Tab " % QString::number(i), QByteArray()); + tabPageAt(i)->restoreStateV1(state); + } } const int index = group.readEntry("Active Tab Index", 0); diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 02b8815e0..1de973bd5 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -1167,6 +1167,14 @@ bool DolphinView::itemsExpandable() const void DolphinView::restoreState(QDataStream& stream) { + // Read the version number of the view state and check if the version is supported. + quint32 version = 0; + stream >> version; + if (version != 1) { + // The version of the view state isn't supported, we can't restore it. + return; + } + // Restore the current item that had the keyboard focus stream >> m_currentItemUrl; @@ -1181,6 +1189,8 @@ void DolphinView::restoreState(QDataStream& stream) void DolphinView::saveState(QDataStream& stream) { + stream << quint32(1); // View state version + // Save the current item that has the keyboard focus const int currentIndex = m_container->controller()->selectionManager()->currentItem(); if (currentIndex != -1) { -- cgit v1.3