summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qcocoaview_mac.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qcocoaview_mac.mm')
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm1388
1 files changed, 0 insertions, 1388 deletions
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
deleted file mode 100644
index 6c5e05b32a..0000000000
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ /dev/null
@@ -1,1388 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#import <private/qcocoaview_mac_p.h>
-#ifdef QT_MAC_USE_COCOA
-
-#include <private/qwidget_p.h>
-#include <private/qt_mac_p.h>
-#include <private/qapplication_p.h>
-#include <private/qabstractscrollarea_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <private/qdnd_p.h>
-#include <private/qmacinputcontext_p.h>
-#include <private/qevent_p.h>
-#include <private/qbackingstore_p.h>
-#include <private/qwindowsurface_raster_p.h>
-#include <private/qunifiedtoolbarsurface_mac_p.h>
-
-#include <qscrollarea.h>
-#include <qhash.h>
-#include <qtextformat.h>
-#include <qpaintengine.h>
-#include <QUrl>
-#include <QAccessible>
-#include <QFileInfo>
-#include <QFile>
-
-#include <qdebug.h>
-
-@interface NSEvent (Qt_Compile_Leopard_DeviceDelta)
- - (CGFloat)deviceDeltaX;
- - (CGFloat)deviceDeltaY;
- - (CGFloat)deviceDeltaZ;
-@end
-
-@interface NSEvent (Qt_Compile_Leopard_Gestures)
- - (CGFloat)magnification;
-@end
-
-QT_BEGIN_NAMESPACE
-
-extern void qt_mac_update_cursor(); // qcursor_mac.mm
-extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); // qapplication.cpp
-extern QPointer<QWidget> qt_last_mouse_receiver; // qapplication_mac.cpp
-extern QPointer<QWidget> qt_last_native_mouse_receiver; // qt_cocoa_helpers_mac.mm
-extern OSViewRef qt_mac_nativeview_for(const QWidget *w); // qwidget_mac.mm
-extern OSViewRef qt_mac_effectiveview_for(const QWidget *w); // qwidget_mac.mm
-extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
-extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum);
-extern QWidget *mac_mouse_grabber;
-extern bool qt_mac_clearDirtyOnWidgetInsideDrawWidget; // qwidget.cpp
-
-static QColor colorFrom(NSColor *color)
-{
- QColor qtColor;
- NSString *colorSpace = [color colorSpaceName];
- if (colorSpace == NSDeviceCMYKColorSpace) {
- CGFloat cyan, magenta, yellow, black, alpha;
- [color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha];
- qtColor.setCmykF(cyan, magenta, yellow, black, alpha);
- } else {
- NSColor *tmpColor;
- tmpColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
- CGFloat red, green, blue, alpha;
- [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
- qtColor.setRgbF(red, green, blue, alpha);
- }
- return qtColor;
-}
-
-QT_END_NAMESPACE
-
-QT_FORWARD_DECLARE_CLASS(QMacCocoaAutoReleasePool)
-QT_FORWARD_DECLARE_CLASS(QCFString)
-QT_FORWARD_DECLARE_CLASS(QDragManager)
-QT_FORWARD_DECLARE_CLASS(QMimeData)
-QT_FORWARD_DECLARE_CLASS(QPoint)
-QT_FORWARD_DECLARE_CLASS(QApplication)
-QT_FORWARD_DECLARE_CLASS(QApplicationPrivate)
-QT_FORWARD_DECLARE_CLASS(QDragEnterEvent)
-QT_FORWARD_DECLARE_CLASS(QDragMoveEvent)
-QT_FORWARD_DECLARE_CLASS(QStringList)
-QT_FORWARD_DECLARE_CLASS(QString)
-QT_FORWARD_DECLARE_CLASS(QRect)
-QT_FORWARD_DECLARE_CLASS(QRegion)
-QT_FORWARD_DECLARE_CLASS(QAbstractScrollArea)
-QT_FORWARD_DECLARE_CLASS(QAbstractScrollAreaPrivate)
-QT_FORWARD_DECLARE_CLASS(QPaintEvent)
-QT_FORWARD_DECLARE_CLASS(QPainter)
-QT_FORWARD_DECLARE_CLASS(QHoverEvent)
-QT_FORWARD_DECLARE_CLASS(QCursor)
-QT_USE_NAMESPACE
-extern "C" {
- extern NSString *NSTextInputReplacementRangeAttributeName;
-}
-
-//#define ALIEN_DEBUG 1
-#ifdef ALIEN_DEBUG
-static int qCocoaViewCount = 0;
-#endif
-
-@implementation QT_MANGLE_NAMESPACE(QCocoaView)
-
-- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate
-{
- self = [super init];
- if (self) {
- [self finishInitWithQWidget:widget widgetPrivate:widgetprivate];
- }
- [self setFocusRingType:NSFocusRingTypeNone];
- composingText = new QString();
-
-#ifdef ALIEN_DEBUG
- ++qCocoaViewCount;
- qDebug() << "Alien: create native view for" << widget << ". qCocoaViewCount is:" << qCocoaViewCount;
-#endif
-
- composing = false;
- sendKeyEvents = true;
- fromKeyDownEvent = false;
- alienTouchCount = 0;
-
- [self setHidden:YES];
- return self;
-}
-
-- (void) finishInitWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate
-{
- qwidget = widget;
- qwidgetprivate = widgetprivate;
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(frameDidChange:)
- name:@"NSViewFrameDidChangeNotification"
- object:self];
-}
-
-- (void)dealloc
-{
- QMacCocoaAutoReleasePool pool;
- delete composingText;
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-
-#ifdef ALIEN_DEBUG
- --qCocoaViewCount;
- qDebug() << "Alien: widget deallocated. qCocoaViewCount is:" << qCocoaViewCount;
-#endif
-
- [super dealloc];
-}
-
-- (BOOL)isOpaque
-{
- if (!qwidgetprivate)
- return [super isOpaque];
- return qwidgetprivate->isOpaque;
-}
-
-- (BOOL)isFlipped
-{
- return YES;
-}
-
-// We preserve the content of the view if WA_StaticContents is defined.
-//
-// More info in the Cocoa documentation:
-// http://developer.apple.com/mac/library/documentation/cocoa/conceptual/CocoaViewsGuide/Optimizing/Optimizing.html
-- (BOOL) preservesContentDuringLiveResize
-{
- return qwidget->testAttribute(Qt::WA_StaticContents);
-}
-
-- (void) setFrameSize:(NSSize)newSize
-{
- [super setFrameSize:newSize];
-
- // A change in size has required the view to be invalidated.
- if ([self inLiveResize]) {
- NSRect rects[4];
- NSInteger count;
- [self getRectsExposedDuringLiveResize:rects count:&count];
- while (count-- > 0)
- {
- [self setNeedsDisplayInRect:rects[count]];
- }
- } else {
- [self setNeedsDisplay:YES];
- }
-
- // Make sure the opengl context is updated on resize.
- if (qwidgetprivate && qwidgetprivate->isGLWidget && [self window]) {
- qwidgetprivate->needWindowChange = true;
- QEvent event(QEvent::MacGLWindowChange);
- qApp->sendEvent(qwidget, &event);
- }
-}
-
-// We catch the 'setNeedsDisplay:' message in order to avoid a useless full repaint.
-// During the resize, the top of the widget is repainted, probably because of the
-// change of coordinate space (Quartz vs Qt). This is then followed by this message:
-// -[NSView _setNeedsDisplayIfTopLeftChanged]
-// which force a full repaint by sending the message 'setNeedsDisplay:'.
-// That is what we are preventing here.
-- (void)setNeedsDisplay:(BOOL)flag {
- if (![self inLiveResize] || !(qwidget->testAttribute(Qt::WA_StaticContents))) {
- [super setNeedsDisplay:flag];
- }
-}
-
-- (void)drawRect:(NSRect)aRect
-{
- if (!qwidget)
- return;
-
- // Getting context.
- CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
- qt_mac_retain_graphics_context(context);
-
- // We use a different graphics system.
- //
- // Widgets that are set to paint on screen, specifically QGLWidget,
- // requires the native engine to execute in order to be drawn.
- if (QApplicationPrivate::graphicsSystem() != 0 && !qwidget->testAttribute(Qt::WA_PaintOnScreen)) {
-
- // Raster engine.
- if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) {
-
- if (!qwidgetprivate->isInUnifiedToolbar) {
-
- // Qt handles the painting occuring inside the window.
- // Cocoa also keeps track of all widgets as NSView and therefore might
- // ask for a repainting of a widget even if Qt is already taking care of it.
- //
- // The only valid reason for Cocoa to call drawRect: is for window manipulation
- // (ie. resize, ...).
- //
- // Qt will then forward the update to the children.
- if (!qwidget->isWindow()) {
- qt_mac_release_graphics_context(context);
- return;
- }
-
- QRasterWindowSurface *winSurface = dynamic_cast<QRasterWindowSurface *>(qwidget->windowSurface());
- if (!winSurface || !winSurface->needsFlush) {
- qt_mac_release_graphics_context(context);
- return;
- }
-
- // Clip to region.
- const QVector<QRect> &rects = winSurface->regionToFlush.rects();
- for (int i = 0; i < rects.size(); ++i) {
- const QRect &rect = rects.at(i);
- CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()));
- }
- CGContextClip(context);
-
- QRect r = winSurface->regionToFlush.boundingRect();
- const CGRect area = CGRectMake(r.x(), r.y(), r.width(), r.height());
-
- qt_mac_draw_image(context, winSurface->imageContext(), area, area);
-
- winSurface->needsFlush = false;
- winSurface->regionToFlush = QRegion();
-
- } else {
-
- QUnifiedToolbarSurface *unifiedSurface = qwidgetprivate->unifiedSurface;
- if (!unifiedSurface) {
- qt_mac_release_graphics_context(context);
- return;
- }
-
- int areaX = qwidgetprivate->toolbar_offset.x();
- int areaY = qwidgetprivate->toolbar_offset.y();
- int areaWidth = qwidget->geometry().width();
- int areaHeight = qwidget->geometry().height();
- const CGRect area = CGRectMake(areaX, areaY, areaWidth, areaHeight);
- const CGRect drawingArea = CGRectMake(0, 0, areaWidth, areaHeight);
-
- qt_mac_draw_image(context, unifiedSurface->imageContext(), area, drawingArea);
-
- qwidgetprivate->flushRequested = false;
-
- }
-
- CGContextFlush(context);
- qt_mac_release_graphics_context(context);
- return;
- }
-
- // Qt handles the painting occuring inside the window.
- // Cocoa also keeps track of all widgets as NSView and therefore might
- // ask for a repainting of a widget even if Qt is already taking care of it.
- //
- // The only valid reason for Cocoa to call drawRect: is for window manipulation
- // (ie. resize, ...).
- //
- // Qt will then forward the update to the children.
- if (qwidget->isWindow()) {
- qwidgetprivate->syncBackingStore(qwidget->rect());
- }
- }
-
- // Native engine.
- qwidgetprivate->hd = context;
-
- if (qwidget->isVisible() && qwidget->updatesEnabled()) { //process the actual paint event.
- if (qwidget->testAttribute(Qt::WA_WState_InPaintEvent))
- qWarning("QWidget::repaint: Recursive repaint detected");
-
- const QRect qrect = QRect(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height);
- QRegion qrgn;
-
- const NSRect *rects;
- NSInteger count;
- [self getRectsBeingDrawn:&rects count:&count];
- for (int i = 0; i < count; ++i) {
- QRect tmpRect = QRect(rects[i].origin.x, rects[i].origin.y, rects[i].size.width, rects[i].size.height);
- qrgn += tmpRect;
- }
-
- if (!qwidget->isWindow() && !qobject_cast<QAbstractScrollArea *>(qwidget->parent())) {
- const QRegion &parentMask = qwidget->window()->mask();
- if (!parentMask.isEmpty()) {
- const QPoint mappedPoint = qwidget->mapTo(qwidget->window(), qrect.topLeft());
- qrgn.translate(mappedPoint);
- qrgn &= parentMask;
- qrgn.translate(-mappedPoint.x(), -mappedPoint.y());
- }
- }
-
- QPoint redirectionOffset(0, 0);
- //setup the context
- qwidget->setAttribute(Qt::WA_WState_InPaintEvent);
- QPaintEngine *engine = qwidget->paintEngine();
- if (engine)
- engine->setSystemClip(qrgn);
- if (qwidgetprivate->extra && qwidgetprivate->extra->hasMask) {
- CGRect widgetRect = CGRectMake(0, 0, qwidget->width(), qwidget->height());
- CGContextTranslateCTM (context, 0, widgetRect.size.height);
- CGContextScaleCTM(context, 1, -1);
- if (qwidget->isWindow())
- CGContextClearRect(context, widgetRect);
- CGContextClipToMask(context, widgetRect, qwidgetprivate->extra->imageMask);
- CGContextScaleCTM(context, 1, -1);
- CGContextTranslateCTM (context, 0, -widgetRect.size.height);
- }
-
- if (qwidget->isWindow() && !qwidgetprivate->isOpaque
- && !qwidget->testAttribute(Qt::WA_MacBrushedMetal)) {
- CGContextClearRect(context, NSRectToCGRect(aRect));
- }
-
- qwidget->setAttribute(Qt::WA_WState_InPaintEvent, false);
- QWidgetPrivate *qwidgetPrivate = qt_widget_private(qwidget);
-
- // We specify that we want to draw the widget itself, and
- // all its children recursive. But we skip native children, because
- // they will receive drawRect calls by themselves as needed:
- int flags = QWidgetPrivate::DrawPaintOnScreen
- | QWidgetPrivate::DrawRecursive
- | QWidgetPrivate::DontDrawNativeChildren;
-
- if (qwidget->isWindow())
- flags |= QWidgetPrivate::DrawAsRoot;
-
- // Start to draw:
- qt_mac_clearDirtyOnWidgetInsideDrawWidget = true;
- qwidgetPrivate->drawWidget(qwidget, qrgn, QPoint(), flags, 0);
- qt_mac_clearDirtyOnWidgetInsideDrawWidget = false;
-
- if (!redirectionOffset.isNull())
- QPainter::restoreRedirected(qwidget);
- if (engine)
- engine->setSystemClip(QRegion());
- qwidget->setAttribute(Qt::WA_WState_InPaintEvent, false);
- if(!qwidget->testAttribute(Qt::WA_PaintOutsidePaintEvent) && qwidget->paintingActive())
- qWarning("QWidget: It is dangerous to leave painters active on a"
- " widget outside of the PaintEvent");
- }
- qwidgetprivate->hd = 0;
- qt_mac_release_graphics_context(context);
-}
-
-- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
-{
- // Find the widget that should receive the event:
- QPoint qlocal, qglobal;
- QWidget *widgetToGetMouse = qt_mac_getTargetForMouseEvent(theEvent, QEvent::MouseButtonPress, qlocal, qglobal, qwidget, 0);
- if (!widgetToGetMouse)
- return NO;
-
- return !widgetToGetMouse->testAttribute(Qt::WA_MacNoClickThrough);
-}
-
-- (NSView *)hitTest:(NSPoint)aPoint
-{
- if (!qwidget)
- return [super hitTest:aPoint];
-
- if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents))
- return nil; // You cannot hit a transparent for mouse event widget.
- return [super hitTest:aPoint];
-}
-
-- (void)updateTrackingAreas
-{
- if (!qwidget)
- return;
-
- // [NSView addTrackingArea] is slow, so bail out early if we can:
- if (NSIsEmptyRect([self visibleRect]))
- return;
-
- QMacCocoaAutoReleasePool pool;
- if (NSArray *trackingArray = [self trackingAreas]) {
- NSUInteger size = [trackingArray count];
- for (NSUInteger i = 0; i < size; ++i) {
- NSTrackingArea *t = [trackingArray objectAtIndex:i];
- [self removeTrackingArea:t];
- }
- }
-
- // Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should
- // only be turned on if mouseTracking, hover is on or a tool tip is set.
- // Unfortunately, Qt will send "tooltip" events on mouse moves, so we need to
- // turn it on in ALL case. That means EVERY QCocoaView gets to pay the cost of
- // mouse moves delivered to it (Apple recommends keeping it OFF because there
- // is a performance hit). So it goes.
- NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp
- | NSTrackingInVisibleRect | NSTrackingMouseMoved;
- NSTrackingArea *ta = [[NSTrackingArea alloc] initWithRect:NSMakeRect(0, 0,
- qwidget->width(),
- qwidget->height())
- options:trackingOptions
- owner:self
- userInfo:nil];
- [self addTrackingArea:ta];
- [ta release];
-}
-
-- (void)mouseEntered:(NSEvent *)event
-{
- // Cocoa will not send a move event on mouseEnter. But since
- // Qt expect this, we fake one now. See also mouseExited below
- // for info about enter/leave event handling
- NSEvent *nsmoveEvent = [NSEvent
- mouseEventWithType:NSMouseMoved
- location:[[self window] mouseLocationOutsideOfEventStream]
- modifierFlags: [event modifierFlags]
- timestamp: [event timestamp]
- windowNumber: [event windowNumber]
- context: [event context]
- eventNumber: [event eventNumber]
- clickCount: 0
- pressure: 0];
-
- // Important: Cocoa sends us mouseEnter on all views under the mouse
- // and not just the one on top. Therefore, to we cannot use qwidget
- // as native widget for this case. Instead, we let qt_mac_handleMouseEvent
- // resolve it (last argument set to 0):
- qt_mac_handleMouseEvent(nsmoveEvent, QEvent::MouseMove, Qt::NoButton, 0);
-}
-
-- (void)mouseExited:(NSEvent *)event
-{
- // Note: normal enter/leave handling is done from within mouseMove. This handler
- // catches the case when the mouse moves out of the window (which mouseMove do not).
- // Updating the mouse cursor follows the same logic as enter/leave. And we update
- // neither if a grab exists (even if the grab points to this widget, it seems, ref X11)
- Q_UNUSED(event);
- if (self == [[self window] contentView] && !qt_button_down && !QWidget::mouseGrabber()) {
- qt_mac_update_cursor();
- // If the mouse exits the content view, but qt_mac_getTargetForMouseEvent still
- // reports a target, it means that either there is a grab involved, or the mouse
- // hovered over another window in the application. In both cases, move events will
- // cause qt_mac_handleMouseEvent to be called, which will handle enter/leave.
- QPoint qlocal, qglobal;
- QWidget *widgetUnderMouse = 0;
- qt_mac_getTargetForMouseEvent(event, QEvent::Leave, qlocal, qglobal, qwidget, &widgetUnderMouse);
-
- if (widgetUnderMouse == 0) {
- QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver);
- qt_last_mouse_receiver = 0;
- qt_last_native_mouse_receiver = 0;
- }
- }
-}
-
-- (void)flagsChanged:(NSEvent *)theEvent
-{
- QWidget *widgetToGetKey = qt_mac_getTargetForKeyEvent(qwidget);
- if (!widgetToGetKey)
- return;
-
- qt_dispatchModifiersChanged(theEvent, widgetToGetKey);
- [super flagsChanged:theEvent];
-}
-
-- (void)mouseMoved:(NSEvent *)theEvent
-{
- // Important: this method will only be called when the view's window is _not_ inside
- // QCocoaWindow/QCocoaPanel. Otherwise, [QCocoaWindow sendEvent] will handle the event
- // before it ends up here. So, this method is added for supporting QMacNativeWidget.
- // TODO: Cocoa send move events to all views under the mouse. So make sure we only
- // handle the event for the widget on top when using QMacNativeWidget.
- qt_mac_handleMouseEvent(theEvent, QEvent::MouseMove, Qt::NoButton, qwidget);
-}
-
-- (void)mouseDown:(NSEvent *)theEvent
-{
- qt_mac_handleMouseEvent(theEvent, QEvent::MouseButtonPress, Qt::LeftButton, qwidget);
- // Don't call super here. This prevents us from getting the mouseUp event,
- // which we need to send even if the mouseDown event was not accepted.
- // (this is standard Qt behavior.)
-}
-
-- (void)mouseUp:(NSEvent *)theEvent
-{
- qt_mac_handleMouseEvent(theEvent, QEvent::MouseButtonRelease, Qt::LeftButton, qwidget);
-}
-
-- (void)rightMouseDown:(NSEvent *)theEvent
-{
- qt_mac_handleMouseEvent(theEvent, QEvent::MouseButtonPress, Qt::RightButton, qwidget);
-}
-
-- (void)rightMouseUp:(NSEvent *)theEvent
-{
- qt_mac_handleMouseEvent(theEvent, QEvent::MouseButtonRelease, Qt::RightButton, qwidget);
-}
-
-- (void)otherMouseDown:(NSEvent *)theEvent
-{
- Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
- qt_mac_handleMouseEvent(theEvent, QEvent::MouseButtonPress, mouseButton, qwidget);
-}
-
-- (void)otherMouseUp:(NSEvent *)theEvent
-{
- Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
- qt_mac_handleMouseEvent(theEvent, QEvent::MouseButtonRelease, mouseButton, qwidget);
-}
-
-- (void)mouseDragged:(NSEvent *)theEvent
-{
- qt_mac_handleMouseEvent(theEvent, QEvent::MouseMove, Qt::NoButton, qwidget);
-}
-
-- (void)rightMouseDragged:(NSEvent *)theEvent
-{
- qt_mac_handleMouseEvent(theEvent, QEvent::MouseMove, Qt::NoButton, qwidget);
-}
-
-- (void)otherMouseDragged:(NSEvent *)theEvent
-{
- qt_mac_handleMouseEvent(theEvent, QEvent::MouseMove, Qt::NoButton, qwidget);
-}
-
-- (void)scrollWheel:(NSEvent *)theEvent
-{
- // Give the Input Manager a chance to process the wheel event.
- NSInputManager *currentIManager = [NSInputManager currentInputManager];
- if (currentIManager && [currentIManager wantsToHandleMouseEvents]) {
- [currentIManager handleMouseEvent:theEvent];
- }
-
- Qt::MouseButtons buttons = QApplication::mouseButtons();
- Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
-
- // Find the widget that should receive the event:
- QPoint qlocal, qglobal;
- QWidget *widgetToGetMouse = qt_mac_getTargetForMouseEvent(theEvent, QEvent::Wheel, qlocal, qglobal, qwidget, 0);
- if (!widgetToGetMouse)
- return;
-
- int deltaX = 0;
- int deltaY = 0;
- int deltaZ = 0;
-
- const EventRef carbonEvent = (EventRef)[theEvent eventRef];
- const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
- const bool scrollEvent = carbonEventKind == kEventMouseScroll;
-
- if (scrollEvent) {
- // The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad).
- // Since deviceDelta is delivered as pixels rather than degrees, we need to
- // convert from pixels to degrees in a sensible manner.
- // It looks like 1/4 degrees per pixel behaves most native.
- // (NB: Qt expects the unit for delta to be 8 per degree):
- const int pixelsToDegrees = 2; // 8 * 1/4
- deltaX = [theEvent deviceDeltaX] * pixelsToDegrees;
- deltaY = [theEvent deviceDeltaY] * pixelsToDegrees;
- deltaZ = [theEvent deviceDeltaZ] * pixelsToDegrees;
- } else {
- // carbonEventKind == kEventMouseWheelMoved
- // Remove acceleration, and use either -120 or 120 as delta:
- deltaX = qBound(-120, int([theEvent deltaX] * 10000), 120);
- deltaY = qBound(-120, int([theEvent deltaY] * 10000), 120);
- deltaZ = qBound(-120, int([theEvent deltaZ] * 10000), 120);
- }
-
-#ifndef QT_NO_WHEELEVENT
- // ### Qt 5: Send one QWheelEvent with dx, dy and dz
-
- if (deltaX != 0 && deltaY != 0)
- QMacScrollOptimization::initDelayedScroll();
-
- if (deltaX != 0) {
- QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal);
- qt_sendSpontaneousEvent(widgetToGetMouse, &qwe);
- }
-
- if (deltaY != 0) {
- QWheelEvent qwe(qlocal, qglobal, deltaY, buttons, keyMods, Qt::Vertical);
- qt_sendSpontaneousEvent(widgetToGetMouse, &qwe);
- }
-
- if (deltaZ != 0) {
- // Qt doesn't explicitly support wheels with a Z component. In a misguided attempt to
- // try to be ahead of the pack, I'm adding this extra value.
- QWheelEvent qwe(qlocal, qglobal, deltaZ, buttons, keyMods, (Qt::Orientation)3);
- qt_sendSpontaneousEvent(widgetToGetMouse, &qwe);
- }
-
- if (deltaX != 0 && deltaY != 0)
- QMacScrollOptimization::performDelayedScroll();
-#endif //QT_NO_WHEELEVENT
-}
-
-- (void)tabletProximity:(NSEvent *)tabletEvent
-{
- qt_dispatchTabletProximityEvent(tabletEvent);
-}
-
-- (void)tabletPoint:(NSEvent *)tabletEvent
-{
- if (!qt_mac_handleTabletEvent(self, tabletEvent))
- [super tabletPoint:tabletEvent];
-}
-
-- (void)magnifyWithEvent:(NSEvent *)event
-{
- QPoint qlocal, qglobal;
- QWidget *widgetToGetGesture = 0;
- qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, qwidget, &widgetToGetGesture);
- if (!widgetToGetGesture)
- return;
- if (!QApplicationPrivate::tryModalHelper(widgetToGetGesture, 0))
- return;
-
-#ifndef QT_NO_GESTURES
- QNativeGestureEvent qNGEvent;
- qNGEvent.gestureType = QNativeGestureEvent::Zoom;
- NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]];
- qNGEvent.position = flipPoint(p).toPoint();
- qNGEvent.percentage = [event magnification];
- qt_sendSpontaneousEvent(widgetToGetGesture, &qNGEvent);
-#endif // QT_NO_GESTURES
-}
-
-- (void)rotateWithEvent:(NSEvent *)event
-{
- QPoint qlocal, qglobal;
- QWidget *widgetToGetGesture = 0;
- qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, qwidget, &widgetToGetGesture);
- if (!widgetToGetGesture)
- return;
- if (!QApplicationPrivate::tryModalHelper(widgetToGetGesture, 0))
- return;
-
-#ifndef QT_NO_GESTURES
- QNativeGestureEvent qNGEvent;
- qNGEvent.gestureType = QNativeGestureEvent::Rotate;
- NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]];
- qNGEvent.position = flipPoint(p).toPoint();
- qNGEvent.percentage = -[event rotation];
- qt_sendSpontaneousEvent(widgetToGetGesture, &qNGEvent);
-#endif // QT_NO_GESTURES
-}
-
-- (void)swipeWithEvent:(NSEvent *)event
-{
- QPoint qlocal, qglobal;
- QWidget *widgetToGetGesture = 0;
- qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, qwidget, &widgetToGetGesture);
- if (!widgetToGetGesture)
- return;
- if (!QApplicationPrivate::tryModalHelper(widgetToGetGesture, 0))
- return;
-
-#ifndef QT_NO_GESTURES
- QNativeGestureEvent qNGEvent;
- qNGEvent.gestureType = QNativeGestureEvent::Swipe;
- NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]];
- qNGEvent.position = flipPoint(p).toPoint();
- if ([event deltaX] == 1)
- qNGEvent.angle = 180.0f;
- else if ([event deltaX] == -1)
- qNGEvent.angle = 0.0f;
- else if ([event deltaY] == 1)
- qNGEvent.angle = 90.0f;
- else if ([event deltaY] == -1)
- qNGEvent.angle = 270.0f;
- qt_sendSpontaneousEvent(widgetToGetGesture, &qNGEvent);
-#endif // QT_NO_GESTURES
-}
-
-- (void)beginGestureWithEvent:(NSEvent *)event
-{
- QPoint qlocal, qglobal;
- QWidget *widgetToGetGesture = 0;
- qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, qwidget, &widgetToGetGesture);
- if (!widgetToGetGesture)
- return;
- if (!QApplicationPrivate::tryModalHelper(widgetToGetGesture, 0))
- return;
-
-#ifndef QT_NO_GESTURES
- QNativeGestureEvent qNGEvent;
- qNGEvent.gestureType = QNativeGestureEvent::GestureBegin;
- NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]];
- qNGEvent.position = flipPoint(p).toPoint();
- qt_sendSpontaneousEvent(widgetToGetGesture, &qNGEvent);
-#endif // QT_NO_GESTURES
-}
-
-- (void)endGestureWithEvent:(NSEvent *)event
-{
- QPoint qlocal, qglobal;
- QWidget *widgetToGetGesture = 0;
- qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, qwidget, &widgetToGetGesture);
- if (!widgetToGetGesture)
- return;
- if (!QApplicationPrivate::tryModalHelper(widgetToGetGesture, 0))
- return;
-
-#ifndef QT_NO_GESTURES
- QNativeGestureEvent qNGEvent;
- qNGEvent.gestureType = QNativeGestureEvent::GestureEnd;
- NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]];
- qNGEvent.position = flipPoint(p).toPoint();
- qt_sendSpontaneousEvent(widgetToGetGesture, &qNGEvent);
-}
-#endif // QT_NO_GESTURES
-
-- (void)frameDidChange:(NSNotification *)note
-{
- Q_UNUSED(note);
- if (!qwidget)
- return;
- if (qwidget->isWindow())
- return;
- NSRect newFrame = [self frame];
- QRect newGeo(newFrame.origin.x, newFrame.origin.y, newFrame.size.width, newFrame.size.height);
- bool moved = qwidget->testAttribute(Qt::WA_Moved);
- bool resized = qwidget->testAttribute(Qt::WA_Resized);
- qwidget->setGeometry(newGeo);
- qwidget->setAttribute(Qt::WA_Moved, moved);
- qwidget->setAttribute(Qt::WA_Resized, resized);
- qwidgetprivate->syncCocoaMask();
-}
-
-- (BOOL)isEnabled
-{
- if (!qwidget)
- return [super isEnabled];
- return [super isEnabled] && qwidget->isEnabled();
-}
-
-- (void)setEnabled:(BOOL)flag
-{
- QMacCocoaAutoReleasePool pool;
- [super setEnabled:flag];
- if (qwidget && qwidget->isEnabled() != flag)
- qwidget->setEnabled(flag);
-}
-
-+ (Class)cellClass
-{
- return [NSActionCell class];
-}
-
-- (BOOL)acceptsFirstResponder
-{
- if (!qwidget)
- return NO;
-
- // Disabled widget shouldn't get focus even if it's a window.
- // hence disabled windows will not get any key or mouse events.
- if (!qwidget->isEnabled())
- return NO;
-
- if (qwidget->isWindow() && !qt_widget_private(qwidget)->topData()->embedded) {
- QWidget *focusWidget = qApp->focusWidget();
- if (!focusWidget) {
- // There is no focus widget, but we still want to receive key events
- // for shortcut handling etc. So we accept first responer for the
- // content view as a last resort:
- return YES;
- }
- if (!focusWidget->internalWinId() && focusWidget->nativeParentWidget() == qwidget) {
- // The current focus widget is alien, and hence, cannot get acceptsFirstResponder
- // calls. Since the focus widget is a child of qwidget, we let this view say YES:
- return YES;
- }
- if (focusWidget->window() != qwidget) {
- // The current focus widget is in another window. Since cocoa
- // suggest that this window should be key now, we accept:
- return YES;
- }
- }
-
- return qwidget->focusPolicy() != Qt::NoFocus;
-}
-
-- (BOOL)resignFirstResponder
-{
- if (!qwidget)
- return YES;
-
- // Seems like the following test only triggers if this
- // view is inside a QMacNativeWidget:
-// if (QWidget *fw = QApplication::focusWidget()) {
-// if (qwidget == fw || qwidget == fw->nativeParentWidget())
-// fw->clearFocus();
-// }
- return YES;
-}
-
-- (BOOL)becomeFirstResponder
-{
- // see the comment in the acceptsFirstResponder - if the window "stole" focus
- // let it become the responder, but don't tell Qt
- if (qwidget && qt_widget_private(qwidget->window())->topData()->embedded
- && !QApplication::focusWidget() && qwidget->focusPolicy() != Qt::NoFocus)
- qwidget->setFocus(Qt::OtherFocusReason);
- return YES;
-}
-
-- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal
-{
- Q_UNUSED(isLocal);
- return supportedActions;
-}
-
-- (void)setSupportedActions:(NSDragOperation)actions
-{
- supportedActions = actions;
-}
-
-- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
-{
- Q_UNUSED(anImage);
- Q_UNUSED(aPoint);
- macCurrentDnDParameters()->performedAction = operation;
- if (QDragManager::self()->object
- && QDragManager::self()->dragPrivate()->executed_action != Qt::ActionMask) {
- macCurrentDnDParameters()->performedAction =
- qt_mac_mapDropAction(QDragManager::self()->dragPrivate()->executed_action);
- }
-}
-
-- (QWidget *)qt_qwidget
-{
- return qwidget;
-}
-
-- (void) qt_clearQWidget
-{
- qwidget = 0;
- qwidgetprivate = 0;
-}
-
-- (void)keyDown:(NSEvent *)theEvent
-{
- if (!qwidget)
- return;
- QWidget *widgetToGetKey = qt_mac_getTargetForKeyEvent(qwidget);
- if (!widgetToGetKey)
- return;
-
- sendKeyEvents = true;
-
- if (widgetToGetKey->testAttribute(Qt::WA_InputMethodEnabled)
- && !(widgetToGetKey->inputMethodHints() & Qt::ImhDigitsOnly
- || widgetToGetKey->inputMethodHints() & Qt::ImhFormattedNumbersOnly
- || widgetToGetKey->inputMethodHints() & Qt::ImhHiddenText)) {
- fromKeyDownEvent = true;
- [qt_mac_nativeview_for(qwidget) interpretKeyEvents:[NSArray arrayWithObject: theEvent]];
- fromKeyDownEvent = false;
- }
-
- if (sendKeyEvents && !composing) {
- bool keyEventEaten = qt_dispatchKeyEvent(theEvent, widgetToGetKey);
- if (!keyEventEaten && qwidget) {
- // The event is not yet eaten, and if Qt is embedded inside a native
- // cocoa application, send it to first responder not owned by Qt.
- // The exception is if widgetToGetKey was redirected to a popup.
- QWidget *toplevel = qwidget->window();
- if (toplevel == widgetToGetKey->window()) {
- if (qt_widget_private(toplevel)->topData()->embedded) {
- if (NSResponder *w = [qt_mac_nativeview_for(toplevel) superview])
- [w keyDown:theEvent];
- }
- }
- }
- }
-}
-
-
-- (void)keyUp:(NSEvent *)theEvent
-{
- if (sendKeyEvents) {
- QWidget *widgetToGetKey = qt_mac_getTargetForKeyEvent(qwidget);
- if (!widgetToGetKey)
- return;
-
- bool keyEventEaten = qt_dispatchKeyEvent(theEvent, widgetToGetKey);
- if (!keyEventEaten && qwidget) {
- // The event is not yet eaten, and if Qt is embedded inside a native
- // cocoa application, send it to first responder not owned by Qt.
- // The exception is if widgetToGetKey was redirected to a popup.
- QWidget *toplevel = qwidget->window();
- if (toplevel == widgetToGetKey->window()) {
- if (qt_widget_private(toplevel)->topData()->embedded) {
- if (NSResponder *w = [qt_mac_nativeview_for(toplevel) superview])
- [w keyUp:theEvent];
- }
- }
- }
- }
-}
-
-- (void)viewWillMoveToWindow:(NSWindow *)window
-{
- if (qwidget == 0)
- return;
-
- if (qwidget->windowFlags() & Qt::MSWindowsOwnDC
- && (window != [self window])) { // OpenGL Widget
- QEvent event(QEvent::MacGLClearDrawable);
- qApp->sendEvent(qwidget, &event);
- }
-}
-
-- (void)viewDidMoveToWindow
-{
- if (qwidget == 0)
- return;
-
- if (qwidget->windowFlags() & Qt::MSWindowsOwnDC && [self window]) {
- // call update paint event
- qwidgetprivate->needWindowChange = true;
- QEvent event(QEvent::MacGLWindowChange);
- qApp->sendEvent(qwidget, &event);
- }
-}
-
-
-// NSTextInput Protocol implementation
-
-- (void) insertText:(id)aString
-{
- QString commitText;
- if ([aString length]) {
- if ([aString isKindOfClass:[NSAttributedString class]]) {
- commitText = QCFString::toQString(reinterpret_cast<CFStringRef>([aString string]));
- } else {
- commitText = QCFString::toQString(reinterpret_cast<CFStringRef>(aString));
- };
- }
-
- // When entering characters through Character Viewer or Keyboard Viewer, the text is passed
- // through this insertText method. Since we dont receive a keyDown Event in such cases, the
- // composing flag will be false.
- if (([aString length] && composing) || !fromKeyDownEvent) {
- // Send the commit string to the widget.
- composing = false;
- sendKeyEvents = false;
- QInputMethodEvent e;
- e.setCommitString(commitText);
- if (QWidget *widgetToGetKey = qt_mac_getTargetForKeyEvent(qwidget))
- qt_sendSpontaneousEvent(widgetToGetKey, &e);
- } else {
- // The key sequence "`q" on a French Keyboard will generate two calls to insertText before
- // it returns from interpretKeyEvents. The first call will turn off 'composing' and accept
- // the "`" key. The last keyDown event needs to be processed by the widget to get the
- // character "q". The string parameter is ignored for the second call.
- sendKeyEvents = true;
- }
-
- composingText->clear();
-}
-
-- (void) setMarkedText:(id)aString selectedRange:(NSRange)selRange
-{
- // Generate the QInputMethodEvent with preedit string and the attributes
- // for rendering it. The attributes handled here are 'underline',
- // 'underline color' and 'cursor position'.
- sendKeyEvents = false;
- composing = true;
- QString qtText;
- // Cursor position is retrived from the range.
- QList<QInputMethodEvent::Attribute> attrs;
- attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, selRange.location + selRange.length, 1, QVariant());
- if ([aString isKindOfClass:[NSAttributedString class]]) {
- qtText = QCFString::toQString(reinterpret_cast<CFStringRef>([aString string]));
- composingLength = qtText.length();
- int index = 0;
- // Create attributes for individual sections of preedit text
- while (index < composingLength) {
- NSRange effectiveRange;
- NSRange range = NSMakeRange(index, composingLength-index);
- NSDictionary *attributes = [aString attributesAtIndex:index
- longestEffectiveRange:&effectiveRange
- inRange:range];
- NSNumber *underlineStyle = [attributes objectForKey:NSUnderlineStyleAttributeName];
- if (underlineStyle) {
- QColor clr (Qt::black);
- NSColor *color = [attributes objectForKey:NSUnderlineColorAttributeName];
- if (color) {
- clr = colorFrom(color);
- }
- QTextCharFormat format;
- format.setFontUnderline(true);
- format.setUnderlineColor(clr);
- attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
- effectiveRange.location,
- effectiveRange.length,
- format);
- }
- index = effectiveRange.location + effectiveRange.length;
- }
- } else {
- // No attributes specified, take only the preedit text.
- qtText = QCFString::toQString(reinterpret_cast<CFStringRef>(aString));
- composingLength = qtText.length();
- }
- // Make sure that we have at least one text format.
- if (attrs.size() <= 1) {
- QTextCharFormat format;
- format.setFontUnderline(true);
- attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
- 0, composingLength, format);
- }
- *composingText = qtText;
-
- QInputMethodEvent e(qtText, attrs);
- if (QWidget *widgetToGetKey = qt_mac_getTargetForKeyEvent(qwidget))
- qt_sendSpontaneousEvent(widgetToGetKey, &e);
-
- if (!composingLength)
- composing = false;
-}
-
-- (void) unmarkText
-{
- if (composing) {
- QInputMethodEvent e;
- e.setCommitString(*composingText);
- if (QWidget *widgetToGetKey = qt_mac_getTargetForKeyEvent(qwidget))
- qt_sendSpontaneousEvent(widgetToGetKey, &e);
- }
- composingText->clear();
- composing = false;
-}
-
-- (BOOL) hasMarkedText
-{
- return (composing ? YES: NO);
-}
-
-- (void) doCommandBySelector:(SEL)aSelector
-{
- Q_UNUSED(aSelector);
-}
-
-- (BOOL)isComposing
-{
- return composing;
-}
-
-- (NSInteger) conversationIdentifier
-{
- // Return a unique identifier fot this ime conversation
- return (NSInteger)self;
-}
-
-- (NSAttributedString *) attributedSubstringFromRange:(NSRange)theRange
-{
- QString selectedText(qwidget->inputMethodQuery(Qt::ImCurrentSelection).toString());
- if (!selectedText.isEmpty()) {
- QCFString string(selectedText.mid(theRange.location, theRange.length));
- const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string);
- return [[[NSAttributedString alloc] initWithString:const_cast<NSString *>(tmpString)] autorelease];
- } else {
- return nil;
- }
-}
-
-- (NSRange) markedRange
-{
- NSRange range;
- if (composing) {
- range.location = 0;
- range.length = composingLength;
- } else {
- range.location = NSNotFound;
- range.length = 0;
- }
- return range;
-}
-
-- (NSRange) selectedRange
-{
- NSRange selRange;
- QString selectedText(qwidget->inputMethodQuery(Qt::ImCurrentSelection).toString());
- if (!selectedText.isEmpty()) {
- // Consider only the selected text.
- selRange.location = 0;
- selRange.length = selectedText.length();
- } else {
- // No selected text.
- selRange.location = NSNotFound;
- selRange.length = 0;
- }
- return selRange;
-
-}
-
-- (NSRect) firstRectForCharacterRange:(NSRange)theRange
-{
- Q_UNUSED(theRange);
- // The returned rect is always based on the internal cursor.
- QWidget *widgetToGetKey = qt_mac_getTargetForKeyEvent(qwidget);
- if (!widgetToGetKey)
- return NSZeroRect;
-
- QRect mr(widgetToGetKey->inputMethodQuery(Qt::ImMicroFocus).toRect());
- QPoint mp(widgetToGetKey->mapToGlobal(QPoint(mr.bottomLeft())));
- NSRect rect ;
- rect.origin.x = mp.x();
- rect.origin.y = flipYCoordinate(mp.y());
- rect.size.width = mr.width();
- rect.size.height = mr.height();
- return rect;
-}
-
-- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
-{
- // We dont support cursor movements using mouse while composing.
- Q_UNUSED(thePoint);
- return NSNotFound;
-}
-
-- (NSArray*) validAttributesForMarkedText
-{
- QWidget *widgetToGetKey = qt_mac_getTargetForKeyEvent(qwidget);
- if (!widgetToGetKey)
- return nil;
-
- if (!widgetToGetKey->testAttribute(Qt::WA_InputMethodEnabled))
- return nil; // Not sure if that's correct, but it's saves a malloc.
-
- // Support only underline color/style.
- return [NSArray arrayWithObjects:NSUnderlineColorAttributeName,
- NSUnderlineStyleAttributeName, nil];
-}
-@end
-
-QT_BEGIN_NAMESPACE
-void QMacInputContext::reset()
-{
- QWidget *w = QInputContext::focusWidget();
- if (w) {
- NSView *view = qt_mac_effectiveview_for(w);
- if ([view isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]]) {
- QMacCocoaAutoReleasePool pool;
- QT_MANGLE_NAMESPACE(QCocoaView) *qc = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view);
- NSInputManager *currentIManager = [NSInputManager currentInputManager];
- if (currentIManager) {
- [currentIManager markedTextAbandoned:view];
- [qc unmarkText];
- }
- }
- }
-}
-
-bool QMacInputContext::isComposing() const
-{
- QWidget *w = QInputContext::focusWidget();
- if (w) {
- NSView *view = qt_mac_effectiveview_for(w);
- if ([view isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]]) {
- return [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view) isComposing];
- }
- }
- return false;
-}
-
-extern bool qt_mac_in_drag;
-void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm);
-static const int default_pm_hotx = -2;
-static const int default_pm_hoty = -16;
-static const char* default_pm[] = {
- "13 9 3 1",
- ". c None",
- " c #000000",
- "X c #FFFFFF",
- "X X X X X X X",
- " X X X X X X ",
- "X ......... X",
- " X.........X ",
- "X ......... X",
- " X.........X ",
- "X ......... X",
- " X X X X X X ",
- "X X X X X X X",
-};
-
-Qt::DropAction QDragManager::drag(QDrag *o)
-{
- if(qt_mac_in_drag) { //just make sure..
- qWarning("Qt: Internal error: WH0A, unexpected condition reached");
- return Qt::IgnoreAction;
- }
- if(object == o)
- return Qt::IgnoreAction;
- /* At the moment it seems clear that Mac OS X does not want to drag with a non-left button
- so we just bail early to prevent it */
- if(!(GetCurrentEventButtonState() & kEventMouseButtonPrimary))
- return Qt::IgnoreAction;
-
- if(object) {
- dragPrivate()->source->removeEventFilter(this);
- cancel();
- beingCancelled = false;
- }
-
- object = o;
- dragPrivate()->target = 0;
-
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(this, 0, QAccessible::DragDropStart);
-#endif
-
- // setup the data
- QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacPasteboardMime::MIME_DND);
- dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
- dragBoard.setMimeData(dragPrivate()->data);
-
- // create the image
- QPoint hotspot;
- QPixmap pix = dragPrivate()->pixmap;
- if(pix.isNull()) {
- if(dragPrivate()->data->hasText() || dragPrivate()->data->hasUrls()) {
- // get the string
- QString s = dragPrivate()->data->hasText() ? dragPrivate()->data->text()
- : dragPrivate()->data->urls().first().toString();
- if(s.length() > 26)
- s = s.left(23) + QChar(0x2026);
- if(!s.isEmpty()) {
- // draw it
- QFont f(qApp->font());
- f.setPointSize(12);
- QFontMetrics fm(f);
- QPixmap tmp(fm.width(s), fm.height());
- if(!tmp.isNull()) {
- QPainter p(&tmp);
- p.fillRect(0, 0, tmp.width(), tmp.height(), Qt::color0);
- p.setPen(Qt::color1);
- p.setFont(f);
- p.drawText(0, fm.ascent(), s);
- // save it
- pix = tmp;
- hotspot = QPoint(tmp.width() / 2, tmp.height() / 2);
- }
- }
- } else {
- pix = QPixmap(default_pm);
- hotspot = QPoint(default_pm_hotx, default_pm_hoty);
- }
- } else {
- hotspot = dragPrivate()->hotspot;
- }
-
- // Convert the image to NSImage:
- NSImage *image = (NSImage *)qt_mac_create_nsimage(pix);
- [image retain];
-
- DnDParams *dndParams = macCurrentDnDParameters();
- QT_MANGLE_NAMESPACE(QCocoaView) *theView = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(dndParams->view);
-
- // Save supported actions:
- [theView setSupportedActions: qt_mac_mapDropActions(dragPrivate()->possible_actions)];
- QPoint pointInView = [theView qt_qwidget]->mapFromGlobal(dndParams->globalPoint);
- NSPoint imageLoc = {pointInView.x() - hotspot.x(), pointInView.y() + pix.height() - hotspot.y()};
- NSSize mouseOffset = {0.0, 0.0};
- NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
- dragPrivate()->executed_action = Qt::ActionMask;
-
- // Execute the drag:
- [theView retain];
- [theView dragImage:image
- at:imageLoc
- offset:mouseOffset
- event:dndParams->theEvent
- pasteboard:pboard
- source:theView
- slideBack:YES];
-
- // Reset the implicit grab widget when drag ends because we will not
- // receive the mouse release event when DND is active:
- qt_button_down = 0;
- [theView release];
- [image release];
- if (dragPrivate())
- dragPrivate()->executed_action = Qt::IgnoreAction;
- object = 0;
- Qt::DropAction performedAction(qt_mac_mapNSDragOperation(dndParams->performedAction));
-
- // Do post drag processing, if required.
- if (performedAction != Qt::IgnoreAction) {
- // Check if the receiver points us to a file location.
- // if so, we need to do the file copy/move ourselves.
- QCFType<CFURLRef> pasteLocation = 0;
- PasteboardCopyPasteLocation(dragBoard.pasteBoard(), &pasteLocation);
- if (pasteLocation) {
- QList<QUrl> urls = o->mimeData()->urls();
- for (int i = 0; i < urls.size(); ++i) {
- QUrl fromUrl = urls.at(i);
- QString filename = QFileInfo(fromUrl.path()).fileName();
- QUrl toUrl(QCFString::toQString(CFURLGetString(pasteLocation)) + filename);
- if (performedAction == Qt::MoveAction)
- QFile::rename(fromUrl.path(), toUrl.path());
- else if (performedAction == Qt::CopyAction)
- QFile::copy(fromUrl.path(), toUrl.path());
- }
- }
- }
-
- // Clean-up:
- o->setMimeData(0);
- o->deleteLater();
- return performedAction;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_MAC_USE_COCOA