Ref T103, verify important files/directories

* utility function in CDirectoryUtils
* deployed in main/application
This commit is contained in:
Klaus Basan
2017-07-07 19:31:15 +02:00
committed by Mathew Sutcliffe
parent d25be35868
commit 07b096b398
9 changed files with 68 additions and 16 deletions

View File

@@ -102,7 +102,7 @@ namespace BlackCore
Q_ASSERT_X(!sApp, Q_FUNC_INFO, "already initialized");
Q_ASSERT_X(QCoreApplication::instance(), Q_FUNC_INFO, "no application object");
// init skiped when called from CGuiApplication
// init skipped when called from CGuiApplication
if (init)
{
this->init(true);
@@ -133,8 +133,6 @@ namespace BlackCore
//
// Translations
const QFile file(":blackmisc/translations/blackmisc_i18n_de.qm");
CLogMessage(this).debug() << (file.exists() ? "Found translations in resources" : "No translations in resources");
QTranslator translator;
if (translator.load("blackmisc_i18n_de", ":blackmisc/translations/")) { CLogMessage(this).debug() << "Translator loaded"; }
QCoreApplication::instance()->installTranslator(&translator);
@@ -315,7 +313,7 @@ namespace BlackCore
// parse if needed, parsing contains its own error handling
if (!this->m_parsed)
{
const bool s = this->parse();
const bool s = this->parseAndStartupCheck();
if (!s) { return false; }
}
@@ -985,15 +983,24 @@ namespace BlackCore
return this->m_parser.value(option).trimmed();
}
bool CApplication::parse()
bool CApplication::parseAndStartupCheck()
{
if (this->m_parsed) { return m_parsed; }
if (this->m_parsed) { return m_parsed; } // already done
// checks
if (CBuildConfig::isLifetimeExpired())
{
this->cmdLineErrorMessage("Program exired " + CBuildConfig::getEol().toString());
return false;
}
const QStringList verifyErrors = CDirectoryUtils::verifyRuntimeDirectoriesAndFiles();
if (!verifyErrors.isEmpty())
{
this->cmdLineErrorMessage("Missing runtime directories/files: " + verifyErrors.join(", "));
return false;
}
if (this->m_singleApplication && this->m_alreadyRunning)
{
this->cmdLineErrorMessage("Program must only run once");
@@ -1036,7 +1043,7 @@ namespace BlackCore
bool CApplication::cmdLineErrorMessage(const QString &errorMessage, bool retry) const
{
Q_UNUSED(retry); // onyl works with UI version
Q_UNUSED(retry); // only works with UI version
fputs(qPrintable(errorMessage), stderr);
fputs("\n\n", stderr);
fputs(qPrintable(this->m_parser.helpText()), stderr);
@@ -1045,7 +1052,7 @@ namespace BlackCore
bool CApplication::cmdLineErrorMessage(const CStatusMessageList &msgs, bool retry) const
{
Q_UNUSED(retry); // onyl works with UI version
Q_UNUSED(retry); // only works with UI version
if (msgs.isEmpty()) { return false; }
if (!msgs.hasErrorMessages()) { return false; }
CApplication::cmdLineErrorMessage(

View File

@@ -290,7 +290,7 @@ namespace BlackCore
//! \note in some cases (error, version, help) application is terminated during this step
//! \sa parsingHookIn
//! \return true means to continue, false to stop
bool parse();
bool parseAndStartupCheck();
//! @}
//! Display error message

View File

@@ -263,9 +263,23 @@ namespace BlackGui
bool CGuiApplication::cmdLineErrorMessage(const QString &errorMessage, bool retry) const
{
const QString helpText(beautifyHelpMessage(this->m_parser.helpText()));
constexpr int MaxLength = 60;
QString htmlMsg;
if (errorMessage.length() > MaxLength)
{
htmlMsg = "<html><head/><body><h4>" + errorMessage.left(MaxLength) + "..." + "</h4>" +
"Details: " + errorMessage + "<br><br>";
}
else
{
htmlMsg = "<html><head/><body><h4>" + errorMessage + "</h4>";
}
htmlMsg += helpText + "</body></html>";
const int r = QMessageBox::warning(nullptr,
QGuiApplication::applicationDisplayName(),
"<html><head/><body><h2>" + errorMessage + "</h2><br>" + helpText + "</body></html>", QMessageBox::Abort, retry ? QMessageBox::Retry : QMessageBox::NoButton);
htmlMsg, QMessageBox::Abort, retry ? QMessageBox::Retry : QMessageBox::NoButton);
return (r == QMessageBox::Retry);
}
@@ -279,7 +293,7 @@ namespace BlackGui
const QString msgsHtml = msgs.toHtml(msgs.size() > 1 ? propertiesMulti : propertiesSingle);
const int r = QMessageBox::critical(nullptr,
QGuiApplication::applicationDisplayName(),
"<html><head/><body>" + msgsHtml + "<br><br>" + helpText + "</body></html>", QMessageBox::Abort, retry ? QMessageBox::Retry : QMessageBox::NoButton);
"<html><head><body>" + msgsHtml + "<br><br>" + helpText + "</body></html>", QMessageBox::Abort, retry ? QMessageBox::Retry : QMessageBox::NoButton);
return (r == QMessageBox::Retry);
}

View File

@@ -327,6 +327,34 @@ namespace BlackMisc
return dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
}
QStringList CDirectoryUtils::verifyRuntimeDirectoriesAndFiles()
{
QStringList failed;
QDir d(CDirectoryUtils::binDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(CDirectoryUtils::imagesDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(CDirectoryUtils::stylesheetsDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(CDirectoryUtils::applicationDataDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
// check if the executables are avialable
QString fn = CDirectoryUtils::executableFilePath(CBuildConfig::swiftCoreExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
fn = CDirectoryUtils::executableFilePath(CBuildConfig::swiftDataExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
fn = CDirectoryUtils::executableFilePath(CBuildConfig::swiftGuiExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
return failed;
}
QSet<QString> CDirectoryUtils::fileNamesToQSet(const QFileInfoList &fileInfoList)
{
QSet<QString> sl;

View File

@@ -100,7 +100,7 @@ namespace BlackMisc
//! \remark In BlackMisc so it can also be used from BlackMisc classes
static const QString &logDirectory();
//! Directory for log files
//! Directory for crashpad files
static const QString &crashpadDirectory();
//! Virtually the inverse operation of CDirectoryUtils::normalizedApplicationDirectory
@@ -109,6 +109,9 @@ namespace BlackMisc
//! All sub directories of given dir
static QStringList getSubDirectories(const QString &rootDir);
//! Check if the (most important) runtime directories are available
static QStringList verifyRuntimeDirectoriesAndFiles();
//! Result of directory comparison
struct DirComparison
{

View File

@@ -35,7 +35,7 @@ int main(int argc, char *argv[])
a.addVatlibOptions();
a.addParserOption({{"r", "start"}, QCoreApplication::translate("main", "Start the server.")});
a.addParserOption({{"c", "coreaudio"}, QCoreApplication::translate("main", "Audio in core.")});
if (!a.parse()) { return EXIT_FAILURE; }
if (!a.parseAndStartupCheck()) { return EXIT_FAILURE; }
const QString dBusAdress(a.getCmdDBusAddressValue());
a.useContexts(a.isParserOptionSet("coreaudio") ?

View File

@@ -30,7 +30,7 @@ int main(int argc, char *argv[])
CGuiApplication a(CApplicationInfo::swiftMappingTool(), CApplicationInfo::MappingTool, CIcons::swiftDatabase48());
a.setSignalStartupAutomatically(false); // application will signal startup on its own
a.splashScreen(CIcons::swiftDatabase256());
if (!a.parse()) { return EXIT_FAILURE; }
if (!a.parseAndStartupCheck()) { return EXIT_FAILURE; }
a.useWebDataServices(BlackCore::CWebReaderFlags::AllSwiftDbReaders, CDatabaseReaderConfigList::forMappingTool());
if (!a.start())
{

View File

@@ -29,7 +29,7 @@ int main(int argc, char *argv[])
CSwiftGuiStdApplication a;
a.setSignalStartupAutomatically(false); // application will signal startup on its own
a.splashScreen(CIcons::swift256());
if (!a.parse()) { return EXIT_FAILURE; }
if (!a.parseAndStartupCheck()) { return EXIT_FAILURE; }
if (!a.hasSetupReader() || !a.start())
{
a.gracefulShutdown();

View File

@@ -35,7 +35,7 @@ int main(int argc, char *argv[])
Q_UNUSED(qa);
CGuiApplication a(CApplicationInfo::swiftLauncher(), CApplicationInfo::Laucher, CIcons::swiftLauncher1024());
a.addParserOption({{"i", "installer"}, QCoreApplication::translate("main", "Installer setup.") });
if (!a.parse()) { return EXIT_FAILURE; }
if (!a.parseAndStartupCheck()) { return EXIT_FAILURE; }
a.useWebDataServices(BlackCore::CWebReaderFlags::AllSwiftDbReaders, CDatabaseReaderConfigList::forLauncher());
if (!a.start())
{