VirtualBox

Changeset 50305 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Feb 3, 2014 10:47:45 AM (11 years ago)
Author:
vboxsync
Message:

DnD: Update.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r50265 r50305  
    451451
    452452ifdef VBOX_WITH_DRAG_AND_DROP
     453 VirtualBox_QT_MOCHDRS += \
     454        src/runtime/UIDnDHandler.h
    453455 ifdef VBOX_WITH_DRAG_AND_DROP_GH
    454456  VirtualBox_QT_MOCHDRS += \
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.cpp

    r50278 r50305  
    2323#include <QStringList>
    2424#include <QTimer>
     25#include <QUrl>
    2526
    2627#ifdef LOG_GROUP
     
    168169     * Do guest -> host format conversion, if needed.
    169170     * On X11 this already maps to the Xdnd protocol.
    170      ** @todo What about MacOS X Carbon Drag Manager?
     171     ** @todo What about the MacOS Carbon Drag Manager? Needs testing.
    171172     *
    172173     * See: https://www.iana.org/assignments/media-types/media-types.xhtml
     
    176177    for (int i = 0; i < vecFmtGuest.size(); i++)
    177178    {
    178         const QString &strFmt = vecFmtGuest.at(i);
     179        const QString &strFmtGuest = vecFmtGuest.at(i);
    179180        LogFlowFunc(("\tFormat %d: %s\n", i,
    180                      strFmt.toAscii().constData()));
     181                     strFmtGuest.toAscii().constData()));
    181182#ifdef RT_OS_WINDOWS
    182         if (   strFmt.contains("text", Qt::CaseInsensitive)
     183        /* CF_TEXT */
     184        if (   strFmtGuest.contains("text/plain", Qt::CaseInsensitive)
    183185            && !lstFmtNative.contains("text/plain"))
    184186        {
    185187            lstFmtNative << "text/plain";
    186188        }
     189        /* CF_HDROP */
     190        else if (   strFmtGuest.contains("text/uri-list", Qt::CaseInsensitive)
     191                 && !lstFmtNative.contains("text/uri-list"))
     192        {
     193            lstFmtNative << "text/uri-list";
     194        }
    187195#else
    188         lstFmtNative << strFmt;
     196        /* On non-Windows just do a 1:1 mapping. */
     197        lstFmtNative << strFmtGuest;
     198# ifdef RT_OS_MACOS
     199        /** @todo Does the mapping apply here? Don't think so ... */
     200# endif
    189201#endif
    190202    }
     
    204216
    205217            /* pMData is transfered to the QDrag object, so no need for deletion. */
    206             UIDnDMimeData *pMData = new UIDnDMimeData(session, lstFmtNative,
     218            pMData = new UIDnDMimeData(session, lstFmtNative,
    207219                                                      toQtDnDAction(defaultAction),
    208220                                                      toQtDnDActions(vecActions), pParent);
     221
     222            /* Inform this object that MIME data from the guest is available so that
     223             * it can update the MIME data object accordingly. */
     224            connect(pMData, SIGNAL(sigDataAvailable(QString)),
     225                    this, SLOT(sltDataAvailable(QString)), Qt::DirectConnection);
    209226
    210227            /* Inform the MIME data object of any changes in the current action. */
     
    218235             * is finished. */
    219236            pDrag->setMimeData(pMData);
    220             pDrag->exec(toQtDnDActions(vecActions), toQtDnDAction(defaultAction));
    221 
     237            Qt::DropAction dropAction =
     238                 pDrag->exec(toQtDnDActions(vecActions), toQtDnDAction(defaultAction));
     239            LogFlowFunc(("dropAction=%ld\n", toVBoxDnDAction(dropAction)));
     240#ifdef RT_OS_WINDOWS
     241            /* Since the QDrag::exec() call above was blocking on Windows, decide what
     242             * to do now, e.g. if there was a "drop" action.
     243             *
     244             * Note: The UIDnDMimeData object will not be not accessible here anymore,
     245             *       since QDrag had its ownership and deleted it after the (blocking)
     246             *       QDrag::exec() call. */
     247#endif
    222248            rc = VINF_SUCCESS;
    223249        }
     
    310336}
    311337
     338void UIDnDHandler::sltDataAvailable(const QString &mimeType)
     339{
     340    LogFlowFunc(("pMData=0x%p, mimeType=%s\n",
     341                 pMData, mimeType.toAscii().constData()));
     342
     343    if (pMData)
     344        pMData->setData(mimeType);
     345}
     346
    312347#include "UIDnDHandler.moc"
    313348
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.h

    r50265 r50305  
    2424#include "COMEnums.h"
    2525
    26 /* Forward declarations. */
     26/* Forward declarations: */
    2727class QMimeData;
    2828class CSession;
    2929class CGuest;
     30class UIDnDMimeData;
    3031
    31 /** @todo Check for making this a full static class when possible. */
    3232class UIDnDHandler: public QObject
    3333{
     34    Q_OBJECT;
     35
    3436public:
    3537    /* Singleton factory. */
     
    5860    int            dragGHPending(CSession &session, ulong screenId, QWidget *pParent = NULL);
    5961
     62public slots:
     63
     64    void sltDataAvailable(const QString &mimetype);
     65
    6066private:
    6167    static UIDnDHandler *m_pInstance;
     
    7076    static Qt::DropActions             toQtDnDActions(const QVector<KDragAndDropAction> &vecActions);
    7177
     78    UIDnDMimeData *pMData;
     79
    7280    friend class UIDnDMimeData;
    7381};
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.cpp

    r50265 r50305  
    2424#include <QStringList>
    2525#include <QTimer>
     26#include <QUrl>
    2627
    2728#ifdef LOG_GROUP
     
    107108                                     QVariant::Type type) const
    108109{
    109     LogFlowFunc(("m_enmState=%d, mimeType=%s, type=%d\n",
    110                  m_enmState, mimeType.toStdString().c_str(), type));
     110    LogFlowFunc(("m_enmState=%d, mimeType=%s, type=%d (%s)\n",
     111                 m_enmState, mimeType.toStdString().c_str(),
     112                 type, QVariant::typeToName(type)));
    111113
    112114    bool fCanDrop = true;
     
    132134     * So just update our internal state to reflect the same as on other
    133135     * platforms. */
    134     m_enmState = Dropped;
     136    fCanDrop = true;
    135137#else
    136138    /* Mouse button released? See eventFilter for more information. */
     
    139141#endif
    140142
    141 #if defined (RT_OS_WINDOWS) || defined (RT_OS_MACOS)
    142     /* Special MIME handling. Later. */
    143 #endif
    144 
    145143    /* Do we support the requested MIME type? */
    146144    if (   fCanDrop
     
    154152    /* Supported types. See below in the switch statement. */
    155153    if (   fCanDrop
    156         && !(   /* Regular text. */
     154        && !(
     155             /* Plain text. */
    157156                type == QVariant::String
    158157             /* Binary data. */
     
    170169        LogFlowFunc(("Skipping request, m_enmState=%d ...\n",
    171170                     m_enmState));
    172         return QVariant();
    173     }
    174 
    175     CGuest guest = m_session.GetConsole().GetGuest();
    176     /* Start getting the data from the guest. First inform the guest we
    177      * want the data in the specified MIME type. */
    178     CProgress progress = guest.DragGHDropped(mimeType,
    179                                              UIDnDHandler::toVBoxDnDAction(m_defAction));
    180     if (guest.isOk())
    181     {
    182         msgCenter().showModalProgressDialog(progress,
    183                                             tr("Retrieving data ..."), ":/progress_dnd_gh_90px.png",
    184                                             m_pParent);
    185         if (!progress.GetCanceled())
    186         {
    187             if (   progress.isOk()
    188                 && progress.GetResultCode() == 0)
    189             {
    190                 /** @todo What about retrieving bigger files? Loop? */
    191 
    192                 /* After the data successfully arrived from the guest, we query it from Main. */
    193                 QVector<uint8_t> data = guest.DragGHGetData();
    194                 if (!data.isEmpty())
     171        return QMimeData::retrieveData(mimeType, type);
     172    }
     173
     174    if (m_enmState == Dragging)
     175    {
     176        int rc = VINF_SUCCESS;
     177
     178        CGuest guest = m_session.GetConsole().GetGuest();
     179        /* Start getting the data from the guest. First inform the guest we
     180         * want the data in the specified MIME type. */
     181        CProgress progress = guest.DragGHDropped(mimeType,
     182                                                 UIDnDHandler::toVBoxDnDAction(m_defAction));
     183        if (guest.isOk())
     184        {
     185            msgCenter().showModalProgressDialog(progress,
     186                                                tr("Retrieving data ..."), ":/progress_dnd_gh_90px.png",
     187                                                m_pParent);
     188            if (!progress.GetCanceled())
     189            {
     190                if (   progress.isOk()
     191                    && progress.GetResultCode() == 0)
    195192                {
    196                     switch (type)
     193                    /** @todo What about retrieving bigger files? Loop? */
     194
     195                    /* After the data successfully arrived from the guest, we query it from Main. */
     196                    QVector<uint8_t> data = guest.DragGHGetData();
     197                    if (!data.isEmpty())
    197198                    {
    198                         case QVariant::String:
     199                        switch (type)
    199200                        {
    200                             m_data = QVariant(QString(reinterpret_cast<const char*>(data.data())));
    201                             break;
     201                            case QVariant::String:
     202                            {
     203                                m_data = QVariant(QString(reinterpret_cast<const char*>(data.data())));
     204                                break;
     205                            }
     206
     207                            case QVariant::ByteArray:
     208                            {
     209                                QByteArray ba(reinterpret_cast<const char*>(data.constData()), data.size());
     210                                m_data = QVariant(ba);
     211                                break;
     212                            }
     213
     214                            case QVariant::List:
     215                            {
     216                                QString strData = QString(reinterpret_cast<const char*>(data.data()));
     217                                QStringList lstString = strData.split("\r\n", QString::SkipEmptyParts);
     218
     219                                m_data = QVariant(lstString);
     220                                break;
     221                            }
     222
     223                            default:
     224                                AssertMsgFailed(("Should never happen, d'oh!\n"));
     225                                rc = VERR_NOT_SUPPORTED;
     226                                break;
    202227                        }
    203 
    204                         case QVariant::ByteArray:
    205                         {
    206                             QByteArray ba(reinterpret_cast<const char*>(data.constData()), data.size());
    207                             m_data = QVariant(ba);
    208                             break;
    209                         }
    210 
    211                         case QVariant::List:
    212                         {
    213                             /** @todo Support URIs. */
    214                             break;
    215                         }
    216 
    217                         default:
    218                             AssertMsgFailed(("Should never happen, d'oh!\n"));
    219                             break;
    220228                    }
     229                    /** @todo How often to retry on empty data received? */
     230
     231                    if (RT_SUCCESS(rc))
     232                        emit sigDataAvailable(mimeType);
     233
     234                    m_enmState = DataRetrieved;
    221235                }
    222                 /** @todo How often to retry on empty data received? */
    223 
    224                 m_enmState = Finished;
     236                else
     237                    msgCenter().cannotDropData(progress, m_pParent);
    225238            }
    226239            else
    227                 msgCenter().cannotDropData(progress, m_pParent);
     240                m_enmState = Canceled;
    228241        }
    229242        else
    230             m_enmState = Canceled;
    231     }
    232     else
    233         msgCenter().cannotDropData(guest, m_pParent);
    234 
     243            msgCenter().cannotDropData(guest, m_pParent);
     244    }
     245
     246    //return QMimeData::retrieveData(mimeType, type);
    235247    return m_data;
    236248}
     
    288300#endif /* RT_OS_WINDOWS */
    289301
     302int UIDnDMimeData::setData(const QString &mimeType)
     303{
     304    LogFlowFunc(("mimeType=%s, dataType=%s\n",
     305                 mimeType.toAscii().constData(), m_data.typeName()));
     306
     307    int rc = VINF_SUCCESS;
     308
     309    switch (m_data.type())
     310    {
     311        case QVariant::String: /* Plain text. */
     312        {
     313            QMimeData::setText(m_data.toString());
     314            break;
     315        }
     316
     317        case QVariant::ByteArray: /* Raw byte data. */
     318        {
     319            QMimeData::setData(mimeType, m_data.toByteArray());
     320            break;
     321        }
     322
     323        case QVariant::StringList: /* URI. */
     324        {
     325            QList<QVariant> lstData = m_data.toList();
     326            QList<QUrl> lstURL;
     327            for (int i = 0; i < lstData.size(); i++)
     328            {
     329                QString strURL = lstData.at(i).toString();
     330                LogFlowFunc(("\tURL: %s\n",
     331                             strURL.toAscii().constData()));
     332                lstURL << QUrl(strURL.toAscii());
     333            }
     334            LogFlowFunc(("Number of URLs: %d\n",  lstURL.size()));
     335
     336            QMimeData::setUrls(f);
     337            break;
     338        }
     339
     340        default:
     341            rc = VERR_NOT_SUPPORTED;
     342            break;
     343    }
     344
     345    LogFlowFuncLeaveRC(rc);
     346    return rc;
     347}
     348
     349#include "UIDnDMIMEData.moc"
     350
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.h

    r50265 r50305  
    4646    {
    4747        Dragging = 0,
     48        DataRetrieved,
    4849        Dropped,
    49         Finished,
    5050        Canceled
    5151    };
     
    5656                  Qt::DropAction defAction,
    5757                  Qt::DropActions actions, QWidget *pParent);
     58
     59    int setData(const QString &mimeType);
    5860
    5961public slots:
     
    7476#endif
    7577    /** @}  */
     78
     79signals:
     80
     81    void sigDataAvailable(const QString &mimeType) const;
    7682
    7783private slots:
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette