refs #642, fixed setup loading, in same step refs #636 clear cache

* changed signals in setup reader
* explicit mode is default
* detailed information what is loaded
* new log pattern
* allow to add message list to log component
* allow to clear cache by cmd line arg
* consolidated cmd names
This commit is contained in:
Klaus Basan
2016-04-14 02:27:23 +02:00
parent bd9de9308c
commit d0daad7d34
17 changed files with 372 additions and 159 deletions

View File

@@ -41,10 +41,9 @@ BlackCore::CApplication *sApp = nullptr; // set by constructor
namespace BlackCore namespace BlackCore
{ {
CApplication::CApplication(const QString &applicationName, bool init) : CApplication::CApplication(
m_cookieManager( {}, this), const QString &applicationName, bool init) :
m_applicationName(applicationName), m_cookieManager( {}, this), m_applicationName(applicationName), m_coreFacadeConfig(CCoreFacadeConfig::allEmpty())
m_coreFacadeConfig(CCoreFacadeConfig::allEmpty())
{ {
Q_ASSERT_X(!sApp, Q_FUNC_INFO, "already initialized"); Q_ASSERT_X(!sApp, Q_FUNC_INFO, "already initialized");
Q_ASSERT_X(QCoreApplication::instance(), Q_FUNC_INFO, "no application object"); Q_ASSERT_X(QCoreApplication::instance(), Q_FUNC_INFO, "no application object");
@@ -67,25 +66,26 @@ namespace BlackCore
this->initParser(); this->initParser();
this->initLogging(); this->initLogging();
//
// cmd line arguments not yet parsed here
//
// Translations // Translations
QFile file(":blackmisc/translations/blackmisc_i18n_de.qm"); QFile file(":blackmisc/translations/blackmisc_i18n_de.qm");
CLogMessage(this).debug() << (file.exists() ? "Found translations in resources" : "No translations in resources"); CLogMessage(this).debug() << (file.exists() ? "Found translations in resources" : "No translations in resources");
QTranslator translator; QTranslator translator;
if (translator.load("blackmisc_i18n_de", ":blackmisc/translations/")) if (translator.load("blackmisc_i18n_de", ":blackmisc/translations/")) { CLogMessage(this).debug() << "Translator loaded"; }
{
CLogMessage(this).debug() << "Translator loaded";
}
QCoreApplication::instance()->installTranslator(&translator); QCoreApplication::instance()->installTranslator(&translator);
// Global setup / bootstraping // Init network
this->m_cookieManager.setParent(&this->m_accessManager); this->m_cookieManager.setParent(&this->m_accessManager);
this->m_accessManager.setCookieJar(&this->m_cookieManager); this->m_accessManager.setCookieJar(&this->m_cookieManager);
// global setup // global setup
sApp = this; sApp = this;
this->m_setupReader.reset(new CSetupReader(this)); this->m_setupReader.reset(new CSetupReader(this));
connect(this->m_setupReader.data(), &CSetupReader::setupSynchronized, this, &CApplication::ps_setupSyncronized); connect(this->m_setupReader.data(), &CSetupReader::setupAvailable, this, &CApplication::ps_setupAvailable);
connect(this->m_setupReader.data(), &CSetupReader::updateInfoSynchronized, this, &CApplication::updateInfoSynchronized); connect(this->m_setupReader.data(), &CSetupReader::updateInfoAvailable, this, &CApplication::updateInfoAvailable);
this->m_parser.addOptions(this->m_setupReader->getCmdLineOptions()); this->m_parser.addOptions(this->m_setupReader->getCmdLineOptions());
@@ -97,7 +97,6 @@ namespace BlackCore
} }
} }
CApplication::~CApplication() CApplication::~CApplication()
{ {
this->gracefulShutdown(); this->gracefulShutdown();
@@ -137,13 +136,21 @@ namespace BlackCore
if (!s) { return false; } if (!s) { return false; }
} }
// parsing itself is done // clear cache?
if (this->m_startSetupReader && !this->m_setupReader->isSetupSyncronized()) if (this->isSetOrTrue(this->m_cmdClearCache))
{ {
CStatusMessage m(this->requestReloadOfSetupAndVersion()); QStringList files(CApplication::clearCaches());
if (m.isWarningOrAbove()) CLogMessage(this).debug() << "Cleared cache, " << files.size() << " files";
}
// parsing itself is done
if (this->m_startSetupReader && !this->m_setupReader->isSetupAvailable())
{
const CStatusMessageList msgs(this->requestReloadOfSetupAndVersion());
CLogMessage::preformatted(msgs);
if (msgs.isFailure())
{ {
this->cmdLineErrorMessage(m.getMessage()); this->cmdLineErrorMessage(msgs.getWarningAndErrorMessages().toSingleMessage().getMessage());
return false; return false;
} }
} }
@@ -188,13 +195,13 @@ namespace BlackCore
return this->m_started; return this->m_started;
} }
bool CApplication::isSetupSyncronized() const bool CApplication::isSetupAvailable() const
{ {
if (this->m_shutdown || !this->m_setupReader) { return false; } if (this->m_shutdown || !this->m_setupReader) { return false; }
return this->m_setupReader->isSetupSyncronized(); return this->m_setupReader->isSetupAvailable();
} }
CStatusMessage CApplication::requestReloadOfSetupAndVersion() CStatusMessageList CApplication::requestReloadOfSetupAndVersion()
{ {
if (!this->m_shutdown) if (!this->m_shutdown)
{ {
@@ -256,16 +263,14 @@ namespace BlackCore
return a.constData(); return a.constData();
} }
bool CApplication::isRunningInDeveloperEnvironment() const bool CApplication::initIsRunningInDeveloperEnvironment() const
{ {
if (!CBuildConfig::canRunInDeveloperEnvironment()) { return false; } if (!CBuildConfig::canRunInDeveloperEnvironment()) { return false; }
if (!this->m_parser.value(this->m_cmdDevelopment).isEmpty()) if (this->m_parser.isSet(this->m_cmdDevelopment))
{ {
// explicit value return this->isSetOrTrue(this->m_cmdDevelopment);
const QString v(this->m_parser.value(this->m_cmdDevelopment));
return stringToBool(v);
} }
else if (this->isSetupSyncronized()) else if (this->isSetupAvailable())
{ {
// assume value from setup // assume value from setup
return this->getGlobalSetup().isDevelopment(); return this->getGlobalSetup().isDevelopment();
@@ -442,7 +447,7 @@ namespace BlackCore
{ {
if (!this->m_useContexts) { return true; } // we do not use context, so no need to startup if (!this->m_useContexts) { return true; } // we do not use context, so no need to startup
if (!this->m_parsed) { return false; } if (!this->m_parsed) { return false; }
if (!this->m_setupReader || !this->m_setupReader->isSetupSyncronized()) { return false; } if (!this->m_setupReader || !this->m_setupReader->isSetupAvailable()) { return false; }
Q_ASSERT_X(this->m_coreFacade.isNull(), Q_FUNC_INFO, "Cannot alter facade"); Q_ASSERT_X(this->m_coreFacade.isNull(), Q_FUNC_INFO, "Cannot alter facade");
Q_ASSERT_X(this->m_setupReader, Q_FUNC_INFO, "No facade without setup possible"); Q_ASSERT_X(this->m_setupReader, Q_FUNC_INFO, "No facade without setup possible");
@@ -460,7 +465,7 @@ namespace BlackCore
{ {
if (!this->m_useWebData) { return true; } if (!this->m_useWebData) { return true; }
if (!this->m_parsed) { return false; } if (!this->m_parsed) { return false; }
if (!this->m_setupReader || !this->m_setupReader->isSetupSyncronized()) { return false; } if (!this->m_setupReader || !this->m_setupReader->isSetupAvailable()) { return false; }
Q_ASSERT_X(this->m_setupReader, Q_FUNC_INFO, "No web data services without setup possible"); Q_ASSERT_X(this->m_setupReader, Q_FUNC_INFO, "No web data services without setup possible");
if (!this->m_webDataServices) if (!this->m_webDataServices)
@@ -490,7 +495,7 @@ namespace BlackCore
this->m_cmdHelp = this->m_parser.addHelpOption(); this->m_cmdHelp = this->m_parser.addHelpOption();
this->m_cmdVersion = this->m_parser.addVersionOption(); this->m_cmdVersion = this->m_parser.addVersionOption();
this->m_cmdDevelopment = QCommandLineOption({ "dev", "developemnt" }, this->m_cmdDevelopment = QCommandLineOption({ "dev", "development" },
QCoreApplication::translate("application", "Dev.system feature?"), QCoreApplication::translate("application", "Dev.system feature?"),
"development"); "development");
this->addParserOption(this->m_cmdDevelopment); this->addParserOption(this->m_cmdDevelopment);
@@ -499,6 +504,22 @@ namespace BlackCore
QCoreApplication::translate("application", "Local shared directory."), QCoreApplication::translate("application", "Local shared directory."),
"shared"); "shared");
this->addParserOption(this->m_cmdSharedDir); this->addParserOption(this->m_cmdSharedDir);
this->m_cmdClearCache = QCommandLineOption({ "ccache", "clearcache" },
QCoreApplication::translate("application", "Clear (reset) the caches."),
"clearcache");
this->addParserOption(this->m_cmdClearCache);
}
bool CApplication::isSetOrTrue(const QCommandLineOption &option) const
{
if (!this->m_parser.isSet(option)) { return false; }
// explicit value
const QString v(this->m_parser.value(option).trimmed());
if (v.isEmpty()) { return true; } // just flag
if (v.startsWith("-")) { return true; } // just flag, because value is already next parameter
return stringToBool(v);
} }
void CApplication::registerMetadata() void CApplication::registerMetadata()
@@ -507,6 +528,13 @@ namespace BlackCore
BlackCore::registerMetadata(); BlackCore::registerMetadata();
} }
QStringList CApplication::clearCaches()
{
const QStringList files(CDataCache::instance()->enumerateStore());
CDataCache::instance()->clearAllValues();
return files;
}
void CApplication::gracefulShutdown() void CApplication::gracefulShutdown()
{ {
if (this->m_shutdown) { return; } if (this->m_shutdown) { return; }
@@ -553,14 +581,15 @@ namespace BlackCore
this->m_fileLogger->close(); this->m_fileLogger->close();
} }
void CApplication::ps_setupSyncronized(bool success) void CApplication::ps_setupAvailable(bool available)
{ {
if (success) if (available)
{ {
emit setupSyncronized(success);
this->m_started = this->asyncWebAndContextStart(); this->m_started = this->asyncWebAndContextStart();
} }
this->m_startUpCompleted = true; this->m_startUpCompleted = true;
emit setupAvailable(available);
if (this->m_signalStartup) if (this->m_signalStartup)
{ {
emit this->startUpCompleted(this->m_started); emit this->startUpCompleted(this->m_started);
@@ -624,7 +653,7 @@ namespace BlackCore
void CApplication::addDBusAddressOption() void CApplication::addDBusAddressOption()
{ {
this->m_cmdDBusAddress = QCommandLineOption({ "dbus", "dbus-address", "dbusaddress" }, this->m_cmdDBusAddress = QCommandLineOption({ "dbus", "dbusaddress" },
QCoreApplication::translate("application", "DBus address."), QCoreApplication::translate("application", "DBus address."),
"dbusaddress"); "dbusaddress");
this->addParserOption(this->m_cmdDBusAddress); this->addParserOption(this->m_cmdDBusAddress);
@@ -704,6 +733,9 @@ namespace BlackCore
return true; return true;
} }
// dev.
this->m_devEnv = this->initIsRunningInDeveloperEnvironment();
// Hookin, other parsing // Hookin, other parsing
if (!this->parsingHookIn()) { return false; } if (!this->parsingHookIn()) { return false; }

View File

@@ -90,10 +90,10 @@ namespace BlackCore
void deleteAllCookies(); void deleteAllCookies();
//! Setup already syncronized //! Setup already syncronized
bool isSetupSyncronized() const; bool isSetupAvailable() const;
//! Reload setup and version //! Reload setup and version
BlackMisc::CStatusMessage requestReloadOfSetupAndVersion(); BlackMisc::CStatusMessageList requestReloadOfSetupAndVersion();
//! Web data services available? //! Web data services available?
bool hasWebDataServices() const; bool hasWebDataServices() const;
@@ -114,7 +114,7 @@ namespace BlackCore
const char *swiftVersionChar(); const char *swiftVersionChar();
//! Running in dev.environment? //! Running in dev.environment?
bool isRunningInDeveloperEnvironment() const; bool isRunningInDeveloperEnvironment() const { return this->m_devEnv; }
//! Signal startup automatically or individually //! Signal startup automatically or individually
void signalStartupAutomatically(bool signal = false); void signalStartupAutomatically(bool signal = false);
@@ -137,6 +137,9 @@ namespace BlackCore
//! Process all events for some time //! Process all events for some time
static void processEventsFor(int milliseconds); static void processEventsFor(int milliseconds);
//! Clear the caches
static QStringList clearCaches();
// ----------------------- parsing ---------------------------------------- // ----------------------- parsing ----------------------------------------
//! \name parsing of command line options //! \name parsing of command line options
@@ -259,11 +262,11 @@ namespace BlackCore
const BlackMisc::CSlot<void(QNetworkReply *)> &callback); const BlackMisc::CSlot<void(QNetworkReply *)> &callback);
signals: signals:
//! Setup syncronized //! Setup available (cache, web load, ..)
void setupSyncronized(bool success); void setupAvailable(bool success);
//! Update info syncronized //! Update info available (cache, web load)
void updateInfoSynchronized(bool success); void updateInfoAvailable(bool success);
//! Startup has been completed //! Startup has been completed
void startUpCompleted(bool success); void startUpCompleted(bool success);
@@ -276,7 +279,7 @@ namespace BlackCore
protected slots: protected slots:
//! Setup read/syncronized //! Setup read/syncronized
void ps_setupSyncronized(bool success); void ps_setupAvailable(bool available);
//! Startup completed //! Startup completed
virtual void ps_startupCompleted(); virtual void ps_startupCompleted();
@@ -297,6 +300,9 @@ namespace BlackCore
//! Can be used to start special services //! Can be used to start special services
virtual bool startHookIn() { return true; } virtual bool startHookIn() { return true; }
//! Flag set or explicitly set to true
bool isSetOrTrue(const QCommandLineOption &option) const;
//! Severe issue during startup, most likely it does not make sense to continue //! Severe issue during startup, most likely it does not make sense to continue
//! \note call this here if the parsing stage is over and reaction to a runtime issue //! \note call this here if the parsing stage is over and reaction to a runtime issue
//! is needed //! is needed
@@ -317,17 +323,17 @@ namespace BlackCore
static void registerMetadata(); static void registerMetadata();
// cmd parsing // cmd parsing
QCommandLineParser m_parser; //!< cmd parser QCommandLineParser m_parser; //!< cmd parser
QCommandLineOption m_cmdHelp {"help"}; //!< help option QCommandLineOption m_cmdHelp {"help"}; //!< help option
QCommandLineOption m_cmdVersion {"version"}; //!< version option QCommandLineOption m_cmdVersion {"version"}; //!< version option
QCommandLineOption m_cmdDBusAddress {"empty"}; //!< DBus address QCommandLineOption m_cmdDBusAddress {"empty"}; //!< DBus address
QCommandLineOption m_cmdDevelopment {"dev"}; //!< Dev flag QCommandLineOption m_cmdDevelopment {"dev"}; //!< Dev. flag
QCommandLineOption m_cmdSharedDir {"shared"}; //!< Dev flag QCommandLineOption m_cmdSharedDir {"shared"}; //!< Shared directory
QCommandLineOption m_cmdClearCache {"clearcache"}; //!< Clear cache
bool m_parsed = false; //!< Parsing accomplished? bool m_parsed = false; //!< Parsing accomplished?
bool m_started = false; //!< started with success? bool m_started = false; //!< started with success?
bool m_startUpCompleted = false; //!< startup phase completed? Can mean startup failed bool m_startUpCompleted = false; //!< startup phase completed? Can mean startup failed
bool m_startSetupReader = false; //!< start the setup reader bool m_startSetupReader = false; //!< start the setup reader
private: private:
//! init logging system //! init logging system
@@ -336,6 +342,9 @@ namespace BlackCore
//! Init parser //! Init parser
void initParser(); void initParser();
//! Dev.environment
bool initIsRunningInDeveloperEnvironment() const;
//! Async. start when setup is loaded //! Async. start when setup is loaded
bool asyncWebAndContextStart(); bool asyncWebAndContextStart();
@@ -354,6 +363,7 @@ namespace BlackCore
bool m_useContexts = false; //!< use contexts bool m_useContexts = false; //!< use contexts
bool m_useWebData = false; //!< use web data bool m_useWebData = false; //!< use web data
bool m_signalStartup = true; //!< signal startup automatically bool m_signalStartup = true; //!< signal startup automatically
bool m_devEnv = false; //!< dev. environment
}; };
} // namespace } // namespace

View File

@@ -82,14 +82,14 @@ namespace BlackCore
QString CGlobalSetup::buildBootstrapFileUrl(const QString &candidate) QString CGlobalSetup::buildBootstrapFileUrl(const QString &candidate)
{ {
static const QString vS(QString(versionString()).append("/")); static const QString version(QString(versionString()).append("/"));
if (candidate.endsWith("bootstrap.json")) { return candidate; } if (candidate.endsWith("bootstrap.json")) { return candidate; }
CUrl url(candidate); CUrl url(candidate);
if (candidate.contains("/bootstrap")) if (candidate.contains("/bootstrap"))
{ {
url.appendPath("bootstrap.json"); url.appendPath("bootstrap.json");
} }
else if (candidate.endsWith(versionString()) || candidate.endsWith(vS)) else if (candidate.endsWith(versionString()) || candidate.endsWith(version))
{ {
url.appendPath("/bootstrap/bootstrap.json"); url.appendPath("/bootstrap/bootstrap.json");
} }

View File

@@ -30,10 +30,7 @@ namespace BlackCore
{ {
CSetupReader::CSetupReader(QObject *parent) : CSetupReader::CSetupReader(QObject *parent) :
QObject(parent) QObject(parent)
{ { }
connect(this, &CSetupReader::setupSynchronized, this, &CSetupReader::ps_setupSyncronized);
connect(this, &CSetupReader::updateInfoSynchronized, this, &CSetupReader::ps_versionInfoSyncronized);
}
QList<QCommandLineOption> CSetupReader::getCmdLineOptions() const QList<QCommandLineOption> CSetupReader::getCmdLineOptions() const
{ {
@@ -46,24 +43,33 @@ namespace BlackCore
}; };
} }
CStatusMessage CSetupReader::asyncLoad() CStatusMessageList CSetupReader::asyncLoad()
{ {
CStatusMessageList msgs;
if (this->readLocalBootstrapFile(this->m_localSetupFileValue)) if (this->readLocalBootstrapFile(this->m_localSetupFileValue))
{ {
// initialized by local file for testing // initialized by local file for testing
emit this->setupSynchronized(true); msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, "Using local bootstrap file: " + this->m_localSetupFileValue));
return CStatusMessage(this, CStatusMessage::SeverityInfo, "Using local bootstrap file: " + this->m_localSetupFileValue); msgs.push_back(this->manageSetupAvailability(false, true));
return msgs;
} }
m_setup.synchronize(); // make sure it is loaded m_setup.synchronize(); // make sure it is loaded
CGlobalSetup cachedSetup = m_setup.getCopy();
const bool cacheAvailable = cachedSetup.wasLoaded();
msgs.push_back(cacheAvailable ?
CStatusMessage(this, CStatusMessage::SeverityInfo , "Cached setup syncronized and contains data") :
CStatusMessage(this, CStatusMessage::SeverityInfo , "Cached setup syncronized, but no data")
);
if (this->m_bootstrapMode == CacheOnly) if (this->m_bootstrapMode == CacheOnly)
{ {
this->m_updateInfoUrls = cachedSetup.getUpdateInfoFileUrls();
CGlobalSetup currentSetup = m_setup.getCopy(); msgs.push_back(cacheAvailable ?
this->m_updateInfoUrls = currentSetup.getUpdateInfoFileUrls(); CStatusMessage(this, CStatusMessage::SeverityInfo, "Cache only setup, using it as it is") :
emit this->setupSynchronized(true); CStatusMessage(this, CStatusMessage::SeverityError, "Cache only setup, but cache is empty")
emit this->updateInfoSynchronized(true); );
return CStatusMessage(this, CStatusMessage::SeverityInfo, "Cache only setup, using it as it is"); msgs.push_back(this->manageSetupAvailability(false, false));
return msgs;
} }
this->m_bootstrapUrls.clear(); // clean up previous values this->m_bootstrapUrls.clear(); // clean up previous values
@@ -76,37 +82,45 @@ namespace BlackCore
} }
// if ever loaded add those URLs // if ever loaded add those URLs
const CGlobalSetup currentSetup = m_setup.getCopy(); if (cacheAvailable)
if (this->m_bootstrapMode != Explicit)
{ {
// also use previously cached URLs if (this->m_bootstrapMode != Explicit)
this->m_bootstrapUrls.push_back(currentSetup.getBootstrapFileUrls());
// fail over if still empty
//! \todo do we want to keep this or use a cmd line flag to enable the behaviour. Risk here to use an undesired setup
if (this->m_bootstrapUrls.isEmpty())
{ {
// use file from disk delivered with swift // also use previously cached URLs
// there is a potential risk here, if the URL passed via cmd args is actually adressing an entirely diffent scenario, const CUrlList bootstrapCacheUrls(cachedSetup.getBootstrapFileUrls());
// this would load a file for something else this->m_bootstrapUrls.push_back(bootstrapCacheUrls);
CGlobalSetup resourceSetup(CGlobalSetup::fromJsonFile( msgs.push_back(bootstrapCacheUrls.isEmpty() ?
CBuildConfig::getBootstrapResourceFile() CStatusMessage(this, CStatusMessage::SeverityWarning, "No bootsrap URLs in cache") :
)); CStatusMessage(this, CStatusMessage::SeverityInfo, "Adding " + QString::number(bootstrapCacheUrls.size()) + " bootstrap URLs from cache"));
this->m_bootstrapUrls.push_back(resourceSetup.getBootstrapFileUrls());
} }
} }
else
{
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, "Empty cache, will not add URLs"));
}
this->m_bootstrapUrls.removeDuplicates(); // clean up this->m_bootstrapUrls.removeDuplicates(); // clean up
if (this->m_bootstrapUrls.isEmpty()) if (this->m_bootstrapUrls.isEmpty())
{ {
// after all still empty // after all still empty
return CStatusMessage(this, CStatusMessage::SeverityError, "No bootstrap URLs, cannot load setup"); msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityError, "No bootstrap URLs, cannot load setup"));
} }
else else
{ {
this->ps_readSetup(); // start reading CStatusMessageList readMsgs = triggerReadSetup();
return CStatusMessage(this, CStatusMessage::SeverityInfo, "Will start loading setup"); if (cacheAvailable && readMsgs.isFailure())
{
// error but cache is available, we can continue
readMsgs.clipSeverity(CStatusMessage::SeverityWarning);
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityWarning, "Loading setup failed, but cache is available, will continue"));
msgs.push_back(readMsgs);
}
else
{
msgs.push_back(readMsgs);
}
} }
return msgs;
} }
bool CSetupReader::parseCmdLineArguments() bool CSetupReader::parseCmdLineArguments()
@@ -114,8 +128,13 @@ namespace BlackCore
this->m_bootstrapUrlFileValue = CGlobalSetup::buildBootstrapFileUrl( this->m_bootstrapUrlFileValue = CGlobalSetup::buildBootstrapFileUrl(
sApp->getParserValue(this->m_cmdBootstrapUrl) sApp->getParserValue(this->m_cmdBootstrapUrl)
); );
this->m_bootstrapMode = stringToEnum(sApp->getParserValue(this->m_cmdBootstrapMode));
QUrl url(this->m_bootstrapUrlFileValue); QUrl url(this->m_bootstrapUrlFileValue);
const QString urlString(url.toString());
this->m_bootstrapMode = stringToEnum(sApp->getParserValue(this->m_cmdBootstrapMode));
if (urlString.isEmpty() && this->m_bootstrapMode == Explicit)
{
this->m_bootstrapMode = Implicit; // no URL, we use implicit mode
}
// check on local file // check on local file
if (url.isLocalFile()) if (url.isLocalFile())
@@ -136,7 +155,7 @@ namespace BlackCore
{ {
if (!CNetworkUtils::canConnect(url)) if (!CNetworkUtils::canConnect(url))
{ {
sApp->cmdLineErrorMessage("URL " + url.toString() + " not reachable"); sApp->cmdLineErrorMessage("URL " + urlString + " not reachable");
return false; return false;
} }
} }
@@ -151,17 +170,29 @@ namespace BlackCore
void CSetupReader::ps_readSetup() void CSetupReader::ps_readSetup()
{ {
const CStatusMessageList msgs(this->triggerReadSetup());
if (!msgs.isSuccess())
{
CLogMessage::preformatted(msgs);
}
}
CStatusMessageList CSetupReader::triggerReadSetup()
{
if (m_shutdown) { return CStatusMessage(this, CStatusMessage::SeverityError, "shutdown"); }
const CUrl url(this->m_bootstrapUrls.obtainNextWorkingUrl()); const CUrl url(this->m_bootstrapUrls.obtainNextWorkingUrl());
if (url.isEmpty()) if (url.isEmpty())
{ {
CLogMessage(this).warning("Cannot read setup, URLs: %1, failed URLs: %2") const CStatusMessage m(this, CStatusMessage::SeverityError,
<< this->m_bootstrapUrls "Cannot read setup, URLs: " + this->m_bootstrapUrls.toQString() +
<< this->m_bootstrapUrls.getFailedUrls(); " failed URLs: " + this->m_bootstrapUrls.getFailedUrls().toQString());
emit setupSynchronized(false); CStatusMessageList msgs(m);
return; msgs.push_back(this->manageSetupAvailability(false, false));
return msgs;
} }
if (m_shutdown) { return; } const CStatusMessage m(this, CStatusMessage::SeverityInfo, "Start reading URL: " + url.toQString());
sApp->getFromNetwork(url.toNetworkRequest(), { this, &CSetupReader::ps_parseSetupFile }); sApp->getFromNetwork(url.toNetworkRequest(), { this, &CSetupReader::ps_parseSetupFile });
return m;
} }
void CSetupReader::ps_readUpdateInfo() void CSetupReader::ps_readUpdateInfo()
@@ -172,33 +203,13 @@ namespace BlackCore
CLogMessage(this).warning("Cannot read update info, URLs: %1, failed URLs: %2") CLogMessage(this).warning("Cannot read update info, URLs: %1, failed URLs: %2")
<< this->m_updateInfoUrls << this->m_updateInfoUrls
<< this->m_updateInfoUrls.getFailedUrls(); << this->m_updateInfoUrls.getFailedUrls();
emit updateInfoSynchronized(false); this->manageUpdateAvailability(false);
return; return;
} }
if (m_shutdown) { return; } if (m_shutdown) { return; }
sApp->getFromNetwork(url.toNetworkRequest(), { this, &CSetupReader::ps_parseUpdateInfoFile}); sApp->getFromNetwork(url.toNetworkRequest(), { this, &CSetupReader::ps_parseUpdateInfoFile});
} }
void CSetupReader::ps_setupSyncronized(bool success)
{
// trigger consecutive read
this->m_setupSyncronized = success;
if (success)
{
CLogMessage(this).info("Setup synchronized, will trigger read of update information");
QTimer::singleShot(500, this, &CSetupReader::ps_readUpdateInfo);
}
else
{
CLogMessage(this).error("Setup reading failed, hence version info will not be loaded");
}
}
void CSetupReader::ps_versionInfoSyncronized(bool success)
{
this->m_updateInfoSyncronized = success;
}
void CSetupReader::ps_setupChanged() void CSetupReader::ps_setupChanged()
{ {
// settings have changed on disk // settings have changed on disk
@@ -209,7 +220,7 @@ namespace BlackCore
const QString bsm(s.toLower().trimmed()); const QString bsm(s.toLower().trimmed());
if (bsm.startsWith("expl")) return Explicit; if (bsm.startsWith("expl")) return Explicit;
if (bsm.startsWith("cache")) return CacheOnly; if (bsm.startsWith("cache")) return CacheOnly;
return Default; return Implicit;
} }
bool CSetupReader::readLocalBootstrapFile(QString &fileName) bool CSetupReader::readLocalBootstrapFile(QString &fileName)
@@ -273,7 +284,7 @@ namespace BlackCore
{ {
this->m_updateInfoUrls = currentSetup.getUpdateInfoFileUrls(); // defaults this->m_updateInfoUrls = currentSetup.getUpdateInfoFileUrls(); // defaults
CLogMessage(this).info("Same setup version loaded from %1 as already in data cache %2") << urlString << m_setup.getFilename(); CLogMessage(this).info("Same setup version loaded from %1 as already in data cache %2") << urlString << m_setup.getFilename();
emit setupSynchronized(true); CLogMessage::preformatted(this->manageSetupAvailability(true));
return; // success return; // success
} }
@@ -284,14 +295,14 @@ namespace BlackCore
{ {
m.setCategories(getLogCategories()); m.setCategories(getLogCategories());
CLogMessage::preformatted(m); CLogMessage::preformatted(m);
emit setupSynchronized(false); CLogMessage::preformatted(this->manageSetupAvailability(false));
return; // issue with cache return; // issue with cache
} }
else else
{ {
this->m_updateInfoUrls = loadedSetup.getUpdateInfoFileUrls(); this->m_updateInfoUrls = loadedSetup.getUpdateInfoFileUrls();
CLogMessage(this).info("Setup: Updated data cache in %1") << this->m_setup.getFilename(); CLogMessage(this).info("Setup: Updated data cache in %1") << this->m_setup.getFilename();
emit setupSynchronized(true); CLogMessage::preformatted(this->manageSetupAvailability(true));
return; // success return; // success
} // cache } // cache
@@ -311,7 +322,7 @@ namespace BlackCore
} }
else else
{ {
emit setupSynchronized(false); CLogMessage::preformatted(manageSetupAvailability(false));
} }
} }
@@ -346,7 +357,7 @@ namespace BlackCore
if (sameVersionLoaded) if (sameVersionLoaded)
{ {
CLogMessage(this).info("Same update info version loaded from %1 as already in data cache %2") << urlString << m_setup.getFilename(); CLogMessage(this).info("Same update info version loaded from %1 as already in data cache %2") << urlString << m_setup.getFilename();
emit updateInfoSynchronized(true); this->manageUpdateAvailability(true);
return; // success return; // success
} }
@@ -355,13 +366,13 @@ namespace BlackCore
{ {
m.setCategories(getLogCategories()); m.setCategories(getLogCategories());
CLogMessage::preformatted(m); CLogMessage::preformatted(m);
emit updateInfoSynchronized(false); this->manageUpdateAvailability(false);
return; // issue with cache return; // issue with cache
} }
else else
{ {
CLogMessage(this).info("Update info: Updated data cache in %1") << m_updateInfo.getFilename(); CLogMessage(this).info("Update info: Updated data cache in %1") << m_updateInfo.getFilename();
emit updateInfoSynchronized(true); this->manageUpdateAvailability(true);
return; // success return; // success
} // cache } // cache
} // json empty } // json empty
@@ -380,13 +391,13 @@ namespace BlackCore
} }
else else
{ {
emit updateInfoSynchronized(false); this->manageUpdateAvailability(false);
} }
} // function } // function
const CLogCategoryList &CSetupReader::getLogCategories() const CLogCategoryList &CSetupReader::getLogCategories()
{ {
static const CLogCategoryList cats({ CLogCategory("swift.setupreader"), CLogCategory::webservice()}); static const CLogCategoryList cats({ CLogCategory("swift.setupreader"), CLogCategory::webservice(), CLogCategory::startup()});
return cats; return cats;
} }
@@ -399,4 +410,65 @@ namespace BlackCore
{ {
return m_updateInfo.getCopy(); return m_updateInfo.getCopy();
} }
CStatusMessageList CSetupReader::manageSetupAvailability(bool webRead, bool localRead)
{
Q_ASSERT_X(!(webRead && localRead), Q_FUNC_INFO, "Local and web read together seems to be wrong");
CStatusMessageList msgs;
if (webRead)
{
msgs.push_back(CLogMessage(this).info("Setup loaded from web, will trigger read of update information"));
QTimer::singleShot(500, this, &CSetupReader::ps_readUpdateInfo);
}
if (localRead)
{
msgs.push_back(CLogMessage(this).info("Setup loaded locally, will trigger read of update information"));
QTimer::singleShot(500, this, &CSetupReader::ps_readUpdateInfo);
}
bool available = false;
if (webRead || localRead)
{
available = true;
}
else
{
bool cacheAvailable = this->m_setup.get().wasLoaded();
available = cacheAvailable && this->m_bootstrapMode != Explicit;
}
if (available && !webRead && !localRead)
{
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, "Setup available, but not updated this time"));
}
else if (!available)
{
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityError, "Setup not available"));
}
this->m_setupAvailable = available;
emit setupAvailable(available);
if (!webRead && !localRead)
{
msgs.push_back(CStatusMessage(this).warning("Since setup was not updated this time, will not start loading of update information"));
this->manageUpdateAvailability(false);
}
return msgs;
}
void CSetupReader::manageUpdateAvailability(bool webRead)
{
if (webRead)
{
this->m_updateInfoAvailable = true;
emit updateInfoAvailable(true);
}
else
{
bool cached = this->m_updateInfo.isSaved();
this->m_updateInfoAvailable = cached;
emit updateInfoAvailable(cached);
}
}
} // namespace } // namespace

