summaryrefslogtreecommitdiff
path: root/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.cpp
blob: 5634c4eb7f4581be9acca55795a5c5603f3100b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (C) 2016 Jochen Becher
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

#include "diagramview.h"

#include "qmt/diagram_ui/diagram_mime_types.h"

#include "qmt/infrastructure/uid.h"
#include "qmt/diagram_scene/diagramscenemodel.h"
#include "qmt/tasks/diagramscenecontroller.h"

#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDragLeaveEvent>
#include <QDropEvent>
#include <QMimeData>

namespace qmt {

DiagramView::DiagramView(QWidget *parent)
    : QGraphicsView(parent)
{
    setAcceptDrops(true);
    setAlignment(Qt::AlignLeft | Qt::AlignTop);
    setDragMode(QGraphicsView::RubberBandDrag);
    setFrameShape(QFrame::NoFrame);
    setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
}

DiagramView::~DiagramView()
{
}

DiagramSceneModel *DiagramView::diagramSceneModel() const
{
    return m_diagramSceneModel;
}

void DiagramView::setDiagramSceneModel(DiagramSceneModel *diagramSceneModel)
{
    setScene(nullptr);
    m_diagramSceneModel = diagramSceneModel;
    if (diagramSceneModel) {
        setScene(m_diagramSceneModel->graphicsScene());
        connect(m_diagramSceneModel, &DiagramSceneModel::sceneRectChanged,
                this, &DiagramView::onSceneRectChanged, Qt::QueuedConnection);
        // Signal is connected after diagram is updated. Enforce setting of scene rect.
        onSceneRectChanged(m_diagramSceneModel->sceneRect());
    }
}

void DiagramView::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasFormat(QLatin1String(MIME_TYPE_MODEL_ELEMENTS))) {
        bool accept = false;
        QDataStream dataStream(event->mimeData()->data(QLatin1String(MIME_TYPE_MODEL_ELEMENTS)));
        while (dataStream.status() == QDataStream::Ok) {
            QString key;
            dataStream >> key;
            if (!key.isEmpty()) {
                if (m_diagramSceneModel->diagramSceneController()
                        ->isAddingAllowed(Uid(QUuid(key)), m_diagramSceneModel->diagram()))
                    accept = true;
            }
        }
        event->setAccepted(accept);
    } else if (event->mimeData()->hasFormat(QLatin1String(MIME_TYPE_NEW_MODEL_ELEMENTS))) {
        bool accept = false;
        QDataStream dataStream(event->mimeData()->data(QLatin1String(MIME_TYPE_NEW_MODEL_ELEMENTS)));
        while (dataStream.status() == QDataStream::Ok) {
            QString newElementId;
            dataStream >> newElementId;
            if (!newElementId.isEmpty()) {
                // TODO ask a factory if newElementId is a known type
                accept = true;
            }
        }
        event->setAccepted(accept);
    } else {
        event->ignore();
    }
}

void DiagramView::dragLeaveEvent(QDragLeaveEvent *event)
{
    event->accept();
}

void DiagramView::dragMoveEvent(QDragMoveEvent *event)
{
    event->accept();
}

void DiagramView::dropEvent(QDropEvent *event)
{
    event->setDropAction(Qt::MoveAction);
    DiagramSceneController *diagramSceneController = m_diagramSceneModel->diagramSceneController();
    if (event->mimeData()->hasFormat(QLatin1String(MIME_TYPE_MODEL_ELEMENTS))) {
        QDataStream dataStream(event->mimeData()->data(QLatin1String(MIME_TYPE_MODEL_ELEMENTS)));
        while (dataStream.status() == QDataStream::Ok) {
            QString key;
            dataStream >> key;
            if (!key.isEmpty()) {
                if (diagramSceneController->isAddingAllowed(Uid(QUuid(key)),
                                                            m_diagramSceneModel->diagram())) {
                    diagramSceneController->addExistingModelElement(Uid(QUuid(key)),
                                                                    mapToScene(event->pos()),
                                                                    m_diagramSceneModel->diagram());
                }
            }
        }
        event->accept();
    } else if (event->mimeData()->hasFormat(QLatin1String(MIME_TYPE_NEW_MODEL_ELEMENTS))) {
        QDataStream dataStream(event->mimeData()->data(QLatin1String(MIME_TYPE_NEW_MODEL_ELEMENTS)));
        while (dataStream.status() == QDataStream::Ok) {
            QString newElementId;
            QString name;
            QString stereotype;
            dataStream >> newElementId >> name >> stereotype;
            if (!newElementId.isEmpty()) {
                QPointF pos = mapToScene(event->pos());
                diagramSceneController->dropNewElement(
                            newElementId, name, stereotype, m_diagramSceneModel->findTopmostElement(pos),
                            pos, m_diagramSceneModel->diagram(), event->pos(), size());
            }
        }
        event->accept();
    } else  {
        event->ignore();
    }
}

void DiagramView::onSceneRectChanged(const QRectF &sceneRect)
{
    // add some adjustment to all 4 sides
    static const qreal ADJUSTMENT = 80;
    QRectF rect = sceneRect.adjusted(-ADJUSTMENT, -ADJUSTMENT, ADJUSTMENT, ADJUSTMENT);
    setSceneRect(rect);
}

} // namespace qmt