src/gui/widgets/qmaccocoaviewcontainer_mac.mm
changeset 0 1918ee327afb
child 4 3b1da2848fc7
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 #import <Cocoa/Cocoa.h>
       
    43 #include <private/qwidget_p.h>
       
    44 #include "qmaccocoaviewcontainer_mac.h"
       
    45 #include <private/qt_mac_p.h>
       
    46 
       
    47 /*!
       
    48     \class QMacCocoaViewContainer
       
    49     \since 4.5
       
    50 
       
    51     \brief The QMacCocoaViewContainer class provides a widget for Mac OS X that can be used to wrap arbitrary
       
    52     Cocoa views (i.e., NSView subclasses) and insert them into Qt hierarchies.
       
    53 
       
    54     \ingroup advanced
       
    55 
       
    56     While Qt offers a lot of classes for writing your application, Apple's
       
    57     Cocoa framework offers lots of functionality that is not currently in Qt or
       
    58     may never end up in Qt. Using QMacCocoaViewContainer, it is possible to put an
       
    59     arbitrary NSView-derived class from Cocoa and put it in a Qt hierarchy.
       
    60     Depending on how comfortable you are with using objective-C, you can use
       
    61     QMacCocoaViewContainer directly, or subclass it to wrap further functionality
       
    62     of the underlying NSView.
       
    63 
       
    64     QMacCocoaViewContainer works regardless if Qt is built against Carbon or
       
    65     Cocoa. However, QCocoaContainerView requires Mac OS X 10.5 or better to be
       
    66     used with Carbon.
       
    67 
       
    68     It should be also noted that at the low level on Mac OS X, there is a
       
    69     difference between windows (top-levels) and view (widgets that are inside a
       
    70     window). For this reason, make sure that the NSView that you are wrapping
       
    71     doesn't end up as a top-level. The best way to ensure this is to make sure
       
    72     you always have a parent and not set the parent to 0.
       
    73 
       
    74     If you are using QMacCocoaViewContainer as a sub-class and are mixing and
       
    75     matching objective-C with C++ (a.k.a. objective-C++). It is probably
       
    76     simpler to have your file end with \tt{.mm} than \tt{.cpp}. Most Apple tools will
       
    77     correctly identify the source as objective-C++.
       
    78 
       
    79     QMacCocoaViewContainer requires knowledge of how Cocoa works, especially in
       
    80     regard to its reference counting (retain/release) nature. It is noted in
       
    81     the functions below if there is any change in the reference count. Cocoa
       
    82     views often generate temporary objects that are released by an autorelease
       
    83     pool. If this is done outside of a running event loop, it is up to the
       
    84     developer to provide the autorelease pool.
       
    85 
       
    86     The following is a snippet of subclassing QMacCocoaViewContainer to wrap a NSSearchField.
       
    87     \snippet demos/macmainwindow/macmainwindow.mm 0
       
    88 
       
    89 */
       
    90 
       
    91 QT_BEGIN_NAMESPACE
       
    92 
       
    93 class QMacCocoaViewContainerPrivate : public QWidgetPrivate
       
    94 {
       
    95     Q_DECLARE_PUBLIC(QMacCocoaViewContainer)
       
    96 public:
       
    97     NSView *nsview;
       
    98 #ifndef QT_MAC_USE_COCOA
       
    99     HIViewRef wrapperView;
       
   100 #endif
       
   101     QMacCocoaViewContainerPrivate();
       
   102     ~QMacCocoaViewContainerPrivate();
       
   103 };
       
   104 
       
   105 QMacCocoaViewContainerPrivate::QMacCocoaViewContainerPrivate()
       
   106      : nsview(0)
       
   107 #ifndef QT_MAC_USE_COCOA
       
   108        , wrapperView(0)
       
   109 #endif
       
   110 {
       
   111 }
       
   112 
       
   113 QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate()
       
   114 {
       
   115     [nsview release];
       
   116 #ifndef QT_MAC_USE_COCOA
       
   117     if (wrapperView)
       
   118         CFRelease(wrapperView);
       
   119 #endif
       
   120 }
       
   121 
       
   122 /*!
       
   123     \fn QMacCocoaViewContainer::QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *parent)
       
   124  
       
   125     Create a new QMacCocoaViewContainer using the NSView pointer in \a
       
   126     cocoaViewToWrap with parent, \a parent. QMacCocoaViewContainer will
       
   127     retain \a cocoaViewToWrap.
       
   128 
       
   129     \a cocoaViewToWrap is a void pointer that allows the header to be included
       
   130     with C++ source.
       
   131 */
       
   132 QMacCocoaViewContainer::QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *parent)
       
   133    : QWidget(*new QMacCocoaViewContainerPrivate, parent, 0)
       
   134 {
       
   135     if (cocoaViewToWrap)
       
   136         setCocoaView(cocoaViewToWrap);
       
   137 }
       
   138 
       
   139 /*!
       
   140     Destroy the QMacCocoaViewContainer and release the wrapped view.
       
   141 */
       
   142 QMacCocoaViewContainer::~QMacCocoaViewContainer()
       
   143 {
       
   144 }
       
   145 
       
   146 /*!
       
   147     Returns the NSView that has been set on this container.  The returned view
       
   148     has been autoreleased, so you will need to retain it if you want to make
       
   149     use of it.
       
   150 */
       
   151 void *QMacCocoaViewContainer::cocoaView() const
       
   152 {
       
   153     Q_D(const QMacCocoaViewContainer);
       
   154     return [[d->nsview retain] autorelease];
       
   155 }
       
   156 
       
   157 /*!
       
   158     Sets the NSView to contain to be \a cocoaViewToWrap and retains it. If this
       
   159     container already had a view set, it will release the previously set view.
       
   160 */
       
   161 void QMacCocoaViewContainer::setCocoaView(void *cocoaViewToWrap)
       
   162 {
       
   163     Q_D(QMacCocoaViewContainer);
       
   164     QMacCocoaAutoReleasePool pool;
       
   165     NSView *view = static_cast<NSView *>(cocoaViewToWrap);
       
   166     NSView *oldView = d->nsview;
       
   167     destroy(true, true);
       
   168     [view retain];
       
   169     d->nsview = view;
       
   170 #ifndef QT_MAC_USE_COCOA
       
   171     if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5) {
       
   172         qWarning("QMacCocoaViewContainer::setCocoaView: You cannot use this class with Carbon on versions of Mac OS X less than 10.5.");
       
   173         return;
       
   174     }
       
   175 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
       
   176     if (d->wrapperView)
       
   177         CFRelease(d->wrapperView);
       
   178     HICocoaViewCreate(d->nsview, 0, &d->wrapperView);
       
   179     create(WId(d->wrapperView), false, true);
       
   180 #endif
       
   181 #else
       
   182     create(WId(d->nsview), false, true);
       
   183 #endif
       
   184     [oldView release];
       
   185 }
       
   186 
       
   187 QT_END_NAMESPACE