⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qdnd_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                       (XEvent*)&move);    } else {        if (willDrop) {            willDrop = false;            updateCursor();        }    }    DEBUG() << "QDragManager::move leave";}void QDragManager::drop(){    Q_ASSERT(heartbeat != -1);    killTimer(heartbeat);    heartbeat = -1;    if (!qt_xdnd_current_target)        return;    delete xdnd_data.deco;    xdnd_data.deco = 0;    XClientMessageEvent drop;    drop.type = ClientMessage;    drop.window = qt_xdnd_current_target;    drop.format = 32;    drop.message_type = ATOM(XdndDrop);    drop.data.l[0] = dragPrivate()->source->winId();    drop.data.l[1] = 0; // flags    drop.data.l[2] = X11->time;    drop.data.l[3] = 0;    drop.data.l[4] = 0;    QWidget * w = QWidget::find(qt_xdnd_current_proxy_target);    if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())        w = 0;    QXdndDropTransaction t = {        X11->time,        qt_xdnd_current_target,        qt_xdnd_current_proxy_target,        current_embedding_widget,        object    };    X11->dndDropTransactions.append(t);    restartXdndDropExpiryTimer();    if (w)        X11->xdndHandleDrop(w, (const XEvent *)&drop, false);    else        XSendEvent(X11->display, qt_xdnd_current_proxy_target, False,                   NoEventMask, (XEvent*)&drop);    qt_xdnd_current_target = 0;    qt_xdnd_current_proxy_target = 0;    qt_xdnd_source_current_time = 0;    current_embedding_widget = 0;    object = 0;#ifndef QT_NO_CURSOR    if (restoreCursor) {        QApplication::restoreOverrideCursor();        restoreCursor = false;    }#endif}bool QX11Data::xdndHandleBadwindow(){    QDragManager *manager = QDragManager::self();    if (manager->object && qt_xdnd_current_target) {        qt_xdnd_current_target = 0;        qt_xdnd_current_proxy_target = 0;        manager->object->deleteLater();        manager->object = 0;        delete xdnd_data.deco;        xdnd_data.deco = 0;        return true;    }    if (qt_xdnd_dragsource_xid) {        qt_xdnd_dragsource_xid = 0;        if (qt_xdnd_current_widget) {            QDragLeaveEvent e;            QApplication::sendEvent(qt_xdnd_current_widget, &e);            qt_xdnd_current_widget = 0;        }        return true;    }    return false;}void QX11Data::xdndHandleSelectionRequest(const XSelectionRequestEvent * req){    if (!req)        return;    XEvent evt;    evt.xselection.type = SelectionNotify;    evt.xselection.display = req->display;    evt.xselection.requestor = req->requestor;    evt.xselection.selection = req->selection;    evt.xselection.target = req->target;    evt.xselection.property = XNone;    evt.xselection.time = req->time;    QByteArray format;    if (req->target == XA_STRING || req->target == ATOM(UTF8_STRING))        format = "text/plain";    else        format = X11->xdndAtomToString(req->target);    QDragManager *manager = QDragManager::self();    QDrag *currentObject = manager->object;    // which transaction do we use? (note: -2 means use current manager->object)    int at = -1;    // figure out which data the requestor is really interested in    if (manager->object && req->time == qt_xdnd_source_current_time) {        // requestor wants the current drag data        at = -2;    } else {        // if someone has requested data in response to XdndDrop, find the corresponding transaction. the        // spec says to call XConvertSelection() using the timestamp from the XdndDrop        at = findXdndDropTransactionByTime(req->time);        if (at == -1) {            // no dice, perhaps the client was nice enough to use the same window id in XConvertSelection()            // that we sent the XdndDrop event to.            at = findXdndDropTransactionByWindow(req->requestor);        }        if (at == -1 && req->time == CurrentTime) {            // bastards! previous Qt versions always requested the data on a child of the target window            // using CurrentTime... but it could be asking for either drop data or the current drag's data            Window target = findXdndAwareParent(req->requestor);            if (target) {                if (qt_xdnd_current_target && qt_xdnd_current_target == target)                    at = -2;                else                    at = findXdndDropTransactionByWindow(target);            }        }    }    if (at >= 0) {        restartXdndDropExpiryTimer();        // use the drag object from an XdndDrop tansaction        manager->object = X11->dndDropTransactions.at(at).object;    } else if (at != -2) {        // no transaction found, we'll have to reject the request        manager->object = 0;    }    if (manager->object) {        QDragPrivate* dp = QDragManager::self()->dragPrivate();        if (!format.isEmpty() && QInternalMimeData::hasFormatHelper(QLatin1String(format), dp->data)) {            QByteArray a = QInternalMimeData::renderDataHelper(QLatin1String(format), dp->data);            int dataFormat = 8;            int dataSize = a.size();            if (format == "application/x-color") {                dataFormat = 16;                dataSize = a.size() / 2;            }            XChangeProperty (X11->display, req->requestor, req->property,                             req->target, dataFormat, PropModeReplace,                             (unsigned char *)a.data(), dataSize);            evt.xselection.property = req->property;        }    }    // reset manager->object in case we modified it above    manager->object = currentObject;    // ### this can die if req->requestor crashes at the wrong    // ### moment    XSendEvent(X11->display, req->requestor, False, 0, &evt);}static QByteArray xdndObtainData(const char *format){    QByteArray result;    QWidget* w;    QDragManager *manager = QDragManager::self();    if (qt_xdnd_dragsource_xid && manager->object &&         (w=QWidget::find(qt_xdnd_dragsource_xid))         && (!(w->windowType() == Qt::Desktop) || w->acceptDrops()))    {        QDragPrivate * o = QDragManager::self()->dragPrivate();        if (o->data->hasFormat(QLatin1String(format)))            result = o->data->data(QLatin1String(format));        return result;    }    Atom a = X11->xdndStringToAtom(format);    if (!a)        return result;    // if a is not provided then find best match    int i = 0;    bool found = false;    while ((qt_xdnd_types[i])) {        if (qt_xdnd_types[i] == a) {            found = true;            break;        }        ++i;    }    if (!found && strcmp(format, "text/plain") == 0) {        int i = 0;        while ((qt_xdnd_types[i])) {            if (qt_xdnd_types[i] == ATOM(UTF8_STRING)) {                a = ATOM(UTF8_STRING);                break;            } else if (qt_xdnd_types[i] == XA_STRING) {                a = XA_STRING;                break;            }            ++i;        }    }    if (XGetSelectionOwner(X11->display, ATOM(XdndSelection)) == XNone)        return result; // should never happen?    QWidget* tw = qt_xdnd_current_widget;    if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))        tw = new QWidget;    XConvertSelection(X11->display, ATOM(XdndSelection), a, ATOM(XdndSelection), tw->winId(),                      qt_xdnd_target_current_time);    XFlush(X11->display);    XEvent xevent;    bool got=X11->clipboardWaitForEvent(tw->winId(), SelectionNotify, &xevent, 5000);    if (got) {        Atom type;        if (X11->clipboardReadProperty(tw->winId(), ATOM(XdndSelection), true, &result, 0, &type, 0, false)) {            if (type == ATOM(INCR)) {                int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0;                result = X11->clipboardReadIncrementalProperty(tw->winId(), ATOM(XdndSelection), nbytes, false);            } else if (type != a && type != XNone) {                DEBUG("Qt clipboard: unknown atom %ld", type);            }        }    }    if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))        delete tw;    return result;}/*  Enable drag and drop for widget w by installing the proper  properties on w's toplevel widget.*/bool QX11Data::dndEnable(QWidget* w, bool on){    w = w->window();    if (on) {        if (((QExtraWidget*)w)->topData()->dnd)            return true; // been there, done that        ((QExtraWidget*)w)->topData()->dnd  = 1;    }    motifdndEnable(w, on);    return xdndEnable(w, on);}Qt::DropAction QDragManager::drag(QDrag * o){    if (object == o || !o || !o->d_func()->source)        return Qt::IgnoreAction;    if (object) {        cancel();        qApp->removeEventFilter(this);        beingCancelled = false;    }    if (object) {        // the last drag and drop operation hasn't finished, so we are going to wait        // for one second to see if it does... if the finish message comes after this,        // then we could still have problems, but this is highly unlikely        QApplication::flush();        QTime started = QTime::currentTime();        QTime now = started;        do {            XEvent event;            if (XCheckTypedEvent(X11->display, ClientMessage, &event))                qApp->x11ProcessEvent(&event);            now = QTime::currentTime();            if (started > now) // crossed midnight                started = now;            // sleep 50ms, so we don't use up CPU cycles all the time.            struct timeval usleep_tv;            usleep_tv.tv_sec = 0;            usleep_tv.tv_usec = 50000;            select(0, 0, 0, 0, &usleep_tv);        } while (object && started.msecsTo(now) < 1000);    }    object = o;    object->d_func()->target = 0;    xdnd_data.deco = new QShapedPixmapWidget();    willDrop = false;    updatePixmap();    qApp->installEventFilter(this);    XSetSelectionOwner(X11->display, ATOM(XdndSelection), dragPrivate()->source->window()->winId(), X11->time);    global_accepted_action = Qt::CopyAction;    qt_xdnd_source_sameanswer = QRect();    move(QCursor::pos());    heartbeat = startTimer(200);#ifndef QT_NO_CURSOR    qApp->setOverrideCursor(Qt::ArrowCursor);    restoreCursor = true;    updateCursor();#endif    qt_xdnd_dragging = true;    if (!QWidget::mouseGrabber())        xdnd_data.deco->grabMouse();    eventLoop = new QEventLoop;    (void) eventLoop->exec();    delete eventLoop;    eventLoop = 0;#ifndef QT_NO_CURSOR    if (restoreCursor) {        qApp->restoreOverrideCursor();        restoreCursor = false;    }#endif    // delete cursors as they may be different next drag.    delete noDropCursor;    noDropCursor = 0;    delete copyCursor;    copyCursor = 0;    delete moveCursor;    moveCursor = 0;    delete linkCursor;    linkCursor = 0;    delete xdnd_data.deco;    xdnd_data.deco = 0;    if (heartbeat != -1)        killTimer(heartbeat);    heartbeat = -1;    qt_xdnd_current_screen = -1;    qt_xdnd_dragging = false;    return global_accepted_action;    // object persists until we get an xdnd_finish message}void QDragManager::updatePixmap(){    if (xdnd_data.deco) {        QPixmap pm;        QPoint pm_hot(default_pm_hotx,default_pm_hoty);        if (object) {            pm = dragPrivate()->pixmap;            if (!pm.isNull())                pm_hot = dragPrivate()->hotspot;        }        if (pm.isNull()) {            if (!defaultPm)                defaultPm = new QPixmap(default_pm);            pm = *defaultPm;        }        xdnd_data.deco->pm_hot = pm_hot;        xdnd_data.deco->setPixmap(pm);        xdnd_data.deco->move(QCursor::pos()-pm_hot);        xdnd_data.deco->show();    }}QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type) const{    QByteArray mime = mimetype.toLatin1();    QByteArray data = X11->motifdnd_active                      ? X11->motifdndObtainData(mime)                      : xdndObtainData(mime);    return data;}bool QDropData::hasFormat_sys(const QString &format) const{    return formats().contains(format);}QStringList QDropData::formats_sys() const{    QStringList formats;    if (X11->motifdnd_active) {        int i = 0;        QByteArray fmt;        while (!(fmt = X11->motifdndFormat(i)).isEmpty()) {            formats.append(QLatin1String(fmt));            ++i;        }    } else {        int i = 0;        while ((qt_xdnd_types[i])) {	   QString f = QLatin1String(X11->xdndAtomToString(qt_xdnd_types[i]));	   if (!formats.contains(f))	       formats.append(f);            ++i;        }    }    return formats;}#endif // QT_NO_DRAGANDDROP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -