1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the demonstration applications of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
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 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at [email protected].
|
---|
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
|
---|