From 2f91e3097aaf77e02828e6b053b088bcb36ed888 Mon Sep 17 00:00:00 2001 From: fourtf Date: Thu, 21 Jun 2018 13:02:34 +0200 Subject: [PATCH] changed settings paths --- chatterino.pro | 3 +- src/channel.cpp | 5 +- .../commands/commandcontroller.cpp | 2 +- src/main.cpp | 4 +- src/singletons/helper/loggingchannel.cpp | 5 +- src/singletons/nativemessagingmanager.cpp | 5 +- src/singletons/pathmanager.cpp | 139 ++++++++++-------- src/singletons/pathmanager.hpp | 35 +++-- src/singletons/settingsmanager.cpp | 2 +- src/singletons/windowmanager.cpp | 8 +- src/util/combine_path.hpp | 16 ++ src/util/networkrequest.cpp | 2 +- src/util/networkrequest.hpp | 4 +- src/widgets/logindialog.cpp | 15 +- src/widgets/settingspages/commandpage.cpp | 4 + .../settingspages/highlightingpage.cpp | 1 + src/widgets/settingspages/moderationpage.cpp | 2 +- 17 files changed, 158 insertions(+), 94 deletions(-) create mode 100644 src/util/combine_path.hpp diff --git a/chatterino.pro b/chatterino.pro index 8e251f257..8f90bc343 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -378,7 +378,8 @@ HEADERS += \ src/widgets/userinfopopup.hpp \ src/widgets/welcomedialog.hpp \ src/util/clamp.hpp \ - src/widgets/label.hpp + src/widgets/label.hpp \ + src/util/combine_path.hpp RESOURCES += \ resources/resources.qrc diff --git a/src/channel.cpp b/src/channel.cpp index e5156a872..90359bf52 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -71,7 +71,10 @@ void Channel::addMessage(MessagePtr message) this->addRecentChatter(message); } - app->logging->addMessage(this->name, message); + // FOURTF: change this when adding more providers + if (this->isTwitchChannel()) { + app->logging->addMessage(this->name, message); + } if (this->messages.pushBack(message, deleted)) { this->messageRemovedFromStart.invoke(deleted); diff --git a/src/controllers/commands/commandcontroller.cpp b/src/controllers/commands/commandcontroller.cpp index 2213258b8..734f2dcb9 100644 --- a/src/controllers/commands/commandcontroller.cpp +++ b/src/controllers/commands/commandcontroller.cpp @@ -40,7 +40,7 @@ CommandController::CommandController() void CommandController::load() { auto app = getApp(); - this->filePath = app->paths->customFolderPath + "/Commands.txt"; + this->filePath = app->paths->settingsDirectory + "/commands.txt"; QFile textFile(this->filePath); if (!textFile.open(QIODevice::ReadOnly)) { diff --git a/src/main.cpp b/src/main.cpp index 19e435e53..b8d9655cc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,7 +39,7 @@ int main(int argc, char *argv[]) // QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL, true); QApplication a(argc, argv); - chatterino::singletons::PathManager::initInstance(argc, argv); + chatterino::singletons::PathManager::initInstance(); // read args QStringList args; @@ -83,7 +83,7 @@ int runGui(QApplication &a, int argc, char *argv[]) auto &pathMan = *app->paths; // Running file - auto runningPath = pathMan.settingsFolderPath + "/running_" + pathMan.appPathHash; + auto runningPath = pathMan.miscDirectory + "/running_" + pathMan.applicationFilePathHash; if (QFile::exists(runningPath)) { #ifndef DISABLE_CRASH_DIALOG diff --git a/src/singletons/helper/loggingchannel.cpp b/src/singletons/helper/loggingchannel.cpp index 363157958..e41876e8a 100644 --- a/src/singletons/helper/loggingchannel.cpp +++ b/src/singletons/helper/loggingchannel.cpp @@ -25,13 +25,16 @@ LoggingChannel::LoggingChannel(const QString &_channelName) this->subDirectory = QStringLiteral("Channels") + QDir::separator() + channelName; } + // FOURTF: change this when adding more providers + this->subDirectory = "Twitch/" + this->subDirectory; + auto app = getApp(); app->settings->logPath.connect([this](const QString &logPath, auto) { auto app = getApp(); if (logPath.isEmpty()) { - this->baseDirectory = app->paths->logsFolderPath; + this->baseDirectory = app->paths->messageLogDirectory; } else { this->baseDirectory = logPath; } diff --git a/src/singletons/nativemessagingmanager.cpp b/src/singletons/nativemessagingmanager.cpp index a77c931b8..26fdf6e46 100644 --- a/src/singletons/nativemessagingmanager.cpp +++ b/src/singletons/nativemessagingmanager.cpp @@ -69,7 +69,7 @@ void NativeMessagingManager::registerHost() auto registerManifest = [&](const QString &manifestFilename, const QString ®istryKeyName, const QJsonDocument &document) { // save the manifest - QString manifestPath = app->paths->settingsFolderPath + manifestFilename; + QString manifestPath = app->paths->miscDirectory + manifestFilename; QFile file(manifestPath); file.open(QIODevice::WriteOnly | QIODevice::Truncate); file.write(document.toJson()); @@ -235,7 +235,8 @@ void NativeMessagingManager::ReceiverThread::handleMessage(const QJsonObject &ro std::string &NativeMessagingManager::getGuiMessageQueueName() { static std::string name = - "chatterino_gui" + singletons::PathManager::getInstance()->appPathHash.toStdString(); + "chatterino_gui" + + singletons::PathManager::getInstance()->applicationFilePathHash.toStdString(); return name; } diff --git a/src/singletons/pathmanager.cpp b/src/singletons/pathmanager.cpp index b830a68db..a473f47a1 100644 --- a/src/singletons/pathmanager.cpp +++ b/src/singletons/pathmanager.cpp @@ -6,76 +6,27 @@ #include #include +#include "util/combine_path.hpp" + namespace chatterino { namespace singletons { PathManager *PathManager::instance = nullptr; -PathManager::PathManager(int argc, char **argv) +PathManager::PathManager() { - // hash of app path - this->appPathHash = QCryptographicHash::hash(QCoreApplication::applicationFilePath().toUtf8(), - QCryptographicHash::Sha224) - .toBase64() - .mid(0, 32) - .replace("+", "-") - .replace("/", "x"); + this->initAppFilePathHash(); - // Options - this->portable = false; - - for (int i = 1; i < argc; ++i) { - if (strcmp(argv[i], "portable") == 0) { - this->portable = true; - } - } - - if (QFileInfo::exists(QCoreApplication::applicationDirPath() + "/this->portable")) { - this->portable = true; - } - - // Root path = %APPDATA%/Chatterino or the folder that the executable resides in - QString rootPath; - if (this->portable) { - rootPath.append(QCoreApplication::applicationDirPath()); - } else { - // Get settings path - rootPath.append(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); - if (rootPath.isEmpty()) { - throw std::runtime_error("Error finding writable location for settings"); - } - } - - this->settingsFolderPath = rootPath; - - if (!QDir().mkpath(this->settingsFolderPath)) { - throw std::runtime_error("Error creating settings folder"); - } - - this->customFolderPath = rootPath + "/Custom"; - - if (!QDir().mkpath(this->customFolderPath)) { - throw std::runtime_error("Error creating custom folder"); - } - - this->cacheFolderPath = rootPath + "/Cache"; - - if (!QDir().mkpath(this->cacheFolderPath)) { - throw std::runtime_error("Error creating cache folder"); - } - - this->logsFolderPath = rootPath + "/Logs"; - - if (!QDir().mkpath(this->logsFolderPath)) { - throw std::runtime_error("Error creating logs folder"); - } + this->initCheckPortable(); + this->initAppDataDirectory(); + this->initSubDirectories(); } -void PathManager::initInstance(int argc, char **argv) +void PathManager::initInstance() { assert(!instance); - instance = new PathManager(argc, argv); + instance = new PathManager(); } PathManager *PathManager::getInstance() @@ -92,7 +43,77 @@ bool PathManager::createFolder(const QString &folderPath) bool PathManager::isPortable() { - return this->portable; + return this->portable.get(); +} + +void PathManager::initAppFilePathHash() +{ + this->applicationFilePathHash = + QCryptographicHash::hash(QCoreApplication::applicationFilePath().toUtf8(), + QCryptographicHash::Sha224) + .toBase64() + .mid(0, 32) + .replace("+", "-") + .replace("/", "x"); +} + +void PathManager::initCheckPortable() +{ + this->portable = + QFileInfo::exists(util::combinePath(QCoreApplication::applicationDirPath(), "portable")); +} + +void PathManager::initAppDataDirectory() +{ + assert(this->portable.is_initialized()); + + // Root path = %APPDATA%/Chatterino or the folder that the executable resides in + + this->rootAppDataDirectory = [&]() -> QString { + // portable + if (this->portable) { + return QCoreApplication::applicationDirPath(); + } + + // permanent installation + QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + if (path.isEmpty()) { + throw std::runtime_error("Error finding writable location for settings"); + } + +// create directory Chatterino2 instead of chatterino on windows because the ladder one is takes by +// chatterino 1 already +#ifdef Q_OS_WIN + path.replace("chatterino", "Chatterino"); + + path += "2"; +#endif + return path; + }(); +} + +void PathManager::initSubDirectories() +{ + // required the app data directory to be set first + assert(!this->rootAppDataDirectory.isEmpty()); + + // create settings subdirectories and validate that they are created properly + auto makePath = [&](const std::string &name) -> QString { + + auto path = util::combinePath(this->rootAppDataDirectory, QString::fromStdString(name)); + + if (!QDir().mkpath(path)) { + throw std::runtime_error("Error creating appdata path %appdata%/chatterino/" + name); + } + + return path; + }; + + makePath(""); + this->settingsDirectory = makePath("Settings"); + this->cacheDirectory = makePath("Cache"); + this->messageLogDirectory = makePath("Logs"); + this->miscDirectory = makePath("Misc"); } } // namespace singletons diff --git a/src/singletons/pathmanager.hpp b/src/singletons/pathmanager.hpp index 003c4e192..27a672c15 100644 --- a/src/singletons/pathmanager.hpp +++ b/src/singletons/pathmanager.hpp @@ -1,38 +1,49 @@ #pragma once #include +#include namespace chatterino { namespace singletons { class PathManager { - PathManager(int argc, char **argv); + PathManager(); public: - static void initInstance(int argc, char **argv); + static void initInstance(); static PathManager *getInstance(); - // %APPDATA%/chatterino or ExecutablePath for portable mode - QString settingsFolderPath; + // Root directory for the configuration files. %APPDATA%/chatterino or ExecutablePath for + // portable mode + QString rootAppDataDirectory; - // %APPDATA%/chatterino/Custom or ExecutablePath/Custom for portable mode - QString customFolderPath; + // Directory for settings files. Same as /Settings + QString settingsDirectory; - // %APPDATA%/chatterino/Cache or ExecutablePath/Cache for portable mode - QString cacheFolderPath; + // Directory for cache files. Same as /Misc + QString cacheDirectory; - // Default folder for logs. %APPDATA%/chatterino/Logs or ExecutablePath/Logs for portable mode - QString logsFolderPath; + // Directory for message log files. Same as /Misc + QString messageLogDirectory; - QString appPathHash; + // Directory for miscellaneous files. Same as /Misc + QString miscDirectory; + + // Hash of QCoreApplication::applicationFilePath() + QString applicationFilePathHash; bool createFolder(const QString &folderPath); bool isPortable(); private: static PathManager *instance; - bool portable; + boost::optional portable; + + void initAppFilePathHash(); + void initCheckPortable(); + void initAppDataDirectory(); + void initSubDirectories(); }; } // namespace singletons diff --git a/src/singletons/settingsmanager.cpp b/src/singletons/settingsmanager.cpp index 27bca154e..16f0ef578 100644 --- a/src/singletons/settingsmanager.cpp +++ b/src/singletons/settingsmanager.cpp @@ -66,7 +66,7 @@ bool SettingManager::isIgnoredEmote(const QString &) void SettingManager::load() { auto app = getApp(); - QString settingsPath = app->paths->settingsFolderPath + "/settings.json"; + QString settingsPath = app->paths->settingsDirectory + "/settings.json"; pajlada::Settings::SettingManager::load(qPrintable(settingsPath)); } diff --git a/src/singletons/windowmanager.cpp b/src/singletons/windowmanager.cpp index f7734451e..f33a64c14 100644 --- a/src/singletons/windowmanager.cpp +++ b/src/singletons/windowmanager.cpp @@ -17,7 +17,7 @@ #include -#define SETTINGS_FILENAME "/layout.json" +#define SETTINGS_FILENAME "/window-layout.json" namespace chatterino { namespace singletons { @@ -157,7 +157,7 @@ void WindowManager::initialize() assert(!this->initialized); // load file - QString settingsPath = app->paths->settingsFolderPath + SETTINGS_FILENAME; + QString settingsPath = app->paths->settingsDirectory + SETTINGS_FILENAME; QFile file(settingsPath); file.open(QIODevice::ReadOnly); QByteArray data = file.readAll(); @@ -311,7 +311,7 @@ void WindowManager::save() document.setObject(obj); // save file - QString settingsPath = app->paths->settingsFolderPath + SETTINGS_FILENAME; + QString settingsPath = app->paths->settingsDirectory + SETTINGS_FILENAME; QFile file(settingsPath); file.open(QIODevice::WriteOnly | QIODevice::Truncate); @@ -459,6 +459,8 @@ float WindowManager::getUiScaleValue(int scale) return 3.5f; case 10: return 4; + default: + assert(false); } } diff --git a/src/util/combine_path.hpp b/src/util/combine_path.hpp new file mode 100644 index 000000000..79a4262b9 --- /dev/null +++ b/src/util/combine_path.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +namespace chatterino { +namespace util { + +// https://stackoverflow.com/a/13014491 +static QString combinePath(const QString &a, const QString &b) +{ + return QDir::cleanPath(a + QDir::separator() + b); +} + +} // namespace util +} // namespace chatterino diff --git a/src/util/networkrequest.cpp b/src/util/networkrequest.cpp index f62361146..f23cfedc9 100644 --- a/src/util/networkrequest.cpp +++ b/src/util/networkrequest.cpp @@ -30,7 +30,7 @@ void NetworkRequest::Data::writeToCache(const QByteArray &bytes) if (this->useQuickLoadCache) { auto app = getApp(); - QFile cachedFile(app->paths->cacheFolderPath + "/" + this->getHash()); + QFile cachedFile(app->paths->cacheDirectory + "/" + this->getHash()); if (cachedFile.open(QIODevice::WriteOnly)) { cachedFile.write(bytes); diff --git a/src/util/networkrequest.hpp b/src/util/networkrequest.hpp index e4d786747..991936da3 100644 --- a/src/util/networkrequest.hpp +++ b/src/util/networkrequest.hpp @@ -183,7 +183,7 @@ public: if (this->data.useQuickLoadCache) { auto app = getApp(); - QFile cachedFile(app->paths->cacheFolderPath + "/" + this->data.getHash()); + QFile cachedFile(app->paths->cacheDirectory + "/" + this->data.getHash()); if (cachedFile.exists()) { if (cachedFile.open(QIODevice::ReadOnly)) { @@ -329,7 +329,7 @@ private: if (this->data.useQuickLoadCache) { auto app = getApp(); - QFile cachedFile(app->paths->cacheFolderPath + "/" + this->data.getHash()); + QFile cachedFile(app->paths->cacheDirectory + "/" + this->data.getHash()); if (cachedFile.exists()) { if (cachedFile.open(QIODevice::ReadOnly)) { diff --git a/src/widgets/logindialog.cpp b/src/widgets/logindialog.cpp index 4f77ebaa7..961522e43 100644 --- a/src/widgets/logindialog.cpp +++ b/src/widgets/logindialog.cpp @@ -44,9 +44,9 @@ void LogInWithCredentials(const std::string &userID, const std::string &username return; } - QMessageBox messageBox; - messageBox.setIcon(QMessageBox::Information); - messageBox.setText("Successfully logged in with user " + qS(username) + "!"); + // QMessageBox messageBox; + // messageBox.setIcon(QMessageBox::Information); + // messageBox.setText("Successfully logged in with user " + qS(username) + "!"); pajlada::Settings::Setting::set("/accounts/uid" + userID + "/username", username); pajlada::Settings::Setting::set("/accounts/uid" + userID + "/userID", userID); pajlada::Settings::Setting::set("/accounts/uid" + userID + "/clientID", clientID); @@ -55,7 +55,7 @@ void LogInWithCredentials(const std::string &userID, const std::string &username getApp()->accounts->twitch.reloadUsers(); - messageBox.exec(); + // messageBox.exec(); } } // namespace @@ -190,9 +190,10 @@ void AdvancedLoginWidget::refreshButtons() LoginWidget::LoginWidget() { - #ifdef USEWINSDK - ::SetWindowPos((HWND)this->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); - #endif +#ifdef USEWINSDK + ::SetWindowPos((HWND)this->winId(), HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); +#endif this->setLayout(&this->ui.mainLayout); diff --git a/src/widgets/settingspages/commandpage.cpp b/src/widgets/settingspages/commandpage.cpp index 15b6f5548..fdf20789f 100644 --- a/src/widgets/settingspages/commandpage.cpp +++ b/src/widgets/settingspages/commandpage.cpp @@ -36,6 +36,10 @@ CommandPage::CommandPage() util::LayoutCreator layoutCreator(this); auto layout = layoutCreator.emplace().withoutMargin(); + auto warning = layout.emplace("The command system will be reworked in the " + "future!\nYour saved commands will get discarded then."); + warning.getElement()->setStyleSheet("color: #f00"); + helper::EditableModelView *view = *layout.emplace(app->commands->createModel(nullptr)); diff --git a/src/widgets/settingspages/highlightingpage.cpp b/src/widgets/settingspages/highlightingpage.cpp index df8a0242b..e5f0ad178 100644 --- a/src/widgets/settingspages/highlightingpage.cpp +++ b/src/widgets/settingspages/highlightingpage.cpp @@ -10,6 +10,7 @@ #include "widgets/helper/editablemodelview.hpp" #include +#include #include #include #include diff --git a/src/widgets/settingspages/moderationpage.cpp b/src/widgets/settingspages/moderationpage.cpp index c5f2070d6..e854fd17c 100644 --- a/src/widgets/settingspages/moderationpage.cpp +++ b/src/widgets/settingspages/moderationpage.cpp @@ -50,7 +50,7 @@ ModerationPage::ModerationPage() app->settings->logPath.connect([app, created](const QString &logPath, auto) mutable { if (logPath == "") { created->setText("Logs are saved to " + - CreateLink(app->paths->logsFolderPath, true)); + CreateLink(app->paths->messageLogDirectory, true)); } else { created->setText("Logs are saved to " + CreateLink(logPath, true)); }