comparison framework/MainWindowBase.cpp @ 384:ad33fdc4ad92 tonioni

OS/X: When augmenting a single-key shortcut associated with an action with a global shortcut, leave the shortcut attached to the original action as well if it is a menu action with no toolbar button. Do not augment toolbar actions with global shortcuts. Aims to fix #1009 (single-key shortcuts work, but do not appear in menu)
author Chris Cannam
date Fri, 18 Jul 2014 13:25:11 +0100
parents 6a84102c006a
children 105b4e237434
comparison
equal deleted inserted replaced
383:681447b07142 384:ad33fdc4ad92
292 { 292 {
293 #ifdef Q_OS_MAC 293 #ifdef Q_OS_MAC
294 // See https://bugreports.qt-project.org/browse/QTBUG-38256 and 294 // See https://bugreports.qt-project.org/browse/QTBUG-38256 and
295 // our issue #890 http://code.soundsoftware.ac.uk/issues/890 -- 295 // our issue #890 http://code.soundsoftware.ac.uk/issues/890 --
296 // single-key shortcuts that are associated only with a menu 296 // single-key shortcuts that are associated only with a menu
297 // action do not work with Qt 5.x under OS/X. 297 // action (and not with a toolbar button) do not work with Qt 5.x
298 // under OS/X.
298 // 299 //
299 // Apparently Cocoa never handled them as a matter of course, but 300 // Apparently Cocoa never handled them as a matter of course, but
300 // earlier versions of Qt picked them up as widget shortcuts and 301 // earlier versions of Qt picked them up as widget shortcuts and
301 // handled them anyway. That behaviour was removed to fix a crash 302 // handled them anyway. That behaviour was removed to fix a crash
302 // when invoking a menu while its window was overridden by a modal 303 // when invoking a menu while its window was overridden by a modal
303 // dialog (https://bugreports.qt-project.org/browse/QTBUG-30657). 304 // dialog (https://bugreports.qt-project.org/browse/QTBUG-30657).
304 // 305 //
305 // This workaround restores the single-key shortcut behaviour by 306 // This workaround restores the single-key shortcut behaviour by
306 // searching for single-key shortcuts in menus and replacing them 307 // searching in menus for single-key shortcuts that are associated
307 // with global application shortcuts that invoke the relevant 308 // only with the menu and not with a toolbar button, and
308 // actions, testing whether the actions are enabled on invocation. 309 // augmenting them with global application shortcuts that invoke
309 // As it happens, it also replaces some shortcuts that were 310 // the relevant actions, testing whether the actions are enabled
310 // working fine (because they were also associated with toolbar 311 // on invocation.
311 // buttons) but that seems to be OK so long as we remove the
312 // shortcuts from the actions as well as adding the new global
313 // shortcuts, to avoid an ambiguous shortcut error.
314 // 312 //
315 // If the Qt developers ever fix this in Qt (I couldn't think of 313 // (Previously this acted on all single-key shortcuts in menus,
316 // an obvious fix myself) then presumably we can remove this. 314 // and it removed the shortcut from the action when it created
315 // each new global one, in order to avoid an "ambiguous shortcut"
316 // error in the case where the action was also associated with a
317 // toolbar button. But that has the unwelcome side-effect of
318 // removing the shortcut hint from the menu entry. So now we leave
319 // the shortcut in the menu action as well as creating a global
320 // one, and we only act on shortcuts that have no toolbar button,
321 // i.e. that will not otherwise work. The downside is that if this
322 // bug is fixed in a future Qt release, we will start getting
323 // "ambiguous shortcut" errors from the menu entry actions and
324 // will need to update the code.)
317 325
318 QSignalMapper *mapper = new QSignalMapper(this); 326 QSignalMapper *mapper = new QSignalMapper(this);
319 327
320 connect(mapper, SIGNAL(mapped(QObject *)), 328 connect(mapper, SIGNAL(mapped(QObject *)),
321 this, SLOT(menuActionMapperInvoked(QObject *))); 329 this, SLOT(menuActionMapperInvoked(QObject *)));
322 330
323 foreach (QAction *a, menu->actions()) { 331 foreach (QAction *a, menu->actions()) {
332 QWidgetList ww = a->associatedWidgets();
333 bool hasButton = false;
334 foreach (QWidget *w, ww) {
335 if (qobject_cast<QAbstractButton *>(w)) {
336 hasButton = true;
337 break;
338 }
339 }
340 if (hasButton) continue;
324 QKeySequence sc = a->shortcut(); 341 QKeySequence sc = a->shortcut();
325 if (sc.count() == 1 && !(sc[0] & Qt::KeyboardModifierMask)) { 342 if (sc.count() == 1 && !(sc[0] & Qt::KeyboardModifierMask)) {
326 QShortcut *newSc = new QShortcut(sc, a->parentWidget()); 343 QShortcut *newSc = new QShortcut(sc, a->parentWidget());
327 QObject::connect(newSc, SIGNAL(activated()), mapper, SLOT(map())); 344 QObject::connect(newSc, SIGNAL(activated()), mapper, SLOT(map()));
328 mapper->setMapping(newSc, a); 345 mapper->setMapping(newSc, a);
329 a->setShortcut(QKeySequence()); // avoid ambiguous shortcut error
330 } 346 }
331 } 347 }
332 #endif 348 #endif
333 } 349 }
334 350