Use LocalAppData fallback for Windows ChatGUI storage
This commit is contained in:
1 parent
b6f80668d1
commit
753aa4217d
2 files changed
+52
-4
No files matched your search
@@ -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));
|
||||
|
||||
|
||||
@@ -53,6 +53,9 @@ extern "C" {
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QDir>
|
||||
#ifdef _WIN32
|
||||
#include <QFileInfo>
|
||||
#endif
|
||||
#include <cmath>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
@@ -362,7 +365,11 @@ void MainWindow::setupSoundFromConfig() {
|
||||
}
|
||||
|
||||
if (soundDir.isEmpty()) soundDir = "sounds";
|
||||
#ifdef _WIN32
|
||||
QDir binDir(QFileInfo(m_cfgPath).absolutePath());
|
||||
#else
|
||||
QDir binDir(QApplication::applicationDirPath());
|
||||
#endif
|
||||
QString baseDir = QDir::isAbsolutePath(soundDir) ? soundDir : binDir.absoluteFilePath(soundDir);
|
||||
auto resolvePath = [&baseDir](const QString& f) { return f.isEmpty() ? QString() : QDir::cleanPath(baseDir + "/" + f); };
|
||||
|
||||
|
||||
Reference in new issue
Block a user