| 1 | /****************************************************************************
 | 
|---|
| 2 | **
 | 
|---|
| 3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
 | 
|---|
| 4 | ** Contact: Qt Software Information (qt-info@nokia.com)
 | 
|---|
| 5 | **
 | 
|---|
| 6 | ** This file is part of the QtGui module of the Qt Toolkit.
 | 
|---|
| 7 | **
 | 
|---|
| 8 | ** $QT_BEGIN_LICENSE:LGPL$
 | 
|---|
| 9 | ** Commercial Usage
 | 
|---|
| 10 | ** Licensees holding valid Qt Commercial licenses may use this file in
 | 
|---|
| 11 | ** accordance with the Qt Commercial License Agreement provided with the
 | 
|---|
| 12 | ** Software or, alternatively, in accordance with the terms contained in
 | 
|---|
| 13 | ** a written agreement between you and Nokia.
 | 
|---|
| 14 | **
 | 
|---|
| 15 | ** GNU Lesser General Public License Usage
 | 
|---|
| 16 | ** Alternatively, this file may be used under the terms of the GNU Lesser
 | 
|---|
| 17 | ** General Public License version 2.1 as published by the Free Software
 | 
|---|
| 18 | ** Foundation and appearing in the file LICENSE.LGPL included in the
 | 
|---|
| 19 | ** packaging of this file.  Please review the following information to
 | 
|---|
| 20 | ** ensure the GNU Lesser General Public License version 2.1 requirements
 | 
|---|
| 21 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
|---|
| 22 | **
 | 
|---|
| 23 | ** In addition, as a special exception, Nokia gives you certain
 | 
|---|
| 24 | ** additional rights. These rights are described in the Nokia Qt LGPL
 | 
|---|
| 25 | ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
 | 
|---|
| 26 | ** package.
 | 
|---|
| 27 | **
 | 
|---|
| 28 | ** GNU General Public License Usage
 | 
|---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU
 | 
|---|
| 30 | ** General Public License version 3.0 as published by the Free Software
 | 
|---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the
 | 
|---|
| 32 | ** packaging of this file.  Please review the following information to
 | 
|---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be
 | 
|---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html.
 | 
|---|
| 35 | **
 | 
|---|
| 36 | ** If you are unsure which license is appropriate for your use, please
 | 
|---|
| 37 | ** contact the sales department at qt-sales@nokia.com.
 | 
|---|
| 38 | ** $QT_END_LICENSE$
 | 
|---|
| 39 | **
 | 
|---|
| 40 | ****************************************************************************/
 | 
|---|
| 41 | 
 | 
|---|
| 42 | #include "qapplication.h"
 | 
|---|
| 43 | #ifndef QT_NO_DRAGANDDROP
 | 
|---|
| 44 | #include "qbitmap.h"
 | 
|---|
| 45 | #include "qcursor.h"
 | 
|---|
| 46 | #include "qevent.h"
 | 
|---|
| 47 | #include "qpainter.h"
 | 
|---|
| 48 | #include "qurl.h"
 | 
|---|
| 49 | #include "qwidget.h"
 | 
|---|
| 50 | #include "qfile.h"
 | 
|---|
| 51 | #include "qfileinfo.h"
 | 
|---|
| 52 | #include <stdlib.h>
 | 
|---|
| 53 | #include <string.h>
 | 
|---|
| 54 | #ifndef QT_NO_ACCESSIBILITY
 | 
|---|
| 55 | # include "qaccessible.h"
 | 
|---|
| 56 | #endif
 | 
|---|
| 57 | 
 | 
|---|
| 58 | #include <private/qapplication_p.h>
 | 
|---|
| 59 | #include <private/qwidget_p.h>
 | 
|---|
| 60 | #include <private/qdnd_p.h>
 | 
|---|
| 61 | #include <private/qt_mac_p.h>
 | 
|---|
| 62 | 
 | 
|---|
| 63 | QT_BEGIN_NAMESPACE
 | 
|---|
| 64 | 
 | 
|---|
| 65 | QT_USE_NAMESPACE
 | 
|---|
| 66 | 
 | 
|---|
| 67 | QMacDndAnswerRecord qt_mac_dnd_answer_rec; 
 | 
|---|
| 68 | 
 | 
|---|
| 69 | /*****************************************************************************
 | 
|---|
| 70 |   QDnD debug facilities
 | 
|---|
| 71 |  *****************************************************************************/
 | 
|---|
| 72 | //#define DEBUG_DRAG_EVENTS
 | 
|---|
| 73 | //#define DEBUG_DRAG_PROMISES
 | 
|---|
| 74 | 
 | 
|---|
| 75 | /*****************************************************************************
 | 
|---|
| 76 |   QDnD globals
 | 
|---|
| 77 |  *****************************************************************************/
 | 
|---|
| 78 | bool qt_mac_in_drag = false;
 | 
|---|
| 79 | #ifndef QT_MAC_USE_COCOA
 | 
|---|
| 80 | static DragReference qt_mac_current_dragRef = 0;
 | 
|---|
| 81 | #endif
 | 
|---|
| 82 | 
 | 
|---|
| 83 | /*****************************************************************************
 | 
|---|
| 84 |   Externals
 | 
|---|
| 85 |  *****************************************************************************/
 | 
|---|
| 86 | extern void qt_mac_send_modifiers_changed(quint32, QObject *); //qapplication_mac.cpp
 | 
|---|
| 87 | extern uint qGlobalPostedEventsCount(); //qapplication.cpp
 | 
|---|
| 88 | extern RgnHandle qt_mac_get_rgn(); // qregion_mac.cpp
 | 
|---|
| 89 | extern void qt_mac_dispose_rgn(RgnHandle); // qregion_mac.cpp
 | 
|---|
| 90 | /*****************************************************************************
 | 
|---|
| 91 |   QDnD utility functions
 | 
|---|
| 92 |  *****************************************************************************/
 | 
|---|
| 93 | 
 | 
|---|
| 94 | //default pixmap
 | 
|---|
| 95 | static const int default_pm_hotx = -2;
 | 
|---|
| 96 | static const int default_pm_hoty = -16;
 | 
|---|
| 97 | #ifndef QT_MAC_USE_COCOA
 | 
