diff --git a/kcms/componentchooser/CMakeLists.txt b/kcms/componentchooser/CMakeLists.txt index 822df8794..15c93cbc9 100644 --- a/kcms/componentchooser/CMakeLists.txt +++ b/kcms/componentchooser/CMakeLists.txt @@ -1,49 +1,51 @@ # KI18N Translation Domain for this library add_definitions(-DTRANSLATION_DOMAIN=\"kcm5_componentchooser\") add_subdirectory( componentservices ) ########### next target ############### set(kcm_componentchooser_SRCS componentchooser.cpp componentchooserbrowser.cpp componentchooserfilemanager.cpp componentchooseremail.cpp componentchooserterminal.cpp kcm_componentchooser.cpp ) +kconfig_add_kcfg_files(kcm_componentchooser_SRCS browser_settings.kcfgc GENERATE_MOC) ki18n_wrap_ui(kcm_componentchooser_SRCS browserconfig_ui.ui filemanagerconfig_ui.ui emailclientconfig_ui.ui componentchooser_ui.ui componentconfig_ui.ui terminalemulatorconfig_ui.ui ) add_library(kcm_componentchooser MODULE ${kcm_componentchooser_SRCS}) target_link_libraries(kcm_componentchooser KF5::I18n KF5::Completion KF5::ConfigWidgets KF5::Service KF5::KIOWidgets KF5::KDELibs4Support Qt5::DBus Qt5::X11Extras ) install(TARGETS kcm_componentchooser DESTINATION ${KDE_INSTALL_PLUGINDIR} ) ########### install files ############### install( FILES componentchooser.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install(FILES browser_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) diff --git a/kcms/componentchooser/browser_settings.kcfg b/kcms/componentchooser/browser_settings.kcfg new file mode 100644 index 000000000..7fd4fce83 --- /dev/null +++ b/kcms/componentchooser/browser_settings.kcfg @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/kcms/componentchooser/browser_settings.kcfgc b/kcms/componentchooser/browser_settings.kcfgc new file mode 100644 index 000000000..f3a5b81a3 --- /dev/null +++ b/kcms/componentchooser/browser_settings.kcfgc @@ -0,0 +1,5 @@ +File=browser_settings.kcfg +ClassName=BrowserSettings +Mutators=true +DefaultValueGetters=true +GenerateProperties=true diff --git a/kcms/componentchooser/componentchooser.cpp b/kcms/componentchooser/componentchooser.cpp index ada5da6da..ea5921b5f 100644 --- a/kcms/componentchooser/componentchooser.cpp +++ b/kcms/componentchooser/componentchooser.cpp @@ -1,263 +1,273 @@ /*************************************************************************** componentchooser.cpp - description ------------------- copyright : (C) 2002 by Joseph Wenninger email : jowenn@kde.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License verstion 2 as * * published by the Free Software Foundation * * * ***************************************************************************/ #include "componentchooser.h" #include "componentchooserbrowser.h" #include "componentchooseremail.h" #include "componentchooserfilemanager.h" #ifdef Q_OS_UNIX #include "componentchooserterminal.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include //BEGIN General kpart based Component selection CfgComponent::CfgComponent(QWidget *parent) : QWidget(parent), Ui::ComponentConfig_UI(), CfgPlugin() { setupUi( this ); connect(ComponentSelector,SIGNAL(activated(const QString&)),this,SLOT(slotComponentChanged(const QString&))); } CfgComponent::~CfgComponent() { } void CfgComponent::slotComponentChanged(const QString&) { emit changed(true); } void CfgComponent::save(KConfig *cfg) { // yes, this can happen if there are NO KTrader offers for this component if (!m_lookupDict.contains(ComponentSelector->currentText())) return; KConfigGroup mainGroup = cfg->group(QByteArray()); QString serviceTypeToConfigure=mainGroup.readEntry("ServiceTypeToConfigure"); KConfig store(mainGroup.readPathEntry("storeInFile", QStringLiteral("null"))); KConfigGroup cg(&store, mainGroup.readEntry("valueSection")); cg.writePathEntry(mainGroup.readEntry("valueName", "kcm_componenchooser_null"), m_lookupDict.value(ComponentSelector->currentText())); store.sync(); emit changed(false); } void CfgComponent::load(KConfig *cfg) { ComponentSelector->clear(); m_lookupDict.clear(); m_revLookupDict.clear(); const KConfigGroup mainGroup = cfg->group(QByteArray()); const QString serviceTypeToConfigure = mainGroup.readEntry("ServiceTypeToConfigure"); const KService::List offers = KServiceTypeTrader::self()->query(serviceTypeToConfigure); for (const auto &service: offers) { ComponentSelector->addItem(service->name()); m_lookupDict.insert(service->name(), service->desktopEntryName()); m_revLookupDict.insert(service->desktopEntryName(), service->name()); } KConfig store(mainGroup.readPathEntry("storeInFile",QStringLiteral("null"))); const KConfigGroup group(&store, mainGroup.readEntry("valueSection")); QString setting = group.readEntry(mainGroup.readEntry("valueName","kcm_componenchooser_null"), QString()); if (setting.isEmpty()) setting = mainGroup.readEntry("defaultImplementation", QString()); QString tmp = m_revLookupDict.value(setting); if (!tmp.isEmpty()) { for (int i=0;icount();i++) if (tmp==ComponentSelector->itemText(i)) { ComponentSelector->setCurrentIndex(i); break; } } emit changed(false); } void CfgComponent::defaults() { //todo } +bool CfgComponent::isDefaults() const +{ + return false; +} + //END General kpart based Component selection ComponentChooser::ComponentChooser(QWidget *parent): QWidget(parent), Ui::ComponentChooser_UI(), somethingChanged(false), configWidget(nullptr) { setupUi(this); static_cast(layout())->setRowStretch(1, 1); const QStringList directories = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("kcm_componentchooser"), QStandardPaths::LocateDirectory); QStringList services; for(const QString &directory : directories) { const QDir dir(directory); for(const QString &f: dir.entryList(QStringList("*.desktop"))) { services += dir.absoluteFilePath(f); } } for (const QString &service : qAsConst(services)) { KConfig cfg(service, KConfig::SimpleConfig); KConfigGroup cg = cfg.group(QByteArray()); QListWidgetItem *item = new QListWidgetItem( QIcon::fromTheme(cg.readEntry("Icon",QStringLiteral("preferences-desktop-default-applications"))), cg.readEntry("Name",i18n("Unknown"))); item->setData(Qt::UserRole, service); ServiceChooser->addItem(item); loadConfigWidget(service, cfg.group(QByteArray()).readEntry("configurationType"), item->text()); } ServiceChooser->setFixedWidth(ServiceChooser->sizeHintForColumn(0) + 20); ServiceChooser->sortItems(); connect(ServiceChooser,&QListWidget::currentItemChanged,this,&ComponentChooser::slotServiceSelected); ServiceChooser->setCurrentRow(0); } void ComponentChooser::loadConfigWidget(const QString &service, const QString &cfgType, const QString &name) { QWidget *loadedConfigWidget = nullptr; if (cfgType.isEmpty() || (cfgType == QLatin1String("component"))) { loadedConfigWidget = new CfgComponent(configContainer); static_cast(loadedConfigWidget)->ChooserDocu->setText(i18n("Choose from the list below which component should be used by default for the %1 service.", name)); } else if (cfgType==QLatin1String("internal_email")) { loadedConfigWidget = new CfgEmailClient(configContainer); } #ifdef Q_OS_UNIX else if (cfgType==QLatin1String("internal_terminal")) { loadedConfigWidget = new CfgTerminalEmulator(configContainer); } #endif else if (cfgType==QLatin1String("internal_filemanager")) { loadedConfigWidget = new CfgFileManager(configContainer); } else if (cfgType==QLatin1String("internal_browser")) { loadedConfigWidget = new CfgBrowser(configContainer); } if (loadedConfigWidget) { configWidgetMap.insert(service, loadedConfigWidget); configContainer->addWidget(loadedConfigWidget); connect(loadedConfigWidget, SIGNAL(changed(bool)), this, SLOT(emitChanged(bool))); } } void ComponentChooser::slotServiceSelected(QListWidgetItem* it) { if (!it) return; if (somethingChanged) { if (KMessageBox::questionYesNo(this,i18n("You changed the default component of your choice, do want to save that change now ?"),QString(),KStandardGuiItem::save(),KStandardGuiItem::discard())==KMessageBox::Yes) save(); } const QString &service = it->data(Qt::UserRole).toString(); KConfig cfg(service, KConfig::SimpleConfig); ComponentDescription->setText(cfg.group(QByteArray()).readEntry("Comment",i18n("No description available"))); ComponentDescription->setMinimumSize(ComponentDescription->sizeHint()); configWidget = configWidgetMap.value(service); if (configWidget) { - configContainer->setCurrentWidget(configWidget); - dynamic_cast(configWidget)->load(&cfg); + configContainer->setCurrentWidget(configWidget); + const auto plugin = dynamic_cast(configWidget); + plugin->load(&cfg); + emit defaulted(plugin->isDefaults()); } emitChanged(false); latestEditedService = service; } void ComponentChooser::emitChanged(bool val) { somethingChanged=val; emit changed(val); + + CfgPlugin *plugin = dynamic_cast( configWidget ); + emit defaulted(plugin->isDefaults()); } ComponentChooser::~ComponentChooser() { for (QWidget *configWidget : configWidgetMap) { delete configWidget; } } void ComponentChooser::load() { if( configWidget ) { CfgPlugin * plugin = dynamic_cast( configWidget ); if( plugin ) { KConfig cfg(latestEditedService, KConfig::SimpleConfig); plugin->load( &cfg ); } } } void ComponentChooser::save() { if( configWidget ) { CfgPlugin* plugin = dynamic_cast( configWidget ); if( plugin ) { KConfig cfg(latestEditedService, KConfig::SimpleConfig); plugin->save( &cfg ); } } } void ComponentChooser::restoreDefault() { if (configWidget) { dynamic_cast(configWidget)->defaults(); emitChanged(true); } /* txtEMailClient->setText("kmail"); chkRunTerminal->setChecked(false); // Check if -e is needed, I do not think so terminalLE->setText("xterm"); //No need for i18n terminalCB->setChecked(true); emitChanged(false); */ } // vim: sw=4 ts=4 noet diff --git a/kcms/componentchooser/componentchooser.h b/kcms/componentchooser/componentchooser.h index 88366c993..66c4be01d 100644 --- a/kcms/componentchooser/componentchooser.h +++ b/kcms/componentchooser/componentchooser.h @@ -1,94 +1,98 @@ /*************************************************************************** componentchooser.h - description ------------------- copyright : (C) 2002 by Joseph Wenninger email : jowenn@kde.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundationi * * * ***************************************************************************/ #ifndef _COMPONENTCHOOSER_H_ #define _COMPONENTCHOOSER_H_ #include "ui_componentchooser_ui.h" #include "ui_componentconfig_ui.h" #include #include #include class QListWidgetItem; class KConfig; /* The CfgPlugin class is an exception. It is LGPL. It will be parted of the plugin interface which I plan for KDE 3.2. */ class CfgPlugin { public: CfgPlugin(){} virtual ~CfgPlugin(){} virtual void load(KConfig *cfg)=0; virtual void save(KConfig *cfg)=0; virtual void defaults()=0; + virtual bool isDefaults() const=0; }; class CfgComponent: public QWidget, public Ui::ComponentConfig_UI, public CfgPlugin { Q_OBJECT public: CfgComponent(QWidget *parent); ~CfgComponent() override; void load(KConfig *cfg) override; void save(KConfig *cfg) override; void defaults() override; + bool isDefaults() const override; protected: QHash m_lookupDict,m_revLookupDict; protected Q_SLOTS: void slotComponentChanged(const QString&); Q_SIGNALS: void changed(bool); + void defaulted(bool); }; class ComponentChooser : public QWidget, public Ui::ComponentChooser_UI { Q_OBJECT public: ComponentChooser(QWidget *parent=nullptr); ~ComponentChooser() override; void load(); void save(); void restoreDefault(); private: QString latestEditedService; bool somethingChanged; QWidget *configWidget; QVBoxLayout *myLayout; QMap configWidgetMap; void loadConfigWidget(const QString &, const QString &, const QString &); protected Q_SLOTS: void emitChanged(bool); void slotServiceSelected(QListWidgetItem *); Q_SIGNALS: void changed(bool); + void defaulted(bool); }; #endif diff --git a/kcms/componentchooser/componentchooserbrowser.cpp b/kcms/componentchooser/componentchooserbrowser.cpp index ecfd5063b..cd61eeefb 100644 --- a/kcms/componentchooser/componentchooserbrowser.cpp +++ b/kcms/componentchooser/componentchooserbrowser.cpp @@ -1,175 +1,195 @@ /*************************************************************************** componentchooserbrowser.cpp ------------------- copyright : (C) 2002 by Joseph Wenninger email : jowenn@kde.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundationi * * * ***************************************************************************/ #include "componentchooserbrowser.h" #include -#include +#include "browser_settings.h" #include #include #include #include "../migrationlib/kdelibs4config.h" #include #include #include CfgBrowser::CfgBrowser(QWidget *parent) : QWidget(parent), Ui::BrowserConfig_UI(),CfgPlugin() { setupUi(this); connect(lineExec, &KLineEdit::textChanged, this, &CfgBrowser::configChanged); connect(radioKIO, &QRadioButton::toggled, this, &CfgBrowser::configChanged); connect(radioService, &QRadioButton::toggled, this, &CfgBrowser::selectBrowserApp); connect(browserCombo, static_cast(&QComboBox::activated), this, &CfgBrowser::selectBrowserApp); connect(radioExec, &QRadioButton::toggled, this, &CfgBrowser::configChanged); connect(btnSelectApplication, &QToolButton::clicked, this, &CfgBrowser::selectBrowser); } CfgBrowser::~CfgBrowser() { } void CfgBrowser::selectBrowserApp() { const QString &storageId = browserCombo->currentData().toString(); m_browserService = KService::serviceByStorageId(storageId); m_browserExec.clear(); configChanged(); } void CfgBrowser::configChanged() { - emit changed(true); + bool hasChanged = false; + const BrowserSettings settings; + const QString exec = settings.browserApplication(); + + if (exec.isEmpty()) { + hasChanged |= !radioKIO->isChecked(); + } else { + if (exec.startsWith('!')) { + hasChanged |= lineExec->text() != exec; + } else { + hasChanged |= KService::serviceByStorageId(lineExec->text()) != KService::serviceByStorageId( exec ); + } + } + + emit changed(hasChanged); } void CfgBrowser::defaults() { - load(nullptr); + emit changed(!radioKIO->isChecked()); + radioKIO->setChecked(true); +} + +bool CfgBrowser::isDefaults() const +{ + return radioKIO->isChecked(); } void CfgBrowser::load(KConfig *) { - const KConfigGroup config(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), QStringLiteral("General") ); - const QString exec = config.readPathEntry( QStringLiteral("BrowserApplication"), QString() ); + const BrowserSettings settings; + const QString exec = settings.browserApplication(); if (exec.isEmpty()) { radioKIO->setChecked(true); m_browserExec = exec; m_browserService = nullptr; } else { radioExec->setChecked(true); if (exec.startsWith('!')) { m_browserExec = exec.mid(1); m_browserService = nullptr; } else { m_browserService = KService::serviceByStorageId( exec ); if (m_browserService) { m_browserExec = m_browserService->desktopEntryName(); } else { m_browserExec.clear(); } } } lineExec->setText(m_browserExec); browserCombo->clear(); - const auto &browsers = KServiceTypeTrader::self()->query(QStringLiteral("Application"), - QStringLiteral("'WebBrowser' in Categories")); + const auto constraint = QStringLiteral("'WebBrowser' in Categories and" + " ('x-scheme-handler/http' in ServiceTypes or 'x-scheme-handler/https' in ServiceTypes)"); + const auto browsers = KServiceTypeTrader::self()->query(QStringLiteral("Application"), constraint); for (const auto &service : browsers) { browserCombo->addItem(QIcon::fromTheme(service->icon()), service->name(), service->storageId()); if ((m_browserService && m_browserService->storageId() == service->storageId()) || service->exec() == m_browserExec) { browserCombo->setCurrentIndex(browserCombo->count() - 1); radioService->setChecked(true); } } emit changed(false); } void CfgBrowser::save(KConfig *) { - KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("kdeglobals")); - KConfigGroup config(profile, QStringLiteral("General")); + BrowserSettings settings; QString exec; if (radioService->isChecked()) { if (m_browserService) { exec = m_browserService->storageId(); } } else if (radioExec->isChecked()) { exec = lineExec->text(); if (m_browserService && (exec == m_browserExec)) { exec = m_browserService->storageId(); // Use service } else if (!exec.isEmpty()) { exec = '!' + exec; // Literal command } } - config.writePathEntry( QStringLiteral("BrowserApplication"), exec); // KConfig::Normal|KConfig::Global - config.sync(); + settings.setBrowserApplication(exec); + settings.save(); // Save the default browser as scheme handler for http(s) in mimeapps.list KSharedConfig::Ptr mimeAppList = KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::GenericConfigLocation); if (mimeAppList->isConfigWritable(true /*warn user if not writable*/)) { KConfigGroup defaultApp(mimeAppList, "Default Applications"); if (m_browserService) { defaultApp.writeXdgListEntry(QStringLiteral("x-scheme-handler/http"), QStringList(m_browserService->storageId())); defaultApp.writeXdgListEntry(QStringLiteral("x-scheme-handler/https"), QStringList(m_browserService->storageId())); } else { defaultApp.deleteEntry(QStringLiteral("x-scheme-handler/http")); defaultApp.deleteEntry(QStringLiteral("x-scheme-handler/https")); } mimeAppList->sync(); KBuildSycocaProgressDialog::rebuildKSycoca(this); } Kdelibs4SharedConfig::syncConfigGroup(QLatin1String("General"), "kdeglobals"); QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.klauncher5"), QStringLiteral("/KLauncher"), QStringLiteral("org.kde.KLauncher"), QStringLiteral("reparseConfiguration")); QDBusConnection::sessionBus().send(message); emit changed(false); } void CfgBrowser::selectBrowser() { QList urlList; KOpenWithDialog dlg(urlList, i18n("Select preferred Web browser application:"), QString(), this); if (dlg.exec() != QDialog::Accepted) return; m_browserService = dlg.service(); if (m_browserService) { // check if we have listed it in the browser combo, if so, put it there instead const int index = browserCombo->findData(m_browserService->storageId()); if (index > -1) { browserCombo->setCurrentIndex(index); radioService->setChecked(true); } else { m_browserExec = m_browserService->desktopEntryName(); if (m_browserExec.isEmpty()) { m_browserExec = m_browserService->exec(); } } } else { m_browserExec = dlg.text(); } lineExec->setText(m_browserExec); } diff --git a/kcms/componentchooser/componentchooserbrowser.h b/kcms/componentchooser/componentchooserbrowser.h index 1dd212635..f16b2ea9d 100644 --- a/kcms/componentchooser/componentchooserbrowser.h +++ b/kcms/componentchooser/componentchooserbrowser.h @@ -1,45 +1,46 @@ /*************************************************************************** componentchooserbrowser.h ------------------- copyright : (C) 2002 by Joseph Wenninger email : jowenn@kde.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundationi * * * ***************************************************************************/ #ifndef COMPONENTCHOOSERBROWSER_H #define COMPONENTCHOOSERBROWSER_H #include "ui_browserconfig_ui.h" #include "componentchooser.h" class CfgBrowser: public QWidget, public Ui::BrowserConfig_UI, public CfgPlugin { Q_OBJECT public: CfgBrowser(QWidget *parent); ~CfgBrowser() override; void load(KConfig *cfg) override; void save(KConfig *cfg) override; void defaults() override; + bool isDefaults() const override; protected Q_SLOTS: void selectBrowser(); void configChanged(); void selectBrowserApp(); Q_SIGNALS: void changed(bool); private: QString m_browserExec; KService::Ptr m_browserService; }; #endif /* COMPONENTCHOOSERBROWSER_H */ diff --git a/kcms/componentchooser/componentchooseremail.cpp b/kcms/componentchooser/componentchooseremail.cpp index f9bc92b55..eb330b43b 100644 --- a/kcms/componentchooser/componentchooseremail.cpp +++ b/kcms/componentchooser/componentchooseremail.cpp @@ -1,146 +1,151 @@ /*************************************************************************** componentchooseremail.cpp ------------------- copyright : (C) 2002 by Joseph Wenninger email : jowenn@kde.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License verstion 2 as * * published by the Free Software Foundation * * * ***************************************************************************/ #include "componentchooseremail.h" #include #include #include #include #include #include #include #include #include #include #include // for chmod: #include #include #include CfgEmailClient::CfgEmailClient(QWidget *parent) : QWidget(parent), Ui::EmailClientConfig_UI(), CfgPlugin() { setupUi( this ); pSettings = new KEMailSettings(); connect(kmailCB, &QRadioButton::toggled, this, &CfgEmailClient::configChanged); connect(txtEMailClient, &KLineEdit::textChanged, this, &CfgEmailClient::configChanged); #ifdef Q_OS_UNIX connect(chkRunTerminal, &QCheckBox::clicked, this, &CfgEmailClient::configChanged); #else chkRunTerminal->hide(); #endif connect(btnSelectEmail, &QToolButton::clicked, this, &CfgEmailClient::selectEmailClient); } CfgEmailClient::~CfgEmailClient() { delete pSettings; } void CfgEmailClient::defaults() { load(nullptr); } +bool CfgEmailClient::isDefaults() const +{ + return false; +} + void CfgEmailClient::load(KConfig *) { QString emailClient = pSettings->getSetting(KEMailSettings::ClientProgram); bool useKMail = (emailClient.isEmpty()); kmailCB->setChecked(useKMail); otherCB->setChecked(!useKMail); txtEMailClient->setText(emailClient); txtEMailClient->setFixedHeight(txtEMailClient->sizeHint().height()); chkRunTerminal->setChecked((pSettings->getSetting(KEMailSettings::ClientTerminal) == QLatin1String("true"))); emit changed(false); } void CfgEmailClient::configChanged() { emit changed(true); } void CfgEmailClient::selectEmailClient() { QList urlList; KOpenWithDialog dlg(urlList, i18n("Select preferred email client:"), QString(), this); // hide "Do not &close when command exits" here, we don't need it for a mail client dlg.hideNoCloseOnExit(); if (dlg.exec() != QDialog::Accepted) return; QString client = dlg.text(); m_emailClientService = dlg.service(); // get the preferred Terminal Application KConfigGroup confGroup( KSharedConfig::openConfig(), QStringLiteral("General") ); QString preferredTerminal = confGroup.readPathEntry("TerminalApplication", QStringLiteral("konsole")); preferredTerminal += QLatin1String(" -e "); int len = preferredTerminal.length(); bool b = client.left(len) == preferredTerminal; if (b) client = client.mid(len); if (!client.isEmpty()) { chkRunTerminal->setChecked(b); txtEMailClient->setText(client); } } void CfgEmailClient::save(KConfig *) { if (kmailCB->isChecked()) { pSettings->setSetting(KEMailSettings::ClientProgram, QString()); pSettings->setSetting(KEMailSettings::ClientTerminal, QStringLiteral("false")); } else { pSettings->setSetting(KEMailSettings::ClientProgram, txtEMailClient->text()); pSettings->setSetting(KEMailSettings::ClientTerminal, (chkRunTerminal->isChecked()) ? "true" : "false"); } // Save the default email client in mimeapps.list into the group [Default Applications] KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::GenericConfigLocation); if (profile->isConfigWritable(true)) { KConfigGroup defaultApp(profile, "Default Applications"); if (kmailCB->isChecked()) { QString kmailDesktop = QStringLiteral("org.kde.kmail.desktop"); if (KService::serviceByDesktopName(QStringLiteral("org.kde.kmail2"))) { kmailDesktop = QStringLiteral("org.kde.kmail2.desktop"); } defaultApp.writeXdgListEntry("x-scheme-handler/mailto", QStringList(kmailDesktop)); } else if (m_emailClientService) { defaultApp.writeXdgListEntry("x-scheme-handler/mailto", QStringList(m_emailClientService->storageId())); } profile->sync(); } // insure proper permissions -- contains sensitive data QString cfgName(QStandardPaths::locate(QStandardPaths::ConfigLocation, QStringLiteral("emails"))); if (!cfgName.isEmpty()) ::chmod(QFile::encodeName(cfgName), 0600); QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/Component"), QStringLiteral("org.kde.Kcontrol"), QStringLiteral("KDE_emailSettingsChanged") ); QDBusConnection::sessionBus().send(message); emit changed(false); } diff --git a/kcms/componentchooser/componentchooseremail.h b/kcms/componentchooser/componentchooseremail.h index 75f7337c8..7fc5a04fc 100644 --- a/kcms/componentchooser/componentchooseremail.h +++ b/kcms/componentchooser/componentchooseremail.h @@ -1,45 +1,46 @@ /*************************************************************************** componentchooseremail.h ------------------- copyright : (C) 2002 by Joseph Wenninger email : jowenn@kde.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundationi * * * ***************************************************************************/ #ifndef COMPONENTCHOOSEREMAIL_H #define COMPONENTCHOOSEREMAIL_H class KEMailSettings; #include "ui_emailclientconfig_ui.h" #include "componentchooser.h" class CfgEmailClient: public QWidget, public Ui::EmailClientConfig_UI, public CfgPlugin { Q_OBJECT public: CfgEmailClient(QWidget *parent); ~CfgEmailClient() override; void load(KConfig *cfg) override; void save(KConfig *cfg) override; void defaults() override; + bool isDefaults() const override; private: KEMailSettings *pSettings; KService::Ptr m_emailClientService; protected Q_SLOTS: void selectEmailClient(); void configChanged(); Q_SIGNALS: void changed(bool); }; #endif diff --git a/kcms/componentchooser/componentchooserfilemanager.cpp b/kcms/componentchooser/componentchooserfilemanager.cpp index 0a9f39031..a80bbf6e6 100644 --- a/kcms/componentchooser/componentchooserfilemanager.cpp +++ b/kcms/componentchooser/componentchooserfilemanager.cpp @@ -1,142 +1,147 @@ /* This file is part of the KDE project Copyright (C) 2008 David Faure This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "componentchooserfilemanager.h" #include #include #include #include #include #include #include #include #include "../migrationlib/kdelibs4config.h" CfgFileManager::CfgFileManager(QWidget *parent) : QWidget(parent), Ui::FileManagerConfig_UI(),CfgPlugin() { setupUi(this); connect(btnSelectFileManager, &QToolButton::clicked, this, &CfgFileManager::slotAddFileManager); } CfgFileManager::~CfgFileManager() { } void CfgFileManager::configChanged() { emit changed(true); } void CfgFileManager::defaults() { load(nullptr); } +bool CfgFileManager::isDefaults() const +{ + return false; +} + static KService::List appOffers() { return KMimeTypeTrader::self()->query(QStringLiteral("inode/directory"), QStringLiteral("Application")); } void CfgFileManager::load(KConfig *) { qDeleteAll(mDynamicWidgets); mDynamicWidgets.clear(); const KService::List apps = appOffers(); bool first = true; Q_FOREACH(const KService::Ptr& service, apps) { QRadioButton* button = new QRadioButton(service->name(), this); connect(button, &QRadioButton::toggled, this, &CfgFileManager::configChanged); button->setProperty("storageId", service->storageId()); radioLayout->addWidget(button); if (first) { button->setChecked(true); first = false; } mDynamicWidgets << button; } emit changed(false); } static const char s_DefaultApplications[] = "Default Applications"; static const char s_AddedAssociations[] = "Added Associations"; static const char s_RemovedAssociations[] = "Removed Associations"; void CfgFileManager::save(KConfig *) { QString storageId; Q_FOREACH(QRadioButton* button, qFindChildren(this)) { if (button->isChecked()) { storageId = button->property("storageId").toString(); } } qDebug() << storageId; if (!storageId.isEmpty()) { // This is taken from filetypes/mimetypedata.cpp KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::GenericConfigLocation); if (!profile->isConfigWritable(true)) // warn user if mimeapps.list is root-owned (#155126/#94504) return; const QString mime = QStringLiteral("inode/directory"); KConfigGroup addedApps(profile, s_AddedAssociations); QStringList userApps = addedApps.readXdgListEntry(mime); userApps.removeAll(storageId); // remove if present, to make it first in the list userApps.prepend(storageId); addedApps.writeXdgListEntry(mime, userApps); // Save the default file manager as per mime-apps spec 1.0.1 KConfigGroup defaultApp(profile, s_DefaultApplications); defaultApp.writeXdgListEntry(mime, QStringList(storageId)); Kdelibs4SharedConfig::syncConfigGroup(QLatin1String("Added Associations"), QStringLiteral("mimeapps.list")); profile->sync(); // Clean out any kde-mimeapps.list which would take precedence any cancel our changes. // (also taken from filetypes/mimetypedata.cpp) const QString desktops = QString::fromLocal8Bit(qgetenv("XDG_CURRENT_DESKTOP")); foreach (const QString &desktop, desktops.split(":", QString::SkipEmptyParts)) { const QString file = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + desktop.toLower() + QLatin1String("-mimeapps.list"); if (QFileInfo::exists(file)) { qDebug() << "Cleaning up" << file; KConfig conf(file, KConfig::NoGlobals); KConfigGroup(&conf, s_DefaultApplications).deleteEntry(mime); KConfigGroup(&conf, s_AddedAssociations).deleteEntry(mime); KConfigGroup(&conf, s_RemovedAssociations).deleteEntry(mime); } } KBuildSycocaProgressDialog::rebuildKSycoca(this); } emit changed(false); } void CfgFileManager::slotAddFileManager() { KProcess proc; proc << QStringLiteral("keditfiletype5"); proc << QStringLiteral("inode/directory"); if (proc.execute() == 0) { load(nullptr); } } diff --git a/kcms/componentchooser/componentchooserfilemanager.h b/kcms/componentchooser/componentchooserfilemanager.h index 41374f022..978af3a83 100644 --- a/kcms/componentchooser/componentchooserfilemanager.h +++ b/kcms/componentchooser/componentchooserfilemanager.h @@ -1,48 +1,49 @@ /* This file is part of the KDE project Copyright (C) 2008 David Faure This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef COMPONENTCHOOSERFILEMANAGER_H #define COMPONENTCHOOSERFILEMANAGER_H #include "ui_filemanagerconfig_ui.h" #include "componentchooser.h" class CfgFileManager: public QWidget, public Ui::FileManagerConfig_UI, public CfgPlugin { Q_OBJECT public: CfgFileManager(QWidget *parent); ~CfgFileManager() override; void load(KConfig *cfg) override; void save(KConfig *cfg) override; void defaults() override; + bool isDefaults() const override; protected Q_SLOTS: void slotAddFileManager(); void configChanged(); Q_SIGNALS: void changed(bool); private: QList mDynamicWidgets; }; #endif diff --git a/kcms/componentchooser/componentchooserterminal.cpp b/kcms/componentchooser/componentchooserterminal.cpp index 9a3416678..7d0eaa097 100644 --- a/kcms/componentchooser/componentchooserterminal.cpp +++ b/kcms/componentchooser/componentchooserterminal.cpp @@ -1,110 +1,115 @@ /*************************************************************************** componentchooser.cpp - description ------------------- copyright : (C) 2002 by Joseph Wenninger email : jowenn@kde.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License verstion 2 as * * published by the Free Software Foundation * * * ***************************************************************************/ #include "componentchooserterminal.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "../migrationlib/kdelibs4config.h" CfgTerminalEmulator::CfgTerminalEmulator(QWidget *parent) : QWidget(parent), Ui::TerminalEmulatorConfig_UI(), CfgPlugin() { setupUi(this); connect(terminalLE, &QLineEdit::textChanged, this, &CfgTerminalEmulator::configChanged); connect(terminalCB, &QRadioButton::toggled, this, &CfgTerminalEmulator::configChanged); connect(otherCB, &QRadioButton::toggled, this, &CfgTerminalEmulator::configChanged); connect(btnSelectTerminal, &QToolButton::clicked, this, &CfgTerminalEmulator::selectTerminalApp); } CfgTerminalEmulator::~CfgTerminalEmulator() { } void CfgTerminalEmulator::configChanged() { emit changed(true); } void CfgTerminalEmulator::defaults() { load(nullptr); } +bool CfgTerminalEmulator::isDefaults() const +{ + return false; +} + void CfgTerminalEmulator::load(KConfig *) { KConfigGroup config(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), "General"); QString terminal = config.readPathEntry("TerminalApplication",QStringLiteral("konsole")); if (terminal == QLatin1String("konsole")) { terminalLE->setText(QStringLiteral("xterm")); terminalCB->setChecked(true); } else { terminalLE->setText(terminal); otherCB->setChecked(true); } emit changed(false); } void CfgTerminalEmulator::save(KConfig *) { KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("kdeglobals")); KConfigGroup config(profile, QStringLiteral("General")); const QString terminal = terminalCB->isChecked() ? QStringLiteral("konsole") : terminalLE->text(); config.writePathEntry("TerminalApplication", terminal); // KConfig::Normal|KConfig::Global); config.sync(); Kdelibs4SharedConfig::syncConfigGroup(QLatin1String("General"), "kdeglobals"); QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.klauncher5"), QStringLiteral("/KLauncher"), QStringLiteral("org.kde.KLauncher"), QStringLiteral("reparseConfiguration")); QDBusConnection::sessionBus().send(message); emit changed(false); } void CfgTerminalEmulator::selectTerminalApp() { QList urlList; KOpenWithDialog dlg(urlList, i18n("Select preferred terminal application:"), QString(), this); // hide "Run in &terminal" here, we don't need it for a Terminal Application dlg.hideRunInTerminal(); if (dlg.exec() != QDialog::Accepted) return; QString client = dlg.text(); if (!client.isEmpty()) { terminalLE->setText(client); } } // vim: sw=4 ts=4 noet diff --git a/kcms/componentchooser/componentchooserterminal.h b/kcms/componentchooser/componentchooserterminal.h index 0ec0f9663..8f245be83 100644 --- a/kcms/componentchooser/componentchooserterminal.h +++ b/kcms/componentchooser/componentchooserterminal.h @@ -1,42 +1,43 @@ /*************************************************************************** componentchooserterminal.h - description ------------------- copyright : (C) 2002 by Joseph Wenninger email : jowenn@kde.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundationi * * * ***************************************************************************/ #ifndef _COMPONENTCHOOSERTERMINAL_H_ #define _COMPONENTCHOOSERTERMINAL_H_ #include "ui_terminalemulatorconfig_ui.h" #include "componentchooser.h" class KConfig; class CfgPlugin; class CfgTerminalEmulator: public QWidget, public Ui::TerminalEmulatorConfig_UI, public CfgPlugin { Q_OBJECT public: CfgTerminalEmulator(QWidget *parent); ~CfgTerminalEmulator() override; void load(KConfig *cfg) override; void save(KConfig *cfg) override; void defaults() override; + bool isDefaults() const override; protected Q_SLOTS: void selectTerminalApp(); void configChanged(); Q_SIGNALS: void changed(bool); }; #endif diff --git a/kcms/componentchooser/kcm_componentchooser.cpp b/kcms/componentchooser/kcm_componentchooser.cpp index 4de03d984..530888941 100644 --- a/kcms/componentchooser/kcm_componentchooser.cpp +++ b/kcms/componentchooser/kcm_componentchooser.cpp @@ -1,63 +1,63 @@ /*************************************************************************** kcm_componentchooser.cpp - description ------------------- copyright : (C) 2002 by Joseph Wenninger email : jowenn@kde.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation * * * ***************************************************************************/ #include "kcm_componentchooser.h" #include #include #include #include #include K_PLUGIN_FACTORY(KCMComponentChooserFactory, registerPlugin(); ) KCMComponentChooser::KCMComponentChooser(QWidget *parent, const QVariantList &): KCModule(parent) { QVBoxLayout *lay = new QVBoxLayout(this); lay->setContentsMargins(0, 0, 0, 0); m_chooser=new ComponentChooser(this); lay->addWidget(m_chooser); connect(m_chooser,SIGNAL(changed(bool)),this,SIGNAL(changed(bool))); - setButtons( Default|Apply|Help ); + connect(m_chooser, &ComponentChooser::defaulted, this, &KCModule::defaulted); KAboutData *about = new KAboutData( QStringLiteral("kcmcomponentchooser"), i18n("Component Chooser"), QStringLiteral("1.0"), QString(), KAboutLicense::GPL, i18n("(c), 2002 Joseph Wenninger")); about->addAuthor(i18n("Joseph Wenninger"), QString() , QStringLiteral("jowenn@kde.org")); setAboutData( about ); } void KCMComponentChooser::load(){ m_chooser->load(); } void KCMComponentChooser::save(){ m_chooser->save(); } void KCMComponentChooser::defaults(){ m_chooser->restoreDefault(); } #include "kcm_componentchooser.moc"