Skip to content

Commit

Permalink
Merge pull request musescore#315 from mgavioli/Fix_20826_Numpad_note_…
Browse files Browse the repository at this point in the history
…duration_shortcuts

Fix musescore#20826 - Numpad numbers no longer work to select note duration.
  • Loading branch information
mgavioli committed Apr 29, 2013
2 parents 47f50aa + cd40022 commit ec6b45e
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 23 deletions.
20 changes: 10 additions & 10 deletions mscore/data/shortcuts.xml
Original file line number Diff line number Diff line change
Expand Up @@ -752,52 +752,52 @@
<SC>
<key>note-longa-TAB</key>
<seq>Shift+9</seq>
<code>536870969</code>
<seq>NumPad+9</seq>
</SC>
<SC>
<key>note-breve-TAB</key>
<seq>Shift+8</seq>
<code>536870968</code>
<seq>NumPad+8</seq>
</SC>
<SC>
<key>pad-note-1-TAB</key>
<seq>Shift+7</seq>
<code>536870967</code>
<seq>NumPad+7</seq>
</SC>
<SC>
<key>pad-note-2-TAB</key>
<seq>Shift+6</seq>
<code>536870966</code>
<seq>NumPad+6</seq>
</SC>
<SC>
<key>pad-note-4-TAB</key>
<seq>Shift+5</seq>
<code>536870965</code>
<seq>NumPad+5</seq>
</SC>
<SC>
<key>pad-note-8-TAB</key>
<seq>Shift+4</seq>
<code>536870964</code>
<seq>NumPad+4</seq>
</SC>
<SC>
<key>pad-note-16-TAB</key>
<seq>Shift+3</seq>
<code>536870963</code>
<seq>NumPad+3</seq>
</SC>
<SC>
<key>pad-note-32-TAB</key>
<seq>Shift+2</seq>
<code>536870962</code>
<seq>NumPad+1</seq>
</SC>
<SC>
<key>pad-note-64-TAB</key>
<seq>Shift+1</seq>
<code>536870961</code>
<seq>NumPad+1</seq>
</SC>
<SC>
<key>pad-note-128-TAB</key>
<seq>Shift+0</seq>
<code>536870960</code>
<seq>NumPad+0</seq>
</SC>
<SC>
<key>pad-note-increase-TAB</key>
Expand Down
3 changes: 2 additions & 1 deletion mscore/musescore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,8 @@ MuseScore::MuseScore()
ag->setExclusive(false);
foreach(const Shortcut* s, Shortcut::shortcuts()) {
QAction* a = s->action();
ag->addAction(a);
if (a)
ag->addAction(a);
}
addActions(ag->actions());
connect(ag, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
Expand Down
73 changes: 64 additions & 9 deletions mscore/shortcut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ QAction* Shortcut::action() const
if (_action)
return _action;

if (_state == STATE_NEVER)
return 0;

_action = new QAction(_text, 0);
_action->setData(_key);

Expand All @@ -259,7 +262,8 @@ QAction* Shortcut::action() const
for (int i = 0; i < kl.size(); ++i) {
if (i)
s += ",";
s += kl[i].toString(QKeySequence::NativeText);
// s += kl[i].toString(QKeySequence::NativeText);
s += Shortcut::keySeqToString(kl[i], QKeySequence::NativeText);
}
s += ")";
_action->setToolTip(s);
Expand Down Expand Up @@ -287,13 +291,11 @@ void Shortcut::addShortcut(const QKeySequence& ks)

QString Shortcut::keysToString() const
{
QAction* a = action();
QList<QKeySequence> kl = a->shortcuts();
QString s;
for (int i = 0; i < kl.size(); ++i) {
for (int i = 0; i < _keys.size(); ++i) {
if (i)
s += "; ";
s += kl[i].toString(QKeySequence::NativeText);
s += Shortcut::keySeqToString(_keys[i], QKeySequence::NativeText);
}
return s;
}
Expand Down Expand Up @@ -367,7 +369,8 @@ void Shortcut::write(Xml& xml) const
if (_standardKey != QKeySequence::UnknownKey)
xml.tag("std", QString("%1").arg(_standardKey));
foreach(QKeySequence ks, _keys)
xml.tag("seq", ks.toString(QKeySequence::PortableText));
// xml.tag("seq", ks.toString(QKeySequence::PortableText));
xml.tag("seq", Shortcut::keySeqToString(ks, QKeySequence::PortableText));
xml.etag();
}

Expand All @@ -384,7 +387,8 @@ void Shortcut::read(XmlReader& e)
else if (tag == "std")
_standardKey = QKeySequence::StandardKey(e.readInt());
else if (tag == "seq")
_keys.append(QKeySequence::fromString(e.readElementText(), QKeySequence::PortableText));
// _keys.append(QKeySequence::fromString(e.readElementText(), QKeySequence::PortableText));
_keys.append(Shortcut::keySeqFromString(e.readElementText(), QKeySequence::PortableText));
else
e.unknown();
}
Expand Down Expand Up @@ -426,7 +430,8 @@ void Shortcut::load()
else if (tag == "std")
sc->_standardKey = QKeySequence::StandardKey(e.readInt());
else if (tag == "seq")
sc->_keys.append(QKeySequence::fromString(e.readElementText(), QKeySequence::PortableText));
// sc->_keys.append(QKeySequence::fromString(e.readElementText(), QKeySequence::PortableText));
sc->_keys.append(Shortcut::keySeqFromString(e.readElementText(), QKeySequence::PortableText));
else if (tag == "code")
sc->_keys.append(QKeySequence(e.readInt()));
else
Expand Down Expand Up @@ -483,7 +488,8 @@ static QList<Shortcut1*> loadDefaultShortcuts()
else if (tag == "std")
sc->standardKey = QKeySequence::StandardKey(e.readInt());
else if (tag == "seq")
sc->keys.append(QKeySequence::fromString(e.readElementText(), QKeySequence::PortableText));
// sc->keys.append(QKeySequence::fromString(e.readElementText(), QKeySequence::PortableText));
sc->keys.append(Shortcut::keySeqFromString(e.readElementText(), QKeySequence::PortableText));
else
e.unknown();
}
Expand Down Expand Up @@ -537,3 +543,52 @@ void Shortcut::reset()
dirty = true;
}