|---|
| 98 | static const char * const default_pm[] = {
 | 
|---|
| 99 |     "13 9 3 1",
 | 
|---|
| 100 |     ".      c None",
 | 
|---|
| 101 |     "       c #000000",
 | 
|---|
| 102 |     "X      c #FFFFFF",
 | 
|---|
| 103 |     "X X X X X X X",
 | 
|---|
| 104 |     " X X X X X X ",
 | 
|---|
| 105 |     "X ......... X",
 | 
|---|
| 106 |     " X.........X ",
 | 
|---|
| 107 |     "X ......... X",
 | 
|---|
| 108 |     " X.........X ",
 | 
|---|
| 109 |     "X ......... X",
 | 
|---|
| 110 |     " X X X X X X ",
 | 
|---|
| 111 |     "X X X X X X X",
 | 
|---|
| 112 | };
 | 
|---|
| 113 | #endif
 | 
|---|
| 114 | 
 | 
|---|
| 115 | //action management
 | 
|---|
| 116 | #ifdef DEBUG_DRAG_EVENTS
 | 
|---|
| 117 | # define MAP_MAC_ENUM(x) x, #x
 | 
|---|
| 118 | #else
 | 
|---|
| 119 | # define MAP_MAC_ENUM(x) x
 | 
|---|
| 120 | #endif
 | 
|---|
| 121 | struct mac_enum_mapper
 | 
|---|
| 122 | {
 | 
|---|
| 123 |     int mac_code;
 | 
|---|
| 124 |     int qt_code;
 | 
|---|
| 125 | #ifdef DEBUG_DRAG_EVENTS
 | 
|---|
| 126 |     char *qt_desc;
 | 
|---|
| 127 | #endif
 | 
|---|
| 128 | };
 | 
|---|
| 129 | #ifndef QT_MAC_USE_COCOA
 | 
|---|
| 130 | static mac_enum_mapper dnd_action_symbols[] = {
 | 
|---|
| 131 |     { kDragActionAlias, MAP_MAC_ENUM(Qt::LinkAction) },
 | 
|---|
| 132 |     { kDragActionMove, MAP_MAC_ENUM(Qt::MoveAction) },
 | 
|---|
| 133 |     { kDragActionGeneric, MAP_MAC_ENUM(Qt::CopyAction) },
 | 
|---|
| 134 |     { kDragActionCopy, MAP_MAC_ENUM(Qt::CopyAction) },
 | 
|---|
| 135 |     { 0, MAP_MAC_ENUM(0) }
 | 
|---|
| 136 | };
 | 
|---|
| 137 | static DragActions qt_mac_dnd_map_qt_actions(Qt::DropActions qActions)
 | 
|---|
| 138 | {
 | 
|---|
| 139 |     DragActions ret = kDragActionNothing;
 | 
|---|
| 140 |     for(int i = 0; dnd_action_symbols[i].qt_code; ++i) {
 | 
|---|
| 141 |         if(qActions & dnd_action_symbols[i].qt_code)
 | 
|---|
| 142 |             ret |= dnd_action_symbols[i].mac_code;
 | 
|---|
| 143 |     }
 | 
|---|
| 144 |     return ret;
 | 
|---|
| 145 | }
 | 
|---|
| 146 | static Qt::DropActions qt_mac_dnd_map_mac_actions(DragActions macActions)
 | 
|---|
| 147 | {
 | 
|---|
| 148 | #ifdef DEBUG_DRAG_EVENTS
 | 
|---|
| 149 |     qDebug("Converting DND ActionList: 0x%lx", macActions);
 | 
|---|
| 150 | #endif
 | 
|---|
| 151 |     Qt::DropActions ret = Qt::IgnoreAction;
 | 
|---|
| 152 |     for(int i = 0; dnd_action_symbols[i].qt_code; ++i) {
 | 
|---|
| 153 | #ifdef DEBUG_DRAG_EVENTS
 | 
|---|
| 154 |         qDebug(" %d) [%s] : %s", i, dnd_action_symbols[i].qt_desc,
 | 
|---|
| 155 |                 (macActions & dnd_action_symbols[i].mac_code) ? "true" : "false");
 | 
|---|
| 156 | #endif
 | 
|---|
| 157 |         if(macActions & dnd_action_symbols[i].mac_code)
 | 
|---|
| 158 |             ret |= Qt::DropAction(dnd_action_symbols[i].qt_code);
 | 
|---|
| 159 |     }
 | 
|---|
| 160 |     return ret;
 | 
|---|
| 161 | }
 | 
|---|
| 162 | static Qt::DropAction qt_mac_dnd_map_mac_default_action(DragActions macActions)
 | 
|---|
| 163 | {
 | 
|---|
| 164 |     static Qt::DropAction preferred_actions[] = { Qt::CopyAction, Qt::LinkAction, //in order
 | 
|---|
| 165 |         Qt::MoveAction, Qt::IgnoreAction };
 | 
|---|
| 166 |     Qt::DropAction ret = Qt::IgnoreAction;
 | 
|---|
| 167 |     const Qt::DropActions qtActions = qt_mac_dnd_map_mac_actions(macActions);
 | 
|---|
| 168 |     for(int i = 0; preferred_actions[i] != Qt::IgnoreAction; ++i) {
 | 
|---|
| 169 |         if(qtActions & preferred_actions[i]) {
 | 
|---|
| 170 |             ret = preferred_actions[i];
 | 
|---|
| 171 |             break;
 | 
|---|
| 172 |         }
 | 
|---|
| 173 |     }
 | 
|---|
| 174 | #ifdef DEBUG_DRAG_EVENTS
 | 
|---|
| 175 |     for(int i = 0; dnd_action_symbols[i].qt_code; ++i) {
 | 
|---|
| 176 |         if(dnd_action_symbols[i].qt_code == ret) {
 | 
|---|
| 177 |             qDebug("Got default action: %s [0x%lx]", dnd_action_symbols[i].qt_desc, macActions);
 | 
|---|
| 178 |             break;
 | 
|---|
| 179 |         }
 | 
|---|
| 180 |     }
 | 
|---|
| 181 | #endif
 | 
|---|
| 182 |     return ret;
 | 
|---|
| 183 | }
 | 
