src/gui/widgets/qmainwindowlayout_mac.mm
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <private/qmainwindowlayout_p.h>
       
    43 #include <qtoolbar.h>
       
    44 #include <private/qtoolbarlayout_p.h>
       
    45 #include <private/qt_cocoa_helpers_mac_p.h>
       
    46 
       
    47 #ifndef QT_MAC_USE_COCOA
       
    48 #include <Carbon/Carbon.h>
       
    49 #else
       
    50 #include <private/qcocoatoolbardelegate_mac_p.h>
       
    51 #endif
       
    52 
       
    53 QT_BEGIN_NAMESPACE
       
    54 #ifdef QT_NAMESPACE
       
    55 
       
    56 // namespace up the stuff
       
    57 #define SS(x) #x
       
    58 #define S0(x) SS(x)
       
    59 #define S "com.trolltech.qt-" S0(QT_NAMESPACE) ".qmainwindow.qtoolbarInHIToolbar"
       
    60 #define SToolbar "com.trolltech.qt-" S0(QT_NAMESPACE) ".hitoolbar-qtoolbar"
       
    61 #define SNSToolbar "com.trolltech.qt-" S0(QT_NAMESPACE) ".qtoolbarInNSToolbar"
       
    62 #define MacToolbar "com.trolltech.qt-" S0(QT_NAMESPACE) ".qmainwindow.mactoolbar"
       
    63 
       
    64 #ifndef QT_MAC_USE_COCOA
       
    65 static CFStringRef kQToolBarHIToolbarItemClassID = CFSTR(S);
       
    66 static CFStringRef kQToolBarHIToolbarIdentifier = CFSTR(SToolbar);
       
    67 #else
       
    68 static NSString *kQToolBarNSToolbarIdentifier = @SNSToolbar;
       
    69 #endif
       
    70 static CFStringRef kQMainWindowMacToolbarID = CFSTR(MacToolbar);
       
    71 #undef SS
       
    72 #undef S0
       
    73 #undef S
       
    74 #undef SToolbar
       
    75 #undef SNSToolbar
       
    76 #undef MacToolbar
       
    77 
       
    78 #else
       
    79 #ifndef QT_MAC_USE_COCOA
       
    80 static CFStringRef kQToolBarHIToolbarItemClassID = CFSTR("com.trolltech.qt.qmainwindow.qtoolbarInHIToolbar");
       
    81 static CFStringRef kQToolBarHIToolbarIdentifier = CFSTR("com.trolltech.qt.hitoolbar-qtoolbar");
       
    82 #else
       
    83 static NSString *kQToolBarNSToolbarIdentifier = @"com.trolltech.qt.qmainwindow.qtoolbarInNSToolbar";
       
    84 #endif
       
    85 static CFStringRef kQMainWindowMacToolbarID = CFSTR("com.trolltech.qt.qmainwindow.mactoolbar");
       
    86 #endif // QT_NAMESPACE
       
    87 
       
    88 #ifndef QT_MAC_USE_COCOA
       
    89 
       
    90 static const int kEventParamQToolBar = 'QTBR';
       
    91 static const int kEventParamQMainWindowLayout = 'QMWL';
       
    92 
       
    93 const EventTypeSpec qtoolbarEvents[] =
       
    94 {
       
    95     { kEventClassHIObject, kEventHIObjectConstruct },
       
    96     { kEventClassHIObject, kEventHIObjectDestruct },
       
    97     { kEventClassHIObject, kEventHIObjectInitialize },
       
    98     { kEventClassToolbarItem, kEventToolbarItemCreateCustomView }
       
    99 };
       
   100 
       
   101 struct QToolBarInHIToolbarInfo
       
   102 {
       
   103     QToolBarInHIToolbarInfo(HIToolbarItemRef item)
       
   104         : toolbarItem(item), mainWindowLayout(0)
       
   105     {}
       
   106     HIToolbarItemRef toolbarItem;
       
   107     QMainWindowLayout *mainWindowLayout;
       
   108 };
       
   109 
       
   110 OSStatus QMainWindowLayout::qtoolbarInHIToolbarHandler(EventHandlerCallRef inCallRef,
       
   111                                                        EventRef event, void *data)
       
   112 {
       
   113     OSStatus result = eventNotHandledErr;
       
   114     QToolBarInHIToolbarInfo *object = static_cast<QToolBarInHIToolbarInfo *>(data);
       
   115 
       
   116     switch (GetEventClass(event)) {
       
   117         case kEventClassHIObject:
       
   118             switch (GetEventKind(event)) {
       
   119                 case kEventHIObjectConstruct:
       
   120                 {
       
   121                     HIObjectRef toolbarItem;
       
   122                     GetEventParameter(event, kEventParamHIObjectInstance, typeHIObjectRef,
       
   123                                       0, sizeof( HIObjectRef ), 0, &toolbarItem);
       
   124 
       
   125                     QToolBarInHIToolbarInfo *item = new QToolBarInHIToolbarInfo(toolbarItem);
       
   126                     SetEventParameter(event, kEventParamHIObjectInstance, typeVoidPtr,
       
   127                                       sizeof(void *), &item);
       
   128                     result = noErr;
       
   129                 }
       
   130                     break;
       
   131                 case kEventHIObjectInitialize:
       
   132                     result = CallNextEventHandler(inCallRef, event);
       
   133                     if (result == noErr) {
       
   134                         QToolBar *toolbar = 0;
       
   135                         QMainWindowLayout *layout = 0;
       
   136                         GetEventParameter(event, kEventParamQToolBar, typeVoidPtr,
       
   137                                           0, sizeof(void *), 0, &toolbar);
       
   138                         GetEventParameter(event, kEventParamQMainWindowLayout, typeVoidPtr,
       
   139                                           0, sizeof(void *), 0, &layout);
       
   140                         object->mainWindowLayout = layout;
       
   141                         object->mainWindowLayout->unifiedToolbarHash.insert(object->toolbarItem, toolbar);
       
   142                         HIToolbarItemChangeAttributes(object->toolbarItem,
       
   143                                                       kHIToolbarItemLabelDisabled, 0);
       
   144                     }
       
   145                     break;
       
   146 
       
   147                 case kEventHIObjectDestruct:
       
   148                     delete object;
       
   149                     result = noErr;
       
   150                     break;
       
   151             }
       
   152             break;
       
   153 
       
   154         case kEventClassToolbarItem:
       
   155             switch (GetEventKind(event))
       
   156         {
       
   157             case kEventToolbarItemCreateCustomView:
       
   158             {
       
   159                 QToolBar *toolbar
       
   160                 = object->mainWindowLayout->unifiedToolbarHash.value(object->toolbarItem);
       
   161                 if (toolbar) {
       
   162                     HIViewRef hiview = HIViewRef(toolbar->winId());
       
   163                     SetEventParameter(event, kEventParamControlRef, typeControlRef,
       
   164                                       sizeof(HIViewRef), &hiview);
       
   165                     result = noErr;
       
   166                 }
       
   167             }
       
   168                 break;
       
   169         }
       
   170             break;
       
   171     }
       
   172     return result;
       
   173 }
       
   174 
       
   175 void QMainWindowLayout::qtMacHIToolbarRegisterQToolBarInHIToolborItemClass()
       
   176 {
       
   177     static bool registered = false;
       
   178 
       
   179     if (!registered) {
       
   180         HIObjectRegisterSubclass( kQToolBarHIToolbarItemClassID,
       
   181                                  kHIToolbarItemClassID, 0, QMainWindowLayout::qtoolbarInHIToolbarHandler,
       
   182                                  GetEventTypeCount(qtoolbarEvents), qtoolbarEvents, 0, 0 );
       
   183         registered = true;
       
   184     }
       
   185 }
       
   186 
       
   187 static void GetToolbarAllowedItems(CFMutableArrayRef array)
       
   188 {
       
   189     CFArrayAppendValue(array, kQToolBarHIToolbarIdentifier);
       
   190 }
       
   191 
       
   192 HIToolbarItemRef QMainWindowLayout::createQToolBarInHIToolbarItem(QToolBar *toolbar,
       
   193                                                                   QMainWindowLayout *layout)
       
   194 {
       
   195     QMainWindowLayout::qtMacHIToolbarRegisterQToolBarInHIToolborItemClass();
       
   196 
       
   197     EventRef event;
       
   198     HIToolbarItemRef result = 0;
       
   199 
       
   200     CFStringRef identifier = kQToolBarHIToolbarIdentifier;
       
   201     UInt32 options = kHIToolbarItemAllowDuplicates;
       
   202 
       
   203     CreateEvent(0, kEventClassHIObject, kEventHIObjectInitialize,
       
   204                 GetCurrentEventTime(), 0, &event);
       
   205     SetEventParameter(event, kEventParamToolbarItemIdentifier, typeCFStringRef,
       
   206                       sizeof(CFStringRef), &identifier);
       
   207     SetEventParameter(event, kEventParamAttributes, typeUInt32, sizeof(UInt32), &options);
       
   208     SetEventParameter(event, kEventParamQToolBar, typeVoidPtr, sizeof(void *), &toolbar);
       
   209     SetEventParameter(event, kEventParamQMainWindowLayout, typeVoidPtr, sizeof(void *), &layout);
       
   210 
       
   211     HIObjectCreate(kQToolBarHIToolbarItemClassID, event,
       
   212                    static_cast<HIObjectRef *>(&result));
       
   213 
       
   214     ReleaseEvent(event);
       
   215     return result;
       
   216 
       
   217 }
       
   218 
       
   219 HIToolbarItemRef QMainWindowLayout::CreateToolbarItemForIdentifier(CFStringRef identifier,
       
   220                                                                    CFTypeRef data)
       
   221 {
       
   222     HIToolbarItemRef item = 0;
       
   223     if (CFStringCompare(kQToolBarHIToolbarIdentifier, identifier,
       
   224                         kCFCompareBackwards) == kCFCompareEqualTo) {
       
   225         if (data && CFGetTypeID(data) == CFArrayGetTypeID()) {
       
   226             CFArrayRef array = static_cast<CFArrayRef>(data);
       
   227             QToolBar *toolbar = static_cast<QToolBar *>(const_cast<void *>(CFArrayGetValueAtIndex(array, 0)));
       
   228             QMainWindowLayout *layout = static_cast<QMainWindowLayout *>(const_cast<void *>(CFArrayGetValueAtIndex(array, 1)));
       
   229             item = createQToolBarInHIToolbarItem(toolbar, layout);
       
   230         }
       
   231     }
       
   232     return item;
       
   233 }
       
   234 
       
   235 static const EventTypeSpec kToolbarEvents[] = {
       
   236 { kEventClassToolbar, kEventToolbarGetDefaultIdentifiers },
       
   237 { kEventClassToolbar, kEventToolbarGetAllowedIdentifiers },
       
   238 { kEventClassToolbar, kEventToolbarCreateItemWithIdentifier },
       
   239 { kEventClassToolbar, kEventToolbarItemAdded },
       
   240 { kEventClassToolbar, kEventToolbarItemRemoved }
       
   241 };
       
   242 
       
   243 OSStatus QMainWindowLayout::qtmacToolbarDelegate(EventHandlerCallRef, EventRef event, void *data)
       
   244 {
       
   245     QMainWindowLayout *mainWindowLayout = static_cast<QMainWindowLayout *>(data);
       
   246     OSStatus            result = eventNotHandledErr;
       
   247     CFMutableArrayRef   array;
       
   248     CFStringRef         identifier;
       
   249     switch (GetEventKind(event)) {
       
   250         case kEventToolbarGetDefaultIdentifiers:
       
   251         case kEventToolbarGetAllowedIdentifiers:
       
   252             GetEventParameter(event, kEventParamMutableArray, typeCFMutableArrayRef, 0,
       
   253                               sizeof(CFMutableArrayRef), 0, &array);
       
   254             GetToolbarAllowedItems(array);
       
   255             result = noErr;
       
   256             break;
       
   257         case kEventToolbarCreateItemWithIdentifier: {
       
   258             HIToolbarItemRef item;
       
   259             CFTypeRef data = 0;
       
   260             OSStatus err = GetEventParameter(event, kEventParamToolbarItemIdentifier, typeCFStringRef,
       
   261                                              0, sizeof(CFStringRef), 0, &identifier);
       
   262             err = GetEventParameter(event, kEventParamToolbarItemConfigData, typeCFTypeRef,
       
   263                                     0, sizeof(CFTypeRef), 0, &data);
       
   264             item = CreateToolbarItemForIdentifier(identifier, data);
       
   265             if (item) {
       
   266                 result = SetEventParameter(event, kEventParamToolbarItem, typeHIToolbarItemRef,
       
   267                                            sizeof(HIToolbarItemRef), &item );
       
   268             }
       
   269             break;
       
   270         }
       
   271         case kEventToolbarItemAdded: {
       
   272             // Double check that our "view" of the toolbar is similar.
       
   273             HIToolbarItemRef item;
       
   274             CFIndex index;
       
   275             if (GetEventParameter(event, kEventParamToolbarItem, typeHIToolbarItemRef,
       
   276                                   0, sizeof(HIToolbarItemRef), 0, &item) == noErr
       
   277                 && GetEventParameter(event, kEventParamIndex, typeCFIndex, 0,
       
   278                                      sizeof(CFIndex), 0, &index) == noErr) {
       
   279                 CFRetain(item); // We will watch this until it's removed from the list (or bust).
       
   280                 mainWindowLayout->toolbarItemsCopy.insert(index, item);
       
   281                 QToolBar *toolbar = mainWindowLayout->unifiedToolbarHash.value(item);
       
   282                 if (toolbar) {
       
   283                     int toolbarIndex = mainWindowLayout->qtoolbarsInUnifiedToolbarList.indexOf(toolbar);
       
   284                     if (index != toolbarIndex) {
       
   285                         // Dang, we must be out of sync, rebuild it from the "toolbarItemsCopy"
       
   286                         mainWindowLayout->qtoolbarsInUnifiedToolbarList.clear();
       
   287                         for (int i = 0; i < mainWindowLayout->toolbarItemsCopy.size(); ++i) {
       
   288                             // This will either append the correct toolbar or an
       
   289                             // null toolbar. This is fine because this list
       
   290                             // is really only kept to make sure that things are but in the right order.
       
   291                             mainWindowLayout->qtoolbarsInUnifiedToolbarList.append(
       
   292                                                                                    mainWindowLayout->unifiedToolbarHash.value(mainWindowLayout->
       
   293                                                                                                                               toolbarItemsCopy.at(i)));
       
   294                         }
       
   295                     }
       
   296                 }
       
   297             }
       
   298             break;
       
   299         }
       
   300         case kEventToolbarItemRemoved: {
       
   301             HIToolbarItemRef item;
       
   302             if (GetEventParameter(event, kEventParamToolbarItem, typeHIToolbarItemRef,
       
   303                                   0, sizeof(HIToolbarItemRef), 0, &item) == noErr) {
       
   304                 mainWindowLayout->unifiedToolbarHash.remove(item);
       
   305                 for (int i = 0; i < mainWindowLayout->toolbarItemsCopy.size(); ++i) {
       
   306                     if (mainWindowLayout->toolbarItemsCopy.at(i) == item) {
       
   307                         // I know about it, so release it.
       
   308                         mainWindowLayout->toolbarItemsCopy.removeAt(i);
       
   309                         mainWindowLayout->qtoolbarsInUnifiedToolbarList.removeAt(i);
       
   310                         CFRelease(item);
       
   311                         break;
       
   312                     }
       
   313                 }
       
   314             }
       
   315             break;
       
   316         }
       
   317     }
       
   318     return result;
       
   319 }
       
   320 #endif // ! QT_MAC_USE_COCOA
       
   321 
       
   322 #ifndef kWindowUnifiedTitleAndToolbarAttribute
       
   323 #define kWindowUnifiedTitleAndToolbarAttribute (1 << 7)
       
   324 #endif
       
   325 
       
   326 void QMainWindowLayout::updateHIToolBarStatus()
       
   327 {
       
   328     bool useMacToolbar = layoutState.mainWindow->unifiedTitleAndToolBarOnMac();
       
   329 #ifndef QT_MAC_USE_COCOA
       
   330     if (useMacToolbar) {
       
   331         ChangeWindowAttributes(qt_mac_window_for(layoutState.mainWindow),
       
   332                                kWindowUnifiedTitleAndToolbarAttribute, 0);
       
   333     } else {
       
   334         ChangeWindowAttributes(qt_mac_window_for(layoutState.mainWindow),
       
   335                                0, kWindowUnifiedTitleAndToolbarAttribute);
       
   336     }
       
   337 #endif
       
   338 
       
   339     layoutState.mainWindow->setUpdatesEnabled(false);  // reduces a little bit of flicker, not all though
       
   340     if (!useMacToolbar) {
       
   341         macWindowToolbarShow(layoutState.mainWindow, false);
       
   342         // Move everything out of the HIToolbar into the main toolbar.
       
   343         while (!qtoolbarsInUnifiedToolbarList.isEmpty()) {
       
   344             // Should shrink the list by one every time.
       
   345             layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, qtoolbarsInUnifiedToolbarList.first());
       
   346         }
       
   347         macWindowToolbarSet(qt_mac_window_for(layoutState.mainWindow), 0);
       
   348     } else {
       
   349         QList<QToolBar *> toolbars = layoutState.mainWindow->findChildren<QToolBar *>();
       
   350         for (int i = 0; i < toolbars.size(); ++i) {
       
   351             QToolBar *toolbar = toolbars.at(i);
       
   352             if (toolBarArea(toolbar) == Qt::TopToolBarArea) {
       
   353                 removeWidget(toolbar);  // Do this here, because we are in an in-between state.
       
   354                 layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar);
       
   355             }
       
   356         }
       
   357         syncUnifiedToolbarVisibility();
       
   358     }
       
   359     layoutState.mainWindow->setUpdatesEnabled(true);
       
   360 }
       
   361 
       
   362 void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar)
       
   363 {
       
   364     // This layering could go on to one more level, but I decided to stop here.
       
   365     // The HIToolbar and NSToolbar APIs are fairly similar as you will see.
       
   366     if (toolbar == 0)
       
   367         return;
       
   368 
       
   369 
       
   370     QToolBarLayout *toolbarLayout = static_cast<QToolBarLayout *>(toolbar->layout());
       
   371     toolbarSaveState.insert(toolbar, ToolBarSaveState(toolbar->isMovable(),
       
   372                                                       toolbar->maximumSize()));
       
   373 
       
   374     if (toolbarLayout->hasExpandFlag() == false)
       
   375         toolbar->setMaximumSize(toolbar->sizeHint());
       
   376 
       
   377     toolbar->setMovable(false);
       
   378     toolbarLayout->setUsePopupMenu(true);
       
   379     // Make the toolbar a child of the mainwindow to avoid creating a window.
       
   380     toolbar->setParent(layoutState.mainWindow);
       
   381     toolbar->createWinId();  // Now create the OSViewRef.
       
   382 
       
   383     layoutState.mainWindow->createWinId();
       
   384 
       
   385     OSWindowRef window = qt_mac_window_for(layoutState.mainWindow);
       
   386     int beforeIndex = qtoolbarsInUnifiedToolbarList.indexOf(before);
       
   387     if (beforeIndex == -1)
       
   388         beforeIndex = qtoolbarsInUnifiedToolbarList.size();
       
   389 
       
   390     int toolbarIndex = qtoolbarsInUnifiedToolbarList.indexOf(toolbar);
       
   391 #ifndef QT_MAC_USE_COCOA
       
   392     HIToolbarRef macToolbar = NULL;
       
   393     if ((GetWindowToolbar(window, &macToolbar) == noErr) && !macToolbar) {
       
   394         HIToolbarCreate(kQMainWindowMacToolbarID,
       
   395                         kHIToolbarItemAllowDuplicates, &macToolbar);
       
   396         InstallEventHandler(HIObjectGetEventTarget(static_cast<HIToolbarRef>(macToolbar)),
       
   397                             QMainWindowLayout::qtmacToolbarDelegate, GetEventTypeCount(kToolbarEvents),
       
   398                             kToolbarEvents, this, 0);
       
   399         HIToolbarSetDisplaySize(macToolbar, kHIToolbarDisplaySizeNormal);
       
   400         HIToolbarSetDisplayMode(macToolbar, kHIToolbarDisplayModeIconOnly);
       
   401         macWindowToolbarSet(window, macToolbar);
       
   402         if (layoutState.mainWindow->isVisible())
       
   403             macWindowToolbarShow(layoutState.mainWindow, true);
       
   404         CFRelease(macToolbar);
       
   405     }
       
   406 #else
       
   407     QMacCocoaAutoReleasePool pool;
       
   408     NSToolbar *macToolbar = [window toolbar];
       
   409     if (macToolbar == nil) {
       
   410         macToolbar = [[NSToolbar alloc] initWithIdentifier:(NSString *)kQMainWindowMacToolbarID];
       
   411         [macToolbar setDisplayMode:NSToolbarDisplayModeIconOnly];
       
   412         [macToolbar setSizeMode:NSToolbarSizeModeRegular];
       
   413         [macToolbar setDelegate:[[QCocoaToolBarDelegate alloc] initWithMainWindowLayout:this]];
       
   414         [window setToolbar:macToolbar];
       
   415         [macToolbar release];
       
   416     }
       
   417 #endif
       
   418     if (toolbarIndex != -1) {
       
   419         qtoolbarsInUnifiedToolbarList.removeAt(toolbarIndex);
       
   420 #ifndef QT_MAC_USE_COCOA
       
   421         HIToolbarRemoveItemAtIndex(macToolbar, toolbarIndex);
       
   422 #else
       
   423         [macToolbar removeItemAtIndex:toolbarIndex];
       
   424 #endif
       
   425     }
       
   426     qtoolbarsInUnifiedToolbarList.insert(beforeIndex, toolbar);
       
   427 #ifndef QT_MAC_USE_COCOA
       
   428     QCFType<HIToolbarItemRef> outItem;
       
   429     const QObject *stupidArray[] = { toolbar, this };
       
   430     QCFType<CFArrayRef> array = CFArrayCreate(0, reinterpret_cast<const void **>(&stupidArray),
       
   431                                               2, 0);
       
   432     HIToolbarCreateItemWithIdentifier(macToolbar, kQToolBarHIToolbarIdentifier,
       
   433                                       array, &outItem);
       
   434     HIToolbarInsertItemAtIndex(macToolbar, outItem, beforeIndex);
       
   435 #else
       
   436     NSString *toolbarID = kQToolBarNSToolbarIdentifier;
       
   437     toolbarID = [toolbarID stringByAppendingFormat:@"%p", toolbar];
       
   438     cocoaItemIDToToolbarHash.insert(qt_mac_NSStringToQString(toolbarID), toolbar);
       
   439     [macToolbar insertItemWithItemIdentifier:toolbarID atIndex:beforeIndex];
       
   440 #endif
       
   441 }
       
   442 
       
   443 void QMainWindowLayout::removeFromMacToolbar(QToolBar *toolbar)
       
   444 {
       
   445     QHash<void *, QToolBar *>::iterator it = unifiedToolbarHash.begin();
       
   446     while (it != unifiedToolbarHash.end()) {
       
   447         if (it.value() == toolbar) {
       
   448             // Rescue our HIView and set it on the mainWindow again.
       
   449             bool saveVisible = !toolbar->isHidden();
       
   450             toolbar->setParent(0);
       
   451             toolbar->setParent(parentWidget());
       
   452             toolbar->setVisible(saveVisible);
       
   453             ToolBarSaveState saveState = toolbarSaveState.value(toolbar);
       
   454             static_cast<QToolBarLayout *>(toolbar->layout())->setUsePopupMenu(false);
       
   455             toolbar->setMovable(saveState.movable);
       
   456             toolbar->setMaximumSize(saveState.maximumSize);
       
   457             toolbarSaveState.remove(toolbar);
       
   458 #ifndef QT_MAC_USE_COCOA
       
   459             HIToolbarItemRef item = static_cast<HIToolbarItemRef>(it.key());
       
   460             HIToolbarRemoveItemAtIndex(HIToolbarItemGetToolbar(item),
       
   461                                        toolbarItemsCopy.indexOf(item));
       
   462 #else
       
   463             NSToolbarItem *item = static_cast<NSToolbarItem *>(it.key());
       
   464             [[qt_mac_window_for(layoutState.mainWindow->window()) toolbar]
       
   465                 removeItemAtIndex:toolbarItemsCopy.indexOf(item)];
       
   466             // In Carbon this hash and list gets emptied via events. In Cocoa, we have to do it ourselves here.
       
   467             it = unifiedToolbarHash.erase(it);
       
   468             qtoolbarsInUnifiedToolbarList.removeAll(toolbar);
       
   469 #endif
       
   470             break;
       
   471         }
       
   472         ++it;
       
   473     }
       
   474 }
       
   475 
       
   476 void QMainWindowLayout::cleanUpMacToolbarItems()
       
   477 {
       
   478     for (int i = 0; i < toolbarItemsCopy.size(); ++i)
       
   479         CFRelease(toolbarItemsCopy.at(i));
       
   480     toolbarItemsCopy.clear();
       
   481     unifiedToolbarHash.clear();
       
   482 }
       
   483 
       
   484 void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const
       
   485 {
       
   486 #ifdef QT_MAC_USE_COCOA
       
   487     QHash<void *, QToolBar *>::const_iterator it = unifiedToolbarHash.constBegin();
       
   488     NSToolbarItem *item = nil;
       
   489     while (it != unifiedToolbarHash.constEnd()) {
       
   490         if (tb == it.value()) {
       
   491             item = static_cast<NSToolbarItem *>(it.key());
       
   492             break;
       
   493         }
       
   494         ++it;
       
   495     }
       
   496     if (item) {
       
   497         QMacCocoaAutoReleasePool pool;
       
   498         QWidgetItem layoutItem(tb);
       
   499         QSize size = layoutItem.maximumSize();
       
   500         NSSize nssize = NSMakeSize(size.width(), size.height() - 2);
       
   501         [item setMaxSize:nssize];
       
   502         size = layoutItem.minimumSize();
       
   503         nssize.width = size.width();
       
   504         nssize.height = size.height() - 2;
       
   505         [item setMinSize:nssize];
       
   506     }
       
   507 #else
       
   508     Q_UNUSED(tb);
       
   509 #endif
       
   510 }
       
   511 
       
   512 void QMainWindowLayout::syncUnifiedToolbarVisibility()
       
   513 {
       
   514     if (blockVisiblityCheck)
       
   515         return;
       
   516 
       
   517     Q_ASSERT(layoutState.mainWindow->unifiedTitleAndToolBarOnMac());
       
   518     bool show = false;
       
   519     const int ToolBarCount = qtoolbarsInUnifiedToolbarList.count();
       
   520     for (int i = 0; i < ToolBarCount; ++i) {
       
   521         if (qtoolbarsInUnifiedToolbarList.at(i)->isVisible()) {
       
   522             show = true;
       
   523             break;
       
   524         }
       
   525     }
       
   526     macWindowToolbarShow(layoutState.mainWindow, show);
       
   527 }
       
   528 
       
   529 QT_END_NAMESPACE