diff options
Diffstat (limited to 'src/config.cpp')
-rw-r--r-- | src/config.cpp | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/src/config.cpp b/src/config.cpp new file mode 100644 index 0000000..6405e2b --- /dev/null +++ b/src/config.cpp @@ -0,0 +1,211 @@ +#include "config.hpp" + +#include <algorithm> +#include <vector> + +namespace getsuyomi { + +using fud::FudStatus; + +ShortcutSet shortcutSetFromList(const ShortcutList& shortcutList) +{ + ShortcutSet shortcutSet{}; + for (const auto& entry : shortcutList) { + shortcutSet.insert(entry); + } + return shortcutSet; +} + +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) { + return; + } + } + } + m_valid = true; +} + +bool Shortcuts::contains(QKeySequence keySequence) const +{ + return m_shortcuts.contains(keySequence); +} + +bool Shortcuts::contains(ActionType actionType) const +{ + return m_actionToShortcuts.contains(actionType); +} + +std::vector<ActionType> Shortcuts::actions() const { + std::vector<ActionType> actionList{}; + actionList.reserve(m_actionToShortcuts.size()); + for (const auto& [action, discarded] : m_actionToShortcuts) { + actionList.push_back(action); + } + return actionList; +} + +std::optional<ActionType> Shortcuts::action(QKeySequence keySequence) const +{ + if (m_shortcutToAction.contains(keySequence)) { + return m_shortcutToAction.at(keySequence); + } else { + return std::nullopt; + } +} + +std::optional<ShortcutList> Shortcuts::shortcuts(ActionType action) const +{ + if (contains(action)) { + const auto& shortcuts = m_actionToShortcuts.at(action); + ShortcutList shortcutList{}; + shortcutList.reserve(static_cast<qsizetype>(shortcuts.size())); + for (const auto& shortcut : shortcuts) { + shortcutList.push_back(shortcut); + } + return shortcutList; + } else { + return std::nullopt; + } +} + +FudStatus Shortcuts::bind(ActionType action, QKeySequence keySequence) +{ + if (contains(keySequence)) { + return FudStatus::Full; + } + + m_shortcuts.insert(keySequence); + + if (!contains(action)) { + m_actionToShortcuts[action] = ShortcutSet{}; + } + m_actionToShortcuts[action].insert(keySequence); + m_shortcutToAction[keySequence] = action; + return FudStatus::Success; +} + +fud::FudStatus Shortcuts::remove(QKeySequence keySequence) +{ + if (!contains(keySequence)) { + return FudStatus::NotFound; + } + + auto action = m_shortcutToAction[keySequence]; + auto& actionShortcuts = m_actionToShortcuts[action]; + + actionShortcuts.erase(keySequence); + m_shortcutToAction.erase(keySequence); + m_shortcuts.erase(keySequence); + + return FudStatus::Success; +} + +fud::FudStatus Shortcuts::clear(ActionType action) +{ + if (!contains(action)) { + return FudStatus::NotFound; + } + + auto& actionShortcuts = m_actionToShortcuts[action]; + + for (const auto& shortcut : actionShortcuts) { + m_shortcuts.erase(shortcut); + m_shortcutToAction.erase(shortcut); + } + m_actionToShortcuts[action] = {}; + + return FudStatus::Success; +} + +bool Shortcuts::valid() const { + return m_valid; +} + +ShortcutMap GetsuyomiConfig::shortcuts() const +{ + ShortcutMap shortcuts{}; + + 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)}); + + return shortcuts; +} + +ShortcutCollector::ShortcutCollector(QWidget* parent, ActionType action, Shortcuts& shortcuts) : + QWidget(parent), m_action{action}, m_shortcuts{shortcuts} +{ + m_layout = new QGridLayout(); + auto* name = new QLabel(actionTypeToString(m_action)); + m_layout->addWidget(name, 0, 0); + m_shortcutEditor = new QKeySequenceEdit(this); + m_layout->addWidget(m_shortcutEditor, 0, 1); + m_shortcutTable = new QTableWidget(this); + m_layout->addWidget(m_shortcutTable); + + auto shortcutOptions = m_shortcuts.shortcuts(m_action); + if (shortcutOptions != std::nullopt) { + m_shortcutTable->setColumnCount(2); + m_actionList = *shortcutOptions; + + m_shortcutTable->setRowCount(static_cast<int>(m_actionList.size())); + + for (auto index = 0; index < m_actionList.size(); ++index) { + const auto& shortcut = m_actionList[index]; + m_shortcutTable->setCellWidget(index, 0, new QLabel(shortcut.toString())); + auto* deleteButton = new QPushButton("Delete", this); + m_shortcutTable->setCellWidget(index, 1, deleteButton); + connect(m_shortcutTable, &QTableWidget::cellClicked, this, &ShortcutCollector::removeShortcut); + } + } else { + qWarning("No shortcuts found for %s", actionTypeToString(action)); + } + + setLayout(m_layout); +} + +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 { + qCritical("What"); + } +} + +Settings::Settings(QWidget* parent, Shortcuts&& shortcuts) : QDialog{parent}, m_shortcuts{std::move(shortcuts)} +{ + auto* layout = new QVBoxLayout(); + setWindowTitle("getsuyomi settings"); + + if (!m_shortcuts.valid()) { + return; + } + + for (const auto& action : m_shortcuts.actions()) { + auto* collector = new ShortcutCollector(this, action, shortcuts); + layout->addWidget(collector); + } + + setLayout(layout); +} + +bool Settings::valid() const { + return m_shortcuts.valid(); +} + +const Shortcuts& Settings::shortcuts() const { + return m_shortcuts; +} + +} // namespace getsuyomi |