|---|
| 184 | static void qt_mac_dnd_update_action(DragReference dragRef) {
 | 
|---|
| 185 |     SInt16 modifiers;
 | 
|---|
| 186 |     GetDragModifiers(dragRef, &modifiers, 0, 0);
 | 
|---|
| 187 |     qt_mac_send_modifiers_changed(modifiers, qApp);
 | 
|---|
| 188 | 
 | 
|---|
| 189 |     Qt::DropAction qtAction = Qt::IgnoreAction;
 | 
|---|
| 190 |     {
 | 
|---|
| 191 |         DragActions macAllowed = kDragActionNothing;
 | 
|---|
| 192 |         GetDragDropAction(dragRef, &macAllowed);
 | 
|---|
| 193 |         Qt::DropActions qtAllowed = qt_mac_dnd_map_mac_actions(macAllowed);
 | 
|---|
| 194 |         qtAction = QDragManager::self()->defaultAction(qtAllowed, QApplication::keyboardModifiers());
 | 
|---|
| 195 | #if 1
 | 
|---|
| 196 |         if(!(qtAllowed & qtAction))
 | 
|---|
| 197 |             qtAction = qt_mac_dnd_map_mac_default_action(macAllowed);
 | 
|---|
| 198 | #endif
 | 
|---|
| 199 |     }
 | 
|---|
| 200 |     DragActions macAction = qt_mac_dnd_map_qt_actions(qtAction);
 | 
|---|
| 201 | 
 | 
|---|
| 202 |     DragActions currentActions;
 | 
|---|
| 203 |     GetDragDropAction(dragRef, ¤tActions);
 | 
|---|
| 204 |     if(currentActions != macAction) {
 | 
|---|
| 205 |         SetDragDropAction(dragRef, macAction);
 | 
|---|
| 206 |         QDragManager::self()->emitActionChanged(qtAction);
 | 
|---|
| 207 |     }
 | 
|---|
| 208 | }
 | 
|---|
| 209 | #endif // !QT_MAC_USE_COCOA
 | 
|---|
| 210 | 
 | 
|---|
| 211 | /*****************************************************************************
 | 
|---|
| 212 |   DnD functions
 | 
|---|
| 213 |  *****************************************************************************/
 | 
|---|
| 214 | bool QDropData::hasFormat_sys(const QString &mime) const
 | 
|---|
| 215 | {
 | 
|---|
| 216 | #ifndef QT_MAC_USE_COCOA
 | 
|---|
| 217 |     OSPasteboardRef board;
 | 
|---|
| 218 |     if(GetDragPasteboard(qt_mac_current_dragRef, &board) != noErr) {
 | 
|---|
| 219 |         qDebug("DnD: Cannot get PasteBoard!");
 | 
|---|
| 220 |         return false;
 | 
|---|
| 221 |     }
 | 
|---|
| 222 |     return QMacPasteboard(board, QMacPasteboardMime::MIME_DND).hasFormat(mime);
 | 
|---|
| 223 | #else
 | 
|---|
| 224 |     Q_UNUSED(mime);
 | 
|---|
| 225 |     return false;
 | 
|---|
| 226 | #endif // !QT_MAC_USE_COCOA
 | 
|---|
| 227 | }
 | 
|---|
| 228 | 
 | 
|---|
| 229 | QVariant QDropData::retrieveData_sys(const QString &mime, QVariant::Type type) const
 | 
|---|
| 230 | {
 | 
|---|
| 231 | #ifndef QT_MAC_USE_COCOA
 | 
|---|
| 232 |     OSPasteboardRef board;
 | 
|---|
| 233 |     if(GetDragPasteboard(qt_mac_current_dragRef, &board) != noErr) {
 | 
|---|
| 234 |         qDebug("DnD: Cannot get PasteBoard!");
 | 
|---|
| 235 |         return QVariant();
 | 
|---|
| 236 |     }
 | 
|---|
| 237 |     return QMacPasteboard(board, QMacPasteboardMime::MIME_DND).retrieveData(mime, type);
 | 
|---|
| 238 | #else
 | 
|---|
| 239 |     Q_UNUSED(mime);
 | 
|---|
| 240 |     Q_UNUSED(type);
 | 
|---|
| 241 |     return QVariant();
 | 
|---|
| 242 | #endif // !QT_MAC_USE_COCOA
 | 
|---|
| 243 | }
 | 
|---|
| 244 | 
 | 
|---|
| 245 | QStringList QDropData::formats_sys() const
 | 
|---|
| 246 | {
 | 
|---|
| 247 | #ifndef QT_MAC_USE_COCOA
 | 
|---|
| 248 |     OSPasteboardRef board;
 | 
|---|
| 249 |     if(GetDragPasteboard(qt_mac_current_dragRef, &board) != noErr) {
 | 
|---|
| 250 |         qDebug("DnD: Cannot get PasteBoard!");
 | 
|---|
| 251 |         return QStringList();
 | 
|---|
| 252 |     }
 | 
|---|
| 253 |     return QMacPasteboard(board, QMacPasteboardMime::MIME_DND).formats();
 | 
|---|
| 254 | #else
 | 
|---|
| 255 |     return QStringList();
 | 
|---|
| 256 | #endif
 | 
|---|
| 257 | }
 | 
|---|
| 258 | 
 | 
|---|
| 259 | void QDragManager::timerEvent(QTimerEvent*)
 | 
|---|
| 260 | {
 | 
|---|
| 261 | }
 | 
|---|
| 262 | 
 | 
|---|
| 263 | bool QDragManager::eventFilter(QObject *, QEvent *)
 | 
|---|
| 264 | {
 | 
|---|
| 265 |     return false;
 | 
|---|
| 266 | }
 | 
|---|
| 267 | 
 | 
|---|
| 268 | void QDragManager::updateCursor()
 | 
|---|
| 269 | {
 | 
|---|
| 270 | }
 | 
|---|
| 271 | 
 | 
|---|
| 272 | void QDragManager::cancel(bool)
 | 
|---|
| 273 | {
 | 
|---|
| 274 |     if(object) {
 | 
|---|
| 275 |         beingCancelled = true;
 | 
|---|
| 276 |         object = 0;
 | 
|---|
| 277 |     }
 | 
|---|
| 278 | #ifndef QT_NO_ACCESSIBILITY
 | 
|---|
| 279 |     QAccessible::updateAccessibility(this, 0, QAccessible::DragDropEnd);
 | 
|---|
| 280 | #endif
 | 
|---|
| 281 | }
 | 
|---|
| 282 | 
 | 
|---|
| 283 | void QDragManager::move(const QPoint &)
 | 
|---|
| 284 | {
 | 
|---|
| 285 | }
 | 
|---|
| 286 | 
 | 
|---|
| 287 | void QDragManager::drop()
 | 
|---|
| 288 | {
 | 
|---|
| 289 | }
 | 
|---|
| 290 | 
 | 
|---|
| 291 | /**
 | 
|---|
| 292 |     If a drop action is already set on the carbon event
 | 
|---|
| 293 |     (from e.g. an earlier enter event), we insert the same
 | 
|---|
| 294 |     action on the new Qt event that has yet to be sendt.
 | 
|---|
| 295 | */
 | 
