📄 qdnd_qws.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qapplication.h"#ifndef QT_NO_DRAGANDDROP#include "qwidget.h"#include "qdatetime.h"#include "qbitmap.h"#include "qcursor.h"#include "qevent.h"#include "qpainter.h"#include "qdnd_p.h"static QPixmap *defaultPm = 0;static const int default_pm_hotx = -2;static const int default_pm_hoty = -16;static const char *const default_pm[] = {"13 9 3 1",". c None"," c #000000","X c #FFFFFF","X X X X X X X"," X X X X X X ","X ......... X"," X.........X ","X ......... X"," X.........X ","X ......... X"," X X X X X X ","X X X X X X X",};// Shift/Ctrl handling, and final drop statusstatic Qt::DropAction global_accepted_action = Qt::CopyAction;static Qt::DropActions possible_actions = Qt::IgnoreAction;// static variables in place of a proper cross-process solutionstatic QDrag *drag_object;static bool qt_qws_dnd_dragging = false;static Qt::KeyboardModifiers oldstate;class QShapedPixmapWidget : public QWidget { QPixmap pixmap;public: QShapedPixmapWidget() : QWidget(0, Qt::Tool | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint) { // ### Temporary workaround for 4.2-rc1!!! To prevent flickering when // using drag'n drop in a client application. (task 126956) // setAttribute() should be done unconditionally! if (QApplication::type() == QApplication::GuiServer) setAttribute(Qt::WA_TransparentForMouseEvents); } void setPixmap(QPixmap pm) { pixmap = pm; if (!pixmap.mask().isNull()) { setMask(pixmap.mask()); } else { clearMask(); } resize(pm.width(),pm.height()); } void paintEvent(QPaintEvent*) { QPainter p(this); p.drawPixmap(0,0,pixmap); }};static QShapedPixmapWidget *qt_qws_dnd_deco = 0;void QDragManager::updatePixmap(){ if (qt_qws_dnd_deco) { QPixmap pm; QPoint pm_hot(default_pm_hotx,default_pm_hoty); if (drag_object) { pm = drag_object->pixmap(); if (!pm.isNull()) pm_hot = drag_object->hotSpot(); } if (pm.isNull()) { if (!defaultPm) defaultPm = new QPixmap(default_pm); pm = *defaultPm; } qt_qws_dnd_deco->setPixmap(pm); qt_qws_dnd_deco->move(QCursor::pos()-pm_hot); if (willDrop) { qt_qws_dnd_deco->show(); } else { qt_qws_dnd_deco->hide(); } }}void QDragManager::timerEvent(QTimerEvent *) { }void QDragManager::move(const QPoint &) { }void QDragManager::updateCursor(){#ifndef QT_NO_CURSOR if (willDrop) { if (qt_qws_dnd_deco) qt_qws_dnd_deco->show(); if (currentActionForOverrideCursor != global_accepted_action) { QApplication::changeOverrideCursor(QCursor(dragCursor(global_accepted_action), 0, 0)); currentActionForOverrideCursor = global_accepted_action; } } else { QCursor *overrideCursor = QApplication::overrideCursor(); if (!overrideCursor || overrideCursor->shape() != Qt::ForbiddenCursor) { QApplication::changeOverrideCursor(QCursor(Qt::ForbiddenCursor)); currentActionForOverrideCursor = Qt::IgnoreAction; } if (qt_qws_dnd_deco) qt_qws_dnd_deco->hide(); }#endif}bool QDragManager::eventFilter(QObject *o, QEvent *e){ if (beingCancelled) { if (e->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) { qApp->removeEventFilter(this); Q_ASSERT(object == 0); beingCancelled = false; eventLoop->exit(); return true; // block the key release } return false; } if (!o->isWidgetType()) return false; switch(e->type()) { case QEvent::KeyPress: case QEvent::KeyRelease: { QKeyEvent *ke = ((QKeyEvent*)e); if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) { cancel(); qApp->removeEventFilter(this); beingCancelled = false; eventLoop->exit(); } else { updateCursor(); } return true; // Eat all key events } case QEvent::MouseButtonPress: case QEvent::MouseMove: { if (!object) { //#### this should not happen qWarning("QDragManager::eventFilter: No object"); return true; } QDragManager *manager = QDragManager::self(); QMimeData *dropData = manager->object ? manager->dragPrivate()->data : manager->dropData; if (manager->object) possible_actions = manager->dragPrivate()->possible_actions; else possible_actions = Qt::IgnoreAction; QMouseEvent *me = (QMouseEvent *)e; if (me->buttons()) { Qt::DropAction prevAction = global_accepted_action; QWidget *cw = QApplication::widgetAt(me->globalPos()); // Fix for when we move mouse on to the deco widget if (qt_qws_dnd_deco && cw == qt_qws_dnd_deco) cw = object->target(); while (cw && !cw->acceptDrops() && !cw->isWindow()) cw = cw->parentWidget(); if (object->target() != cw) { if (object->target()) { QDragLeaveEvent dle; QApplication::sendEvent(object->target(), &dle); willDrop = false; global_accepted_action = Qt::IgnoreAction; updateCursor(); restoreCursor = true; object->d_func()->target = 0; } if (cw && cw->acceptDrops()) { object->d_func()->target = cw; QDragEnterEvent dee(cw->mapFromGlobal(me->globalPos()), possible_actions, dropData, me->buttons(), me->modifiers()); QApplication::sendEvent(object->target(), &dee); willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction; global_accepted_action = willDrop ? dee.dropAction() : Qt::IgnoreAction; updateCursor(); restoreCursor = true; } } else if (cw) { QDragMoveEvent dme(cw->mapFromGlobal(me->globalPos()), possible_actions, dropData, me->buttons(), me->modifiers()); if (global_accepted_action != Qt::IgnoreAction) { dme.setDropAction(global_accepted_action); dme.accept(); } QApplication::sendEvent(cw, &dme); willDrop = dme.isAccepted(); global_accepted_action = willDrop ? dme.dropAction() : Qt::IgnoreAction; updatePixmap(); updateCursor(); } if (global_accepted_action != prevAction) emitActionChanged(global_accepted_action); } return true; // Eat all mouse events } case QEvent::MouseButtonRelease: { qApp->removeEventFilter(this); if (restoreCursor) { willDrop = false;#ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor();#endif restoreCursor = false; } if (object && object->target()) { QMouseEvent *me = (QMouseEvent *)e; QDragManager *manager = QDragManager::self(); QMimeData *dropData = manager->object ? manager->dragPrivate()->data : manager->dropData; QDropEvent de(object->target()->mapFromGlobal(me->globalPos()), possible_actions, dropData, me->buttons(), me->modifiers()); QApplication::sendEvent(object->target(), &de); if (de.isAccepted()) global_accepted_action = de.dropAction(); else global_accepted_action = Qt::IgnoreAction; if (object) object->deleteLater(); drag_object = object = 0; } eventLoop->exit(); return true; // Eat all mouse events } default: break; } return false;}Qt::DropAction QDragManager::drag(QDrag *o){ if (object == o || !o || !o->source()) return Qt::IgnoreAction; if (object) { cancel(); qApp->removeEventFilter(this); beingCancelled = false; } object = drag_object = o; qt_qws_dnd_deco = new QShapedPixmapWidget(); oldstate = Qt::NoModifier; // #### Should use state that caused the drag// drag_mode = mode; willDrop = false; updatePixmap(); updateCursor(); restoreCursor = true; object->d_func()->target = 0; qApp->installEventFilter(this); global_accepted_action = Qt::CopyAction;#ifndef QT_NO_CURSOR qApp->setOverrideCursor(Qt::ArrowCursor); restoreCursor = true; updateCursor();#endif qt_qws_dnd_dragging = true; eventLoop = new QEventLoop; (void) eventLoop->exec(); delete eventLoop; eventLoop = 0; delete qt_qws_dnd_deco; qt_qws_dnd_deco = 0; qt_qws_dnd_dragging = false; return global_accepted_action;}void QDragManager::cancel(bool deleteSource){// qDebug("QDragManager::cancel"); beingCancelled = true; if (object->target()) { QDragLeaveEvent dle; QApplication::sendEvent(object->target(), &dle); }#ifndef QT_NO_CURSOR if (restoreCursor) { QApplication::restoreOverrideCursor(); restoreCursor = false; }#endif if (drag_object) { if (deleteSource) object->deleteLater(); drag_object = object = 0; } delete qt_qws_dnd_deco; qt_qws_dnd_deco = 0; global_accepted_action = Qt::IgnoreAction;}void QDragManager::drop(){}QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const{ if (!drag_object) return QVariant(); QByteArray data = drag_object->mimeData()->data(mimetype); if (type == QVariant::String) return QString::fromUtf8(data); return data;}bool QDropData::hasFormat_sys(const QString &format) const{ return formats().contains(format);}QStringList QDropData::formats_sys() const{ if (drag_object) return drag_object->mimeData()->formats(); return QStringList();}#endif // QT_NO_DRAGANDDROP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -