forked from qt-creator/qt-creator
ModelEditor: move 3rd_party/modeling into libs/modelinglib
Only moved the files and adapted .pro and .qbs files accordingly. Change-Id: I7c17c2ebf246595c104edf60013bf78379955aa7 Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
237
src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp
Normal file
237
src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp
Normal file
@@ -0,0 +1,237 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "dclonevisitor.h"
|
||||
|
||||
#include "qmt/diagram/delement.h"
|
||||
#include "qmt/diagram/dobject.h"
|
||||
#include "qmt/diagram/dpackage.h"
|
||||
#include "qmt/diagram/dclass.h"
|
||||
#include "qmt/diagram/dcomponent.h"
|
||||
#include "qmt/diagram/ddiagram.h"
|
||||
#include "qmt/diagram/ditem.h"
|
||||
#include "qmt/diagram/drelation.h"
|
||||
#include "qmt/diagram/dinheritance.h"
|
||||
#include "qmt/diagram/ddependency.h"
|
||||
#include "qmt/diagram/dassociation.h"
|
||||
#include "qmt/diagram/dannotation.h"
|
||||
#include "qmt/diagram/dboundary.h"
|
||||
#include "qmt/infrastructure/qmtassert.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
DCloneVisitor::DCloneVisitor()
|
||||
: m_cloned(0)
|
||||
{
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDElement(const DElement *element)
|
||||
{
|
||||
Q_UNUSED(element);
|
||||
QMT_CHECK(m_cloned);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDObject(const DObject *object)
|
||||
{
|
||||
QMT_CHECK(m_cloned);
|
||||
visitDElement(object);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDPackage(const DPackage *package)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DPackage(*package);
|
||||
visitDObject(package);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDClass(const DClass *klass)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DClass(*klass);
|
||||
visitDObject(klass);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDComponent(const DComponent *component)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DComponent(*component);
|
||||
visitDObject(component);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDDiagram(const DDiagram *diagram)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DDiagram(*diagram);
|
||||
visitDObject(diagram);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDItem(const DItem *item)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DItem(*item);
|
||||
visitDObject(item);
|
||||
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDRelation(const DRelation *relation)
|
||||
{
|
||||
QMT_CHECK(m_cloned);
|
||||
visitDElement(relation);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDInheritance(const DInheritance *inheritance)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DInheritance(*inheritance);
|
||||
visitDRelation(inheritance);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDDependency(const DDependency *dependency)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DDependency(*dependency);
|
||||
visitDRelation(dependency);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDAssociation(const DAssociation *association)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DAssociation(*association);
|
||||
visitDRelation(association);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDAnnotation(const DAnnotation *annotation)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DAnnotation(*annotation);
|
||||
visitDElement(annotation);
|
||||
}
|
||||
|
||||
void DCloneVisitor::visitDBoundary(const DBoundary *boundary)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DBoundary(*boundary);
|
||||
visitDElement(boundary);
|
||||
}
|
||||
|
||||
DCloneDeepVisitor::DCloneDeepVisitor()
|
||||
: m_cloned(0)
|
||||
{
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDElement(const DElement *element)
|
||||
{
|
||||
Q_UNUSED(element);
|
||||
QMT_CHECK(m_cloned);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDObject(const DObject *object)
|
||||
{
|
||||
QMT_CHECK(m_cloned);
|
||||
visitDElement(object);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDPackage(const DPackage *package)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DPackage(*package);
|
||||
visitDObject(package);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDClass(const DClass *klass)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DClass(*klass);
|
||||
visitDObject(klass);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDComponent(const DComponent *component)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DComponent(*component);
|
||||
visitDObject(component);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDDiagram(const DDiagram *diagram)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DDiagram(*diagram);
|
||||
visitDObject(diagram);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDItem(const DItem *item)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DItem(*item);
|
||||
visitDObject(item);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDRelation(const DRelation *relation)
|
||||
{
|
||||
QMT_CHECK(m_cloned);
|
||||
visitDElement(relation);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDInheritance(const DInheritance *inheritance)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DInheritance(*inheritance);
|
||||
visitDRelation(inheritance);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDDependency(const DDependency *dependency)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DDependency(*dependency);
|
||||
visitDRelation(dependency);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDAssociation(const DAssociation *association)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DAssociation(*association);
|
||||
visitDRelation(association);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDAnnotation(const DAnnotation *annotation)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DAnnotation(*annotation);
|
||||
visitDElement(annotation);
|
||||
}
|
||||
|
||||
void DCloneDeepVisitor::visitDBoundary(const DBoundary *boundary)
|
||||
{
|
||||
if (!m_cloned)
|
||||
m_cloned = new DBoundary(*boundary);
|
||||
visitDElement(boundary);
|
||||
}
|
||||
|
||||
} // namespace qmt
|
||||
91
src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.h
Normal file
91
src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_DCLONEVISITOR_H
|
||||
#define QMT_DCLONEVISITOR_H
|
||||
|
||||
#include "qmt/diagram/dconstvisitor.h"
|
||||
#include "qmt/infrastructure/qmt_global.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class QMT_EXPORT DCloneVisitor : public DConstVisitor
|
||||
{
|
||||
public:
|
||||
DCloneVisitor();
|
||||
|
||||
DElement *cloned() const { return m_cloned; }
|
||||
|
||||
void visitDElement(const DElement *element) override;
|
||||
void visitDObject(const DObject *object) override;
|
||||
void visitDPackage(const DPackage *package) override;
|
||||
void visitDClass(const DClass *klass) override;
|
||||
void visitDComponent(const DComponent *component) override;
|
||||
void visitDDiagram(const DDiagram *diagram) override;
|
||||
void visitDItem(const DItem *item) override;
|
||||
void visitDRelation(const DRelation *relation) override;
|
||||
void visitDInheritance(const DInheritance *inheritance) override;
|
||||
void visitDDependency(const DDependency *dependency) override;
|
||||
void visitDAssociation(const DAssociation *association) override;
|
||||
void visitDAnnotation(const DAnnotation *annotation) override;
|
||||
void visitDBoundary(const DBoundary *boundary) override;
|
||||
|
||||
private:
|
||||
DElement *m_cloned;
|
||||
};
|
||||
|
||||
class QMT_EXPORT DCloneDeepVisitor : public DConstVisitor
|
||||
{
|
||||
public:
|
||||
DCloneDeepVisitor();
|
||||
|
||||
DElement *cloned() const { return m_cloned; }
|
||||
|
||||
void visitDElement(const DElement *element) override;
|
||||
void visitDObject(const DObject *object) override;
|
||||
void visitDPackage(const DPackage *package) override;
|
||||
void visitDClass(const DClass *klass) override;
|
||||
void visitDComponent(const DComponent *component) override;
|
||||
void visitDDiagram(const DDiagram *diagram) override;
|
||||
void visitDItem(const DItem *item) override;
|
||||
void visitDRelation(const DRelation *relation) override;
|
||||
void visitDInheritance(const DInheritance *inheritance) override;
|
||||
void visitDDependency(const DDependency *dependency) override;
|
||||
void visitDAssociation(const DAssociation *association) override;
|
||||
void visitDAnnotation(const DAnnotation *annotation) override;
|
||||
void visitDBoundary(const DBoundary *boundary) override;
|
||||
|
||||
private:
|
||||
DElement *m_cloned;
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
||||
#endif // QMT_DCLONEVISITOR_H
|
||||
45
src/libs/modelinglib/qmt/diagram_controller/dcontainer.h
Normal file
45
src/libs/modelinglib/qmt/diagram_controller/dcontainer.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_DCONTAINER_H
|
||||
#define QMT_DCONTAINER_H
|
||||
|
||||
#include "qmt/controller/container.h"
|
||||
#include "qmt/diagram/delement.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class QMT_EXPORT DContainer : public Container<DElement>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
||||
#endif // QMT_DCONTAINER_H
|
||||
157
src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp
Normal file
157
src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "dfactory.h"
|
||||
|
||||
#include "qmt/diagram/delement.h"
|
||||
#include "qmt/diagram/dobject.h"
|
||||
#include "qmt/diagram/dpackage.h"
|
||||
#include "qmt/diagram/dclass.h"
|
||||
#include "qmt/diagram/dcomponent.h"
|
||||
#include "qmt/diagram/ddiagram.h"
|
||||
#include "qmt/diagram/ditem.h"
|
||||
#include "qmt/diagram/drelation.h"
|
||||
#include "qmt/diagram/dinheritance.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 {
|
||||
|
||||
DFactory::DFactory()
|
||||
: m_product(0)
|
||||
{
|
||||
}
|
||||
|
||||
void DFactory::visitMElement(const MElement *element)
|
||||
{
|
||||
Q_UNUSED(element);
|
||||
QMT_CHECK(m_product);
|
||||
}
|
||||
|
||||
void DFactory::visitMObject(const MObject *object)
|
||||
{
|
||||
auto diagramObject = dynamic_cast<DObject *>(m_product);
|
||||
QMT_CHECK(diagramObject);
|
||||
diagramObject->setModelUid(object->uid());
|
||||
visitMElement(object);
|
||||
}
|
||||
|
||||
void DFactory::visitMPackage(const MPackage *package)
|
||||
{
|
||||
QMT_CHECK(!m_product);
|
||||
auto diagramPackage = new DPackage();
|
||||
m_product = diagramPackage;
|
||||
visitMObject(package);
|
||||
}
|
||||
|
||||
void DFactory::visitMClass(const MClass *klass)
|
||||
{
|
||||
QMT_CHECK(!m_product);
|
||||
auto diagramKlass = new DClass();
|
||||
m_product = diagramKlass;
|
||||
visitMObject(klass);
|
||||
}
|
||||
|
||||
void DFactory::visitMComponent(const MComponent *component)
|
||||
{
|
||||
QMT_CHECK(!m_product);
|
||||
auto diagramComponent = new DComponent();
|
||||
m_product = diagramComponent;
|
||||
visitMObject(component);
|
||||
}
|
||||
|
||||
void DFactory::visitMDiagram(const MDiagram *diagram)
|
||||
{
|
||||
QMT_CHECK(!m_product);
|
||||
auto diagramDiagram = new DDiagram();
|
||||
m_product = diagramDiagram;
|
||||
visitMObject(diagram);
|
||||
}
|
||||
|
||||
void DFactory::visitMCanvasDiagram(const MCanvasDiagram *diagram)
|
||||
{
|
||||
QMT_CHECK(!m_product);
|
||||
visitMDiagram(diagram);
|
||||
}
|
||||
|
||||
void DFactory::visitMItem(const MItem *item)
|
||||
{
|
||||
QMT_CHECK(!m_product);
|
||||
auto diagramItem = new DItem();
|
||||
m_product = diagramItem;
|
||||
visitMObject(item);
|
||||
}
|
||||
|
||||
void DFactory::visitMRelation(const MRelation *relation)
|
||||
{
|
||||
auto diagramRelation = dynamic_cast<DRelation *>(m_product);
|
||||
QMT_CHECK(diagramRelation);
|
||||
diagramRelation->setModelUid(relation->uid());
|
||||
visitMElement(relation);
|
||||
}
|
||||
|
||||
void DFactory::visitMDependency(const MDependency *dependency)
|
||||
{
|
||||
QMT_CHECK(!m_product);
|
||||
auto diagramDependency = new DDependency();
|
||||
m_product = diagramDependency;
|
||||
visitMRelation(dependency);
|
||||
}
|
||||
|
||||
void DFactory::visitMInheritance(const MInheritance *inheritance)
|
||||
{
|
||||
QMT_CHECK(!m_product);
|
||||
auto diagramInheritance = new DInheritance();
|
||||
m_product = diagramInheritance;
|
||||
visitMRelation(inheritance);
|
||||
}
|
||||
|
||||
void DFactory::visitMAssociation(const MAssociation *association)
|
||||
{
|
||||
QMT_CHECK(!m_product);
|
||||
auto diagramAssociation = new DAssociation();
|
||||
m_product = diagramAssociation;
|
||||
visitMRelation(association);
|
||||
}
|
||||
|
||||
} // namespace qmt
|
||||
67
src/libs/modelinglib/qmt/diagram_controller/dfactory.h
Normal file
67
src/libs/modelinglib/qmt/diagram_controller/dfactory.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_DFACTORY_H
|
||||
#define QMT_DFACTORY_H
|
||||
|
||||
#include "qmt/model/mconstvisitor.h"
|
||||
#include "qmt/infrastructure/qmt_global.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class DElement;
|
||||
|
||||
class QMT_EXPORT DFactory : public MConstVisitor
|
||||
{
|
||||
public:
|
||||
DFactory();
|
||||
|
||||
DElement *product() const { return m_product; }
|
||||
|
||||
void visitMElement(const MElement *element) override;
|
||||
void visitMObject(const MObject *object) override;
|
||||
void visitMPackage(const MPackage *package) override;
|
||||
void visitMClass(const MClass *klass) override;
|
||||
void visitMComponent(const MComponent *component) override;
|
||||
void visitMDiagram(const MDiagram *diagram) override;
|
||||
void visitMCanvasDiagram(const MCanvasDiagram *diagram) override;
|
||||
void visitMItem(const MItem *item) override;
|
||||
void visitMRelation(const MRelation *relation) override;
|
||||
void visitMDependency(const MDependency *dependency) override;
|
||||
void visitMInheritance(const MInheritance *inheritance) override;
|
||||
void visitMAssociation(const MAssociation *association) override;
|
||||
|
||||
private:
|
||||
DElement *m_product;
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
||||
#endif // QMT_DFACTORY_H
|
||||
@@ -0,0 +1,172 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "dflatassignmentvisitor.h"
|
||||
|
||||
#include "qmt/diagram/delement.h"
|
||||
#include "qmt/diagram/dobject.h"
|
||||
#include "qmt/diagram/dpackage.h"
|
||||
#include "qmt/diagram/dclass.h"
|
||||
#include "qmt/diagram/dcomponent.h"
|
||||
#include "qmt/diagram/ddiagram.h"
|
||||
#include "qmt/diagram/ditem.h"
|
||||
#include "qmt/diagram/drelation.h"
|
||||
#include "qmt/diagram/dinheritance.h"
|
||||
#include "qmt/diagram/ddependency.h"
|
||||
#include "qmt/diagram/dassociation.h"
|
||||
#include "qmt/diagram/dannotation.h"
|
||||
#include "qmt/diagram/dboundary.h"
|
||||
#include "qmt/infrastructure/qmtassert.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
// TODO may flat assignment visitor use operator=() ?
|
||||
|
||||
DFlatAssignmentVisitor::DFlatAssignmentVisitor(DElement *target)
|
||||
: m_target(target)
|
||||
{
|
||||
QMT_CHECK(target);
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDElement(const DElement *element)
|
||||
{
|
||||
Q_UNUSED(element);
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDObject(const DObject *object)
|
||||
{
|
||||
visitDElement(object);
|
||||
auto target = dynamic_cast<DObject *>(m_target);
|
||||
QMT_CHECK(target);
|
||||
target->setStereotypes(object->stereotypes());
|
||||
target->setName(object->name());
|
||||
target->setPos(object->pos());
|
||||
target->setRect(object->rect());
|
||||
target->setAutoSized(object->isAutoSized());
|
||||
target->setDepth(object->depth());
|
||||
target->setVisualPrimaryRole(object->visualPrimaryRole());
|
||||
target->setVisualSecondaryRole(object->visualSecondaryRole());
|
||||
target->setVisualEmphasized(object->isVisualEmphasized());
|
||||
target->setStereotypeDisplay(object->stereotypeDisplay());
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDPackage(const DPackage *package)
|
||||
{
|
||||
visitDObject(package);
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDClass(const DClass *klass)
|
||||
{
|
||||
visitDObject(klass);
|
||||
auto target = dynamic_cast<DClass *>(m_target);
|
||||
QMT_CHECK(target);
|
||||
target->setUmlNamespace(klass->umlNamespace());
|
||||
target->setTemplateParameters(klass->templateParameters());
|
||||
target->setTemplateDisplay(klass->templateDisplay());
|
||||
target->setMembers(klass->members());
|
||||
target->setShowAllMembers(klass->showAllMembers());
|
||||
target->setVisibleMembers(klass->visibleMembers());
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDComponent(const DComponent *component)
|
||||
{
|
||||
visitDObject(component);
|
||||
auto target = dynamic_cast<DComponent *>(m_target);
|
||||
QMT_CHECK(target);
|
||||
target->setPlainShape(component->isPlainShape());
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDDiagram(const DDiagram *diagram)
|
||||
{
|
||||
visitDObject(diagram);
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDItem(const DItem *item)
|
||||
{
|
||||
visitDObject(item);
|
||||
auto target = dynamic_cast<DItem *>(m_target);
|
||||
QMT_CHECK(target);
|
||||
target->setVariety(target->variety());
|
||||
target->setShapeEditable(target->isShapeEditable());
|
||||
target->setShape(target->shape());
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDRelation(const DRelation *relation)
|
||||
{
|
||||
visitDElement(relation);
|
||||
auto target = dynamic_cast<DRelation *>(m_target);
|
||||
QMT_CHECK(target);
|
||||
target->setStereotypes(relation->stereotypes());
|
||||
target->setIntermediatePoints(relation->intermediatePoints());
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDInheritance(const DInheritance *inheritance)
|
||||
{
|
||||
visitDRelation(inheritance);
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDDependency(const DDependency *dependency)
|
||||
{
|
||||
visitDRelation(dependency);
|
||||
auto target = dynamic_cast<DDependency *>(m_target);
|
||||
QMT_CHECK(target);
|
||||
target->setDirection(dependency->direction());
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDAssociation(const DAssociation *association)
|
||||
{
|
||||
visitDRelation(association);
|
||||
auto target = dynamic_cast<DAssociation *>(m_target);
|
||||
QMT_CHECK(target);
|
||||
target->setEndA(association->endA());
|
||||
target->setEndB(association->endB());
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDAnnotation(const DAnnotation *annotation)
|
||||
{
|
||||
visitDElement(annotation);
|
||||
auto target = dynamic_cast<DAnnotation *>(m_target);
|
||||
target->setText(annotation->text());
|
||||
target->setPos(annotation->pos());
|
||||
target->setRect(annotation->rect());
|
||||
target->setAutoSized(annotation->isAutoSized());
|
||||
target->setVisualRole(annotation->visualRole());
|
||||
}
|
||||
|
||||
void DFlatAssignmentVisitor::visitDBoundary(const DBoundary *boundary)
|
||||
{
|
||||
visitDElement(boundary);
|
||||
auto target = dynamic_cast<DBoundary *>(m_target);
|
||||
target->setText(boundary->text());
|
||||
target->setPos(boundary->pos());
|
||||
target->setRect(boundary->rect());
|
||||
}
|
||||
|
||||
} // namespace qmt
|
||||
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_DFLATASSIGNMENTVISITOR_H
|
||||
#define QMT_DFLATASSIGNMENTVISITOR_H
|
||||
|
||||
#include "qmt/diagram/dconstvisitor.h"
|
||||
#include "qmt/infrastructure/qmt_global.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class QMT_EXPORT DFlatAssignmentVisitor : public DConstVisitor
|
||||
{
|
||||
public:
|
||||
explicit DFlatAssignmentVisitor(DElement *target);
|
||||
|
||||
void visitDElement(const DElement *element) override;
|
||||
void visitDObject(const DObject *object) override;
|
||||
void visitDPackage(const DPackage *package) override;
|
||||
void visitDClass(const DClass *klass) override;
|
||||
void visitDComponent(const DComponent *component) override;
|
||||
void visitDDiagram(const DDiagram *diagram) override;
|
||||
void visitDItem(const DItem *item) override;
|
||||
void visitDRelation(const DRelation *relation) override;
|
||||
void visitDInheritance(const DInheritance *inheritance) override;
|
||||
void visitDDependency(const DDependency *dependency) override;
|
||||
void visitDAssociation(const DAssociation *association) override;
|
||||
void visitDAnnotation(const DAnnotation *annotation) override;
|
||||
void visitDBoundary(const DBoundary *boundary) override;
|
||||
|
||||
private:
|
||||
DElement *m_target;
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
||||
#endif // QMT_DFLATASSIGNMENTVISITOR_H
|
||||
@@ -0,0 +1,905 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "diagramcontroller.h"
|
||||
|
||||
#include "dselection.h"
|
||||
#include "dcontainer.h"
|
||||
#include "dreferences.h"
|
||||
#include "dflatassignmentvisitor.h"
|
||||
#include "dclonevisitor.h"
|
||||
#include "dupdatevisitor.h"
|
||||
|
||||
#include "qmt/model_controller/modelcontroller.h"
|
||||
#include "qmt/model_controller/mchildrenvisitor.h"
|
||||
|
||||
#include "qmt/controller/undocontroller.h"
|
||||
#include "qmt/controller/undocommand.h"
|
||||
|
||||
#include "qmt/diagram/dobject.h"
|
||||
#include "qmt/diagram/drelation.h"
|
||||
|
||||
#include "qmt/model/mobject.h"
|
||||
#include "qmt/model/mpackage.h"
|
||||
#include "qmt/model/mdiagram.h"
|
||||
#include "qmt/model/mrelation.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class DiagramController::Clone
|
||||
{
|
||||
public:
|
||||
Uid m_elementKey;
|
||||
int m_indexOfElement = -1;
|
||||
DElement *m_clonedElement = 0;
|
||||
};
|
||||
|
||||
class DiagramController::DiagramUndoCommand : public UndoCommand
|
||||
{
|
||||
public:
|
||||
DiagramUndoCommand(DiagramController *diagramController, const Uid &diagramKey, const QString &text)
|
||||
: UndoCommand(text),
|
||||
m_diagramController(diagramController),
|
||||
m_diagramKey(diagramKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
DiagramController *diagramController() const
|
||||
{
|
||||
return m_diagramController;
|
||||
}
|
||||
|
||||
Uid diagramKey() const { return m_diagramKey; }
|
||||
|
||||
MDiagram *diagram() const
|
||||
{
|
||||
MDiagram *diagram = m_diagramController->findDiagram(m_diagramKey);
|
||||
QMT_CHECK(diagram);
|
||||
return diagram;
|
||||
}
|
||||
|
||||
private:
|
||||
DiagramController *m_diagramController = 0;
|
||||
Uid m_diagramKey;
|
||||
};
|
||||
|
||||
class DiagramController::UpdateElementCommand : public DiagramUndoCommand
|
||||
{
|
||||
public:
|
||||
UpdateElementCommand(DiagramController *diagramController, const Uid &diagramKey, DElement *element,
|
||||
DiagramController::UpdateAction updateAction)
|
||||
: DiagramUndoCommand(diagramController, diagramKey, tr("Change")),
|
||||
m_updateAction(updateAction)
|
||||
{
|
||||
DCloneVisitor visitor;
|
||||
element->accept(&visitor);
|
||||
m_clonedElements.insert(visitor.cloned()->uid(), visitor.cloned());
|
||||
}
|
||||
|
||||
~UpdateElementCommand() override
|
||||
{
|
||||
qDeleteAll(m_clonedElements);
|
||||
}
|
||||
|
||||
bool mergeWith(const UndoCommand *other) override
|
||||
{
|
||||
auto otherUpdateCommand = dynamic_cast<const UpdateElementCommand *>(other);
|
||||
if (!otherUpdateCommand)
|
||||
return false;
|
||||
if (diagramKey() != otherUpdateCommand->diagramKey())
|
||||
return false;
|
||||
if (m_updateAction == DiagramController::UpdateMajor
|
||||
|| otherUpdateCommand->m_updateAction == DiagramController::UpdateMajor
|
||||
|| m_updateAction != otherUpdateCommand->m_updateAction) {
|
||||
return false;
|
||||
}
|
||||
// join other elements into this command
|
||||
foreach (const DElement *otherElement, otherUpdateCommand->m_clonedElements.values()) {
|
||||
if (!m_clonedElements.contains(otherElement->uid())) {
|
||||
DCloneVisitor visitor;
|
||||
otherElement->accept(&visitor);
|
||||
m_clonedElements.insert(visitor.cloned()->uid(), visitor.cloned());
|
||||
}
|
||||
}
|
||||
// the last update is a complete update of all changes...
|
||||
return true;
|
||||
}
|
||||
|
||||
void redo() override
|
||||
{
|
||||
if (canRedo()) {
|
||||
swap();
|
||||
UndoCommand::redo();
|
||||
}
|
||||
}
|
||||
|
||||
void undo() override
|
||||
{
|
||||
swap();
|
||||
UndoCommand::undo();
|
||||
}
|
||||
|
||||
private:
|
||||
void swap()
|
||||
{
|
||||
DiagramController *diagramController = this->diagramController();
|
||||
MDiagram *diagram = this->diagram();
|
||||
foreach (DElement *clonedElement, m_clonedElements) {
|
||||
DElement *activeElement = diagramController->findElement(clonedElement->uid(), diagram);
|
||||
QMT_CHECK(activeElement);
|
||||
int row = diagram->diagramElements().indexOf(activeElement);
|
||||
emit diagramController->beginUpdateElement(row, diagram);
|
||||
// clone active element
|
||||
DCloneVisitor cloneVisitor;
|
||||
activeElement->accept(&cloneVisitor);
|
||||
DElement *newElement = cloneVisitor.cloned();
|
||||
// reset active element to cloned element
|
||||
DFlatAssignmentVisitor visitor(activeElement);
|
||||
clonedElement->accept(&visitor);
|
||||
// replace stored element with new cloned active element
|
||||
QMT_CHECK(clonedElement->uid() == newElement->uid());
|
||||
m_clonedElements.insert(newElement->uid(), newElement);
|
||||
delete clonedElement;
|
||||
emit diagramController->endUpdateElement(row, diagram);
|
||||
}
|
||||
diagramController->diagramModified(diagram);
|
||||
}
|
||||
|
||||
DiagramController::UpdateAction m_updateAction = DiagramController::UpdateMajor;
|
||||
QHash<Uid, DElement *> m_clonedElements;
|
||||
};
|
||||
|
||||
class DiagramController::AbstractAddRemCommand : public DiagramUndoCommand
|
||||
{
|
||||
protected:
|
||||
AbstractAddRemCommand(DiagramController *diagramController, const Uid &diagramKey, const QString &commandLabel)
|
||||
: DiagramUndoCommand(diagramController, diagramKey, commandLabel)
|
||||
{
|
||||
}
|
||||
|
||||
~AbstractAddRemCommand() override
|
||||
{
|
||||
foreach (const Clone &clone, m_clonedElements)
|
||||
delete clone.m_clonedElement;
|
||||
}
|
||||
|
||||
void remove()
|
||||
{
|
||||
DiagramController *diagramController = this->diagramController();
|
||||
MDiagram *diagram = this->diagram();
|
||||
bool removed = false;
|
||||
for (int i = 0; i < m_clonedElements.count(); ++i) {
|
||||
Clone &clone = m_clonedElements[i];
|
||||
QMT_CHECK(!clone.m_clonedElement);
|
||||
DElement *activeElement = diagramController->findElement(clone.m_elementKey, diagram);
|
||||
QMT_CHECK(activeElement);
|
||||
clone.m_indexOfElement = diagram->diagramElements().indexOf(activeElement);
|
||||
QMT_CHECK(clone.m_indexOfElement >= 0);
|
||||
emit diagramController->beginRemoveElement(clone.m_indexOfElement, diagram);
|
||||
DCloneDeepVisitor cloneVisitor;
|
||||
activeElement->accept(&cloneVisitor);
|
||||
clone.m_clonedElement = cloneVisitor.cloned();
|
||||
diagram->removeDiagramElement(activeElement);
|
||||
emit diagramController->endRemoveElement(clone.m_indexOfElement, diagram);
|
||||
removed = true;
|
||||
}
|
||||
if (removed)
|
||||
diagramController->diagramModified(diagram);
|
||||
}
|
||||
|
||||
void insert()
|
||||
{
|
||||
DiagramController *diagramController = this->diagramController();
|
||||
MDiagram *diagram = this->diagram();
|
||||
bool inserted = false;
|
||||
for (int i = m_clonedElements.count() - 1; i >= 0; --i) {
|
||||
Clone &clone = m_clonedElements[i];
|
||||
QMT_CHECK(clone.m_clonedElement);
|
||||
QMT_CHECK(clone.m_clonedElement->uid() == clone.m_elementKey);
|
||||
emit diagramController->beginInsertElement(clone.m_indexOfElement, diagram);
|
||||
diagram->insertDiagramElement(clone.m_indexOfElement, clone.m_clonedElement);
|
||||
clone.m_clonedElement = 0;
|
||||
emit diagramController->endInsertElement(clone.m_indexOfElement, diagram);
|
||||
inserted = true;
|
||||
}
|
||||
if (inserted)
|
||||
diagramController->diagramModified(diagram);
|
||||
}
|
||||
|
||||
QList<DiagramController::Clone> m_clonedElements;
|
||||
};
|
||||
|
||||
class DiagramController::AddElementsCommand : public AbstractAddRemCommand
|
||||
{
|
||||
public:
|
||||
AddElementsCommand(DiagramController *diagramController, const Uid &diagramKey, const QString &commandLabel)
|
||||
: AbstractAddRemCommand(diagramController, diagramKey, commandLabel)
|
||||
{
|
||||
}
|
||||
|
||||
void add(const Uid &elementKey)
|
||||
{
|
||||
Clone clone;
|
||||
|
||||
clone.m_elementKey = elementKey;
|
||||
m_clonedElements.append(clone);
|
||||
}
|
||||
|
||||
void redo() override
|
||||
{
|
||||
if (canRedo()) {
|
||||
insert();
|
||||
UndoCommand::redo();
|
||||
}
|
||||
}
|
||||
|
||||
void undo() override
|
||||
{
|
||||
remove();
|
||||
UndoCommand::undo();
|
||||
}
|
||||
};
|
||||
|
||||
class DiagramController::RemoveElementsCommand : public AbstractAddRemCommand
|
||||
{
|
||||
public:
|
||||
RemoveElementsCommand(DiagramController *diagramController, const Uid &diagramKey, const QString &commandLabel)
|
||||
: AbstractAddRemCommand(diagramController, diagramKey, commandLabel)
|
||||
{
|
||||
}
|
||||
|
||||
void add(DElement *element)
|
||||
{
|
||||
Clone clone;
|
||||
|
||||
MDiagram *diagram = this->diagram();
|
||||
clone.m_elementKey = element->uid();
|
||||
clone.m_indexOfElement = diagram->diagramElements().indexOf(element);
|
||||
QMT_CHECK(clone.m_indexOfElement >= 0);
|
||||
DCloneDeepVisitor visitor;
|
||||
element->accept(&visitor);
|
||||
clone.m_clonedElement = visitor.cloned();
|
||||
QMT_CHECK(clone.m_clonedElement);
|
||||
m_clonedElements.append(clone);
|
||||
}
|
||||
|
||||
void redo() override
|
||||
{
|
||||
if (canRedo()) {
|
||||
remove();
|
||||
UndoCommand::redo();
|
||||
}
|
||||
}
|
||||
|
||||
void undo() override
|
||||
{
|
||||
insert();
|
||||
UndoCommand::undo();
|
||||
}
|
||||
};
|
||||
|
||||
class DiagramController::FindDiagramsVisitor : public MChildrenVisitor
|
||||
{
|
||||
public:
|
||||
FindDiagramsVisitor(QList<MDiagram *> *allDiagrams)
|
||||
: m_allDiagrams(allDiagrams)
|
||||
{
|
||||
}
|
||||
|
||||
void visitMDiagram(MDiagram *diagram) override
|
||||
{
|
||||
m_allDiagrams->append(diagram);
|
||||
MChildrenVisitor::visitMDiagram(diagram);
|
||||
}
|
||||
|
||||
private:
|
||||
QList<MDiagram *> *m_allDiagrams = 0;
|
||||
};
|
||||
|
||||
DiagramController::DiagramController(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_modelController(0),
|
||||
m_undoController(0)
|
||||
{
|
||||
}
|
||||
|
||||
DiagramController::~DiagramController()
|
||||
{
|
||||
}
|
||||
|
||||
void DiagramController::setModelController(ModelController *modelController)
|
||||
{
|
||||
if (m_modelController) {
|
||||
disconnect(m_modelController, 0, this, 0);
|
||||
m_modelController = 0;
|
||||
}
|
||||
if (modelController) {
|
||||
m_modelController = modelController;
|
||||
connect(modelController, &ModelController::beginResetModel,
|
||||
this, &DiagramController::onBeginResetModel);
|
||||
connect(modelController, &ModelController::endResetModel,
|
||||
this, &DiagramController::onEndResetModel);
|
||||
|
||||
connect(modelController, &ModelController::beginUpdateObject,
|
||||
this, &DiagramController::onBeginUpdateObject);
|
||||
connect(modelController, &ModelController::endUpdateObject,
|
||||
this, &DiagramController::onEndUpdateObject);
|
||||
connect(modelController, &ModelController::beginInsertObject,
|
||||
this, &DiagramController::onBeginInsertObject);
|
||||
connect(modelController, &ModelController::endInsertObject,
|
||||
this, &DiagramController::onEndInsertObject);
|
||||
connect(modelController, &ModelController::beginRemoveObject,
|
||||
this, &DiagramController::onBeginRemoveObject);
|
||||
connect(modelController, &ModelController::endRemoveObject,
|
||||
this, &DiagramController::onEndRemoveObject);
|
||||
connect(modelController, &ModelController::beginMoveObject,
|
||||
this, &DiagramController::onBeginMoveObject);
|
||||
connect(modelController, &ModelController::endMoveObject,
|
||||
this, &DiagramController::onEndMoveObject);
|
||||
|
||||
connect(modelController, &ModelController::beginUpdateRelation,
|
||||
this, &DiagramController::onBeginUpdateRelation);
|
||||
connect(modelController, &ModelController::endUpdateRelation,
|
||||
this, &DiagramController::onEndUpdateRelation);
|
||||
connect(modelController, &ModelController::beginRemoveRelation,
|
||||
this, &DiagramController::onBeginRemoveRelation);
|
||||
connect(modelController, &ModelController::endRemoveRelation,
|
||||
this, &DiagramController::onEndRemoveRelation);
|
||||
connect(modelController, &ModelController::beginMoveRelation,
|
||||
this, &DiagramController::onBeginMoveRelation);
|
||||
connect(modelController, &ModelController::endMoveRelation,
|
||||
this, &DiagramController::onEndMoveRelation);
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramController::setUndoController(UndoController *undoController)
|
||||
{
|
||||
m_undoController = undoController;
|
||||
}
|
||||
|
||||
MDiagram *DiagramController::findDiagram(const Uid &diagramKey) const
|
||||
{
|
||||
return dynamic_cast<MDiagram *>(m_modelController->findObject(diagramKey));
|
||||
}
|
||||
|
||||
void DiagramController::addElement(DElement *element, MDiagram *diagram)
|
||||
{
|
||||
int row = diagram->diagramElements().count();
|
||||
emit beginInsertElement(row, diagram);
|
||||
updateElementFromModel(element, diagram, false);
|
||||
if (m_undoController) {
|
||||
auto undoCommand = new AddElementsCommand(this, diagram->uid(), tr("Add Object"));
|
||||
m_undoController->push(undoCommand);
|
||||
undoCommand->add(element->uid());
|
||||
}
|
||||
diagram->addDiagramElement(element);
|
||||
emit endInsertElement(row, diagram);
|
||||
diagramModified(diagram);
|
||||
}
|
||||
|
||||
void DiagramController::removeElement(DElement *element, MDiagram *diagram)
|
||||
{
|
||||
removeRelations(element, diagram);
|
||||
int row = diagram->diagramElements().indexOf(element);
|
||||
emit beginRemoveElement(row, diagram);
|
||||
if (m_undoController) {
|
||||
auto undoCommand = new RemoveElementsCommand(this, diagram->uid(), tr("Remove Object"));
|
||||
m_undoController->push(undoCommand);
|
||||
undoCommand->add(element);
|
||||
}
|
||||
diagram->removeDiagramElement(element);
|
||||
emit endRemoveElement(row, diagram);
|
||||
diagramModified(diagram);
|
||||
}
|
||||
|
||||
DElement *DiagramController::findElement(const Uid &key, const MDiagram *diagram) const
|
||||
{
|
||||
QMT_CHECK(diagram);
|
||||
|
||||
return diagram->findDiagramElement(key);
|
||||
}
|
||||
|
||||
bool DiagramController::hasDelegate(const MElement *modelElement, const MDiagram *diagram) const
|
||||
{
|
||||
// PERFORM smarter implementation after map is introduced
|
||||
return findDelegate(modelElement, diagram) != 0;
|
||||
}
|
||||
|
||||
DElement *DiagramController::findDelegate(const MElement *modelElement, const MDiagram *diagram) const
|
||||
{
|
||||
// PERFORM use map to increase performance
|
||||
foreach (DElement *diagramElement, diagram->diagramElements()) {
|
||||
if (diagramElement->modelUid().isValid() && diagramElement->modelUid() == modelElement->uid())
|
||||
return diagramElement;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DiagramController::startUpdateElement(DElement *element, MDiagram *diagram, UpdateAction updateAction)
|
||||
{
|
||||
emit beginUpdateElement(diagram->diagramElements().indexOf(element), diagram);
|
||||
if (m_undoController)
|
||||
m_undoController->push(new UpdateElementCommand(this, diagram->uid(), element, updateAction));
|
||||
}
|
||||
|
||||
void DiagramController::finishUpdateElement(DElement *element, MDiagram *diagram, bool cancelled)
|
||||
{
|
||||
if (!cancelled)
|
||||
updateElementFromModel(element, diagram, false);
|
||||
emit endUpdateElement(diagram->diagramElements().indexOf(element), diagram);
|
||||
if (!cancelled)
|
||||
diagramModified(diagram);
|
||||
}
|
||||
|
||||
void DiagramController::breakUndoChain()
|
||||
{
|
||||
m_undoController->doNotMerge();
|
||||
}
|
||||
|
||||
DContainer DiagramController::cutElements(const DSelection &diagramSelection, MDiagram *diagram)
|
||||
{
|
||||
DContainer copiedElements = copyElements(diagramSelection, diagram);
|
||||
deleteElements(diagramSelection, diagram, tr("Cut"));
|
||||
return copiedElements;
|
||||
}
|
||||
|
||||
DContainer DiagramController::copyElements(const DSelection &diagramSelection, const MDiagram *diagram)
|
||||
{
|
||||
QMT_CHECK(diagram);
|
||||
|
||||
DReferences simplifiedSelection = simplify(diagramSelection, diagram);
|
||||
DContainer copiedElements;
|
||||
foreach (const DElement *element, simplifiedSelection.elements()) {
|
||||
DCloneDeepVisitor visitor;
|
||||
element->accept(&visitor);
|
||||
DElement *clonedElement = visitor.cloned();
|
||||
copiedElements.submit(clonedElement);
|
||||
}
|
||||
return copiedElements;
|
||||
}
|
||||
|
||||
void DiagramController::pasteElements(const DContainer &diagramContainer, MDiagram *diagram)
|
||||
{
|
||||
QMT_CHECK(diagram);
|
||||
|
||||
// clone all elements and renew their keys
|
||||
QHash<Uid, Uid> renewedKeys;
|
||||
QList<DElement *> clonedElements;
|
||||
foreach (const DElement *element, diagramContainer.elements()) {
|
||||
if (!isDelegatedElementOnDiagram(element, diagram)) {
|
||||
DCloneDeepVisitor visitor;
|
||||
element->accept(&visitor);
|
||||
DElement *clonedElement = visitor.cloned();
|
||||
renewElementKey(clonedElement, &renewedKeys);
|
||||
clonedElements.append(clonedElement);
|
||||
}
|
||||
}
|
||||
// fix all keys referencing between pasting elements
|
||||
foreach(DElement *clonedElement, clonedElements) {
|
||||
auto relation = dynamic_cast<DRelation *>(clonedElement);
|
||||
if (relation)
|
||||
updateRelationKeys(relation, renewedKeys);
|
||||
}
|
||||
if (m_undoController)
|
||||
m_undoController->beginMergeSequence(tr("Paste"));
|
||||
// insert all elements
|
||||
bool added = false;
|
||||
foreach (DElement *clonedElement, clonedElements) {
|
||||
if (!dynamic_cast<DRelation *>(clonedElement)) {
|
||||
int row = diagram->diagramElements().size();
|
||||
emit beginInsertElement(row, diagram);
|
||||
if (m_undoController) {
|
||||
auto undoCommand = new AddElementsCommand(this, diagram->uid(), tr("Paste"));
|
||||
m_undoController->push(undoCommand);
|
||||
undoCommand->add(clonedElement->uid());
|
||||
}
|
||||
diagram->addDiagramElement(clonedElement);
|
||||
emit endInsertElement(row, diagram);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
foreach (DElement *clonedElement, clonedElements) {
|
||||
auto clonedRelation = dynamic_cast<DRelation *>(clonedElement);
|
||||
if (clonedRelation && areRelationEndsOnDiagram(clonedRelation, diagram)) {
|
||||
int row = diagram->diagramElements().size();
|
||||
emit beginInsertElement(row, diagram);
|
||||
if (m_undoController) {
|
||||
auto undoCommand = new AddElementsCommand(this, diagram->uid(), tr("Paste"));
|
||||
m_undoController->push(undoCommand);
|
||||
undoCommand->add(clonedElement->uid());
|
||||
}
|
||||
diagram->addDiagramElement(clonedElement);
|
||||
emit endInsertElement(row, diagram);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
if (added)
|
||||
diagramModified(diagram);
|
||||
if (m_undoController)
|
||||
m_undoController->endMergeSequence();
|
||||
}
|
||||
|
||||
void DiagramController::deleteElements(const DSelection &diagramSelection, MDiagram *diagram)
|
||||
{
|
||||
deleteElements(diagramSelection, diagram, tr("Delete"));
|
||||
}
|
||||
|
||||
void DiagramController::onBeginResetModel()
|
||||
{
|
||||
m_allDiagrams.clear();
|
||||
emit beginResetAllDiagrams();
|
||||
}
|
||||
|
||||
void DiagramController::onEndResetModel()
|
||||
{
|
||||
updateAllDiagramsList();
|
||||
foreach (MDiagram *diagram, m_allDiagrams) {
|
||||
// remove all elements which are not longer part of the model
|
||||
foreach (DElement *element, diagram->diagramElements()) {
|
||||
if (element->modelUid().isValid()) {
|
||||
MElement *modelElement = m_modelController->findElement(element->modelUid());
|
||||
if (!modelElement)
|
||||
removeElement(element, diagram);
|
||||
}
|
||||
}
|
||||
// update all remaining elements from model
|
||||
foreach (DElement *element, diagram->diagramElements())
|
||||
updateElementFromModel(element, diagram, false);
|
||||
}
|
||||
emit endResetAllDiagrams();
|
||||
}
|
||||
|
||||
void DiagramController::onBeginUpdateObject(int row, const MObject *parent)
|
||||
{
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(parent);
|
||||
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
void DiagramController::onEndUpdateObject(int row, const MObject *parent)
|
||||
{
|
||||
MObject *modelObject = m_modelController->object(row, parent);
|
||||
QMT_CHECK(modelObject);
|
||||
auto modelPackage = dynamic_cast<MPackage *>(modelObject);
|
||||
foreach (MDiagram *diagram, m_allDiagrams) {
|
||||
DObject *object = findDelegate<DObject>(modelObject, diagram);
|
||||
if (object) {
|
||||
updateElementFromModel(object, diagram, true);
|
||||
}
|
||||
if (modelPackage) {
|
||||
// update each element that has the updated object as its owner (for context changes)
|
||||
foreach (DElement *diagramElement, diagram->diagramElements()) {
|
||||
if (diagramElement->modelUid().isValid()) {
|
||||
MObject *mobject = m_modelController->findObject(diagramElement->modelUid());
|
||||
if (mobject && mobject->owner() == modelPackage)
|
||||
updateElementFromModel(diagramElement, diagram, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramController::onBeginInsertObject(int row, const MObject *owner)
|
||||
{
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(owner);
|
||||
}
|
||||
|
||||
void DiagramController::onEndInsertObject(int row, const MObject *owner)
|
||||
{
|
||||
QMT_CHECK(owner);
|
||||
|
||||
MObject *modelObject = m_modelController->object(row, owner);
|
||||
if (auto modelDiagram = dynamic_cast<MDiagram *>(modelObject)) {
|
||||
QMT_CHECK(!m_allDiagrams.contains(modelDiagram));
|
||||
m_allDiagrams.append(modelDiagram);
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramController::onBeginRemoveObject(int row, const MObject *parent)
|
||||
{
|
||||
QMT_CHECK(parent);
|
||||
|
||||
MObject *modelObject = m_modelController->object(row, parent);
|
||||
removeObjects(modelObject);
|
||||
}
|
||||
|
||||
void DiagramController::onEndRemoveObject(int row, const MObject *parent)
|
||||
{
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(parent);
|
||||
}
|
||||
|
||||
void DiagramController::onBeginMoveObject(int formerRow, const MObject *formerOwner)
|
||||
{
|
||||
Q_UNUSED(formerRow);
|
||||
Q_UNUSED(formerOwner);
|
||||
}
|
||||
|
||||
void DiagramController::onEndMoveObject(int row, const MObject *owner)
|
||||
{
|
||||
onEndUpdateObject(row, owner);
|
||||
|
||||
// if diagram was moved update all elements because of changed context
|
||||
MObject *modelObject = m_modelController->object(row, owner);
|
||||
QMT_CHECK(modelObject);
|
||||
auto modelDiagram = dynamic_cast<MDiagram *>(modelObject);
|
||||
if (modelDiagram) {
|
||||
emit beginResetDiagram(modelDiagram);
|
||||
foreach (DElement *diagramElement, modelDiagram->diagramElements())
|
||||
updateElementFromModel(diagramElement, modelDiagram, false);
|
||||
emit endResetDiagram(modelDiagram);
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramController::onBeginUpdateRelation(int row, const MObject *owner)
|
||||
{
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(owner);
|
||||
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
void DiagramController::onEndUpdateRelation(int row, const MObject *owner)
|
||||
{
|
||||
MRelation *modelRelation = owner->relations().at(row);
|
||||
foreach (MDiagram *diagram, m_allDiagrams) {
|
||||
DRelation *relation = findDelegate<DRelation>(modelRelation, diagram);
|
||||
if (relation) {
|
||||
updateElementFromModel(relation, diagram, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramController::onBeginRemoveRelation(int row, const MObject *owner)
|
||||
{
|
||||
QMT_CHECK(owner);
|
||||
|
||||
MRelation *modelRelation = owner->relations().at(row);
|
||||
removeRelations(modelRelation);
|
||||
}
|
||||
|
||||
void DiagramController::onEndRemoveRelation(int row, const MObject *owner)
|
||||
{
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(owner);
|
||||
}
|
||||
|
||||
void DiagramController::onBeginMoveRelation(int formerRow, const MObject *formerOwner)
|
||||
{
|
||||
Q_UNUSED(formerRow);
|
||||
Q_UNUSED(formerOwner);
|
||||
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
void DiagramController::onEndMoveRelation(int row, const MObject *owner)
|
||||
{
|
||||
onEndUpdateRelation(row, owner);
|
||||
}
|
||||
|
||||
void DiagramController::deleteElements(const DSelection &diagramSelection, MDiagram *diagram,
|
||||
const QString &commandLabel)
|
||||
{
|
||||
QMT_CHECK(diagram);
|
||||
|
||||
DReferences simplifiedSelection = simplify(diagramSelection, diagram);
|
||||
if (simplifiedSelection.elements().isEmpty())
|
||||
return;
|
||||
if (m_undoController)
|
||||
m_undoController->beginMergeSequence(commandLabel);
|
||||
bool removed = false;
|
||||
foreach (DElement *element, simplifiedSelection.elements()) {
|
||||
// element may have been deleted indirectly by predecessor element in loop
|
||||
if ((element = findElement(element->uid(), diagram))) {
|
||||
removeRelations(element, diagram);
|
||||
int row = diagram->diagramElements().indexOf(element);
|
||||
emit beginRemoveElement(diagram->diagramElements().indexOf(element), diagram);
|
||||
if (m_undoController) {
|
||||
auto cutCommand = new RemoveElementsCommand(this, diagram->uid(), commandLabel);
|
||||
m_undoController->push(cutCommand);
|
||||
cutCommand->add(element);
|
||||
}
|
||||
diagram->removeDiagramElement(element);
|
||||
emit endRemoveElement(row, diagram);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
if (removed)
|
||||
diagramModified(diagram);
|
||||
if (m_undoController)
|
||||
m_undoController->endMergeSequence();
|
||||
}
|
||||
|
||||
DElement *DiagramController::findElementOnAnyDiagram(const Uid &uid)
|
||||
{
|
||||
foreach (MDiagram *diagram, m_allDiagrams) {
|
||||
DElement *element = findElement(uid, diagram);
|
||||
if (element)
|
||||
return element;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DiagramController::removeObjects(MObject *modelObject)
|
||||
{
|
||||
foreach (MDiagram *diagram, m_allDiagrams) {
|
||||
DElement *diagramElement = findDelegate(modelObject, diagram);
|
||||
if (diagramElement)
|
||||
removeElement(diagramElement, diagram);
|
||||
foreach (const Handle<MRelation> &relation, modelObject->relations()) {
|
||||
DElement *diagramElement = findDelegate(relation.target(), diagram);
|
||||
if (diagramElement)
|
||||
removeElement(diagramElement, diagram);
|
||||
}
|
||||
}
|
||||
foreach (const Handle<MObject> &object, modelObject->children()) {
|
||||
if (object.hasTarget())
|
||||
removeObjects(object.target());
|
||||
}
|
||||
if (auto diagram = dynamic_cast<MDiagram *>(modelObject)) {
|
||||
emit diagramAboutToBeRemoved(diagram);
|
||||
QMT_CHECK(m_allDiagrams.contains(diagram));
|
||||
m_allDiagrams.removeOne(diagram);
|
||||
QMT_CHECK(!m_allDiagrams.contains(diagram));
|
||||
// PERFORM increase performace
|
||||
while (!diagram->diagramElements().isEmpty()) {
|
||||
DElement *element = diagram->diagramElements().first();
|
||||
removeElement(element, diagram);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramController::removeRelations(MRelation *modelRelation)
|
||||
{
|
||||
foreach (MDiagram *diagram, m_allDiagrams) {
|
||||
DElement *diagramElement = findDelegate(modelRelation, diagram);
|
||||
if (diagramElement)
|
||||
removeElement(diagramElement, diagram);
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramController::removeRelations(DElement *element, MDiagram *diagram)
|
||||
{
|
||||
auto diagramObject = dynamic_cast<DObject *>(element);
|
||||
if (diagramObject) {
|
||||
foreach (DElement *diagramElement, diagram->diagramElements()) {
|
||||
if (auto diagramRelation = dynamic_cast<DRelation *>(diagramElement)) {
|
||||
if (diagramRelation->endAUid() == diagramObject->uid()
|
||||
|| diagramRelation->endBUid() == diagramObject->uid()) {
|
||||
removeElement(diagramRelation, diagram);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramController::renewElementKey(DElement *element, QHash<Uid, Uid> *renewedKeys)
|
||||
{
|
||||
QMT_CHECK(renewedKeys);
|
||||
|
||||
if (element) {
|
||||
DElement *existingElementOnDiagram = findElementOnAnyDiagram(element->uid());
|
||||
if (existingElementOnDiagram) {
|
||||
QMT_CHECK(existingElementOnDiagram != element);
|
||||
Uid oldKey = element->uid();
|
||||
element->renewUid();
|
||||
Uid newKey = element->uid();
|
||||
renewedKeys->insert(oldKey, newKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramController::updateRelationKeys(DRelation *relation, const QHash<Uid, Uid> &renewedKeys)
|
||||
{
|
||||
Uid newEndAKey = renewedKeys.value(relation->endAUid(), Uid::invalidUid());
|
||||
if (newEndAKey.isValid())
|
||||
relation->setEndAUid(newEndAKey);
|
||||
Uid newEndBKey = renewedKeys.value(relation->endBUid(), Uid::invalidUid());
|
||||
if (newEndBKey.isValid())
|
||||
relation->setEndBUid(newEndBKey);
|
||||
}
|
||||
|
||||
void DiagramController::updateElementFromModel(DElement *element, const MDiagram *diagram, bool emitUpdateSignal)
|
||||
{
|
||||
if (!element->modelUid().isValid())
|
||||
return;
|
||||
|
||||
DUpdateVisitor visitor(element, diagram);
|
||||
|
||||
MElement *melement = m_modelController->findElement(element->modelUid());
|
||||
QMT_CHECK(melement);
|
||||
|
||||
if (emitUpdateSignal) {
|
||||
visitor.setCheckNeedsUpdate(true);
|
||||
melement->accept(&visitor);
|
||||
if (visitor.isUpdateNeeded()) {
|
||||
int row = diagram->diagramElements().indexOf(element);
|
||||
emit beginUpdateElement(row, diagram);
|
||||
visitor.setCheckNeedsUpdate(false);
|
||||
melement->accept(&visitor);
|
||||
emit endUpdateElement(row, diagram);
|
||||
}
|
||||
} else {
|
||||
melement->accept(&visitor);
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramController::diagramModified(MDiagram *diagram)
|
||||
{
|
||||
// the modification date is updated intentionally without signalling model controller
|
||||
// avoiding recursive change updates
|
||||
diagram->setLastModifiedToNow();
|
||||
emit modified(diagram);
|
||||
}
|
||||
|
||||
DReferences DiagramController::simplify(const DSelection &diagramSelection, const MDiagram *diagram)
|
||||
{
|
||||
DReferences references;
|
||||
foreach (const DSelection::Index &index, diagramSelection.indices()) {
|
||||
DElement *element = findElement(index.elementKey(), diagram);
|
||||
if (element)
|
||||
references.append(element);
|
||||
}
|
||||
return references;
|
||||
}
|
||||
|
||||
MElement *DiagramController::delegatedElement(const DElement *element) const
|
||||
{
|
||||
if (!element->modelUid().isValid())
|
||||
return 0;
|
||||
return m_modelController->findElement(element->modelUid());
|
||||
}
|
||||
|
||||
bool DiagramController::isDelegatedElementOnDiagram(const DElement *element, const MDiagram *diagram) const
|
||||
{
|
||||
MElement *modelElement = delegatedElement(element);
|
||||
if (!modelElement)
|
||||
return false;
|
||||
return hasDelegate(modelElement, diagram);
|
||||
}
|
||||
|
||||
bool DiagramController::areRelationEndsOnDiagram(const DRelation *relation, const MDiagram *diagram) const
|
||||
{
|
||||
return findElement(relation->endAUid(), diagram) && findElement(relation->endBUid(), diagram);
|
||||
}
|
||||
|
||||
void DiagramController::updateAllDiagramsList()
|
||||
{
|
||||
m_allDiagrams.clear();
|
||||
if (m_modelController && m_modelController->rootPackage()) {
|
||||
FindDiagramsVisitor visitor(&m_allDiagrams);
|
||||
m_modelController->rootPackage()->accept(&visitor);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace qmt
|
||||
179
src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.h
Normal file
179
src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.h
Normal file
@@ -0,0 +1,179 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_DIAGRAMCONTROLLER_H
|
||||
#define QMT_DIAGRAMCONTROLLER_H
|
||||
|
||||
#include "qmt/infrastructure/uid.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class UndoController;
|
||||
class ModelController;
|
||||
class MElement;
|
||||
class MObject;
|
||||
class MDiagram;
|
||||
class MRelation;
|
||||
class DSelection;
|
||||
class DContainer;
|
||||
class DReferences;
|
||||
class DElement;
|
||||
class DRelation;
|
||||
|
||||
class QMT_EXPORT DiagramController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum UpdateAction {
|
||||
UpdateGeometry, // update only position and size of element
|
||||
UpdateMajor, // a major update of the element which will create a separate undo command
|
||||
UpdateMinor // a minor update of the element which may be merged with other minor updates in one undo command
|
||||
};
|
||||
|
||||
private:
|
||||
class Clone;
|
||||
class DiagramUndoCommand;
|
||||
class UpdateElementCommand;
|
||||
class AbstractAddRemCommand;
|
||||
class AddElementsCommand;
|
||||
class RemoveElementsCommand;
|
||||
class FindDiagramsVisitor;
|
||||
|
||||
public:
|
||||
explicit DiagramController(QObject *parent = 0);
|
||||
~DiagramController() override;
|
||||
|
||||
signals:
|
||||
void beginResetAllDiagrams();
|
||||
void endResetAllDiagrams();
|
||||
void beginResetDiagram(const MDiagram *diagram);
|
||||
void endResetDiagram(const MDiagram *diagram);
|
||||
void beginUpdateElement(int row, const MDiagram *diagram);
|
||||
void endUpdateElement(int row, const MDiagram *diagram);
|
||||
void beginInsertElement(int row, const MDiagram *diagram);
|
||||
void endInsertElement(int row, const MDiagram *diagram);
|
||||
void beginRemoveElement(int row, const MDiagram *diagram);
|
||||
void endRemoveElement(int row, const MDiagram *diagram);
|
||||
void modified(const MDiagram *diagram);
|
||||
void diagramAboutToBeRemoved(const MDiagram *diagram);
|
||||
|
||||
public:
|
||||
ModelController *modelController() const { return m_modelController; }
|
||||
void setModelController(ModelController *modelController);
|
||||
UndoController *undoController() const { return m_undoController; }
|
||||
void setUndoController(UndoController *undoController);
|
||||
|
||||
private:
|
||||
MDiagram *findDiagram(const Uid &diagramKey) const;
|
||||
|
||||
public:
|
||||
void addElement(DElement *element, MDiagram *diagram);
|
||||
void removeElement(DElement *element, MDiagram *diagram);
|
||||
|
||||
DElement *findElement(const Uid &key, const MDiagram *diagram) const;
|
||||
|
||||
template<class T>
|
||||
T *findElement(const Uid &key, const MDiagram *diagram) const
|
||||
{
|
||||
return dynamic_cast<T *>(findElement(key, diagram));
|
||||
}
|
||||
|
||||
bool hasDelegate(const MElement *modelElement, const MDiagram *diagram) const;
|
||||
DElement *findDelegate(const MElement *modelElement, const MDiagram *diagram) const;
|
||||
|
||||
template<class T>
|
||||
T *findDelegate(const MElement *modelElement, const MDiagram *diagram) const
|
||||
{
|
||||
return dynamic_cast<T *>(findDelegate(modelElement, diagram));
|
||||
}
|
||||
|
||||
void startUpdateElement(DElement *element, MDiagram *diagram, UpdateAction updateAction);
|
||||
void finishUpdateElement(DElement *element, MDiagram *diagram, bool cancelled);
|
||||
|
||||
void breakUndoChain();
|
||||
|
||||
DContainer cutElements(const DSelection &diagramSelection, MDiagram *diagram);
|
||||
DContainer copyElements(const DSelection &diagramSelection, const MDiagram *diagram);
|
||||
void pasteElements(const DContainer &diagramContainer, MDiagram *diagram);
|
||||
void deleteElements(const DSelection &diagramSelection, MDiagram *diagram);
|
||||
|
||||
private:
|
||||
void onBeginResetModel();
|
||||
void onEndResetModel();
|
||||
void onBeginUpdateObject(int row, const MObject *parent);
|
||||
void onEndUpdateObject(int row, const MObject *parent);
|
||||
void onBeginInsertObject(int row, const MObject *owner);
|
||||
void onEndInsertObject(int row, const MObject *owner);
|
||||
void onBeginRemoveObject(int row, const MObject *parent);
|
||||
void onEndRemoveObject(int row, const MObject *parent);
|
||||
void onBeginMoveObject(int formerRow, const MObject *formerOwner);
|
||||
void onEndMoveObject(int row, const MObject *owner);
|
||||
void onBeginUpdateRelation(int row, const MObject *owner);
|
||||
void onEndUpdateRelation(int row, const MObject *owner);
|
||||
void onBeginRemoveRelation(int row, const MObject *owner);
|
||||
void onEndRemoveRelation(int row, const MObject *owner);
|
||||
void onBeginMoveRelation(int formerRow, const MObject *formerOwner);
|
||||
void onEndMoveRelation(int row, const MObject *owner);
|
||||
|
||||
void deleteElements(const DSelection &diagramSelection, MDiagram *diagram,
|
||||
const QString &commandLabel);
|
||||
|
||||
DElement *findElementOnAnyDiagram(const Uid &uid);
|
||||
|
||||
void removeObjects(MObject *modelObject);
|
||||
void removeRelations(MRelation *modelRelation);
|
||||
void removeRelations(DElement *element, MDiagram *diagram);
|
||||
|
||||
void renewElementKey(DElement *element, QHash<Uid, Uid> *renewedKeys);
|
||||
void updateRelationKeys(DRelation *relation, const QHash<Uid, Uid> &renewedKeys);
|
||||
void updateElementFromModel(DElement *element, const MDiagram *diagram, bool emitUpdateSignal);
|
||||
|
||||
void diagramModified(MDiagram *diagram);
|
||||
|
||||
DReferences simplify(const DSelection &diagramSelection, const MDiagram *diagram);
|
||||
|
||||
MElement *delegatedElement(const DElement *element) const;
|
||||
bool isDelegatedElementOnDiagram(const DElement *element, const MDiagram *diagram) const;
|
||||
bool areRelationEndsOnDiagram(const DRelation *relation, const MDiagram *diagram) const;
|
||||
|
||||
void updateAllDiagramsList();
|
||||
|
||||
ModelController *m_modelController;
|
||||
UndoController *m_undoController;
|
||||
QList<MDiagram *> m_allDiagrams;
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
||||
#endif // DIAGRAMCONTROLLER_H
|
||||
47
src/libs/modelinglib/qmt/diagram_controller/dreferences.h
Normal file
47
src/libs/modelinglib/qmt/diagram_controller/dreferences.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_DREFERENCES_H
|
||||
#define QMT_DREFERENCES_H
|
||||
|
||||
#include "qmt/controller/references.h"
|
||||
#include "qmt/infrastructure/qmt_global.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class DElement;
|
||||
|
||||
class QMT_EXPORT DReferences : public References<DElement>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
||||
#endif // QMT_DREFERENCES_H
|
||||
45
src/libs/modelinglib/qmt/diagram_controller/dselection.h
Normal file
45
src/libs/modelinglib/qmt/diagram_controller/dselection.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_DSELECTION_H
|
||||
#define QMT_DSELECTION_H
|
||||
|
||||
#include "qmt/controller/selection.h"
|
||||
#include "qmt/infrastructure/qmt_global.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class QMT_EXPORT DSelection : public Selection
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
||||
#endif // QMT_DSELECTION_H
|
||||
240
src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp
Normal file
240
src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#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 {
|
||||
|
||||
DUpdateVisitor::DUpdateVisitor(DElement *target, const MDiagram *diagram, bool checkNeedsUpdate)
|
||||
: m_target(target),
|
||||
m_diagram(diagram),
|
||||
m_checkNeedsUpdate(checkNeedsUpdate),
|
||||
m_isUpdateNeeded(!checkNeedsUpdate)
|
||||
{
|
||||
}
|
||||
|
||||
void DUpdateVisitor::setCheckNeedsUpdate(bool checkNeedsUpdate)
|
||||
{
|
||||
m_checkNeedsUpdate = checkNeedsUpdate;
|
||||
m_isUpdateNeeded = !checkNeedsUpdate;
|
||||
}
|
||||
|
||||
void DUpdateVisitor::visitMElement(const MElement *element)
|
||||
{
|
||||
Q_UNUSED(element);
|
||||
|
||||
QMT_CHECK(m_target);
|
||||
}
|
||||
|
||||
void DUpdateVisitor::visitMObject(const MObject *object)
|
||||
{
|
||||
auto dobject = dynamic_cast<DObject *>(m_target);
|
||||
QMT_CHECK(dobject);
|
||||
if (isUpdating(object->stereotypes() != dobject->stereotypes()))
|
||||
dobject->setStereotypes(object->stereotypes());
|
||||
const MObject *objectOwner = object->owner();
|
||||
const MObject *diagramOwner = m_diagram->owner();
|
||||
if (objectOwner && diagramOwner && objectOwner->uid() != diagramOwner->uid()) {
|
||||
if (isUpdating(objectOwner->name() != dobject->context()))
|
||||
dobject->setContext(objectOwner->name());
|
||||
} else {
|
||||
if (isUpdating(!dobject->context().isEmpty()))
|
||||
dobject->setContext(QString());
|
||||
}
|
||||
if (isUpdating(object->name() != dobject->name()))
|
||||
dobject->setName(object->name());
|
||||
// TODO unlikely that this is called for all objects if hierarchy is modified
|
||||
// PERFORM remove loop
|
||||
int depth = 1;
|
||||
const MObject *owner = object->owner();
|
||||
while (owner) {
|
||||
owner = owner->owner();
|
||||
depth += 1;
|
||||
}
|
||||
if (isUpdating(depth != dobject->depth()))
|
||||
dobject->setDepth(depth);
|
||||
visitMElement(object);
|
||||
}
|
||||
|
||||
void DUpdateVisitor::visitMPackage(const MPackage *package)
|
||||
{
|
||||
visitMObject(package);
|
||||
}
|
||||
|
||||
void DUpdateVisitor::visitMClass(const MClass *klass)
|
||||
{
|
||||
auto dclass = dynamic_cast<DClass *>(m_target);
|
||||
QMT_CHECK(dclass);
|
||||
if (isUpdating(klass->umlNamespace() != dclass->umlNamespace()))
|
||||
dclass->setUmlNamespace(klass->umlNamespace());
|
||||
if (isUpdating(klass->templateParameters() != dclass->templateParameters()))
|
||||
dclass->setTemplateParameters(klass->templateParameters());
|
||||
if (isUpdating(klass->members() != dclass->members()))
|
||||
dclass->setMembers(klass->members());
|
||||
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)
|
||||
{
|
||||
auto ditem = dynamic_cast<DItem *>(m_target);
|
||||
QMT_CHECK(ditem);
|
||||
if (isUpdating(item->isShapeEditable() != ditem->isShapeEditable()))
|
||||
ditem->setShapeEditable(item->isShapeEditable());
|
||||
if (isUpdating(item->variety() != ditem->variety()))
|
||||
ditem->setVariety(item->variety());
|
||||
visitMObject(item);
|
||||
}
|
||||
|
||||
void DUpdateVisitor::visitMRelation(const MRelation *relation)
|
||||
{
|
||||
auto drelation = dynamic_cast<DRelation *>(m_target);
|
||||
QMT_CHECK(drelation);
|
||||
if (isUpdating(relation->stereotypes() != drelation->stereotypes()))
|
||||
drelation->setStereotypes(relation->stereotypes());
|
||||
if (isUpdating(relation->name() != drelation->name()))
|
||||
drelation->setName(relation->name());
|
||||
// TODO improve performance of MDiagram::findDiagramElement
|
||||
DObject *endAObject = dynamic_cast<DObject *>(m_diagram->findDiagramElement(drelation->endAUid()));
|
||||
if (!endAObject || relation->endAUid() != endAObject->modelUid()) {
|
||||
isUpdating(true);
|
||||
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()) {
|
||||
isUpdating(true);
|
||||
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());
|
||||
}
|
||||
visitMElement(relation);
|
||||
}
|
||||
|
||||
void DUpdateVisitor::visitMDependency(const MDependency *dependency)
|
||||
{
|
||||
auto ddependency = dynamic_cast<DDependency *>(m_target);
|
||||
QMT_CHECK(ddependency);
|
||||
if (isUpdating(dependency->direction() != ddependency->direction()))
|
||||
ddependency->setDirection(dependency->direction());
|
||||
visitMRelation(dependency);
|
||||
}
|
||||
|
||||
void DUpdateVisitor::visitMInheritance(const MInheritance *inheritance)
|
||||
{
|
||||
visitMRelation(inheritance);
|
||||
}
|
||||
|
||||
void DUpdateVisitor::visitMAssociation(const MAssociation *association)
|
||||
{
|
||||
auto dassociation = dynamic_cast<DAssociation *>(m_target);
|
||||
QMT_CHECK(dassociation);
|
||||
DAssociationEnd endA;
|
||||
endA.setName(association->endA().name());
|
||||
endA.setCardinatlity(association->endA().cardinality());
|
||||
endA.setNavigable(association->endA().isNavigable());
|
||||
endA.setKind(association->endA().kind());
|
||||
if (isUpdating(endA != dassociation->endA()))
|
||||
dassociation->setEndA(endA);
|
||||
DAssociationEnd endB;
|
||||
endB.setName(association->endB().name());
|
||||
endB.setCardinatlity(association->endB().cardinality());
|
||||
endB.setNavigable(association->endB().isNavigable());
|
||||
endB.setKind(association->endB().kind());
|
||||
if (isUpdating(endB != dassociation->endB()))
|
||||
dassociation->setEndB(endB);
|
||||
visitMRelation(association);
|
||||
}
|
||||
|
||||
bool DUpdateVisitor::isUpdating(bool valueChanged)
|
||||
{
|
||||
if (m_checkNeedsUpdate) {
|
||||
if (valueChanged)
|
||||
m_isUpdateNeeded = true;
|
||||
return false;
|
||||
}
|
||||
return valueChanged;
|
||||
}
|
||||
|
||||
} // namespace qmt
|
||||
73
src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.h
Normal file
73
src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_DUPDATEVISITOR_H
|
||||
#define QMT_DUPDATEVISITOR_H
|
||||
|
||||
#include "qmt/model/mconstvisitor.h"
|
||||
#include "qmt/infrastructure/qmt_global.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class DElement;
|
||||
|
||||
class QMT_EXPORT DUpdateVisitor : public MConstVisitor
|
||||
{
|
||||
public:
|
||||
DUpdateVisitor(DElement *target, const MDiagram *diagram, bool checkNeedsUpdate = false);
|
||||
|
||||
bool isUpdateNeeded() const { return m_isUpdateNeeded; }
|
||||
void setCheckNeedsUpdate(bool checkNeedsUpdate);
|
||||
|
||||
void visitMElement(const MElement *element) override;
|
||||
void visitMObject(const MObject *object) override;
|
||||
void visitMPackage(const MPackage *package) override;
|
||||
void visitMClass(const MClass *klass) override;
|
||||
void visitMComponent(const MComponent *component) override;
|
||||
void visitMDiagram(const MDiagram *diagram) override;
|
||||
void visitMCanvasDiagram(const MCanvasDiagram *diagram) override;
|
||||
void visitMItem(const MItem *item) override;
|
||||
void visitMRelation(const MRelation *relation) override;
|
||||
void visitMDependency(const MDependency *dependency) override;
|
||||
void visitMInheritance(const MInheritance *inheritance) override;
|
||||
void visitMAssociation(const MAssociation *association) override;
|
||||
|
||||
private:
|
||||
bool isUpdating(bool valueChanged);
|
||||
|
||||
DElement *m_target;
|
||||
const MDiagram *m_diagram;
|
||||
bool m_checkNeedsUpdate;
|
||||
bool m_isUpdateNeeded;
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
||||
#endif // QMT_DUPDATEVISITOR_H
|
||||
187
src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp
Normal file
187
src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "dvoidvisitor.h"
|
||||
|
||||
#include "qmt/diagram/delement.h"
|
||||
#include "qmt/diagram/dobject.h"
|
||||
#include "qmt/diagram/dpackage.h"
|
||||
#include "qmt/diagram/dclass.h"
|
||||
#include "qmt/diagram/dcomponent.h"
|
||||
#include "qmt/diagram/ddiagram.h"
|
||||
#include "qmt/diagram/ditem.h"
|
||||
#include "qmt/diagram/drelation.h"
|
||||
#include "qmt/diagram/dinheritance.h"
|
||||
#include "qmt/diagram/ddependency.h"
|
||||
#include "qmt/diagram/dassociation.h"
|
||||
#include "qmt/diagram/dannotation.h"
|
||||
#include "qmt/diagram/dboundary.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
DVoidVisitor::DVoidVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDElement(DElement *element)
|
||||
{
|
||||
Q_UNUSED(element);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDObject(DObject *object)
|
||||
{
|
||||
visitDElement(object);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDPackage(DPackage *package)
|
||||
{
|
||||
visitDObject(package);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDClass(DClass *klass)
|
||||
{
|
||||
visitDObject(klass);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDComponent(DComponent *component)
|
||||
{
|
||||
visitDObject(component);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDDiagram(DDiagram *diagram)
|
||||
{
|
||||
visitDObject(diagram);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDItem(DItem *item)
|
||||
{
|
||||
visitDObject(item);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDRelation(DRelation *relation)
|
||||
{
|
||||
visitDElement(relation);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDInheritance(DInheritance *inheritance)
|
||||
{
|
||||
visitDRelation(inheritance);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDDependency(DDependency *dependency)
|
||||
{
|
||||
visitDRelation(dependency);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDAssociation(DAssociation *association)
|
||||
{
|
||||
visitDRelation(association);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDAnnotation(DAnnotation *annotation)
|
||||
{
|
||||
visitDElement(annotation);
|
||||
}
|
||||
|
||||
void DVoidVisitor::visitDBoundary(DBoundary *boundary)
|
||||
{
|
||||
visitDElement(boundary);
|
||||
}
|
||||
|
||||
DConstVoidVisitor::DConstVoidVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDElement(const DElement *element)
|
||||
{
|
||||
Q_UNUSED(element);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDObject(const DObject *object)
|
||||
{
|
||||
visitDElement(object);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDPackage(const DPackage *package)
|
||||
{
|
||||
visitDObject(package);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDClass(const DClass *klass)
|
||||
{
|
||||
visitDObject(klass);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDComponent(const DComponent *component)
|
||||
{
|
||||
visitDObject(component);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDDiagram(const DDiagram *diagram)
|
||||
{
|
||||
visitDObject(diagram);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDItem(const DItem *item)
|
||||
{
|
||||
visitDObject(item);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDRelation(const DRelation *relation)
|
||||
{
|
||||
visitDElement(relation);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDInheritance(const DInheritance *inheritance)
|
||||
{
|
||||
visitDRelation(inheritance);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDDependency(const DDependency *dependency)
|
||||
{
|
||||
visitDRelation(dependency);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDAssociation(const DAssociation *association)
|
||||
{
|
||||
visitDRelation(association);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDAnnotation(const DAnnotation *annotation)
|
||||
{
|
||||
visitDElement(annotation);
|
||||
}
|
||||
|
||||
void DConstVoidVisitor::visitDBoundary(const DBoundary *boundary)
|
||||
{
|
||||
visitDElement(boundary);
|
||||
}
|
||||
|
||||
} // namespace qmt
|
||||
82
src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.h
Normal file
82
src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Jochen Becher
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** 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
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMT_DVOIDVISITOR_H
|
||||
#define QMT_DVOIDVISITOR_H
|
||||
|
||||
#include "qmt/diagram/dvisitor.h"
|
||||
#include "qmt/diagram/dconstvisitor.h"
|
||||
#include "qmt/infrastructure/qmt_global.h"
|
||||
|
||||
namespace qmt {
|
||||
|
||||
class QMT_EXPORT DVoidVisitor : public DVisitor
|
||||
{
|
||||
public:
|
||||
DVoidVisitor();
|
||||
|
||||
void visitDElement(DElement *element) override;
|
||||
void visitDObject(DObject *object) override;
|
||||
void visitDPackage(DPackage *package) override;
|
||||
void visitDClass(DClass *klass) override;
|
||||
void visitDComponent(DComponent *component) override;
|
||||
void visitDDiagram(DDiagram *diagram) override;
|
||||
void visitDItem(DItem *item) override;
|
||||
void visitDRelation(DRelation *relation) override;
|
||||
void visitDInheritance(DInheritance *inheritance) override;
|
||||
void visitDDependency(DDependency *dependency) override;
|
||||
void visitDAssociation(DAssociation *association) override;
|
||||
void visitDAnnotation(DAnnotation *annotation) override;
|
||||
void visitDBoundary(DBoundary *boundary) override;
|
||||
};
|
||||
|
||||
class QMT_EXPORT DConstVoidVisitor : public DConstVisitor
|
||||
{
|
||||
public:
|
||||
DConstVoidVisitor();
|
||||
|
||||
void visitDElement(const DElement *element) override;
|
||||
void visitDObject(const DObject *object) override;
|
||||
void visitDPackage(const DPackage *package) override;
|
||||
void visitDClass(const DClass *klass) override;
|
||||
void visitDComponent(const DComponent *component) override;
|
||||
void visitDDiagram(const DDiagram *diagram) override;
|
||||
void visitDItem(const DItem *item) override;
|
||||
void visitDRelation(const DRelation *relation) override;
|
||||
void visitDInheritance(const DInheritance *inheritance) override;
|
||||
void visitDDependency(const DDependency *dependency) override;
|
||||
void visitDAssociation(const DAssociation *association) override;
|
||||
void visitDAnnotation(const DAnnotation *annotation) override;
|
||||
void visitDBoundary(const DBoundary *boundary) override;
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
||||
#endif // DVOIDVISITOR_H
|
||||
Reference in New Issue
Block a user