|---|
| 296 | static inline bool qt_mac_set_existing_drop_action(const DragRef &dragRef, QDropEvent &event)
 | 
|---|
| 297 | {
 | 
|---|
| 298 | #ifndef QT_MAC_USE_COCOA
 | 
|---|
| 299 |     DragActions currentAction = kDragActionNothing;        
 | 
|---|
| 300 |     OSStatus err = GetDragDropAction(dragRef, ¤tAction);
 | 
|---|
| 301 |     if (err == noErr && currentAction != kDragActionNothing) {
 | 
|---|
| 302 |         // This looks a bit evil, but we only ever set one action, so it's OK.
 | 
|---|
| 303 |         event.setDropAction(Qt::DropAction(int(qt_mac_dnd_map_mac_actions(currentAction))));
 | 
|---|
| 304 |         return true;
 | 
|---|
| 305 |     }
 | 
|---|
| 306 | #else
 | 
|---|
| 307 |     Q_UNUSED(dragRef);
 | 
|---|
| 308 |     Q_UNUSED(event);
 | 
|---|
| 309 | #endif
 | 
|---|
| 310 |     return false;
 | 
|---|
| 311 | }
 | 
|---|
| 312 | 
 | 
|---|
| 313 | /**
 | 
|---|
| 314 |     If an answer rect has been set on the event (after being sent
 | 
|---|
| 315 |     to the global event processor), we store that rect so we can
 | 
|---|
| 316 |     check if the mouse is in the same area upon next drag move event. 
 | 
|---|
| 317 | */
 | 
|---|
| 318 | void qt_mac_copy_answer_rect(const QDragMoveEvent &event)
 | 
|---|
| 319 | {
 | 
|---|
| 320 |     if (!event.answerRect().isEmpty()) {
 | 
|---|
| 321 |         qt_mac_dnd_answer_rec.rect = event.answerRect();
 | 
|---|
| 322 |         qt_mac_dnd_answer_rec.buttons = event.mouseButtons();
 | 
|---|
| 323 |         qt_mac_dnd_answer_rec.modifiers = event.keyboardModifiers();
 | 
|---|
| 324 |         qt_mac_dnd_answer_rec.lastAction = event.dropAction();
 | 
|---|
| 325 |     }    
 | 
|---|
| 326 | }
 | 
|---|
| 327 | 
 | 
|---|
| 328 | bool qt_mac_mouse_inside_answer_rect(QPoint mouse)
 | 
|---|
| 329 | {
 | 
|---|
| 330 |     if (!qt_mac_dnd_answer_rec.rect.isEmpty()
 | 
|---|
| 331 |             && qt_mac_dnd_answer_rec.rect.contains(mouse)
 | 
|---|
| 332 |             && QApplication::mouseButtons() == qt_mac_dnd_answer_rec.buttons
 | 
|---|
| 333 |             && QApplication::keyboardModifiers() == qt_mac_dnd_answer_rec.modifiers)
 | 
|---|
| 334 |         return true;
 | 
|---|
| 335 |     else
 | 
|---|
| 336 |         return false;
 | 
|---|
| 337 | }
 | 
|---|
| 338 | 
 | 
|---|
| 339 | bool QWidgetPrivate::qt_mac_dnd_event(uint kind, DragRef dragRef)
 | 