//---------------------------------------------------------
// keySeqToString / keySeqFromString
//---------------------------------------------------------

static const QString numPadPrefix("NumPad+");
static const int NUMPADPREFIX_SIZE = 7; // the length in chars of the above string
static const QString keySepar(", ");

QString Shortcut::keySeqToString(const QKeySequence& keySeq, QKeySequence::SequenceFormat fmt)
{
QString s;
int code, i;
for (i = 0; i < KEYSEQ_SIZE; ++i) {
if ( (code = keySeq[i]) == 0)
break;
if (i)
s += keySepar;
if (code & Qt::KeypadModifier) {
s += numPadPrefix;
code &= ~Qt::KeypadModifier;
}
QKeySequence kSeq(code);
s += kSeq.toString(fmt);
}
return s;
}

QKeySequence Shortcut::keySeqFromString(const QString& str, QKeySequence::SequenceFormat fmt)
{
int code[KEYSEQ_SIZE], i;
for (i = 0; i < KEYSEQ_SIZE; ++i)
code[i] = 0;

QStringList strList = str.split(keySepar, QString::SkipEmptyParts, Qt::CaseSensitive);

i = 0;
foreach (QString keyStr, strList) {
if( keyStr.startsWith(numPadPrefix, Qt::CaseInsensitive) ) {
code[i] += Qt::KeypadModifier;
keyStr.remove(0, NUMPADPREFIX_SIZE);
}
QKeySequence seq = QKeySequence::fromString(keyStr, fmt);
code[i] += seq[0];
if(++i >= KEYSEQ_SIZE)
break;
}
QKeySequence keySeq(code[0], code[1], code[2], code[3]);
return keySeq;
}
53 changes: 53 additions & 0 deletions mscore/shortcut.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,63 @@
#ifndef __SHORTCUT_H__
#define __SHORTCUT_H__

