Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204#include "shortcutsetting.hpp"
#include <QEvent>#include <QKeyEvent>#include <QLabel>#include <QMouseEvent>#include <QPushButton>#include <QString>#include <QWidget>
#include <components/settings/settings.hpp>
#include <apps/opencs/model/prefs/category.hpp>#include <apps/opencs/model/prefs/setting.hpp>
#include "shortcutmanager.hpp"#include "state.hpp"
namespace CSMPrefs{ ShortcutSetting::ShortcutSetting( Category* parent, QMutex* mutex, std::string_view key, const QString& label, Settings::Index& index) : TypedSetting(parent, mutex, key, label, index) , mButton(nullptr) , mEditorActive(false) , mEditorPos(0) { for (int i = 0; i < MaxKeys; ++i) { mEditorKeys[i] = 0; } }
SettingWidgets ShortcutSetting::makeWidgets(QWidget* parent) { QKeySequence sequence; State::get().getShortcutManager().getSequence(getKey(), sequence);
QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(sequence).c_str());
QLabel* label = new QLabel(getLabel(), parent); QPushButton* widget = new QPushButton(text, parent);
widget->setCheckable(true); widget->installEventFilter(this);
// right clicking on button sets shortcut to RMB, so context menu should not appear widget->setContextMenuPolicy(Qt::PreventContextMenu);
mButton = widget;
connect(widget, &QPushButton::toggled, this, &ShortcutSetting::buttonToggled);
return SettingWidgets{ .mLabel = label, .mInput = widget }; }
void ShortcutSetting::updateWidget() { if (mButton) { const std::string shortcut = getValue();
QKeySequence sequence; State::get().getShortcutManager().convertFromString(shortcut, sequence); State::get().getShortcutManager().setSequence(getKey(), sequence); resetState(); } }
bool ShortcutSetting::eventFilter(QObject* target, QEvent* event) { if (event->type() == QEvent::KeyPress) { QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); if (keyEvent->isAutoRepeat()) return true;
int mod = keyEvent->modifiers(); int key = keyEvent->key();
return handleEvent(target, mod, key, true); } else if (event->type() == QEvent::KeyRelease) { QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); if (keyEvent->isAutoRepeat()) return true;
int mod = keyEvent->modifiers(); int key = keyEvent->key();
return handleEvent(target, mod, key, false); } else if (event->type() == QEvent::MouseButtonPress) { QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); int mod = mouseEvent->modifiers(); int key = mouseEvent->button();
return handleEvent(target, mod, key, true); } else if (event->type() == QEvent::MouseButtonRelease) { QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); int mod = mouseEvent->modifiers(); int key = mouseEvent->button();
return handleEvent(target, mod, key, false); } else if (event->type() == QEvent::FocusOut) { resetState(); }
return false; }
bool ShortcutSetting::handleEvent(QObject* target, int mod, int value, bool active) { // Modifiers are handled differently const int blacklist[] = { Qt::Key_Shift, Qt::Key_Control, Qt::Key_Meta, Qt::Key_Alt, Qt::Key_AltGr };
const size_t blacklistSize = std::size(blacklist);
if (!mEditorActive) { if (value == Qt::RightButton && !active) { // Clear sequence QKeySequence sequence = QKeySequence(0, 0, 0, 0); storeValue(sequence);
resetState(); }
return false; }
// Handle blacklist for (size_t i = 0; i < blacklistSize; ++i) { if (value == blacklist[i]) return true; }
if (!active || mEditorPos >= MaxKeys) { // Update key QKeySequence sequence = QKeySequence(mEditorKeys[0], mEditorKeys[1], mEditorKeys[2], mEditorKeys[3]); storeValue(sequence);
resetState(); } else { if (mEditorPos == 0) { mEditorKeys[0] = mod | value; } else { mEditorKeys[mEditorPos] = value; }
mEditorPos += 1; }
return true; }
void ShortcutSetting::storeValue(const QKeySequence& sequence) { State::get().getShortcutManager().setSequence(getKey(), sequence); setValue(State::get().getShortcutManager().convertToString(sequence)); getParent()->getState()->update(*this); }
void ShortcutSetting::resetState() { mButton->setChecked(false); mEditorActive = false; mEditorPos = 0; for (int i = 0; i < MaxKeys; ++i) { mEditorKeys[i] = 0; }
// Button text QKeySequence sequence; State::get().getShortcutManager().getSequence(getKey(), sequence);
QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(sequence).c_str()); mButton->setText(text); }
void ShortcutSetting::buttonToggled(bool checked) { if (checked) mButton->setText("Press keys or click here...");
mEditorActive = checked; }}