diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -201,6 +202,13 @@ DolphinMainWindow::~DolphinMainWindow() { + if (GeneralSettings::rememberOpenedTabs()) { + KConfigGui::setSessionConfig(QStringLiteral("dolphin"), QStringLiteral("dolphin")); + KConfig *config = KConfigGui::sessionConfig(); + saveGlobalProperties(config); + savePropertiesInternal(config, 1); + config->sync(); + } } QVector DolphinMainWindow::viewContainers() const diff --git a/src/global.h b/src/global.h --- a/src/global.h +++ b/src/global.h @@ -20,6 +20,8 @@ #ifndef GLOBAL_H #define GLOBAL_H +#include +#include #include #include @@ -48,6 +50,12 @@ */ bool attachToExistingInstance(const QList& inputUrls, bool openFiles, bool splitView, const QString& preferredService = QString()); + /** + * Returns a QVector with full data about all currently-running GUI-capable + * Dolphin instances + */ + QVector, QStringList>> dolphinInstanceData(const QString& preferredService); + /** * TODO: Move this somewhere global to all KDE apps, not just Dolphin */ diff --git a/src/global.cpp b/src/global.cpp --- a/src/global.cpp +++ b/src/global.cpp @@ -77,6 +77,42 @@ return false; } + QVector, QStringList>> dolphinServices = dolphinInstanceData(preferredService); + if (dolphinServices.isEmpty()) { + return false; + } + + QStringList newUrls; + + // check to see if any instances already have any of the given URLs open + const auto urls = QUrl::toStringList(inputUrls); + for (const QString& url : urls) { + bool urlFound = false; + for (auto& service: dolphinServices) { + QDBusReply isUrlOpen = service.first->call(QStringLiteral("isUrlOpen"), url); + if (isUrlOpen.isValid() && isUrlOpen.value()) { + service.second.append(url); + urlFound = true; + break; + } + } + if (!urlFound) { + newUrls.append(url); + } + } + dolphinServices.front().second << newUrls; + + for (const auto& service: dolphinServices) { + if (!service.second.isEmpty()) { + service.first->call(openFiles ? QStringLiteral("openFiles") : QStringLiteral("openDirectories"), service.second, splitView); + service.first->call(QStringLiteral("activateWindow")); + } + } + return true; +} + +QVector, QStringList>> Dolphin::dolphinInstanceData(const QString& preferredService) +{ QVector, QStringList>> dolphinServices; if (!preferredService.isEmpty()) { QSharedPointer preferred( @@ -110,34 +146,7 @@ } if (dolphinServices.isEmpty()) { - return false; + return QVector, QStringList>>(); } - - QStringList newUrls; - - // check to see if any instances already have any of the given URLs open - const auto urls = QUrl::toStringList(inputUrls); - for (const QString& url : urls) { - bool urlFound = false; - for (auto& service: dolphinServices) { - QDBusReply isUrlOpen = service.first->call(QStringLiteral("isUrlOpen"), url); - if (isUrlOpen.isValid() && isUrlOpen.value()) { - service.second.append(url); - urlFound = true; - break; - } - } - if (!urlFound) { - newUrls.append(url); - } - } - dolphinServices.front().second << newUrls; - - for (const auto& service: dolphinServices) { - if (!service.second.isEmpty()) { - service.first->call(openFiles ? QStringLiteral("openFiles") : QStringLiteral("openDirectories"), service.second, splitView); - service.first->call(QStringLiteral("activateWindow")); - } - } - return true; + return dolphinServices; } diff --git a/src/main.cpp b/src/main.cpp --- a/src/main.cpp +++ b/src/main.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -139,6 +140,7 @@ const bool openFiles = parser.isSet(QStringLiteral("select")); const QStringList args = parser.positionalArguments(); QList urls = Dolphin::validateUris(args); + bool urlCommandLineArguments = !urls.isEmpty(); if (parser.isSet(QStringLiteral("daemon"))) { KDBusService dolphinDBusService; @@ -173,12 +175,18 @@ mainWindow->show(); - if (app.isSessionRestored()) { - const QString className = KXmlGuiWindow::classNameOfToplevel(1); - if (className == QLatin1String("DolphinMainWindow")) { - mainWindow->restore(1); - } else { - qCWarning(DolphinDebug) << "Unknown class " << className << " in session saved data!"; + if (!app.isSessionRestored()) { + KConfigGui::setSessionConfig(QStringLiteral("dolphin"), QStringLiteral("dolphin")); + } + + if (!urlCommandLineArguments && (app.isSessionRestored() || GeneralSettings::rememberOpenedTabs()) ) { + // Only restore if there are no Dolphin windows already open; in this case + // we want to open a new fresh window + if (Dolphin::dolphinInstanceData(QStringLiteral("org.kde.dolphin-%1").arg(QCoreApplication::applicationPid())).isEmpty()) { + const QString className = KXmlGuiWindow::classNameOfToplevel(1); + if (className == QLatin1String("DolphinMainWindow")) { + mainWindow->restore(1); + } } } diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg --- a/src/settings/dolphin_generalsettings.kcfg +++ b/src/settings/dolphin_generalsettings.kcfg @@ -42,6 +42,10 @@ QUrl::fromLocalFile(QDir::homePath()).toDisplayString(QUrl::PreferLocalFile) + + + true + false diff --git a/src/settings/startup/startupsettingspage.h b/src/settings/startup/startupsettingspage.h --- a/src/settings/startup/startupsettingspage.h +++ b/src/settings/startup/startupsettingspage.h @@ -23,8 +23,9 @@ #include -class QLineEdit; class QCheckBox; +class QLineEdit; +class QRadioButton; /** * @brief Page for the 'Startup' settings of the Dolphin settings dialog. @@ -48,6 +49,7 @@ private slots: void slotSettingsChanged(); + void updateInitialViewOptions(); void selectHomeUrl(); void useCurrentLocation(); void useDefaultLocation(); @@ -58,6 +60,10 @@ private: QUrl m_url; QLineEdit* m_homeUrl; + QWidget* m_homeUrlBoxLayoutContainer; + QWidget* m_buttonBoxLayoutContainer; + QRadioButton* m_rememberOpenedTabsRadioButton; + QRadioButton* m_homeUrlRadioButton; QCheckBox* m_splitView; QCheckBox* m_editableUrl; diff --git a/src/settings/startup/startupsettingspage.cpp b/src/settings/startup/startupsettingspage.cpp --- a/src/settings/startup/startupsettingspage.cpp +++ b/src/settings/startup/startupsettingspage.cpp @@ -27,18 +27,24 @@ #include #include +#include #include #include #include #include +#include #include +#include #include -#include StartupSettingsPage::StartupSettingsPage(const QUrl& url, QWidget* parent) : SettingsPageBase(parent), m_url(url), m_homeUrl(nullptr), + m_homeUrlBoxLayoutContainer(nullptr), + m_buttonBoxLayoutContainer(nullptr), + m_rememberOpenedTabsRadioButton(nullptr), + m_homeUrlRadioButton(nullptr), m_splitView(nullptr), m_editableUrl(nullptr), m_showFullPath(nullptr), @@ -48,9 +54,17 @@ { QFormLayout* topLayout = new QFormLayout(this); + m_rememberOpenedTabsRadioButton = new QRadioButton(i18nc("@option:radio Startup Settings", "Folders and tabs that were open before")); + m_homeUrlRadioButton = new QRadioButton(); + + QButtonGroup* initialViewGroup = new QButtonGroup(this); + initialViewGroup->addButton(m_rememberOpenedTabsRadioButton); + initialViewGroup->addButton(m_homeUrlRadioButton); + // create 'Home URL' editor - QHBoxLayout* homeUrlBoxLayout = new QHBoxLayout(); + m_homeUrlBoxLayoutContainer = new QWidget; + QHBoxLayout* homeUrlBoxLayout = new QHBoxLayout(m_homeUrlBoxLayoutContainer); homeUrlBoxLayout->setContentsMargins(0, 0, 0, 0); m_homeUrl = new QLineEdit(); @@ -67,7 +81,8 @@ connect(selectHomeUrlButton, &QPushButton::clicked, this, &StartupSettingsPage::selectHomeUrl); - QHBoxLayout* buttonBoxLayout = new QHBoxLayout(); + m_buttonBoxLayoutContainer = new QWidget; + QHBoxLayout* buttonBoxLayout = new QHBoxLayout(m_buttonBoxLayoutContainer); buttonBoxLayout->setContentsMargins(0, 0, 0, 0); QPushButton* useCurrentButton = new QPushButton(i18nc("@action:button", "Use Current Location")); @@ -79,41 +94,50 @@ connect(useDefaultButton, &QPushButton::clicked, this, &StartupSettingsPage::useDefaultLocation); - QVBoxLayout* homeBoxLayout = new QVBoxLayout(); - homeBoxLayout->setContentsMargins(0, 0, 0, 0); - homeBoxLayout->addLayout(homeUrlBoxLayout); - homeBoxLayout->addLayout(buttonBoxLayout); + QGridLayout* startInLocationLayout = new QGridLayout(); + startInLocationLayout->setContentsMargins(0, 0, 0, 0); + startInLocationLayout->addWidget(m_homeUrlRadioButton, 0, 0); + startInLocationLayout->addWidget(m_homeUrlBoxLayoutContainer, 0, 1); + startInLocationLayout->addWidget(m_buttonBoxLayoutContainer, 1, 1); - topLayout->addRow(i18nc("@label:textbox", "Start in:"), homeBoxLayout); + topLayout->addRow(i18nc("@label:textbox", "Show on startup:"), m_rememberOpenedTabsRadioButton); + topLayout->addRow(QString(), startInLocationLayout); topLayout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed)); - - // create 'Split view', 'Show full path', 'Editable location' and 'Filter bar' checkboxes - m_splitView = new QCheckBox(i18nc("@option:check Startup Settings", "Split view mode")); - topLayout->addRow(i18nc("@label:checkbox", "Window options:"), m_splitView); - m_editableUrl = new QCheckBox(i18nc("@option:check Startup Settings", "Editable location bar")); + m_splitView = new QCheckBox(i18nc("@option:check Startup Settings", "Begin in split view mode")); + topLayout->addRow(i18n("New windows:"), m_splitView); + m_filterBar = new QCheckBox(i18nc("@option:check Startup Settings", "Show filter bar")); + topLayout->addRow(QString(), m_filterBar); + m_editableUrl = new QCheckBox(i18nc("@option:check Startup Settings", "Make location bar editable")); topLayout->addRow(QString(), m_editableUrl); + + topLayout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed)); + + m_openExternallyCalledFolderInNewTab = new QCheckBox(i18nc("@option:check Startup Settings", "Open new folders in tabs")); + topLayout->addRow(i18nc("@label:checkbox", "General:"), m_openExternallyCalledFolderInNewTab); m_showFullPath = new QCheckBox(i18nc("@option:check Startup Settings", "Show full path inside location bar")); topLayout->addRow(QString(), m_showFullPath); - m_filterBar = new QCheckBox(i18nc("@option:check Startup Settings", "Show filter bar")); - topLayout->addRow(QString(), m_filterBar); m_showFullPathInTitlebar = new QCheckBox(i18nc("@option:check Startup Settings", "Show full path in title bar")); topLayout->addRow(QString(), m_showFullPathInTitlebar); - m_openExternallyCalledFolderInNewTab = new QCheckBox(i18nc("@option:check Startup Settings", "Open new folders in tabs")); - topLayout->addRow(QString(), m_openExternallyCalledFolderInNewTab); - loadSettings(); + updateInitialViewOptions(); + connect(m_homeUrl, &QLineEdit::textChanged, this, &StartupSettingsPage::slotSettingsChanged); + connect(m_rememberOpenedTabsRadioButton, &QRadioButton::toggled, this, &StartupSettingsPage::slotSettingsChanged); + connect(m_homeUrlRadioButton, &QRadioButton::toggled, this, + &StartupSettingsPage::slotSettingsChanged); + connect(m_splitView, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); connect(m_editableUrl, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); - connect(m_showFullPath, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); connect(m_filterBar, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); - connect(m_showFullPathInTitlebar, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); + connect(m_openExternallyCalledFolderInNewTab, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); + connect(m_showFullPath, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); + connect(m_showFullPathInTitlebar, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged); } StartupSettingsPage::~StartupSettingsPage() @@ -132,12 +156,21 @@ KMessageBox::error(this, i18nc("@info", "The location for the home folder is invalid or does not exist, it will not be applied.")); } + // Remove saved state state if "remember open tabs" has been turned off + if (!m_rememberOpenedTabsRadioButton->isChecked()) { + KConfigGroup windowState{KSharedConfig::openConfig(QStringLiteral("dolphinrc")), "WindowState"}; + if (windowState.exists()) { + windowState.deleteGroup(); + } + } + + settings->setRememberOpenedTabs(m_rememberOpenedTabsRadioButton->isChecked()); settings->setSplitView(m_splitView->isChecked()); settings->setEditableUrl(m_editableUrl->isChecked()); - settings->setShowFullPath(m_showFullPath->isChecked()); settings->setFilterBar(m_filterBar->isChecked()); - settings->setShowFullPathInTitlebar(m_showFullPathInTitlebar->isChecked()); settings->setOpenExternallyCalledFolderInNewTab(m_openExternallyCalledFolderInNewTab->isChecked()); + settings->setShowFullPath(m_showFullPath->isChecked()); + settings->setShowFullPathInTitlebar(m_showFullPathInTitlebar->isChecked()); settings->save(); } @@ -155,9 +188,18 @@ // to apply the startup settings only if they have been explicitly changed by the user // (see bug #254947). GeneralSettings::setModifiedStartupSettings(true); + + // Enable and disable home URL controls appropriately + updateInitialViewOptions(); emit changed(); } +void StartupSettingsPage::updateInitialViewOptions() +{ + m_homeUrlBoxLayoutContainer->setEnabled(m_homeUrlRadioButton->isChecked()); + m_buttonBoxLayoutContainer->setEnabled(m_homeUrlRadioButton->isChecked()); +} + void StartupSettingsPage::selectHomeUrl() { const QUrl homeUrl(QUrl::fromUserInput(m_homeUrl->text(), QString(), QUrl::AssumeLocalFile)); @@ -182,6 +224,8 @@ { const QUrl url(Dolphin::homeUrl()); m_homeUrl->setText(url.toDisplayString(QUrl::PreferLocalFile)); + m_rememberOpenedTabsRadioButton->setChecked(GeneralSettings::rememberOpenedTabs()); + m_homeUrlRadioButton->setChecked(!GeneralSettings::rememberOpenedTabs()); m_splitView->setChecked(GeneralSettings::splitView()); m_editableUrl->setChecked(GeneralSettings::editableUrl()); m_showFullPath->setChecked(GeneralSettings::showFullPath());