diff --git a/CMakeLists.txt b/CMakeLists.txt index fbc96dfd..21710020 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,96 +1,96 @@ cmake_minimum_required(VERSION 3.5) set(KDEPIM_VERSION_NUMBER "5.11.40") project(akregator VERSION ${KDEPIM_VERSION_NUMBER}) set(KF5_MIN_VERSION "5.57.0") find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) include(ECMInstallIcons) include(ECMSetupVersion) include(ECMAddTests) include(GenerateExportHeader) include(ECMGenerateHeaders) include(FeatureSummary) include(CheckFunctionExists) include(ECMGeneratePriFile) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMAddAppIcon) include(ECMQtDeclareLoggingCategory) # Do NOT add quote set(KDEPIM_DEV_VERSION alpha) # add an extra space if(DEFINED KDEPIM_DEV_VERSION) set(KDEPIM_DEV_VERSION " ${KDEPIM_DEV_VERSION}") endif() set(KDEPIM_VERSION "${KDEPIM_VERSION_NUMBER}${KDEPIM_DEV_VERSION}") set(KDEPIM_LIB_VERSION "${KDEPIM_VERSION_NUMBER}") set(KDEPIM_LIB_SOVERSION "5") set(QT_REQUIRED_VERSION "5.10.0") set(KONTACTINTERFACE_LIB_VERSION "5.11.40") set(KPIMTEXTEDIT_LIB_VERSION "5.11.40") set(LIBGRANTLEETHEME_LIB_VERSION_LIB "5.11.40") set(LIBKDEPIM_LIB_VERSION_LIB "5.11.40") set(LIBKLEO_LIB_VERSION_LIB "5.11.40") set(MESSAGELIB_LIB_VERSION_LIB "5.11.40") set(PIMCOMMON_LIB_VERSION_LIB "5.11.40") find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets Test WebEngine WebEngineWidgets PrintSupport) find_package(Grantlee5 "5.1" CONFIG REQUIRED) # Find KF5 package find_package(KF5Crash ${KF5_MIN_VERSION} REQUIRED) find_package(KF5DocTools ${KF5_MIN_VERSION} REQUIRED) find_package(KF5KCMUtils ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5NotifyConfig ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Parts ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5TextEditor ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5XmlGui ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5IconThemes ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Notifications ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Syndication ${KF5_MIN_VERSION} CONFIG REQUIRED) # Find KdepimLibs Package find_package(KF5GrantleeTheme ${LIBGRANTLEETHEME_LIB_VERSION_LIB} CONFIG REQUIRED) find_package(KF5KontactInterface ${KONTACTINTERFACE_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Libkdepim ${LIBKDEPIM_LIB_VERSION_LIB} CONFIG REQUIRED) find_package(KF5Libkleo ${LIBKLEO_LIB_VERSION_LIB} CONFIG REQUIRED) find_package(KF5MessageViewer ${MESSAGELIB_LIB_VERSION_LIB} CONFIG REQUIRED) find_package(KF5PimTextEdit ${KPIMTEXTEDIT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5WebEngineViewer ${MESSAGELIB_LIB_VERSION_LIB} CONFIG REQUIRED) # Fix plugin support for removing theses dependancies find_package(KF5AkonadiMime ${AKONADI_MIMELIB_VERSION} CONFIG REQUIRED) find_package(KF5PimCommonAkonadi ${PIMCOMMON_LIB_VERSION_LIB} CONFIG REQUIRED) include_directories(${akregator_SOURCE_DIR} ${akregator_BINARY_DIR}) add_definitions(-DTRANSLATION_DOMAIN=\"akregator\") - +set(CMAKE_CXX_STANDARD 14) #add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) add_subdirectory(export) add_subdirectory(interfaces) add_subdirectory(plugins) add_subdirectory(configuration) add_subdirectory(src) add_subdirectory(kontactplugin) add_subdirectory(kconf_update) install(FILES akregator.renamecategories akregator.categories DESTINATION ${KDE_INSTALL_CONFDIR}) add_subdirectory(doc) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/configuration/akregator_config_appearance.cpp b/configuration/akregator_config_appearance.cpp index bb7724cc..15fb3461 100644 --- a/configuration/akregator_config_appearance.cpp +++ b/configuration/akregator_config_appearance.cpp @@ -1,77 +1,77 @@ /* This file is part of Akregator. Copyright (c) 2008 Frank Osterfeld 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) 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; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "akregator_config_appearance.h" #include "akregatorconfig.h" #include #include #include #include #include using namespace Akregator; K_PLUGIN_CLASS_WITH_JSON(KCMAkregatorAppearanceConfig, "akregator_config_appearance.json") KCMAkregatorAppearanceConfig::KCMAkregatorAppearanceConfig(QWidget *parent, const QVariantList &args) : KCModule(parent, args) , m_widget(new QWidget) { m_ui.setupUi(m_widget); QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(m_widget); connect(m_ui.kcfg_UseCustomColors, &QAbstractButton::toggled, m_ui.kcfg_ColorUnreadArticles, &QWidget::setEnabled); connect(m_ui.kcfg_UseCustomColors, &QAbstractButton::toggled, m_ui.kcfg_ColorNewArticles, &QWidget::setEnabled); connect(m_ui.kcfg_UseCustomColors, &QAbstractButton::toggled, m_ui.lbl_newArticles, &QWidget::setEnabled); connect(m_ui.kcfg_UseCustomColors, &QAbstractButton::toggled, m_ui.lbl_unreadArticles, &QWidget::setEnabled); connect(m_ui.slider_minimumFontSize, &QAbstractSlider::valueChanged, m_ui.kcfg_MinimumFontSize, &QSpinBox::setValue); connect(m_ui.slider_mediumFontSize, &QAbstractSlider::valueChanged, m_ui.kcfg_MediumFontSize, &QSpinBox::setValue); connect(m_ui.slider_minimumFontSize, &QAbstractSlider::sliderMoved, m_ui.kcfg_MinimumFontSize, &QSpinBox::setValue); connect(m_ui.slider_mediumFontSize, &QAbstractSlider::sliderMoved, m_ui.kcfg_MediumFontSize, &QSpinBox::setValue); - connect(m_ui.kcfg_MinimumFontSize, QOverload::of(&KPluralHandlingSpinBox::valueChanged), m_ui.slider_minimumFontSize, &QSlider::setValue); - connect(m_ui.kcfg_MediumFontSize, QOverload::of(&KPluralHandlingSpinBox::valueChanged), m_ui.slider_mediumFontSize, &QSlider::setValue); + connect(m_ui.kcfg_MinimumFontSize, qOverload(&KPluralHandlingSpinBox::valueChanged), m_ui.slider_minimumFontSize, &QSlider::setValue); + connect(m_ui.kcfg_MediumFontSize, qOverload(&KPluralHandlingSpinBox::valueChanged), m_ui.slider_mediumFontSize, &QSlider::setValue); KAboutData *about = new KAboutData(QStringLiteral("kcmakrappearanceconfig"), i18n("Configure Feed Reader Appearance"), QString(), QString(), KAboutLicense::GPL, i18n("(c), 2004 - 2008 Frank Osterfeld")); about->addAuthor(i18n("Frank Osterfeld"), QString(), QStringLiteral("osterfeld@kde.org")); setAboutData(about); m_ui.slider_minimumFontSize->setDisabled(Settings::self()->isImmutable(QStringLiteral("MinimumFontSize"))); m_ui.slider_mediumFontSize->setDisabled(Settings::self()->isImmutable(QStringLiteral("MediumFontSize"))); m_ui.lbl_MinimumFontSize->setDisabled(Settings::self()->isImmutable(QStringLiteral("MinimumFontSize"))); m_ui.lbl_MediumFontSize->setDisabled(Settings::self()->isImmutable(QStringLiteral("MediumFontSize"))); addConfig(Settings::self(), m_widget); } #include "akregator_config_appearance.moc" diff --git a/configuration/akregator_config_archive.cpp b/configuration/akregator_config_archive.cpp index 613735ff..59670dfa 100644 --- a/configuration/akregator_config_archive.cpp +++ b/configuration/akregator_config_archive.cpp @@ -1,104 +1,104 @@ /* This file is part of Akregator. Copyright (c) 2008 Frank Osterfeld 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) 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; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "akregator_config_archive.h" #include "akregatorconfig.h" #include "ui_settings_archive.h" #include #include #include #include #include using namespace Akregator; K_PLUGIN_FACTORY(KCMAkregatorArchiveConfigFactory, registerPlugin(); ) KCMAkregatorArchiveConfig::KCMAkregatorArchiveConfig(QWidget *parent, const QVariantList &args) : KCModule(parent, args) , m_widget(new QWidget) { Ui::SettingsArchive m_ui; m_ui.setupUi(m_widget); QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(m_widget); connect(m_ui.rb_LimitArticleNumber, &QAbstractButton::toggled, m_ui.kcfg_MaxArticleNumber, &QWidget::setEnabled); connect(m_ui.rb_LimitArticleAge, &QAbstractButton::toggled, m_ui.kcfg_MaxArticleAge, &QWidget::setEnabled); m_ui.kcfg_MaxArticleNumber->setSuffix(ki18ncp("Limit feed archive size to:", " article", " articles")); m_ui.kcfg_MaxArticleAge->setSuffix(ki18ncp("Delete articles older than:", " day", " days")); m_archiveModeGroup = new QButtonGroup(this); m_archiveModeGroup->addButton(m_ui.rb_KeepAllArticles, Settings::EnumArchiveMode::keepAllArticles); m_archiveModeGroup->addButton(m_ui.rb_LimitArticleNumber, Settings::EnumArchiveMode::limitArticleNumber); m_archiveModeGroup->addButton(m_ui.rb_LimitArticleAge, Settings::EnumArchiveMode::limitArticleAge); m_archiveModeGroup->addButton(m_ui.rb_DisableArchiving, Settings::EnumArchiveMode::disableArchiving); - connect(m_archiveModeGroup, QOverload::of(&QButtonGroup::buttonClicked), this, QOverload<>::of(&KCMAkregatorArchiveConfig::changed)); + connect(m_archiveModeGroup, QOverload::of(&QButtonGroup::buttonClicked), this, qOverload<>(&KCMAkregatorArchiveConfig::changed)); KAboutData *about = new KAboutData(QStringLiteral("kcmakrarchiveconfig"), i18n("Configure Feed Reader Archive"), QString(), QString(), KAboutLicense::GPL, i18n("(c), 2004 - 2008 Frank Osterfeld")); about->addAuthor(i18n("Frank Osterfeld"), QString(), QStringLiteral("osterfeld@kde.org")); setAboutData(about); addConfig(Settings::self(), m_widget); } void KCMAkregatorArchiveConfig::load() { setArchiveMode(Settings::archiveMode()); KCModule::load(); } void KCMAkregatorArchiveConfig::save() { Settings::setArchiveMode(archiveMode()); KCModule::save(); } void KCMAkregatorArchiveConfig::setArchiveMode(int mode) { QAbstractButton *const b = m_archiveModeGroup->button(mode); if (b) { b->setChecked(true); } else { qWarning() << QStringLiteral("No button for %1 registered, ignoring call").arg(mode); } } int KCMAkregatorArchiveConfig::archiveMode() const { const int id = m_archiveModeGroup->checkedId(); if (id < 0 || id >= Settings::EnumArchiveMode::COUNT) { return Settings::EnumArchiveMode::keepAllArticles; } return id; } #include "akregator_config_archive.moc" diff --git a/configuration/settings_advanced.cpp b/configuration/settings_advanced.cpp index 77a912fa..b60745ce 100644 --- a/configuration/settings_advanced.cpp +++ b/configuration/settings_advanced.cpp @@ -1,95 +1,95 @@ /* This file is part of Akregator. Copyright (C) 2005-2007 Frank Osterfeld 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) 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; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "settings_advanced.h" #include "akregatorconfig.h" #include "storagefactory.h" #include "storagefactoryregistry.h" #include #include #include #include #include using namespace Akregator; SettingsAdvanced::SettingsAdvanced(QWidget *parent, const char *name) : QWidget(parent) { setObjectName(QLatin1String(name)); setupUi(this); const QStringList backends = Backend::StorageFactoryRegistry::self()->list(); for (const QString &i : backends) { Backend::StorageFactory *const factory = Backend::StorageFactoryRegistry::self()->getFactory(i); if (!factory) { continue; } m_factories.insert(factory->key(), factory); cbBackend->addItem(factory->name(), factory->key()); } connect(pbBackendConfigure, &QPushButton::clicked, this, &SettingsAdvanced::slotConfigureStorage); - connect(cbBackend, QOverload::of(&QComboBox::activated), this, &SettingsAdvanced::slotFactorySelected); + connect(cbBackend, qOverload(&QComboBox::activated), this, &SettingsAdvanced::slotFactorySelected); connect(kcfg_UseMarkReadDelay, &QCheckBox::toggled, kcfg_MarkReadDelay, &KPluralHandlingSpinBox::setEnabled); kcfg_MarkReadDelay->setSuffix(ki18ncp("Mark selected article read after", " second", " seconds")); } QString SettingsAdvanced::selectedFactory() const { return cbBackend->itemData(cbBackend->currentIndex()).toString(); } void SettingsAdvanced::selectFactory(const QString &key) { const int idx = cbBackend->findData(key); if (idx < 0) { return; } cbBackend->setCurrentIndex(idx); const Backend::StorageFactory *const factory = m_factories.value(key); Q_ASSERT(factory); pbBackendConfigure->setEnabled(factory->isConfigurable()); } void SettingsAdvanced::slotConfigureStorage() { const QString key = cbBackend->itemData(cbBackend->currentIndex()).toString(); if (!key.isEmpty()) { Backend::StorageFactory *const factory = m_factories.value(key); Q_ASSERT(factory); factory->configure(); } } void SettingsAdvanced::slotFactorySelected(int pos) { const QString key = cbBackend->itemData(pos).toString(); const Backend::StorageFactory *const factory = m_factories.value(key); Q_ASSERT(factory); pbBackendConfigure->setEnabled(factory->isConfigurable()); } diff --git a/src/akregator_part.cpp b/src/akregator_part.cpp index c0b9c16b..411846f8 100644 --- a/src/akregator_part.cpp +++ b/src/akregator_part.cpp @@ -1,844 +1,844 @@ /* This file is part of Akregator. Copyright (C) 2004 Stanislav Karchebny 2005 Frank Osterfeld 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) 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; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "akregator_part.h" #include "akregator_debug.h" #include "messageviewer/messageviewersettings.h" #include "akregatorconfig.h" #include "aboutdata.h" #include "actionmanagerimpl.h" #include "article.h" #include "fetchqueue.h" #include "feedlist.h" #include "framemanager.h" #include "kernel.h" #include "loadfeedlistcommand.h" #include "mainwidget.h" #include "notificationmanager.h" #include "plugin.h" #include "pluginmanager.h" #include "storage.h" #include "storagefactory.h" #include "storagefactoryregistry.h" #include "trayicon.h" #include "widgets/akregatorcentralwidget.h" #include "dummystorage/storagefactorydummyimpl.h" #include "utils.h" #include "akregator_options.h" #include #include "akregator-version.h" #include "unityservicemanager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "akregratormigrateapplication.h" #include "partadaptor.h" #include #include #include namespace { static QDomDocument createDefaultFeedList() { QDomDocument doc; QDomProcessingInstruction z = doc.createProcessingInstruction(QStringLiteral("xml"), QStringLiteral("version=\"1.0\" encoding=\"UTF-8\"")); doc.appendChild(z); QDomElement root = doc.createElement(QStringLiteral("opml")); root.setAttribute(QStringLiteral("version"), QStringLiteral("1.0")); doc.appendChild(root); QDomElement head = doc.createElement(QStringLiteral("head")); root.appendChild(head); QDomElement text = doc.createElement(QStringLiteral("text")); text.appendChild(doc.createTextNode(i18n("Feeds"))); head.appendChild(text); QDomElement body = doc.createElement(QStringLiteral("body")); root.appendChild(body); QDomElement mainFolder = doc.createElement(QStringLiteral("outline")); mainFolder.setAttribute(QStringLiteral("text"), QStringLiteral("KDE")); body.appendChild(mainFolder); QDomElement dot = doc.createElement(QStringLiteral("outline")); dot.setAttribute(QStringLiteral("text"), i18n("KDE Dot News")); dot.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://dot.kde.org/rss.xml")); mainFolder.appendChild(dot); QDomElement linuxFeeds = doc.createElement(QStringLiteral("outline")); linuxFeeds.setAttribute(QStringLiteral("text"), i18n("Linux.com")); linuxFeeds.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://www.linux.com/feeds/rss")); mainFolder.appendChild(linuxFeeds); QDomElement planetkde = doc.createElement(QStringLiteral("outline")); planetkde.setAttribute(QStringLiteral("text"), i18n("Planet KDE")); planetkde.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://planetkde.org/rss20.xml")); mainFolder.appendChild(planetkde); QDomElement apps = doc.createElement(QStringLiteral("outline")); apps.setAttribute(QStringLiteral("text"), i18n("KDE Apps")); apps.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://store.kde.org/content.rdf")); mainFolder.appendChild(apps); // Brazilian Portuguese feeds QDomElement portugueuseFolder = doc.createElement(QStringLiteral("outline")); portugueuseFolder.setAttribute(QStringLiteral("text"), i18n("Brazilian Portuguese feeds")); mainFolder.appendChild(portugueuseFolder); QDomElement portugueuseKde = doc.createElement(QStringLiteral("outline")); portugueuseKde.setAttribute(QStringLiteral("text"), i18n("Planet KDE Brazilian Portuguese")); portugueuseKde.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://planetkde.org/pt-br/rss20.xml")); portugueuseFolder.appendChild(portugueuseKde); // spanish feed(s) QDomElement spanishFolder = doc.createElement(QStringLiteral("outline")); spanishFolder.setAttribute(QStringLiteral("text"), i18n("Spanish feeds")); mainFolder.appendChild(spanishFolder); QDomElement spanishKde = doc.createElement(QStringLiteral("outline")); spanishKde.setAttribute(QStringLiteral("text"), i18n("Planet KDE EspaƱa")); spanishKde.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://planet.kde-espana.org/atom.xml")); spanishFolder.appendChild(spanishKde); return doc; } } namespace Akregator { K_PLUGIN_FACTORY(AkregatorFactory, registerPlugin(); ) static Part *mySelf = nullptr; BrowserExtension::BrowserExtension(Part *p, const char *name) : KParts::BrowserExtension(p) { AkregratorMigrateApplication migrate; migrate.migrate(); setObjectName(QLatin1String(name)); m_part = p; } void BrowserExtension::saveSettings() { m_part->saveSettings(); } Part::Part(QWidget *parentWidget, QObject *parent, const QVariantList &) : KParts::ReadOnlyPart(parent) , m_standardListLoaded(false) , m_shuttingDown(false) , m_doCrashSave(false) , m_backedUpList(false) , m_mainWidget(nullptr) , m_storage(nullptr) , m_dialog(nullptr) { mySelf = this; //Make sure to initialize settings Part::config(); initFonts(); setPluginLoadingMode(LoadPluginsIfEnabled); setPluginInterfaceVersion(AKREGATOR_PLUGIN_INTERFACE_VERSION); setComponentName(QStringLiteral("akregator"), i18n("Akregator")); setXMLFile(QStringLiteral("akregator_part.rc"), true); new PartAdaptor(this); QDBusConnection::sessionBus().registerObject(QStringLiteral("/Akregator"), this); const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/akregator/data/"); QDir().mkpath(path); m_standardFeedList = path + QStringLiteral("/feeds.opml"); Backend::StorageFactoryDummyImpl *dummyFactory = new Backend::StorageFactoryDummyImpl(); if (!Backend::StorageFactoryRegistry::self()->registerFactory(dummyFactory, dummyFactory->key())) { // There was already a dummy factory registered. delete dummyFactory; } loadPlugins(QStringLiteral("storage")); // FIXME: also unload them! m_storage = nullptr; Backend::StorageFactory *storageFactory = Backend::StorageFactoryRegistry::self()->getFactory(Settings::archiveBackend()); if (storageFactory != nullptr) { m_storage = storageFactory->createStorage(QStringList()); } if (!m_storage) { // Houston, we have a problem m_storage = Backend::StorageFactoryRegistry::self()->getFactory(QStringLiteral("dummy"))->createStorage(QStringList()); KMessageBox::error(parentWidget, i18n("Unable to load storage backend plugin \"%1\". No feeds are archived.", Settings::archiveBackend()), i18n("Plugin error")); } m_storage->open(true); Kernel::self()->setStorage(m_storage); m_actionManager = new ActionManagerImpl(this); ActionManager::setInstance(m_actionManager); mCentralWidget = new Akregator::AkregatorCentralWidget(parentWidget); connect(mCentralWidget, &AkregatorCentralWidget::restoreSession, this, &Part::slotRestoreSession); m_mainWidget = new Akregator::MainWidget(this, parentWidget, m_actionManager, QStringLiteral("akregator_view")); mCentralWidget->setMainWidget(m_mainWidget); m_extension = new BrowserExtension(this, "ak_extension"); connect(Kernel::self()->frameManager(), &FrameManager::signalCaptionChanged, this, &Part::setWindowCaption); connect(Kernel::self()->frameManager(), &FrameManager::signalStatusText, this, &Part::slotSetStatusText); connect(Kernel::self()->frameManager(), &FrameManager::signalLoadingProgress, m_extension, &BrowserExtension::loadingProgress); connect(Kernel::self()->frameManager(), &FrameManager::signalCanceled, this, &ReadOnlyPart::canceled); connect(Kernel::self()->frameManager(), &FrameManager::signalStarted, this, &Part::slotStarted); connect(Kernel::self()->frameManager(), SIGNAL(signalCompleted()), this, SIGNAL(completed())); // notify the part that this is our internal widget setWidget(mCentralWidget); //Initialize instance. (void)UnityServiceManager::instance(); connect(m_mainWidget.data(), &MainWidget::signalUnreadCountChanged, UnityServiceManager::instance(), &UnityServiceManager::slotSetUnread); if (Settings::showTrayIcon() && !TrayIcon::getInstance()) { initializeTrayIcon(); QWidget *const notificationParent = isTrayIconEnabled() ? m_mainWidget->window() : nullptr; NotificationManager::self()->setWidget(notificationParent, componentData().componentName()); } connect(qApp, &QCoreApplication::aboutToQuit, this, &Part::slotOnShutdown); m_autosaveTimer = new QTimer(this); connect(m_autosaveTimer, &QTimer::timeout, this, &Part::slotSaveFeedList); m_autosaveTimer->start(5 * 60 * 1000); // 5 minutes loadPlugins(QStringLiteral("extension")); // FIXME: also unload them! if (mCentralWidget->previousSessionCrashed()) { mCentralWidget->needToRestoreCrashedSession(); } else { m_doCrashSave = true; autoReadProperties(); } } KSharedConfig::Ptr Part::config() { assert(mySelf); if (!mySelf->mConfig) { mySelf->mConfig = KSharedConfig::openConfig(QStringLiteral("akregatorrc")); } return mySelf->mConfig; } void Part::updateQuickSearchLineText() { if (m_mainWidget) { m_mainWidget->updateQuickSearchLineText(); } } void Part::loadPlugins(const QString &type) { const KService::List offers = PluginManager::query(QStringLiteral("[X-KDE-akregator-plugintype] == '%1'").arg(type)); for (const KService::Ptr &i : offers) { Akregator::Plugin *plugin = PluginManager::createFromService(i, this); if (!plugin) { continue; } plugin->initialize(); plugin->insertGuiClients(this); } } void Part::slotStarted() { Q_EMIT started(nullptr); } void Part::slotOnShutdown() { autoSaveProperties(); m_shuttingDown = true; m_autosaveTimer->stop(); if (m_mainWidget) { saveSettings(); m_mainWidget->slotOnShutdown(); } //delete m_mainWidget; delete TrayIcon::getInstance(); TrayIcon::setInstance(nullptr); delete m_storage; m_storage = nullptr; //delete m_actionManager; } void Part::initializeTrayIcon() { TrayIcon *trayIcon = new TrayIcon(m_mainWidget->window()); TrayIcon::setInstance(trayIcon); m_actionManager->setTrayIcon(trayIcon); if (isTrayIconEnabled()) { trayIcon->setStatus(KStatusNotifierItem::Active); } connect(m_mainWidget.data(), &MainWidget::signalUnreadCountChanged, trayIcon, &TrayIcon::slotSetUnread); connect(m_mainWidget.data(), &MainWidget::signalArticlesSelected, this, &Part::signalArticlesSelected); m_mainWidget->slotSetTotalUnread(); } void Part::slotSettingsChanged() { NotificationManager::self()->setWidget(isTrayIconEnabled() ? m_mainWidget->window() : nullptr, componentData().componentName()); if (Settings::showTrayIcon()) { if (!TrayIcon::getInstance()) { initializeTrayIcon(); m_mainWidget->slotSetTotalUnread(); } } else { TrayIcon::getInstance()->disconnect(); delete TrayIcon::getInstance(); TrayIcon::setInstance(nullptr); m_actionManager->setTrayIcon(nullptr); } const QStringList fonts { Settings::standardFont(), Settings::fixedFont(), Settings::sansSerifFont(), Settings::serifFont(), Settings::standardFont(), Settings::standardFont(), QStringLiteral("0") }; Settings::setFonts(fonts); if (Settings::minimumFontSize() > Settings::mediumFontSize()) { Settings::setMediumFontSize(Settings::minimumFontSize()); } saveSettings(); Q_EMIT signalSettingsChanged(); initFonts(); } void Part::slotSetStatusText(const QString &statusText) { KPIM::BroadcastStatus::instance()->setStatusMsg(statusText); } void Part::saveSettings() { if (m_mainWidget) { m_mainWidget->saveSettings(); } } Part::~Part() { disconnect(qApp, &QCoreApplication::aboutToQuit, this, &Part::slotOnShutdown); qCDebug(AKREGATOR_LOG) << "Part::~Part() enter"; // If the widget is destroyed for some reason, KParts::Part will set its // widget property to 0 and then delete itself (and therefore this object). // In this case, it's not safe to do our normal shutdown routine. if (widget() && !m_shuttingDown) { slotOnShutdown(); } qCDebug(AKREGATOR_LOG) << "Part::~Part(): leaving"; } void Part::readProperties(const KConfigGroup &config) { m_backedUpList = false; openStandardFeedList(); if (m_mainWidget) { m_mainWidget->readProperties(config); } } void Part::saveProperties(KConfigGroup &config) { if (m_mainWidget) { slotSaveFeedList(); m_mainWidget->saveProperties(config); } } void Part::exportFile(const QString &str) { exportFile(QUrl(str)); } bool Part::openUrl(const QUrl &url) { setLocalFilePath(url.toLocalFile()); return openFile(); } void Part::openStandardFeedList() { if (!m_standardFeedList.isEmpty()) { openUrl(QUrl::fromLocalFile(m_standardFeedList)); } } bool Part::openFile() { if (m_loadFeedListCommand || m_standardListLoaded) { return true; } QScopedPointer cmd(new LoadFeedListCommand(m_mainWidget)); cmd->setParentWidget(m_mainWidget); cmd->setStorage(Kernel::self()->storage()); cmd->setFileName(localFilePath()); cmd->setDefaultFeedList(createDefaultFeedList()); connect(cmd.data(), &LoadFeedListCommand::result, this, &Part::feedListLoaded); m_loadFeedListCommand = cmd.take(); m_loadFeedListCommand->start(); return true; } bool Part::writeToTextFile(const QString &data, const QString &filename) const { QSaveFile file(filename); if (!file.open(QIODevice::WriteOnly)) { return false; } QTextStream stream(&file); stream.setCodec("UTF-8"); stream << data << endl; return file.commit(); } void Part::feedListLoaded(const QSharedPointer &list) { Q_ASSERT(!m_standardListLoaded); if (!m_mainWidget) { return; } m_mainWidget->setFeedList(list); m_standardListLoaded = list != nullptr; if (Settings::markAllFeedsReadOnStartup()) { m_mainWidget->slotMarkAllFeedsRead(); } if (m_standardListLoaded) { QTimer::singleShot(0, this, &Part::flushAddFeedRequests); } if (Settings::fetchOnStartup()) { m_mainWidget->slotFetchAllFeeds(); } } void Part::flushAddFeedRequests() { if (!m_mainWidget) { return; } for (const AddFeedRequest &i : qAsConst(m_requests)) { for (const QString &j : qAsConst(i.urls)) { m_mainWidget->addFeedToGroup(j, i.group); } NotificationManager::self()->slotNotifyFeeds(i.urls); } m_requests.clear(); } void Part::slotSaveFeedList() { // don't save to the standard feed list, when it wasn't completely loaded before if (!m_standardListLoaded) { return; } // the first time we overwrite the feed list, we create a backup if (!m_backedUpList) { const QString backup = localFilePath() + QLatin1Char('~'); if (QFile::exists(backup)) { QFile::remove(backup); } if (QFile::copy(localFilePath(), backup)) { m_backedUpList = true; } } const QString xml = m_mainWidget->feedListToOPML().toString(); if (xml.isEmpty()) { return; } m_storage->storeFeedList(xml); if (writeToTextFile(xml, localFilePath())) { return; } KMessageBox::error(m_mainWidget, i18n("Access denied: Cannot save feed list to %1. Please check your permissions.", localFilePath()), i18n("Write Error")); } bool Part::isTrayIconEnabled() const { return Settings::showTrayIcon(); } void Part::importFile(const QUrl &url) { QString filename; QTemporaryFile tempFile; if (url.isLocalFile()) { filename = url.toLocalFile(); } else { if (!tempFile.open()) { return; } filename = tempFile.fileName(); auto job = KIO::file_copy(url, QUrl::fromLocalFile(filename), -1, KIO::Overwrite | KIO::HideProgressInfo); KJobWidgets::setWindow(job, m_mainWidget); if (!job->exec()) { KMessageBox::error(m_mainWidget, job->errorString()); return; } } QFile file(filename); if (file.open(QIODevice::ReadOnly)) { // Read OPML feeds list and build QDom tree. QDomDocument doc; if (doc.setContent(file.readAll())) { m_mainWidget->importFeedList(doc); } else { KMessageBox::error(m_mainWidget, i18n("Could not import the file %1 (no valid OPML)", filename), i18n("OPML Parsing Error")); } } else { KMessageBox::error(m_mainWidget, i18n("The file %1 could not be read, check if it exists or if it is readable for the current user.", filename), i18n("Read Error")); } } void Part::exportFile(const QUrl &url) { if (url.isLocalFile()) { const QString fname = url.toLocalFile(); if (!writeToTextFile(m_mainWidget->feedListToOPML().toString(), fname)) { KMessageBox::error(m_mainWidget, i18n("Access denied: cannot write to file %1. Please check your permissions.", fname), i18n("Write Error")); } return; } else { auto job = KIO::storedPut(m_mainWidget->feedListToOPML().toString().toUtf8(), url, -1); KJobWidgets::setWindow(job, m_mainWidget); if (!job->exec()) { KMessageBox::error(m_mainWidget, job->errorString()); } } } void Part::fileImport() { const QString filters = i18n("OPML Outlines (*.opml *.xml);;All Files (*)"); const QUrl url = QFileDialog::getOpenFileUrl(m_mainWidget, QString(), QUrl(), filters); if (!url.isEmpty()) { importFile(url); } } void Part::fileExport() { const QString filters = i18n("OPML Outlines (*.opml *.xml);;All Files (*)"); const QUrl url = QFileDialog::getSaveFileUrl(m_mainWidget, QString(), QUrl(), filters); if (!url.isEmpty()) { exportFile(url); } } void Part::fetchAllFeeds() { m_mainWidget->slotFetchAllFeeds(); } void Part::fetchFeedUrl(const QString &s) { qCDebug(AKREGATOR_LOG) << "fetchFeedURL==" << s; } void Part::addFeedsToGroup(const QStringList &urls, const QString &group) { AddFeedRequest req; req.group = group; req.urls = urls; m_requests.append(req); if (m_standardListLoaded) { flushAddFeedRequests(); } } void Part::addFeed() { m_mainWidget->slotFeedAdd(); } void Part::showNotificationOptions() { const Akregator::AboutData about; KNotifyConfigWidget::configure(m_mainWidget, about.productName()); } void Part::showOptions() { saveSettings(); if (!m_dialog) { m_dialog = new KCMultiDialog(m_mainWidget); - connect(m_dialog, QOverload<>::of(&KCMultiDialog::configCommitted), + connect(m_dialog, qOverload<>(&KCMultiDialog::configCommitted), this, &Part::slotSettingsChanged); if (TrayIcon::getInstance()) { - connect(m_dialog, QOverload<>::of(&KCMultiDialog::configCommitted), + connect(m_dialog, qOverload<>(&KCMultiDialog::configCommitted), TrayIcon::getInstance(), &TrayIcon::settingsChanged); } m_dialog->addModule(QStringLiteral("akregator_config_general")); m_dialog->addModule(QStringLiteral("akregator_config_appearance")); m_dialog->addModule(QStringLiteral("akregator_config_archive")); m_dialog->addModule(QStringLiteral("akregator_config_browser")); m_dialog->addModule(QStringLiteral("akregator_config_advanced")); m_dialog->addModule(QStringLiteral("akregator_config_plugins")); } m_dialog->show(); m_dialog->raise(); } void Part::initFonts() { QStringList fonts = Settings::fonts(); if (fonts.isEmpty()) { fonts.append(QFontDatabase::systemFont(QFontDatabase::GeneralFont).family()); fonts.append(QFontDatabase::systemFont(QFontDatabase::FixedFont).family()); fonts.append(QFontDatabase::systemFont(QFontDatabase::GeneralFont).family()); fonts.append(QFontDatabase::systemFont(QFontDatabase::GeneralFont).family()); fonts.append(QStringLiteral("0")); } Settings::setFonts(fonts); if (Settings::standardFont().isEmpty()) { Settings::setStandardFont(fonts[0]); } if (Settings::fixedFont().isEmpty()) { Settings::setFixedFont(fonts[1]); } if (Settings::sansSerifFont().isEmpty()) { Settings::setSansSerifFont(fonts[2]); } if (Settings::serifFont().isEmpty()) { Settings::setSerifFont(fonts[3]); } //TODO add CursiveFont, FantasyFont KConfigGroup conf(Settings::self()->config(), "HTML Settings"); KConfig _konq(QStringLiteral("konquerorrc"), KConfig::NoGlobals); KConfigGroup konq(&_konq, "HTML Settings"); if (!conf.hasKey("MinimumFontSize")) { int minfs; if (konq.hasKey("MinimumFontSize")) { minfs = konq.readEntry("MinimumFontSize", 8); } else { minfs = std::max(QFontDatabase::systemFont(QFontDatabase::GeneralFont).pointSize() - 2, 4); } Settings::setMinimumFontSize(minfs); } if (!conf.hasKey("MediumFontSize")) { int medfs; if (konq.hasKey("MediumFontSize")) { medfs = konq.readEntry("MediumFontSize", 12); } else { medfs = QFontDatabase::systemFont(QFontDatabase::GeneralFont).pointSize(); } Settings::setMediumFontSize(medfs); } QWebEngineSettings::defaultSettings()->setFontFamily(QWebEngineSettings::StandardFont, Settings::standardFont()); QWebEngineSettings::defaultSettings()->setFontFamily(QWebEngineSettings::FixedFont, Settings::fixedFont()); QWebEngineSettings::defaultSettings()->setFontFamily(QWebEngineSettings::SerifFont, Settings::serifFont()); QWebEngineSettings::defaultSettings()->setFontFamily(QWebEngineSettings::SansSerifFont, Settings::sansSerifFont()); QWebEngineSettings::defaultSettings()->setFontSize(QWebEngineSettings::MinimumFontSize, Settings::minimumFontSize()); QWebEngineSettings::defaultSettings()->setFontSize(QWebEngineSettings::DefaultFontSize, Settings::mediumFontSize()); } bool Part::handleCommandLine(const QStringList &args) { QCommandLineParser parser; akregator_options(&parser); parser.process(args); const QString addFeedGroup = parser.isSet(QStringLiteral("group")) ? parser.value(QStringLiteral("group")) : i18n("Imported Folder"); QStringList feedsToAdd = parser.values(QStringLiteral("addfeed")); if (feedsToAdd.isEmpty() && !parser.positionalArguments().isEmpty()) { Q_FOREACH (QString url, parser.positionalArguments()) { const QUrl tempUrl = QUrl::fromUserInput(url); if (tempUrl.isLocalFile()) { const QString tempLocalFile = tempUrl.toLocalFile(); if (tempLocalFile.startsWith(QDir::tempPath())) { const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/akregator/data/"); QDir().mkpath(path); QFile f(tempLocalFile); const QString newRssFileName = path + QFileInfo(f).fileName(); if (!f.copy(newRssFileName)) { qCWarning(AKREGATOR_LOG) << "Impossible to copy in local folder" << newRssFileName; } else { url = newRssFileName; } } } feedsToAdd.append(url); } } if (!feedsToAdd.isEmpty()) { addFeedsToGroup(feedsToAdd, addFeedGroup); } return true; } void Part::clearCrashProperties() { if (!m_doCrashSave) { return; } KConfig config(QStringLiteral("crashed"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation); KConfigGroup configGroup(&config, "Part"); configGroup.writeEntry("crashed", false); } void Part::saveCrashProperties() { if (!m_doCrashSave) { return; } KConfig config(QStringLiteral("crashed"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation); KConfigGroup configGroup(&config, "Part"); configGroup.deleteGroup(); configGroup.writeEntry("crashed", true); saveProperties(configGroup); } void Part::slotAutoSave() { saveCrashProperties(); } void Part::autoSaveProperties() { KConfig config(QStringLiteral("autosaved"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation); KConfigGroup configGroup(&config, "Part"); configGroup.deleteGroup(); saveProperties(configGroup); clearCrashProperties(); } void Part::autoReadProperties() { if (qGuiApp->isSessionRestored()) { return; } KConfig config(QStringLiteral("autosaved"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation); KConfigGroup configGroup(&config, "Part"); readProperties(configGroup); } void Part::slotRestoreSession(Akregator::CrashWidget::CrashAction type) { switch (type) { case Akregator::CrashWidget::RestoreSession: { KConfig config(QStringLiteral("crashed"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation); KConfigGroup configGroup(&config, "Part"); readProperties(configGroup); clearCrashProperties(); break; } case Akregator::CrashWidget::NotRestoreSession: clearCrashProperties(); break; case Akregator::CrashWidget::AskMeLater: break; } m_doCrashSave = true; } } // namespace Akregator #include "akregator_part.moc" diff --git a/src/feed/feedpropertiesdialog.cpp b/src/feed/feedpropertiesdialog.cpp index 74033c41..bed9b41b 100644 --- a/src/feed/feedpropertiesdialog.cpp +++ b/src/feed/feedpropertiesdialog.cpp @@ -1,349 +1,349 @@ /* This file is part of Akregator. Copyright (C) 2004 Stanislav Karchebny 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) 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; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "feedpropertiesdialog.h" #include "akregatorconfig.h" #include #include #include #include #include #include using namespace Akregator; FeedPropertiesWidget::FeedPropertiesWidget(QWidget *parent, const QString &name) : QWidget(parent) { setObjectName(name); setupUi(this); connect(cb_updateInterval, &QCheckBox::toggled, updateSpinBox, &QSpinBox::setEnabled); connect(cb_updateInterval, &QCheckBox::toggled, updateComboBox, &QComboBox::setEnabled); connect(cb_updateInterval, &QCheckBox::toggled, updateLabel, &QLabel::setEnabled); connect(cb_updateInterval, &QCheckBox::toggled, this, &FeedPropertiesWidget::slotUpdateCheckBoxToggled); - connect(updateComboBox, QOverload::of(&QComboBox::activated), this, &FeedPropertiesWidget::slotUpdateComboBoxActivated); - connect(updateSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &FeedPropertiesWidget::slotUpdateComboBoxLabels); + connect(updateComboBox, qOverload(&QComboBox::activated), this, &FeedPropertiesWidget::slotUpdateComboBoxActivated); + connect(updateSpinBox, qOverload(&QSpinBox::valueChanged), this, &FeedPropertiesWidget::slotUpdateComboBoxLabels); connect(rb_limitArticleAge, &QRadioButton::toggled, sb_maxArticleAge, &KPluralHandlingSpinBox::setEnabled); connect(rb_limitArticleNumber, &QRadioButton::toggled, sb_maxArticleNumber, &KPluralHandlingSpinBox::setEnabled); } FeedPropertiesWidget::~FeedPropertiesWidget() { } void FeedPropertiesWidget::slotUpdateComboBoxActivated(int index) { updateSpinBox->setEnabled(index != Never); } void FeedPropertiesWidget::slotUpdateComboBoxLabels(int value) { updateComboBox->setItemText(FeedPropertiesWidget::Minutes, i18np("Minute", "Minutes", value)); updateComboBox->setItemText(FeedPropertiesWidget::Hours, i18np("Hour", "Hours", value)); updateComboBox->setItemText(FeedPropertiesWidget::Days, i18np("Day", "Days", value)); } void FeedPropertiesWidget::slotUpdateCheckBoxToggled(bool enabled) { updateSpinBox->setEnabled(enabled && updateComboBox->currentIndex() != Never); } FeedPropertiesDialog::FeedPropertiesDialog(QWidget *parent, const QString &name) : QDialog(parent) , m_feed(nullptr) { setObjectName(name); setWindowTitle(i18n("Feed Properties")); QVBoxLayout *mainLayout = new QVBoxLayout(this); widget = new FeedPropertiesWidget(this); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); mOkButton = buttonBox->button(QDialogButtonBox::Ok); mOkButton->setDefault(true); mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::accepted, this, &FeedPropertiesDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &FeedPropertiesDialog::reject); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); setModal(true); mainLayout->addWidget(widget); mainLayout->addWidget(buttonBox); widget->feedNameEdit->setFocus(); widget->updateComboBox->insertItem(FeedPropertiesWidget::Minutes, i18np("Minute", "Minutes", 0)); widget->updateComboBox->insertItem(FeedPropertiesWidget::Hours, i18np("Hour", "Hours", 0)); widget->updateComboBox->insertItem(FeedPropertiesWidget::Days, i18np("Day", "Days", 0)); widget->updateComboBox->insertItem(FeedPropertiesWidget::Never, i18nc("never fetch new articles", "Never")); widget->sb_maxArticleAge->setSuffix(ki18np(" day", " days")); widget->sb_maxArticleNumber->setSuffix(ki18np(" article", " articles")); connect(widget->feedNameEdit, &QLineEdit::textChanged, this, &FeedPropertiesDialog::slotSetWindowTitle); } FeedPropertiesDialog::~FeedPropertiesDialog() { } void FeedPropertiesDialog::accept() { m_feed->setNotificationMode(false); m_feed->setTitle(feedName()); m_feed->setXmlUrl(url()); m_feed->setCustomFetchIntervalEnabled(autoFetch()); if (autoFetch()) { m_feed->setFetchInterval(fetchInterval()); } m_feed->setArchiveMode(archiveMode()); m_feed->setMaxArticleAge(maxArticleAge()); m_feed->setMaxArticleNumber(maxArticleNumber()); m_feed->setMarkImmediatelyAsRead(markImmediatelyAsRead()); m_feed->setUseNotification(useNotification()); m_feed->setLoadLinkedWebsite(loadLinkedWebsite()); m_feed->setNotificationMode(true); QDialog::accept(); } void FeedPropertiesDialog::slotSetWindowTitle(const QString &title) { setWindowTitle(title.isEmpty() ? i18n("Feed Properties") : i18n("Properties of %1", title)); mOkButton->setEnabled(!title.trimmed().isEmpty()); } void FeedPropertiesDialog::setFeed(Feed *feed) { m_feed = feed; if (!feed) { return; } setFeedName(feed->title()); setUrl(feed->xmlUrl()); setAutoFetch(feed->useCustomFetchInterval()); if (feed->useCustomFetchInterval()) { setFetchInterval(feed->fetchInterval()); } else { setFetchInterval(Settings::autoFetchInterval()); } setArchiveMode(feed->archiveMode()); setMaxArticleAge(feed->maxArticleAge()); setMaxArticleNumber(feed->maxArticleNumber()); setMarkImmediatelyAsRead(feed->markImmediatelyAsRead()); setUseNotification(feed->useNotification()); setLoadLinkedWebsite(feed->loadLinkedWebsite()); slotSetWindowTitle(feedName()); } QString FeedPropertiesDialog::feedName() const { return widget->feedNameEdit->text(); } QString FeedPropertiesDialog::url() const { return widget->urlEdit->text(); } bool FeedPropertiesDialog::autoFetch() const { return widget->cb_updateInterval->isChecked(); } int FeedPropertiesDialog::fetchInterval() const { switch (widget->updateComboBox->currentIndex()) { case FeedPropertiesWidget::Minutes: return widget->updateSpinBox->value(); case FeedPropertiesWidget::Hours: return widget->updateSpinBox->value() * 60; case FeedPropertiesWidget::Days: return widget->updateSpinBox->value() * 60 * 24; case FeedPropertiesWidget::Never: default: return -1; // never } } Feed::ArchiveMode FeedPropertiesDialog::archiveMode() const { // i could check the button group's int, but order could change... if (widget->rb_globalDefault->isChecked()) { return Feed::globalDefault; } if (widget->rb_keepAllArticles->isChecked()) { return Feed::keepAllArticles; } if (widget->rb_limitArticleAge->isChecked()) { return Feed::limitArticleAge; } if (widget->rb_limitArticleNumber->isChecked()) { return Feed::limitArticleNumber; } if (widget->rb_disableArchiving->isChecked()) { return Feed::disableArchiving; } // in a perfect world, this is never reached return Feed::globalDefault; } int FeedPropertiesDialog::maxArticleAge() const { return widget->sb_maxArticleAge->value(); } int FeedPropertiesDialog::maxArticleNumber() const { return widget->sb_maxArticleNumber->value(); } void FeedPropertiesDialog::setArchiveMode(Feed::ArchiveMode mode) { switch (mode) { case Feed::globalDefault: widget->rb_globalDefault->setChecked(true); break; case Feed::keepAllArticles: widget->rb_keepAllArticles->setChecked(true); break; case Feed::disableArchiving: widget->rb_disableArchiving->setChecked(true); break; case Feed::limitArticleAge: widget->rb_limitArticleAge->setChecked(true); break; case Feed::limitArticleNumber: widget->rb_limitArticleNumber->setChecked(true); } } void FeedPropertiesDialog::setFeedName(const QString &title) { widget->feedNameEdit->setText(title); } void FeedPropertiesDialog::setUrl(const QString &url) { widget->urlEdit->setText(url); } void FeedPropertiesDialog::setAutoFetch(bool customFetchEnabled) { widget->cb_updateInterval->setChecked(customFetchEnabled); widget->updateComboBox->setEnabled(customFetchEnabled); if (widget->updateSpinBox->value() > -1) { widget->updateSpinBox->setEnabled(customFetchEnabled); } else { widget->updateSpinBox->setEnabled(false); } } void FeedPropertiesDialog::setFetchInterval(int interval) { if (interval == -1) { // never update widget->updateSpinBox->setValue(0); widget->updateSpinBox->setDisabled(true); widget->updateComboBox->setCurrentIndex(FeedPropertiesWidget::Never); return; } if (interval == 0) { widget->updateSpinBox->setValue(0); widget->updateSpinBox->setEnabled(widget->cb_updateInterval->isChecked()); widget->updateComboBox->setCurrentIndex(FeedPropertiesWidget::Minutes); return; } if (interval % (60 * 24) == 0) { widget->updateSpinBox->setValue(interval / (60 * 24)); widget->updateSpinBox->setEnabled(widget->cb_updateInterval->isChecked()); widget->updateComboBox->setCurrentIndex(FeedPropertiesWidget::Days); return; } if (interval % 60 == 0) { widget->updateSpinBox->setValue(interval / 60); widget->updateSpinBox->setEnabled(widget->cb_updateInterval->isChecked()); widget->updateComboBox->setCurrentIndex(FeedPropertiesWidget::Hours); return; } widget->updateSpinBox->setValue(interval); widget->updateSpinBox->setEnabled(widget->cb_updateInterval->isChecked()); widget->updateComboBox->setCurrentIndex(FeedPropertiesWidget::Minutes); } void FeedPropertiesDialog::setMaxArticleAge(int age) { widget->sb_maxArticleAge->setValue(age); } void FeedPropertiesDialog::setMaxArticleNumber(int number) { widget->sb_maxArticleNumber->setValue(number); } void FeedPropertiesDialog::setMarkImmediatelyAsRead(bool enabled) { widget->checkBox_markRead->setChecked(enabled); } bool FeedPropertiesDialog::markImmediatelyAsRead() const { return widget->checkBox_markRead->isChecked(); } void FeedPropertiesDialog::setUseNotification(bool enabled) { widget->checkBox_useNotification->setChecked(enabled); } bool FeedPropertiesDialog::useNotification() const { return widget->checkBox_useNotification->isChecked(); } bool FeedPropertiesDialog::loadLinkedWebsite() const { return widget->checkBox_loadWebsite->isChecked(); } void FeedPropertiesDialog::setLoadLinkedWebsite(bool enabled) { widget->checkBox_loadWebsite->setChecked(enabled); } void FeedPropertiesDialog::selectFeedName() { widget->feedNameEdit->selectAll(); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8587b930..1d88b378 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,233 +1,233 @@ /* This file is part of Akregator. Copyright (C) 2004 Stanislav Karchebny 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) 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; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "mainwindow.h" #include "akregator_part.h" #include "akregatorconfig.h" #include "trayicon.h" #include "Libkdepim/BroadcastStatus" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Akregator; BrowserInterface::BrowserInterface(MainWindow *shell, const QString &name) : KParts::BrowserInterface(shell) { setObjectName(name); m_shell = shell; } MainWindow::MainWindow(QWidget *parent) : KParts::MainWindow(parent) , m_browserIface(new BrowserInterface(this, QStringLiteral("browser_interface"))) , m_part() , m_statusLabel(new KSqueezedTextLabel(this)) { setPluginLoadingMode(DoNotLoadPlugins); // set the shell's ui resource file setXMLFile(QStringLiteral("akregator_shell.rc")); KStandardAction::keyBindings(this, &MainWindow::optionsConfigureKeys, actionCollection()); // options_configure_keybinding KStandardAction::configureToolbars(this, &MainWindow::optionsConfigureToolbars, actionCollection()); // options_configure_toolbars toolBar()->show(); statusBar()->show(); int statH = fontMetrics().height() + 2; m_statusLabel->setTextFormat(Qt::RichText); m_statusLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed)); m_statusLabel->setMinimumWidth(0); m_statusLabel->setFixedHeight(statH); statusBar()->addWidget(m_statusLabel, 1); KStandardAction::quit(qApp, &QApplication::quit, actionCollection()); KStandardAction::showMenubar(menuBar(), &QMenuBar::setVisible, actionCollection()); setStandardToolBarMenuEnabled(true); createStandardStatusBarAction(); connect(KPIM::BroadcastStatus::instance(), &KPIM::BroadcastStatus::statusMsg, this, &MainWindow::slotSetStatusBarText); connect(qApp, &QCoreApplication::aboutToQuit, this, &MainWindow::slotOnShutdown); } bool MainWindow::loadPart() { if (m_part) { return true; } // this routine will find and load our Part. it finds the Part by // name which is a bad idea usually.. but it's alright in this // case since our Part is made for this Shell KPluginLoader loader(QStringLiteral("akregatorpart")); KPluginFactory *const factory = loader.factory(); if (!factory) { KMessageBox::error(this, i18n("Could not find the Akregator part; please check your installation.\n%1", loader.errorString())); return false; } m_part = static_cast(factory->create(this)); if (!m_part) { return false; } m_part->setObjectName(QStringLiteral("akregator_part")); setCentralWidget(m_part->widget()); - connect(m_part.data(), &Part::setWindowCaption, this, QOverload::of(&KMainWindow::setCaption)); + connect(m_part.data(), &Part::setWindowCaption, this, qOverload(&KMainWindow::setCaption)); createGUI(m_part); browserExtension(m_part)->setBrowserInterface(m_browserIface); setAutoSaveSettings(); return true; } void MainWindow::setupProgressWidgets() { KPIM::ProgressStatusBarWidget *progressStatusBarWidget = new KPIM::ProgressStatusBarWidget(statusBar(), this); statusBar()->addPermanentWidget(progressStatusBarWidget->littleProgress(), 0); } MainWindow::~MainWindow() { } void MainWindow::saveProperties(KConfigGroup &config) { if (!m_part) { if (!loadPart()) { return; } } m_part->saveProperties(config); config.writeEntry("docked", isHidden()); } void MainWindow::readProperties(const KConfigGroup &config) { if (!m_part) { if (!loadPart()) { return; } } m_part->readProperties(config); setVisible(!Settings::showTrayIcon() || !config.readEntry("docked", false)); } // TODO: move to part? void MainWindow::optionsConfigureKeys() { KShortcutsDialog dlg(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this); dlg.addCollection(actionCollection()); if (m_part) { dlg.addCollection(m_part->actionCollection()); } if (dlg.configure()) { if (m_part) { //FIXME // m_part->updateQuickSearchLineText(); } } } // TODO: move to part? void MainWindow::optionsConfigureToolbars() { KConfigGroup grp(KSharedConfig::openConfig().data()->group(autoSaveGroup())); saveMainWindowSettings(grp); QPointer dlg = new KEditToolBar(factory()); connect(dlg.data(), &KEditToolBar::newToolBarConfig, this, &MainWindow::applyNewToolbarConfig); dlg->exec(); delete dlg; } // TODO: move to part? void MainWindow::applyNewToolbarConfig() { applyMainWindowSettings(KSharedConfig::openConfig()->group(autoSaveGroup())); } KParts::BrowserExtension *MainWindow::browserExtension(KParts::ReadOnlyPart *p) { return KParts::BrowserExtension::childObject(p); } void MainWindow::slotQuit() { qApp->quit(); } void MainWindow::slotOnShutdown() { delete m_part; } bool MainWindow::queryClose() { if (qApp->isSavingSession()) { return true; } if (!TrayIcon::getInstance()) { delete m_part; // delete that here instead of dtor to ensure nested khtmlparts are deleted before singleton objects like KHTMLPageCache return true; } hide(); return false; } void MainWindow::slotClearStatusText() { m_statusLabel->setText(QString()); } void MainWindow::slotSetStatusBarText(const QString &text) { m_statusLabel->setText(text); }