diff --git a/src/core/feedsmodel.cpp b/src/core/feedsmodel.cpp index e5f73fa0f..e5b8f93c4 100755 --- a/src/core/feedsmodel.cpp +++ b/src/core/feedsmodel.cpp @@ -418,11 +418,8 @@ void FeedsModel::loadActivatedServiceAccounts() { QList roots = entry_point->initializeSubtree(this); foreach (ServiceRoot *root, roots) { - if (SystemFactory::isInstanceOf(root)) { - - } - m_rootItem->appendChild(root); + root->start(); } } } diff --git a/src/main.cpp b/src/main.cpp index 6a6c2fcde..9ce0874b6 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -107,27 +107,15 @@ int main(int argc, char *argv[]) { else { qDebug("Showing the main window when the application is starting."); main_window.show(); - - if (qApp->settings()->value(GROUP(General), SETTING(General::FirstRun)).toBool()) { - // This is the first time user runs this application. - qApp->settings()->setValue(GROUP(General), General::FirstRun, false); - - if (MessageBox::show(&main_window, QMessageBox::Question, QObject::tr("Load initial feeds"), - QObject::tr("You started %1 for the first time, now you can load initial set of feeds.").arg(APP_NAME), - QObject::tr("Do you want to load initial set of feeds?"), - QString(), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - qApp->mainForm()->tabWidget()->feedMessageViewer()->loadInitialFeeds(); - } - } } // Display tray icon if it is enabled and available. if (SystemTrayIcon::isSystemTrayActivated()) { qApp->showTrayIcon(); + } - if (qApp->settings()->value(GROUP(General), SETTING(General::UpdateOnStartup)).toBool()) { - QTimer::singleShot(STARTUP_UPDATE_DELAY, application.system(), SLOT(checkForUpdatesOnStartup())); - } + if (qApp->settings()->value(GROUP(General), SETTING(General::UpdateOnStartup)).toBool()) { + QTimer::singleShot(STARTUP_UPDATE_DELAY, application.system(), SLOT(checkForUpdatesOnStartup())); } // Setup single-instance behavior. diff --git a/src/miscellaneous/application.cpp b/src/miscellaneous/application.cpp index e4f7190ca..b47449d5b 100755 --- a/src/miscellaneous/application.cpp +++ b/src/miscellaneous/application.cpp @@ -28,6 +28,7 @@ #include "exceptions/applicationexception.h" #include "adblock/adblockmanager.h" +#include "services/abstract/serviceroot.h" #include "services/standard/standardserviceentrypoint.h" #include "services/tt-rss/ttrssserviceentrypoint.h" @@ -70,6 +71,22 @@ QList Application::userActions() { return m_userActions; } +bool Application::isFirstRun() { + return settings()->value(GROUP(General), SETTING(General::FirstRun)).toBool(); +} + +bool Application::isFirstRun(const QString &version) { + return settings()->value(GROUP(General), QString(General::FirstRun) + QL1C('_') + version, true).toBool(); +} + +void Application::eliminateFirstRun() { + settings()->setValue(GROUP(General), General::FirstRun, false); +} + +void Application::eliminateFirstRun(const QString &version) { + settings()->setValue(GROUP(General), QString(General::FirstRun) + QL1C('_') + version, false); +} + IconFactory *Application::icons() { if (m_icons == NULL) { m_icons = new IconFactory(this); @@ -216,6 +233,9 @@ void Application::onSaveState(QSessionManager &manager) { } void Application::onAboutToQuit() { + eliminateFirstRun(); + eliminateFirstRun(APP_VERSION); + // Make sure that we obtain close lock BEFORE even trying to quit the application. bool locked_safely = feedUpdateLock()->tryLock(4 * CLOSE_LOCK_TIMEOUT); @@ -264,14 +284,6 @@ void Application::onAboutToQuit() { } } -bool Application::shouldRestart() const { - return m_shouldRestart; -} - -void Application::setShouldRestart(bool shouldRestart) { - m_shouldRestart = shouldRestart; -} - void Application::restart() { m_shouldRestart = true; quit(); diff --git a/src/miscellaneous/application.h b/src/miscellaneous/application.h index c9aa87cb5..7899cec46 100755 --- a/src/miscellaneous/application.h +++ b/src/miscellaneous/application.h @@ -59,8 +59,15 @@ class Application : public QtSingleApplication { // "standard" service entry point. QList feedServices(); + // Globally accessible actions. QList userActions(); + // Check whether this application starts for the first time (ever). + bool isFirstRun(); + + // Check whether GIVEN VERSION of the application starts for the first time. + bool isFirstRun(const QString &version); + inline SystemFactory *system() { if (m_system == NULL) { m_system = new SystemFactory(this); @@ -159,10 +166,8 @@ class Application : public QtSingleApplication { return static_cast(QCoreApplication::instance()); } - bool shouldRestart() const; - void setShouldRestart(bool shouldRestart); - public slots: + // Restarts the application. void restart(); // Processes incoming message from another RSS Guard instance. @@ -175,6 +180,9 @@ class Application : public QtSingleApplication { void onAboutToQuit(); private: + void eliminateFirstRun(); + void eliminateFirstRun(const QString &version); + // This read-write lock is used by application on its close. // Application locks this lock for WRITING. // This means that if application locks that lock, then diff --git a/src/miscellaneous/systemfactory.cpp b/src/miscellaneous/systemfactory.cpp index 1e80fa486..ea424ef60 100755 --- a/src/miscellaneous/systemfactory.cpp +++ b/src/miscellaneous/systemfactory.cpp @@ -272,6 +272,6 @@ void SystemFactory::checkForUpdatesOnStartup() { qApp->showGuiMessage(tr("New version available"), tr("Click the bubble for more information."), QSystemTrayIcon::Information, - NULL, false, QIcon(), qApp->mainForm(), SLOT(showUpdates())); + NULL, true, QIcon(), qApp->mainForm(), SLOT(showUpdates())); } } diff --git a/src/services/abstract/serviceroot.cpp b/src/services/abstract/serviceroot.cpp index 994dbdaa9..516331c7d 100755 --- a/src/services/abstract/serviceroot.cpp +++ b/src/services/abstract/serviceroot.cpp @@ -26,3 +26,7 @@ ServiceRoot::ServiceRoot(FeedsModel *feeds_model, RootItem *parent) : RootItem(p ServiceRoot::~ServiceRoot() { } + +FeedsModel *ServiceRoot::feedsModel() const { + return m_feedsModel; +} diff --git a/src/services/abstract/serviceroot.h b/src/services/abstract/serviceroot.h index a8471eea3..08ecd307d 100755 --- a/src/services/abstract/serviceroot.h +++ b/src/services/abstract/serviceroot.h @@ -47,11 +47,18 @@ class ServiceRoot : public RootItem { // NOTE: Caller does NOT take ownership of created menu! virtual QList serviceMenu() = 0; - inline FeedsModel *feedsModel() const { - return m_feedsModel; - } + // Start/stop services. + // Start method is called when feed model gets initialized OR after user adds new service. + // + // Stop method is called just before application exits OR when + // user explicitly deletes existing service instance. + virtual void start() = 0; + virtual void stop() = 0; - protected: + // Access to feed model. + FeedsModel *feedsModel() const; + + private: FeedsModel *m_feedsModel; }; diff --git a/src/services/standard/standardserviceroot.cpp b/src/services/standard/standardserviceroot.cpp index 9bb171d59..cf71c528b 100755 --- a/src/services/standard/standardserviceroot.cpp +++ b/src/services/standard/standardserviceroot.cpp @@ -22,6 +22,9 @@ #include "miscellaneous/settings.h" #include "miscellaneous/iconfactory.h" #include "core/feedsmodel.h" +#include "gui/messagebox.h" +#include "gui/dialogs/formmain.h" +#include "exceptions/applicationexception.h" #include "services/standard/standardserviceentrypoint.h" #include "services/standard/standardrecyclebin.h" #include "services/standard/standardfeed.h" @@ -53,6 +56,44 @@ StandardServiceRoot::~StandardServiceRoot() { qDeleteAll(m_feedContextMenu); } +void StandardServiceRoot::start() { + if (qApp->isFirstRun()) { + if (MessageBox::show(qApp->mainForm(), QMessageBox::Question, QObject::tr("Load initial feeds"), + QObject::tr("You started %1 for the first time, now you can load initial set of feeds.").arg(APP_NAME), + QObject::tr("Do you want to load initial set of feeds?"), + QString(), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + QString target_opml_file = APP_INITIAL_FEEDS_PATH + QDir::separator() + FEED_INITIAL_OPML_PATTERN; + QString current_locale = qApp->localization()->loadedLanguage(); + QString file_to_load; + + if (QFile::exists(target_opml_file.arg(current_locale))) { + file_to_load = target_opml_file.arg(current_locale); + } + else if (QFile::exists(target_opml_file.arg(DEFAULT_LOCALE))) { + file_to_load = target_opml_file.arg(DEFAULT_LOCALE); + } + + FeedsImportExportModel model; + QString output_msg; + + try { + model.importAsOPML20(IOFactory::readTextFile(file_to_load)); + model.checkAllItems(); + + // TODO: Expand all items here? + mergeImportExportModel(&model, output_msg); + } + catch (ApplicationException &ex) { + MessageBox::show(qApp->mainForm(), QMessageBox::Critical, tr("Error when loading initial feeds"), ex.message()); + } + } + } +} + +void StandardServiceRoot::stop() { + +} + bool StandardServiceRoot::canBeEdited() { return false; } @@ -234,7 +275,7 @@ bool StandardServiceRoot::mergeImportExportModel(FeedsImportExportModel *model, new_category->clearChildren(); if (new_category->addItself(target_parent)) { - m_feedsModel->reassignNodeToNewParent(new_category, target_parent); + feedsModel()->reassignNodeToNewParent(new_category, target_parent); // Process all children of this category. original_parents.push(new_category); @@ -268,7 +309,7 @@ bool StandardServiceRoot::mergeImportExportModel(FeedsImportExportModel *model, // Append this feed and end this iteration. if (new_feed->addItself(target_parent)) { - m_feedsModel->reassignNodeToNewParent(new_feed, target_parent); + feedsModel()->reassignNodeToNewParent(new_feed, target_parent); } else { delete new_feed; diff --git a/src/services/standard/standardserviceroot.h b/src/services/standard/standardserviceroot.h index 406d0e74a..7af1838ab 100755 --- a/src/services/standard/standardserviceroot.h +++ b/src/services/standard/standardserviceroot.h @@ -42,6 +42,9 @@ class StandardServiceRoot : public ServiceRoot { explicit StandardServiceRoot(bool load_from_db, FeedsModel *feeds_model, RootItem *parent = NULL); virtual ~StandardServiceRoot(); + void start(); + void stop(); + bool canBeEdited(); bool canBeDeleted(); QVariant data(int column, int role) const;