|
|
|
|
@ -14,6 +14,8 @@
|
|
|
|
|
#include "gui_language.h" |
|
|
|
|
#include <cstdio> |
|
|
|
|
#ifdef _WIN32 |
|
|
|
|
#include <QStandardPaths> |
|
|
|
|
#include <QTemporaryFile> |
|
|
|
|
#include <windows.h> |
|
|
|
|
#include <tlhelp32.h> |
|
|
|
|
#endif |
|
|
|
|
@ -85,9 +87,44 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
app.setQuitOnLastWindowClosed(false); |
|
|
|
|
debug_config_init(); |
|
|
|
|
|
|
|
|
|
QString cfgDir = QCoreApplication::applicationDirPath(); |
|
|
|
|
#ifdef _WIN32 |
|
|
|
|
QString storageReason; |
|
|
|
|
if (!QFile::exists(cfgDir + "/vibechat.cfg") && !QFile::exists(cfgDir + "/chatgui.cfg")) { |
|
|
|
|
storageReason = QStringLiteral("config missing in executable directory"); |
|
|
|
|
} else { |
|
|
|
|
/* Реальная проверка записи учитывает ACL Windows, а не только атрибуты каталога. */ |
|
|
|
|
QTemporaryFile probe(cfgDir + "/.vibechat-write-XXXXXX"); |
|
|
|
|
if (!probe.open()) { |
|
|
|
|
storageReason = QStringLiteral("executable directory is not writable: %1").arg(probe.errorString()); |
|
|
|
|
} else if (!probe.remove()) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Cannot remove write probe %s: %s", |
|
|
|
|
qPrintable(probe.fileName()), qPrintable(probe.errorString())); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!storageReason.isEmpty()) { |
|
|
|
|
cfgDir = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); |
|
|
|
|
if (cfgDir.isEmpty() || !QDir().mkpath(cfgDir)) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Cannot create LocalAppData directory %s; fallback reason: %s", |
|
|
|
|
qPrintable(cfgDir), qPrintable(storageReason)); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
storageReason = QStringLiteral("config found in writable executable directory"); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* Блокировка до любых изменений конфига/БД; предупреждение после загрузки языка. */ |
|
|
|
|
QLockFile lock(QCoreApplication::applicationDirPath() + "/vibechat.lock"); |
|
|
|
|
QLockFile lock(cfgDir + "/vibechat.lock"); |
|
|
|
|
const bool locked = lock.tryLock(); |
|
|
|
|
#ifdef _WIN32 |
|
|
|
|
if (!locked && lock.error() != QLockFile::LockFailedError) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Cannot lock data directory %s: error=%d; selection reason: %s", |
|
|
|
|
qPrintable(cfgDir), static_cast<int>(lock.error()), qPrintable(storageReason)); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
app.setStyle(QStyleFactory::create("Fusion")); |
|
|
|
|
QPalette p; |
|
|
|
|
@ -108,7 +145,6 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(127, 127, 127)); |
|
|
|
|
app.setPalette(p); |
|
|
|
|
|
|
|
|
|
QString cfgDir = QCoreApplication::applicationDirPath(); |
|
|
|
|
QString cfgPath = cfgDir + "/vibechat.cfg"; |
|
|
|
|
/* миграция: старый конфиг chatgui.cfg → vibechat.cfg */ |
|
|
|
|
if (locked && !QFile::exists(cfgPath) && QFile::exists(cfgDir + "/chatgui.cfg")) |
|
|
|
|
@ -166,13 +202,13 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
QString dbPath = cfg.dbPath(); |
|
|
|
|
if (dbPath.isEmpty()) dbPath = "chat_data"; |
|
|
|
|
if (!QDir::isAbsolutePath(dbPath)) |
|
|
|
|
dbPath = QCoreApplication::applicationDirPath() + "/" + dbPath; |
|
|
|
|
dbPath = cfgDir + "/" + dbPath; |
|
|
|
|
QDir(dbPath).mkpath("."); |
|
|
|
|
|
|
|
|
|
QString debugFile = cfg.debugFile(); |
|
|
|
|
if (debugFile.isEmpty()) debugFile = "chatgui.log"; |
|
|
|
|
if (!QDir::isAbsolutePath(debugFile)) |
|
|
|
|
debugFile = QCoreApplication::applicationDirPath() + "/" + debugFile; |
|
|
|
|
debugFile = cfgDir + "/" + debugFile; |
|
|
|
|
|
|
|
|
|
/* ранняя инициализация лога в GUI-потоке: SoundManager::init() вызывается в
|
|
|
|
|
* конструкторе MainWindow ДО старта utun-потока, поэтому без этого его диагностика |
|
|
|
|
@ -183,6 +219,11 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
if (lvl.isEmpty()) lvl = QStringLiteral("info"); |
|
|
|
|
debug_apply_global_level(lvl.toUtf8().constData()); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "vibechat: version=%s", qPrintable(app.applicationVersion())); |
|
|
|
|
#ifdef _WIN32 |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "Windows storage: reason=%s config=%s db=%s log=%s lock=%s", |
|
|
|
|
qPrintable(storageReason), qPrintable(cfgPath), qPrintable(dbPath), qPrintable(debugFile), |
|
|
|
|
qPrintable(cfgDir + "/vibechat.lock")); |
|
|
|
|
#endif |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "GUI language: preference=%s system=%s selected=%s", |
|
|
|
|
qPrintable(cfg.language()), qPrintable(QLocale::system().uiLanguages().join(',')), qPrintable(language)); |
|
|
|
|
|
|
|
|
|
|