/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtWidgets>#include "dragwidget.h"staticQLabel*createDragLabel(constQString&text,QWidget*parent)
{
QLabel*label =newQLabel(text, parent);
label->setAutoFillBackground(true);
label->setFrameShape(QFrame::Panel);
label->setFrameShadow(QFrame::Raised);
return label;
}
staticQString hotSpotMimeDataKey() { returnQStringLiteral("application/x-hotspot"); }
DragWidget::DragWidget(QWidget*parent)
: QWidget(parent)
{
QFile dictionaryFile(QStringLiteral(":/dictionary/words.txt"));
dictionaryFile.open(QIODevice::ReadOnly);
QTextStream inputStream(&dictionaryFile);
int x =5;
int y =5;
while (!inputStream.atEnd()) {
QString word;
inputStream >> word;
if (!word.isEmpty()) {
QLabel*wordLabel = createDragLabel(word,this);
wordLabel->move(x, y);
wordLabel->show();
wordLabel->setAttribute(Qt::WA_DeleteOnClose);
x += wordLabel->width() +2;
if (x >=245) {
x =5;
y += wordLabel->height() +2;
}
}
}
setAcceptDrops(true);
setMinimumSize(400,qMax(200, y));
setWindowTitle(tr("Draggable Text"));
}
void DragWidget::dragEnterEvent(QDragEnterEvent*event)
{
if (event->mimeData()->hasText()) {
if (event->source() ==this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else {
event->ignore();
}
}
void DragWidget::dropEvent(QDropEvent*event)
{
if (event->mimeData()->hasText()) {
constQMimeData*mime = event->mimeData();
QStringList pieces = mime->text().split(QRegularExpression(QStringLiteral("\\s+")),QString::SkipEmptyParts);
QPoint position = event->pos();
QPoint hotSpot;
QByteArrayList hotSpotPos = mime->data(hotSpotMimeDataKey()).split(' ');
if (hotSpotPos.size() ==2) {
hotSpot.setX(hotSpotPos.first().toInt());
hotSpot.setY(hotSpotPos.last().toInt());
}
for (constQString&piece : pieces) {
QLabel*newLabel = createDragLabel(piece,this);
newLabel->move(position - hotSpot);
newLabel->show();
newLabel->setAttribute(Qt::WA_DeleteOnClose);
position +=QPoint(newLabel->width(),0);
}
if (event->source() ==this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else {
event->ignore();
}
for (QWidget*widget : findChildren<QWidget*>()) {
if (!widget->isVisible())
widget->deleteLater();
}
}
void DragWidget::mousePressEvent(QMouseEvent*event)
{
QLabel*child = qobject_cast<QLabel*>(childAt(event->pos()));
if (!child)
return;
QPoint hotSpot = event->pos() - child->pos();
QMimeData*mimeData =newQMimeData;
mimeData->setText(child->text());
mimeData->setData(hotSpotMimeDataKey(),QByteArray::number(hotSpot.x()) +' '+QByteArray::number(hotSpot.y()));
qreal dpr = window()->windowHandle()->devicePixelRatio();
QPixmap pixmap(child->size() * dpr);
pixmap.setDevicePixelRatio(dpr);
child->render(&pixmap);
QDrag*drag =newQDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(pixmap);
drag->setHotSpot(hotSpot);
Qt::DropAction dropAction = drag->exec(Qt::CopyAction |Qt::MoveAction,Qt::CopyAction);
if (dropAction ==Qt::MoveAction)
child->close();
}