src/gui/kernel/qcocoaview_mac.mm
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
--- a/src/gui/kernel/qcocoaview_mac.mm	Tue Jul 06 15:10:48 2010 +0300
+++ b/src/gui/kernel/qcocoaview_mac.mm	Wed Aug 18 10:37:55 2010 +0300
@@ -269,6 +269,28 @@
     dropData = new QCocoaDropData(dropPasteboard);
 }
 
+- (void)changeDraggingCursor:(NSDragOperation)newOperation
+{
+    static SEL action = nil;
+    static bool operationSupported = false;
+    if (action == nil) {
+        action = NSSelectorFromString(@"operationNotAllowedCursor");
+        if ([NSCursor respondsToSelector:action]) {
+            operationSupported = true;
+        }
+    }
+    if (operationSupported) {
+        NSCursor *notAllowedCursor = [NSCursor performSelector:action];
+        bool isNotAllowedCursor = ([NSCursor currentCursor] == notAllowedCursor);
+        if (newOperation == NSDragOperationNone && !isNotAllowedCursor) {
+            [notAllowedCursor push];
+        } else if (newOperation != NSDragOperationNone && isNotAllowedCursor) {
+            [notAllowedCursor pop];
+        }
+
+    }
+}
+
 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
 {
     // NB: This function is called from QCoocaWindow/QCocoaPanel rather than directly
@@ -300,6 +322,7 @@
     if (!qDEEvent.isAccepted()) {
         // widget is not interested in this drag, so ignore this drop data.
         [self removeDropData];
+        [self changeDraggingCursor:NSDragOperationNone];
         return NSDragOperationNone;
     } else {
         // save the mouse position, used by draggingExited handler.
@@ -321,6 +344,7 @@
             nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDMEvent.dropAction());
         }
         QT_PREPEND_NAMESPACE(qt_mac_copy_answer_rect)(qDMEvent);
+        [self changeDraggingCursor:nsActions];
         return nsActions;
     }
  }
@@ -335,16 +359,21 @@
     if (dragEnterSequence != [sender draggingSequenceNumber])
         [self draggingEntered:sender];
     // drag enter event was rejected, so ignore the move event.
-    if (dropData == 0)
+    if (dropData == 0) {
+        [self changeDraggingCursor:NSDragOperationNone];
         return NSDragOperationNone;
+    }
     // return last value, if we are still in the answerRect.
     NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
     NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
     NSDragOperation nsActions = [sender draggingSourceOperationMask];
     QPoint posDrag(localPoint.x, localPoint.y);
     if (qt_mac_mouse_inside_answer_rect(posDrag)
-        && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions)
-        return QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction));
+        && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions) {
+        NSDragOperation operation = QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction));
+        [self changeDraggingCursor:operation];
+        return operation;
+    }
     // send drag move event to the widget
     QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions;
     Qt::DropActions qtAllowed = QT_PREPEND_NAMESPACE(qt_mac_mapNSDragOperations)(nsActions);
@@ -361,7 +390,10 @@
     if (QDragManager::self()->source())
         mimeData = QDragManager::self()->dragPrivate()->data;
     QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
-    qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction);
+    if (QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction != Qt::IgnoreAction
+        && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).buttons == qDMEvent.mouseButtons()
+        && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).modifiers == qDMEvent.keyboardModifiers())
+        qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction);
     qDMEvent.accept();
     QApplication::sendEvent(qwidget, &qDMEvent);
 
@@ -373,6 +405,7 @@
         qDMEvent.setDropAction(Qt::IgnoreAction);
     }
     qt_mac_copy_answer_rect(qDMEvent);
+    [self changeDraggingCursor:operation];
     return operation;
 }
 
@@ -388,6 +421,8 @@
         QApplication::sendEvent(qwidget, &de);
         [self removeDropData];
     }
+    [self changeDraggingCursor:NSDragOperationEvery];
+
 }
 
 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
@@ -952,12 +987,14 @@
     if (!QApplicationPrivate::tryModalHelper(qwidget, 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(qwidget, &qNGEvent);
+#endif // QT_NO_GESTURES
 }
 
 - (void)rotateWithEvent:(NSEvent *)event;
@@ -965,12 +1002,14 @@
     if (!QApplicationPrivate::tryModalHelper(qwidget, 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(qwidget, &qNGEvent);
+#endif // QT_NO_GESTURES
 }
 
 - (void)swipeWithEvent:(NSEvent *)event;
@@ -978,6 +1017,7 @@
     if (!QApplicationPrivate::tryModalHelper(qwidget, 0))
         return;
 
+#ifndef QT_NO_GESTURES
     QNativeGestureEvent qNGEvent;
     qNGEvent.gestureType = QNativeGestureEvent::Swipe;
     NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]];
@@ -991,6 +1031,7 @@
     else if ([event deltaY] == -1)
         qNGEvent.angle = 270.0f;
     qt_sendSpontaneousEvent(qwidget, &qNGEvent);
+#endif // QT_NO_GESTURES
 }
 
 - (void)beginGestureWithEvent:(NSEvent *)event;
@@ -998,11 +1039,13 @@
     if (!QApplicationPrivate::tryModalHelper(qwidget, 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(qwidget, &qNGEvent);
+#endif // QT_NO_GESTURES
 }
 
 - (void)endGestureWithEvent:(NSEvent *)event;
@@ -1010,11 +1053,13 @@
     if (!QApplicationPrivate::tryModalHelper(qwidget, 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(qwidget, &qNGEvent);
+#endif // QT_NO_GESTURES
 }
 
 - (void)frameDidChange:(NSNotification *)note
@@ -1577,6 +1622,8 @@
             }
         }
     }
+    o->setMimeData(0);
+    o->deleteLater();
     return performedAction;
 }