|---|
| 340 | {
 | 
|---|
| 341 | #ifndef QT_MAC_USE_COCOA
 | 
|---|
| 342 |     Q_Q(QWidget);
 | 
|---|
| 343 |     qt_mac_current_dragRef = dragRef;
 | 
|---|
| 344 |     if (kind != kEventControlDragLeave)
 | 
|---|
| 345 |         qt_mac_dnd_update_action(dragRef);
 | 
|---|
| 346 | 
 | 
|---|
| 347 |     Point mouse;
 | 
|---|
| 348 |     GetDragMouse(dragRef, &mouse, 0L);
 | 
|---|
| 349 |     if(!mouse.h && !mouse.v)
 | 
|---|
| 350 |         GetGlobalMouse(&mouse);
 | 
|---|
| 351 | 
 | 
|---|
| 352 |     if(QApplicationPrivate::modalState()) {
 | 
|---|
| 353 |         for(QWidget *modal = q; modal; modal = modal->parentWidget()) {
 | 
|---|
| 354 |             if(modal->isWindow()) {
 | 
|---|
| 355 |                 if(modal != QApplication::activeModalWidget())
 | 
|---|
| 356 |                     return noErr;
 | 
|---|
| 357 |                 break;
 | 
|---|
| 358 |             }
 | 
|---|
| 359 |         }
 | 
|---|
| 360 |     }
 | 
|---|
| 361 | 
 | 
|---|
| 362 |     //lookup the possible actions
 | 
|---|
| 363 |     DragActions allowed = kDragActionNothing;
 | 
|---|
| 364 |     GetDragAllowableActions(dragRef, &allowed);
 | 
|---|
| 365 |     Qt::DropActions qtAllowed = qt_mac_dnd_map_mac_actions(allowed);
 | 
|---|
| 366 | 
 | 
|---|
| 367 |     //lookup the source dragAccepted 
 | 
|---|
| 368 |     QMimeData *dropdata = QDragManager::self()->dropData;
 | 
|---|
| 369 |     if(QDragManager::self()->source())
 | 
|---|
| 370 |         dropdata = QDragManager::self()->dragPrivate()->data;
 | 
|---|
| 371 | 
 | 
|---|
| 372 |     // 'interrestedInDrag' should end up being 'true' if a later drop
 | 
|---|
| 373 |     // will be accepted by the widget for the current mouse position 
 | 
|---|
| 374 |     bool interrestedInDrag = true;
 | 
|---|
| 375 | 
 | 
|---|
| 376 |     //Dispatch events
 | 
|---|
| 377 |     if (kind == kEventControlDragWithin) {
 | 
|---|
| 378 |         if (qt_mac_mouse_inside_answer_rect(q->mapFromGlobal(QPoint(mouse.h, mouse.v))))
 | 
|---|
| 379 |             return qt_mac_dnd_answer_rec.lastAction == Qt::IgnoreAction;
 | 
|---|
| 380 |         else
 | 
|---|
| 381 |             qt_mac_dnd_answer_rec.clear();
 | 
|---|
| 382 |         
 | 
|---|
| 383 |         QDragMoveEvent qDMEvent(q->mapFromGlobal(QPoint(mouse.h, mouse.v)), qtAllowed, dropdata,
 | 
|---|
| 384 |                 QApplication::mouseButtons(), QApplication::keyboardModifiers());
 | 
|---|
| 385 |                 
 | 
|---|
| 386 |         // Accept the event by default if a
 | 
|---|
| 387 |         // drag action exists on the carbon event
 | 
|---|
| 388 |         if (qt_mac_set_existing_drop_action(dragRef, qDMEvent))
 | 
|---|
| 389 |             qDMEvent.accept();
 | 
|---|
| 390 |             
 | 
|---|
| 391 |         QApplication::sendEvent(q, &qDMEvent);
 | 
|---|
| 392 |         if (!qDMEvent.isAccepted() || qDMEvent.dropAction() == Qt::IgnoreAction)
 | 
|---|
| 393 |             interrestedInDrag = false;
 | 
|---|
| 394 | 
 | 
|---|
| 395 |         qt_mac_copy_answer_rect(qDMEvent);
 | 
|---|
| 396 |         SetDragDropAction(dragRef, qt_mac_dnd_map_qt_actions(qDMEvent.dropAction()));
 | 
|---|
| 397 |         
 | 
|---|
| 398 |     } else if (kind == kEventControlDragEnter) {
 | 
|---|
| 399 |         qt_mac_dnd_answer_rec.clear();
 | 
|---|
| 400 |         
 | 
|---|
| 401 |         QDragEnterEvent qDEEvent(q->mapFromGlobal(QPoint(mouse.h, mouse.v)), qtAllowed, dropdata,
 | 
|---|
| 402 |                 QApplication::mouseButtons(), QApplication::keyboardModifiers());
 | 
|---|
| 403 |         qt_mac_set_existing_drop_action(dragRef, qDEEvent);                         
 | 
|---|
| 404 |         QApplication::sendEvent(q, &qDEEvent);
 | 
|---|
| 405 |         SetDragDropAction(dragRef, qt_mac_dnd_map_qt_actions(qDEEvent.dropAction()));
 | 
|---|
| 406 |         
 | 
|---|
| 407 |         if (!qDEEvent.isAccepted())
 | 
|---|
| 408 |             // The widget is simply not interrested in this
 | 
|---|
| 409 |             // drag. So tell carbon this by returning 'false'. We will then
 | 
|---|
| 410 |             // not receive any further move, drop or leave events for this widget.
 | 
|---|
| 411 |             return false;
 | 
|---|
| 412 |         else {
 | 
|---|
| 413 |             // Documentation states that a drag move event is sendt immidiatly after
 | 
|---|
| 414 |             // a drag enter event. So we do that. This will honor widgets overriding
 | 
|---|
| 415 |             // 'dragMoveEvent' only, and not 'dragEnterEvent' 
 | 
|---|
| 416 |             QDragMoveEvent qDMEvent(q->mapFromGlobal(QPoint(mouse.h, mouse.v)), qtAllowed, dropdata,
 | 
|---|
| 417 |                     QApplication::mouseButtons(), QApplication::keyboardModifiers());
 | 
|---|
| 418 |             qDMEvent.accept(); // accept by default, since enter event was accepted.
 | 
|---|
| 419 |             qDMEvent.setDropAction(qDEEvent.dropAction());         
 | 
|---|
| 420 |             QApplication::sendEvent(q, &qDMEvent);
 | 
|---|
| 421 |             if (!qDMEvent.isAccepted() || qDMEvent.dropAction() == Qt::IgnoreAction)
 | 
|---|
| 422 |                 interrestedInDrag = false;
 | 
|---|
| 423 |             
 | 
|---|
| 424 |             qt_mac_copy_answer_rect(qDMEvent);           
 | 
|---|
| 425 |             SetDragDropAction(dragRef, qt_mac_dnd_map_qt_actions(qDMEvent.dropAction()));
 | 
|---|
| 426 |         }
 | 
|---|
| 427 |         
 | 
|---|
| 428 |     } else if(kind == kEventControlDragLeave) {
 | 
|---|
| 429 |         QDragLeaveEvent de;
 | 
|---|
| 430 |         QApplication::sendEvent(q, &de);
 | 
|---|
| 431 |     } else if(kind == kEventControlDragReceive) {
 | 
|---|
| 432 |         QDropEvent de(q->mapFromGlobal(QPoint(mouse.h, mouse.v)), qtAllowed, dropdata,
 | 
|---|
| 433 |                       QApplication::mouseButtons(), QApplication::keyboardModifiers());
 | 
|---|
| 434 |         if(QDragManager::self()->object)
 | 
|---|
| 435 |             QDragManager::self()->dragPrivate()->target = q;
 | 
|---|
| 436 |         QApplication::sendEvent(q, &de);
 | 
|---|
| 437 |         if(!de.isAccepted()) {
 | 
|---|
| 438 |             interrestedInDrag = false;
 | 
|---|
| 439 |             SetDragDropAction(dragRef, kDragActionNothing);
 | 
|---|
| 440 |         } else {
 | 
|---|
| 441 |             if(QDragManager::self()->object)
 | 
|---|
| 442 |                 QDragManager::self()->dragPrivate()->executed_action = de.dropAction();
 | 
|---|
| 443 |             SetDragDropAction(dragRef, qt_mac_dnd_map_qt_actions(de.dropAction()));
 | 
|---|
| 444 |         }
 | 
|---|
| 445 |     }
 | 
|---|
| 446 | 
 | 
|---|
| 447 | #ifdef DEBUG_DRAG_EVENTS
 | 
|---|
| 448 |     {
 | 
|---|
| 449 |         const char *desc = 0;
 | 
|---|
| 450 |         switch(kind) {
 | 
|---|
| 451 |         case kEventControlDragWithin: desc = "DragMove"; break;
 | 
|---|
| 452 |         case kEventControlDragEnter: desc = "DragEnter"; break;
 | 
|---|
| 453 |         case kEventControlDragLeave: desc = "DragLeave"; break;
 | 
|---|
| 454 |         case kEventControlDragReceive: desc = "DragDrop"; break;
 | 
|---|
| 455 |         }
 | 
|---|
| 456 |         if(desc) {
 | 
|---|
| 457 |             QPoint pos(q->mapFromGlobal(QPoint(mouse.h, mouse.v)));
 | 
|---|
| 458 |             qDebug("Sending <%s>(%d, %d) event to %p(%s::%s) [%d] (%p)",
 | 
|---|
| 459 |                    desc, pos.x(), pos.y(), q, q->metaObject()->className(),
 | 
|---|
| 460 |                    q->objectName().toLocal8Bit().constData(), ret, dragRef);
 | 
|---|
| 461 |         }
 | 
|---|
| 462 |     }
 | 
|---|
| 463 | #endif
 | 
|---|
| 464 | 
 | 
|---|
| 465 |     //set the cursor
 | 
|---|
| 466 |     bool found_cursor = false;
 | 
|---|
| 467 |     if(kind == kEventControlDragWithin || kind == kEventControlDragEnter) {
 | 
|---|
| 468 |         ThemeCursor cursor = kThemeNotAllowedCursor;
 | 
|---|
| 469 |         found_cursor = true;
 | 
|---|
| 470 |         if (interrestedInDrag) {
 | 
|---|
| 471 |             DragActions action = kDragActionNothing;
 | 
|---|
| 472 |             GetDragDropAction(dragRef, &action);
 | 
|---|
| 473 |             switch(qt_mac_dnd_map_mac_default_action(action)) {
 | 
|---|
| 474 |             case Qt::IgnoreAction:
 | 
|---|
| 475 |                 cursor = kThemeNotAllowedCursor;
 | 
|---|
| 476 |                 break;
 | 
|---|
| 477 |             case Qt::MoveAction:
 | 
|---|
| 478 |                 cursor = kThemeArrowCursor;
 | 
|---|
| 479 |                 break;
 | 
|---|
| 480 |             case Qt::CopyAction:
 | 
|---|
| 481 |                 cursor = kThemeCopyArrowCursor;
 | 
|---|
| 482 |                 break;
 | 
|---|
| 483 |             case Qt::LinkAction:
 | 
|---|
| 484 |                 cursor = kThemeAliasArrowCursor;
 | 
|---|
| 485 |                 break;
 | 
|---|
| 486 |             default:
 | 
|---|
| 487 |                 cursor = kThemeNotAllowedCursor;
 | 
|---|
| 488 |                 break;
 | 
|---|
| 489 |             }
 | 
|---|
| 490 |         }
 | 
|---|
| 491 |         SetThemeCursor(cursor);
 | 
|---|
| 492 |     }
 | 
|---|
| 493 |     if(found_cursor) {
 | 
|---|
| 494 |         qt_mac_set_cursor(0, QPoint()); //just use our's
 | 
|---|
| 495 |     } else {
 | 
|---|
| 496 |         QCursor cursor(Qt::ArrowCursor);
 | 
|---|
| 497 |         if(qApp && qApp->overrideCursor()) {
 | 
|---|
| 498 |             cursor = *qApp->overrideCursor();
 | 
|---|
| 499 |         } else if(q) {
 | 
|---|
| 500 |             for(QWidget *p = q; p; p = p->parentWidget()) {
 | 
|---|
| 501 |                 if(p->isEnabled() && p->testAttribute(Qt::WA_SetCursor)) {
 | 
|---|
| 502 |                     cursor = p->cursor();
 | 
|---|
| 503 |                     break;
 | 
|---|
| 504 |                 }
 | 
|---|
| 505 |             }
 | 
|---|
| 506 |         }
 | 
|---|
| 507 |         qt_mac_set_cursor(&cursor, QPoint(mouse.h, mouse.v));
 | 
|---|
| 508 |     }
 | 
|---|
| 509 | 
 | 
|---|
| 510 |     //idle things
 | 
|---|
| 511 |     if(qGlobalPostedEventsCount()) {
 | 
|---|
| 512 |         QApplication::sendPostedEvents();
 | 
|---|
| 513 |         QApplication::flush();
 | 
|---|
| 514 |     }
 | 
|---|
| 515 |     
 | 
|---|
| 516 |     // If this was not a drop, tell carbon that we will be interresed in receiving more
 | 
|---|
| 517 |     // events for the current drag. We do that by returning true. 
 | 
|---|
| 518 |     if (kind == kEventControlDragReceive)
 | 
|---|
| 519 |         return interrestedInDrag;
 | 
|---|
| 520 |     else
 | 
|---|
| 521 |         return true;
 | 
|---|
| 522 | #else
 | 
|---|
| 523 |     Q_UNUSED(kind);
 | 
|---|
| 524 |     Q_UNUSED(dragRef);
 | 
|---|
| 525 |     return false;
 | 
|---|
| 526 | #endif // !QT_MAC_USE_COCOA
 | 
|---|
| 527 | }
 | 
