summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.cpp157
-rw-r--r--src/config.hpp18
-rw-r--r--src/luacxx.cpp9
-rw-r--r--src/main_window.cpp74
4 files changed, 196 insertions, 62 deletions
diff --git a/src/config.cpp b/src/config.cpp
index 6405e2b..1ab2b93 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -1,6 +1,9 @@
#include "config.hpp"
+#include "luacxx.hpp"
+
#include <algorithm>
+#include <fcntl.h>
#include <vector>
namespace getsuyomi {
@@ -16,14 +19,27 @@ ShortcutSet shortcutSetFromList(const ShortcutList& shortcutList)
return shortcutSet;
}
+ShortcutList shortcutListFromSet(const ShortcutSet& shortcutSet)
+{
+ ShortcutList shortcutList{};
+ for (const auto& entry : shortcutSet) {
+ shortcutList.push_back(entry);
+ }
+ return shortcutList;
+}
+
Shortcuts::Shortcuts(ShortcutMap&& shortcutMap) :
m_actionToShortcuts{std::move(shortcutMap)}, m_shortcuts{}, m_shortcutToAction{}
{
for (const auto& [action, shortcuts] : m_actionToShortcuts) {
for (const auto& shortcut : shortcuts) {
qDebug("Working on action %s", actionTypeToString(action));
- if (bind(action, shortcut) != FudStatus::Success) {
+ auto bindResult = bind(action, shortcut);
+ if (bindResult != FudStatus::Success) {
+ qWarning("Error: %s", FudStatusToString(bindResult));
return;
+ } else {
+ qDebug("Bound %s to %s", qPrintable(shortcut.toString()), actionTypeToString(action));
}
}
}
@@ -40,7 +56,8 @@ bool Shortcuts::contains(ActionType actionType) const
return m_actionToShortcuts.contains(actionType);
}
-std::vector<ActionType> Shortcuts::actions() const {
+std::vector<ActionType> Shortcuts::actions() const
+{
std::vector<ActionType> actionList{};
actionList.reserve(m_actionToShortcuts.size());
for (const auto& [action, discarded] : m_actionToShortcuts) {
@@ -69,6 +86,7 @@ std::optional<ShortcutList> Shortcuts::shortcuts(ActionType action) const
}
return shortcutList;
} else {
+ qWarning("Action %s not found", actionTypeToString(action));
return std::nullopt;
}
}
@@ -122,10 +140,123 @@ fud::FudStatus Shortcuts::clear(ActionType action)
return FudStatus::Success;
}
-bool Shortcuts::valid() const {
+bool Shortcuts::valid() const
+{
return m_valid;
}
+const ShortcutMap& Shortcuts::shortcutMap() const
+{
+ return m_actionToShortcuts;
+}
+
+Shortcuts Shortcuts::fromLuaConfig(const std::filesystem::path& configFileName)
+{
+ Shortcuts shortcuts{};
+ shortcuts.m_valid = true;
+
+ LuaContext luaContext{};
+ if (!luaContext.valid()) {
+ qCritical("Failed to create lua context");
+ return shortcuts;
+ }
+
+ auto luaStatus = luaContext.loadFile(configFileName.c_str());
+ if (luaStatus != FudStatus::Success) {
+ qCritical("Failed to load file in lua %s", fud::FudStatusToString(luaStatus));
+ return shortcuts;
+ }
+
+ std::vector<ActionType> actions{
+ ActionType::OpenFile,
+ ActionType::OpenDirectory,
+ ActionType::Quit,
+ ActionType::Configure,
+ // ActionType::Help,
+ // ActionType::About
+ // ActionType::GotoFirst,
+ ActionType::Next,
+ ActionType::Back,
+ // ActionType::GotoLast,
+ ActionType::SinglePage,
+ ActionType::DualPage,
+ ActionType::MangaPage};
+
+ for (auto action : actions) {
+ auto result = luaContext.getGlobalStringArray(actionTypeToString(action));
+ if (result.isError()) {
+ qWarning(
+ "Failed to get variable %s from lua %s",
+ actionTypeToString(action),
+ fud::FudStatusToString(result.getError()));
+ // return RetType::error(result.getError());
+ continue;
+ }
+
+ auto actionBindings = result.getOkay();
+
+ for (const auto& shortcut : actionBindings) {
+ QKeySequence keySeq{shortcut.c_str()};
+ if (keySeq == Qt::Key_unknown) {
+ qCritical("Error: shortcut %s unknown", shortcut.c_str());
+ continue;
+ }
+ auto bindStatus = shortcuts.bind(action, keySeq);
+ if (bindStatus != FudStatus::Success) {
+ qCritical(
+ "Error: failure to bind to action %s keySeq %s",
+ actionTypeToString(action),
+ shortcut.c_str());
+ continue;
+ }
+ }
+ }
+
+ return shortcuts;
+}
+
+ShortcutMap Shortcuts::fromUserConfig(const std::filesystem::path& configFileName)
+{
+ constexpr mode_t configFileMode = 0600;
+ auto fdResult = open(configFileName.c_str(), O_CREAT, configFileMode);
+ if (fdResult == -1) {
+ if (errno != EEXIST) {
+ qCritical("Could not load or create user config file %s.", configFileName.c_str());
+ }
+ }
+ close(fdResult);
+
+ auto shortcuts = Shortcuts::fromLuaConfig(configFileName);
+
+ auto binder = [&](ActionType action, QKeySequence keySeq) {
+ auto bindDefaultStatus = shortcuts.bind(action, keySeq);
+ if (bindDefaultStatus != FudStatus::Success) {
+ qDebug("%s already bound", actionTypeToString(action));
+ }
+ };
+ binder(ActionType::OpenFile, QKeySequence(QKeySequence::Open));
+ binder(ActionType::OpenDirectory, QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_O));
+ binder(ActionType::Quit, QKeySequence(QKeySequence::Quit));
+
+ binder(ActionType::Configure, QKeySequence(Qt::CTRL | Qt::Key_P));
+
+ ShortcutList nextDefaults{QKeySequence{Qt::Key_L}, QKeySequence{Qt::Key_Right}, QKeySequence{Qt::Key_Down}};
+ for (const auto& binding : nextDefaults) {
+ binder(ActionType::Next, binding);
+ }
+
+ ShortcutList backDefaults{QKeySequence{Qt::Key_H}, QKeySequence{Qt::Key_Left}, QKeySequence{Qt::Key_Up}};
+ for (const auto& binding : backDefaults) {
+ binder(ActionType::Back, binding);
+ }
+
+ binder(ActionType::SinglePage, QKeySequence{Qt::Key_S});
+ binder(ActionType::DualPage, QKeySequence{Qt::Key_D});
+ binder(ActionType::MangaPage, QKeySequence{Qt::Key_M});
+
+ return shortcuts.shortcutMap();
+}
+
ShortcutMap GetsuyomiConfig::shortcuts() const
{
ShortcutMap shortcuts{};
@@ -133,10 +264,16 @@ ShortcutMap GetsuyomiConfig::shortcuts() const
shortcuts.insert({ActionType::OpenFile, shortcutSetFromList(openFileShortcuts)});
shortcuts.insert({ActionType::OpenDirectory, shortcutSetFromList(openDirectoryShortcuts)});
shortcuts.insert({ActionType::Quit, shortcutSetFromList(quitShortcuts)});
+
shortcuts.insert({ActionType::Configure, shortcutSetFromList(settingsShortcuts)});
+
shortcuts.insert({ActionType::Next, shortcutSetFromList(nextShortcuts)});
shortcuts.insert({ActionType::Back, shortcutSetFromList(backShortcuts)});
+ shortcuts.insert({ActionType::SinglePage, shortcutSetFromList(singlePageShortcuts)});
+ shortcuts.insert({ActionType::DualPage, shortcutSetFromList(dualPageShortcuts)});
+ shortcuts.insert({ActionType::MangaPage, shortcutSetFromList(mangaPageShortcuts)});
+
return shortcuts;
}
@@ -172,13 +309,13 @@ ShortcutCollector::ShortcutCollector(QWidget* parent, ActionType action, Shortcu
setLayout(m_layout);
}
-void ShortcutCollector::removeShortcut(int row, int) {
+void ShortcutCollector::removeShortcut(int row, int)
+{
auto keySequence = m_actionList[row];
auto result = m_shortcuts.remove(keySequence);
if (result == FudStatus::Success) {
m_actionList.removeAt(row);
- }
- else {
+ } else {
qCritical("What");
}
}
@@ -193,18 +330,20 @@ Settings::Settings(QWidget* parent, Shortcuts&& shortcuts) : QDialog{parent}, m_
}
for (const auto& action : m_shortcuts.actions()) {
- auto* collector = new ShortcutCollector(this, action, shortcuts);
+ auto* collector = new ShortcutCollector(this, action, m_shortcuts);
layout->addWidget(collector);
}
setLayout(layout);
}
-bool Settings::valid() const {
+bool Settings::valid() const
+{
return m_shortcuts.valid();
}
-const Shortcuts& Settings::shortcuts() const {
+const Shortcuts& Settings::shortcuts() const
+{
return m_shortcuts;
}
diff --git a/src/config.hpp b/src/config.hpp
index 81da2dc..95df6b6 100644
--- a/src/config.hpp
+++ b/src/config.hpp
@@ -3,6 +3,7 @@
#include <QtWidgets>
#include <fud_status.hpp>
+#include <fud_result.hpp>
#include <map>
#include <optional>
#include <qkeysequence.h>
@@ -69,6 +70,7 @@ using ShortcutMap = std::map<ActionType, ShortcutSet>;
using ShortcutRevMap = std::map<QKeySequence, ActionType>;
ShortcutSet shortcutSetFromList(const ShortcutList& shortcutList);
+ShortcutList shortcutListFromSet(const ShortcutSet& shortcutList);
class Shortcuts {
public:
@@ -91,12 +93,18 @@ class Shortcuts {
const ShortcutMap& shortcutMap() const;
+ static ShortcutMap fromUserConfig(const std::filesystem::path& configFileName);
+
private:
+ Shortcuts() = default;
+
+ static Shortcuts fromLuaConfig(const std::filesystem::path& configFileName);
+
bool m_valid{false};
- ShortcutMap m_actionToShortcuts;
- ShortcutSet m_shortcuts;
- ShortcutRevMap m_shortcutToAction;
+ ShortcutMap m_actionToShortcuts{};
+ ShortcutSet m_shortcuts{};
+ ShortcutRevMap m_shortcutToAction{};
};
struct GetsuyomiConfig {
@@ -114,6 +122,10 @@ struct GetsuyomiConfig {
ShortcutList nextShortcuts{};
ShortcutList backShortcuts{};
+ ShortcutList singlePageShortcuts{};
+ ShortcutList dualPageShortcuts{};
+ ShortcutList mangaPageShortcuts{};
+
ShortcutMap shortcuts() const;
};
diff --git a/src/luacxx.cpp b/src/luacxx.cpp
index 926e30f..c4bc063 100644
--- a/src/luacxx.cpp
+++ b/src/luacxx.cpp
@@ -102,11 +102,14 @@ LuaResult<std::vector<std::string>> LuaContext::getGlobalStringArray(const char*
}
auto luaType = lua_getglobal(m_state, name);
- static_cast<void>(luaType);
+ if (luaType == LUA_TNONE || luaType == LUA_TNIL) {
+ lua_pop(m_state, 1);
+ return RetType::error(FudStatus::NotFound);
+ }
- if (!lua_istable(m_state, -1)) {
+ if (luaType != LUA_TTABLE) {
lua_pop(m_state, 1);
- return RetType::error(FudStatus::Failure);
+ return RetType::error(FudStatus::InvalidInput);
}
int64_t length;
diff --git a/src/main_window.cpp b/src/main_window.cpp
index 007705f..dea951c 100644
--- a/src/main_window.cpp
+++ b/src/main_window.cpp
@@ -5,12 +5,12 @@
#include <QString>
#include <cerrno>
+#include <fcntl.h>
#include <filesystem>
#include <fud_result.hpp>
#include <fud_status.hpp>
#include <string>
#include <sys/stat.h>
-#include <fcntl.h>
#include <vector>
namespace getsuyomi {
@@ -29,15 +29,14 @@ FudStatus createXdgDirectory(const std::string& directoryName)
{
constexpr mode_t xdgMode = 0700;
auto dirStatus = mkdir(directoryName.c_str(), xdgMode);
- if (dirStatus == 0)
- {
+ if (dirStatus == 0) {
return FudStatus::Success;
}
if (errno != EEXIST) {
return FudStatus::Failure;
}
- struct stat statBuffer{};
+ struct stat statBuffer {};
dirStatus = stat(directoryName.c_str(), &statBuffer);
if (dirStatus != 0) {
@@ -72,36 +71,25 @@ GetConfigResult getUserConfig()
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());
+ auto shortcutMap = Shortcuts::fromUserConfig(configFileName);
- 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 binder = [&](ShortcutList& shortcuts, ActionType action) {
+ shortcuts = shortcutListFromSet(shortcutMap.at(action));
+ };
- 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);
- }
+ binder(config.openFileShortcuts, ActionType::OpenFile);
+ binder(config.openDirectoryShortcuts, ActionType::OpenDirectory);
+ binder(config.quitShortcuts, ActionType::Quit);
- 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());
- }
+ binder(config.settingsShortcuts, ActionType::Configure);
+
+ binder(config.nextShortcuts, ActionType::Next);
+ binder(config.backShortcuts, ActionType::Back);
+
+ binder(config.singlePageShortcuts, ActionType::SinglePage);
+ binder(config.dualPageShortcuts, ActionType::DualPage);
+ binder(config.mangaPageShortcuts, ActionType::MangaPage);
return GetConfigResult::okay(config);
}
@@ -142,55 +130,47 @@ FudStatus GetsuyomiApp::setup()
void GetsuyomiApp::createActions()
{
m_openFile = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::DocumentOpen), tr("&Open File"), this);
- m_openFile->setShortcuts(QKeySequence::Open);
+ m_openFile->setShortcuts(m_config.openFileShortcuts);
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->setShortcut(Qt::CTRL | Qt::ALT | Qt::Key_O);
+ m_openDirectory->setShortcuts(m_config.openDirectoryShortcuts);
m_openDirectory->setStatusTip(tr("Open a directory"));
connect(m_openDirectory, &QAction::triggered, this, &GetsuyomiApp::openDirectory);
m_quitAction = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::ApplicationExit), tr("&Quit"), this);
- m_quitAction->setShortcuts(QKeySequence::Quit);
+ m_quitAction->setShortcuts(m_config.quitShortcuts);
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->setShortcuts(m_config.settingsShortcuts);
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});
- nextShortcuts.append(QKeySequence{Qt::Key_Down});
m_nextAction = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::GoNext), tr("Next"), this);
- m_nextAction->setShortcuts(nextShortcuts);
+ m_nextAction->setShortcuts(m_config.nextShortcuts);
m_nextAction->setStatusTip(tr("Next"));
connect(m_nextAction, &QAction::triggered, this, &GetsuyomiApp::next);
- auto backShortcuts = QList<QKeySequence>{};
- backShortcuts.append(QKeySequence{Qt::Key_H});
- backShortcuts.append(QKeySequence{Qt::Key_Left});
- backShortcuts.append(QKeySequence{Qt::Key_Up});
m_backAction = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::GoPrevious), tr("Back"), this);
- m_backAction->setShortcuts(backShortcuts);
+ m_backAction->setShortcuts(m_config.backShortcuts);
m_backAction->setStatusTip(tr("Back"));
connect(m_backAction, &QAction::triggered, this, &GetsuyomiApp::back);
m_setSinglePageLayout = new QAction(QIcon("../resources/pageSingle.png"), tr("Single Page Layout"), this);
- m_setSinglePageLayout->setShortcut(QKeySequence{Qt::Key_S});
+ m_setSinglePageLayout->setShortcuts(m_config.singlePageShortcuts);
m_setSinglePageLayout->setStatusTip(tr("Set Single Page Layout"));
connect(m_setSinglePageLayout, &QAction::triggered, this, &GetsuyomiApp::setSinglePageLayout);
m_setDualPageLayout = new QAction(QIcon("../resources/pageDual.png"), tr("Dual Page Layout"), this);
- m_setDualPageLayout->setShortcut(QKeySequence{Qt::Key_D});
+ m_setDualPageLayout->setShortcuts(m_config.dualPageShortcuts);
m_setDualPageLayout->setStatusTip(tr("Set Dual Page Layout"));
connect(m_setDualPageLayout, &QAction::triggered, this, &GetsuyomiApp::setDualPageLayout);
m_setMangaLayout = new QAction(QIcon("../resources/pageManga.png"), tr("Manga Page Layout"), this);
- m_setMangaLayout->setShortcut(QKeySequence{Qt::Key_M});
+ m_setMangaLayout->setShortcuts(m_config.mangaPageShortcuts);
m_setMangaLayout->setStatusTip(tr("Set Manga Page Layout"));
connect(m_setMangaLayout, &QAction::triggered, this, &GetsuyomiApp::setMangaLayout);