2 This file is part of Akregator.
4 Copyright (C) 2004 Stanislav Karchebny <Stanislav.Karchebny@kdemail.net>
5 2005 Frank Osterfeld <osterfeld@kde.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 As a special exception, permission is given to link this program
22 with any edition of Qt, and distribute the resulting executable,
23 without including the source code for Qt in the source distribution.
26 #include "akregator_part.h"
27 #include "akregator_debug.h"
28 #include "config-akregator.h"
29 #include "messageviewer/messageviewersettings.h"
30 #include "akregatorconfig.h"
31 #include "aboutdata.h"
32 #include "actionmanagerimpl.h"
34 #include "fetchqueue.h"
36 #include "framemanager.h"
38 #include "loadfeedlistcommand.h"
39 #include "mainwidget.h"
40 #include "notificationmanager.h"
42 #include "pluginmanager.h"
44 #include "storagefactory.h"
45 #include "storagefactoryregistry.h"
47 #include "widgets/akregatorcentralwidget.h"
48 #include "dummystorage/storagefactorydummyimpl.h"
50 #include "akregator_options.h"
51 #include <Libkdepim/BroadcastStatus>
52 #include "akregator-version.h"
53 #include <kio/filecopyjob.h>
54 #include <knotifyconfigwidget.h>
55 #include <kaboutdata.h>
57 #include <kconfigdialog.h>
58 #include <qfiledialog.h>
59 #include <kmessagebox.h>
61 #include <QTemporaryFile>
62 #include <QWebEngineSettings>
65 #include <kxmlguifactory.h>
66 #include <KIO/StoredTransferJob>
67 #include <KJobWidgets>
68 #include <KPluginFactory>
69 #include <KParts/Plugin>
70 #include <KCMultiDialog>
71 #include <kstandardaction.h>
73 #include <QApplication>
76 #include <QStringList>
77 #include <QTextStream>
80 #include <QDomDocument>
81 #include "akregratormigrateapplication.h"
82 #include "partadaptor.h"
85 #include <QFontDatabase>
86 #include <QStandardPaths>
91 static QDomDocument
createDefaultFeedList()
94 QDomProcessingInstruction z
= doc
.createProcessingInstruction(QStringLiteral("xml"), QStringLiteral("version=\"1.0\" encoding=\"UTF-8\""));
97 QDomElement root
= doc
.createElement(QStringLiteral("opml"));
98 root
.setAttribute(QStringLiteral("version"), QStringLiteral("1.0"));
99 doc
.appendChild(root
);
101 QDomElement head
= doc
.createElement(QStringLiteral("head"));
102 root
.appendChild(head
);
104 QDomElement text
= doc
.createElement(QStringLiteral("text"));
105 text
.appendChild(doc
.createTextNode(i18n("Feeds")));
106 head
.appendChild(text
);
108 QDomElement body
= doc
.createElement(QStringLiteral("body"));
109 root
.appendChild(body
);
111 QDomElement mainFolder
= doc
.createElement(QStringLiteral("outline"));
112 mainFolder
.setAttribute(QStringLiteral("text"), QStringLiteral("KDE"));
113 body
.appendChild(mainFolder
);
115 QDomElement dot
= doc
.createElement(QStringLiteral("outline"));
116 dot
.setAttribute(QStringLiteral("text"), i18n("KDE Dot News"));
117 dot
.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("http://www.kde.org/dotkdeorg.rdf"));
118 mainFolder
.appendChild(dot
);
120 QDomElement linuxFeeds
= doc
.createElement(QStringLiteral("outline"));
121 linuxFeeds
.setAttribute(QStringLiteral("text"), i18n("Linux.com"));
122 linuxFeeds
.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://www.linux.com/rss/feeds.php"));
123 mainFolder
.appendChild(linuxFeeds
);
125 QDomElement planetkde
= doc
.createElement(QStringLiteral("outline"));
126 planetkde
.setAttribute(QStringLiteral("text"), i18n("Planet KDE"));
127 planetkde
.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("http://planetkde.org/rss20.xml"));
128 mainFolder
.appendChild(planetkde
);
130 QDomElement planetkdepim
= doc
.createElement(QStringLiteral("outline"));
131 planetkdepim
.setAttribute(QStringLiteral("text"), i18n("Planet KDE PIM"));
132 planetkdepim
.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("http://pim.planetkde.org/rss20.xml"));
133 mainFolder
.appendChild(planetkdepim
);
135 QDomElement apps
= doc
.createElement(QStringLiteral("outline"));
136 apps
.setAttribute(QStringLiteral("text"), i18n("KDE Apps"));
137 apps
.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("http://www.kde.org/dot/kde-apps-content.rdf"));
138 mainFolder
.appendChild(apps
);
140 QDomElement look
= doc
.createElement(QStringLiteral("outline"));
141 look
.setAttribute(QStringLiteral("text"), i18n("KDE Look"));
142 look
.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("http://www.kde.org/kde-look-content.rdf"));
143 mainFolder
.appendChild(look
);
147 QDomElement hungarianFolder
= doc
.createElement(QStringLiteral("outline"));
148 hungarianFolder
.setAttribute(QStringLiteral("text"), i18n("Hungarian feeds"));
149 mainFolder
.appendChild(hungarianFolder
);
151 QDomElement hungarianKde
= doc
.createElement(QStringLiteral("outline"));
152 hungarianKde
.setAttribute(QStringLiteral("text"), i18n("KDE.HU"));
153 hungarianKde
.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("http://kde.hu/rss.xml"));
154 hungarianFolder
.appendChild(hungarianKde
);
156 // Brazilian Portuguese feeds
157 QDomElement portugueuseFolder
= doc
.createElement(QStringLiteral("outline"));
158 portugueuseFolder
.setAttribute(QStringLiteral("text"), i18n("Brazilian Portuguese feeds"));
159 mainFolder
.appendChild(portugueuseFolder
);
161 QDomElement portugueuseKde
= doc
.createElement(QStringLiteral("outline"));
162 portugueuseKde
.setAttribute(QStringLiteral("text"), i18n("Planet KDE Brazilian Portuguese"));
163 portugueuseKde
.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("http://planetkde.org/pt-br/rss20.xml"));
164 portugueuseFolder
.appendChild(portugueuseKde
);
167 QDomElement spanishFolder
= doc
.createElement(QStringLiteral("outline"));
168 spanishFolder
.setAttribute(QStringLiteral("text"), i18n("Spanish feeds"));
169 mainFolder
.appendChild(spanishFolder
);
171 QDomElement spanishKde
= doc
.createElement(QStringLiteral("outline"));
172 spanishKde
.setAttribute(QStringLiteral("text"), i18n("Planet KDE EspaƱa"));
173 spanishKde
.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("http://planet.kde-espana.org/atom.xml"));
174 spanishFolder
.appendChild(spanishKde
);
177 QDomElement frenchFolder
= doc
.createElement(QStringLiteral("outline"));
178 frenchFolder
.setAttribute(QStringLiteral("text"), i18n("French feeds"));
179 mainFolder
.appendChild(frenchFolder
);
181 QDomElement frenchKde
= doc
.createElement(QStringLiteral("outline"));
182 frenchKde
.setAttribute(QStringLiteral("text"), i18n("Planet KDE France"));
183 frenchKde
.setAttribute(QStringLiteral("xmlUrl"), QStringLiteral("https://fr.planetkde.org/rss20.xml"));
184 frenchFolder
.appendChild(frenchKde
);
193 K_PLUGIN_FACTORY(AkregatorFactory
, registerPlugin
<Part
>();)
195 static Part
*mySelf
= Q_NULLPTR
;
196 BrowserExtension::BrowserExtension(Part
*p
, const char *name
)
197 : KParts::BrowserExtension(p
)
199 AkregratorMigrateApplication migrate
;
201 setObjectName(QLatin1String(name
));
205 void BrowserExtension::saveSettings()
207 m_part
->saveSettings();
210 Part::Part(QWidget
*parentWidget
, QObject
*parent
, const QVariantList
&)
211 : KParts::ReadOnlyPart(parent
)
212 , m_standardListLoaded(false)
213 , m_shuttingDown(false)
214 , m_doCrashSave(false)
215 , m_backedUpList(false)
222 //Make sure to initialize settings
226 setPluginLoadingMode(LoadPluginsIfEnabled
);
227 setPluginInterfaceVersion(AKREGATOR_PLUGIN_INTERFACE_VERSION
);
229 setComponentName(QStringLiteral("akregator"), QStringLiteral("akregator"));
230 setXMLFile(QStringLiteral("akregator_part.rc"), true);
232 new PartAdaptor(this);
233 QDBusConnection::sessionBus().registerObject(QStringLiteral("/Akregator"), this);
235 m_standardFeedList
= QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation
) + QStringLiteral("/akregator/data/feeds.opml");
236 QFileInfo
fileInfo(m_standardFeedList
);
237 QDir().mkpath(fileInfo
.absolutePath());
239 Backend::StorageFactoryDummyImpl
*dummyFactory
= new Backend::StorageFactoryDummyImpl();
240 if (!Backend::StorageFactoryRegistry::self()->registerFactory(dummyFactory
, dummyFactory
->key())) {
241 // There was already a dummy factory registered.
244 loadPlugins(QStringLiteral("storage")); // FIXME: also unload them!
247 Backend::StorageFactory
*storageFactory
= Backend::StorageFactoryRegistry::self()->getFactory(Settings::archiveBackend());
248 if (storageFactory
!= 0) {
249 m_storage
= storageFactory
->createStorage(QStringList());
252 if (!m_storage
) { // Houston, we have a problem
253 m_storage
= Backend::StorageFactoryRegistry::self()->getFactory(QStringLiteral("dummy"))->createStorage(QStringList());
255 KMessageBox::error(parentWidget
, i18n("Unable to load storage backend plugin \"%1\". No feeds are archived.", Settings::archiveBackend()), i18n("Plugin error"));
258 m_storage
->open(true);
259 Kernel::self()->setStorage(m_storage
);
261 m_actionManager
= new ActionManagerImpl(this);
262 ActionManager::setInstance(m_actionManager
);
264 mCentralWidget
= new Akregator::AkregatorCentralWidget(parentWidget
);
265 connect(mCentralWidget
, &AkregatorCentralWidget::restoreSession
, this, &Part::slotRestoreSession
);
266 m_mainWidget
= new Akregator::MainWidget(this, parentWidget
, m_actionManager
, "akregator_view");
267 mCentralWidget
->setMainWidget(m_mainWidget
);
268 m_extension
= new BrowserExtension(this, "ak_extension");
270 connect(Kernel::self()->frameManager(), &FrameManager::signalCaptionChanged
, this, &Part::setWindowCaption
);
271 connect(Kernel::self()->frameManager(), &FrameManager::signalStatusText
, this, &Part::slotSetStatusText
);
272 connect(Kernel::self()->frameManager(), &FrameManager::signalLoadingProgress
, m_extension
, &BrowserExtension::loadingProgress
);
273 connect(Kernel::self()->frameManager(), &FrameManager::signalCanceled
, this, &ReadOnlyPart::canceled
);
274 connect(Kernel::self()->frameManager(), &FrameManager::signalStarted
, this, &Part::slotStarted
);
275 connect(Kernel::self()->frameManager(), SIGNAL(signalCompleted()), this, SIGNAL(completed()));
277 // notify the part that this is our internal widget
278 setWidget(mCentralWidget
);
280 if (Settings::showTrayIcon() && !TrayIcon::getInstance()) {
281 TrayIcon
*trayIcon
= new TrayIcon(m_mainWidget
->window());
282 TrayIcon::setInstance(trayIcon
);
283 m_actionManager
->setTrayIcon(trayIcon
);
285 if (isTrayIconEnabled()) {
286 trayIcon
->setStatus(KStatusNotifierItem::Active
);
289 QWidget
*const notificationParent
= isTrayIconEnabled() ? m_mainWidget
->window() : Q_NULLPTR
;
290 NotificationManager::self()->setWidget(notificationParent
, componentData().componentName());
292 connect(m_mainWidget
.data(), &MainWidget::signalUnreadCountChanged
, trayIcon
, &TrayIcon::slotSetUnread
);
293 connect(m_mainWidget
.data(), &MainWidget::signalArticlesSelected
,
294 this, &Part::signalArticlesSelected
);
297 connect(qApp
, &QCoreApplication::aboutToQuit
, this, &Part::slotOnShutdown
);
299 m_autosaveTimer
= new QTimer(this);
300 connect(m_autosaveTimer
, &QTimer::timeout
, this, &Part::slotSaveFeedList
);
301 m_autosaveTimer
->start(5 * 60 * 1000); // 5 minutes
303 QString useragent
= QStringLiteral("Akregator/%1; syndication").arg(QStringLiteral(AKREGATOR_VERSION
));
305 if (!Settings::customUserAgent().isEmpty()) {
306 useragent
= Settings::customUserAgent();
309 Syndication::FileRetriever::setUserAgent(useragent
);
311 loadPlugins(QStringLiteral("extension")); // FIXME: also unload them!
312 if (mCentralWidget
->previousSessionCrashed()) {
313 mCentralWidget
->needToRestoreCrashedSession();
315 m_doCrashSave
= true;
316 autoReadProperties();
320 KSharedConfig::Ptr
Part::config()
323 if (!mySelf
->mConfig
) {
324 mySelf
->mConfig
= KSharedConfig::openConfig(QStringLiteral("akregatorrc"));
325 MessageViewer::MessageViewerSettings::self()->setSharedConfig(mySelf
->mConfig
);
326 MessageViewer::MessageViewerSettings::self()->load();
328 return mySelf
->mConfig
;
331 void Part::updateQuickSearchLineText()
334 m_mainWidget
->updateQuickSearchLineText();
338 void Part::loadPlugins(const QString
&type
)
340 const KService::List offers
= PluginManager::query(QStringLiteral("[X-KDE-akregator-plugintype] == '%1'").arg(type
));
342 Q_FOREACH (const KService::Ptr
&i
, offers
) {
343 Akregator::Plugin
*plugin
= PluginManager::createFromService(i
, this);
347 plugin
->initialize();
348 plugin
->insertGuiClients(this);
352 void Part::slotStarted()
354 Q_EMIT
started(Q_NULLPTR
);
357 void Part::slotOnShutdown()
359 autoSaveProperties();
360 m_shuttingDown
= true;
361 m_autosaveTimer
->stop();
365 m_mainWidget
->slotOnShutdown();
367 //delete m_mainWidget;
368 delete TrayIcon::getInstance();
369 TrayIcon::setInstance(Q_NULLPTR
);
372 //delete m_actionManager;
375 void Part::slotSettingsChanged()
377 NotificationManager::self()->setWidget(isTrayIconEnabled() ? m_mainWidget
->window() : 0, componentData().componentName());
379 if (Settings::showTrayIcon() && !TrayIcon::getInstance()) {
380 TrayIcon
*trayIcon
= new TrayIcon(m_mainWidget
->window());
381 TrayIcon::setInstance(trayIcon
);
382 m_actionManager
->setTrayIcon(trayIcon
);
384 if (isTrayIconEnabled()) {
385 trayIcon
->setStatus(KStatusNotifierItem::Active
);
388 connect(m_mainWidget
.data(), &MainWidget::signalUnreadCountChanged
, trayIcon
, &TrayIcon::slotSetUnread
);
389 connect(m_mainWidget
.data(), &MainWidget::signalArticlesSelected
,
390 this, &Part::signalArticlesSelected
);
392 m_mainWidget
->slotSetTotalUnread();
394 if (!Settings::showTrayIcon()) {
395 TrayIcon::getInstance()->disconnect();
396 delete TrayIcon::getInstance();
397 TrayIcon::setInstance(0);
398 m_actionManager
->setTrayIcon(0);
401 Syndication::FileRetriever::setUseCache(Settings::useHTMLCache());
404 fonts
.append(Settings::standardFont());
405 fonts
.append(Settings::fixedFont());
406 fonts
.append(Settings::sansSerifFont());
407 fonts
.append(Settings::serifFont());
408 fonts
.append(Settings::standardFont());
409 fonts
.append(Settings::standardFont());
410 fonts
.append(QStringLiteral("0"));
411 Settings::setFonts(fonts
);
413 if (Settings::minimumFontSize() > Settings::mediumFontSize()) {
414 Settings::setMediumFontSize(Settings::minimumFontSize());
417 Q_EMIT
signalSettingsChanged();
420 void Part::slotSetStatusText(const QString
&statusText
)
422 KPIM::BroadcastStatus::instance()->setStatusMsg(statusText
);
425 void Part::saveSettings()
427 m_mainWidget
->saveSettings();
432 disconnect(qApp
, &QCoreApplication::aboutToQuit
, this, &Part::slotOnShutdown
);
433 qCDebug(AKREGATOR_LOG
) << "Part::~Part() enter";
434 // If the widget is destroyed for some reason, KParts::Part will set its
435 // widget property to 0 and then delete itself (and therefore this object).
436 // In this case, it's not safe to do our normal shutdown routine.
437 if (widget() && !m_shuttingDown
) {
440 qCDebug(AKREGATOR_LOG
) << "Part::~Part(): leaving";
443 void Part::readProperties(const KConfigGroup
&config
)
445 m_backedUpList
= false;
446 openStandardFeedList();
449 m_mainWidget
->readProperties(config
);
453 void Part::saveProperties(KConfigGroup
&config
)
457 m_mainWidget
->saveProperties(config
);
461 bool Part::openUrl(const QUrl
&url
)
463 setLocalFilePath(url
.toLocalFile());
467 void Part::openStandardFeedList()
469 if (!m_standardFeedList
.isEmpty()) {
470 openUrl(QUrl::fromLocalFile(m_standardFeedList
));
474 bool Part::openFile()
476 if (m_loadFeedListCommand
|| m_standardListLoaded
) {
479 QScopedPointer
<LoadFeedListCommand
> cmd(new LoadFeedListCommand(m_mainWidget
));
480 cmd
->setParentWidget(m_mainWidget
);
481 cmd
->setStorage(Kernel::self()->storage());
482 cmd
->setFileName(localFilePath());
483 cmd
->setDefaultFeedList(createDefaultFeedList());
484 connect(cmd
.data(), &LoadFeedListCommand::result
,
485 this, &Part::feedListLoaded
);
486 m_loadFeedListCommand
= cmd
.take();
487 m_loadFeedListCommand
->start();
491 bool Part::writeToTextFile(const QString
&data
, const QString
&filename
) const
493 QSaveFile
file(filename
);
494 if (!file
.open(QIODevice::WriteOnly
)) {
497 QTextStream
stream(&file
);
498 stream
.setCodec("UTF-8");
499 stream
<< data
<< endl
;
500 return file
.commit();
503 void Part::feedListLoaded(const QSharedPointer
<FeedList
> &list
)
505 Q_ASSERT(!m_standardListLoaded
);
506 m_mainWidget
->setFeedList(list
);
507 m_standardListLoaded
= list
!= 0;
509 if (Settings::markAllFeedsReadOnStartup()) {
510 m_mainWidget
->slotMarkAllFeedsRead();
513 if (m_standardListLoaded
) {
514 QTimer::singleShot(0, this, &Part::flushAddFeedRequests
);
517 if (Settings::fetchOnStartup()) {
518 m_mainWidget
->slotFetchAllFeeds();
522 void Part::flushAddFeedRequests()
524 Q_FOREACH (const AddFeedRequest
&i
, m_requests
) {
525 Q_FOREACH (const QString
&j
, i
.urls
) {
526 m_mainWidget
->addFeedToGroup(j
, i
.group
);
528 NotificationManager::self()->slotNotifyFeeds(i
.urls
);
533 void Part::slotSaveFeedList()
535 // don't save to the standard feed list, when it wasn't completely loaded before
536 if (!m_standardListLoaded
) {
540 // the first time we overwrite the feed list, we create a backup
541 if (!m_backedUpList
) {
542 const QString backup
= localFilePath() + QStringLiteral("~");
543 if (QFile::copy(localFilePath(), backup
)) {
544 m_backedUpList
= true;
548 const QString xml
= m_mainWidget
->feedListToOPML().toString();
549 m_storage
->storeFeedList(xml
);
550 if (writeToTextFile(xml
, localFilePath())) {
554 KMessageBox::error(m_mainWidget
,
555 i18n("Access denied: Cannot save feed list to <b>%1</b>. Please check your permissions.", localFilePath()),
556 i18n("Write Error"));
559 bool Part::isTrayIconEnabled() const
561 return Settings::showTrayIcon();
564 void Part::importFile(const QUrl
&url
)
567 QTemporaryFile tempFile
;
569 if (url
.isLocalFile()) {
570 filename
= url
.toLocalFile();
572 if (!tempFile
.open()) {
575 filename
= tempFile
.fileName();
577 auto job
= KIO::file_copy(url
, QUrl::fromLocalFile(filename
), -1, KIO::Overwrite
| KIO::HideProgressInfo
);
578 KJobWidgets::setWindow(job
, m_mainWidget
);
580 KMessageBox::error(m_mainWidget
, job
->errorString());
585 QFile
file(filename
);
586 if (file
.open(QIODevice::ReadOnly
)) {
587 // Read OPML feeds list and build QDom tree.
589 if (doc
.setContent(file
.readAll())) {
590 m_mainWidget
->importFeedList(doc
);
592 KMessageBox::error(m_mainWidget
, i18n("Could not import the file %1 (no valid OPML)", filename
), i18n("OPML Parsing Error"));
595 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"));
599 void Part::exportFile(const QUrl
&url
)
601 if (url
.isLocalFile()) {
602 const QString fname
= url
.toLocalFile();
604 if (QFile::exists(fname
) &&
605 KMessageBox::questionYesNo(m_mainWidget
,
606 i18n("The file %1 already exists; do you want to overwrite it?", fname
),
608 KStandardGuiItem::overwrite(),
609 KStandardGuiItem::cancel()) == KMessageBox::No
) {
613 if (!writeToTextFile(m_mainWidget
->feedListToOPML().toString(), fname
)) {
614 KMessageBox::error(m_mainWidget
, i18n("Access denied: cannot write to file %1. Please check your permissions.", fname
), i18n("Write Error"));
619 auto job
= KIO::storedPut(m_mainWidget
->feedListToOPML().toString().toUtf8(), url
, -1);
620 KJobWidgets::setWindow(job
, m_mainWidget
);
622 KMessageBox::error(m_mainWidget
, job
->errorString());
627 void Part::fileImport()
629 const QString filters
= i18n("OPML Outlines (*.opml *.xml);;All Files (*)");
630 const QUrl url
= QFileDialog::getOpenFileUrl(m_mainWidget
, QString(), QUrl(), filters
);
631 if (!url
.isEmpty()) {
636 void Part::fileExport()
638 const QString filters
= i18n("OPML Outlines (*.opml *.xml);;All Files (*)");
639 const QUrl url
= QFileDialog::getSaveFileUrl(m_mainWidget
, QString(), QUrl(), filters
);
641 if (!url
.isEmpty()) {
646 void Part::fetchAllFeeds()
648 m_mainWidget
->slotFetchAllFeeds();
651 void Part::fetchFeedUrl(const QString
&s
)
653 qCDebug(AKREGATOR_LOG
) << "fetchFeedURL==" << s
;
656 void Part::addFeedsToGroup(const QStringList
&urls
, const QString
&group
)
661 m_requests
.append(req
);
662 if (m_standardListLoaded
) {
663 flushAddFeedRequests();
669 m_mainWidget
->slotFeedAdd();
672 void Part::showNotificationOptions()
674 const Akregator::AboutData about
;
675 KNotifyConfigWidget::configure(m_mainWidget
, about
.productName());
678 void Part::showOptions()
683 m_dialog
= new KCMultiDialog(m_mainWidget
);
684 connect(m_dialog
, SIGNAL(configCommitted()),
685 this, SLOT(slotSettingsChanged()));
686 connect(m_dialog
, SIGNAL(configCommitted()),
687 TrayIcon::getInstance(), SLOT(settingsChanged()));
689 m_dialog
->addModule(QStringLiteral("akregator_config_general"));
690 m_dialog
->addModule(QStringLiteral("akregator_config_appearance"));
691 m_dialog
->addModule(QStringLiteral("akregator_config_archive"));
692 m_dialog
->addModule(QStringLiteral("akregator_config_browser"));
693 m_dialog
->addModule(QStringLiteral("akregator_config_advanced"));
694 m_dialog
->addModule(QStringLiteral("akregator_config_webengineurlinterceptor"));
701 void Part::initFonts()
703 QStringList fonts
= Settings::fonts();
704 if (fonts
.isEmpty()) {
705 fonts
.append(QFontDatabase::systemFont(QFontDatabase::GeneralFont
).family());
706 fonts
.append(QFontDatabase::systemFont(QFontDatabase::FixedFont
).family());
707 fonts
.append(QFontDatabase::systemFont(QFontDatabase::GeneralFont
).family());
708 fonts
.append(QFontDatabase::systemFont(QFontDatabase::GeneralFont
).family());
709 fonts
.append(QStringLiteral("0"));
711 Settings::setFonts(fonts
);
712 if (Settings::standardFont().isEmpty()) {
713 Settings::setStandardFont(fonts
[0]);
715 if (Settings::fixedFont().isEmpty()) {
716 Settings::setFixedFont(fonts
[1]);
718 if (Settings::sansSerifFont().isEmpty()) {
719 Settings::setSansSerifFont(fonts
[2]);
721 if (Settings::serifFont().isEmpty()) {
722 Settings::setSerifFont(fonts
[3]);
725 //TODO add CursiveFont, FantasyFont
727 KConfigGroup
conf(Settings::self()->config(), "HTML Settings");
729 KConfig
_konq(QStringLiteral("konquerorrc"), KConfig::NoGlobals
);
730 KConfigGroup
konq(&_konq
, "HTML Settings");
732 if (!conf
.hasKey("MinimumFontSize")) {
734 if (konq
.hasKey("MinimumFontSize")) {
735 minfs
= konq
.readEntry("MinimumFontSize", 8);
737 minfs
= std::max(QFontDatabase::systemFont(QFontDatabase::GeneralFont
).pointSize() - 2, 4);
739 Settings::setMinimumFontSize(minfs
);
742 if (!conf
.hasKey("MediumFontSize")) {
744 if (konq
.hasKey("MediumFontSize")) {
745 medfs
= konq
.readEntry("MediumFontSize", 12);
747 medfs
= QFontDatabase::systemFont(QFontDatabase::GeneralFont
).pointSize();
749 Settings::setMediumFontSize(medfs
);
751 QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::StandardFont
, Settings::standardFont());
752 QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::FixedFont
, Settings::fixedFont());
753 QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::SerifFont
, Settings::serifFont());
754 QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::SansSerifFont
, Settings::sansSerifFont());
755 QWebEngineSettings::globalSettings()->setFontSize(QWebEngineSettings::MinimumFontSize
, Settings::minimumFontSize());
756 QWebEngineSettings::globalSettings()->setFontSize(QWebEngineSettings::DefaultFontSize
, Settings::mediumFontSize());
759 bool Part::handleCommandLine(const QStringList
&args
)
761 QCommandLineParser parser
;
762 akregator_options(&parser
);
763 parser
.process(args
);
765 const QString addFeedGroup
= parser
.isSet(QStringLiteral("group"))
766 ? parser
.value(QStringLiteral("group"))
767 : i18n("Imported Folder");
769 QStringList feedsToAdd
= parser
.values(QStringLiteral("addfeed"));
771 if (feedsToAdd
.isEmpty() && !parser
.positionalArguments().isEmpty()) {
772 Q_FOREACH (const QString
&url
, parser
.positionalArguments()) {
773 feedsToAdd
.append(url
);
777 if (!feedsToAdd
.isEmpty()) {
778 addFeedsToGroup(feedsToAdd
, addFeedGroup
);
783 void Part::clearCrashProperties()
785 if (!m_doCrashSave
) {
788 KConfig
config(QStringLiteral("crashed"), KConfig::SimpleConfig
,
789 QStandardPaths::AppDataLocation
);
790 KConfigGroup
configGroup(&config
, "Part");
791 configGroup
.writeEntry("crashed", false);
794 void Part::saveCrashProperties()
796 if (!m_doCrashSave
) {
799 KConfig
config(QStringLiteral("crashed"), KConfig::SimpleConfig
,
800 QStandardPaths::AppDataLocation
);
801 KConfigGroup
configGroup(&config
, "Part");
802 configGroup
.deleteGroup();
804 configGroup
.writeEntry("crashed", true);
806 saveProperties(configGroup
);
809 void Part::slotAutoSave()
811 saveCrashProperties();
814 void Part::autoSaveProperties()
816 KConfig
config(QStringLiteral("autosaved"), KConfig::SimpleConfig
, QStandardPaths::AppDataLocation
);
817 KConfigGroup
configGroup(&config
, "Part");
818 configGroup
.deleteGroup();
820 saveProperties(configGroup
);
822 clearCrashProperties();
825 void Part::autoReadProperties()
827 if (qGuiApp
->isSessionRestored()) {
830 KConfig
config(QStringLiteral("autosaved"), KConfig::SimpleConfig
, QStandardPaths::AppDataLocation
);
831 KConfigGroup
configGroup(&config
, "Part");
833 readProperties(configGroup
);
836 void Part::slotRestoreSession(Akregator::CrashWidget::CrashAction type
)
839 case Akregator::CrashWidget::RestoreSession
: {
840 KConfig
config(QStringLiteral("crashed"), KConfig::SimpleConfig
,
841 QStandardPaths::AppDataLocation
);
842 KConfigGroup
configGroup(&config
, "Part");
843 readProperties(configGroup
);
844 clearCrashProperties();
847 case Akregator::CrashWidget::NotRestoreSession
:
848 clearCrashProperties();
850 case Akregator::CrashWidget::AskMeLater
:
853 m_doCrashSave
= true;
856 } // namespace Akregator
857 #include "akregator_part.moc"