View File

@@ -52,18 +52,18 @@ namespace BlackCore
BlackCore::Data::CUpdateInfo getUpdateInfo() const; BlackCore::Data::CUpdateInfo getUpdateInfo() const;
signals: signals:
//! Setup has been read //! Setup avialable (from web, cache, or local file)
void setupSynchronized(bool success); void setupAvailable(bool available);
//! Version bas been read //! Setup avialable (from web, cache
void updateInfoSynchronized(bool success); void updateInfoAvailable(bool available);
protected: protected:
//! Constructor //! Constructor
explicit CSetupReader(QObject *parent); explicit CSetupReader(QObject *parent);
//! Load the data //! Load the data
BlackMisc::CStatusMessage asyncLoad(); BlackMisc::CStatusMessageList asyncLoad();
//! Parse cmd line arguments //! Parse cmd line arguments
bool parseCmdLineArguments(); bool parseCmdLineArguments();
@@ -74,13 +74,13 @@ namespace BlackCore
//! Terminate //! Terminate
void gracefulShutdown(); void gracefulShutdown();
//! Setup loaded? //! Setup available?
//! \threadsafe //! \threadsafe
bool isSetupSyncronized() const { return m_setupSyncronized; } bool isSetupAvailable() const { return m_setupAvailable; }
//! Version info loaded? //! Version info available?
//! \threadsafe //! \threadsafe
bool isUpdateSyncronized() const { return m_updateInfoSyncronized; } bool isUpdateInfoAvailable() const { return m_updateInfoAvailable; }
private slots: private slots:
//! Setup has been read //! Setup has been read
@@ -95,12 +95,6 @@ namespace BlackCore
//! Do reading //! Do reading
void ps_readUpdateInfo(); void ps_readUpdateInfo();
//! Setup has beem syncronized
void ps_setupSyncronized(bool success);
//! Version info has beem syncronized
void ps_versionInfoSyncronized(bool success);
//! Setup has been changed //! Setup has been changed
void ps_setupChanged(); void ps_setupChanged();
@@ -108,17 +102,17 @@ namespace BlackCore
//! Bootstrap mode //! Bootstrap mode
enum BootstrapMode enum BootstrapMode
{ {
Default, Implicit,
Explicit, Explicit,
CacheOnly CacheOnly
}; };
bool m_shutdown = false; bool m_shutdown = false;
std::atomic<bool> m_setupSyncronized { false }; std::atomic<bool> m_setupAvailable { false };
std::atomic<bool> m_updateInfoSyncronized { false }; std::atomic<bool> m_updateInfoAvailable { false };
QString m_localSetupFileValue; //! Local file for setup, passed by cmd line arguments QString m_localSetupFileValue; //! Local file for setup, passed by cmd line arguments
QString m_bootstrapUrlFileValue; //! Bootstrap URL if not local QString m_bootstrapUrlFileValue; //! Bootstrap URL if not local
BootstrapMode m_bootstrapMode; //! How to bootstrap BootstrapMode m_bootstrapMode = Explicit; //! How to bootstrap
BlackMisc::Network::CFailoverUrlList m_bootstrapUrls; //!< location of setup files BlackMisc::Network::CFailoverUrlList m_bootstrapUrls; //!< location of setup files
BlackMisc::Network::CFailoverUrlList m_updateInfoUrls; //!< location of info files BlackMisc::Network::CFailoverUrlList m_updateInfoUrls; //!< location of info files
BlackMisc::CData<BlackCore::Data::GlobalSetup> m_setup {this, &CSetupReader::ps_setupChanged}; //!< data cache setup BlackMisc::CData<BlackCore::Data::GlobalSetup> m_setup {this, &CSetupReader::ps_setupChanged}; //!< data cache setup
@@ -126,20 +120,31 @@ namespace BlackCore
QCommandLineOption m_cmdBootstrapUrl QCommandLineOption m_cmdBootstrapUrl
{ {
{ "url", "bootstrap-url", "bootstrapurl" }, { "url", "bootstrapurl" },
QCoreApplication::translate("application", "bootstrap URL, e.g. datastore.swift-project.org"), QCoreApplication::translate("application", "bootstrap URL, e.g. datastore.swift-project.org"),
"bootstrapurl" "bootstrapurl"
}; //!< bootstrap URL }; //!< bootstrap URL
QCommandLineOption m_cmdBootstrapMode QCommandLineOption m_cmdBootstrapMode
{ {
{ "bmode", "bootstrap-mode", "bootstrapmode" }, { "bmode", "bootstrapmode" },
QCoreApplication::translate("application", "bootstrap mode: (e)xplicit, d(default), (c)ache-only"), QCoreApplication::translate("application", "bootstrap mode: explicit, implicit, cache(-only)"),
"bootstrapmode", "default" "bootstrapmode", "explicit"
}; //!< bootstrap mode }; //!< bootstrap mode
//! Read by local individual file //! Read by local individual file and update cache from that
bool readLocalBootstrapFile(QString &fileName); bool readLocalBootstrapFile(QString &fileName);
//! Trigger reading
BlackMisc::CStatusMessageList triggerReadSetup();
//! Emit the availability signal and state
//! \threadsafe
BlackMisc::CStatusMessageList manageSetupAvailability(bool webRead, bool localRead = false);
//! Emit the available signal
//! \threadsafe
void manageUpdateAvailability(bool webRead);
//! Convert string to mode //! Convert string to mode
static BootstrapMode stringToEnum(const QString &s); static BootstrapMode stringToEnum(const QString &s);
}; };

