1 //=============================================================================
2 //  MusE Score
3 //  Linux Music Score Editor
4 //
5 //  Copyright (C) 2002-2007 Werner Schweer and others
6 //  Copyright (C) 2003 Mathias Lundgren (lunar_shuttle@users.sourceforge.net)
7 //
8 //  This program is free software; you can redistribute it and/or modify
9 //  it under the terms of the GNU General Public License version 2.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 //=============================================================================
20 
21 #include "shortcutcapturedialog.h"
22 #include "musescore.h"
23 #include "shortcut.h"
24 
25 namespace Ms {
26 
27 //---------------------------------------------------------
28 //   ShortcutCaptureDialog
29 //---------------------------------------------------------
30 
ShortcutCaptureDialog(Shortcut * _s,QMap<QString,Shortcut * > ls,QWidget * parent)31 ShortcutCaptureDialog::ShortcutCaptureDialog(Shortcut* _s, QMap<QString, Shortcut*> ls, QWidget* parent)
32    : QDialog(parent)
33       {
34       setObjectName("ShortcutCaptureDialog");
35       setupUi(this);
36       setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
37       localShortcuts = ls;
38       s = _s;
39 
40       addButton->setEnabled(false);
41       replaceButton->setEnabled(false);
42       oshrtLabel->setText(s->keysToString());
43       oshrtTextLabel->setAccessibleDescription(s->keysToString());
44       oshrtLabel->setEnabled(false);
45       connect(clearButton, SIGNAL(clicked()), SLOT(clearClicked()));
46       connect(addButton, SIGNAL(clicked()), SLOT(addClicked()));
47       connect(replaceButton, SIGNAL(clicked()), SLOT(replaceClicked()));
48       clearClicked();
49 
50       nshrtLabel->installEventFilter(this);
51       MuseScore::restoreGeometry(this);
52       }
53 
54 //---------------------------------------------------------
55 //   addClicked
56 //---------------------------------------------------------
57 
addClicked()58 void ShortcutCaptureDialog::addClicked()
59       {
60       done(1);
61       }
62 
63 //---------------------------------------------------------
64 //   replaceClicked
65 //---------------------------------------------------------
66 
replaceClicked()67 void ShortcutCaptureDialog::replaceClicked()
68       {
69       done(2);
70       }
71 
72 //---------------------------------------------------------
73 //   ShortcutCaptureDialog
74 //---------------------------------------------------------
75 
~ShortcutCaptureDialog()76 ShortcutCaptureDialog::~ShortcutCaptureDialog()
77       {
78       nshrtLabel->removeEventFilter(this);
79       releaseKeyboard();
80       }
81 
82 //---------------------------------------------------------
83 //   eventFilter
84 //---------------------------------------------------------
85 
eventFilter(QObject *,QEvent * e)86 bool ShortcutCaptureDialog::eventFilter(QObject* /*o*/, QEvent* e)
87       {
88       if (e->type() == QEvent::KeyPress) {
89             QKeyEvent* keyEvent = static_cast<QKeyEvent*>(e);
90             if(keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab){
91                   QWidget::keyPressEvent(keyEvent);
92                   return true;
93                   }
94             keyPress(keyEvent);
95             return true;
96             }
97       return false;
98       }
99 
100 
101 //---------------------------------------------------------
102 //   keyPressEvent
103 //---------------------------------------------------------
104 
keyPress(QKeyEvent * e)105 void ShortcutCaptureDialog::keyPress(QKeyEvent* e)
106       {
107       if (key.count() >= 4)
108             return;
109       int k = e->key();
110       if (k == 0 || k == Qt::Key_Shift || k == Qt::Key_Control ||
111          k == Qt::Key_Meta || k == Qt::Key_Alt || k == Qt::Key_AltGr
112          || k == Qt::Key_CapsLock || k == Qt::Key_NumLock
113          || k == Qt::Key_ScrollLock || k == Qt::Key_unknown)
114             return;
115 
116       k += e->modifiers();
117       // remove shift-modifier for keys that don't need it: letters and special keys
118       if ((k & Qt::ShiftModifier) && ((e->key() < 0x41) || (e->key() > 0x5a) || (e->key() >= 0x01000000))) {
119             qDebug() << k;
120             k -= Qt::ShiftModifier;
121             qDebug() << k;
122             }
123 
124       switch(key.count()) {
125             case 0: key = QKeySequence(k); break;
126             case 1: key = QKeySequence(key[0], k); break;
127             case 2: key = QKeySequence(key[0], key[1], k); break;
128             case 3: key = QKeySequence(key[0], key[1], key[2], k); break;
129             default:
130                   qDebug("Internal error: bad key count");
131                   break;
132             }
133 
134       // Check against conflicting shortcuts
135       bool conflict = false;
136       QString msgString;
137 
138       for (Shortcut* ss : localShortcuts) {
139             if (s == ss)
140                   continue;
141             if (!(s->state() & ss->state()))    // no conflict if states do not overlap
142                   continue;
143 
144             QList<QKeySequence> skeys = QKeySequence::keyBindings(ss->standardKey());
145 
146             for (const QKeySequence& ks : skeys) {
147                   if (ks == key) {
148                         msgString = tr("Shortcut conflicts with %1").arg(ss->descr());
149                         conflict = true;
150                         break;
151                         }
152                   }
153 
154             for (const QKeySequence& ks : ss->keys()) {
155                   if (ks == key) {
156                         msgString = tr("Shortcut conflicts with %1").arg(ss->descr());
157                         conflict = true;
158                         break;
159                         }
160                   }
161             if (conflict)
162                   break;
163             }
164 
165       messageLabel->setText(msgString);
166 
167       if (conflict) {
168             if (!nshrtLabel->accessibleName().contains(tr("Shortcut conflicts with")))
169                   nshrtLabel->setAccessibleName(msgString);
170             }
171       else {
172             if (!nshrtLabel->accessibleName().contains("New shortcut"))
173                   nshrtLabel->setAccessibleName(tr("New shortcut"));
174             }
175       addButton->setEnabled(conflict == false);
176       replaceButton->setEnabled(conflict == false);
177 
178 //      nshrtLabel->setText(key.toString(QKeySequence::NativeText));
179       QString keyStr = Shortcut::keySeqToString(key, QKeySequence::NativeText);
180       nshrtLabel->setText(keyStr);
181 //      QString A = key.toString(QKeySequence::NativeText);
182       QString A = keyStr;
183       QString B = Shortcut::keySeqToString(key, QKeySequence::PortableText);
184       qDebug("capture key 0x%x  modifiers 0x%x virt 0x%x scan 0x%x <%s><%s>",
185             k,
186             int(e->modifiers()),
187             int(e->nativeVirtualKey()),
188             int(e->nativeScanCode()),
189             qPrintable(A),
190             qPrintable(B)
191             );
192       }
193 
194 //---------------------------------------------------------
195 //   clearClicked
196 //---------------------------------------------------------
197 
clearClicked()198 void ShortcutCaptureDialog::clearClicked()
199       {
200       if (!nshrtLabel->accessibleName().contains("New shortcut"))
201             nshrtLabel->setAccessibleName(tr("New shortcut"));
202 
203       nshrtLabel->setAccessibleName(tr("New shortcut"));
204       messageLabel->setText("");
205       addButton->setEnabled(false);
206       replaceButton->setEnabled(false);
207       nshrtLabel->setText("");
208       key = 0;
209       nshrtLabel->setFocus();
210       }
211 
212 //---------------------------------------------------------
213 //   hideEvent
214 //---------------------------------------------------------
215 
hideEvent(QHideEvent * event)216 void ShortcutCaptureDialog::hideEvent(QHideEvent* event)
217       {
218       MuseScore::saveGeometry(this);
219       QWidget::hideEvent(event);
220       }
221 
222 } // namespace Ms
223 
224