~ubuntu-branches/ubuntu/vivid/quassel/vivid-updates

« back to all changes in this revision

Viewing changes to src/qtui/settingspages/keysequencewidget.cpp

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2013-03-06 15:07:41 UTC
  • mfrom: (1.1.49)
  • Revision ID: package-import@ubuntu.com-20130306150741-pys1igw1g8uhja38
Tags: 0.9~beta1-0ubuntu1
* New upstream beta release
  - Remove debian/patches/0001-Support-intermediate-CA-certificates.patch,
    incorporated upstream
  - Remove 0002-Allow-the-core-to-use-expired-certificates.patch,
    incorporated upstream
  - Update kubuntu_02_enable_message_indicator.diff for 0.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/***************************************************************************
2
 
 *   Copyright (C) 2010 by the Quassel Project                             *
 
2
 *   Copyright (C) 2005-2013 by the Quassel Project                        *
3
3
 *   devel@quassel-irc.org                                                 *
4
4
 *                                                                         *
5
5
 *   This class has been inspired by KDE's KKeySequenceWidget and uses     *
22
22
 *   You should have received a copy of the GNU General Public License     *
23
23
 *   along with this program; if not, write to the                         *
24
24
 *   Free Software Foundation, Inc.,                                       *
25
 
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 
25
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
26
26
 ***************************************************************************/
27
27
 
28
28
#include <QApplication>
43
43
#include "keysequencewidget.h"
44
44
 
45
45
KeySequenceButton::KeySequenceButton(KeySequenceWidget *d_, QWidget *parent)
46
 
  : QPushButton(parent),
47
 
  d(d_)
48
 
{
49
 
 
50
 
}
51
 
 
52
 
bool KeySequenceButton::event(QEvent *e) {
53
 
  if(d->isRecording() && e->type() == QEvent::KeyPress) {
54
 
    keyPressEvent(static_cast<QKeyEvent *>(e));
55
 
    return true;
56
 
  }
57
 
 
58
 
  // The shortcut 'alt+c' ( or any other dialog local action shortcut )
59
 
  // ended the recording and triggered the action associated with the
60
 
  // action. In case of 'alt+c' ending the dialog.  It seems that those
61
 
  // ShortcutOverride events get sent even if grabKeyboard() is active.
62
 
  if(d->isRecording() && e->type() == QEvent::ShortcutOverride) {
63
 
    e->accept();
64
 
    return true;
65
 
  }
66
 
 
67
 
  return QPushButton::event(e);
68
 
}
69
 
 
70
 
void KeySequenceButton::keyPressEvent(QKeyEvent *e) {
71
 
  int keyQt = e->key();
72
 
  if(keyQt == -1) {
73
 
    // Qt sometimes returns garbage keycodes, I observed -1, if it doesn't know a key.
74
 
    // We cannot do anything useful with those (several keys have -1, indistinguishable)
75
 
    // and QKeySequence.toString() will also yield a garbage string.
76
 
    QMessageBox::information(this,
77
 
                             tr("The key you just pressed is not supported by Qt."),
78
 
                             tr("Unsupported Key"));
79
 
    return d->cancelRecording();
80
 
  }
81
 
 
82
 
  uint newModifiers = e->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
83
 
 
84
 
  //don't have the return or space key appear as first key of the sequence when they
85
 
  //were pressed to start editing - catch and them and imitate their effect
86
 
  if(!d->isRecording() && ((keyQt == Qt::Key_Return || keyQt == Qt::Key_Space))) {
87
 
    d->startRecording();
88
 
    d->_modifierKeys = newModifiers;
89
 
    d->updateShortcutDisplay();
90
 
    return;
91
 
  }
92
 
 
93
 
  // We get events even if recording isn't active.
94
 
  if(!d->isRecording())
95
 
    return QPushButton::keyPressEvent(e);
96
 
 
97
 
  e->accept();
98
 
  d->_modifierKeys = newModifiers;
99
 
 
100
 
  switch(keyQt) {
101
 
  case Qt::Key_AltGr: //or else we get unicode salad
102
 
    return;
103
 
  case Qt::Key_Shift:
104
 
  case Qt::Key_Control:
105
 
  case Qt::Key_Alt:
106
 
  case Qt::Key_Meta:
107
 
  case Qt::Key_Menu: //unused (yes, but why?)
108
 
    d->updateShortcutDisplay();
109
 
    break;
110
 
 
111
 
  default:
112
 
    if(!(d->_modifierKeys & ~Qt::SHIFT)) {
113
 
      // It's the first key and no modifier pressed. Check if this is
114
 
      // allowed
115
 
      if(!d->isOkWhenModifierless(keyQt))
116
 
        return;
117
 
    }
118
 
 
119
 
    // We now have a valid key press.
120
 
    if(keyQt) {
121
 
      if((keyQt == Qt::Key_Backtab) && (d->_modifierKeys & Qt::SHIFT)) {
122
 
        keyQt = Qt::Key_Tab | d->_modifierKeys;
123
 
      }
124
 
      else if(d->isShiftAsModifierAllowed(keyQt)) {
125
 
        keyQt |= d->_modifierKeys;
126
 
      } else
127
 
        keyQt |= (d->_modifierKeys & ~Qt::SHIFT);
128
 
 
129
 
      d->_keySequence = QKeySequence(keyQt);
130
 
      d->doneRecording();
131
 
    }
132
 
  }
133
 
}
134
 
 
135
 
