demos/macmainwindow/macmainwindow.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 demonstration applications 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 #include "macmainwindow.h"
       
    42 #import <Cocoa/Cocoa.h>
       
    43 #include <QtGui>
       
    44 
       
    45 
       
    46 #ifdef Q_WS_MAC
       
    47 
       
    48 #include <Carbon/Carbon.h>
       
    49 
       
    50 #ifdef QT_MAC_USE_COCOA
       
    51 
       
    52 //![0]
       
    53 SearchWidget::SearchWidget(QWidget *parent)
       
    54     : QMacCocoaViewContainer(0, parent)
       
    55 {
       
    56     // Many Cocoa objects create temporary autorelease objects,
       
    57     // so create a pool to catch them.
       
    58     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
    59 
       
    60     // Create the NSSearchField, set it on the QCocoaViewContainer.
       
    61     NSSearchField *search = [[NSSearchField alloc] init];
       
    62     setCocoaView(search);
       
    63 
       
    64     // Use a Qt menu for the search field menu.
       
    65     QMenu *qtMenu = createMenu(this);
       
    66     NSMenu *nsMenu = qtMenu->macMenu(0);
       
    67     [[search cell] setSearchMenuTemplate:nsMenu];
       
    68 
       
    69     // Release our reference, since our super class takes ownership and we
       
    70     // don't need it anymore.
       
    71     [search release];
       
    72 
       
    73     // Clean up our pool as we no longer need it.
       
    74     [pool release];
       
    75 }
       
    76 //![0]
       
    77 
       
    78 SearchWidget::~SearchWidget()
       
    79 {
       
    80 }
       
    81 
       
    82 QSize SearchWidget::sizeHint() const
       
    83 {
       
    84     return QSize(150, 40);
       
    85 }
       
    86 
       
    87 #else
       
    88 
       
    89 // The SearchWidget class wraps a native HISearchField.
       
    90 SearchWidget::SearchWidget(QWidget *parent)
       
    91     :QWidget(parent)
       
    92 {
       
    93 
       
    94     // Create a native search field and pass its window id to QWidget::create.
       
    95     searchFieldText = CFStringCreateWithCString(0, "search", 0);
       
    96     HISearchFieldCreate(NULL/*bounds*/, kHISearchFieldAttributesSearchIcon | kHISearchFieldAttributesCancel,
       
    97                         NULL/*menu ref*/, searchFieldText, &searchField);
       
    98     create(reinterpret_cast<WId>(searchField));
       
    99 
       
   100     // Use a Qt menu for the search field menu.
       
   101     QMenu *searchMenu = createMenu(this);
       
   102     MenuRef menuRef = searchMenu->macMenu(0);
       
   103     HISearchFieldSetSearchMenu(searchField, menuRef);
       
   104     setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
       
   105 }
       
   106 
       
   107 SearchWidget::~SearchWidget()
       
   108 {
       
   109     CFRelease(searchField);
       
   110     CFRelease(searchFieldText);
       
   111 }
       
   112 
       
   113 // Get the size hint from the search field.
       
   114 QSize SearchWidget::sizeHint() const
       
   115 {
       
   116     EventRef event;
       
   117     HIRect optimalBounds;
       
   118     CreateEvent(0, kEventClassControl,
       
   119         kEventControlGetOptimalBounds,
       
   120         GetCurrentEventTime(),
       
   121         kEventAttributeUserEvent, &event);
       
   122 
       
   123     SendEventToEventTargetWithOptions(event,
       
   124         HIObjectGetEventTarget(HIObjectRef(winId())),
       
   125         kEventTargetDontPropagate);
       
   126 
       
   127     GetEventParameter(event,
       
   128         kEventParamControlOptimalBounds, typeHIRect,
       
   129         0, sizeof(HIRect), 0, &optimalBounds);
       
   130 
       
   131     ReleaseEvent(event);
       
   132     return QSize(optimalBounds.size.width + 100, // make it a bit wider.
       
   133                  optimalBounds.size.height);
       
   134 }
       
   135 
       
   136 #endif
       
   137 
       
   138 QMenu *createMenu(QWidget *parent)
       
   139 {
       
   140     QMenu *searchMenu = new QMenu(parent);
       
   141     
       
   142     QAction * indexAction = searchMenu->addAction("Index Search");
       
   143     indexAction->setCheckable(true);
       
   144     indexAction->setChecked(true);
       
   145 
       
   146     QAction * fulltextAction = searchMenu->addAction("Full Text Search");
       
   147     fulltextAction->setCheckable(true);
       
   148 
       
   149     QActionGroup *searchActionGroup = new QActionGroup(parent);
       
   150     searchActionGroup->addAction(indexAction);
       
   151     searchActionGroup->addAction(fulltextAction);
       
   152     searchActionGroup->setExclusive(true);
       
   153     
       
   154     return searchMenu;
       
   155 }
       
   156 
       
   157 SearchWrapper::SearchWrapper(QWidget *parent)
       
   158 :QWidget(parent)
       
   159 {
       
   160     s = new SearchWidget(this);
       
   161     s->move(2,2);
       
   162     setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
       
   163 }
       
   164 
       
   165 QSize SearchWrapper::sizeHint() const
       
   166 {
       
   167     return s->sizeHint() + QSize(6, 2);
       
   168 }
       
   169 
       
   170 Spacer::Spacer(QWidget *parent)
       
   171 :QWidget(parent)
       
   172 {
       
   173     QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
       
   174     setSizePolicy(sizePolicy);
       
   175 }
       
   176 
       
   177 QSize Spacer::sizeHint() const
       
   178 {
       
   179     return QSize(1, 1);
       
   180 }
       
   181 
       
   182 MacSplitterHandle::MacSplitterHandle(Qt::Orientation orientation, QSplitter *parent)
       
   183 : QSplitterHandle(orientation, parent) {   }
       
   184 
       
   185 // Paint the horizontal handle as a gradient, paint
       
   186 // the vertical handle as a line.
       
   187 void MacSplitterHandle::paintEvent(QPaintEvent *)
       
   188 {
       
   189     QPainter painter(this);
       
   190 
       
   191     QColor topColor(145, 145, 145);
       
   192     QColor bottomColor(142, 142, 142);
       
   193     QColor gradientStart(252, 252, 252);
       
   194     QColor gradientStop(223, 223, 223);
       
   195 
       
   196     if (orientation() == Qt::Vertical) {
       
   197         painter.setPen(topColor);
       
   198         painter.drawLine(0, 0, width(), 0);
       
   199         painter.setPen(bottomColor);
       
   200         painter.drawLine(0, height() - 1, width(), height() - 1);
       
   201 
       
   202         QLinearGradient linearGrad(QPointF(0, 0), QPointF(0, height() -3));
       
   203         linearGrad.setColorAt(0, gradientStart);
       
   204         linearGrad.setColorAt(1, gradientStop);
       
   205         painter.fillRect(QRect(QPoint(0,1), size() - QSize(0, 2)), QBrush(linearGrad));
       
   206     } else {
       
   207         painter.setPen(topColor);
       
   208         painter.drawLine(0, 0, 0, height());
       
   209     }
       
   210 }
       
   211 
       
   212 QSize MacSplitterHandle::sizeHint() const
       
   213 {
       
   214     QSize parent = QSplitterHandle::sizeHint();
       
   215     if (orientation() == Qt::Vertical) {
       
   216         return parent + QSize(0, 3);
       
   217     } else {
       
   218         return QSize(1, parent.height());
       
   219     }
       
   220 }
       
   221 
       
   222 QSplitterHandle *MacSplitter::createHandle()
       
   223 {
       
   224     return new MacSplitterHandle(orientation(), this);
       
   225 }
       
   226 
       
   227 MacMainWindow::MacMainWindow()
       
   228 {
       
   229     QSettings settings;
       
   230     restoreGeometry(settings.value("Geometry").toByteArray());
       
   231 
       
   232     setWindowTitle("Mac Main Window");
       
   233 
       
   234     splitter = new MacSplitter();
       
   235 
       
   236     // Set up the left-hand side blue side bar.
       
   237     sidebar = new QTreeView();
       
   238     sidebar->setFrameStyle(QFrame::NoFrame);
       
   239     sidebar->setAttribute(Qt::WA_MacShowFocusRect, false);
       
   240     sidebar->setAutoFillBackground(true);
       
   241     
       
   242     // Set the palette.
       
   243     QPalette palette = sidebar->palette();
       
   244     QColor macSidebarColor(231, 237, 246);
       
   245     QColor macSidebarHighlightColor(168, 183, 205);
       
   246     palette.setColor(QPalette::Base, macSidebarColor);
       
   247     palette.setColor(QPalette::Highlight, macSidebarHighlightColor);
       
   248     sidebar->setPalette(palette);
       
   249 
       
   250     sidebar->setModel(createItemModel());
       
   251     sidebar->header()->hide();
       
   252     sidebar->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
   253     sidebar->setTextElideMode(Qt::ElideMiddle);
       
   254 
       
   255     splitter->addWidget(sidebar);
       
   256 
       
   257     horizontalSplitter = new MacSplitter();
       
   258     horizontalSplitter->setOrientation(Qt::Vertical);
       
   259     splitter->addWidget(horizontalSplitter);
       
   260     
       
   261     splitter->setStretchFactor(0, 0);
       
   262     splitter->setStretchFactor(1, 1);
       
   263 
       
   264     // Set up the top document list view.
       
   265     documents = new QListView();
       
   266     documents->setFrameStyle(QFrame::NoFrame);
       
   267     documents->setAttribute(Qt::WA_MacShowFocusRect, false);
       
   268     documents->setModel(createDocumentModel());
       
   269     documents->setAlternatingRowColors(true);
       
   270     documents->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
       
   271     horizontalSplitter->addWidget(documents);
       
   272     horizontalSplitter->setStretchFactor(0, 0);
       
   273 
       
   274     // Set up the text view.
       
   275     textedit = new QTextEdit();
       
   276     textedit->setFrameStyle(QFrame::NoFrame);
       
   277     textedit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
       
   278     textedit->setText("<br><br><br><br><br><br><center><b>This demo shows how to create a \
       
   279                        Qt main window application that has the same appearance as other \
       
   280                        Mac OS X applications such as Mail or iTunes. This includes \
       
   281                        customizing the item views and QSplitter and wrapping native widgets \
       
   282                        such as the search field.</b></center>");
       
   283 
       
   284     horizontalSplitter->addWidget(textedit);
       
   285 
       
   286     setCentralWidget(splitter);
       
   287 
       
   288     toolBar = addToolBar(tr("Search"));
       
   289     toolBar->addWidget(new Spacer());
       
   290     toolBar->addWidget(new SearchWrapper());
       
   291     
       
   292     setUnifiedTitleAndToolBarOnMac(true);
       
   293 }
       
   294 
       
   295 MacMainWindow::~MacMainWindow()
       
   296 {
       
   297     QSettings settings;
       
   298     settings.setValue("Geometry", saveGeometry());
       
   299 }
       
   300 
       
   301 QAbstractItemModel *MacMainWindow::createItemModel()
       
   302 {
       
   303     QStandardItemModel *model = new QStandardItemModel();
       
   304     QStandardItem *parentItem = model->invisibleRootItem();
       
   305 
       
   306     QStandardItem *documentationItem = new QStandardItem("Documentation"); 
       
   307     parentItem->appendRow(documentationItem);
       
   308 
       
   309     QStandardItem *assistantItem = new QStandardItem("Qt MainWindow Manual"); 
       
   310     documentationItem->appendRow(assistantItem);
       
   311 
       
   312     QStandardItem *designerItem = new QStandardItem("Qt Designer Manual"); 
       
   313     documentationItem->appendRow(designerItem);
       
   314 
       
   315     QStandardItem *qtItem = new QStandardItem("Qt Reference Documentation"); 
       
   316     qtItem->appendRow(new QStandardItem("Classes"));
       
   317     qtItem->appendRow(new QStandardItem("Overviews"));
       
   318     qtItem->appendRow(new QStandardItem("Tutorial & Examples"));
       
   319     documentationItem->appendRow(qtItem);
       
   320 
       
   321     QStandardItem *bookmarksItem = new QStandardItem("Bookmarks"); 
       
   322     parentItem->appendRow(bookmarksItem);
       
   323     bookmarksItem->appendRow(new QStandardItem("QWidget"));
       
   324     bookmarksItem->appendRow(new QStandardItem("QObject"));
       
   325     bookmarksItem->appendRow(new QStandardItem("QWizard"));
       
   326 
       
   327     return model;
       
   328 }
       
   329 
       
   330 void MacMainWindow::resizeEvent(QResizeEvent *)
       
   331 {
       
   332     if (toolBar)
       
   333         toolBar->updateGeometry();
       
   334 }
       
   335 
       
   336 QAbstractItemModel *MacMainWindow::createDocumentModel()
       
   337 {
       
   338     QStandardItemModel *model = new QStandardItemModel();
       
   339     QStandardItem *parentItem = model->invisibleRootItem(); 
       
   340     parentItem->appendRow(new QStandardItem("QWidget Class Reference"));
       
   341     parentItem->appendRow(new QStandardItem("QObject Class Reference"));
       
   342     parentItem->appendRow(new QStandardItem("QListView Class Reference"));
       
   343 
       
   344     return model;
       
   345 }
       
   346 
       
   347 #endif // Q_WS_MAC