|---|
| 528 | 
 | 
|---|
| 529 | #ifndef QT_MAC_USE_COCOA
 | 
|---|
| 530 | Qt::DropAction QDragManager::drag(QDrag *o)
 | 
|---|
| 531 | {
 | 
|---|
| 532 |   
 | 
|---|
| 533 |     if(qt_mac_in_drag) {     //just make sure..
 | 
|---|
| 534 |         qWarning("Qt: Internal error: WH0A, unexpected condition reached");
 | 
|---|
| 535 |         return Qt::IgnoreAction;
 | 
|---|
| 536 |     }
 | 
|---|
| 537 |     if(object == o)
 | 
|---|
| 538 |         return Qt::IgnoreAction;
 | 
|---|
| 539 |     /* At the moment it seems clear that Mac OS X does not want to drag with a non-left button
 | 
|---|
| 540 |        so we just bail early to prevent it */
 | 
|---|
| 541 |     if(!(GetCurrentEventButtonState() & kEventMouseButtonPrimary))
 | 
|---|
| 542 |         return Qt::IgnoreAction;
 | 
|---|
| 543 | 
 | 
|---|
| 544 |     if(object) {
 | 
|---|
| 545 |         dragPrivate()->source->removeEventFilter(this);
 | 
|---|
| 546 |         cancel();
 | 
|---|
| 547 |         beingCancelled = false;
 | 
|---|
| 548 |     }
 | 
|---|
| 549 | 
 | 
|---|
| 550 |     object = o;
 | 
|---|
| 551 |     dragPrivate()->target = 0;
 | 
|---|
| 552 | 
 | 
|---|
| 553 | #ifndef QT_NO_ACCESSIBILITY
 | 
|---|
| 554 |     QAccessible::updateAccessibility(this, 0, QAccessible::DragDropStart);
 | 
|---|
| 555 | #endif
 | 
|---|
| 556 | 
 | 
|---|
| 557 |     //setup the data
 | 
|---|
| 558 |     QMacPasteboard dragBoard(QMacPasteboardMime::MIME_DND);
 | 
|---|
| 559 |     dragBoard.setMimeData(dragPrivate()->data);
 | 
|---|
| 560 | 
 | 
|---|
| 561 |     //create the drag
 | 
|---|
| 562 |     OSErr result;
 | 
|---|
| 563 |     DragRef dragRef;
 | 
|---|
| 564 |     if((result = NewDragWithPasteboard(dragBoard.pasteBoard(), &dragRef)))
 | 
|---|
| 565 |         return Qt::IgnoreAction;
 | 
|---|
| 566 |     //setup the actions
 | 
|---|
| 567 |     DragActions possibleActions = qt_mac_dnd_map_qt_actions(dragPrivate()->possible_actions);
 | 
|---|
| 568 |     SetDragAllowableActions(dragRef, //local
 | 
|---|
| 569 |                             possibleActions,
 | 
|---|
| 570 |                             true);
 | 
|---|
| 571 |     SetDragAllowableActions(dragRef, //remote (same as local)
 | 
|---|
| 572 |                             possibleActions,
 | 
|---|
| 573 |                             false);
 | 
|---|
| 574 | 
 | 
|---|
| 575 | 
 | 
|---|
| 576 |     QPoint hotspot;
 | 
|---|
| 577 |     QPixmap pix = dragPrivate()->pixmap;
 | 
|---|
| 578 |     if(pix.isNull()) {
 | 
|---|
| 579 |         if(dragPrivate()->data->hasText() || dragPrivate()->data->hasUrls()) {
 | 
|---|
| 580 |             //get the string
 | 
|---|
| 581 |             QString s = dragPrivate()->data->hasText() ? dragPrivate()->data->text()
 | 
|---|
| 582 |                                                 : dragPrivate()->data->urls().first().toString();
 | 
|---|
| 583 |             if(s.length() > 26)
 | 
|---|
| 584 |                 s = s.left(23) + QChar(0x2026);
 | 
|---|
| 585 |             if(!s.isEmpty()) {
 | 
|---|
| 586 |                 //draw it
 | 
|---|
| 587 |                 QFont f(qApp->font());
 | 
|---|
| 588 |                 f.setPointSize(12);
 | 
|---|
| 589 |                 QFontMetrics fm(f);
 | 
|---|
| 590 |                 const int width = fm.width(s);
 | 
|---|
| 591 |                 const int height = fm.height();
 | 
|---|
| 592 |                 if(width > 0 && height > 0) {
 | 
|---|
| 593 |                     QPixmap tmp(width, height);
 | 
|---|
| 594 |                     QPainter p(&tmp);
 | 
|---|
| 595 |                     p.fillRect(0, 0, tmp.width(), tmp.height(), Qt::color0);
 | 
|---|
| 596 |                     p.setPen(Qt::color1);
 | 
|---|
| 597 |                     p.setFont(f);
 | 
|---|
| 598 |                     p.drawText(0, fm.ascent(), s);
 | 
|---|
| 599 |                     p.end();
 | 
|---|
| 600 |                     //save it
 | 
|---|
| 601 |                     pix = tmp;
 | 
|---|
| 602 |                     hotspot = QPoint(tmp.width() / 2, tmp.height() / 2);
 | 
|---|
| 603 |                 }
 | 
|---|
| 604 |             }
 | 
|---|
| 605 |         } else {
 | 
|---|
| 606 |             pix = QPixmap(default_pm);
 | 
|---|
| 607 |             hotspot = QPoint(default_pm_hotx, default_pm_hoty);
 | 
|---|
| 608 |         }
 | 
|---|
| 609 |     } else {
 | 
|---|
| 610 |         hotspot = dragPrivate()->hotspot;
 | 
|---|
| 611 |     }
 | 
|---|
| 612 | 
 | 
|---|
| 613 |     //so we must fake an event
 | 
|---|
| 614 |     EventRecord fakeEvent;
 | 
|---|
| 615 |     GetGlobalMouse(&(fakeEvent.where));
 | 
|---|
| 616 |     fakeEvent.message = 0;
 | 
|---|
| 617 |     fakeEvent.what = mouseDown;
 | 
|---|
| 618 |     fakeEvent.when = EventTimeToTicks(GetCurrentEventTime());
 | 
|---|
| 619 |     fakeEvent.modifiers = GetCurrentKeyModifiers();
 | 
|---|
| 620 |     if(GetCurrentEventButtonState() & 2)
 | 
|---|
| 621 |         fakeEvent.modifiers |= controlKey;
 | 
|---|
| 622 | 
 | 
|---|
| 623 |     //find the hotspot in relation to the pixmap
 | 
|---|
| 624 |     Point boundsPoint;
 | 
|---|
| 625 |     boundsPoint.h = fakeEvent.where.h - hotspot.x();
 | 
|---|
| 626 |     boundsPoint.v = fakeEvent.where.v - hotspot.y();
 | 
|---|
| 627 |     Rect boundsRect;
 | 
|---|
| 628 |     SetRect(&boundsRect, boundsPoint.h, boundsPoint.v, boundsPoint.h + pix.width(), boundsPoint.v + pix.height());
 | 
|---|
| 629 | 
 | 
|---|
| 630 |     //set the drag image
 | 
|---|
| 631 |     QRegion dragRegion(boundsPoint.h, boundsPoint.v, pix.width(), pix.height()), pixRegion;
 | 
|---|
| 632 |     if(!pix.isNull()) {
 | 
|---|
| 633 |         HIPoint hipoint = { -hotspot.x(), -hotspot.y() };
 | 
|---|
| 634 |         CGImageRef img = (CGImageRef)pix.macCGHandle();
 | 
|---|
| 635 |         SetDragImageWithCGImage(dragRef, img, &hipoint, 0);
 | 
|---|
| 636 |         CGImageRelease(img);
 | 
|---|
| 637 |     }
 | 
|---|
| 638 | 
 | 
|---|
| 639 |     SetDragItemBounds(dragRef, (ItemReference)1 , &boundsRect);
 | 
|---|
| 640 |     { //do the drag
 | 
|---|
| 641 |         qt_mac_in_drag = true;
 | 
|---|
| 642 |         qt_mac_dnd_update_action(dragRef);
 | 
|---|
| 643 |         result = TrackDrag(dragRef, &fakeEvent, QMacSmartQuickDrawRegion(dragRegion.toQDRgn()));
 | 
|---|
| 644 |         qt_mac_in_drag = false;
 | 
|---|
| 645 |     }
 | 
|---|
| 646 |     object = 0;
 | 
|---|
| 647 |     if(result == noErr) {
 | 
|---|
| 648 |         // Check if the receiver points us to
 | 
|---|
| 649 |         // a file location. If so, we need to do
 | 
|---|
| 650 |         // the file copy/move ourselves:
 | 
|---|
| 651 |         QCFType<CFURLRef> pasteLocation = 0;
 | 
|---|
| 652 |         PasteboardCopyPasteLocation(dragBoard.pasteBoard(), &pasteLocation);
 | 
|---|
| 653 |         if (pasteLocation){
 | 
|---|
| 654 |             Qt::DropAction action = o->d_func()->defaultDropAction;
 | 
|---|
| 655 |             if (action == Qt::IgnoreAction){
 | 
|---|
| 656 |                 if (o->d_func()->possible_actions & Qt::MoveAction)
 | 
|---|
| 657 |                     action = Qt::MoveAction;
 | 
|---|
| 658 |                 else if (o->d_func()->possible_actions & Qt::CopyAction)
 | 
|---|
| 659 |                     action = Qt::CopyAction;
 | 
|---|
| 660 |                 
 | 
|---|
| 661 |             }
 | 
|---|
| 662 |             bool atleastOne = false;
 | 
|---|
| 663 |             QList<QUrl> urls = o->mimeData()->urls();
 | 
|---|
| 664 |             for (int i = 0; i < urls.size(); ++i){
 | 
|---|
| 665 |                 QUrl fromUrl = urls.at(i);
 | 
|---|
| 666 |                 QString filename = QFileInfo(fromUrl.path()).fileName();
 | 
|---|
| 667 |                 QUrl toUrl(QCFString::toQString(CFURLGetString(pasteLocation)) + filename);
 | 
|---|
| 668 |                 if (action == Qt::MoveAction){
 | 
|---|
| 669 |                     if (QFile::rename(fromUrl.path(), toUrl.path()))
 | 
|---|
| 670 |                         atleastOne = true;
 | 
|---|
| 671 |                 } else if (action == Qt::CopyAction){
 | 
|---|
| 672 |                     if (QFile::copy(fromUrl.path(), toUrl.path()))
 | 
|---|
| 673 |                         atleastOne = true;
 | 
|---|
| 674 |                 }
 | 
|---|
| 675 |             }
 | 
|---|
| 676 |             if (atleastOne){
 | 
|---|
| 677 |                 DisposeDrag(dragRef);
 | 
|---|
| 678 |                 return action;
 | 
|---|
| 679 |             }
 | 
|---|
| 680 |         }
 | 
|---|
| 681 | 
 | 
|---|
| 682 |         DragActions ret = kDragActionNothing;
 | 
|---|
| 683 |         GetDragDropAction(dragRef, &ret);
 | 
|---|
| 684 |         DisposeDrag(dragRef); //cleanup
 | 
|---|
| 685 |         return qt_mac_dnd_map_mac_default_action(ret);
 | 
|---|
| 686 |     }
 | 
|---|
| 687 |     DisposeDrag(dragRef); //cleanup
 | 
|---|
| 688 |     return Qt::IgnoreAction;
 | 
|---|
| 689 | }
 | 