void KeySequenceButton::keyReleaseEvent(QKeyEvent *e) {
136
 
  if(e->key() == -1) {
137
 
    // ignore garbage, see keyPressEvent()
138
 
    return;
139
 
  }
140
 
 
141
 
  if(!d->isRecording())
142
 
    return QPushButton::keyReleaseEvent(e);
143
 
 
144
 
  e->accept();
145
 
 
146
 
  uint newModifiers = e->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
147
 
 
148
 
  // if a modifier that belongs to the shortcut was released...
149
 
  if((newModifiers & d->_modifierKeys) < d->_modifierKeys) {
150
 
    d->_modifierKeys = newModifiers;
151
 
    d->updateShortcutDisplay();
152
 
  }
153
 
}
 
46
    : QPushButton(parent),
 
47
    d(d_)
 
48
{
 
49
}
 
50
 
 
51
 
 
52
bool KeySequenceButton::event(QEvent *e)
 
53
{
 
54
    if (d->isRecording() && e->type() == QEvent::KeyPress) {
 
55
        keyPressEvent(static_cast<QKeyEvent *>(e));
 
56
        return true;
 
57
    }
 
58
 
 
59
    // The shortcut 'alt+c' ( or any other dialog local action shortcut )
 
60
    // ended the recording and triggered the action associated with the
 
61
    // action. In case of 'alt+c' ending the dialog.  It seems that those
 
62
    // ShortcutOverride events get sent even if grabKeyboard() is active.
 
63
    if (d->isRecording() && e->type() == QEvent::ShortcutOverride) {
 
64
        e->accept();
 
65
        return true;
 
66
    }
 
67
 
 
68
    return QPushButton::event(e);
 
69
}
 
70
 
 
71
 
 
72
void KeySequenceButton::keyPressEvent(QKeyEvent *e)
 
