diff options
author | Dominick Allen <djallen@librehumanitas.org> | 2024-09-30 00:36:19 -0500 |
---|---|---|
committer | Dominick Allen <djallen@librehumanitas.org> | 2024-09-30 00:36:19 -0500 |
commit | 6f2b61b676a16482fdac70a58a8e875c4d68e713 (patch) | |
tree | e2f8b2376847b5b13b278572c0fae8a6bc4d0e82 /src/main_window.cpp | |
parent | dacd752bbf46f2afb08b4b8d730ba3619528dda4 (diff) |
Add configuration handling.
Diffstat (limited to 'src/main_window.cpp')
-rw-r--r-- | src/main_window.cpp | 147 |
1 files changed, 127 insertions, 20 deletions
diff --git a/src/main_window.cpp b/src/main_window.cpp index a554358..007705f 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -1,27 +1,112 @@ #include "main_window.hpp" #include "config.hpp" +#include "luacxx.hpp" #include <QString> +#include <cerrno> #include <filesystem> #include <fud_result.hpp> #include <fud_status.hpp> #include <string> +#include <sys/stat.h> +#include <fcntl.h> #include <vector> -#include <zip.h> namespace getsuyomi { using fud::FudStatus; using GetEnvResult = fud::Result<GetsuyomiConfig, FudStatus>; +using GetConfigResult = fud::Result<GetsuyomiConfig, FudStatus>; constexpr const char* HOME{"HOME"}; std::optional<std::string> getEnvVar(const char* envVar); -void getEnvVar(const std::string envVar, std::string& envValue, const char* backup); +void getEnvVar(const std::string& homeVar, const std::string& envVar, std::string& envValue, const char* backup); GetEnvResult getEnvironment(); -GetsuyomiApp::GetsuyomiApp() : m_getsuyomi{new Getsuyomi()} +FudStatus createXdgDirectory(const std::string& directoryName) +{ + constexpr mode_t xdgMode = 0700; + auto dirStatus = mkdir(directoryName.c_str(), xdgMode); + if (dirStatus == 0) + { + return FudStatus::Success; + } + + if (errno != EEXIST) { + return FudStatus::Failure; + } + struct stat statBuffer{}; + dirStatus = stat(directoryName.c_str(), &statBuffer); + + if (dirStatus != 0) { + return FudStatus::Failure; + } + + if ((statBuffer.st_mode & S_IFMT) != S_IFDIR) { + return FudStatus::Failure; + } + + return FudStatus::Success; +} + +GetConfigResult getUserConfig() +{ + auto configResult = getEnvironment(); + if (configResult.isError()) { + return GetConfigResult::error(configResult.getError()); + } + auto config = configResult.getOkay(); + + auto dirStatus = createXdgDirectory(config.dataHome); + if (dirStatus != FudStatus::Success) { + return GetConfigResult::error(dirStatus); + } + dirStatus = createXdgDirectory(config.configHome); + if (dirStatus != FudStatus::Success) { + return GetConfigResult::error(dirStatus); + } + dirStatus = createXdgDirectory(config.stateHome); + if (dirStatus != FudStatus::Success) { + return GetConfigResult::error(dirStatus); + } + + LuaContext luaContext{}; + if (!luaContext.valid()) { + return GetConfigResult::error(FudStatus::Failure); + } + + auto configFileName = std::filesystem::path(config.configHome).append("config.lua"); + qDebug("configFileName is %s", configFileName.c_str()); + + constexpr mode_t configFileMode = 0600; + auto fdResult = open(configFileName.c_str(), O_CREAT, configFileMode); + if (fdResult == -1) { + if (errno != EEXIST) { + return GetConfigResult::error(FudStatus::Failure); + } + } + close(fdResult); + + auto luaStatus = luaContext.loadFile(configFileName.c_str()); + if (luaStatus != FudStatus::Success) + { + qCritical("Failed to load file in lua %s", fud::FudStatusToString(luaStatus)); + return GetConfigResult::error(luaStatus); + } + + auto result = luaContext.getGlobalString(actionTypeToString(ActionType::OpenFile)); + if (result.isError()) + { + qCritical("Failed to get variable from lua %s", fud::FudStatusToString(result.getError())); + return GetConfigResult::error(result.getError()); + } + + return GetConfigResult::okay(config); +} + +GetsuyomiApp::GetsuyomiApp() : QMainWindow(nullptr), m_getsuyomi{new Getsuyomi(this)} { readSettings(); } @@ -34,10 +119,12 @@ FudStatus GetsuyomiApp::setup() QCoreApplication::setApplicationVersion(AppVersionString); setWindowTitle(AppName); - auto envResult = getEnvironment(); + auto envResult = getUserConfig(); if (envResult.isError()) { + qCritical("Failure %s", fud::FudStatusToString(envResult.getError())); return envResult.getError(); } + m_config = envResult.getOkay(); createActions(); createMenus(); @@ -59,7 +146,7 @@ void GetsuyomiApp::createActions() m_openFile->setStatusTip(tr("Open a file")); connect(m_openFile, &QAction::triggered, this, &GetsuyomiApp::openFile); - m_openDirectory = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::FolderOpen), tr("Open Directory"), this); + m_openDirectory = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::FolderOpen), tr("Open &Directory"), this); m_openDirectory->setShortcut(Qt::CTRL | Qt::ALT | Qt::Key_O); m_openDirectory->setStatusTip(tr("Open a directory")); connect(m_openDirectory, &QAction::triggered, this, &GetsuyomiApp::openDirectory); @@ -69,6 +156,11 @@ void GetsuyomiApp::createActions() m_quitAction->setStatusTip(tr("Quit")); connect(m_quitAction, &QAction::triggered, this, &GetsuyomiApp::quit); + m_settingsAction = new QAction(QIcon("resources/gear.svg"), tr("&Settings"), this); + m_settingsAction->setShortcut(Qt::CTRL | Qt::Key_P); + m_settingsAction->setStatusTip(tr("Configure getsuyomi")); + connect(m_settingsAction, &QAction::triggered, this, &GetsuyomiApp::configure); + auto nextShortcuts = QList<QKeySequence>{}; nextShortcuts.append(QKeySequence{Qt::Key_L}); nextShortcuts.append(QKeySequence{Qt::Key_Right}); @@ -111,17 +203,24 @@ void GetsuyomiApp::createActions() void GetsuyomiApp::createMenus() { - m_menuBar = menuBar()->addMenu(tr("&File")); - m_menuBar->addAction(m_openFile); - m_menuBar->addAction(m_openDirectory); - m_menuBar->addAction(m_quitAction); + m_fileMenu = menuBar()->addMenu(tr("&File")); + m_fileMenu->addAction(m_openFile); + m_fileMenu->addAction(m_openDirectory); + m_fileMenu->addAction(m_quitAction); + + m_SettingsMenu = menuBar()->addMenu(tr("&Settings")); + m_SettingsMenu->addAction(m_settingsAction); } void GetsuyomiApp::createToolBar() { m_toolBar = addToolBar(tr("&Navigation")); + m_toolBar->setObjectName("Navigation"); + + // goto first m_toolBar->addAction(m_backAction); m_toolBar->addAction(m_nextAction); + // goto last m_toolBar->addSeparator(); @@ -170,10 +269,7 @@ void GetsuyomiApp::openFile() void GetsuyomiApp::openDirectory() { - auto dialog = QFileDialog( - this, - tr("Open Directory"), - m_lastOpenedDirectory); + auto dialog = QFileDialog(this, tr("Open Directory"), m_lastOpenedDirectory); dialog.setFileMode(QFileDialog::Directory); QString directoryName; if (dialog.exec()) { @@ -199,6 +295,16 @@ void GetsuyomiApp::quit() QCoreApplication::quit(); } +void GetsuyomiApp::configure() +{ + Settings settings(this, m_config.shortcuts()); + if (!settings.valid()) { + qCritical("Invalid settings"); + return; + } + settings.exec(); +} + void GetsuyomiApp::next() { m_getsuyomi->next(); @@ -270,16 +376,17 @@ std::optional<std::string> getEnvVar(const char* envVar) return varArray.toStdString(); } -void getEnvVar(const std::string envVar, std::string& envValue, const char* backup) +void getEnvVar(const std::string& homeVar, const std::string& envVar, std::string& envValue, const char* backup) { auto envValueOpt = getEnvVar(envVar.c_str()); + std::filesystem::path envValuePath{homeVar}; if (envValueOpt == std::nullopt || envValueOpt->length() == 0) { - std::filesystem::path envValuePath{HOME}; envValuePath.append(backup); - envValue = envValuePath; } else { - envValue = *envValueOpt; + envValuePath = *envValueOpt; } + envValuePath.append(AppName); + envValue = envValuePath; // qDebug("%s is %s", envVar.c_str(), envValue.c_str()); } @@ -297,15 +404,15 @@ GetEnvResult getEnvironment() /* If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used. */ const std::string XdgDataHome{"XDG_DATA_HOME"}; - getEnvVar(XdgDataHome, config.dataHome, ".local/share"); + getEnvVar(config.home, XdgDataHome, config.dataHome, ".local/share"); /* If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used. */ const std::string XdgConfigHome{"XDG_CONFIG_HOME"}; - getEnvVar(XdgConfigHome, config.configHome, ".config"); + getEnvVar(config.home, XdgConfigHome, config.configHome, ".config"); /* If $XDG_STATE_HOME is either not set or empty, a default equal to $HOME/.local/state should be used. */ const std::string XdgStateHome{"XDG_STATE_HOME"}; - getEnvVar(XdgStateHome, config.stateHome, ".local/state"); + getEnvVar(config.home, XdgStateHome, config.stateHome, ".local/state"); return GetEnvResult::okay(config); } |