src/gui/kernel/qdnd.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qplatformdefs.h"
       
    43 
       
    44 #include "qbitmap.h"
       
    45 #include "qdrag.h"
       
    46 #include "qpixmap.h"
       
    47 #include "qevent.h"
       
    48 #include "qfile.h"
       
    49 #include "qtextcodec.h"
       
    50 #include "qapplication.h"
       
    51 #include "qpoint.h"
       
    52 #include "qwidget.h"
       
    53 #include "qbuffer.h"
       
    54 #include "qimage.h"
       
    55 #include "qregexp.h"
       
    56 #include "qdir.h"
       
    57 #include "qdnd_p.h"
       
    58 #include "qimagereader.h"
       
    59 #include "qimagewriter.h"
       
    60 #include "qdebug.h"
       
    61 #include <ctype.h>
       
    62 
       
    63 #ifndef QT_NO_DRAGANDDROP
       
    64 
       
    65 QT_BEGIN_NAMESPACE
       
    66 
       
    67 // These pixmaps approximate the images in the Windows User Interface Guidelines.
       
    68 
       
    69 // XPM
       
    70 
       
    71 static const char * const move_xpm[] = {
       
    72 "11 20 3 1",
       
    73 ".        c None",
       
    74 #if defined(Q_WS_WIN)
       
    75 "a        c #000000",
       
    76 "X        c #FFFFFF", // Windows cursor is traditionally white
       
    77 #else
       
    78 "a        c #FFFFFF",
       
    79 "X        c #000000", // X11 cursor is traditionally black
       
    80 #endif
       
    81 "aa.........",
       
    82 "aXa........",
       
    83 "aXXa.......",
       
    84 "aXXXa......",
       
    85 "aXXXXa.....",
       
    86 "aXXXXXa....",
       
    87 "aXXXXXXa...",
       
    88 "aXXXXXXXa..",
       
    89 "aXXXXXXXXa.",
       
    90 "aXXXXXXXXXa",
       
    91 "aXXXXXXaaaa",
       
    92 "aXXXaXXa...",
       
    93 "aXXaaXXa...",
       
    94 "aXa..aXXa..",
       
    95 "aa...aXXa..",
       
    96 "a.....aXXa.",
       
    97 "......aXXa.",
       
    98 ".......aXXa",
       
    99 ".......aXXa",
       
   100 "........aa."};
       
   101 
       
   102 #ifdef Q_WS_WIN
       
   103 /* XPM */
       
   104 static const char * const ignore_xpm[] = {
       
   105 "24 30 3 1",
       
   106 ".        c None",
       
   107 "a        c #000000",
       
   108 "X        c #FFFFFF",
       
   109 "aa......................",
       
   110 "aXa.....................",
       
   111 "aXXa....................",
       
   112 "aXXXa...................",
       
   113 "aXXXXa..................",
       
   114 "aXXXXXa.................",
       
   115 "aXXXXXXa................",
       
   116 "aXXXXXXXa...............",
       
   117 "aXXXXXXXXa..............",
       
   118 "aXXXXXXXXXa.............",
       
   119 "aXXXXXXaaaa.............",
       
   120 "aXXXaXXa................",
       
   121 "aXXaaXXa................",
       
   122 "aXa..aXXa...............",
       
   123 "aa...aXXa...............",
       
   124 "a.....aXXa..............",
       
   125 "......aXXa.....XXXX.....",
       
   126 ".......aXXa..XXaaaaXX...",
       
   127 ".......aXXa.XaaaaaaaaX..",
       
   128 "........aa.XaaaXXXXaaaX.",
       
   129 "...........XaaaaX..XaaX.",
       
   130 "..........XaaXaaaX..XaaX",
       
   131 "..........XaaXXaaaX.XaaX",
       
   132 "..........XaaX.XaaaXXaaX",
       
   133 "..........XaaX..XaaaXaaX",
       
   134 "...........XaaX..XaaaaX.",
       
   135 "...........XaaaXXXXaaaX.",
       
   136 "............XaaaaaaaaX..",
       
   137 ".............XXaaaaXX...",
       
   138 "...............XXXX....."};
       
   139 #endif
       
   140 
       
   141 /* XPM */
       
   142 static const char * const copy_xpm[] = {
       
   143 "24 30 3 1",
       
   144 ".        c None",
       
   145 "a        c #000000",
       
   146 "X        c #FFFFFF",
       
   147 #if defined(Q_WS_WIN) // Windows cursor is traditionally white
       
   148 "aa......................",
       
   149 "aXa.....................",
       
   150 "aXXa....................",
       
   151 "aXXXa...................",
       
   152 "aXXXXa..................",
       
   153 "aXXXXXa.................",
       
   154 "aXXXXXXa................",
       
   155 "aXXXXXXXa...............",
       
   156 "aXXXXXXXXa..............",
       
   157 "aXXXXXXXXXa.............",
       
   158 "aXXXXXXaaaa.............",
       
   159 "aXXXaXXa................",
       
   160 "aXXaaXXa................",
       
   161 "aXa..aXXa...............",
       
   162 "aa...aXXa...............",
       
   163 "a.....aXXa..............",
       
   164 "......aXXa..............",
       
   165 ".......aXXa.............",
       
   166 ".......aXXa.............",
       
   167 "........aa...aaaaaaaaaaa",
       
   168 #else
       
   169 "XX......................",
       
   170 "XaX.....................",
       
   171 "XaaX....................",
       
   172 "XaaaX...................",
       
   173 "XaaaaX..................",
       
   174 "XaaaaaX.................",
       
   175 "XaaaaaaX................",
       
   176 "XaaaaaaaX...............",
       
   177 "XaaaaaaaaX..............",
       
   178 "XaaaaaaaaaX.............",
       
   179 "XaaaaaaXXXX.............",
       
   180 "XaaaXaaX................",
       
   181 "XaaXXaaX................",
       
   182 "XaX..XaaX...............",
       
   183 "XX...XaaX...............",
       
   184 "X.....XaaX..............",
       
   185 "......XaaX..............",
       
   186 ".......XaaX.............",
       
   187 ".......XaaX.............",
       
   188 "........XX...aaaaaaaaaaa",
       
   189 #endif
       
   190 ".............aXXXXXXXXXa",
       
   191 ".............aXXXXXXXXXa",
       
   192 ".............aXXXXaXXXXa",
       
   193 ".............aXXXXaXXXXa",
       
   194 ".............aXXaaaaaXXa",
       
   195 ".............aXXXXaXXXXa",
       
   196 ".............aXXXXaXXXXa",
       
   197 ".............aXXXXXXXXXa",
       
   198 ".............aXXXXXXXXXa",
       
   199 ".............aaaaaaaaaaa"};
       
   200 
       
   201 /* XPM */
       
   202 static const char * const link_xpm[] = {
       
   203 "24 30 3 1",
       
   204 ".        c None",
       
   205 "a        c #000000",
       
   206 "X        c #FFFFFF",
       
   207 #if defined(Q_WS_WIN) // Windows cursor is traditionally white
       
   208 "aa......................",
       
   209 "aXa.....................",
       
   210 "aXXa....................",
       
   211 "aXXXa...................",
       
   212 "aXXXXa..................",
       
   213 "aXXXXXa.................",
       
   214 "aXXXXXXa................",
       
   215 "aXXXXXXXa...............",
       
   216 "aXXXXXXXXa..............",
       
   217 "aXXXXXXXXXa.............",
       
   218 "aXXXXXXaaaa.............",
       
   219 "aXXXaXXa................",
       
   220 "aXXaaXXa................",
       
   221 "aXa..aXXa...............",
       
   222 "aa...aXXa...............",
       
   223 "a.....aXXa..............",
       
   224 "......aXXa..............",
       
   225 ".......aXXa.............",
       
   226 ".......aXXa.............",
       
   227 "........aa...aaaaaaaaaaa",
       
   228 #else
       
   229 "XX......................",
       
   230 "XaX.....................",
       
   231 "XaaX....................",
       
   232 "XaaaX...................",
       
   233 "XaaaaX..................",
       
   234 "XaaaaaX.................",
       
   235 "XaaaaaaX................",
       
   236 "XaaaaaaaX...............",
       
   237 "XaaaaaaaaX..............",
       
   238 "XaaaaaaaaaX.............",
       
   239 "XaaaaaaXXXX.............",
       
   240 "XaaaXaaX................",
       
   241 "XaaXXaaX................",
       
   242 "XaX..XaaX...............",
       
   243 "XX...XaaX...............",
       
   244 "X.....XaaX..............",
       
   245 "......XaaX..............",
       
   246 ".......XaaX.............",
       
   247 ".......XaaX.............",
       
   248 "........XX...aaaaaaaaaaa",
       
   249 #endif
       
   250 ".............aXXXXXXXXXa",
       
   251 ".............aXXXaaaaXXa",
       
   252 ".............aXXXXaaaXXa",
       
   253 ".............aXXXaaaaXXa",
       
   254 ".............aXXaaaXaXXa",
       
   255 ".............aXXaaXXXXXa",
       
   256 ".............aXXaXXXXXXa",
       
   257 ".............aXXXaXXXXXa",
       
   258 ".............aXXXXXXXXXa",
       
   259 ".............aaaaaaaaaaa"};
       
   260 
       
   261 #ifndef QT_NO_DRAGANDDROP
       
   262 
       
   263 //#define QDND_DEBUG
       
   264 
       
   265 #ifdef QDND_DEBUG
       
   266 QString dragActionsToString(Qt::DropActions actions)
       
   267 {
       
   268     QString str;
       
   269     if (actions == Qt::IgnoreAction) {
       
   270         if (!str.isEmpty())
       
   271             str += " | ";
       
   272         str += "IgnoreAction";
       
   273     }
       
   274     if (actions & Qt::LinkAction) {
       
   275         if (!str.isEmpty())
       
   276             str += " | ";
       
   277         str += "LinkAction";
       
   278     }
       
   279     if (actions & Qt::CopyAction) {
       
   280         if (!str.isEmpty())
       
   281             str += " | ";
       
   282         str += "CopyAction";
       
   283     }
       
   284     if (actions & Qt::MoveAction) {
       
   285         if (!str.isEmpty())
       
   286             str += " | ";
       
   287         str += "MoveAction";
       
   288     }
       
   289     if ((actions & Qt::TargetMoveAction) == Qt::TargetMoveAction ) {
       
   290         if (!str.isEmpty())
       
   291             str += " | ";
       
   292         str += "TargetMoveAction";
       
   293     }
       
   294     return str;
       
   295 }
       
   296 
       
   297 QString KeyboardModifiersToString(Qt::KeyboardModifiers moderfies)
       
   298 {
       
   299     QString str;
       
   300     if (moderfies & Qt::ControlModifier) {
       
   301         if (!str.isEmpty())
       
   302             str += " | ";
       
   303         str += Qt::ControlModifier;
       
   304     }
       
   305     if (moderfies & Qt::AltModifier) {
       
   306         if (!str.isEmpty())
       
   307             str += " | ";
       
   308         str += Qt::AltModifier;
       
   309     }
       
   310     if (moderfies & Qt::ShiftModifier) {
       
   311         if (!str.isEmpty())
       
   312             str += " | ";
       
   313         str += Qt::ShiftModifier;
       
   314     }
       
   315     return str;
       
   316 }
       
   317 #endif
       
   318 
       
   319 
       
   320 // the universe's only drag manager
       
   321 QDragManager *QDragManager::instance = 0;
       
   322 
       
   323 
       
   324 QDragManager::QDragManager()
       
   325     : QObject(qApp)
       
   326 {
       
   327     Q_ASSERT(!instance);
       
   328 
       
   329 #ifdef Q_WS_WIN
       
   330     n_cursor = 4;
       
   331 #else
       
   332     n_cursor = 3;
       
   333 #endif
       
   334 
       
   335 #ifdef Q_WS_QWS
       
   336     currentActionForOverrideCursor = Qt::IgnoreAction;
       
   337 #endif
       
   338     pm_cursor = new QPixmap[n_cursor];
       
   339     pm_cursor[0] = QPixmap((const char **)move_xpm);
       
   340     pm_cursor[1] = QPixmap((const char **)copy_xpm);
       
   341     pm_cursor[2] = QPixmap((const char **)link_xpm);
       
   342 #ifdef Q_WS_WIN
       
   343     pm_cursor[3] = QPixmap((const char **)ignore_xpm);
       
   344 #endif
       
   345     object = 0;
       
   346     beingCancelled = false;
       
   347     restoreCursor = false;
       
   348     willDrop = false;
       
   349     eventLoop = 0;
       
   350     dropData = new QDropData();
       
   351     currentDropTarget = 0;
       
   352 #ifdef Q_WS_X11
       
   353     xdndMimeTransferedPixmapIndex = 0;
       
   354 #endif
       
   355 }
       
   356 
       
   357 
       
   358 QDragManager::~QDragManager()
       
   359 {
       
   360 #ifndef QT_NO_CURSOR
       
   361     if (restoreCursor)
       
   362         QApplication::restoreOverrideCursor();
       
   363 #endif
       
   364     instance = 0;
       
   365     delete [] pm_cursor;
       
   366     delete dropData;
       
   367 }
       
   368 
       
   369 QDragManager *QDragManager::self()
       
   370 {
       
   371     if (!instance && !QApplication::closingDown())
       
   372         instance = new QDragManager;
       
   373     return instance;
       
   374 }
       
   375 
       
   376 QPixmap QDragManager::dragCursor(Qt::DropAction action) const
       
   377 {
       
   378     QDragPrivate * d = dragPrivate();
       
   379     if (d && d->customCursors.contains(action))
       
   380         return d->customCursors[action];
       
   381     else if (action == Qt::MoveAction)
       
   382         return pm_cursor[0];
       
   383     else if (action == Qt::CopyAction)
       
   384         return pm_cursor[1];
       
   385     else if (action == Qt::LinkAction)
       
   386         return pm_cursor[2];
       
   387 #ifdef Q_WS_WIN
       
   388     else if (action == Qt::IgnoreAction)
       
   389         return pm_cursor[3];
       
   390 #endif
       
   391     return QPixmap();
       
   392 }
       
   393 
       
   394 bool QDragManager::hasCustomDragCursors() const
       
   395 {
       
   396     QDragPrivate * d = dragPrivate();
       
   397     return d && !d->customCursors.isEmpty();
       
   398 }
       
   399 
       
   400 Qt::DropAction QDragManager::defaultAction(Qt::DropActions possibleActions,
       
   401                                            Qt::KeyboardModifiers modifiers) const
       
   402 {
       
   403 #ifdef QDND_DEBUG
       
   404     qDebug("QDragManager::defaultAction(Qt::DropActions possibleActions)");
       
   405     qDebug("keyboard modifiers : %s", KeyboardModifiersToString(modifiers).latin1());
       
   406 #endif
       
   407 
       
   408     QDragPrivate *d = dragPrivate();
       
   409     Qt::DropAction defaultAction = d ? d->defaultDropAction : Qt::IgnoreAction;
       
   410 
       
   411     if (defaultAction == Qt::IgnoreAction) {
       
   412         //This means that the drag was initiated by QDrag::start and we need to
       
   413         //preserve the old behavior
       
   414 #ifdef Q_WS_MAC
       
   415         defaultAction = Qt::MoveAction;
       
   416 #else
       
   417         defaultAction = Qt::CopyAction;
       
   418 #endif
       
   419     }
       
   420 
       
   421 #ifdef Q_WS_MAC
       
   422     if (modifiers & Qt::ControlModifier && modifiers & Qt::AltModifier)
       
   423         defaultAction = Qt::LinkAction;
       
   424     else if (modifiers & Qt::AltModifier)
       
   425         defaultAction = Qt::CopyAction;
       
   426     else if (modifiers & Qt::ControlModifier)
       
   427         defaultAction = Qt::MoveAction;
       
   428 #else
       
   429     if (modifiers & Qt::ControlModifier && modifiers & Qt::ShiftModifier)
       
   430         defaultAction = Qt::LinkAction;
       
   431     else if (modifiers & Qt::ControlModifier)
       
   432         defaultAction = Qt::CopyAction;
       
   433     else if (modifiers & Qt::ShiftModifier)
       
   434         defaultAction = Qt::MoveAction;
       
   435     else if (modifiers & Qt::AltModifier)
       
   436         defaultAction = Qt::LinkAction;
       
   437 #endif
       
   438 
       
   439     // if the object is set take the list of possibles from it
       
   440     if (object)
       
   441         possibleActions = object->d_func()->possible_actions;
       
   442 
       
   443 #ifdef QDND_DEBUG
       
   444     qDebug("possible actions : %s", dragActionsToString(possibleActions).latin1());
       
   445 #endif
       
   446 
       
   447     // Check if the action determined is allowed
       
   448     if (!(possibleActions & defaultAction)) {
       
   449         if (possibleActions & Qt::CopyAction)
       
   450             defaultAction = Qt::CopyAction;
       
   451         else if (possibleActions & Qt::MoveAction)
       
   452             defaultAction = Qt::MoveAction;
       
   453         else if (possibleActions & Qt::LinkAction)
       
   454             defaultAction = Qt::LinkAction;
       
   455         else
       
   456             defaultAction = Qt::IgnoreAction;
       
   457     }
       
   458 
       
   459 #ifdef QDND_DEBUG
       
   460     qDebug("default action : %s", dragActionsToString(defaultAction).latin1());
       
   461 #endif
       
   462 
       
   463     return defaultAction;
       
   464 }
       
   465 
       
   466 void QDragManager::setCurrentTarget(QWidget *target, bool dropped)
       
   467 {
       
   468     if (currentDropTarget == target)
       
   469         return;
       
   470 
       
   471     currentDropTarget = target;
       
   472     if (!dropped && object) {
       
   473         object->d_func()->target = target;
       
   474         emit object->targetChanged(target);
       
   475     }
       
   476 
       
   477 }
       
   478 
       
   479 QWidget *QDragManager::currentTarget()
       
   480 {
       
   481     return currentDropTarget;
       
   482 }
       
   483 
       
   484 #endif
       
   485 
       
   486 QDropData::QDropData()
       
   487     : QInternalMimeData()
       
   488 {
       
   489 }
       
   490 
       
   491 QDropData::~QDropData()
       
   492 {
       
   493 }
       
   494 #endif // QT_NO_DRAGANDDROP
       
   495 
       
   496 #if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD))
       
   497 
       
   498 static QStringList imageReadMimeFormats()
       
   499 {
       
   500     QStringList formats;
       
   501     QList<QByteArray> imageFormats = QImageReader::supportedImageFormats();
       
   502     for (int i = 0; i < imageFormats.size(); ++i) {
       
   503         QString format = QLatin1String("image/");
       
   504         format += QString::fromLatin1(imageFormats.at(i).toLower());
       
   505         formats.append(format);
       
   506     }
       
   507 
       
   508     //put png at the front because it is best
       
   509     int pngIndex = formats.indexOf(QLatin1String("image/png"));
       
   510     if (pngIndex != -1 && pngIndex != 0)
       
   511         formats.move(pngIndex, 0);
       
   512 
       
   513     return formats;
       
   514 }
       
   515 
       
   516 
       
   517 static QStringList imageWriteMimeFormats()
       
   518 {
       
   519     QStringList formats;
       
   520     QList<QByteArray> imageFormats = QImageWriter::supportedImageFormats();
       
   521     for (int i = 0; i < imageFormats.size(); ++i) {
       
   522         QString format = QLatin1String("image/");
       
   523         format += QString::fromLatin1(imageFormats.at(i).toLower());
       
   524         formats.append(format);
       
   525     }
       
   526 
       
   527     //put png at the front because it is best
       
   528     int pngIndex = formats.indexOf(QLatin1String("image/png"));
       
   529     if (pngIndex != -1 && pngIndex != 0)
       
   530         formats.move(pngIndex, 0);
       
   531 
       
   532     return formats;
       
   533 }
       
   534 
       
   535 QInternalMimeData::QInternalMimeData()
       
   536     : QMimeData()
       
   537 {
       
   538 }
       
   539 
       
   540 QInternalMimeData::~QInternalMimeData()
       
   541 {
       
   542 }
       
   543 
       
   544 bool QInternalMimeData::hasFormat(const QString &mimeType) const
       
   545 {
       
   546     bool foundFormat = hasFormat_sys(mimeType);
       
   547     if (!foundFormat && mimeType == QLatin1String("application/x-qt-image")) {
       
   548         QStringList imageFormats = imageReadMimeFormats();
       
   549         for (int i = 0; i < imageFormats.size(); ++i) {
       
   550             if ((foundFormat = hasFormat_sys(imageFormats.at(i))))
       
   551                 break;
       
   552         }
       
   553     }
       
   554     return foundFormat;
       
   555 }
       
   556 
       
   557 QStringList QInternalMimeData::formats() const
       
   558 {
       
   559     QStringList realFormats = formats_sys();
       
   560     if (!realFormats.contains(QLatin1String("application/x-qt-image"))) {
       
   561         QStringList imageFormats = imageReadMimeFormats();
       
   562         for (int i = 0; i < imageFormats.size(); ++i) {
       
   563             if (realFormats.contains(imageFormats.at(i))) {
       
   564                 realFormats += QLatin1String("application/x-qt-image");
       
   565                 break;
       
   566             }
       
   567         }
       
   568     }
       
   569     return realFormats;
       
   570 }
       
   571 
       
   572 QVariant QInternalMimeData::retrieveData(const QString &mimeType, QVariant::Type type) const
       
   573 {
       
   574     QVariant data = retrieveData_sys(mimeType, type);
       
   575     if (mimeType == QLatin1String("application/x-qt-image")) {
       
   576         if (data.isNull() || (data.type() == QVariant::ByteArray && data.toByteArray().isEmpty())) {
       
   577             // try to find an image
       
   578             QStringList imageFormats = imageReadMimeFormats();
       
   579             for (int i = 0; i < imageFormats.size(); ++i) {
       
   580                 data = retrieveData_sys(imageFormats.at(i), type);
       
   581                 if (data.isNull() || (data.type() == QVariant::ByteArray && data.toByteArray().isEmpty()))
       
   582                     continue;
       
   583                 break;
       
   584             }
       
   585         }
       
   586         // we wanted some image type, but all we got was a byte array. Convert it to an image.
       
   587         if (data.type() == QVariant::ByteArray
       
   588             && (type == QVariant::Image || type == QVariant::Pixmap || type == QVariant::Bitmap))
       
   589             data = QImage::fromData(data.toByteArray());
       
   590 
       
   591     } else if (mimeType == QLatin1String("application/x-color") && data.type() == QVariant::ByteArray) {
       
   592         QColor c;
       
   593         QByteArray ba = data.toByteArray();
       
   594         if (ba.size() == 8) {
       
   595             ushort * colBuf = (ushort *)ba.data();
       
   596             c.setRgbF(qreal(colBuf[0]) / qreal(0xFFFF),
       
   597                       qreal(colBuf[1]) / qreal(0xFFFF),
       
   598                       qreal(colBuf[2]) / qreal(0xFFFF),
       
   599                       qreal(colBuf[3]) / qreal(0xFFFF));
       
   600             data = c;
       
   601         } else {
       
   602             qWarning("Qt: Invalid color format");
       
   603         }
       
   604     } else if (data.type() != type && data.type() == QVariant::ByteArray) {
       
   605         // try to use mime data's internal conversion stuf.
       
   606         QInternalMimeData *that = const_cast<QInternalMimeData *>(this);
       
   607         that->setData(mimeType, data.toByteArray());
       
   608         data = QMimeData::retrieveData(mimeType, type);
       
   609         that->clear();
       
   610     }
       
   611     return data;
       
   612 }
       
   613 
       
   614 bool QInternalMimeData::canReadData(const QString &mimeType)
       
   615 {
       
   616     return imageReadMimeFormats().contains(mimeType);
       
   617 }
       
   618 
       
   619 // helper functions for rendering mimedata to the system, this is needed because QMimeData is in core.
       
   620 QStringList QInternalMimeData::formatsHelper(const QMimeData *data)
       
   621 {
       
   622     QStringList realFormats = data->formats();
       
   623     if (realFormats.contains(QLatin1String("application/x-qt-image"))) {
       
   624         // add all supported image formats
       
   625         QStringList imageFormats = imageWriteMimeFormats();
       
   626         for (int i = 0; i < imageFormats.size(); ++i) {
       
   627             if (!realFormats.contains(imageFormats.at(i)))
       
   628                 realFormats.append(imageFormats.at(i));
       
   629         }
       
   630     }
       
   631     return realFormats;
       
   632 }
       
   633 
       
   634 bool QInternalMimeData::hasFormatHelper(const QString &mimeType, const QMimeData *data)
       
   635 {
       
   636 
       
   637     bool foundFormat = data->hasFormat(mimeType);
       
   638     if (!foundFormat) {
       
   639         if (mimeType == QLatin1String("application/x-qt-image")) {
       
   640             // check all supported image formats
       
   641             QStringList imageFormats = imageWriteMimeFormats();
       
   642             for (int i = 0; i < imageFormats.size(); ++i) {
       
   643                 if ((foundFormat = data->hasFormat(imageFormats.at(i))))
       
   644                     break;
       
   645             }
       
   646         } else if (mimeType.startsWith(QLatin1String("image/"))) {
       
   647             return data->hasImage() && imageWriteMimeFormats().contains(mimeType);
       
   648         }
       
   649     }
       
   650     return foundFormat;
       
   651 }
       
   652 
       
   653 QByteArray QInternalMimeData::renderDataHelper(const QString &mimeType, const QMimeData *data)
       
   654 {
       
   655     QByteArray ba;
       
   656     if (mimeType == QLatin1String("application/x-color")) {
       
   657         /* QMimeData can only provide colors as QColor or the name
       
   658            of a color as a QByteArray or a QString. So we need to do
       
   659            the conversion to application/x-color here.
       
   660            The application/x-color format is :
       
   661            type: application/x-color
       
   662            format: 16
       
   663            data[0]: red
       
   664            data[1]: green
       
   665            data[2]: blue
       
   666            data[3]: opacity
       
   667         */
       
   668         ba.resize(8);
       
   669         ushort * colBuf = (ushort *)ba.data();
       
   670         QColor c = qvariant_cast<QColor>(data->colorData());
       
   671         colBuf[0] = ushort(c.redF() * 0xFFFF);
       
   672         colBuf[1] = ushort(c.greenF() * 0xFFFF);
       
   673         colBuf[2] = ushort(c.blueF() * 0xFFFF);
       
   674         colBuf[3] = ushort(c.alphaF() * 0xFFFF);
       
   675     } else {
       
   676         ba = data->data(mimeType);
       
   677         if (ba.isEmpty()) {
       
   678             if (mimeType == QLatin1String("application/x-qt-image") && data->hasImage()) {
       
   679                 QImage image = qvariant_cast<QImage>(data->imageData());
       
   680                 QBuffer buf(&ba);
       
   681                 buf.open(QBuffer::WriteOnly);
       
   682                 // would there not be PNG ??
       
   683                 image.save(&buf, "PNG");
       
   684             } else if (mimeType.startsWith(QLatin1String("image/")) && data->hasImage()) {
       
   685                 QImage image = qvariant_cast<QImage>(data->imageData());
       
   686                 QBuffer buf(&ba);
       
   687                 buf.open(QBuffer::WriteOnly);
       
   688                 image.save(&buf, mimeType.mid(mimeType.indexOf(QLatin1Char('/')) + 1).toLatin1().toUpper());
       
   689             }
       
   690         }
       
   691     }
       
   692     return ba;
       
   693 }
       
   694 
       
   695 #endif // QT_NO_DRAGANDDROP && QT_NO_CLIPBOARD
       
   696 
       
   697 QT_END_NAMESPACE