author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Tue, 02 Feb 2010 00:43:10 +0200 | |
changeset 3 | 41300fa6a67c |
parent 0 | 1918ee327afb |
child 4 | 3b1da2848fc7 |
permissions | -rw-r--r-- |
0 | 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 |
/**************************************************************************** |
|
43 |
** |
|
44 |
** Copyright (c) 2007-2008, Apple, Inc. |
|
45 |
** |
|
46 |
** All rights reserved. |
|
47 |
** |
|
48 |
** Redistribution and use in source and binary forms, with or without |
|
49 |
** modification, are permitted provided that the following conditions are met: |
|
50 |
** |
|
51 |
** * Redistributions of source code must retain the above copyright notice, |
|
52 |
** this list of conditions and the following disclaimer. |
|
53 |
** |
|
54 |
** * Redistributions in binary form must reproduce the above copyright notice, |
|
55 |
** this list of conditions and the following disclaimer in the documentation |
|
56 |
** and/or other materials provided with the distribution. |
|
57 |
** |
|
58 |
** * Neither the name of Apple, Inc. nor the names of its contributors |
|
59 |
** may be used to endorse or promote products derived from this software |
|
60 |
** without specific prior written permission. |
|
61 |
** |
|
62 |
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
63 |
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
64 |
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
65 |
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
66 |
** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
67 |
** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
68 |
** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
69 |
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
70 |
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
71 |
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
72 |
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
73 |
** |
|
74 |
****************************************************************************/ |
|
75 |
||
76 |
#include <private/qcore_mac_p.h> |
|
77 |
#include <qaction.h> |
|
78 |
#include <qwidget.h> |
|
79 |
#include <qdesktopwidget.h> |
|
80 |
#include <qevent.h> |
|
81 |
#include <qpixmapcache.h> |
|
82 |
#include <private/qevent_p.h> |
|
83 |
#include <private/qt_cocoa_helpers_mac_p.h> |
|
84 |
#include <private/qt_mac_p.h> |
|
85 |
#include <private/qapplication_p.h> |
|
86 |
#include <private/qcocoawindow_mac_p.h> |
|
87 |
#include <private/qcocoaview_mac_p.h> |
|
88 |
#include <private/qkeymapper_p.h> |
|
89 |
#include <private/qwidget_p.h> |
|
90 |
||
91 |
QT_BEGIN_NAMESPACE |
|
92 |
||
93 |
Q_GLOBAL_STATIC(QMacWindowFader, macwindowFader); |
|
94 |
||
95 |
QMacWindowFader::QMacWindowFader() |
|
96 |
: m_duration(0.250) |
|
97 |
{ |
|
98 |
} |
|
99 |
||
100 |
QMacWindowFader *QMacWindowFader::currentFader() |
|
101 |
{ |
|
102 |
return macwindowFader(); |
|
103 |
} |
|
104 |
||
105 |
void QMacWindowFader::registerWindowToFade(QWidget *window) |
|
106 |
{ |
|
107 |
m_windowsToFade.append(window); |
|
108 |
} |
|
109 |
||
110 |
void QMacWindowFader::performFade() |
|
111 |
{ |
|
112 |
const QWidgetList myWidgetsToFade = m_windowsToFade; |
|
113 |
const int widgetCount = myWidgetsToFade.count(); |
|
114 |
#if QT_MAC_USE_COCOA |
|
115 |
QMacCocoaAutoReleasePool pool; |
|
116 |
[NSAnimationContext beginGrouping]; |
|
117 |
[[NSAnimationContext currentContext] setDuration:NSTimeInterval(m_duration)]; |
|
118 |
#endif |
|
119 |
||
120 |
for (int i = 0; i < widgetCount; ++i) { |
|
121 |
QWidget *widget = m_windowsToFade.at(i); |
|
122 |
OSWindowRef window = qt_mac_window_for(widget); |
|
123 |
#if QT_MAC_USE_COCOA |
|
124 |
[[window animator] setAlphaValue:0.0]; |
|
125 |
QTimer::singleShot(qRound(m_duration * 1000), widget, SLOT(hide())); |
|
126 |
#else |
|
127 |
TransitionWindowOptions options = {0, m_duration, 0, 0}; |
|
128 |
TransitionWindowWithOptions(window, kWindowFadeTransitionEffect, kWindowHideTransitionAction, |
|
129 |
0, 1, &options); |
|
130 |
#endif |
|
131 |
} |
|
132 |
#if QT_MAC_USE_COCOA |
|
133 |
[NSAnimationContext endGrouping]; |
|
134 |
#endif |
|
135 |
m_duration = 0.250; |
|
136 |
m_windowsToFade.clear(); |
|
137 |
} |
|
138 |
||
139 |
extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp; |
|
140 |
extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm |
|
141 |
extern QWidget * mac_mouse_grabber; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
142 |
extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp |
0 | 143 |
|
144 |
void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds) |
|
145 |
{ |
|
146 |
OSWindowRef wnd = static_cast<OSWindowRef>(window); |
|
147 |
if (wnd) { |
|
148 |
QWidget *widget; |
|
149 |
#if QT_MAC_USE_COCOA |
|
150 |
widget = [wnd QT_MANGLE_NAMESPACE(qt_qwidget)]; |
|
151 |
#else |
|
152 |
const UInt32 kWidgetCreatorQt = kEventClassQt; |
|
153 |
enum { |
|
154 |
kWidgetPropertyQWidget = 'QWId' //QWidget * |
|
155 |
}; |
|
156 |
if (GetWindowProperty(static_cast<WindowRef>(window), kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(widget), 0, &widget) != noErr) |
|
157 |
widget = 0; |
|
158 |
#endif |
|
159 |
if (widget) { |
|
160 |
QMacWindowFader::currentFader()->setFadeDuration(durationSeconds); |
|
161 |
QMacWindowFader::currentFader()->registerWindowToFade(widget); |
|
162 |
QMacWindowFader::currentFader()->performFade(); |
|
163 |
} |
|
164 |
} |
|
165 |
} |
|
166 |
||
167 |
bool macWindowIsTextured( void * /*OSWindowRef*/ window ) |
|
168 |
{ |
|
169 |
OSWindowRef wnd = static_cast<OSWindowRef>(window); |
|
170 |
#if QT_MAC_USE_COCOA |
|
171 |
return ( [wnd styleMask] & NSTexturedBackgroundWindowMask ) ? true : false; |
|
172 |
#else |
|
173 |
WindowAttributes currentAttributes; |
|
174 |
GetWindowAttributes(wnd, ¤tAttributes); |
|
175 |
return (currentAttributes & kWindowMetalAttribute) ? true : false; |
|
176 |
#endif |
|
177 |
} |
|
178 |
||
179 |
void macWindowToolbarShow(const QWidget *widget, bool show ) |
|
180 |
{ |
|
181 |
OSWindowRef wnd = qt_mac_window_for(widget); |
|
182 |
#if QT_MAC_USE_COCOA |
|
183 |
if (NSToolbar *toolbar = [wnd toolbar]) { |
|
184 |
QMacCocoaAutoReleasePool pool; |
|
185 |
if (show != [toolbar isVisible]) { |
|
186 |
[toolbar setVisible:show]; |
|
187 |
} else { |
|
188 |
// The toolbar may be in sync, but we are not, update our framestrut. |
|
189 |
qt_widget_private(const_cast<QWidget *>(widget))->updateFrameStrut(); |
|
190 |
} |
|
191 |
} |
|
192 |
#else |
|
193 |
ShowHideWindowToolbar(wnd, show, false); |
|
194 |
#endif |
|
195 |
} |
|
196 |
||
197 |
||
198 |
void macWindowToolbarSet( void * /*OSWindowRef*/ window, void *toolbarRef ) |
|
199 |
{ |
|
200 |
OSWindowRef wnd = static_cast<OSWindowRef>(window); |
|
201 |
#if QT_MAC_USE_COCOA |
|
202 |
[wnd setToolbar:static_cast<NSToolbar *>(toolbarRef)]; |
|
203 |
#else |
|
204 |
SetWindowToolbar(wnd, static_cast<HIToolbarRef>(toolbarRef)); |
|
205 |
#endif |
|
206 |
} |
|
207 |
||
208 |
bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window ) |
|
209 |
{ |
|
210 |
OSWindowRef wnd = static_cast<OSWindowRef>(window); |
|
211 |
#if QT_MAC_USE_COCOA |
|
212 |
if (NSToolbar *toolbar = [wnd toolbar]) |
|
213 |
return [toolbar isVisible]; |
|
214 |
return false; |
|
215 |
#else |
|
216 |
return IsWindowToolbarVisible(wnd); |
|
217 |
#endif |
|
218 |
} |
|
219 |
||
220 |
void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow ) |
|
221 |
{ |
|
222 |
OSWindowRef wnd = static_cast<OSWindowRef>(window); |
|
223 |
#if QT_MAC_USE_COCOA |
|
224 |
[wnd setHasShadow:BOOL(hasShadow)]; |
|
225 |
#else |
|
226 |
if (hasShadow) |
|
227 |
ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute); |
|
228 |
else |
|
229 |
ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0); |
|
230 |
#endif |
|
231 |
} |
|
232 |
||
233 |
void macWindowFlush(void * /*OSWindowRef*/ window) |
|
234 |
{ |
|
235 |
OSWindowRef wnd = static_cast<OSWindowRef>(window); |
|
236 |
#if QT_MAC_USE_COCOA |
|
237 |
[wnd flushWindowIfNeeded]; |
|
238 |
#else |
|
239 |
HIWindowFlush(wnd); |
|
240 |
#endif |
|
241 |
} |
|
242 |
||
243 |
void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm) |
|
244 |
{ |
|
245 |
QMacCocoaAutoReleasePool pool; |
|
246 |
if(QCFType<CGImageRef> image = pm.toMacCGImageRef()) { |
|
247 |
NSImage *newImage = 0; |
|
248 |
NSRect imageRect = NSMakeRect(0.0, 0.0, CGImageGetWidth(image), CGImageGetHeight(image)); |
|
249 |
newImage = [[NSImage alloc] initWithSize:imageRect.size]; |
|
250 |
[newImage lockFocus]; |
|
251 |
{ |
|
252 |
CGContextRef imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; |
|
253 |
CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image); |
|
254 |
} |
|
255 |
[newImage unlockFocus]; |
|
256 |
return newImage; |
|
257 |
} |
|
258 |
return 0; |
|
259 |
} |
|
260 |
||
261 |
void qt_mac_update_mouseTracking(QWidget *widget) |
|
262 |
{ |
|
263 |
#ifdef QT_MAC_USE_COCOA |
|
264 |
[qt_mac_nativeview_for(widget) updateTrackingAreas]; |
|
265 |
#else |
|
266 |
Q_UNUSED(widget); |
|
267 |
#endif |
|
268 |
} |
|
269 |
||
270 |
OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage) |
|
271 |
{ |
|
272 |
// Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev) |
|
273 |
OSStatus err = noErr; |
|
274 |
||
275 |
require_action(inContext != NULL, InvalidContext, err = paramErr); |
|
276 |
require_action(inBounds != NULL, InvalidBounds, err = paramErr); |
|
277 |
require_action(inImage != NULL, InvalidImage, err = paramErr); |
|
278 |
||
279 |
CGContextSaveGState( inContext ); |
|
280 |
CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds)); |
|
281 |
CGContextScaleCTM(inContext, 1, -1); |
|
282 |
||
283 |
CGContextDrawImage(inContext, *inBounds, inImage); |
|
284 |
||
285 |
CGContextRestoreGState(inContext); |
|
286 |
InvalidImage: |
|
287 |
InvalidBounds: |
|
288 |
InvalidContext: |
|
289 |
return err; |
|
290 |
} |
|
291 |
||
292 |
bool qt_mac_checkForNativeSizeGrip(const QWidget *widget) |
|
293 |
{ |
|
294 |
#ifndef QT_MAC_USE_COCOA |
|
295 |
OSViewRef nativeSizeGrip = 0; |
|
296 |
HIViewFindByID(HIViewGetRoot(HIViewGetWindow(HIViewRef(widget->winId()))), kHIViewWindowGrowBoxID, &nativeSizeGrip); |
|
297 |
return (nativeSizeGrip != 0); |
|
298 |
#else |
|
299 |
return [[reinterpret_cast<NSView *>(widget->winId()) window] showsResizeIndicator]; |
|
300 |
#endif |
|
301 |
} |
|
302 |
struct qt_mac_enum_mapper |
|
303 |
{ |
|
304 |
int mac_code; |
|
305 |
int qt_code; |
|
306 |
#if defined(DEBUG_MOUSE_MAPS) |
|
307 |
# define QT_MAC_MAP_ENUM(x) x, #x |
|
308 |
const char *desc; |
|
309 |
#else |
|
310 |
# define QT_MAC_MAP_ENUM(x) x |
|
311 |
#endif |
|
312 |
}; |
|
313 |
||
314 |
//mouse buttons |
|
315 |
static qt_mac_enum_mapper qt_mac_mouse_symbols[] = { |
|
316 |
{ kEventMouseButtonPrimary, QT_MAC_MAP_ENUM(Qt::LeftButton) }, |
|
317 |
{ kEventMouseButtonSecondary, QT_MAC_MAP_ENUM(Qt::RightButton) }, |
|
318 |
{ kEventMouseButtonTertiary, QT_MAC_MAP_ENUM(Qt::MidButton) }, |
|
319 |
{ 4, QT_MAC_MAP_ENUM(Qt::XButton1) }, |
|
320 |
{ 5, QT_MAC_MAP_ENUM(Qt::XButton2) }, |
|
321 |
{ 0, QT_MAC_MAP_ENUM(0) } |
|
322 |
}; |
|
323 |
Qt::MouseButtons qt_mac_get_buttons(int buttons) |
|
324 |
{ |
|
325 |
#ifdef DEBUG_MOUSE_MAPS |
|
326 |
qDebug("Qt: internal: **Mapping buttons: %d (0x%04x)", buttons, buttons); |
|
327 |
#endif |
|
328 |
Qt::MouseButtons ret = Qt::NoButton; |
|
329 |
for(int i = 0; qt_mac_mouse_symbols[i].qt_code; i++) { |
|
330 |
if (buttons & (0x01<<(qt_mac_mouse_symbols[i].mac_code-1))) { |
|
331 |
#ifdef DEBUG_MOUSE_MAPS |
|
332 |
qDebug("Qt: internal: got button: %s", qt_mac_mouse_symbols[i].desc); |
|
333 |
#endif |
|
334 |
ret |= Qt::MouseButtons(qt_mac_mouse_symbols[i].qt_code); |
|
335 |
} |
|
336 |
} |
|
337 |
return ret; |
|
338 |
} |
|
339 |
Qt::MouseButton qt_mac_get_button(EventMouseButton button) |
|
340 |
{ |
|
341 |
#ifdef DEBUG_MOUSE_MAPS |
|
342 |
qDebug("Qt: internal: **Mapping button: %d (0x%04x)", button, button); |
|
343 |
#endif |
|
344 |
Qt::MouseButtons ret = 0; |
|
345 |
for(int i = 0; qt_mac_mouse_symbols[i].qt_code; i++) { |
|
346 |
if (button == qt_mac_mouse_symbols[i].mac_code) { |
|
347 |
#ifdef DEBUG_MOUSE_MAPS |
|
348 |
qDebug("Qt: internal: got button: %s", qt_mac_mouse_symbols[i].desc); |
|
349 |
#endif |
|
350 |
return Qt::MouseButton(qt_mac_mouse_symbols[i].qt_code); |
|
351 |
} |
|
352 |
} |
|
353 |
return Qt::NoButton; |
|
354 |
} |
|
355 |
||
356 |
void macSendToolbarChangeEvent(QWidget *widget) |
|
357 |
{ |
|
358 |
QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey)); |
|
359 |
qt_sendSpontaneousEvent(widget, &ev); |
|
360 |
} |
|
361 |
||
362 |
Q_GLOBAL_STATIC(QMacTabletHash, tablet_hash) |
|
363 |
QMacTabletHash *qt_mac_tablet_hash() |
|
364 |
{ |
|
365 |
return tablet_hash(); |
|
366 |
} |
|
367 |
||
368 |
#ifdef QT_MAC_USE_COCOA |
|
369 |
void qt_dispatchTabletProximityEvent(void * /*NSEvent * */ tabletEvent) |
|
370 |
{ |
|
371 |
NSEvent *proximityEvent = static_cast<NSEvent *>(tabletEvent); |
|
372 |
// simply construct a Carbon proximity record and handle it all in one spot. |
|
373 |
TabletProximityRec carbonProximityRec = { [proximityEvent vendorID], |
|
374 |
[proximityEvent tabletID], |
|
375 |
[proximityEvent pointingDeviceID], |
|
376 |
[proximityEvent deviceID], |
|
377 |
[proximityEvent systemTabletID], |
|
378 |
[proximityEvent vendorPointingDeviceType], |
|
379 |
[proximityEvent pointingDeviceSerialNumber], |
|
380 |
[proximityEvent uniqueID], |
|
381 |
[proximityEvent capabilityMask], |
|
382 |
[proximityEvent pointingDeviceType], |
|
383 |
[proximityEvent isEnteringProximity] }; |
|
384 |
qt_dispatchTabletProximityEvent(carbonProximityRec); |
|
385 |
} |
|
386 |
#endif // QT_MAC_USE_COCOA |
|
387 |
||
388 |
void qt_dispatchTabletProximityEvent(const ::TabletProximityRec &proxRec) |
|
389 |
{ |
|
390 |
QTabletDeviceData proximityDevice; |
|
391 |
proximityDevice.tabletUniqueID = proxRec.uniqueID; |
|
392 |
proximityDevice.capabilityMask = proxRec.capabilityMask; |
|
393 |
||
394 |
switch (proxRec.pointerType) { |
|
395 |
case NSUnknownPointingDevice: |
|
396 |
default: |
|
397 |
proximityDevice.tabletPointerType = QTabletEvent::UnknownPointer; |
|
398 |
break; |
|
399 |
case NSPenPointingDevice: |
|
400 |
proximityDevice.tabletPointerType = QTabletEvent::Pen; |
|
401 |
break; |
|
402 |
case NSCursorPointingDevice: |
|
403 |
proximityDevice.tabletPointerType = QTabletEvent::Cursor; |
|
404 |
break; |
|
405 |
case NSEraserPointingDevice: |
|
406 |
proximityDevice.tabletPointerType = QTabletEvent::Eraser; |
|
407 |
break; |
|
408 |
} |
|
409 |
uint bits = proxRec.vendorPointerType; |
|
410 |
if (bits == 0 && proximityDevice.tabletUniqueID != 0) { |
|
411 |
// Fallback. It seems that the driver doesn't always include all the information. |
|
412 |
// High-End Wacom devices store their "type" in the uper bits of the Unique ID. |
|
413 |
// I'm not sure how to handle it for consumer devices, but I'll test that in a bit. |
|
414 |
bits = proximityDevice.tabletUniqueID >> 32; |
|
415 |
} |
|
416 |
// Defined in the "EN0056-NxtGenImpGuideX" |
|
417 |
// on Wacom's Developer Website (www.wacomeng.com) |
|
418 |
if (((bits & 0x0006) == 0x0002) && ((bits & 0x0F06) != 0x0902)) { |
|
419 |
proximityDevice.tabletDeviceType = QTabletEvent::Stylus; |
|
420 |
} else { |
|
421 |
switch (bits & 0x0F06) { |
|
422 |
case 0x0802: |
|
423 |
proximityDevice.tabletDeviceType = QTabletEvent::Stylus; |
|
424 |
break; |
|
425 |
case 0x0902: |
|
426 |
proximityDevice.tabletDeviceType = QTabletEvent::Airbrush; |
|
427 |
break; |
|
428 |
case 0x0004: |
|
429 |
proximityDevice.tabletDeviceType = QTabletEvent::FourDMouse; |
|
430 |
break; |
|
431 |
case 0x0006: |
|
432 |
proximityDevice.tabletDeviceType = QTabletEvent::Puck; |
|
433 |
break; |
|
434 |
case 0x0804: |
|
435 |
proximityDevice.tabletDeviceType = QTabletEvent::RotationStylus; |
|
436 |
break; |
|
437 |
default: |
|
438 |
proximityDevice.tabletDeviceType = QTabletEvent::NoDevice; |
|
439 |
} |
|
440 |
} |
|
441 |
// The deviceID is "unique" while in the proximity, it's a key that we can use for |
|
442 |
// linking up TabletDeviceData to an event (especially if there are two devices in action). |
|
443 |
bool entering = proxRec.enterProximity; |
|
444 |
if (entering) { |
|
445 |
qt_mac_tablet_hash()->insert(proxRec.deviceID, proximityDevice); |
|
446 |
} else { |
|
447 |
qt_mac_tablet_hash()->remove(proxRec.deviceID); |
|
448 |
} |
|
449 |
||
450 |
QTabletEvent qtabletProximity(entering ? QEvent::TabletEnterProximity |
|
451 |
: QEvent::TabletLeaveProximity, |
|
452 |
QPoint(), QPoint(), QPointF(), proximityDevice.tabletDeviceType, |
|
453 |
proximityDevice.tabletPointerType, 0., 0, 0, 0., 0., 0, 0, |
|
454 |
proximityDevice.tabletUniqueID); |
|
455 |
||
456 |
qt_sendSpontaneousEvent(qApp, &qtabletProximity); |
|
457 |
} |
|
458 |
||
459 |
#ifdef QT_MAC_USE_COCOA |
|
460 |
// Use this method to keep all the information in the TextSegment. As long as it is ordered |
|
461 |
// we are in OK shape, and we can influence that ourselves. |
|
462 |
struct KeyPair |
|
463 |
{ |
|
464 |
QChar cocoaKey; |
|
465 |
Qt::Key qtKey; |
|
466 |
}; |
|
467 |
||
468 |
bool operator==(const KeyPair &entry, QChar qchar) |
|
469 |
{ |
|
470 |
return entry.cocoaKey == qchar; |
|
471 |
} |
|
472 |
||
473 |
bool operator<(const KeyPair &entry, QChar qchar) |
|
474 |
{ |
|
475 |
return entry.cocoaKey < qchar; |
|
476 |
} |
|
477 |
||
478 |
bool operator<(QChar qchar, const KeyPair &entry) |
|
479 |
{ |
|
480 |
return qchar < entry.cocoaKey; |
|
481 |
} |
|
482 |
||
483 |
static Qt::Key cocoaKey2QtKey(QChar keyCode) |
|
484 |
{ |
|
485 |
static const int NumEntries = 57; |
|
486 |
static const KeyPair entries[NumEntries] = { |
|
487 |
{ NSEnterCharacter, Qt::Key_Enter }, |
|
488 |
{ NSTabCharacter, Qt::Key_Tab }, |
|
489 |
{ NSCarriageReturnCharacter, Qt::Key_Return }, |
|
490 |
{ NSBackTabCharacter, Qt::Key_Backtab }, |
|
491 |
{ kEscapeCharCode, Qt::Key_Escape }, |
|
492 |
{ NSDeleteCharacter, Qt::Key_Backspace }, |
|
493 |
{ NSUpArrowFunctionKey, Qt::Key_Up }, |
|
494 |
{ NSDownArrowFunctionKey, Qt::Key_Down }, |
|
495 |
{ NSLeftArrowFunctionKey, Qt::Key_Left }, |
|
496 |
{ NSRightArrowFunctionKey, Qt::Key_Right }, |
|
497 |
{ NSF1FunctionKey, Qt::Key_F1 }, |
|
498 |
{ NSF2FunctionKey, Qt::Key_F2 }, |
|
499 |
{ NSF3FunctionKey, Qt::Key_F3 }, |
|
500 |
{ NSF4FunctionKey, Qt::Key_F4 }, |
|
501 |
{ NSF5FunctionKey, Qt::Key_F5 }, |
|
502 |
{ NSF6FunctionKey, Qt::Key_F6 }, |
|
503 |
{ NSF7FunctionKey, Qt::Key_F7 }, |
|
504 |
{ NSF8FunctionKey, Qt::Key_F8 }, |
|
505 |
{ NSF9FunctionKey, Qt::Key_F8 }, |
|
506 |
{ NSF10FunctionKey, Qt::Key_F10 }, |
|
507 |
{ NSF11FunctionKey, Qt::Key_F11 }, |
|
508 |
{ NSF12FunctionKey, Qt::Key_F12 }, |
|
509 |
{ NSF13FunctionKey, Qt::Key_F13 }, |
|
510 |
{ NSF14FunctionKey, Qt::Key_F14 }, |
|
511 |
{ NSF15FunctionKey, Qt::Key_F15 }, |
|
512 |
{ NSF16FunctionKey, Qt::Key_F16 }, |
|
513 |
{ NSF17FunctionKey, Qt::Key_F17 }, |
|
514 |
{ NSF18FunctionKey, Qt::Key_F18 }, |
|
515 |
{ NSF19FunctionKey, Qt::Key_F19 }, |
|
516 |
{ NSF20FunctionKey, Qt::Key_F20 }, |
|
517 |
{ NSF21FunctionKey, Qt::Key_F21 }, |
|
518 |
{ NSF22FunctionKey, Qt::Key_F22 }, |
|
519 |
{ NSF23FunctionKey, Qt::Key_F23 }, |
|
520 |
{ NSF24FunctionKey, Qt::Key_F24 }, |
|
521 |
{ NSF25FunctionKey, Qt::Key_F25 }, |
|
522 |
{ NSF26FunctionKey, Qt::Key_F26 }, |
|
523 |
{ NSF27FunctionKey, Qt::Key_F27 }, |
|
524 |
{ NSF28FunctionKey, Qt::Key_F28 }, |
|
525 |
{ NSF29FunctionKey, Qt::Key_F29 }, |
|
526 |
{ NSF30FunctionKey, Qt::Key_F30 }, |
|
527 |
{ NSF31FunctionKey, Qt::Key_F31 }, |
|
528 |
{ NSF32FunctionKey, Qt::Key_F32 }, |
|
529 |
{ NSF33FunctionKey, Qt::Key_F33 }, |
|
530 |
{ NSF34FunctionKey, Qt::Key_F34 }, |
|
531 |
{ NSF35FunctionKey, Qt::Key_F35 }, |
|
532 |
{ NSInsertFunctionKey, Qt::Key_Insert }, |
|
533 |
{ NSDeleteFunctionKey, Qt::Key_Delete }, |
|
534 |
{ NSHomeFunctionKey, Qt::Key_Home }, |
|
535 |
{ NSEndFunctionKey, Qt::Key_End }, |
|
536 |
{ NSPageUpFunctionKey, Qt::Key_PageUp }, |
|
537 |
{ NSPageDownFunctionKey, Qt::Key_PageDown }, |
|
538 |
{ NSPrintScreenFunctionKey, Qt::Key_Print }, |
|
539 |
{ NSScrollLockFunctionKey, Qt::Key_ScrollLock }, |
|
540 |
{ NSPauseFunctionKey, Qt::Key_Pause }, |
|
541 |
{ NSSysReqFunctionKey, Qt::Key_SysReq }, |
|
542 |
{ NSMenuFunctionKey, Qt::Key_Menu }, |
|
543 |
{ NSHelpFunctionKey, Qt::Key_Help }, |
|
544 |
}; |
|
545 |
static const KeyPair * const end = entries + NumEntries; |
|
546 |
const KeyPair *i = qBinaryFind(entries, end, keyCode); |
|
547 |
if (i == end) |
|
548 |
return Qt::Key(keyCode.unicode()); |
|
549 |
return i->qtKey; |
|
550 |
} |
|
551 |
||
552 |
Qt::KeyboardModifiers qt_cocoaModifiers2QtModifiers(ulong modifierFlags) |
|
553 |
{ |
|
554 |
Qt::KeyboardModifiers qtMods =Qt::NoModifier; |
|
555 |
if (modifierFlags & NSShiftKeyMask) |
|
556 |
qtMods |= Qt::ShiftModifier; |
|
557 |
if (modifierFlags & NSControlKeyMask) |
|
558 |
qtMods |= Qt::MetaModifier; |
|
559 |
if (modifierFlags & NSAlternateKeyMask) |
|
560 |
qtMods |= Qt::AltModifier; |
|
561 |
if (modifierFlags & NSCommandKeyMask) |
|
562 |
qtMods |= Qt::ControlModifier; |
|
563 |
if (modifierFlags & NSNumericPadKeyMask) |
|
564 |
qtMods |= Qt::KeypadModifier; |
|
565 |
return qtMods; |
|
566 |
} |
|
567 |
||
568 |
Qt::KeyboardModifiers qt_cocoaDragOperation2QtModifiers(uint dragOperations) |
|
569 |
{ |
|
570 |
Qt::KeyboardModifiers qtMods =Qt::NoModifier; |
|
571 |
if (dragOperations & NSDragOperationLink) |
|
572 |
qtMods |= Qt::MetaModifier; |
|
573 |
if (dragOperations & NSDragOperationGeneric) |
|
574 |
qtMods |= Qt::ControlModifier; |
|
575 |
if (dragOperations & NSDragOperationCopy) |
|
576 |
qtMods |= Qt::AltModifier; |
|
577 |
return qtMods; |
|
578 |
} |
|
579 |
||
580 |
static inline QEvent::Type cocoaEvent2QtEvent(NSUInteger eventType) |
|
581 |
{ |
|
582 |
// Handle the trivial cases that can be determined from the type. |
|
583 |
switch (eventType) { |
|
584 |
case NSKeyDown: |
|
585 |
return QEvent::KeyPress; |
|
586 |
case NSKeyUp: |
|
587 |
return QEvent::KeyRelease; |
|
588 |
case NSLeftMouseDown: |
|
589 |
case NSRightMouseDown: |
|
590 |
case NSOtherMouseDown: |
|
591 |
return QEvent::MouseButtonPress; |
|
592 |
case NSLeftMouseUp: |
|
593 |
case NSRightMouseUp: |
|
594 |
case NSOtherMouseUp: |
|
595 |
return QEvent::MouseButtonRelease; |
|
596 |
case NSMouseMoved: |
|
597 |
case NSLeftMouseDragged: |
|
598 |
case NSRightMouseDragged: |
|
599 |
case NSOtherMouseDragged: |
|
600 |
return QEvent::MouseMove; |
|
601 |
case NSScrollWheel: |
|
602 |
return QEvent::Wheel; |
|
603 |
} |
|
604 |
return QEvent::None; |
|
605 |
} |
|
606 |
||
607 |
static bool mustUseCocoaKeyEvent() |
|
608 |
{ |
|
609 |
QCFType<TISInputSourceRef> source = TISCopyCurrentKeyboardInputSource(); |
|
610 |
return TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData) == 0; |
|
611 |
} |
|
612 |
||
613 |
bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent) |
|
614 |
{ |
|
615 |
NSEvent *event = static_cast<NSEvent *>(keyEvent); |
|
616 |
NSString *keyChars = [event charactersIgnoringModifiers]; |
|
617 |
int keyLength = [keyChars length]; |
|
618 |
if (keyLength == 0) |
|
619 |
return false; // Dead Key, nothing to do! |
|
620 |
bool ignoreText = false; |
|
621 |
Qt::Key qtKey = Qt::Key_unknown; |
|
622 |
if (keyLength == 1) { |
|
623 |
QChar ch([keyChars characterAtIndex:0]); |
|
624 |
if (ch.isLower()) |
|
625 |
ch = ch.toUpper(); |
|
626 |
qtKey = cocoaKey2QtKey(ch); |
|
627 |
// Do not set the text for Function-Key Unicodes characters (0xF700–0xF8FF). |
|
628 |
ignoreText = (ch.unicode() >= 0xF700 && ch.unicode() <= 0xF8FF); |
|
629 |
} |
|
630 |
Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([event modifierFlags]); |
|
631 |
QString text; |
|
632 |
||
633 |
// To quote from the Carbon port: This is actually wrong--but it is the best that |
|
634 |
// can be done for now because of the Control/Meta mapping issues |
|
635 |
// (we always get text on the Mac) |
|
636 |
if (!ignoreText && !(keyMods & (Qt::ControlModifier | Qt::MetaModifier))) |
|
637 |
text = QCFString::toQString(reinterpret_cast<CFStringRef>(keyChars)); |
|
638 |
||
639 |
UInt32 macScanCode = 1; |
|
640 |
QKeyEventEx ke(cocoaEvent2QtEvent([event type]), qtKey, keyMods, text, [event isARepeat], qMax(1, keyLength), |
|
641 |
macScanCode, [event keyCode], [event modifierFlags]); |
|
642 |
qt_sendSpontaneousEvent(widgetToGetEvent, &ke); |
|
643 |
return ke.isAccepted(); |
|
644 |
} |
|
645 |
#endif |
|
646 |
||
647 |
// Helper to share code between QCocoaWindow and QCocoaView |
|
648 |
bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent) |
|
649 |
{ |
|
650 |
#ifndef QT_MAC_USE_COCOA |
|
651 |
Q_UNUSED(keyEvent); |
|
652 |
Q_UNUSED(widgetToGetEvent); |
|
653 |
return false; |
|
654 |
#else |
|
655 |
NSEvent *event = static_cast<NSEvent *>(keyEvent); |
|
656 |
EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef])); |
|
657 |
Q_ASSERT(key_event); |
|
658 |
if ([event type] == NSKeyDown) { |
|
659 |
qt_keymapper_private()->updateKeyMap(0, key_event, 0); |
|
660 |
} |
|
661 |
if (widgetToGetEvent == 0) |
|
662 |
return false; |
|
663 |
||
664 |
if (qt_mac_sendMacEventToWidget(widgetToGetEvent, key_event)) |
|
665 |
return true; |
|
666 |
||
667 |
if (mustUseCocoaKeyEvent()) |
|
668 |
return qt_dispatchKeyEventWithCocoa(keyEvent, widgetToGetEvent); |
|
669 |
bool isAccepted; |
|
670 |
qt_keymapper_private()->translateKeyEvent(widgetToGetEvent, 0, key_event, &isAccepted, true); |
|
671 |
return isAccepted; |
|
672 |
#endif |
|
673 |
} |
|
674 |
||
675 |
void qt_dispatchModifiersChanged(void * /*NSEvent * */flagsChangedEvent, QWidget *widgetToGetEvent) |
|
676 |
{ |
|
677 |
#ifndef QT_MAC_USE_COCOA |
|
678 |
Q_UNUSED(flagsChangedEvent); |
|
679 |
Q_UNUSED(widgetToGetEvent); |
|
680 |
#else |
|
681 |
UInt32 modifiers = 0; |
|
682 |
// Sync modifiers with Qt |
|
683 |
NSEvent *event = static_cast<NSEvent *>(flagsChangedEvent); |
|
684 |
EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef])); |
|
685 |
Q_ASSERT(key_event); |
|
686 |
GetEventParameter(key_event, kEventParamKeyModifiers, typeUInt32, 0, |
|
687 |
sizeof(modifiers), 0, &modifiers); |
|
688 |
extern void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object); |
|
689 |
qt_mac_send_modifiers_changed(modifiers, widgetToGetEvent); |
|
690 |
#endif |
|
691 |
} |
|
692 |
||
693 |
||
694 |
QPointF flipPoint(const NSPoint &p) |
|
695 |
{ |
|
696 |
return QPointF(p.x, flipYCoordinate(p.y)); |
|
697 |
} |
|
698 |
||
699 |
NSPoint flipPoint(const QPoint &p) |
|
700 |
{ |
|
701 |
return NSMakePoint(p.x(), flipYCoordinate(p.y())); |
|
702 |
} |
|
703 |
||
704 |
NSPoint flipPoint(const QPointF &p) |
|
705 |
{ |
|
706 |
return NSMakePoint(p.x(), flipYCoordinate(p.y())); |
|
707 |
} |
|
708 |
||
709 |
void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /* NSEvent* */mouseEvent, |
|
710 |
QWidget *widgetToGetEvent, bool &leftButtonIsRightButton) |
|
711 |
{ |
|
712 |
#ifndef QT_MAC_USE_COCOA |
|
713 |
Q_UNUSED(eventWindow); |
|
714 |
Q_UNUSED(mouseEvent); |
|
715 |
Q_UNUSED(widgetToGetEvent); |
|
716 |
Q_UNUSED(leftButtonIsRightButton); |
|
717 |
#else |
|
718 |
if (widgetToGetEvent == 0) |
|
719 |
return; |
|
720 |
NSWindow *window = static_cast<NSWindow *>(eventWindow); |
|
721 |
NSEvent *event = static_cast<NSEvent *>(mouseEvent); |
|
722 |
NSEventType evtType = [event type]; |
|
723 |
||
724 |
QPoint qlocalPoint; |
|
725 |
QPoint qglobalPoint; |
|
726 |
bool processThisEvent = false; |
|
727 |
bool fakeNCEvents = false; |
|
728 |
bool fakeMouseEvents = false; |
|
729 |
||
730 |
// Check if this is a mouse event. |
|
731 |
if (evtType == NSLeftMouseDown || evtType == NSLeftMouseUp |
|
732 |
|| evtType == NSRightMouseDown || evtType == NSRightMouseUp |
|
733 |
|| evtType == NSOtherMouseDown || evtType == NSOtherMouseUp |
|
734 |
|| evtType == NSMouseMoved || evtType == NSLeftMouseDragged |
|
735 |
|| evtType == NSRightMouseDragged || evtType == NSOtherMouseDragged) { |
|
736 |
// Check if we want to pass this message to another window |
|
737 |
if (mac_mouse_grabber && mac_mouse_grabber != widgetToGetEvent) { |
|
738 |
NSWindow *grabWindow = static_cast<NSWindow *>(qt_mac_window_for(mac_mouse_grabber)); |
|
739 |
if (window != grabWindow) { |
|
740 |
window = grabWindow; |
|
741 |
widgetToGetEvent = mac_mouse_grabber; |
|
742 |
fakeNCEvents = true; |
|
743 |
} |
|
744 |
} |
|
745 |
// Dont generate normal NC mouse events for Left Button dragged |
|
746 |
if(evtType != NSLeftMouseDragged || fakeNCEvents) { |
|
747 |
NSPoint windowPoint = [event locationInWindow]; |
|
748 |
NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint]; |
|
749 |
NSRect frameRect = [window frame]; |
|
750 |
if (fakeNCEvents || NSMouseInRect(globalPoint, frameRect, NO)) { |
|
751 |
NSRect contentRect = [window contentRectForFrameRect:frameRect]; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
752 |
qglobalPoint = QPoint(flipPoint(globalPoint).toPoint()); |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
753 |
QWidget *w = widgetToGetEvent->childAt(widgetToGetEvent->mapFromGlobal(qglobalPoint)); |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
754 |
// check that the mouse pointer is on the non-client area and |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
755 |
// there are not widgets in it. |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
756 |
if (fakeNCEvents || (!NSMouseInRect(globalPoint, contentRect, NO) && !w)) { |
0 | 757 |
qglobalPoint = QPoint(flipPoint(globalPoint).toPoint()); |
758 |
qlocalPoint = widgetToGetEvent->mapFromGlobal(qglobalPoint); |
|
759 |
processThisEvent = true; |
|
760 |
} |
|
761 |
} |
|
762 |
} |
|
763 |
} |
|
764 |
// This is not an NC area mouse message. |
|
765 |
if (!processThisEvent) |
|
766 |
return; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
767 |
|
0 | 768 |
// If the window is frame less, generate fake mouse events instead. (floating QToolBar) |
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
769 |
// or if someone already got an explicit or implicit grab |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
770 |
if (mac_mouse_grabber || qt_button_down || |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
771 |
(fakeNCEvents && (widgetToGetEvent->window()->windowFlags() & Qt::FramelessWindowHint))) |
0 | 772 |
fakeMouseEvents = true; |
773 |
||
774 |
Qt::MouseButton button; |
|
775 |
QEvent::Type eventType; |
|
776 |
// Convert to Qt::Event type |
|
777 |
switch (evtType) { |
|
778 |
case NSLeftMouseDown: |
|
779 |
button = Qt::LeftButton; |
|
780 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress |
|
781 |
: QEvent::MouseButtonPress; |
|
782 |
break; |
|
783 |
case NSLeftMouseUp: |
|
784 |
button = Qt::LeftButton; |
|
785 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease |
|
786 |
: QEvent::MouseButtonRelease; |
|
787 |
break; |
|
788 |
case NSRightMouseDown: |
|
789 |
button = Qt::RightButton; |
|
790 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress |
|
791 |
: QEvent::MouseButtonPress; |
|
792 |
break; |
|
793 |
case NSRightMouseUp: |
|
794 |
button = Qt::RightButton; |
|
795 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease |
|
796 |
: QEvent::MouseButtonRelease; |
|
797 |
break; |
|
798 |
case NSOtherMouseDown: |
|
799 |
button = cocoaButton2QtButton([event buttonNumber]); |
|
800 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress |
|
801 |
: QEvent::MouseButtonPress; |
|
802 |
break; |
|
803 |
case NSOtherMouseUp: |
|
804 |
button = cocoaButton2QtButton([event buttonNumber]); |
|
805 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease |
|
806 |
: QEvent::MouseButtonRelease; |
|
807 |
break; |
|
808 |
case NSMouseMoved: |
|
809 |
button = Qt::NoButton; |
|
810 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove |
|
811 |
: QEvent::MouseMove; |
|
812 |
break; |
|
813 |
case NSLeftMouseDragged: |
|
814 |
button = Qt::LeftButton; |
|
815 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove |
|
816 |
: QEvent::MouseMove; |
|
817 |
break; |
|
818 |
case NSRightMouseDragged: |
|
819 |
button = Qt::RightButton; |
|
820 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove |
|
821 |
: QEvent::MouseMove; |
|
822 |
break; |
|
823 |
case NSOtherMouseDragged: |
|
824 |
button = cocoaButton2QtButton([event buttonNumber]); |
|
825 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove |
|
826 |
: QEvent::MouseMove; |
|
827 |
break; |
|
828 |
default: |
|
829 |
qWarning("not handled! Non client area mouse message"); |
|
830 |
return; |
|
831 |
} |
|
832 |
||
833 |
Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([event modifierFlags]); |
|
834 |
if (eventType == QEvent::NonClientAreaMouseButtonPress || eventType == QEvent::MouseButtonPress) { |
|
835 |
NSInteger clickCount = [event clickCount]; |
|
836 |
if (clickCount % 2 == 0) |
|
837 |
eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonDblClick |
|
838 |
: QEvent::MouseButtonDblClick; |
|
839 |
if (button == Qt::LeftButton && (keyMods & Qt::MetaModifier)) { |
|
840 |
button = Qt::RightButton; |
|
841 |
leftButtonIsRightButton = true; |
|
842 |
} |
|
843 |
} else if (eventType == QEvent::NonClientAreaMouseButtonRelease || eventType == QEvent::MouseButtonRelease) { |
|
844 |
if (button == Qt::LeftButton && leftButtonIsRightButton) { |
|
845 |
button = Qt::RightButton; |
|
846 |
leftButtonIsRightButton = false; |
|
847 |
} |
|
848 |
} |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
849 |
|
0 | 850 |
QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, button, keyMods); |
851 |
qt_sendSpontaneousEvent(widgetToGetEvent, &qme); |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
852 |
|
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
853 |
// We don't need to set the implicit grab widget here because we won't |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
854 |
// reach this point if then event type is Press over a Qt widget. |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
855 |
// However we might need to unset it if the event is Release. |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
856 |
if (eventType == QEvent::MouseButtonRelease) |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
857 |
qt_button_down = 0; |
0 | 858 |
#endif |
859 |
} |
|
860 |
||
861 |
bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */event, QEvent::Type eventType, Qt::MouseButton button) |
|
862 |
{ |
|
863 |
#ifndef QT_MAC_USE_COCOA |
|
864 |
Q_UNUSED(view); |
|
865 |
Q_UNUSED(event); |
|
866 |
Q_UNUSED(eventType); |
|
867 |
Q_UNUSED(button); |
|
868 |
return false; |
|
869 |
#else |
|
870 |
QT_MANGLE_NAMESPACE(QCocoaView) *theView = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view); |
|
871 |
NSEvent *theEvent = static_cast<NSEvent *>(event); |
|
872 |
||
873 |
// Give the Input Manager a chance to process the mouse events. |
|
874 |
NSInputManager *currentIManager = [NSInputManager currentInputManager]; |
|
875 |
if (currentIManager && [currentIManager wantsToHandleMouseEvents]) { |
|
876 |
[currentIManager handleMouseEvent:theEvent]; |
|
877 |
} |
|
878 |
||
879 |
// Handle tablet events (if any) first. |
|
880 |
if (qt_mac_handleTabletEvent(theView, theEvent)) { |
|
881 |
// Tablet event was handled. In Qt we aren't supposed to send the mouse event. |
|
882 |
return true; |
|
883 |
} |
|
884 |
||
885 |
NSPoint windowPoint = [theEvent locationInWindow]; |
|
886 |
NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint]; |
|
887 |
||
888 |
// Find the widget that *should* get the event (e.g., maybe it was a pop-up, |
|
889 |
// they always get the mouse event). |
|
890 |
QWidget *qwidget = [theView qt_qwidget]; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
891 |
QWidget *widgetToGetMouse = 0; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
892 |
NSView *tmpView = 0; |
0 | 893 |
QWidget *popup = qAppInstance()->activePopupWidget(); |
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
894 |
QPoint qglobalPoint(flipPoint(globalPoint).toPoint()); |
0 | 895 |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
896 |
if (popup) { |
0 | 897 |
widgetToGetMouse = popup; |
898 |
tmpView = qt_mac_nativeview_for(popup); |
|
899 |
windowPoint = [[tmpView window] convertScreenToBase:globalPoint]; |
|
900 |
||
901 |
QPoint qWindowPoint(windowPoint.x, windowPoint.y); |
|
902 |
if (widgetToGetMouse->rect().contains(qWindowPoint)) { |
|
903 |
// Keeping the mouse pressed on a combobox button will make |
|
904 |
// the popup pop in front of the mouse. But all mouse events |
|
905 |
// will be sendt to the button. Since we want mouse events |
|
906 |
// to be sendt to widgets inside the popup, we search for the |
|
907 |
// widget in front of the mouse: |
|
908 |
tmpView = [tmpView hitTest:windowPoint]; |
|
909 |
if (!tmpView) |
|
910 |
return false; |
|
911 |
widgetToGetMouse = |
|
912 |
[static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(tmpView) qt_qwidget]; |
|
913 |
} |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
914 |
} else { |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
915 |
extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
916 |
QPoint pos; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
917 |
widgetToGetMouse = QApplicationPrivate::pickMouseReceiver(qwidget, qglobalPoint, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
918 |
pos, eventType, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
919 |
button, qt_button_down, 0); |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
920 |
if (widgetToGetMouse) |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
921 |
tmpView = qt_mac_nativeview_for(widgetToGetMouse); |
0 | 922 |
} |
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
923 |
if (!widgetToGetMouse) |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
924 |
return false; |
0 | 925 |
|
926 |
NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil]; |
|
927 |
QPoint qlocalPoint(localPoint.x, localPoint.y); |
|
928 |
||
929 |
EventRef carbonEvent = static_cast<EventRef>(const_cast<void *>([theEvent eventRef])); |
|
930 |
if (qt_mac_sendMacEventToWidget(widgetToGetMouse, carbonEvent)) |
|
931 |
return true; |
|
932 |
||
933 |
// Yay! All the special cases are handled, it really is just a normal mouse event. |
|
934 |
Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]); |
|
935 |
NSInteger clickCount = [theEvent clickCount]; |
|
936 |
Qt::MouseButtons buttons = 0; |
|
937 |
{ |
|
938 |
UInt32 mac_buttons; |
|
939 |
if (GetEventParameter(carbonEvent, kEventParamMouseChord, typeUInt32, 0, |
|
940 |
sizeof(mac_buttons), 0, &mac_buttons) == noErr) |
|
941 |
buttons = qt_mac_get_buttons(mac_buttons); |
|
942 |
} |
|
943 |
switch (eventType) { |
|
944 |
default: |
|
945 |
qWarning("not handled! %d", eventType); |
|
946 |
break; |
|
947 |
case QEvent::MouseMove: |
|
948 |
break; |
|
949 |
case QEvent::MouseButtonPress: |
|
950 |
[QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = theView; |
|
951 |
[QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = theEvent; |
|
952 |
#ifndef QT_NAMESPACE |
|
953 |
Q_ASSERT(clickCount > 0); |
|
954 |
#endif |
|
955 |
if (clickCount % 2 == 0) |
|
956 |
eventType = QEvent::MouseButtonDblClick; |
|
957 |
if (button == Qt::LeftButton && (keyMods & Qt::MetaModifier)) { |
|
958 |
button = Qt::RightButton; |
|
959 |
[theView qt_setLeftButtonIsRightButton: true]; |
|
960 |
} |
|
961 |
break; |
|
962 |
case QEvent::MouseButtonRelease: |
|
963 |
if (button == Qt::LeftButton && [theView qt_leftButtonIsRightButton]) { |
|
964 |
button = Qt::RightButton; |
|
965 |
[theView qt_setLeftButtonIsRightButton: false]; |
|
966 |
} |
|
967 |
break; |
|
968 |
} |
|
969 |
[QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->localPoint = localPoint; |
|
970 |
QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods); |
|
971 |
qt_sendSpontaneousEvent(widgetToGetMouse, &qme); |
|
972 |
if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) { |
|
973 |
QContextMenuEvent qcme(QContextMenuEvent::Mouse, qlocalPoint, qglobalPoint, keyMods); |
|
974 |
qt_sendSpontaneousEvent(widgetToGetMouse, &qcme); |
|
975 |
} |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
976 |
return true; |
0 | 977 |
#endif |
978 |
} |
|
979 |
||
980 |
bool qt_mac_handleTabletEvent(void * /*QCocoaView * */view, void * /*NSEvent * */tabletEvent) |
|
981 |
{ |
|
982 |
#ifndef QT_MAC_USE_COCOA |
|
983 |
Q_UNUSED(view); |
|
984 |
Q_UNUSED(tabletEvent); |
|
985 |
return false; |
|
986 |
#else |
|
987 |
QT_MANGLE_NAMESPACE(QCocoaView) *theView = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view); |
|
988 |
NSView *theNSView = static_cast<NSView *>(view); |
|
989 |
NSEvent *theTabletEvent = static_cast<NSEvent *>(tabletEvent); |
|
990 |
||
991 |
NSEventType eventType = [theTabletEvent type]; |
|
992 |
if (eventType != NSTabletPoint && [theTabletEvent subtype] != NSTabletPointEventSubtype) |
|
993 |
return false; // Not a tablet event. |
|
994 |
||
995 |
NSPoint windowPoint = [theTabletEvent locationInWindow]; |
|
996 |
NSPoint globalPoint = [[theTabletEvent window] convertBaseToScreen:windowPoint]; |
|
997 |
||
998 |
QWidget *qwidget = [theView qt_qwidget]; |
|
999 |
QWidget *widgetToGetMouse = qwidget; |
|
1000 |
QWidget *popup = qAppInstance()->activePopupWidget(); |
|
1001 |
if (popup && popup != qwidget->window()) |
|
1002 |
widgetToGetMouse = popup; |
|
1003 |
||
1004 |
if (qt_mac_sendMacEventToWidget(widgetToGetMouse, |
|
1005 |
static_cast<EventRef>(const_cast<void *>([theTabletEvent eventRef])))) |
|
1006 |
return true; |
|
1007 |
if (widgetToGetMouse != qwidget) { |
|
1008 |
theNSView = qt_mac_nativeview_for(widgetToGetMouse); |
|
1009 |
windowPoint = [[theNSView window] convertScreenToBase:globalPoint]; |
|
1010 |
} |
|
1011 |
NSPoint localPoint = [theNSView convertPoint:windowPoint fromView:nil]; |
|
1012 |
// Tablet events do not handle WA_TransparentForMouseEvents ATM |
|
1013 |
// In theory, people who set the WA_TransparentForMouseEvents attribute won't handle |
|
1014 |
// tablet events either in which case they will fall into the mouse event case and get |
|
1015 |
// them passed on. This will NOT handle the raw events, but that might not be a big problem. |
|
1016 |
||
1017 |
const QMacTabletHash *tabletHash = qt_mac_tablet_hash(); |
|
1018 |
if (!tabletHash->contains([theTabletEvent deviceID])) { |
|
1019 |
qWarning("QCocoaView handleTabletEvent: This tablet device is unknown" |
|
1020 |
" (received no proximity event for it). Discarding event."); |
|
1021 |
return false; |
|
1022 |
} |
|
1023 |
const QTabletDeviceData &deviceData = tabletHash->value([theTabletEvent deviceID]); |
|
1024 |
||
1025 |
||
1026 |
QEvent::Type qType; |
|
1027 |
switch (eventType) { |
|
1028 |
case NSLeftMouseDown: |
|
1029 |
case NSRightMouseDown: |
|
1030 |
qType = QEvent::TabletPress; |
|
1031 |
break; |
|
1032 |
case NSLeftMouseUp: |
|
1033 |
case NSRightMouseUp: |
|
1034 |
qType = QEvent::TabletRelease; |
|
1035 |
break; |
|
1036 |
case NSMouseMoved: |
|
1037 |
case NSTabletPoint: |
|
1038 |
case NSLeftMouseDragged: |
|
1039 |
case NSRightMouseDragged: |
|
1040 |
default: |
|
1041 |
qType = QEvent::TabletMove; |
|
1042 |
break; |
|
1043 |
} |
|
1044 |
||
1045 |
qreal pressure; |
|
1046 |
if (eventType != NSMouseMoved) { |
|
1047 |
pressure = [theTabletEvent pressure]; |
|
1048 |
} else { |
|
1049 |
pressure = 0.0; |
|
1050 |
} |
|
1051 |
||
1052 |
NSPoint tilt = [theTabletEvent tilt]; |
|
1053 |
int xTilt = qRound(tilt.x * 60.0); |
|
1054 |
int yTilt = qRound(tilt.y * -60.0); |
|
1055 |
qreal tangentialPressure = 0; |
|
1056 |
qreal rotation = 0; |
|
1057 |
int z = 0; |
|
1058 |
if (deviceData.capabilityMask & 0x0200) |
|
1059 |
z = [theTabletEvent absoluteZ]; |
|
1060 |
||
1061 |
if (deviceData.capabilityMask & 0x0800) |
|
1062 |
tangentialPressure = [theTabletEvent tangentialPressure]; |
|
1063 |
||
1064 |
rotation = [theTabletEvent rotation]; |
|
1065 |
QPointF hiRes = flipPoint(globalPoint); |
|
1066 |
QTabletEvent qtabletEvent(qType, QPoint(localPoint.x, localPoint.y), |
|
1067 |
hiRes.toPoint(), hiRes, |
|
1068 |
deviceData.tabletDeviceType, deviceData.tabletPointerType, |
|
1069 |
pressure, xTilt, yTilt, tangentialPressure, rotation, z, |
|
1070 |
qt_cocoaModifiers2QtModifiers([theTabletEvent modifierFlags]), |
|
1071 |
deviceData.tabletUniqueID); |
|
1072 |
||
1073 |
qt_sendSpontaneousEvent(widgetToGetMouse, &qtabletEvent); |
|
1074 |
return qtabletEvent.isAccepted(); |
|
1075 |
#endif |
|
1076 |
} |
|
1077 |
||
1078 |
void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics) |
|
1079 |
{ |
|
1080 |
OSWindowRef theWindow = static_cast<OSWindowRef>(window); |
|
1081 |
#if !defined(QT_MAC_USE_COCOA) |
|
1082 |
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 |
|
1083 |
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { |
|
1084 |
::HIWindowSetContentBorderThickness(theWindow, &metrics); |
|
1085 |
} |
|
1086 |
# else |
|
1087 |
Q_UNUSED(window); |
|
1088 |
Q_UNUSED(metrics); |
|
1089 |
# endif |
|
1090 |
#else |
|
1091 |
if ([theWindow styleMask] & NSTexturedBackgroundWindowMask) |
|
1092 |
[theWindow setContentBorderThickness:metrics.top forEdge:NSMaxYEdge]; |
|
1093 |
[theWindow setContentBorderThickness:metrics.bottom forEdge:NSMinYEdge]; |
|
1094 |
#endif |
|
1095 |
} |
|
1096 |
||
1097 |
void qt_mac_showBaseLineSeparator(void * /*OSWindowRef */window, bool show) |
|
1098 |
{ |
|
1099 |
#if QT_MAC_USE_COCOA |
|
1100 |
QMacCocoaAutoReleasePool pool; |
|
1101 |
OSWindowRef theWindow = static_cast<OSWindowRef>(window); |
|
1102 |
NSToolbar *macToolbar = [theWindow toolbar]; |
|
1103 |
if (macToolbar) |
|
1104 |
[macToolbar setShowsBaselineSeparator: show]; |
|
1105 |
#endif |
|
1106 |
} |
|
1107 |
||
1108 |
QStringList qt_mac_NSArrayToQStringList(void *nsarray) |
|
1109 |
{ |
|
1110 |
QStringList result; |
|
1111 |
NSArray *array = static_cast<NSArray *>(nsarray); |
|
1112 |
for (NSUInteger i=0; i<[array count]; ++i) |
|
1113 |
result << qt_mac_NSStringToQString([array objectAtIndex:i]); |
|
1114 |
return result; |
|
1115 |
} |
|
1116 |
||
1117 |
void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list) |
|
1118 |
{ |
|
1119 |
NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()]; |
|
1120 |
for (int i=0; i<list.size(); ++i){ |
|
1121 |
[result addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(list[i]))]; |
|
1122 |
} |
|
1123 |
return result; |
|
1124 |
} |
|
1125 |
||
1126 |
void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow) |
|
1127 |
{ |
|
1128 |
if (!widgetForWindow) |
|
1129 |
return; |
|
1130 |
||
1131 |
Qt::WindowFlags flags = widgetForWindow->windowFlags(); |
|
1132 |
bool customize = flags & Qt::CustomizeWindowHint; |
|
1133 |
||
1134 |
NSButton *btn = [window standardWindowButton:NSWindowZoomButton]; |
|
1135 |
// BOOL is not an int, so the bitwise AND doesn't work. |
|
1136 |
bool go = uint(customize && !(flags & Qt::WindowMaximizeButtonHint)) == 0; |
|
1137 |
[btn setEnabled:go]; |
|
1138 |
||
1139 |
btn = [window standardWindowButton:NSWindowMiniaturizeButton]; |
|
1140 |
go = uint(customize && !(flags & Qt::WindowMinimizeButtonHint)) == 0; |
|
1141 |
[btn setEnabled:go]; |
|
1142 |
||
1143 |
btn = [window standardWindowButton:NSWindowCloseButton]; |
|
1144 |
go = uint(customize && !(flags & Qt::WindowSystemMenuHint |
|
1145 |
|| flags & Qt::WindowCloseButtonHint)) == 0; |
|
1146 |
[btn setEnabled:go]; |
|
1147 |
||
1148 |
[window setShowsToolbarButton:uint(flags & Qt::MacWindowToolBarButtonHint) != 0]; |
|
1149 |
} |
|
1150 |
||
1151 |
// Carbon: Make sure you call QDEndContext on the context when done with it. |
|
1152 |
CGContextRef qt_mac_graphicsContextFor(QWidget *widget) |
|
1153 |
{ |
|
1154 |
if (!widget) |
|
1155 |
return 0; |
|
1156 |
||
1157 |
#ifndef QT_MAC_USE_COCOA |
|
1158 |
CGContextRef context; |
|
1159 |
CGrafPtr port = GetWindowPort(qt_mac_window_for(widget)); |
|
1160 |
QDBeginCGContext(port, &context); |
|
1161 |
#else |
|
1162 |
CGContextRef context = (CGContextRef)[[NSGraphicsContext graphicsContextWithWindow:qt_mac_window_for(widget)] graphicsPort]; |
|
1163 |
#endif |
|
1164 |
return context; |
|
1165 |
} |
|
1166 |
||
1167 |
CGFloat qt_mac_get_scalefactor() |
|
1168 |
{ |
|
1169 |
#ifndef QT_MAC_USE_COCOA |
|
1170 |
return HIGetScaleFactor(); |
|
1171 |
#else |
|
1172 |
return [[NSScreen mainScreen] userSpaceScaleFactor]; |
|
1173 |
#endif |
|
1174 |
} |
|
1175 |
||
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1176 |
QString qt_mac_get_pasteboardString(OSPasteboardRef paste) |
0 | 1177 |
{ |
1178 |
QMacCocoaAutoReleasePool pool; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1179 |
NSPasteboard *pb = nil; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1180 |
CFStringRef pbname; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1181 |
if (PasteboardCopyName (paste, &pbname)) { |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1182 |
pb = [NSPasteboard generalPasteboard]; |
0 | 1183 |
} else { |
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1184 |
pb = [NSPasteboard pasteboardWithName:reinterpret_cast<const NSString *>(pbname)]; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1185 |
CFRelease (pbname); |
0 | 1186 |
} |
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1187 |
if (pb) { |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1188 |
NSString *text = [pb stringForType:NSStringPboardType]; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1189 |
if (text) |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1190 |
return qt_mac_NSStringToQString(text); |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1191 |
} |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1192 |
return QString(); |
0 | 1193 |
} |
1194 |
||
1195 |
QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height) |
|
1196 |
{ |
|
1197 |
QPixmap ret(width, height); |
|
1198 |
ret.fill(QColor(0, 0, 0, 0)); |
|
1199 |
||
1200 |
CGRect rect = CGRectMake(0, 0, width, height); |
|
1201 |
||
1202 |
CGContextRef ctx = qt_mac_cg_context(&ret); |
|
1203 |
CGAffineTransform old_xform = CGContextGetCTM(ctx); |
|
1204 |
CGContextConcatCTM(ctx, CGAffineTransformInvert(old_xform)); |
|
1205 |
CGContextConcatCTM(ctx, CGAffineTransformIdentity); |
|
1206 |
||
1207 |
::RGBColor b; |
|
1208 |
b.blue = b.green = b.red = 255*255; |
|
1209 |
PlotIconRefInContext(ctx, &rect, kAlignNone, kTransformNone, &b, kPlotIconRefNormalFlags, icon); |
|
1210 |
CGContextRelease(ctx); |
|
1211 |
return ret; |
|
1212 |
} |
|
1213 |
||
1214 |
void qt_mac_constructQIconFromIconRef(const IconRef icon, const IconRef overlayIcon, QIcon *retIcon, QStyle::StandardPixmap standardIcon) |
|
1215 |
{ |
|
1216 |
int size = 16; |
|
1217 |
while (size <= 128) { |
|
1218 |
||
1219 |
const QString cacheKey = QLatin1String("qt_mac_constructQIconFromIconRef") + QString::number(standardIcon) + QString::number(size); |
|
1220 |
QPixmap mainIcon; |
|
1221 |
if (standardIcon >= QStyle::SP_CustomBase) { |
|
1222 |
mainIcon = qt_mac_convert_iconref(icon, size, size); |
|
1223 |
} else if (QPixmapCache::find(cacheKey, mainIcon) == false) { |
|
1224 |
mainIcon = qt_mac_convert_iconref(icon, size, size); |
|
1225 |
QPixmapCache::insert(cacheKey, mainIcon); |
|
1226 |
} |
|
1227 |
||
1228 |
if (overlayIcon) { |
|
1229 |
int littleSize = size / 2; |
|
1230 |
QPixmap overlayPix = qt_mac_convert_iconref(overlayIcon, littleSize, littleSize); |
|
1231 |
QPainter painter(&mainIcon); |
|
1232 |
painter.drawPixmap(size - littleSize, size - littleSize, overlayPix); |
|
1233 |
} |
|
1234 |
||
1235 |
retIcon->addPixmap(mainIcon); |
|
1236 |
size += size; // 16 -> 32 -> 64 -> 128 |
|
1237 |
} |
|
1238 |
} |
|
1239 |
||
1240 |
void qt_mac_menu_collapseSeparators(void */*NSMenu **/ theMenu, bool collapse) |
|
1241 |
{ |
|
1242 |
OSMenuRef menu = static_cast<OSMenuRef>(theMenu); |
|
1243 |
if (collapse) { |
|
1244 |
bool previousIsSeparator = true; // setting to true kills all the separators placed at the top. |
|
1245 |
NSMenuItem *previousItem = nil; |
|
1246 |
||
1247 |
NSArray *itemArray = [menu itemArray]; |
|
1248 |
for (unsigned int i = 0; i < [itemArray count]; ++i) { |
|
1249 |
NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]); |
|
1250 |
if ([item isSeparatorItem]) { |
|
1251 |
[item setHidden:previousIsSeparator]; |
|
1252 |
} |
|
1253 |
||
1254 |
if (![item isHidden]) { |
|
1255 |
previousItem = item; |
|
1256 |
previousIsSeparator = ([previousItem isSeparatorItem]); |
|
1257 |
} |
|
1258 |
} |
|
1259 |
||
1260 |
// We now need to check the final item since we don't want any separators at the end of the list. |
|
1261 |
if (previousItem && previousIsSeparator) |
|
1262 |
[previousItem setHidden:YES]; |
|
1263 |
} else { |
|
1264 |
NSArray *itemArray = [menu itemArray]; |
|
1265 |
for (unsigned int i = 0; i < [itemArray count]; ++i) { |
|
1266 |
NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]); |
|
1267 |
if (QAction *action = reinterpret_cast<QAction *>([item tag])) |
|
1268 |
[item setHidden:!action->isVisible()]; |
|
1269 |
} |
|
1270 |
} |
|
1271 |
} |
|
1272 |
||
1273 |
#ifdef QT_MAC_USE_COCOA |
|
1274 |
void qt_cocoaChangeOverrideCursor(const QCursor &cursor) |
|
1275 |
{ |
|
1276 |
QMacCocoaAutoReleasePool pool; |
|
1277 |
[static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursor)) set]; |
|
1278 |
} |
|
1279 |
#endif |
|
1280 |
||
1281 |
QT_END_NAMESPACE |