From fcabeb2e4758b2d39cfc82928a22f8afdf27ba50 Mon Sep 17 00:00:00 2001 From: Filipe Azevedo Date: Mon, 16 Mar 2015 10:52:05 +0100 Subject: QCocoaDrag: Fix text, url and image preview pixmap while dragging. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OSX was missing text, url and image preview while dragging causing the drag operation to show a small dashed box around the mouse cursor. Task-number: QTBUG-33824 Change-Id: I8d0acd0d6a48b7cb29ad2faba8b9ecb9cdf2a5ab Reviewed-by: Morten Johan Sørvig Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoadrag.h | 2 ++ src/plugins/platforms/cocoa/qcocoadrag.mm | 56 +++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoadrag.h b/src/plugins/platforms/cocoa/qcocoadrag.h index 058941939c..e087fcee26 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.h +++ b/src/plugins/platforms/cocoa/qcocoadrag.h @@ -67,6 +67,8 @@ private: NSEvent *m_lastEvent; NSView *m_lastView; Qt::DropAction m_executed_drop_action; + + QPixmap dragPixmap(QDrag *drag, QPoint &hotSpot) const; }; class QCocoaDropData : public QInternalMimeData diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm index a80b32a0b8..4466d28128 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -37,6 +37,8 @@ QT_BEGIN_NAMESPACE +static const int dragImageMaxChars = 26; + QCocoaDrag::QCocoaDrag() : m_drag(0) { @@ -116,10 +118,8 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o) m_drag = o; m_executed_drop_action = Qt::IgnoreAction; - QPixmap pm = m_drag->pixmap(); - if (pm.isNull()) - pm = defaultPixmap(); - + QPoint hotSpot = m_drag->hotSpot(); + QPixmap pm = dragPixmap(m_drag, hotSpot); NSImage *nsimage = qt_mac_create_nsimage(pm); QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND); @@ -128,8 +128,8 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o) 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.x -= hotSpot.x(); + CGFloat flippedY = pm.height() - hotSpot.y(); local_point.y += flippedY; NSSize mouseOffset = NSMakeSize(0.0, 0.0); NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; @@ -153,6 +153,50 @@ void QCocoaDrag::setAcceptedAction(Qt::DropAction act) m_executed_drop_action = act; } +QPixmap QCocoaDrag::dragPixmap(QDrag *drag, QPoint &hotSpot) const +{ + const QMimeData* data = drag->mimeData(); + QPixmap pm = drag->pixmap(); + + if (pm.isNull()) { + QFont f(qApp->font()); + f.setPointSize(12); + QFontMetrics fm(f); + + if (data->hasImage()) { + const QImage img = data->imageData().value(); + if (!img.isNull()) { + pm = QPixmap::fromImage(img).scaledToWidth(dragImageMaxChars *fm.averageCharWidth()); + } + } + + if (pm.isNull() && (data->hasText() || data->hasUrls()) ) { + QString s = data->hasText() ? data->text() : data->urls().first().toString(); + if (s.length() > dragImageMaxChars) + s = s.left(dragImageMaxChars -3) + QChar(0x2026); + if (!s.isEmpty()) { + const int width = fm.width(s); + const int height = fm.height(); + if (width > 0 && height > 0) { + pm = QPixmap(width, height); + QPainter p(&pm); + p.fillRect(0, 0, pm.width(), pm.height(), Qt::color0); + p.setPen(Qt::color1); + p.setFont(f); + p.drawText(0, fm.ascent(), s); + p.end(); + hotSpot = QPoint(pm.width() / 2, pm.height() / 2); + } + } + } + } + + if (pm.isNull()) + pm = defaultPixmap(); + + return pm; +} + QCocoaDropData::QCocoaDropData(NSPasteboard *pasteboard) { dropPasteboard = reinterpret_cast(const_cast([pasteboard name])); -- cgit v1.2.3