File indexing completed on 2024-04-21 05:10:33

0001 /*
0002     This file is part of Akregator.
0003 
0004     SPDX-FileCopyrightText: 2004 Stanislav Karchebny <Stanislav.Karchebny@kdemail.net>
0005     SPDX-FileCopyrightText: 2005 Frank Osterfeld <osterfeld@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
0008 */
0009 
0010 #include "akregator_part.h"
0011 #include "akregator_debug.h"
0012 
0013 #include <MessageViewer/MessageViewerSettings>
0014 
0015 #include "aboutdata.h"
0016 #include "actionmanagerimpl.h"
0017 #include "akregator_options.h"
0018 #include "akregatorconfig.h"
0019 #include "article.h"
0020 #include "feedlist.h"
0021 #include "framemanager.h"
0022 #include "kernel.h"
0023 #include "loadfeedlistcommand.h"
0024 #include "mainwidget.h"
0025 #include "notificationmanager.h"
0026 #include "storage/storage.h"
0027 #include "trayicon.h"
0028 #include "unityservicemanager.h"
0029 #include "widgets/akregatorcentralwidget.h"
0030 #include <KConfig>
0031 #include <KIO/FileCopyJob>
0032 #include <KMessageBox>
0033 #include <KNotifyConfigWidget>
0034 #include <KPluginMetaData>
0035 #include <PimCommon/BroadcastStatus>
0036 #include <QFileDialog>
0037 
0038 #include <KCMultiDialog>
0039 #include <KIO/StoredTransferJob>
0040 #include <KJobWidgets>
0041 #include <KPluginFactory>
0042 #include <QSaveFile>
0043 #include <QTemporaryFile>
0044 #include <QWebEngineSettings>
0045 #include <kxmlguifactory.h>
0046 
0047 #include "partadaptor.h"
0048 #include <QApplication>
0049 #include <QDomDocument>
0050 #include <QFile>
0051 #include <QObject>
0052 #include <QStringList>
0053 #include <QTextStream>
0054 #include <QTimer>
0055 #include <QWebEngineProfile>
0056 #include <QWidget>
0057 
0058 #include <QFontDatabase>
0059 #include <QStandardPaths>
0060 #include <memory>
0061 
0062 namespace
0063 {
0064 static QDomDocument createDefaultFeedList()
0065 {
0066     QDomDocument doc;
0067     QDomProcessingInstruction z = doc.createProcessingInstruction(QStringLiteral("xml"), QStringLiteral("version=\"1.0\" encoding=\"UTF-8\""));
0068     doc.appendChild(z);
0069 
0070     QDomElement root = doc.createElement(QStringLiteral("opml"));
0071     root.setAttribute(QStringLiteral("version"), QStringLiteral("1.0"));
0072     doc.appendChild(root);
0073 
0074     QDomElement head = doc.createElement(QStringLiteral("head"));
0075     root.appendChild(head);
0076 
0077     QDomElement text = doc.createElement(QStringLiteral("text"));
0078     text.appendChild(doc.createTextNode(i18n("Feeds")));
0079     head.appendChild(text);
0080 
0081     QDomElement body = doc.createElement(QStringLiteral("body"));
0082     root.appendChild(body);
0083 
0084     QDomElement mainFolder = doc.createElement(QStringLiteral("outline"));
0085     mainFolder.setAttribute(QStringLiteral("text"), QStringLiteral("KDE"));
0086     body.appendChild(mainFolder);
0087 
0088     QDomElement dot = doc.createElement(QStringLiteral("outline"));
0089     dot.setAttribute(QStringLiteral("text"), i18n("KDE Dot News"));
0090     dot.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://dot.kde.org/rss.xml"));
0091     mainFolder.appendChild(dot);
0092 
0093     QDomElement linuxFeeds = doc.createElement(QStringLiteral("outline"));
0094     linuxFeeds.setAttribute(QStringLiteral("text"), i18n("Linux.com"));
0095     linuxFeeds.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://www.linux.com/feed/"));
0096     mainFolder.appendChild(linuxFeeds);
0097 
0098     QDomElement planetkde = doc.createElement(QStringLiteral("outline"));
0099     planetkde.setAttribute(QStringLiteral("text"), i18n("Planet KDE"));
0100     planetkde.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://planet.kde.org/global/atom.xml"));
0101     mainFolder.appendChild(planetkde);
0102 
0103     QDomElement apps = doc.createElement(QStringLiteral("outline"));
0104     apps.setAttribute(QStringLiteral("text"), i18n("KDE Apps"));
0105     apps.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://store.kde.org/content.rdf"));
0106     mainFolder.appendChild(apps);
0107 
0108     // spanish feed(s)
0109     QDomElement spanishFolder = doc.createElement(QStringLiteral("outline"));
0110     spanishFolder.setAttribute(QStringLiteral("text"), i18n("Spanish feeds"));
0111     mainFolder.appendChild(spanishFolder);
0112 
0113     QDomElement spanishKde = doc.createElement(QStringLiteral("outline"));
0114     spanishKde.setAttribute(QStringLiteral("text"), i18n("Planet KDE EspaƱa"));
0115     spanishKde.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://planet.kde-espana.org/atom.xml"));
0116     spanishFolder.appendChild(spanishKde);
0117 
0118     return doc;
0119 }
0120 }
0121 
0122 namespace Akregator
0123 {
0124 K_PLUGIN_FACTORY(AkregatorFactory, registerPlugin<Part>();)
0125 
0126 static Part *mySelf = nullptr;
0127 
0128 Part::Part(QWidget *parentWidget, QObject *parent, const KPluginMetaData &data, const QVariantList &)
0129     : KParts::Part(parent, data)
0130 {
0131     mySelf = this;
0132     // Make sure to initialize settings
0133     Part::config();
0134     initFonts();
0135 
0136     setComponentName(QStringLiteral("akregator"), i18n("Akregator"));
0137     setXMLFile(QStringLiteral("akregator_part.rc"), true);
0138 
0139     new PartAdaptor(this);
0140     QDBusConnection::sessionBus().registerObject(QStringLiteral("/Akregator"), this);
0141 
0142     const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/akregator/data/");
0143     QDir().mkpath(path);
0144     m_standardFeedList = path + QStringLiteral("/feeds.opml");
0145 
0146     m_storage = new Backend::Storage;
0147     m_storage->open(true);
0148 
0149     Kernel::self()->setStorage(m_storage);
0150 
0151     m_actionManager = new ActionManagerImpl(this);
0152     ActionManager::setInstance(m_actionManager);
0153 
0154     mCentralWidget = new Akregator::AkregatorCentralWidget(parentWidget);
0155     connect(mCentralWidget, &AkregatorCentralWidget::restoreSession, this, &Part::slotRestoreSession);
0156     m_mainWidget = new Akregator::MainWidget(this, parentWidget, m_actionManager, QStringLiteral("akregator_view"));
0157     mCentralWidget->setMainWidget(m_mainWidget);
0158 
0159     connect(Kernel::self()->frameManager(), &FrameManager::signalCaptionChanged, this, &Part::setWindowCaption);
0160     connect(Kernel::self()->frameManager(), &FrameManager::signalStatusText, this, &Part::slotSetStatusText);
0161 
0162     // notify the part that this is our internal widget
0163     setWidget(mCentralWidget);
0164 
0165     // Initialize instance.
0166     (void)UnityServiceManager::instance();
0167     if (Settings::showUnreadInTaskbar()) {
0168         connect(m_mainWidget.data(), &MainWidget::signalUnreadCountChanged, UnityServiceManager::instance(), &UnityServiceManager::slotSetUnread);
0169     }
0170 
0171     if (Settings::showTrayIcon() && !TrayIcon::getInstance()) {
0172         initializeTrayIcon();
0173         QWidget *const notificationParent = isTrayIconEnabled() ? m_mainWidget->window() : nullptr;
0174         NotificationManager::self()->setWidget(notificationParent, componentName());
0175     }
0176 
0177     connect(qApp, &QCoreApplication::aboutToQuit, this, &Part::slotOnShutdown);
0178 
0179     m_autosaveTimer = new QTimer(this);
0180     connect(m_autosaveTimer, &QTimer::timeout, this, &Part::slotSaveFeedList);
0181     m_autosaveTimer->start(5 * 60 * 1000); // 5 minutes
0182 
0183     if (mCentralWidget->previousSessionCrashed()) {
0184         mCentralWidget->needToRestoreCrashedSession();
0185     } else {
0186         m_doCrashSave = true;
0187         autoReadProperties();
0188     }
0189 }
0190 
0191 KSharedConfig::Ptr Part::config()
0192 {
0193     assert(mySelf);
0194     if (!mySelf->mConfig) {
0195         mySelf->mConfig = KSharedConfig::openConfig(QStringLiteral("akregatorrc"));
0196     }
0197     return mySelf->mConfig;
0198 }
0199 
0200 void Part::updateQuickSearchLineText()
0201 {
0202     if (m_mainWidget) {
0203         m_mainWidget->updateQuickSearchLineText();
0204     }
0205 }
0206 
0207 void Part::slotOnShutdown()
0208 {
0209     autoSaveProperties();
0210     m_shuttingDown = true;
0211     m_autosaveTimer->stop();
0212     if (m_mainWidget) {
0213         saveSettings();
0214         m_mainWidget->slotOnShutdown();
0215     }
0216     // delete m_mainWidget;
0217     delete TrayIcon::getInstance();
0218     TrayIcon::setInstance(nullptr);
0219     delete m_storage;
0220     m_storage = nullptr;
0221     // delete m_actionManager;
0222 }
0223 
0224 void Part::initializeTrayIcon()
0225 {
0226     auto trayIcon = new TrayIcon(m_mainWidget->window());
0227     TrayIcon::setInstance(trayIcon);
0228     m_actionManager->setTrayIcon(trayIcon);
0229 
0230     trayIcon->setEnabled(isTrayIconEnabled());
0231 
0232     connect(m_mainWidget.data(), &MainWidget::signalUnreadCountChanged, trayIcon, &TrayIcon::slotSetUnread);
0233     connect(m_mainWidget.data(), &MainWidget::signalArticlesSelected, this, &Part::signalArticlesSelected);
0234 
0235     m_mainWidget->slotSetTotalUnread();
0236 }
0237 
0238 void Part::slotSettingsChanged()
0239 {
0240     if (Settings::showUnreadInTaskbar()) {
0241         connect(m_mainWidget.data(), &MainWidget::signalUnreadCountChanged, UnityServiceManager::instance(), &UnityServiceManager::slotSetUnread);
0242         m_mainWidget->slotSetTotalUnread();
0243     } else {
0244         disconnect(m_mainWidget.data(), &MainWidget::signalUnreadCountChanged, UnityServiceManager::instance(), &UnityServiceManager::slotSetUnread);
0245         UnityServiceManager::instance()->slotSetUnread(0);
0246     }
0247 
0248     NotificationManager::self()->setWidget(isTrayIconEnabled() ? m_mainWidget->window() : nullptr, componentName());
0249     if (Settings::showTrayIcon()) {
0250         if (!TrayIcon::getInstance()) {
0251             initializeTrayIcon();
0252             m_mainWidget->slotSetTotalUnread();
0253         }
0254     } else {
0255         TrayIcon::getInstance()->disconnect();
0256         delete TrayIcon::getInstance();
0257         TrayIcon::setInstance(nullptr);
0258         m_actionManager->setTrayIcon(nullptr);
0259     }
0260 
0261     const QStringList fonts{Settings::standardFont(),
0262                             Settings::fixedFont(),
0263                             Settings::sansSerifFont(),
0264                             Settings::serifFont(),
0265                             Settings::standardFont(),
0266                             Settings::standardFont(),
0267                             QStringLiteral("0")};
0268     Settings::setFonts(fonts);
0269 
0270     if (Settings::minimumFontSize() > Settings::mediumFontSize()) {
0271         Settings::setMediumFontSize(Settings::minimumFontSize());
0272     }
0273     saveSettings();
0274     Q_EMIT signalSettingsChanged();
0275 
0276     initFonts();
0277 }
0278 
0279 void Part::slotSetStatusText(const QString &statusText)
0280 {
0281     PimCommon::BroadcastStatus::instance()->setStatusMsg(statusText);
0282 }
0283 
0284 void Part::saveSettings()
0285 {
0286     if (m_mainWidget) {
0287         m_mainWidget->saveSettings();
0288     }
0289 }
0290 
0291 Part::~Part()
0292 {
0293     disconnect(qApp, &QCoreApplication::aboutToQuit, this, &Part::slotOnShutdown);
0294     qCDebug(AKREGATOR_LOG) << "Part::~Part() enter";
0295     // If the widget is destroyed for some reason, KParts::Part will set its
0296     // widget property to 0 and then delete itself (and therefore this object).
0297     // In this case, it's not safe to do our normal shutdown routine.
0298     if (widget() && !m_shuttingDown) {
0299         slotOnShutdown();
0300     }
0301     qCDebug(AKREGATOR_LOG) << "Part::~Part(): leaving";
0302 }
0303 
0304 void Part::readProperties(const KConfigGroup &config)
0305 {
0306     m_backedUpList = false;
0307     openStandardFeedList();
0308 
0309     if (m_mainWidget) {
0310         m_mainWidget->readProperties(config);
0311     }
0312 }
0313 
0314 void Part::saveProperties(KConfigGroup &config)
0315 {
0316     if (m_mainWidget) {
0317         slotSaveFeedList();
0318         m_mainWidget->saveProperties(config);
0319     }
0320 }
0321 
0322 void Part::exportFile(const QString &str)
0323 {
0324     exportFile(QUrl(str));
0325 }
0326 
0327 void Part::openStandardFeedList()
0328 {
0329     if (!m_standardFeedList.isEmpty()) {
0330         openFile(m_standardFeedList);
0331     }
0332 }
0333 
0334 void Part::openFile(const QString &filePath)
0335 {
0336     if (m_loadFeedListCommand || m_standardListLoaded) {
0337         return;
0338     }
0339     std::unique_ptr<LoadFeedListCommand> cmd(new LoadFeedListCommand(m_mainWidget));
0340     cmd->setParentWidget(m_mainWidget);
0341     cmd->setStorage(Kernel::self()->storage());
0342     cmd->setFileName(filePath);
0343     cmd->setDefaultFeedList(createDefaultFeedList());
0344     connect(cmd.get(), &LoadFeedListCommand::result, this, &Part::feedListLoaded);
0345     m_loadFeedListCommand = cmd.release();
0346     m_loadFeedListCommand->start();
0347 }
0348 
0349 bool Part::writeToTextFile(const QString &data, const QString &filename) const
0350 {
0351     QSaveFile file(filename);
0352     if (!file.open(QIODevice::WriteOnly)) {
0353         return false;
0354     }
0355     QTextStream stream(&file);
0356     stream << data << Qt::endl;
0357     return file.commit();
0358 }
0359 
0360 void Part::feedListLoaded(const QSharedPointer<FeedList> &list)
0361 {
0362     Q_ASSERT(!m_standardListLoaded);
0363     if (!m_mainWidget) {
0364         return;
0365     }
0366 
0367     m_mainWidget->setFeedList(list);
0368     m_standardListLoaded = list != nullptr;
0369 
0370     if (Settings::markAllFeedsReadOnStartup()) {
0371         m_mainWidget->slotMarkAllFeedsRead();
0372     }
0373 
0374     if (m_standardListLoaded) {
0375         QTimer::singleShot(0, this, &Part::flushAddFeedRequests);
0376     }
0377 
0378     if (Settings::fetchOnStartup()) {
0379         m_mainWidget->slotFetchAllFeeds();
0380     }
0381 }
0382 
0383 void Part::flushAddFeedRequests()
0384 {
0385     if (!m_mainWidget) {
0386         return;
0387     }
0388 
0389     for (const AddFeedRequest &i : std::as_const(m_requests)) {
0390         for (const QString &j : std::as_const(i.urls)) {
0391             m_mainWidget->addFeedToGroup(j, i.group);
0392         }
0393         NotificationManager::self()->slotNotifyFeeds(i.urls);
0394     }
0395     m_requests.clear();
0396 }
0397 
0398 void Part::slotSaveFeedList()
0399 {
0400     // don't save to the standard feed list, when it wasn't completely loaded before
0401     if (!m_standardListLoaded) {
0402         return;
0403     }
0404 
0405     // the first time we overwrite the feed list, we create a backup
0406     if (!m_backedUpList) {
0407         const QString backup = m_standardFeedList + QLatin1Char('~');
0408         if (QFile::exists(backup)) {
0409             QFile::remove(backup);
0410         }
0411         if (QFile::copy(m_standardFeedList, backup)) {
0412             m_backedUpList = true;
0413         }
0414     }
0415 
0416     const QString xml = m_mainWidget->feedListToOPML().toString();
0417     if (xml.isEmpty()) {
0418         return;
0419     }
0420 
0421     m_storage->storeFeedList(xml);
0422     if (writeToTextFile(xml, m_standardFeedList)) {
0423         return;
0424     }
0425 
0426     KMessageBox::error(m_mainWidget,
0427                        i18n("Access denied: Cannot save feed list to <b>%1</b>. Please check your permissions.", m_standardFeedList),
0428                        i18n("Write Error"));
0429 }
0430 
0431 bool Part::isTrayIconEnabled() const
0432 {
0433     return Settings::showTrayIcon();
0434 }
0435 
0436 void Part::importFile(const QUrl &url)
0437 {
0438     QString filename;
0439     QTemporaryFile tempFile;
0440 
0441     if (url.isLocalFile()) {
0442         filename = url.toLocalFile();
0443     } else {
0444         if (!tempFile.open()) {
0445             return;
0446         }
0447         filename = tempFile.fileName();
0448 
0449         auto job = KIO::file_copy(url, QUrl::fromLocalFile(filename), -1, KIO::Overwrite | KIO::HideProgressInfo);
0450         KJobWidgets::setWindow(job, m_mainWidget);
0451         if (!job->exec()) {
0452             KMessageBox::error(m_mainWidget, job->errorString());
0453             return;
0454         }
0455     }
0456 
0457     QFile file(filename);
0458     if (file.open(QIODevice::ReadOnly)) {
0459         // Read OPML feeds list and build QDom tree.
0460         QDomDocument doc;
0461         if (doc.setContent(file.readAll())) {
0462             m_mainWidget->importFeedList(doc);
0463         } else {
0464             KMessageBox::error(m_mainWidget, i18n("Could not import the file %1 (no valid OPML)", filename), i18nc("@title:window", "OPML Parsing Error"));
0465         }
0466     } else {
0467         KMessageBox::error(m_mainWidget,
0468                            i18n("The file %1 could not be read, check if it exists or if it is readable for the current user.", filename),
0469                            i18nc("@title:window", "Read Error"));
0470     }
0471 }
0472 
0473 void Part::exportFile(const QUrl &url)
0474 {
0475     if (url.isLocalFile()) {
0476         const QString fname = url.toLocalFile();
0477 
0478         if (!writeToTextFile(m_mainWidget->feedListToOPML().toString(), fname)) {
0479             KMessageBox::error(m_mainWidget,
0480                                i18n("Access denied: cannot write to file %1. Please check your permissions.", fname),
0481                                i18nc("@title:window", "Write Error"));
0482         }
0483 
0484         return;
0485     } else {
0486         auto job = KIO::storedPut(m_mainWidget->feedListToOPML().toString().toUtf8(), url, -1);
0487         KJobWidgets::setWindow(job, m_mainWidget);
0488         if (!job->exec()) {
0489             KMessageBox::error(m_mainWidget, job->errorString());
0490         }
0491     }
0492 }
0493 
0494 void Part::fileImport()
0495 {
0496     const QString filters = i18n("OPML Outlines (%1);;All Files (*)", QStringLiteral("*.opml *.xml"));
0497     const QUrl url = QFileDialog::getOpenFileUrl(m_mainWidget, QString(), QUrl(), filters);
0498     if (!url.isEmpty()) {
0499         importFile(url);
0500     }
0501 }
0502 
0503 void Part::fileExport()
0504 {
0505     const QString filters = i18n("OPML Outlines (%1);;All Files (*)", QStringLiteral("*.opml *.xml"));
0506     const QUrl url = QFileDialog::getSaveFileUrl(m_mainWidget, QString(), QUrl(), filters);
0507 
0508     if (!url.isEmpty()) {
0509         exportFile(url);
0510     }
0511 }
0512 
0513 void Part::fetchAllFeeds()
0514 {
0515     m_mainWidget->slotFetchAllFeeds();
0516 }
0517 
0518 void Part::fetchFeedUrl(const QString &s)
0519 {
0520     qCDebug(AKREGATOR_LOG) << "fetchFeedURL==" << s;
0521 }
0522 
0523 void Part::addFeedsToGroup(const QStringList &urls, const QString &group)
0524 {
0525     AddFeedRequest req;
0526     req.group = group;
0527     req.urls = urls;
0528     m_requests.append(req);
0529     if (m_standardListLoaded) {
0530         flushAddFeedRequests();
0531     }
0532 }
0533 
0534 void Part::addFeed()
0535 {
0536     m_mainWidget->slotFeedAdd();
0537 }
0538 
0539 void Part::showNotificationOptions()
0540 {
0541     const Akregator::AboutData about;
0542     KNotifyConfigWidget::configure(m_mainWidget, about.productName());
0543 }
0544 
0545 void Part::showOptions()
0546 {
0547     saveSettings();
0548 
0549     if (!m_dialog) {
0550         m_dialog = new KCMultiDialog(m_mainWidget);
0551         connect(m_dialog, &KCMultiDialog::configCommitted, this, &Part::slotSettingsChanged);
0552         if (TrayIcon::getInstance()) {
0553             connect(m_dialog, &KCMultiDialog::configCommitted, TrayIcon::getInstance(), &TrayIcon::settingsChanged);
0554         }
0555         const QList<KPluginMetaData> availablePlugins = KPluginMetaData::findPlugins(QStringLiteral("pim6/kcms/akregator"));
0556         for (const KPluginMetaData &metaData : availablePlugins) {
0557             m_dialog->addModule(metaData);
0558         }
0559     }
0560 
0561     m_dialog->show();
0562     m_dialog->raise();
0563 }
0564 
0565 void Part::initFonts()
0566 {
0567     QStringList fonts = Settings::fonts();
0568     if (fonts.isEmpty()) {
0569         fonts.append(QFontDatabase::systemFont(QFontDatabase::GeneralFont).family());
0570         fonts.append(QFontDatabase::systemFont(QFontDatabase::FixedFont).family());
0571         fonts.append(QFontDatabase::systemFont(QFontDatabase::GeneralFont).family());
0572         fonts.append(QFontDatabase::systemFont(QFontDatabase::GeneralFont).family());
0573         fonts.append(QStringLiteral("0"));
0574     }
0575     Settings::setFonts(fonts);
0576     if (Settings::standardFont().isEmpty()) {
0577         Settings::setStandardFont(fonts[0]);
0578     }
0579     if (Settings::fixedFont().isEmpty()) {
0580         Settings::setFixedFont(fonts[1]);
0581     }
0582     if (Settings::sansSerifFont().isEmpty()) {
0583         Settings::setSansSerifFont(fonts[2]);
0584     }
0585     if (Settings::serifFont().isEmpty()) {
0586         Settings::setSerifFont(fonts[3]);
0587     }
0588 
0589     // TODO add CursiveFont, FantasyFont
0590 
0591     KConfigGroup conf(Settings::self()->config(), QStringLiteral("HTML Settings"));
0592 
0593     KConfig _konq(QStringLiteral("konquerorrc"), KConfig::NoGlobals);
0594     KConfigGroup konq(&_konq, QStringLiteral("HTML Settings"));
0595 
0596     if (!conf.hasKey("MinimumFontSize")) {
0597         int minfs;
0598         if (konq.hasKey("MinimumFontSize")) {
0599             minfs = konq.readEntry("MinimumFontSize", 8);
0600         } else {
0601             minfs = std::max(QFontDatabase::systemFont(QFontDatabase::GeneralFont).pointSize() - 2, 4);
0602         }
0603         Settings::setMinimumFontSize(minfs);
0604     }
0605 
0606     if (!conf.hasKey("MediumFontSize")) {
0607         int medfs;
0608         if (konq.hasKey("MediumFontSize")) {
0609             medfs = konq.readEntry("MediumFontSize", 12);
0610         } else {
0611             medfs = QFontDatabase::systemFont(QFontDatabase::GeneralFont).pointSize();
0612         }
0613         Settings::setMediumFontSize(medfs);
0614     }
0615     QWebEngineProfile::defaultProfile()->settings()->setFontFamily(QWebEngineSettings::StandardFont, Settings::standardFont());
0616     QWebEngineProfile::defaultProfile()->settings()->setFontFamily(QWebEngineSettings::FixedFont, Settings::fixedFont());
0617     QWebEngineProfile::defaultProfile()->settings()->setFontFamily(QWebEngineSettings::SerifFont, Settings::serifFont());
0618     QWebEngineProfile::defaultProfile()->settings()->setFontFamily(QWebEngineSettings::SansSerifFont, Settings::sansSerifFont());
0619     QWebEngineProfile::defaultProfile()->settings()->setFontSize(QWebEngineSettings::MinimumFontSize, Settings::minimumFontSize());
0620     QWebEngineProfile::defaultProfile()->settings()->setFontSize(QWebEngineSettings::DefaultFontSize, Settings::mediumFontSize());
0621 }
0622 
0623 bool Part::handleCommandLine(const QStringList &args)
0624 {
0625     QCommandLineParser parser;
0626     akregator_options(&parser);
0627     parser.process(args);
0628 
0629     const QString addFeedGroup = parser.isSet(QStringLiteral("group")) ? parser.value(QStringLiteral("group")) : i18n("Imported Folder");
0630 
0631     QStringList feedsToAdd = parser.values(QStringLiteral("addfeed"));
0632 
0633     if (feedsToAdd.isEmpty() && !parser.positionalArguments().isEmpty()) {
0634         const auto positionalArguments = parser.positionalArguments();
0635         for (QString url : positionalArguments) {
0636             const QUrl tempUrl = QUrl::fromUserInput(url);
0637             if (tempUrl.isLocalFile()) {
0638                 const QString tempLocalFile = tempUrl.toLocalFile();
0639                 if (tempLocalFile.startsWith(QDir::tempPath())) {
0640                     const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/akregator/data/");
0641                     QDir().mkpath(path);
0642                     QFile f(tempLocalFile);
0643                     const QString newRssFileName = path + QFileInfo(f).fileName();
0644                     if (!f.copy(newRssFileName)) {
0645                         qCWarning(AKREGATOR_LOG) << "Impossible to copy in local folder" << newRssFileName;
0646                     } else {
0647                         url = newRssFileName;
0648                     }
0649                 }
0650             }
0651 
0652             feedsToAdd.append(url);
0653         }
0654     }
0655 
0656     if (!feedsToAdd.isEmpty()) {
0657         addFeedsToGroup(feedsToAdd, addFeedGroup);
0658     }
0659     return true;
0660 }
0661 
0662 void Part::clearCrashProperties()
0663 {
0664     if (!m_doCrashSave) {
0665         return;
0666     }
0667     KConfig config(QStringLiteral("crashed"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation);
0668     KConfigGroup configGroup(&config, QStringLiteral("Part"));
0669     configGroup.writeEntry("crashed", false);
0670 }
0671 
0672 void Part::saveCrashProperties()
0673 {
0674     if (!m_doCrashSave) {
0675         return;
0676     }
0677     KConfig config(QStringLiteral("crashed"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation);
0678     KConfigGroup configGroup(&config, QStringLiteral("Part"));
0679     configGroup.deleteGroup();
0680 
0681     configGroup.writeEntry("crashed", true);
0682 
0683     saveProperties(configGroup);
0684 }
0685 
0686 void Part::slotAutoSave()
0687 {
0688     saveCrashProperties();
0689 }
0690 
0691 void Part::autoSaveProperties()
0692 {
0693     KConfig config(QStringLiteral("autosaved"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation);
0694     KConfigGroup configGroup(&config, QStringLiteral("Part"));
0695     configGroup.deleteGroup();
0696 
0697     saveProperties(configGroup);
0698 
0699     clearCrashProperties();
0700 }
0701 
0702 void Part::autoReadProperties()
0703 {
0704     if (qGuiApp->isSessionRestored()) {
0705         return;
0706     }
0707     KConfig config(QStringLiteral("autosaved"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation);
0708     KConfigGroup configGroup(&config, QStringLiteral("Part"));
0709 
0710     readProperties(configGroup);
0711 }
0712 
0713 void Part::slotRestoreSession(Akregator::CrashWidget::CrashAction type)
0714 {
0715     switch (type) {
0716     case Akregator::CrashWidget::RestoreSession: {
0717         KConfig config(QStringLiteral("crashed"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation);
0718         KConfigGroup configGroup(&config, QStringLiteral("Part"));
0719         readProperties(configGroup);
0720         clearCrashProperties();
0721         break;
0722     }
0723     case Akregator::CrashWidget::NotRestoreSession:
0724         clearCrashProperties();
0725         break;
0726     case Akregator::CrashWidget::AskMeLater:
0727         break;
0728     }
0729     m_doCrashSave = true;
0730 }
0731 } // namespace Akregator
0732 #include "akregator_part.moc"
0733 
0734 #include "moc_akregator_part.cpp"