diff options
author | Morten Sørvig <msorvig@trolltech.com> | 2009-06-16 11:12:26 (GMT) |
---|---|---|
committer | Morten Sørvig <msorvig@trolltech.com> | 2009-06-16 11:19:55 (GMT) |
commit | 1e6b142fa2833f55972d6d4aa7dde0bb215c2f25 (patch) | |
tree | 5fdca7f38b7849f00dd04a66da2d74ea164bf5d6 /src | |
parent | d9308550f104526d29b1cdd56514ae3bb967d7f9 (diff) | |
download | Qt-1e6b142fa2833f55972d6d4aa7dde0bb215c2f25.zip Qt-1e6b142fa2833f55972d6d4aa7dde0bb215c2f25.tar.gz Qt-1e6b142fa2833f55972d6d4aa7dde0bb215c2f25.tar.bz2 |
Implement QMenu::separatorsCollapsible on Mac/Cocoa.
Hide duplicate separators and separators at the beginning and end of the
menu. The main challenge here is that separators and "normal" menu items
can be added in any order, for example add all the separators first
and then fill in the items. This means that we have to redo the visibility
decision for separators above and below when adding normal items.
Reviewed-by: Prasanth Ullattil
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/widgets/qmenu_mac.mm | 59 | ||||
-rw-r--r-- | src/gui/widgets/qmenu_p.h | 5 |
2 files changed, 52 insertions, 12 deletions
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 67656b4..9b496ef 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -972,7 +972,7 @@ void Q_GUI_EXPORT qt_mac_set_menubar_merge(bool b) { qt_mac_no_menubar_merge = ! /***************************************************************************** QMenu bindings *****************************************************************************/ -QMenuPrivate::QMacMenuPrivate::QMacMenuPrivate() : menu(0) +QMenuPrivate::QMacMenuPrivate::QMacMenuPrivate(QMenuPrivate *menu) : menu(0), qmenu(menu) { } @@ -1300,22 +1300,61 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action) #else int itemIndex = [menu indexOfItem:item]; Q_ASSERT(itemIndex != -1); - if (action->action->isSeparator()) { + + // Separator handling: Menu items and separators can be added to a QMenu in + // any order (for example, add all the separators first and then "fill inn" + // the menu items). Create NSMenuItem seperatorItems for the Qt separators, + // and make sure that there are no double separators and no seprators + // at the top or bottom of the menu. + bool itemIsSeparator = action->action->isSeparator(); + bool previousItemIsSeparator = false; + if (itemIndex > 0) { + if ([[menu itemAtIndex : itemIndex - 1] isSeparatorItem]) + previousItemIsSeparator = true; + } + bool nexItemIsSeparator = false; + if (itemIndex > 0 && itemIndex < [menu numberOfItems] -1) { + if ([[menu itemAtIndex : itemIndex + 1] isSeparatorItem]) + nexItemIsSeparator = true; + } + bool itemIsAtBottomOfMenu = (itemIndex == [menu numberOfItems] - 1); + bool itemIsAtTopOfMenu = (itemIndex == 0); + + + if (itemIsSeparator) { + // Create separators items for actions that are now separators action->menuItem = [NSMenuItem separatorItem]; [action->menuItem retain]; + + // Hide duplicate/top/bottom separators. + if (qmenu->collapsibleSeparators && (previousItemIsSeparator || itemIsAtBottomOfMenu || itemIsAtTopOfMenu)) { + [action->menuItem setHidden : true]; + } + [menu insertItem: action->menuItem atIndex:itemIndex]; [menu removeItem:item]; [item release]; item = action->menuItem; return; - } else if ([item isSeparatorItem]) { - // I'm no longer a separator... - action->menuItem = createNSMenuItem(action->action->text()); - [menu insertItem:action->menuItem atIndex:itemIndex]; - [menu removeItem:item]; - [item release]; - item = action->menuItem; + } else { + // Create standard menu items for actions that are no longer separators + if ([item isSeparatorItem]) { + action->menuItem = createNSMenuItem(action->action->text()); + [menu insertItem:action->menuItem atIndex:itemIndex]; + [menu removeItem:item]; + [item release]; + item = action->menuItem; + } + + // Show separators that should now be visible since a non-separator + // item (the current item) was added. + if (previousItemIsSeparator) { + [[menu itemAtIndex : itemIndex - 1] setHidden : false]; + } else if (itemIsAtTopOfMenu && nexItemIsSeparator) { + [[menu itemAtIndex : itemIndex + 1] setHidden : false]; + } } + #endif //find text (and accel) @@ -1499,7 +1538,7 @@ QMenuPrivate::macMenu(OSMenuRef merge) if (mac_menu && mac_menu->menu) return mac_menu->menu; if (!mac_menu) - mac_menu = new QMacMenuPrivate; + mac_menu = new QMacMenuPrivate(this); mac_menu->menu = qt_mac_create_menu(q); if (merge) { #ifndef QT_MAC_USE_COCOA diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 1dfe701..20c63fe 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -263,8 +263,9 @@ public: struct QMacMenuPrivate { QList<QMacMenuAction*> actionItems; OSMenuRef menu; - QMacMenuPrivate(); - ~QMacMenuPrivate(); + QMenuPrivate *qmenu; + QMacMenuPrivate(QMenuPrivate *menu); + ~QMacMenuPrivate(); bool merged(const QAction *action) const; void addAction(QAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0); |