/*---------------------------------------------------------
NOTE ON ARCHITECTURE
The Shortcut class describes the basic configurable shortcut element.
'Real' data are contained in 2 static member variables:
1) sc[], an array of Shortcut: contains the default, built-in data for each shortcut
except the key sequences; it is initialized at startup (code at the begining of
mscore/actions.cpp)
2) _shortcuts, a QMap using the shortcut xml tag name as hash value: is initialized from
data in sc via a call to Shortcut::init() in program main() (mscore/musescore.cpp).
This also load actual key sequences either from an external, hard-coded, file with
user customizations or from a resource (<= mscore/data/shortcuts.xml), if there are
no customizations.
Later during startup, QAction's are derived from each of its elements and pooled
in a single QActionGroup during MuseScore::MuseScore() costructor (mscore/musescore.cpp)
ShortcutFlags:
To be documented
State flags:
Defined in mscore/global.h (ScoreState enum): each shortcut is ignored if its _flags mask
does not include the current score state. This is different from (and additional to)
QAction processing performed by the Qt framework and happens only after the action has
been forwarded to the application (the action must be enabled).
The STATE_NEVER requires an explanation. It has been introduced to mark shortcuts
which need to be recorded (and possibly customized) but are never used directly.
Currently, this applies to a number of shortcuts which:
- have been split between a common and a TAB-specific variant AND
- are linked to tool bar buttons or menu items
If QAction's are created for both, Qt blocks either as duplicate; in addition, the button
or menu item may become disabled on state change. The currently implemented solution is
to create a QAction only for one of them (the common one) and swap the key sequences when
entering or leaving the relevant state.
Swapping is implemented in MuseScore::changeState() (mscore/musescore.cpp).
QAction creation for the 'other' shortcut is blocked in Shortcut::action() (mscore/shortcut.cpp).
This means that Shortcut::action() may return 0. When scanning the whole
shortcuts[] array, this has to be taken into account; currently it happens in two
cases:
- in MuseScore::MuseScore() constructor (mscore/musescore.cpp)
- in MuseScore::changeState() method (mscore/musescore.cpp)
Shortcuts marked with the STATE_NEVER state should NEVER used directly as shortcuts!
---------------------------------------------------------*/

class Xml;
class XmlReader;

enum ShortcutFlags {
A_SCORE = 0x1, A_CMD = 0x2
};

static const int KEYSEQ_SIZE = 4;

//---------------------------------------------------------
// Shortcut
// hold the basic values for configurable shortcuts
Expand Down Expand Up @@ -111,6 +161,9 @@ class Shortcut {
static bool dirty;
static Shortcut* getShortcut(const char* key);
static const QMap<QString, Shortcut*>& shortcuts() { return _shortcuts; }

static QString keySeqToString(const QKeySequence& keySeq, QKeySequence::SequenceFormat fmt);
static QKeySequence keySeqFromString(const QString& str, QKeySequence::SequenceFormat fmt);
};

#endif
Expand Down
9 changes: 6 additions & 3 deletions mscore/shortcutcapturedialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,13 @@ void ShortcutCaptureDialog::keyPressEvent(QKeyEvent* e)
messageLabel->setText(msgString);
addButton->setEnabled(conflict == false);
replaceButton->setEnabled(conflict == false);
nshrtLabel->setText(key.toString(QKeySequence::NativeText));
// nshrtLabel->setText(key.toString(QKeySequence::NativeText));
QString keyStr = Shortcut::keySeqToString(key, QKeySequence::NativeText);
nshrtLabel->setText(keyStr);

QString A = key.toString(QKeySequence::NativeText);
QString B = key.toString(QKeySequence::PortableText);
// QString A = key.toString(QKeySequence::NativeText);
QString A = keyStr;
QString B = Shortcut::keySeqToString(key, QKeySequence::PortableText);
qDebug("capture key 0x%x modifiers 0x%x virt 0x%x scan 0x%x <%s><%s>\n",
k,
int(e->modifiers()),
Expand Down

0 comments on commit ec6b45e

Please sign in to comment.