73
{
 
74
    int keyQt = e->key();
 
75
    if (keyQt == -1) {
 
76
        // Qt sometimes returns garbage keycodes, I observed -1, if it doesn't know a key.
 
77
        // We cannot do anything useful with those (several keys have -1, indistinguishable)
 
78
        // and QKeySequence.toString() will also yield a garbage string.
 
79
        QMessageBox::information(this,
 
80
            tr("The key you just pressed is not supported by Qt."),
 
81
            tr("Unsupported Key"));
 
82
        return d->cancelRecording();
 
83
    }
 
84
 
 
85
    uint newModifiers = e->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
 
86
 
 
87
    //don't have the return or space key appear as first key of the sequence when they
 
88
    //were pressed to start editing - catch and them and imitate their effect
 
89
    if (!d->isRecording() && ((keyQt == Qt::Key_Return || keyQt == Qt::Key_Space))) {
 
90
        d->startRecording();
 
91
        d->_modifierKeys = newModifiers;
 
92
        d->updateShortcutDisplay();
 
93
        return;
 
94
    }
 
95
 
 
96
    // We get events even if recording isn't active.
 
97
    if (!d->isRecording())
 
98
        return QPushButton::keyPressEvent(e);
 
99
 
 
100
    e->accept();
 
101
    d->_modifierKeys = newModifiers;
 
102
 
 
103
    switch (keyQt) {
 
104
    case Qt::Key_AltGr: //or else we get unicode salad
 
105
        return;
 
106
    case Qt::Key_Shift:
 
107
    case Qt::Key_Control:
 
108
    case Qt::Key_Alt:
 
109
    case Qt::Key_Meta:
 
110
    case Qt::Key_Menu: //unused (yes, but why?)
 
111
        d->updateShortcutDisplay();
 
112
        break;
 
113
 
 
114
    default:
 
115
        if (!(d->_modifierKeys & ~Qt::SHIFT)) {
 
116
            // It's the first key and no modifier pressed. Check if this is
 
117
            // allowed
 
118
            if (!d->isOkWhenModifierless(keyQt))
 
119
                return;
 
120
        }
 
121
 
 
122
        // We now have a valid key press.
 
123
        if (keyQt) {
 
124
            if ((keyQt == Qt::Key_Backtab) && (d->_modifierKeys & Qt::SHIFT)) {
 
125
                keyQt = Qt::Key_Tab | d->_modifierKeys;
 
126
            }
 
127
            else if (d->isShiftAsModifierAllowed(keyQt)) {
 
128
                keyQt |= d->_modifierKeys;
 
129
            }
 
130
            else
 
131
                keyQt |= (d->_modifierKeys & ~Qt::SHIFT);
 
132
 
 
133
            d->_keySequence = QKeySequence(keyQt);
 
134
            d->doneRecording();
 
135
        }
 
136
    }
 
137
}
 
138
 
 
139
 
 
140
void KeySequenceButton::keyReleaseEvent(QKeyEvent *e)
 
141
{
 
142
    if (e->key() == -1) {
 
143
        // ignore garbage, see keyPressEvent()
 
144
        return;
 
145
    }
 
146
 
 
147
    if (!d->isRecording())
 
148
        return QPushButton::keyReleaseEvent(e);
 
149
 
 
150
    e->accept();
 
151
 
 
152
    uint newModifiers = e->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
 
153
 
 
154
    // if a modifier that belongs to the shortcut was released...
 
155
    if ((newModifiers & d->_modifierKeys) < d->_modifierKeys) {
 
156
        d->_modifierKeys = newModifiers;
 
157
        d->updateShortcutDisplay();
 
158
    }
 
159
}
 
160
 
154
161
 
155
162
/******************************************************************************/
156
163
 
157
164
KeySequenceWidget::KeySequenceWidget(QWidget *parent)
158
 
  : QWidget(parent),
159
 
  _shortcutsModel(0),
160
 
  _isRecording(false),
161
 
  _modifierKeys(0)
162
 
{
163
 
  QHBoxLayout *layout = new QHBoxLayout(this);
164
 
  layout->setMargin(0);
165
 
 
166
 
  _keyButton = new KeySequenceButton(this, this);
167
 
  _keyButton->setFocusPolicy(Qt::StrongFocus);
168
 
  _keyButton->setIcon(SmallIcon("configure"));
169
 
  _keyButton->setToolTip(tr("Click on the button, then enter the shortcut like you would in the program.\nExample for Ctrl+a: hold the Ctrl key and press a."));
170
 
  layout->addWidget(_keyButton);
171
 
 
172
 
  _clearButton = new QToolButton(this);
173
 
  layout->addWidget(_clearButton);
174
 
 
175
 
  if(qApp->isLeftToRight())
176
 
    _clearButton->setIcon(SmallIcon("edit-clear-locationbar-rtl"));
177
 
  else
178
 
    _clearButton->setIcon(SmallIcon("edit-clear-locationbar-ltr"));
179
 
 
180
 
  setLayout(layout);
181
 
 
182
 
  connect(_keyButton, SIGNAL(clicked()), SLOT(startRecording()));
183
 
  connect(_keyButton, SIGNAL(clicked()), SIGNAL(clicked()));
184
 
  connect(_clearButton, SIGNAL(clicked()), SLOT(clear()));
185
 
  connect(_clearButton, SIGNAL(clicked()), SIGNAL(clicked()));
186
 
}
187
 
 
188
 
