summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoadrag.mm
diff options
context:
space:
mode:
authorJames Turner <james.turner@kdab.com>2012-06-20 15:01:56 +0200
committerQt by Nokia <qt-info@nokia.com>2012-07-04 18:00:41 +0200
commit76b1df303237c1bd37e4b822f44686980e66b73f (patch)
tree46dcd5ef12228319ec9ee394dde08b977b7a35ea /src/plugins/platforms/cocoa/qcocoadrag.mm
parenta8fb38f230da9a7afc3dbace6fa45c33dc58b4a6 (diff)
Native drag implementation on Mac
Create a native implementation of QCocoaDrag, using the 10.6 (and earlier) Cocoa dragging API. This matches the implementation in Qt4 closely for the moment. In the future it may be desirable to create an alternative implementation using the new (non-blocking) drag API introduced in 10.7, but that will require deeper changes to the mime-data handling. This changes makes one more method on QPlatformDrag virtual, since the Cocoa behaviour diverges from the base version: ::defaultAction is customised. Change-Id: I1843293a62b2b4973a07b5e75ea3c312dc064018 Reviewed-by: Christoph Schleifenbaum <christoph.schleifenbaum@kdab.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com> Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoadrag.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index c596e3fdbb..59db986667 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -42,9 +42,114 @@
#include "qcocoadrag.h"
#include "qmacmime.h"
#include "qmacclipboard.h"
+#include "qcocoahelpers.h"
QT_BEGIN_NAMESPACE
+QCocoaDrag::QCocoaDrag() :
+ m_drag(0)
+{
+ m_lastEvent = 0;
+ m_lastView = 0;
+}
+
+void QCocoaDrag::setLastMouseEvent(NSEvent *event, NSView *view)
+{
+ m_lastEvent = event;
+ m_lastView = view;
+}
+
+QMimeData *QCocoaDrag::platformDropData()
+{
+ if (m_drag)
+ return m_drag->mimeData();
+
+ return 0;
+}
+
+Qt::DropAction QCocoaDrag::defaultAction(Qt::DropActions possibleActions,
+ Qt::KeyboardModifiers modifiers) const
+{
+ Qt::DropAction default_action = Qt::IgnoreAction;
+
+ if (currentDrag()) {
+ default_action = currentDrag()->defaultAction();
+ possibleActions = currentDrag()->supportedActions();
+ }
+
+ if (default_action == Qt::IgnoreAction) {
+ //This means that the drag was initiated by QDrag::start and we need to
+ //preserve the old behavior
+ default_action = Qt::CopyAction;
+ }
+
+ if (modifiers & Qt::ControlModifier && modifiers & Qt::AltModifier)
+ default_action = Qt::LinkAction;
+ else if (modifiers & Qt::AltModifier)
+ default_action = Qt::CopyAction;
+ else if (modifiers & Qt::ControlModifier)
+ default_action = Qt::MoveAction;
+
+#ifdef QDND_DEBUG
+ qDebug("possible actions : %s", dragActionsToString(possibleActions).latin1());
+#endif
+
+ // Check if the action determined is allowed
+ if (!(possibleActions & default_action)) {
+ if (possibleActions & Qt::CopyAction)
+ default_action = Qt::CopyAction;
+ else if (possibleActions & Qt::MoveAction)
+ default_action = Qt::MoveAction;
+ else if (possibleActions & Qt::LinkAction)
+ default_action = Qt::LinkAction;
+ else
+ default_action = Qt::IgnoreAction;
+ }
+
+#ifdef QDND_DEBUG
+ qDebug("default action : %s", dragActionsToString(default_action).latin1());
+#endif
+
+ return default_action;
+}
+
+
+Qt::DropAction QCocoaDrag::drag(QDrag *o)
+{
+ m_drag = o;
+ m_executed_drop_action = Qt::IgnoreAction;
+
+ NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(m_drag->pixmap()));
+
+ QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacPasteboardMime::MIME_DND);
+ m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
+ dragBoard.setMimeData(m_drag->mimeData());
+
+ NSPoint event_location = [m_lastEvent locationInWindow];
+ NSPoint local_point = [m_lastView convertPoint:event_location fromView:nil];
+ local_point.x -= m_drag->hotSpot().x();
+ CGFloat flippedY = m_drag->pixmap().height() - m_drag->hotSpot().y();
+ local_point.y += flippedY;
+ NSSize mouseOffset = NSMakeSize(0.0, 0.0);
+ NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
+
+ [m_lastView dragImage:nsimage
+ at:local_point
+ offset:mouseOffset
+ event:m_lastEvent
+ pasteboard:pboard
+ source:m_lastView
+ slideBack:YES];
+
+ m_drag = 0;
+ return m_executed_drop_action;
+}
+
+void QCocoaDrag::setAcceptedAction(Qt::DropAction act)
+{
+ m_executed_drop_action = act;
+}
+
QCocoaDropData::QCocoaDropData(NSPasteboard *pasteboard)
{
dropPasteboard = reinterpret_cast<CFStringRef>(const_cast<const NSString *>([pasteboard name]));