dupdatevisitor.cpp 8.15 KB
Newer Older
1
/****************************************************************************
Jochen Becher's avatar
Jochen Becher committed
2
**
3 4
** Copyright (C) 2016 Jochen Becher
** Contact: https://www.qt.io/licensing/
Jochen Becher's avatar
Jochen Becher committed
5 6 7 8 9 10 11
**
** This file is part of Qt Creator.
**
** 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
12 13 14
** 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.
Jochen Becher's avatar
Jochen Becher committed
15
**
16 17 18 19 20 21 22
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
Jochen Becher's avatar
Jochen Becher committed
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
**
****************************************************************************/

#include "dupdatevisitor.h"

#include "qmt/diagram/delement.h"
#include "qmt/diagram/dobject.h"
#include "qmt/diagram/dclass.h"
#include "qmt/diagram/ditem.h"
#include "qmt/diagram/drelation.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dassociation.h"

#include "qmt/model/melement.h"
#include "qmt/model/mobject.h"
#include "qmt/model/mclass.h"
#include "qmt/model/mcomponent.h"
#include "qmt/model/mpackage.h"
#include "qmt/model/mdiagram.h"
#include "qmt/model/mcanvasdiagram.h"
#include "qmt/model/mitem.h"
#include "qmt/model/mrelation.h"
#include "qmt/model/massociation.h"
#include "qmt/model/mdependency.h"
#include "qmt/model/minheritance.h"