|---|
| 690 | #endif
 | 
|---|
| 691 | 
 | 
|---|
| 692 | void QDragManager::updatePixmap()
 | 
|---|
| 693 | {
 | 
|---|
| 694 | }
 | 
|---|
| 695 | 
 | 
|---|
| 696 | QCocoaDropData::QCocoaDropData(CFStringRef pasteboard)
 | 
|---|
| 697 |     : QInternalMimeData()
 | 
|---|
| 698 | {
 | 
|---|
| 699 |     NSString* pasteboardName = (NSString*)pasteboard;
 | 
|---|
| 700 |     [pasteboardName retain];
 | 
|---|
| 701 |     dropPasteboard = pasteboard;
 | 
|---|
| 702 | }
 | 
|---|
| 703 | 
 | 
|---|
| 704 | QCocoaDropData::~QCocoaDropData()
 | 
|---|
| 705 | {
 | 
|---|
| 706 |     NSString* pasteboardName = (NSString*)dropPasteboard;
 | 
|---|
| 707 |     [pasteboardName release];
 | 
|---|
| 708 | }
 | 
|---|
| 709 | 
 | 
|---|
| 710 | QStringList QCocoaDropData::formats_sys() const
 | 
|---|
| 711 | {
 | 
|---|
| 712 |     QStringList formats; 
 | 
|---|
| 713 |     OSPasteboardRef board;
 | 
|---|
| 714 |     if (PasteboardCreate(dropPasteboard, &board) != noErr) {
 | 
|---|
| 715 |         qDebug("DnD: Cannot get PasteBoard!");
 | 
|---|
| 716 |         return formats;
 | 
|---|
| 717 |     }
 | 
|---|
| 718 |     formats = QMacPasteboard(board, QMacPasteboardMime::MIME_DND).formats();
 | 
|---|
| 719 |     return formats;
 | 
|---|
| 720 | }
 | 
