qdesigner_dnditem.cpp
来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 290 行
CPP
290 行
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt Designer 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 "qdesigner_dnditem_p.h"#include "formwindowbase_p.h"#include "ui4_p.h"#include <QtGui/QPainter>#include <QtGui/QBitmap>#include <QtGui/QPixmap>#include <QtGui/QImage>#include <QtGui/QLabel>#include <QtGui/QDrag>#include <QtGui/QCursor>#include <QtGui/QDropEvent>#include <QtGui/QRgb>#include <QtCore/QMultiMap>namespace qdesigner_internal {QDesignerDnDItem::QDesignerDnDItem(DropType type, QWidget *source) : m_source(source), m_type(type), m_dom_ui(0), m_widget(0), m_decoration(0){}void QDesignerDnDItem::init(DomUI *ui, QWidget *widget, QWidget *decoration, const QPoint &global_mouse_pos){ Q_ASSERT(widget != 0 || ui != 0); Q_ASSERT(decoration != 0); m_dom_ui = ui; m_widget = widget; m_decoration = decoration; const QRect geometry = m_decoration->geometry(); m_hot_spot = global_mouse_pos - m_decoration->geometry().topLeft();}QDesignerDnDItem::~QDesignerDnDItem(){ if (m_decoration != 0) m_decoration->deleteLater(); delete m_dom_ui;}DomUI *QDesignerDnDItem::domUi() const{ return m_dom_ui;}QWidget *QDesignerDnDItem::decoration() const{ return m_decoration;}QPoint QDesignerDnDItem::hotSpot() const{ return m_hot_spot;}QWidget *QDesignerDnDItem::widget() const{ return m_widget;}QDesignerDnDItem::DropType QDesignerDnDItem::type() const{ return m_type;}QWidget *QDesignerDnDItem::source() const{ return m_source;}void QDesignerDnDItem::setDomUi(DomUI *dom_ui){ delete m_dom_ui; m_dom_ui = dom_ui;}// ---------- QDesignerMimeData// Make pixmap transparent on Windows only. Mac is transparent by default, Unix usually does not work.#ifdef Q_WS_WIN# define TRANSPARENT_DRAG_PIXMAP#endifQDesignerMimeData::QDesignerMimeData(const QDesignerDnDItems &items, QDrag *drag) : m_items(items){ enum { Alpha = 200 }; QPoint decorationTopLeft; switch (m_items.size()) { case 0: break; case 1: { QWidget *deco = m_items.first()->decoration(); decorationTopLeft = deco->pos(); const QPixmap widgetPixmap = QPixmap::grabWidget(deco);#ifdef TRANSPARENT_DRAG_PIXMAP QImage image(widgetPixmap.size(), QImage::Format_ARGB32_Premultiplied); image.fill(QColor(Qt::transparent).rgba()); QPainter painter(&image); painter.drawPixmap(QPoint(0, 0), widgetPixmap); painter.end(); setImageTransparency(image, Alpha); drag->setPixmap(QPixmap::fromImage(image));#else drag->setPixmap(widgetPixmap);#endif } break; default: { // determine size of drag decoration by uniting all geometries const QDesignerDnDItems::const_iterator cend = m_items.constEnd(); QDesignerDnDItems::const_iterator it =m_items.constBegin(); QRect unitedGeometry = (*it)->decoration()->geometry(); for (++it; it != cend; ++it ) unitedGeometry = unitedGeometry .united((*it)->decoration()->geometry()); // paint with offset. At the same time, create a mask bitmap, containing widget rectangles. QImage image(unitedGeometry.size(), QImage::Format_ARGB32_Premultiplied); image.fill(QColor(Qt::transparent).rgba()); QBitmap mask(unitedGeometry.size()); mask.clear(); // paint with offset, determine action QPainter painter(&image); QPainter maskPainter(&mask); decorationTopLeft = unitedGeometry.topLeft(); for (it = m_items.constBegin() ; it != cend; ++it ) { QWidget *w = (*it)->decoration(); const QPixmap wp = QPixmap::grabWidget(w); const QPoint pos = w->pos() - decorationTopLeft; painter.drawPixmap(pos, wp); maskPainter.fillRect(QRect(pos, wp.size()), Qt::color1); } painter.end(); maskPainter.end();#ifdef TRANSPARENT_DRAG_PIXMAP setImageTransparency(image, Alpha);#endif QPixmap pixmap = QPixmap::fromImage(image); pixmap.setMask(mask); drag->setPixmap(pixmap); } break; } // determine hot spot and reconstruct the exact starting position as form window // introduces some offset when detecting DnD m_globalStartPos = m_items.first()->decoration()->pos() + m_items.first()->hotSpot(); m_hotSpot = m_globalStartPos - decorationTopLeft; drag->setHotSpot(m_hotSpot); drag->setMimeData(this);}QDesignerMimeData::~QDesignerMimeData(){ const QDesignerDnDItems::const_iterator cend = m_items.constEnd(); for (QDesignerDnDItems::const_iterator it = m_items.constBegin(); it != cend; ++it ) delete *it;}Qt::DropAction QDesignerMimeData::proposedDropAction() const{ return m_items.first()->type() == QDesignerDnDItemInterface::CopyDrop ? Qt::CopyAction : Qt::MoveAction;}bool QDesignerMimeData::execDrag(const QDesignerDnDItems &items, QWidget * dragSource){ if (items.empty()) return false; QDrag *drag = new QDrag(dragSource); QDesignerMimeData *mimeData = new QDesignerMimeData(items, drag); // Store pointers to widgets that are to be re-shown if a move operation is canceled QWidgetList reshowWidgets; const QDesignerDnDItems::const_iterator cend = items.constEnd(); for (QDesignerDnDItems::const_iterator it = items.constBegin(); it != cend; ++it ) if (QWidget *w = (*it)->widget()) if ((*it)->type() == QDesignerDnDItemInterface::MoveDrop) reshowWidgets.push_back(w); const Qt::DropAction executedAction = drag->exec(Qt::CopyAction|Qt::MoveAction, mimeData->proposedDropAction()); if (executedAction == Qt::IgnoreAction && !reshowWidgets.empty()) foreach (QWidget *w, reshowWidgets) w->show(); return executedAction != Qt::IgnoreAction;}void QDesignerMimeData::moveDecoration(const QPoint &globalPos) const{ const QPoint relativeDistance = globalPos - m_globalStartPos; const QDesignerDnDItems::const_iterator cend = m_items.constEnd(); for (QDesignerDnDItems::const_iterator it =m_items.constBegin(); it != cend; ++it ) { QWidget *w = (*it)->decoration(); w->move(w->pos() + relativeDistance); }}void QDesignerMimeData::removeMovedWidgetsFromSourceForm(const QDesignerDnDItems &items){ typedef QMultiMap<FormWindowBase *, QWidget *> FormWidgetMap; FormWidgetMap formWidgetMap; // Find moved widgets per form const QDesignerDnDItems::const_iterator cend = items.constEnd(); for (QDesignerDnDItems::const_iterator it = items.constBegin(); it != cend; ++it ) if ((*it)->type() == QDesignerDnDItemInterface::MoveDrop) if (QWidget *w = (*it)->widget()) if (FormWindowBase *fb = qobject_cast<FormWindowBase *>((*it)->source())) formWidgetMap.insert(fb, w); if (formWidgetMap.empty()) return; foreach (FormWindowBase * fb, formWidgetMap.keys()) fb->deleteWidgetList(formWidgetMap.values(fb));}void QDesignerMimeData::acceptEventWithAction(Qt::DropAction desiredAction, QDropEvent *e){ if (e->proposedAction() == desiredAction) { e->acceptProposedAction(); } else { e->setDropAction(desiredAction); e->accept(); }}void QDesignerMimeData::acceptEvent(QDropEvent *e) const{ acceptEventWithAction(proposedDropAction(), e);}void QDesignerMimeData::setImageTransparency(QImage &image, int alpha){ for (int l = 0; l < image.height(); l++) { QRgb *line = reinterpret_cast<QRgb *>(image.scanLine(l)); QRgb *lineEnd = line + image.width(); for ( ; line < lineEnd; line++) { const QRgb rgba = *line; *line = qRgba(qRed(rgba), qGreen(rgba), qBlue(rgba), alpha); } }}} // namespace qdesigner_internal
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?