void KeySequenceWidget::setModel(ShortcutsModel *model) {
189
 
  Q_ASSERT(!_shortcutsModel);
190
 
  _shortcutsModel = model;
191
 
}
192
 
 
193
 
bool KeySequenceWidget::isOkWhenModifierless(int keyQt) const {
194
 
  //this whole function is a hack, but especially the first line of code
195
 
  if(QKeySequence(keyQt).toString().length() == 1)
196
 
    return false;
197
 
 
198
 
  switch(keyQt) {
199
 
  case Qt::Key_Return:
200
 
  case Qt::Key_Space:
201
 
  case Qt::Key_Tab:
202
 
  case Qt::Key_Backtab: //does this ever happen?
203
 
  case Qt::Key_Backspace:
204
 
  case Qt::Key_Delete:
205
 
    return false;
206
 
  default:
207
 
    return true;
208
 
  }
209
 
}
210
 
 
211
 
bool KeySequenceWidget::isShiftAsModifierAllowed(int keyQt) const {
212
 
  // Shift only works as a modifier with certain keys. It's not possible
213
 
  // to enter the SHIFT+5 key sequence for me because this is handled as
214
 
  // '%' by qt on my keyboard.
215
 
  // The working keys are all hardcoded here :-(
216
 
  if(keyQt >= Qt::Key_F1 && keyQt <= Qt::Key_F35)
217
 
    return true;
218
 
 
219
 
  if(QChar(keyQt).isLetter())
220
 
    return true;
221
 
 
222
 
  switch(keyQt) {
223
 
  case Qt::Key_Return:
224
 
  case Qt::Key_Space:
225
 
  case Qt::Key_Backspace:
226
 
  case Qt::Key_Escape:
227
 
  case Qt::Key_Print:
228
 
  case Qt::Key_ScrollLock:
229
 
  case Qt::Key_Pause:
230
 
  case Qt::Key_PageUp:
231
 
  case Qt::Key_PageDown:
232
 
  case Qt::Key_Insert:
233
 
  case Qt::Key_Delete:
234
 
  case Qt::Key_Home:
235
 
  case Qt::Key_End:
236
 
  case Qt::Key_Up:
237
 
  case Qt::Key_Down:
238
 
  case Qt::Key_Left:
239
 
  case Qt::Key_Right:
240
 
    return true;
241
 
 
242
 
  default:
243
 
    return false;
244
 
  }
245
 
}
246
 
 
247
 