namespace qmt {

51
DUpdateVisitor::DUpdateVisitor(DElement *target, const MDiagram *diagram, bool checkNeedsUpdate)
52 53
    : m_target(target),
      m_diagram(diagram),
54
      m_checkNeedsUpdate(checkNeedsUpdate),
55
      m_isUpdateNeeded(!checkNeedsUpdate)
Jochen Becher's avatar
Jochen Becher committed
56 57 58
{
}

59
void DUpdateVisitor::setCheckNeedsUpdate(bool checkNeedsUpdate)
Jochen Becher's avatar
Jochen Becher committed
60
{
61
    m_checkNeedsUpdate = checkNeedsUpdate;
62
    m_isUpdateNeeded = !checkNeedsUpdate;
Jochen Becher's avatar
Jochen Becher committed
63 64 65 66 67 68
}

void DUpdateVisitor::visitMElement(const MElement *element)
{
    Q_UNUSED(element);

69
    QMT_CHECK(m_target);
Jochen Becher's avatar
Jochen Becher committed
70 71 72 73
}

void DUpdateVisitor::visitMObject(const MObject *object)
{
74
    auto dobject = dynamic_cast<DObject *>(m_target);
Jochen Becher's avatar
Jochen Becher committed
75
    QMT_CHECK(dobject);
76
    if (isUpdating(object->stereotypes() != dobject->stereotypes()))
77 78 79 80
        dobject->setStereotypes(object->stereotypes());
    const MObject *objectOwner = object->owner();
    const MObject *diagramOwner = m_diagram->owner();
    if (objectOwner && diagramOwner && objectOwner->uid() != diagramOwner->uid()) {
81
        if (isUpdating(objectOwner->name() != dobject->context()))
82
            dobject->setContext(objectOwner->name());
Jochen Becher's avatar
Jochen Becher committed
83
    } else {
84
        if (isUpdating(!dobject->context().isEmpty()))
Jochen Becher's avatar
Jochen Becher committed
85 86
            dobject->setContext(QString());
    }
87
    if (isUpdating(object->name() != dobject->name()))
88
        dobject->setName(object->name());
Jochen Becher's avatar
Jochen Becher committed
89 90 91
    // TODO unlikely that this is called for all objects if hierarchy is modified
    // PERFORM remove loop
    int depth = 1;
92
    const MObject *owner = object->owner();
Jochen Becher's avatar
Jochen Becher committed
93
    while (owner) {
94
        owner = owner->owner();
Jochen Becher's avatar
Jochen Becher committed
95 96
        depth += 1;
    }
97
    if (isUpdating(depth != dobject->depth()))
Jochen Becher's avatar
Jochen Becher committed
98 99 100 101 102 103 104 105 106 107 108
        dobject->setDepth(depth);
    visitMElement(object);
}

void DUpdateVisitor::visitMPackage(const MPackage *package)
{
    visitMObject(package);
}

void DUpdateVisitor::visitMClass(const MClass *klass)
{
109
    auto dclass = dynamic_cast<DClass *>(m_target);
Jochen Becher's avatar
Jochen Becher committed
110
    QMT_CHECK(dclass);
111
    if (isUpdating(klass->umlNamespace() != dclass->umlNamespace()))
112
        dclass->setUmlNamespace(klass->umlNamespace());
113
    if (isUpdating(klass->templateParameters() != dclass->templateParameters()))
114
        dclass->setTemplateParameters(klass->templateParameters());
115
    if (isUpdating(klass->members() != dclass->members()))
116
        dclass->setMembers(klass->members());
Jochen Becher's avatar
Jochen Becher committed
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    visitMObject(klass);
}

void DUpdateVisitor::visitMComponent(const MComponent *component)
{
    visitMObject(component);
}

void DUpdateVisitor::visitMDiagram(const MDiagram *diagram)
{
    visitMObject(diagram);
}

void DUpdateVisitor::visitMCanvasDiagram(const MCanvasDiagram *diagram)
{
    visitMDiagram(diagram);
}

void DUpdateVisitor::visitMItem(const MItem *item)
{
137
    auto ditem = dynamic_cast<DItem *>(m_target);
Jochen Becher's avatar
Jochen Becher committed
138
    QMT_CHECK(ditem);
139
    if (isUpdating(item->isShapeEditable() != ditem->isShapeEditable()))
Jochen Becher's avatar
Jochen Becher committed
140
        ditem->setShapeEditable(item->isShapeEditable());
141
    if (isUpdating(item->variety() != ditem->variety()))
142
        ditem->setVariety(item->variety());
Jochen Becher's avatar
Jochen Becher committed
143 144 145 146 147
    visitMObject(item);
}

void DUpdateVisitor::visitMRelation(const MRelation *relation)
{
148
    auto drelation = dynamic_cast<DRelation *>(m_target);
Jochen Becher's avatar
Jochen Becher committed
149
    QMT_CHECK(drelation);
150
    if (isUpdating(relation->stereotypes() != drelation->stereotypes()))
151
        drelation->setStereotypes(relation->stereotypes());
152
    if (isUpdating(relation->name() != drelation->name()))
153
        drelation->setName(relation->name());
154 155 156
    // TODO improve performance of MDiagram::findDiagramElement
    DObject *endAObject = dynamic_cast<DObject *>(m_diagram->findDiagramElement(drelation->endAUid()));
    if (!endAObject || relation->endAUid() != endAObject->modelUid()) {
157
        (void) isUpdating(true);
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
        endAObject = 0;
        // TODO use DiagramController::findDelegate (and improve performance of that method)
        foreach (DElement *diagramElement, m_diagram->diagramElements()) {
            if (diagramElement->modelUid().isValid() && diagramElement->modelUid() == relation->endAUid()) {
                endAObject = dynamic_cast<DObject *>(diagramElement);
                break;
            }
        }
        if (endAObject)
            drelation->setEndAUid(endAObject->uid());
        else
            drelation->setEndAUid(Uid::invalidUid());
    }
    DObject *endBObject = dynamic_cast<DObject *>(m_diagram->findDiagramElement(drelation->endBUid()));
    if (!endBObject || relation->endBUid() != endBObject->modelUid()) {
173
        (void) isUpdating(true);
174 175 176 177 178 179 180 181 182 183 184 185 186
        endBObject = 0;
        // TODO use DiagramController::findDelegate
        foreach (DElement *diagramElement, m_diagram->diagramElements()) {
            if (diagramElement->modelUid().isValid() && diagramElement->modelUid() == relation->endBUid()) {
                endBObject = dynamic_cast<DObject *>(diagramElement);
                break;
            }
        }
        if (endBObject)
            drelation->setEndBUid(endBObject->uid());
        else
            drelation->setEndBUid(Uid::invalidUid());
    }
Jochen Becher's avatar
Jochen Becher committed
187 188 189 190 191
    visitMElement(relation);
}

void DUpdateVisitor::visitMDependency(const MDependency *dependency)
{
192
    auto ddependency = dynamic_cast<DDependency *>(m_target);
Jochen Becher's avatar
Jochen Becher committed
193
    QMT_CHECK(ddependency);
194
    if (isUpdating(dependency->direction() != ddependency->direction()))
195
        ddependency->setDirection(dependency->direction());
Jochen Becher's avatar
Jochen Becher committed
196 197 198 199 200 201 202 203 204 205
    visitMRelation(dependency);
}

void DUpdateVisitor::visitMInheritance(const MInheritance *inheritance)
{
    visitMRelation(inheritance);
}

void DUpdateVisitor::visitMAssociation(const MAssociation *association)
{
206
    auto dassociation = dynamic_cast<DAssociation *>(m_target);
Jochen Becher's avatar
Jochen Becher committed
207
    QMT_CHECK(dassociation);
208
    DAssociationEnd endA;
209 210 211 212
    endA.setName(association->endA().name());
    endA.setCardinatlity(association->endA().cardinality());
    endA.setNavigable(association->endA().isNavigable());
    endA.setKind(association->endA().kind());
213
    if (isUpdating(endA != dassociation->endA()))
214
        dassociation->setEndA(endA);
215
    DAssociationEnd endB;
216 217 218 219
    endB.setName(association->endB().name());
    endB.setCardinatlity(association->endB().cardinality());
    endB.setNavigable(association->endB().isNavigable());
    endB.setKind(association->endB().kind());
220
    if (isUpdating(endB != dassociation->endB()))
221
        dassociation->setEndB(endB);
Jochen Becher's avatar
Jochen Becher committed
222 223 224
    visitMRelation(association);
}

225
bool DUpdateVisitor::isUpdating(bool valueChanged)
Jochen Becher's avatar
Jochen Becher committed
226
{
227
    if (m_checkNeedsUpdate) {
228
        if (valueChanged)
229
            m_isUpdateNeeded = true;
Jochen Becher's avatar
Jochen Becher committed
230 231
        return false;
    }
232
    return valueChanged;
Jochen Becher's avatar
Jochen Becher committed
233 234
}

235
} // namespace qmt