View File

@@ -43,7 +43,7 @@ namespace BlackCore
if (!sApp) { return; } // shutting down if (!sApp) { return; } // shutting down
Q_ASSERT_X(QSslSocket::supportsSsl(), Q_FUNC_INFO, "missing SSL support"); Q_ASSERT_X(QSslSocket::supportsSsl(), Q_FUNC_INFO, "missing SSL support");
Q_ASSERT_X(sApp->isSetupSyncronized(), Q_FUNC_INFO, "Setup not syncronized"); Q_ASSERT_X(sApp->isSetupAvailable(), Q_FUNC_INFO, "Setup not syncronized");
this->setObjectName("CWebDataReader"); this->setObjectName("CWebDataReader");
this->initReaders(readerFlags); this->initReaders(readerFlags);
this->initWriters(); this->initWriters();

View File

@@ -72,10 +72,16 @@ namespace BlackGui
void CLogComponent::appendStatusMessageToList(const CStatusMessage &statusMessage) void CLogComponent::appendStatusMessageToList(const CStatusMessage &statusMessage)
{ {
if (statusMessage.isEmpty()) return; if (statusMessage.isEmpty()) { return; }
this->ui->tvp_StatusMessages->insert(statusMessage); this->ui->tvp_StatusMessages->insert(statusMessage);
} }
void CLogComponent::appendStatusMessagesToList(const CStatusMessageList &statusMessages)
{
if (statusMessages.isEmpty()) { return; }
this->ui->tvp_StatusMessages->insert(statusMessages);
}
void CLogComponent::CLogMenu::customMenu(QMenu &menu) const void CLogComponent::CLogMenu::customMenu(QMenu &menu) const
{ {
CLogComponent *logComp = qobject_cast<CLogComponent *>(this->parent()); CLogComponent *logComp = qobject_cast<CLogComponent *>(this->parent());

View File

@@ -72,6 +72,9 @@ namespace BlackGui
//! Append status message to list //! Append status message to list
void appendStatusMessageToList(const BlackMisc::CStatusMessage &statusMessage); void appendStatusMessageToList(const BlackMisc::CStatusMessage &statusMessage);
//! Append status messages to list
void appendStatusMessagesToList(const BlackMisc::CStatusMessageList &statusMessages);
private: private:
QScopedPointer<Ui::CLogComponent> ui; QScopedPointer<Ui::CLogComponent> ui;

View File

@@ -307,8 +307,8 @@ namespace BlackGui
a = sm->addAction("Reset cache"); a = sm->addAction("Reset cache");
c = connect(a, &QAction::triggered, this, [this]() c = connect(a, &QAction::triggered, this, [this]()
{ {
CDataCache::instance()->clearAllValues(); const QStringList files = CApplication::clearCaches();
this->displayTextInConsole("Cleared cache!"); this->displayTextInConsole("Cleared caches! " + QString::number(files.size()) + " files");
}); });
Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed"); Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");

View File

@@ -106,6 +106,13 @@ namespace BlackMisc
return cat; return cat;
} }
//! Startup of application
static const CLogCategory &startup()
{
static const CLogCategory cat { "swift.startup" };
return cat;
}
//! Webservice with swift DB //! Webservice with swift DB
static const CLogCategory &swiftDbWebservice() static const CLogCategory &swiftDbWebservice()
{ {
@@ -135,6 +142,7 @@ namespace BlackMisc
matching(), matching(),
swiftDbWebservice(), swiftDbWebservice(),
services(), services(),
startup(),
validation(), validation(),
vatsimSpecific(), vatsimSpecific(),
verification(), verification(),

View File

@@ -28,6 +28,7 @@ namespace BlackMisc
{ "downloading data", exactMatch(CLogCategory::download()) }, { "downloading data", exactMatch(CLogCategory::download()) },
{ "VASTIM specific", exactMatch(CLogCategory::vatsimSpecific()) }, { "VASTIM specific", exactMatch(CLogCategory::vatsimSpecific()) },
{ "webservice related", exactMatch(CLogCategory::webservice()) }, { "webservice related", exactMatch(CLogCategory::webservice()) },
{ "startup phase", exactMatch(CLogCategory::startup()) },
{ "swift DB webservice related", exactMatch(CLogCategory::swiftDbWebservice()) }, { "swift DB webservice related", exactMatch(CLogCategory::swiftDbWebservice()) },
{ "Qt library", startsWith("qt.") }, { "Qt library", startsWith("qt.") },
{ "uncategorized (other)", empty() } { "uncategorized (other)", empty() }

View File

@@ -197,6 +197,13 @@ namespace BlackMisc
return c.isEmpty() ? this->getCategoriesAsString() : c; return c.isEmpty() ? this->getCategoriesAsString() : c;
} }
bool CStatusMessage::clipSeverity(CStatusMessage::StatusSeverity severity)
{
if (this->getSeverity() <= severity) { return false; }
this->setSeverity(severity);
return true;
}
bool CStatusMessage::isSuccess() const bool CStatusMessage::isSuccess() const
{ {
return !isFailure(); return !isFailure();

View File

@@ -205,6 +205,9 @@ namespace BlackMisc
//! Message severity //! Message severity
StatusSeverity getSeverity() const { return this->m_severity; } StatusSeverity getSeverity() const { return this->m_severity; }
//! Clip/reduce severity if higher (more critical)
bool clipSeverity(StatusSeverity severity);
//! Info or debug, no warning or error //! Info or debug, no warning or error
bool isSeverityInfoOrLess() const { return this->m_severity == SeverityInfo || this->m_severity == SeverityDebug; } bool isSeverityInfoOrLess() const { return this->m_severity == SeverityInfo || this->m_severity == SeverityDebug; }

View File

@@ -17,6 +17,11 @@ namespace BlackMisc
CSequence<CStatusMessage>(other) CSequence<CStatusMessage>(other)
{ } { }
CStatusMessageList::CStatusMessageList(const CStatusMessage &statusMessage)
{
this->push_back(statusMessage);
}
CStatusMessageList CStatusMessageList::findByCategory(const CLogCategory &category) const CStatusMessageList CStatusMessageList::findByCategory(const CLogCategory &category) const
{ {
return this->findBy([ & ](const CStatusMessage & msg) { return msg.getCategories().contains(category); }); return this->findBy([ & ](const CStatusMessage & msg) { return msg.getCategories().contains(category); });
@@ -43,6 +48,29 @@ namespace BlackMisc
([ = ](const CStatusMessage & m) { return m.getSeverity() == CStatusMessage::SeverityWarning || m.getSeverity() == CStatusMessage::SeverityError; }); ([ = ](const CStatusMessage & m) { return m.getSeverity() == CStatusMessage::SeverityWarning || m.getSeverity() == CStatusMessage::SeverityError; });
} }
bool CStatusMessageList::isSuccess() const
{
return !this->isFailure();
}
bool CStatusMessageList::isFailure() const
{
return this->contains(&CStatusMessage::isFailure, true);
}
CStatusMessageList CStatusMessageList::getErrorMessages() const
{
return findBySeverity(SeverityError);
}
CStatusMessageList CStatusMessageList::getWarningAndErrorMessages() const
{
return this->findBy([ & ](const CStatusMessage & msg)
{
return msg.getSeverity() >= CStatusMessage::SeverityWarning;
});
}
void CStatusMessageList::addCategory(const CLogCategory &category) void CStatusMessageList::addCategory(const CLogCategory &category)
{ {
for (auto &msg : *this) for (auto &msg : *this)
@@ -73,8 +101,16 @@ namespace BlackMisc
{ {
msg.setCategories(categories); msg.setCategories(categories);
} }
} }
void CStatusMessageList::clipSeverity(CStatusMessage::StatusSeverity severity)
{
for (auto &msg : *this)
{
msg.clipSeverity(severity);
}
}
void CStatusMessageList::removeWarningsAndBelow() void CStatusMessageList::removeWarningsAndBelow()
{ {
if (this->isEmpty()) { return; } if (this->isEmpty()) { return; }

View File

@@ -37,6 +37,9 @@ namespace BlackMisc
//! Construct from a base class object. //! Construct from a base class object.
CStatusMessageList(const CSequence<CStatusMessage> &other); CStatusMessageList(const CSequence<CStatusMessage> &other);
//! Construct from single message
CStatusMessageList(const CStatusMessage &statusMessage);
//! Find by type //! Find by type
CStatusMessageList findByCategory(const CLogCategory &category) const; CStatusMessageList findByCategory(const CLogCategory &category) const;
@@ -52,6 +55,18 @@ namespace BlackMisc
//! Warning or error messages //! Warning or error messages
bool hasWarningOrErrorMessages() const; bool hasWarningOrErrorMessages() const;
//! All messages are marked as success
bool isSuccess() const;
//! Any message is marked as failure
bool isFailure() const;
//! Get all error messages
CStatusMessageList getErrorMessages() const;
//! Get all warning and error messages
CStatusMessageList getWarningAndErrorMessages() const;
//! Add a category to all messages in the list //! Add a category to all messages in the list
void addCategory(const CLogCategory &category); void addCategory(const CLogCategory &category);
@@ -64,6 +79,9 @@ namespace BlackMisc
//! Reset the categories of all messages in the list //! Reset the categories of all messages in the list
void setCategories(const CLogCategoryList &categories); void setCategories(const CLogCategoryList &categories);
//! And higher (more critical) severity will be clipped to given severity
void clipSeverity(CStatusMessage::StatusSeverity severity);
//! Remove warnings and below //! Remove warnings and below
void removeWarningsAndBelow(); void removeWarningsAndBelow();

View File

@@ -47,7 +47,7 @@ CSwiftLauncher::CSwiftLauncher(QWidget *parent) :
connect(ui->tb_BackToMain, &QToolButton::pressed, this, &CSwiftLauncher::ps_showMainPage); connect(ui->tb_BackToMain, &QToolButton::pressed, this, &CSwiftLauncher::ps_showMainPage);
// use version signal as trigger for completion // use version signal as trigger for completion
connect(sGui, &CApplication::updateInfoSynchronized, this, &CSwiftLauncher::ps_loadedUpdateInfo); connect(sGui, &CApplication::updateInfoAvailable, this, &CSwiftLauncher::ps_loadedUpdateInfo);
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_L), this, SLOT(ps_showLogPage())); new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_L), this, SLOT(ps_showLogPage()));
this->ui->le_DBusServerPort->setValidator(new QIntValidator(0, 65535, this)); this->ui->le_DBusServerPort->setValidator(new QIntValidator(0, 65535, this));
@@ -287,8 +287,8 @@ void CSwiftLauncher::ps_loadSetup()
if (!this->ui->le_LatestVersion->text().isEmpty()) if (!this->ui->le_LatestVersion->text().isEmpty())
{ {
this->ui->le_LatestVersion->setText(""); this->ui->le_LatestVersion->setText("");
const CStatusMessage m(sApp->requestReloadOfSetupAndVersion()); const CStatusMessageList msgs(sApp->requestReloadOfSetupAndVersion());
this->ps_appendLogMessage(m); this->ps_appendLogMessages(msgs);
} }
} }
@@ -382,6 +382,15 @@ void CSwiftLauncher::ps_appendLogMessage(const CStatusMessage &message)
} }
} }
void CSwiftLauncher::ps_appendLogMessages(const CStatusMessageList &messages)
{
ui->fr_SwiftLauncherLog->appendStatusMessagesToList(messages);
if (messages.hasErrorMessages())
{
this->ps_showStatusMessage(messages.getErrorMessages().toSingleMessage());
}
}
void CSwiftLauncher::ps_showMainPage() void CSwiftLauncher::ps_showMainPage()
{ {
this->ui->sw_SwiftLauncher->setCurrentWidget(this->ui->pg_SwiftLauncherMain); this->ui->sw_SwiftLauncher->setCurrentWidget(this->ui->pg_SwiftLauncherMain);

View File

@@ -145,6 +145,9 @@ private slots:
//! Append status message //! Append status message
void ps_appendLogMessage(const BlackMisc::CStatusMessage &message); void ps_appendLogMessage(const BlackMisc::CStatusMessage &message);
//! Append status messages
void ps_appendLogMessages(const BlackMisc::CStatusMessageList &messages);
//! Show set main page //! Show set main page
void ps_showMainPage(); void ps_showMainPage();