void KeySequenceWidget::updateShortcutDisplay() {
248
 
  QString s = _keySequence.toString(QKeySequence::NativeText);
249
 
  s.replace('&', QLatin1String("&&"));
250
 
 
251
 
  if(_isRecording) {
252
 
    if(_modifierKeys) {
 
165
    : QWidget(parent),
 
166
    _shortcutsModel(0),
 
167
    _isRecording(false),
 
168
    _modifierKeys(0)
 
169
{
 
170
    QHBoxLayout *layout = new QHBoxLayout(this);
 
171
    layout->setMargin(0);
 
172
 
 
173
    _keyButton = new KeySequenceButton(this, this);
 
174
    _keyButton->setFocusPolicy(Qt::StrongFocus);
 
175
    _keyButton->setIcon(SmallIcon("configure"));
 
176
    _keyButton->setToolTip(tr("Click on the button, then enter the shortcut like you would in the program.\nExample for Ctrl+a: hold the Ctrl key and press a."));
 
177
    layout->addWidget(_keyButton);
 
178
 
 
179
    _clearButton = new QToolButton(this);
 
180
    layout->addWidget(_clearButton);
 
181
 
 
182
    if (qApp->isLeftToRight())
 
183
        _clearButton->setIcon(SmallIcon("edit-clear-locationbar-rtl"));
 
184
    else
 
185
        _clearButton->setIcon(SmallIcon("edit-clear-locationbar-ltr"));
 
186
 
 
187
    setLayout(layout);
 
188
 
 
189
    connect(_keyButton, SIGNAL(clicked()), SLOT(startRecording()));
 
190
    connect(_keyButton, SIGNAL(clicked()), SIGNAL(clicked()));
 
191
    connect(_clearButton, SIGNAL(clicked()), SLOT(clear()));
 
192
    connect(_clearButton, SIGNAL(clicked()), SIGNAL(clicked()));
 
193
}
 
194
 
 
195
 
 
196
void KeySequenceWidget::setModel(ShortcutsModel *model)
 
197
{
 
198
    Q_ASSERT(!_shortcutsModel);
 
199
    _shortcutsModel = model;
 
200
}
 
201
 
 
202
 
 
203
bool KeySequenceWidget::isOkWhenModifierless(int keyQt) const
 
204
{
 
205
    //this whole function is a hack, but especially the first line of code
 
206
    if (QKeySequence(keyQt).toString().length() == 1)
 
207
        return false;
 
208
 
 
209
    switch (keyQt) {
 
210
    case Qt::Key_Return:
 
211
    case Qt::Key_Space:
 
212
    case Qt::Key_Tab:
 
213
    case Qt::Key_Backtab: //does this ever happen?
 
214
    case Qt::Key_Backspace:
 
215
    case Qt::Key_Delete:
 
216
        return false;
 
217
    default:
 
218
        return true;
 
219
    }
 
220
}
 
221
 
 
222
 
 
223
bool KeySequenceWidget::isShiftAsModifierAllowed(int keyQt) const
 
224
{
 
225
    // Shift only works as a modifier with certain keys. It's not possible
 
226
    // to enter the SHIFT+5 key sequence for me because this is handled as
 
227
    // '%' by qt on my keyboard.
 
228
    // The working keys are all hardcoded here :-(
 
229
    if (keyQt >= Qt::Key_F1 && keyQt <= Qt::Key_F35)
 
230
        return true;
 
231
 
 
232
    if (QChar(keyQt).isLetter())
 
233
        return true;
 
234
 
 
235
    switch (keyQt) {
 
236
    case Qt::Key_Return:
 
237
    case Qt::Key_Space:
 
238
    case Qt::Key_Backspace:
 
239
    case Qt::Key_Escape:
 
240
    case Qt::Key_Print:
 
241
    case Qt::Key_ScrollLock:
 
242
    case Qt::Key_Pause:
 
243
    case Qt::Key_PageUp:
 
244
    case Qt::Key_PageDown:
 
245
    case Qt::Key_Insert:
 
246
    case Qt::Key_Delete:
 
247
    case Qt::Key_Home:
 
248
    case Qt::Key_End:
 
249
    case Qt::Key_Up:
 
250
    case Qt::Key_Down:
 
251
    case Qt::Key_Left:
 
252
    case Qt::Key_Right:
 
253
        return true;
 
254
 
 
255
    default:
 
256
        return false;
 
257
    }
 
258
}
 
259
 
 
260
 
 
261
void KeySequenceWidget::updateShortcutDisplay()
 
262
{
 
263
    QString s = _keySequence.toString(QKeySequence::NativeText);
 
264
    s.replace('&', QLatin1String("&&"));
 
265
 
 
266
    if (_isRecording) {
 
267
        if (_modifierKeys) {
253
268
#ifdef Q_WS_MAC
254
 
      if(_modifierKeys & Qt::META)  s += QChar(kControlUnicode);
255
 
      if(_modifierKeys & Qt::ALT)   s += QChar(kOptionUnicode);
256
 
      if(_modifierKeys & Qt::SHIFT) s += QChar(kShiftUnicode);
257
 
      if(_modifierKeys & Qt::CTRL)  s += QChar(kCommandUnicode);
 
269
            if (_modifierKeys & Qt::META) s += QChar(kControlUnicode);
 
270
            if (_modifierKeys & Qt::ALT) s += QChar(kOptionUnicode);
 
271
            if (_modifierKeys & Qt::SHIFT) s += QChar(kShiftUnicode);
 
272
            if (_modifierKeys & Qt::CTRL) s += QChar(kCommandUnicode);
258
273
#else
259
 
      if(_modifierKeys & Qt::META)  s += tr("Meta", "Meta key") + '+';
260
 
      if(_modifierKeys & Qt::CTRL)  s += tr("Ctrl", "Ctrl key") + '+';
261
 
      if(_modifierKeys & Qt::ALT)   s += tr("Alt", "Alt key") + '+';
262
 
      if(_modifierKeys & Qt::SHIFT) s += tr("Shift", "Shift key") + '+';
 
274
            if (_modifierKeys & Qt::META) s += tr("Meta", "Meta key") + '+';
 
275
            if (_modifierKeys & Qt::CTRL) s += tr("Ctrl", "Ctrl key") + '+';
 
276
            if (_modifierKeys & Qt::ALT) s += tr("Alt", "Alt key") + '+';
 
277
            if (_modifierKeys & Qt::SHIFT) s += tr("Shift", "Shift key") + '+';
263
278
#endif
264
 
    } else {
265
 
      s = tr("Input", "What the user inputs now will be taken as the new shortcut");
266
 
    }
267
 
    // make it clear that input is still going on
268
 
    s.append(" ...");
269
 
  }
270
 
 
271
 
  if(s.isEmpty()) {
272
 
    s = tr("None", "No shortcut defined");
273
 
  }
274
 
 
275
 
  s.prepend(' ');
276
 
  s.append(' ');
277
 
  _keyButton->setText(s);
278
 
}
279
 
 
280
 
void KeySequenceWidget::startRecording() {
281
 
  _modifierKeys = 0;
282
 
  _oldKeySequence = _keySequence;
283
 
  _keySequence = QKeySequence();
284
 
  _conflictingIndex = QModelIndex();
285
 
  _isRecording = true;
286
 
  _keyButton->grabKeyboard();
287
 
 
288
 
  if(!QWidget::keyboardGrabber()) {
289
 
    qWarning() << "Failed to grab the keyboard! Most likely qt's nograb option is active";
290
 
  }
291
 
 
292
 
  _keyButton->setDown(true);
293
 
  updateShortcutDisplay();
294
 
}
295
 
 
296
 
 
297
 
void KeySequenceWidget::doneRecording() {
298
 
  bool wasRecording = _isRecording;
299
 
  _isRecording = false;
300
 
  _keyButton->releaseKeyboard();
301
 
  _keyButton->setDown(false);
302
 
 
303
 
  if(!wasRecording || _keySequence == _oldKeySequence) {
304
 
    // The sequence hasn't changed
305
 
    updateShortcutDisplay();
306
 
    return;
307
 
  }
308
 
 
309
 
  if(!isKeySequenceAvailable(_keySequence)) {
 
279
        }
 
280
        else {
 
281
            s = tr("Input", "What the user inputs now will be taken as the new shortcut");
 
282
        }
 
283
        // make it clear that input is still going on
 
284
        s.append(" ...");
 
285
    }
 
286
 
 
287
    if (s.isEmpty()) {
 
288
        s = tr("None", "No shortcut defined");
 
289
    }
 
290
 
 
291
    s.prepend(' ');
 
292
    s.append(' ');
 
293
    _keyButton->setText(s);
 
294
}
 
295
 
 
296
 
 
297
void KeySequenceWidget::startRecording()
 
298
{
 
299
    _modifierKeys = 0;
 
300
    _oldKeySequence = _keySequence;
 
301
    _keySequence = QKeySequence();
 
302
    _conflictingIndex = QModelIndex();
 
303
    _isRecording = true;
 
304
    _keyButton->grabKeyboard();
 
305
 
 
306
    if (!QWidget::keyboardGrabber()) {
 
307
        qWarning() << "Failed to grab the keyboard! Most likely qt's nograb option is active";
 
308
    }
 
309
 
 
310
    _keyButton->setDown(true);
 
311
    updateShortcutDisplay();
 
312
}
 
313
 
 
314
 
 
315
void KeySequenceWidget::doneRecording()
 
316
{
 
317
    bool wasRecording = _isRecording;
 
318
    _isRecording = false;
 
319
    _keyButton->releaseKeyboard();
 
320
    _keyButton->setDown(false);
 
321
 
 
322
    if (!wasRecording || _keySequence == _oldKeySequence) {
 
323
        // The sequence hasn't changed
 
324
        updateShortcutDisplay();
 
325
        return;
 
326
    }
 
327
 
 
328
    if (!isKeySequenceAvailable(_keySequence)) {
 
329
        _keySequence = _oldKeySequence;
 
330
    }
 
331
    else if (wasRecording) {
 
332
        emit keySequenceChanged(_keySequence, _conflictingIndex);
 
333
    }
 
334
    updateShortcutDisplay();
 
335
}
 
336
 
 
337
 
 
338
void KeySequenceWidget::cancelRecording()
 
339
{
310
340
    _keySequence = _oldKeySequence;
311
 
  } else if(wasRecording) {
312
 
    emit keySequenceChanged(_keySequence, _conflictingIndex);
313
 
  }
314
 
  updateShortcutDisplay();
315
 
}
316
 
 
317
 
void KeySequenceWidget::cancelRecording() {
318
 
  _keySequence = _oldKeySequence;
319
 
  doneRecording();
320
 
}
321
 
 
322
 
void KeySequenceWidget::setKeySequence(const QKeySequence &seq) {
323
 
  // oldKeySequence holds the key sequence before recording started, if setKeySequence()
324
 
  // is called while not recording then set oldKeySequence to the existing sequence so
325
 
  // that the keySequenceChanged() signal is emitted if the new and previous key
326
 
  // sequences are different
327
 
  if(!isRecording())
328
 
    _oldKeySequence = _keySequence;
329
 
 
330
 
  _keySequence = seq;
331
 
  _clearButton->setVisible(!_keySequence.isEmpty());
332
 
  doneRecording();
333
 
}
334
 
 
335
 
void KeySequenceWidget::clear() {
336
 
  setKeySequence(QKeySequence());
337
 
  // setKeySequence() won't emit a signal when we're not recording
338
 
  emit keySequenceChanged(QKeySequence());
339
 
}
340
 
 
341
 
bool KeySequenceWidget::isKeySequenceAvailable(const QKeySequence &seq) {
342
 
  if(seq.isEmpty())
 
341
    doneRecording();
 
342
}
 
343
 
 
344
 
 
345
void KeySequenceWidget::setKeySequence(const QKeySequence &seq)
 
346
{
 
347
    // oldKeySequence holds the key sequence before recording started, if setKeySequence()
 
348
    // is called while not recording then set oldKeySequence to the existing sequence so
 
349
    // that the keySequenceChanged() signal is emitted if the new and previous key
 
350
    // sequences are different
 
351
    if (!isRecording())
 
352
        _oldKeySequence = _keySequence;
 
353
 
 
354
    _keySequence = seq;
 
355
    _clearButton->setVisible(!_keySequence.isEmpty());
 
356
    doneRecording();
 
357
}
 
358
 
 
359
 
 
360
void KeySequenceWidget::clear()
 
361
{
 
362
    setKeySequence(QKeySequence());
 
363
    // setKeySequence() won't emit a signal when we're not recording
 
364
    emit keySequenceChanged(QKeySequence());
 
365
}
 
366
 
 
367
 
 
368
bool KeySequenceWidget::isKeySequenceAvailable(const QKeySequence &seq)
 
369
{
 
370
    if (seq.isEmpty())
 
371
        return true;
 
372
 
 
373
    // We need to access the root model, not the filtered one
 
374
    for (int cat = 0; cat < _shortcutsModel->rowCount(); cat++) {
 
375
        QModelIndex catIdx = _shortcutsModel->index(cat, 0);
 
376
        for (int r = 0; r < _shortcutsModel->rowCount(catIdx); r++) {
 
377
            QModelIndex actIdx = _shortcutsModel->index(r, 0, catIdx);
 
378
            Q_ASSERT(actIdx.isValid());
 
379
            if (actIdx.data(ShortcutsModel::ActiveShortcutRole).value<QKeySequence>() != seq)
 
380
                continue;
 
381
 
 
382
            if (!actIdx.data(ShortcutsModel::IsConfigurableRole).toBool()) {
 
383
                QMessageBox::warning(this, tr("Shortcut Conflict"),
 
384
                    tr("The \"%1\" shortcut is already in use, and cannot be configured.\nPlease choose another one.").arg(seq.toString(QKeySequence::NativeText)),
 
385
                    QMessageBox::Ok);
 
386
                return false;
 
387
            }
 
388
 
 
389
            QMessageBox box(QMessageBox::Warning, tr("Shortcut Conflict"),
 
390
                (tr("The \"%1\" shortcut is ambiguous with the shortcut for the following action:")
 
391
                 + "<br><ul><li>%2</li></ul><br>"
 
392
                 + tr("Do you want to reassign this shortcut to the selected action?")
 
393
                ).arg(seq.toString(QKeySequence::NativeText), actIdx.data().toString()),
 
394
                QMessageBox::Cancel, this);
 
395
            box.addButton(tr("Reassign"), QMessageBox::AcceptRole);
 
396
            if (box.exec() == QMessageBox::Cancel)
 
397
                return false;
 
398
 
 
399
            _conflictingIndex = actIdx;
 
400
            return true;
 
401
        }
 
402
    }
343
403
    return true;
344
 
 
345
 
  // We need to access the root model, not the filtered one
346
 
  for(int cat = 0; cat < _shortcutsModel->rowCount(); cat++) {
347
 
    QModelIndex catIdx = _shortcutsModel->index(cat, 0);
348
 
    for(int r = 0; r < _shortcutsModel->rowCount(catIdx); r++) {
349
 
      QModelIndex actIdx = _shortcutsModel->index(r, 0, catIdx);
350
 
      Q_ASSERT(actIdx.isValid());
351
 
      if(actIdx.data(ShortcutsModel::ActiveShortcutRole).value<QKeySequence>() != seq)
352
 
        continue;
353
 
 
354
 
      if(!actIdx.data(ShortcutsModel::IsConfigurableRole).toBool()) {
355
 
        QMessageBox::warning(this, tr("Shortcut Conflict"),
356
 
                             tr("The \"%1\" shortcut is already in use, and cannot be configured.\nPlease choose another one.").arg(seq.toString(QKeySequence::NativeText)),
357
 
                             QMessageBox::Ok);
358
 
        return false;
359
 
      }
360
 
 
361
 
      QMessageBox box(QMessageBox::Warning, tr("Shortcut Conflict"),
362
 
                      (tr("The \"%1\" shortcut is ambiguous with the shortcut for the following action:")
363
 
                       + "<br><ul><li>%2</li></ul><br>"
364
 
                       + tr("Do you want to reassign this shortcut to the selected action?")
365
 
                       ).arg(seq.toString(QKeySequence::NativeText), actIdx.data().toString()),
366
 
                      QMessageBox::Cancel, this);
367
 
      box.addButton(tr("Reassign"), QMessageBox::AcceptRole);
368
 
      if(box.exec() == QMessageBox::Cancel)
369
 
        return false;
370
 
 
371
 
      _conflictingIndex = actIdx;
372
 
      return true;
373
 
    }
374
 
  }
375
 
  return true;
376
404
}