summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Sørvig <msorvig@trolltech.com>2009-06-16 11:12:26 (GMT)
committerMorten Sørvig <msorvig@trolltech.com>2009-06-16 11:19:55 (GMT)
commit1e6b142fa2833f55972d6d4aa7dde0bb215c2f25 (patch)
tree5fdca7f38b7849f00dd04a66da2d74ea164bf5d6
parentd9308550f104526d29b1cdd56514ae3bb967d7f9 (diff)
downloadQt-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
-rw-r--r--src/gui/widgets/qmenu_mac.mm59
-rw-r--r--src/gui/widgets/qmenu_p.h5
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);