summaryrefslogtreecommitdiff
path: root/src/main_window.cpp
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2024-09-30 00:36:19 -0500
committerDominick Allen <djallen@librehumanitas.org>2024-09-30 00:36:19 -0500
commit6f2b61b676a16482fdac70a58a8e875c4d68e713 (patch)
treee2f8b2376847b5b13b278572c0fae8a6bc4d0e82 /src/main_window.cpp
parentdacd752bbf46f2afb08b4b8d730ba3619528dda4 (diff)
Add configuration handling.
Diffstat (limited to 'src/main_window.cpp')
-rw-r--r--src/main_window.cpp147
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);
}