diff options
Diffstat (limited to 'src/settings')
18 files changed, 334 insertions, 120 deletions
diff --git a/src/settings/dolphin_detailsmodesettings.kcfg b/src/settings/dolphin_detailsmodesettings.kcfg index e9a8fb28d..9d05a8ab0 100644 --- a/src/settings/dolphin_detailsmodesettings.kcfg +++ b/src/settings/dolphin_detailsmodesettings.kcfg @@ -44,5 +44,13 @@ <label>Expandable folders</label> <default>true</default> </entry> + <entry name="DirectorySizeCount" type="Bool"> + <label>Whether or not content count is used as directory size</label> + <default>true</default> + </entry> + <entry name="RecursiveDirectorySizeLimit" type="UInt"> + <label>Recursive directory size limit</label> + <default>10</default> + </entry> </group> </kcfg> diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg index fca70656d..c397b2945 100644 --- a/src/settings/dolphin_generalsettings.kcfg +++ b/src/settings/dolphin_generalsettings.kcfg @@ -42,6 +42,10 @@ <label>Home URL</label> <default code="true">QUrl::fromLocalFile(QDir::homePath()).toDisplayString(QUrl::PreferLocalFile)</default> </entry> + <entry name="RememberOpenedTabs" type="Bool"> + <label>Remember open folders and tabs</label> + <default>true</default> + </entry> <entry name="SplitView" type="Bool"> <label>Split the view into two panes</label> <default>false</default> diff --git a/src/settings/kcm/kcmdolphingeneral.cpp b/src/settings/kcm/kcmdolphingeneral.cpp index a82cb3858..39eccff76 100644 --- a/src/settings/kcm/kcmdolphingeneral.cpp +++ b/src/settings/kcm/kcmdolphingeneral.cpp @@ -33,12 +33,10 @@ K_PLUGIN_FACTORY(KCMDolphinGeneralConfigFactory, registerPlugin<DolphinGeneralConfigModule>(QStringLiteral("dolphingeneral"));) -DolphinGeneralConfigModule::DolphinGeneralConfigModule(QWidget* parent, const QVariantList& args) : - KCModule(parent), +DolphinGeneralConfigModule::DolphinGeneralConfigModule(QWidget *parent, const QVariantList &args) : + KCModule(parent, args), m_pages() { - Q_UNUSED(args) - setButtons(KCModule::Default | KCModule::Help); QVBoxLayout* topLayout = new QVBoxLayout(this); @@ -49,29 +47,17 @@ DolphinGeneralConfigModule::DolphinGeneralConfigModule(QWidget* parent, const QV // initialize 'Behavior' tab BehaviorSettingsPage* behaviorPage = new BehaviorSettingsPage(QUrl::fromLocalFile(QDir::homePath()), tabWidget); tabWidget->addTab(behaviorPage, i18nc("@title:tab Behavior settings", "Behavior")); -#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0) - connect(behaviorPage, &BehaviorSettingsPage::changed, this, QOverload<>::of(&DolphinGeneralConfigModule::changed)); -#else connect(behaviorPage, &BehaviorSettingsPage::changed, this, &DolphinGeneralConfigModule::markAsChanged); -#endif // initialize 'Previews' tab PreviewsSettingsPage* previewsPage = new PreviewsSettingsPage(tabWidget); tabWidget->addTab(previewsPage, i18nc("@title:tab Previews settings", "Previews")); -#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0) - connect(previewsPage, &PreviewsSettingsPage::changed, this, QOverload<>::of(&DolphinGeneralConfigModule::changed)); -#else connect(previewsPage, &PreviewsSettingsPage::changed, this, &DolphinGeneralConfigModule::markAsChanged); -#endif // initialize 'Confirmations' tab ConfirmationsSettingsPage* confirmationsPage = new ConfirmationsSettingsPage(tabWidget); tabWidget->addTab(confirmationsPage, i18nc("@title:tab Confirmations settings", "Confirmations")); -#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0) - connect(confirmationsPage, &ConfirmationsSettingsPage::changed, this, QOverload<>::of(&DolphinGeneralConfigModule::changed)); -#else connect(confirmationsPage, &ConfirmationsSettingsPage::changed, this, &DolphinGeneralConfigModule::markAsChanged); -#endif m_pages.append(behaviorPage); m_pages.append(previewsPage); m_pages.append(confirmationsPage); @@ -85,14 +71,14 @@ DolphinGeneralConfigModule::~DolphinGeneralConfigModule() void DolphinGeneralConfigModule::save() { - foreach (SettingsPageBase* page, m_pages) { + for (SettingsPageBase* page : qAsConst(m_pages)) { page->applySettings(); } } void DolphinGeneralConfigModule::defaults() { - foreach (SettingsPageBase* page, m_pages) { + for (SettingsPageBase* page : qAsConst(m_pages)) { page->applySettings(); } } diff --git a/src/settings/kcm/kcmdolphingeneral.h b/src/settings/kcm/kcmdolphingeneral.h index c542c0139..2b60c7591 100644 --- a/src/settings/kcm/kcmdolphingeneral.h +++ b/src/settings/kcm/kcmdolphingeneral.h @@ -34,7 +34,7 @@ class DolphinGeneralConfigModule : public KCModule Q_OBJECT public: - DolphinGeneralConfigModule(QWidget* parent, const QVariantList& args); + DolphinGeneralConfigModule(QWidget *parent, const QVariantList &args); ~DolphinGeneralConfigModule() override; void save() override; diff --git a/src/settings/kcm/kcmdolphinnavigation.cpp b/src/settings/kcm/kcmdolphinnavigation.cpp index 2cdabdeee..f8de4eed2 100644 --- a/src/settings/kcm/kcmdolphinnavigation.cpp +++ b/src/settings/kcm/kcmdolphinnavigation.cpp @@ -29,23 +29,17 @@ K_PLUGIN_FACTORY(KCMDolphinNavigationConfigFactory, registerPlugin<DolphinNavigationConfigModule>(QStringLiteral("dolphinnavigation"));) -DolphinNavigationConfigModule::DolphinNavigationConfigModule(QWidget* parent, const QVariantList& args) : - KCModule(parent), +DolphinNavigationConfigModule::DolphinNavigationConfigModule(QWidget *parent, const QVariantList &args) : + KCModule(parent, args), m_navigation(nullptr) { - Q_UNUSED(args) - setButtons(KCModule::Default | KCModule::Help); QVBoxLayout* topLayout = new QVBoxLayout(this); topLayout->setContentsMargins(0, 0, 0, 0); m_navigation = new NavigationSettingsPage(this); -#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0) - connect(m_navigation, &NavigationSettingsPage::changed, this, QOverload<>::of(&DolphinNavigationConfigModule::changed)); -#else connect(m_navigation, &NavigationSettingsPage::changed, this, &DolphinNavigationConfigModule::markAsChanged); -#endif topLayout->addWidget(m_navigation, 0, {}); } diff --git a/src/settings/kcm/kcmdolphinnavigation.h b/src/settings/kcm/kcmdolphinnavigation.h index 2bcc7abab..7eb6b26e7 100644 --- a/src/settings/kcm/kcmdolphinnavigation.h +++ b/src/settings/kcm/kcmdolphinnavigation.h @@ -32,14 +32,14 @@ class DolphinNavigationConfigModule : public KCModule Q_OBJECT public: - DolphinNavigationConfigModule(QWidget* parent, const QVariantList& args); + DolphinNavigationConfigModule(QWidget *parent, const QVariantList &args); ~DolphinNavigationConfigModule() override; void save() override; void defaults() override; private: - NavigationSettingsPage* m_navigation; + NavigationSettingsPage *m_navigation; }; #endif diff --git a/src/settings/kcm/kcmdolphinservices.cpp b/src/settings/kcm/kcmdolphinservices.cpp index e6a8867d7..92e71bae0 100644 --- a/src/settings/kcm/kcmdolphinservices.cpp +++ b/src/settings/kcm/kcmdolphinservices.cpp @@ -30,22 +30,16 @@ K_PLUGIN_FACTORY(KCMDolphinServicesConfigFactory, registerPlugin<DolphinServicesConfigModule>(QStringLiteral("dolphinservices"));) DolphinServicesConfigModule::DolphinServicesConfigModule(QWidget* parent, const QVariantList& args) : - KCModule(parent), + KCModule(parent, args), m_services(nullptr) { - Q_UNUSED(args) - setButtons(KCModule::Default | KCModule::Help); QVBoxLayout* topLayout = new QVBoxLayout(this); topLayout->setContentsMargins(0, 0, 0, 0); m_services = new ServicesSettingsPage(this); -#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0) - connect(m_services, &ServicesSettingsPage::changed, this, QOverload<>::of(&DolphinServicesConfigModule::changed)); -#else connect(m_services, &ServicesSettingsPage::changed, this, &DolphinServicesConfigModule::markAsChanged); -#endif topLayout->addWidget(m_services, 0, {}); } diff --git a/src/settings/kcm/kcmdolphinservices.h b/src/settings/kcm/kcmdolphinservices.h index 6c6af6728..a567450ca 100644 --- a/src/settings/kcm/kcmdolphinservices.h +++ b/src/settings/kcm/kcmdolphinservices.h @@ -39,7 +39,7 @@ public: void defaults() override; private: - ServicesSettingsPage* m_services; + ServicesSettingsPage *m_services; }; #endif diff --git a/src/settings/kcm/kcmdolphinviewmodes.cpp b/src/settings/kcm/kcmdolphinviewmodes.cpp index 4fac11600..91abe5cd4 100644 --- a/src/settings/kcm/kcmdolphinviewmodes.cpp +++ b/src/settings/kcm/kcmdolphinviewmodes.cpp @@ -33,12 +33,10 @@ K_PLUGIN_FACTORY(KCMDolphinViewModesConfigFactory, registerPlugin<DolphinViewModesConfigModule>(QStringLiteral("dolphinviewmodes"));) -DolphinViewModesConfigModule::DolphinViewModesConfigModule(QWidget* parent, const QVariantList& args) : - KCModule(parent), +DolphinViewModesConfigModule::DolphinViewModesConfigModule(QWidget *parent, const QVariantList &args) : + KCModule(parent, args), m_tabs() { - Q_UNUSED(args) - setButtons(KCModule::Default | KCModule::Help); QVBoxLayout* topLayout = new QVBoxLayout(this); @@ -74,7 +72,7 @@ DolphinViewModesConfigModule::~DolphinViewModesConfigModule() void DolphinViewModesConfigModule::save() { - foreach (ViewSettingsTab* tab, m_tabs) { + for (ViewSettingsTab *tab : qAsConst(m_tabs)) { tab->applySettings(); } reparseConfiguration(); @@ -82,7 +80,7 @@ void DolphinViewModesConfigModule::save() void DolphinViewModesConfigModule::defaults() { - foreach (ViewSettingsTab* tab, m_tabs) { + for (ViewSettingsTab *tab : qAsConst(m_tabs)) { tab->restoreDefaultSettings(); } reparseConfiguration(); @@ -90,13 +88,15 @@ void DolphinViewModesConfigModule::defaults() void DolphinViewModesConfigModule::reparseConfiguration() { - QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KonqMain"), QStringLiteral("org.kde.Konqueror.Main"), QStringLiteral("reparseConfiguration")); + QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KonqMain"), + QStringLiteral("org.kde.Konqueror.Main"), + QStringLiteral("reparseConfiguration")); QDBusConnection::sessionBus().send(message); } void DolphinViewModesConfigModule::viewModeChanged() { - emit changed(true); + emit markAsChanged(); } #include "kcmdolphinviewmodes.moc" diff --git a/src/settings/kcm/kcmdolphinviewmodes.h b/src/settings/kcm/kcmdolphinviewmodes.h index c3775adff..40965b0e6 100644 --- a/src/settings/kcm/kcmdolphinviewmodes.h +++ b/src/settings/kcm/kcmdolphinviewmodes.h @@ -32,7 +32,7 @@ class DolphinViewModesConfigModule : public KCModule Q_OBJECT public: - DolphinViewModesConfigModule(QWidget* parent, const QVariantList& args); + DolphinViewModesConfigModule(QWidget *parent, const QVariantList &args); ~DolphinViewModesConfigModule() override; void save() override; diff --git a/src/settings/services/servicemenuinstaller/CMakeLists.txt b/src/settings/services/servicemenuinstaller/CMakeLists.txt index 988899936..46b159079 100644 --- a/src/settings/services/servicemenuinstaller/CMakeLists.txt +++ b/src/settings/services/servicemenuinstaller/CMakeLists.txt @@ -6,5 +6,10 @@ target_link_libraries(servicemenuinstaller PRIVATE Qt5::Core Qt5::Gui KF5::I18n + KF5::CoreAddons ) + +if(HAVE_PACKAGEKIT) + target_link_libraries(servicemenuinstaller PRIVATE PK::packagekitqt5) +endif() install(TARGETS servicemenuinstaller ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp b/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp index 06f34c6b9..89f2545f8 100644 --- a/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp +++ b/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp @@ -20,28 +20,42 @@ #include <QDebug> #include <QProcess> +#include <QTimer> #include <QStandardPaths> #include <QDir> #include <QDirIterator> #include <QCommandLineParser> #include <QMimeDatabase> #include <QUrl> -#include <QDesktopServices> #include <QGuiApplication> - #include <KLocalizedString> +#include <KShell> + +#include "../../../config-packagekit.h" + +const static QStringList binaryPackages = {QStringLiteral("application/vnd.debian.binary-package"), + QStringLiteral("application/x-rpm"), + QStringLiteral("application/x-xz"), + QStringLiteral("application/zstd")}; +enum PackageOperation { + Install, + Uninstall +}; + +#ifdef HAVE_PACKAGEKIT +#include <PackageKit/Daemon> +#include <PackageKit/Details> +#include <PackageKit/Transaction> +#else +#include <QDesktopServices> +#endif // @param msg Error that gets logged to CLI Q_NORETURN void fail(const QString &str) { qCritical() << str; - - QProcess process; - const QStringList args = {"--passivepopup", i18n("Dolphin service menu installation failed"), "15"}; - process.start("kdialog", args, QIODevice::ReadOnly); - if (!process.waitForStarted()) { - qFatal("Failed to run kdialog"); - } + const QStringList args = {"--detailederror" ,i18n("Dolphin service menu installation failed"), str}; + QProcess::startDetached("kdialog", args); exit(1); } @@ -52,6 +66,84 @@ QString getServiceMenusDir() return QDir(dataLocation).absoluteFilePath("kservices5/ServiceMenus"); } +#ifdef HAVE_PACKAGEKIT +void packageKitInstall(const QString &fileName) +{ + PackageKit::Transaction *transaction = PackageKit::Daemon::installFile(fileName); + + const auto exitWithError = [=](PackageKit::Transaction::Error, const QString &details) { + fail(details); + }; + + QObject::connect(transaction, &PackageKit::Transaction::finished, + [=](PackageKit::Transaction::Exit status, uint) { + if (status == PackageKit::Transaction::ExitSuccess) { + exit(0); + } + // Fallback error handling + QTimer::singleShot(500, [=](){ + fail(i18n("Failed to install \"%1\", exited with status \"%2\"", + fileName, QVariant::fromValue(status).toString())); + }); + }); + QObject::connect(transaction, &PackageKit::Transaction::errorCode, exitWithError); +} + +void packageKitUninstall(const QString &fileName) +{ + const auto exitWithError = [=](PackageKit::Transaction::Error, const QString &details) { + fail(details); + }; + const auto uninstallLambda = [=](PackageKit::Transaction::Exit status, uint) { + if (status == PackageKit::Transaction::ExitSuccess) { + exit(0); + } + }; + + PackageKit::Transaction *transaction = PackageKit::Daemon::getDetailsLocal(fileName); + QObject::connect(transaction, &PackageKit::Transaction::details, + [=](const PackageKit::Details &details) { + PackageKit::Transaction *transaction = PackageKit::Daemon::removePackage(details.packageId()); + QObject::connect(transaction, &PackageKit::Transaction::finished, uninstallLambda); + QObject::connect(transaction, &PackageKit::Transaction::errorCode, exitWithError); + }); + + QObject::connect(transaction, &PackageKit::Transaction::errorCode, exitWithError); + // Fallback error handling + QObject::connect(transaction, &PackageKit::Transaction::finished, + [=](PackageKit::Transaction::Exit status, uint) { + if (status != PackageKit::Transaction::ExitSuccess) { + QTimer::singleShot(500, [=]() { + fail(i18n("Failed to uninstall \"%1\", exited with status \"%2\"", + fileName, QVariant::fromValue(status).toString())); + }); + } + }); + } +#endif + +Q_NORETURN void packageKit(PackageOperation operation, const QString &fileName) +{ +#ifdef HAVE_PACKAGEKIT + QFileInfo fileInfo(fileName); + if (!fileInfo.exists()) { + fail(i18n("The file does not exist!")); + } + const QString absPath = fileInfo.absoluteFilePath(); + if (operation == PackageOperation::Install) { + packageKitInstall(absPath); + } else { + packageKitUninstall(absPath); + } + QGuiApplication::exec(); // For event handling, no return after signals finish + fail(i18n("Unknown error when installing package")); +#else + Q_UNUSED(operation) + QDesktopServices::openUrl(QUrl(fileName)); + exit(0); +#endif +} + struct UncompressCommand { QString command; @@ -59,6 +151,11 @@ struct UncompressCommand QStringList args2; }; +enum ScriptExecution{ + Process, + Konsole +}; + void runUncompress(const QString &inputPath, const QString &outputPath) { QVector<QPair<QStringList, UncompressCommand>> mimeTypeToCommand; @@ -126,12 +223,24 @@ QString findRecursive(const QString &dir, const QString &basename) return QString(); } -bool runScriptOnce(const QString &path, const QStringList &args) +bool runScriptOnce(const QString &path, const QStringList &args, ScriptExecution execution) { QProcess process; process.setWorkingDirectory(QFileInfo(path).absolutePath()); - process.start(path, args, QIODevice::NotOpen); + const static bool konsoleAvailable = !QStandardPaths::findExecutable("konsole").isEmpty(); + if (konsoleAvailable && execution == ScriptExecution::Konsole) { + QString bashCommand = KShell::quoteArg(path) + ' '; + if (!args.isEmpty()) { + bashCommand.append(args.join(' ')); + } + bashCommand.append("|| $SHELL"); + // If the install script fails a shell opens and the user can fix the problem + // without an error konsole closes + process.start("konsole", QStringList() << "-e" << "bash" << "-c" << bashCommand, QIODevice::NotOpen); + } else { + process.start(path, args, QIODevice::NotOpen); + } if (!process.waitForStarted()) { fail(i18n("Failed to run installer script %1", path)); } @@ -163,11 +272,11 @@ bool runScriptVariants(const QString &path, bool hasArgVariants, const QStringLi qInfo() << "[servicemenuinstaller]: Trying to run installer/uninstaller" << path; if (hasArgVariants) { for (const auto &arg : argVariants) { - if (runScriptOnce(path, {arg})) { + if (runScriptOnce(path, {arg}, ScriptExecution::Process)) { return true; } } - } else if (runScriptOnce(path, {})) { + } else if (runScriptOnce(path, {}, ScriptExecution::Konsole)) { return true; } @@ -202,9 +311,8 @@ bool cmdInstall(const QString &archive, QString &errorText) return false; } } else { - const QStringList binaryPackages = {"application/vnd.debian.binary-package", "application/x-rpm"}; if (binaryPackages.contains(QMimeDatabase().mimeTypeForFile(archive).name())) { - return QDesktopServices::openUrl(QUrl(archive)); + packageKit(PackageOperation::Install, archive); } const QString dir = generateDirPath(archive); if (QFile::exists(dir)) { @@ -247,7 +355,11 @@ bool cmdInstall(const QString &archive, QString &errorText) } if (!installerPath.isEmpty()) { - return runScriptVariants(installerPath, true, {"--local", "--local-install", "--install"}, errorText); + // Try to run script without variants first + if (!runScriptVariants(installerPath, false, {}, errorText)) { + return runScriptVariants(installerPath, true, {"--local", "--local-install", "--install"}, errorText); + } + return true; } fail(i18n("Failed to find an installation script in %1", dir)); @@ -268,6 +380,9 @@ bool cmdUninstall(const QString &archive, QString &errorText) return false; } } else { + if (binaryPackages.contains(QMimeDatabase().mimeTypeForFile(archive).name())) { + packageKit(PackageOperation::Uninstall, archive); + } const QString dir = generateDirPath(archive); // Try "deinstall" first diff --git a/src/settings/services/servicessettingspage.cpp b/src/settings/services/servicessettingspage.cpp index fe900bc5c..e18bfb09e 100644 --- a/src/settings/services/servicessettingspage.cpp +++ b/src/settings/services/servicessettingspage.cpp @@ -38,6 +38,7 @@ #include <QListWidget> #include <QShowEvent> #include <QSortFilterProxyModel> +#include <QLineEdit> namespace { @@ -61,25 +62,33 @@ ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) : "Select which services should " "be shown in the context menu:"), this); label->setWordWrap(true); + m_searchLineEdit = new QLineEdit(this); + m_searchLineEdit->setPlaceholderText(i18nc("@label:textbox", "Search...")); + connect(m_searchLineEdit, &QLineEdit::textChanged, this, [this](const QString &filter){ + m_sortModel->setFilterFixedString(filter); + }); m_listView = new QListView(this); - ServiceItemDelegate* delegate = new ServiceItemDelegate(m_listView, m_listView); + auto *delegate = new ServiceItemDelegate(m_listView, m_listView); m_serviceModel = new ServiceModel(this); m_sortModel = new QSortFilterProxyModel(this); m_sortModel->setSourceModel(m_serviceModel); m_sortModel->setSortRole(Qt::DisplayRole); m_sortModel->setSortLocaleAware(true); + m_sortModel->setFilterRole(Qt::DisplayRole); + m_sortModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_listView->setModel(m_sortModel); m_listView->setItemDelegate(delegate); m_listView->setVerticalScrollMode(QListView::ScrollPerPixel); connect(m_listView, &QListView::clicked, this, &ServicesSettingsPage::changed); - KNS3::Button* downloadButton = new KNS3::Button(i18nc("@action:button", "Download New Services..."), - QStringLiteral("servicemenu.knsrc"), - this); + auto *downloadButton = new KNS3::Button(i18nc("@action:button", "Download New Services..."), + QStringLiteral("servicemenu.knsrc"), + this); connect(downloadButton, &KNS3::Button::dialogFinished, this, &ServicesSettingsPage::loadServices); topLayout->addWidget(label); + topLayout->addWidget(m_searchLineEdit); topLayout->addWidget(m_listView); topLayout->addWidget(downloadButton); @@ -87,9 +96,7 @@ ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) : std::sort(m_enabledVcsPlugins.begin(), m_enabledVcsPlugins.end()); } -ServicesSettingsPage::~ServicesSettingsPage() -{ -} +ServicesSettingsPage::~ServicesSettingsPage() = default; void ServicesSettingsPage::applySettings() { @@ -102,7 +109,7 @@ void ServicesSettingsPage::applySettings() QStringList enabledPlugins; - const QAbstractItemModel* model = m_listView->model(); + const QAbstractItemModel *model = m_listView->model(); for (int i = 0; i < model->rowCount(); ++i) { const QModelIndex index = model->index(i, 0); const QString service = model->data(index, ServiceModel::DesktopEntryNameRole).toString(); @@ -188,19 +195,16 @@ void ServicesSettingsPage::loadServices() // Load generic services const KService::List entries = KServiceTypeTrader::self()->query(QStringLiteral("KonqPopupMenu/Plugin")); - foreach (const KService::Ptr& service, entries) { + for (const KService::Ptr &service : entries) { const QString file = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kservices5/" % service->entryPath()); - const QList<KServiceAction> serviceActions = - KDesktopFileActions::userDefinedServices(file, true); + const QList<KServiceAction> serviceActions = KDesktopFileActions::userDefinedServices(file, true); - KDesktopFile desktopFile(file); + const KDesktopFile desktopFile(file); const QString subMenuName = desktopFile.desktopGroup().readEntry("X-KDE-Submenu"); - foreach (const KServiceAction& action, serviceActions) { + for (const KServiceAction &action : serviceActions) { const QString serviceName = action.name(); - const bool addService = !action.noDisplay() - && !action.isSeparator() - && !isInServicesList(serviceName); + const bool addService = !action.noDisplay() && !action.isSeparator() && !isInServicesList(serviceName); if (addService) { const QString itemName = subMenuName.isEmpty() @@ -214,7 +218,7 @@ void ServicesSettingsPage::loadServices() // Load service plugins that implement the KFileItemActionPlugin interface const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("KFileItemAction/Plugin")); - foreach (const KService::Ptr& service, pluginServices) { + for (const KService::Ptr &service : pluginServices) { const QString desktopEntryName = service->desktopEntryName(); if (!isInServicesList(desktopEntryName)) { const bool checked = showGroup.readEntry(desktopEntryName, true); @@ -227,7 +231,7 @@ void ServicesSettingsPage::loadServices() return metaData.serviceTypes().contains(QLatin1String("KFileItemAction/Plugin")); }); - foreach (const auto& jsonMetadata, jsonPlugins) { + for (const auto &jsonMetadata : jsonPlugins) { const QString desktopEntryName = jsonMetadata.pluginId(); if (!isInServicesList(desktopEntryName)) { const bool checked = showGroup.readEntry(desktopEntryName, true); @@ -236,6 +240,7 @@ void ServicesSettingsPage::loadServices() } m_sortModel->sort(Qt::DisplayRole); + m_searchLineEdit->setFocus(Qt::OtherFocusReason); } void ServicesSettingsPage::loadVersionControlSystems() @@ -244,8 +249,8 @@ void ServicesSettingsPage::loadVersionControlSystems() // Create a checkbox for each available version control plugin const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("FileViewVersionControlPlugin")); - for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) { - const QString pluginName = (*it)->name(); + for (const auto &plugin : pluginServices) { + const QString pluginName = plugin->name(); addRow(QStringLiteral("code-class"), pluginName, VersionControlServicePrefix + pluginName, @@ -255,7 +260,7 @@ void ServicesSettingsPage::loadVersionControlSystems() m_sortModel->sort(Qt::DisplayRole); } -bool ServicesSettingsPage::isInServicesList(const QString& service) const +bool ServicesSettingsPage::isInServicesList(const QString &service) const { for (int i = 0; i < m_serviceModel->rowCount(); ++i) { const QModelIndex index = m_serviceModel->index(i, 0); @@ -266,9 +271,9 @@ bool ServicesSettingsPage::isInServicesList(const QString& service) const return false; } -void ServicesSettingsPage::addRow(const QString& icon, - const QString& text, - const QString& value, +void ServicesSettingsPage::addRow(const QString &icon, + const QString &text, + const QString &value, bool checked) { m_serviceModel->insertRow(0); diff --git a/src/settings/services/servicessettingspage.h b/src/settings/services/servicessettingspage.h index cd4cbe52f..8f507407b 100644 --- a/src/settings/services/servicessettingspage.h +++ b/src/settings/services/servicessettingspage.h @@ -26,6 +26,7 @@ class QListView; class QSortFilterProxyModel; class ServiceModel; +class QLineEdit; /** * @brief Page for the 'Services' settings of the Dolphin settings dialog. @@ -59,21 +60,22 @@ private: */ void loadVersionControlSystems(); - bool isInServicesList(const QString& service) const; + bool isInServicesList(const QString &service) const; /** * Adds a row to the model of m_listView. */ - void addRow(const QString& icon, - const QString& text, - const QString& value, + void addRow(const QString &icon, + const QString &text, + const QString &value, bool checked); private: bool m_initialized; - ServiceModel* m_serviceModel; - QSortFilterProxyModel* m_sortModel; + ServiceModel *m_serviceModel; + QSortFilterProxyModel *m_sortModel; QListView* m_listView; + QLineEdit *m_searchLineEdit; QStringList m_enabledVcsPlugins; }; diff --git a/src/settings/startup/startupsettingspage.cpp b/src/settings/startup/startupsettingspage.cpp index d7d5fba4c..eb1495746 100644 --- a/src/settings/startup/startupsettingspage.cpp +++ b/src/settings/startup/startupsettingspage.cpp @@ -27,18 +27,24 @@ #include <KLocalizedString> #include <KMessageBox> +#include <QButtonGroup> #include <QCheckBox> #include <QFileDialog> #include <QLineEdit> #include <QPushButton> +#include <QRadioButton> #include <QFormLayout> +#include <QGridLayout> #include <QHBoxLayout> -#include <QVBoxLayout> 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,19 @@ StartupSettingsPage::StartupSettingsPage(const QUrl& url, QWidget* parent) : { QFormLayout* topLayout = new QFormLayout(this); + m_rememberOpenedTabsRadioButton = new QRadioButton(i18nc("@option:radio Startup Settings", "Folders, tabs, and window state from last time")); + m_homeUrlRadioButton = new QRadioButton(); + // HACK: otherwise the radio button has too much spacing in a grid layout + m_homeUrlRadioButton->setMaximumWidth(24); + + 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(this); + QHBoxLayout* homeUrlBoxLayout = new QHBoxLayout(m_homeUrlBoxLayoutContainer); homeUrlBoxLayout->setContentsMargins(0, 0, 0, 0); m_homeUrl = new QLineEdit(); @@ -67,7 +83,8 @@ StartupSettingsPage::StartupSettingsPage(const QUrl& url, QWidget* parent) : connect(selectHomeUrlButton, &QPushButton::clicked, this, &StartupSettingsPage::selectHomeUrl); - QHBoxLayout* buttonBoxLayout = new QHBoxLayout(); + m_buttonBoxLayoutContainer = new QWidget(this); + QHBoxLayout* buttonBoxLayout = new QHBoxLayout(m_buttonBoxLayoutContainer); buttonBoxLayout->setContentsMargins(0, 0, 0, 0); QPushButton* useCurrentButton = new QPushButton(i18nc("@action:button", "Use Current Location")); @@ -79,41 +96,50 @@ StartupSettingsPage::StartupSettingsPage(const QUrl& url, QWidget* parent) : 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->setHorizontalSpacing(0); + 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 +158,21 @@ void StartupSettingsPage::applySettings() 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 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 +190,18 @@ void StartupSettingsPage::slotSettingsChanged() // 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 +226,8 @@ void StartupSettingsPage::loadSettings() { 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()); diff --git a/src/settings/startup/startupsettingspage.h b/src/settings/startup/startupsettingspage.h index a5e0b236f..d1c937f1f 100644 --- a/src/settings/startup/startupsettingspage.h +++ b/src/settings/startup/startupsettingspage.h @@ -23,8 +23,9 @@ #include <QUrl> -class QLineEdit; class QCheckBox; +class QLineEdit; +class QRadioButton; /** * @brief Page for the 'Startup' settings of the Dolphin settings dialog. @@ -48,6 +49,7 @@ public: private slots: void slotSettingsChanged(); + void updateInitialViewOptions(); void selectHomeUrl(); void useCurrentLocation(); void useDefaultLocation(); @@ -58,6 +60,10 @@ private: 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/viewmodes/viewsettingstab.cpp b/src/settings/viewmodes/viewsettingstab.cpp index 06b0b8cf5..3e3f96ffc 100644 --- a/src/settings/viewmodes/viewsettingstab.cpp +++ b/src/settings/viewmodes/viewsettingstab.cpp @@ -33,6 +33,10 @@ #include <QComboBox> #include <QHelpEvent> #include <QFormLayout> +#include <QSpinBox> +#include <QRadioButton> +#include <QButtonGroup> +#include <QLabel> ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) : QWidget(parent), @@ -42,11 +46,11 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) : m_fontRequester(nullptr), m_widthBox(nullptr), m_maxLinesBox(nullptr), - m_expandableFolders(nullptr) + m_expandableFolders(nullptr), + m_recursiveDirectorySizeLimit(nullptr) { QFormLayout* topLayout = new QFormLayout(this); - // Create "Icon Size" section const int minRange = ZoomLevelInfo::minimumLevel(); const int maxRange = ZoomLevelInfo::maximumLevel(); @@ -75,7 +79,6 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) : m_fontRequester = new DolphinFontRequester(this); topLayout->addRow(i18nc("@label:listbox", "Label font:"), m_fontRequester); - switch (m_mode) { case IconsMode: { m_widthBox = new QComboBox(); @@ -107,8 +110,30 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) : case DetailsMode: m_expandableFolders = new QCheckBox(i18nc("@option:check", "Expandable")); topLayout->addRow(i18nc("@label:checkbox", "Folders:"), m_expandableFolders); - break; - default: + +#ifndef Q_OS_WIN + // Sorting properties + m_numberOfItems = new QRadioButton(i18nc("option:radio", "Number of items")); + m_sizeOfContents = new QRadioButton(i18nc("option:radio", "Size of contents, up to ")); + + QButtonGroup* sortingModeGroup = new QButtonGroup(this); + sortingModeGroup->addButton(m_numberOfItems); + sortingModeGroup->addButton(m_sizeOfContents); + + m_recursiveDirectorySizeLimit = new QSpinBox(); + connect(m_recursiveDirectorySizeLimit, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int value) { + m_recursiveDirectorySizeLimit->setSuffix(i18np(" level deep", " levels deep", value)); + }); + m_recursiveDirectorySizeLimit->setRange(1, 20); + m_recursiveDirectorySizeLimit->setSingleStep(1); + + QHBoxLayout *contentsSizeLayout = new QHBoxLayout(); + contentsSizeLayout->addWidget(m_sizeOfContents); + contentsSizeLayout->addWidget(m_recursiveDirectorySizeLimit); + + topLayout->addRow(i18nc("@title:group", "Folder size displays:"), m_numberOfItems); + topLayout->addRow(QString(), contentsSizeLayout); +#endif break; } @@ -128,6 +153,13 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) : break; case DetailsMode: connect(m_expandableFolders, &QCheckBox::toggled, this, &ViewSettingsTab::changed); +#ifndef Q_OS_WIN + connect(m_recursiveDirectorySizeLimit, QOverload<int>::of(&QSpinBox::valueChanged), this, &ViewSettingsTab::changed); + connect(m_numberOfItems, &QRadioButton::toggled, this, &ViewSettingsTab::changed); + connect(m_sizeOfContents, &QRadioButton::toggled, this, [=]() { + m_recursiveDirectorySizeLimit->setEnabled(m_sizeOfContents->isChecked()); + }); +#endif break; default: break; @@ -153,6 +185,10 @@ void ViewSettingsTab::applySettings() break; case DetailsMode: DetailsModeSettings::setExpandableFolders(m_expandableFolders->isChecked()); +#ifndef Q_OS_WIN + DetailsModeSettings::setDirectorySizeCount(m_numberOfItems->isChecked()); + DetailsModeSettings::setRecursiveDirectorySizeLimit(m_recursiveDirectorySizeLimit->value()); +#endif break; default: break; @@ -201,6 +237,14 @@ void ViewSettingsTab::loadSettings() break; case DetailsMode: m_expandableFolders->setChecked(DetailsModeSettings::expandableFolders()); + if (DetailsModeSettings::directorySizeCount()) { + m_numberOfItems->setChecked(true); + m_recursiveDirectorySizeLimit->setEnabled(false); + } else { + m_sizeOfContents->setChecked(true); + m_recursiveDirectorySizeLimit->setEnabled(true); + } + m_recursiveDirectorySizeLimit->setValue(DetailsModeSettings::recursiveDirectorySizeLimit()); break; default: break; diff --git a/src/settings/viewmodes/viewsettingstab.h b/src/settings/viewmodes/viewsettingstab.h index fff882e5e..4d459fca2 100644 --- a/src/settings/viewmodes/viewsettingstab.h +++ b/src/settings/viewmodes/viewsettingstab.h @@ -28,6 +28,8 @@ class DolphinFontRequester; class QComboBox; class QCheckBox; class QSlider; +class QSpinBox; +class QRadioButton; /** * @brief Represents one tab of the view-settings page. @@ -72,6 +74,9 @@ private: QComboBox* m_widthBox; QComboBox* m_maxLinesBox; QCheckBox* m_expandableFolders; + QRadioButton* m_numberOfItems; + QRadioButton* m_sizeOfContents; + QSpinBox* m_recursiveDirectorySizeLimit; }; #endif |
