1 #include "modifiersetting.hpp" 2 3 #include <QEvent> 4 #include <QKeyEvent> 5 #include <QLabel> 6 #include <QMouseEvent> 7 #include <QPushButton> 8 #include <QWidget> 9 10 #include "state.hpp" 11 #include "shortcutmanager.hpp" 12 13 namespace CSMPrefs 14 { ModifierSetting(Category * parent,Settings::Manager * values,QMutex * mutex,const std::string & key,const std::string & label)15 ModifierSetting::ModifierSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key, 16 const std::string& label) 17 : Setting(parent, values, mutex, key, label) 18 , mButton(nullptr) 19 , mEditorActive(false) 20 { 21 } 22 makeWidgets(QWidget * parent)23 std::pair<QWidget*, QWidget*> ModifierSetting::makeWidgets(QWidget* parent) 24 { 25 int modifier = 0; 26 State::get().getShortcutManager().getModifier(getKey(), modifier); 27 28 QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(modifier).c_str()); 29 30 QLabel* label = new QLabel(QString::fromUtf8(getLabel().c_str()), parent); 31 QPushButton* widget = new QPushButton(text, parent); 32 33 widget->setCheckable(true); 34 widget->installEventFilter(this); 35 36 // right clicking on button sets shortcut to RMB, so context menu should not appear 37 widget->setContextMenuPolicy(Qt::PreventContextMenu); 38 39 mButton = widget; 40 41 connect(widget, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool))); 42 43 return std::make_pair(label, widget); 44 } 45 updateWidget()46 void ModifierSetting::updateWidget() 47 { 48 if (mButton) 49 { 50 std::string shortcut = getValues().getString(getKey(), getParent()->getKey()); 51 52 int modifier; 53 State::get().getShortcutManager().convertFromString(shortcut, modifier); 54 State::get().getShortcutManager().setModifier(getKey(), modifier); 55 resetState(); 56 } 57 } 58 eventFilter(QObject * target,QEvent * event)59 bool ModifierSetting::eventFilter(QObject* target, QEvent* event) 60 { 61 if (event->type() == QEvent::KeyPress) 62 { 63 QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); 64 if (keyEvent->isAutoRepeat()) 65 return true; 66 67 int mod = keyEvent->modifiers(); 68 int key = keyEvent->key(); 69 70 return handleEvent(target, mod, key); 71 } 72 else if (event->type() == QEvent::MouseButtonPress) 73 { 74 QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); 75 int mod = mouseEvent->modifiers(); 76 int button = mouseEvent->button(); 77 78 return handleEvent(target, mod, button); 79 } 80 else if (event->type() == QEvent::FocusOut) 81 { 82 resetState(); 83 } 84 85 return false; 86 } 87 handleEvent(QObject * target,int mod,int value)88 bool ModifierSetting::handleEvent(QObject* target, int mod, int value) 89 { 90 // For potential future exceptions 91 const int Blacklist[] = 92 { 93 0 94 }; 95 96 const size_t BlacklistSize = sizeof(Blacklist) / sizeof(int); 97 98 if (!mEditorActive) 99 { 100 if (value == Qt::RightButton) 101 { 102 // Clear modifier 103 int modifier = 0; 104 storeValue(modifier); 105 106 resetState(); 107 } 108 109 return false; 110 } 111 112 // Handle blacklist 113 for (size_t i = 0; i < BlacklistSize; ++i) 114 { 115 if (value == Blacklist[i]) 116 return true; 117 } 118 119 120 // Update modifier 121 int modifier = value; 122 storeValue(modifier); 123 124 resetState(); 125 126 return true; 127 } 128 storeValue(int modifier)129 void ModifierSetting::storeValue(int modifier) 130 { 131 State::get().getShortcutManager().setModifier(getKey(), modifier); 132 133 // Convert to string and assign 134 std::string value = State::get().getShortcutManager().convertToString(modifier); 135 136 { 137 QMutexLocker lock(getMutex()); 138 getValues().setString(getKey(), getParent()->getKey(), value); 139 } 140 141 getParent()->getState()->update(*this); 142 } 143 resetState()144 void ModifierSetting::resetState() 145 { 146 mButton->setChecked(false); 147 mEditorActive = false; 148 149 // Button text 150 int modifier = 0; 151 State::get().getShortcutManager().getModifier(getKey(), modifier); 152 153 QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(modifier).c_str()); 154 mButton->setText(text); 155 } 156 buttonToggled(bool checked)157 void ModifierSetting::buttonToggled(bool checked) 158 { 159 if (checked) 160 mButton->setText("Press keys or click here..."); 161 162 mEditorActive = checked; 163 } 164 } 165