|---|
| 721 | 
 | 
|---|
| 722 | QVariant QCocoaDropData::retrieveData_sys(const QString &mimeType, QVariant::Type type) const
 | 
|---|
| 723 | {
 | 
|---|
| 724 |     QVariant data;
 | 
|---|
| 725 |     OSPasteboardRef board;
 | 
|---|
| 726 |     if (PasteboardCreate(dropPasteboard, &board) != noErr) {
 | 
|---|
| 727 |         qDebug("DnD: Cannot get PasteBoard!");
 | 
|---|
| 728 |         return data;
 | 
|---|
| 729 |     }
 | 
|---|
| 730 |     data = QMacPasteboard(board, QMacPasteboardMime::MIME_DND).retrieveData(mimeType, type);
 | 
|---|
| 731 |     CFRelease(board);
 | 
|---|
| 732 |     return data;
 | 
|---|
| 733 | }
 | 
|---|
| 734 | 
 | 
|---|
| 735 | bool QCocoaDropData::hasFormat_sys(const QString &mimeType) const
 | 
|---|
| 736 | {
 | 
|---|
| 737 |     bool has = false;
 | 
|---|
| 738 |     OSPasteboardRef board;
 | 
|---|
| 739 |     if (PasteboardCreate(dropPasteboard, &board) != noErr) {
 | 
|---|
| 740 |         qDebug("DnD: Cannot get PasteBoard!");
 | 
|---|
| 741 |         return has;
 | 
|---|
| 742 |     }
 | 
|---|
| 743 |     has = QMacPasteboard(board, QMacPasteboardMime::MIME_DND).hasFormat(mimeType);
 | 
|---|
| 744 |     CFRelease(board);
 | 
|---|
| 745 |     return has;
 | 
|---|
| 746 | }
 | 
|---|
| 747 | 
 | 
|---|
| 748 | #endif // QT_NO_DRAGANDDROP
 | 
|---|
| 749 | QT_END_NAMESPACE
 | 
|---|