forked from qt-creator/qt-creator
ModelEditor: Refactor ComponentViewController
Move some generic code into separate controllers for later reuse. Change-Id: Idc0df32e6efe6d8618f556619fa956aded568119 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "componentviewcontroller.h"
|
||||
|
||||
#include "modelutilities.h"
|
||||
#include "packageviewcontroller.h"
|
||||
#include "pxnodeutilities.h"
|
||||
|
||||
#include "qmt/controller/namecontroller.h"
|
||||
@@ -116,31 +118,41 @@ class UpdateIncludeDependenciesVisitor :
|
||||
};
|
||||
|
||||
public:
|
||||
void setPackageViewController(PackageViewController *packageViewController);
|
||||
void setModelController(qmt::ModelController *modelController);
|
||||
void setModelUtilities(ModelUtilities *modelUtilities);
|
||||
void updateFilePaths();
|
||||
void visitMComponent(qmt::MComponent *component);
|
||||
|
||||
private:
|
||||
bool haveMatchingStereotypes(const qmt::MObject *object1, const qmt::MObject *object2);
|
||||
QStringList findFilePathOfComponent(const qmt::MComponent *component);
|
||||
void collectElementPaths(const ProjectExplorer::FolderNode *folderNode, QMultiHash<QString,
|
||||
Node> *filePathsMap);
|
||||
qmt::MComponent *findComponentFromFilePath(const QString &filePath);
|
||||
bool haveDependency(const qmt::MObject *source, const qmt::MObject *target,
|
||||
bool inverted = false);
|
||||
bool haveDependency(const qmt::MObject *source, const QList<qmt::MPackage *> &targets);
|
||||
|
||||
private:
|
||||
PackageViewController *m_packageViewController = nullptr;
|
||||
qmt::ModelController *m_modelController = nullptr;
|
||||
ModelUtilities *m_modelUtilities = nullptr;
|
||||
QMultiHash<QString, Node> m_filePaths;
|
||||
QHash<QString, qmt::MComponent *> m_filePathComponentsMap;
|
||||
};
|
||||
|
||||
void UpdateIncludeDependenciesVisitor::setPackageViewController(PackageViewController *packageViewController)
|
||||
{
|
||||
m_packageViewController = packageViewController;
|
||||
}
|
||||
|
||||
void UpdateIncludeDependenciesVisitor::setModelController(qmt::ModelController *modelController)
|
||||
{
|
||||
m_modelController = modelController;
|
||||
}
|
||||
|
||||
void UpdateIncludeDependenciesVisitor::setModelUtilities(ModelUtilities *modelUtilities)
|
||||
{
|
||||
m_modelUtilities = modelUtilities;
|
||||
}
|
||||
|
||||
void UpdateIncludeDependenciesVisitor::updateFilePaths()
|
||||
{
|
||||
m_filePaths.clear();
|
||||
@@ -175,7 +187,7 @@ void UpdateIncludeDependenciesVisitor::visitMComponent(qmt::MComponent *componen
|
||||
qmt::MComponent *includeComponent = findComponentFromFilePath(includeFilePath);
|
||||
if (includeComponent && includeComponent != component) {
|
||||
// add dependency between components
|
||||
if (!haveDependency(component, includeComponent)) {
|
||||
if (!m_modelUtilities->haveDependency(component, includeComponent)) {
|
||||
auto dependency = new qmt::MDependency;
|
||||
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
||||
dependency->setStereotypes(QStringList() << "include");
|
||||
@@ -184,88 +196,7 @@ void UpdateIncludeDependenciesVisitor::visitMComponent(qmt::MComponent *componen
|
||||
dependency->setTarget(includeComponent->uid());
|
||||
m_modelController->addRelation(component, dependency);
|
||||
}
|
||||
|
||||
// search ancestors sharing a common owner
|
||||
QList<qmt::MPackage *> componentAncestors;
|
||||
auto ancestor = dynamic_cast<qmt::MPackage *>(component->owner());
|
||||
while (ancestor) {
|
||||
componentAncestors.append(ancestor);
|
||||
ancestor = dynamic_cast<qmt::MPackage *>(ancestor->owner());
|
||||
}
|
||||
QList<qmt::MPackage *> includeComponentAncestors;
|
||||
ancestor = dynamic_cast<qmt::MPackage *>(includeComponent->owner());
|
||||
while (ancestor) {
|
||||
includeComponentAncestors.append(ancestor);
|
||||
ancestor = dynamic_cast<qmt::MPackage *>(ancestor->owner());
|
||||
}
|
||||
|
||||
int componentHighestAncestorIndex = componentAncestors.size() - 1;
|
||||
int includeComponentHighestAncestorIndex = includeComponentAncestors.size() - 1;
|
||||
QMT_ASSERT(componentAncestors.at(componentHighestAncestorIndex) == includeComponentAncestors.at(includeComponentHighestAncestorIndex), return);
|
||||
while (componentHighestAncestorIndex > 0 && includeComponentHighestAncestorIndex > 0) {
|
||||
if (componentAncestors.at(componentHighestAncestorIndex) != includeComponentAncestors.at(includeComponentHighestAncestorIndex))
|
||||
break;
|
||||
--componentHighestAncestorIndex;
|
||||
--includeComponentHighestAncestorIndex;
|
||||
}
|
||||
|
||||
// add dependency between parent packages with same stereotype
|
||||
int index1 = 0;
|
||||
int includeComponentLowestIndex = 0;
|
||||
while (index1 <= componentHighestAncestorIndex
|
||||
&& includeComponentLowestIndex <= includeComponentHighestAncestorIndex) {
|
||||
if (!componentAncestors.at(index1)->stereotypes().isEmpty()) {
|
||||
int index2 = includeComponentLowestIndex;
|
||||
while (index2 <= includeComponentHighestAncestorIndex) {
|
||||
if (haveMatchingStereotypes(componentAncestors.at(index1), includeComponentAncestors.at(index2))) {
|
||||
if (!haveDependency(componentAncestors.at(index1), includeComponentAncestors.at(index2))) {
|
||||
auto dependency = new qmt::MDependency;
|
||||
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
||||
// TODO set stereotype for testing purpose
|
||||
dependency->setStereotypes(QStringList() << "same stereotype");
|
||||
dependency->setDirection(qmt::MDependency::AToB);
|
||||
dependency->setSource(componentAncestors.at(index1)->uid());
|
||||
dependency->setTarget(includeComponentAncestors.at(index2)->uid());
|
||||
m_modelController->addRelation(componentAncestors.at(index1), dependency);
|
||||
}
|
||||
includeComponentLowestIndex = index2 + 1;
|
||||
break;
|
||||
}
|
||||
++index2;
|
||||
}
|
||||
}
|
||||
++index1;
|
||||
}
|
||||
|
||||
// add dependency between topmost packages with common owner
|
||||
if (componentAncestors.at(componentHighestAncestorIndex) != includeComponentAncestors.at(includeComponentHighestAncestorIndex)) {
|
||||
if (!haveDependency(componentAncestors.at(componentHighestAncestorIndex), includeComponentAncestors)) {
|
||||
auto dependency = new qmt::MDependency;
|
||||
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
||||
// TODO set stereotype for testing purpose
|
||||
dependency->setStereotypes(QStringList() << "ancestor");
|
||||
dependency->setDirection(qmt::MDependency::AToB);
|
||||
dependency->setSource(componentAncestors.at(componentHighestAncestorIndex)->uid());
|
||||
dependency->setTarget(includeComponentAncestors.at(includeComponentHighestAncestorIndex)->uid());
|
||||
m_modelController->addRelation(componentAncestors.at(componentHighestAncestorIndex), dependency);
|
||||
}
|
||||
}
|
||||
|
||||
// add dependency between parent packages
|
||||
if (componentHighestAncestorIndex > 0 && includeComponentHighestAncestorIndex > 0) { // check for valid parents
|
||||
if (componentAncestors.at(0) != includeComponentAncestors.at(0)) {
|
||||
if (!haveDependency(componentAncestors.at(0), includeComponentAncestors)) {
|
||||
auto dependency = new qmt::MDependency;
|
||||
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
||||
// TODO set stereotype for testing purpose
|
||||
dependency->setStereotypes(QStringList() << "parents");
|
||||
dependency->setDirection(qmt::MDependency::AToB);
|
||||
dependency->setSource(componentAncestors.at(0)->uid());
|
||||
dependency->setTarget(includeComponentAncestors.at(0)->uid());
|
||||
m_modelController->addRelation(componentAncestors.at(0), dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_packageViewController->createAncestorDependencies(component, includeComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,12 +204,6 @@ void UpdateIncludeDependenciesVisitor::visitMComponent(qmt::MComponent *componen
|
||||
visitMObject(component);
|
||||
}
|
||||
|
||||
bool UpdateIncludeDependenciesVisitor::haveMatchingStereotypes(const qmt::MObject *object1,
|
||||
const qmt::MObject *object2)
|
||||
{
|
||||
return !(object1->stereotypes().toSet() & object2->stereotypes().toSet()).isEmpty();
|
||||
}
|
||||
|
||||
QStringList UpdateIncludeDependenciesVisitor::findFilePathOfComponent(const qmt::MComponent *component)
|
||||
{
|
||||
QStringList elementPath;
|
||||
@@ -335,48 +260,10 @@ qmt::MComponent *UpdateIncludeDependenciesVisitor::findComponentFromFilePath(con
|
||||
return component;
|
||||
}
|
||||
|
||||
bool UpdateIncludeDependenciesVisitor::haveDependency(const qmt::MObject *source,
|
||||
const qmt::MObject *target, bool inverted)
|
||||
{
|
||||
qmt::MDependency::Direction aToB = qmt::MDependency::AToB;
|
||||
qmt::MDependency::Direction bToA = qmt::MDependency::BToA;
|
||||
if (inverted) {
|
||||
aToB = qmt::MDependency::BToA;
|
||||
bToA = qmt::MDependency::AToB;
|
||||
}
|
||||
for (const qmt::Handle<qmt::MRelation> &handle : source->relations()) {
|
||||
if (auto dependency = dynamic_cast<qmt::MDependency *>(handle.target())) {
|
||||
if (dependency->source() == source->uid()
|
||||
&& dependency->target() == target->uid()
|
||||
&& (dependency->direction() == aToB
|
||||
|| dependency->direction() == qmt::MDependency::Bidirectional)) {
|
||||
return true;
|
||||
}
|
||||
if (dependency->source() == target->uid()
|
||||
&& dependency->target() == source->uid()
|
||||
&& (dependency->direction() == bToA
|
||||
|| dependency->direction() == qmt::MDependency::Bidirectional)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!inverted)
|
||||
return haveDependency(target, source, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UpdateIncludeDependenciesVisitor::haveDependency(const qmt::MObject *source,
|
||||
const QList<qmt::MPackage *> &targets)
|
||||
{
|
||||
foreach (const qmt::MObject *target, targets) {
|
||||
if (haveDependency(source, target))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class ComponentViewController::ComponentViewControllerPrivate {
|
||||
public:
|
||||
ModelUtilities *modelUtilities = nullptr;
|
||||
PackageViewController *packageViewController = nullptr;
|
||||
PxNodeUtilities *pxnodeUtilities = nullptr;
|
||||
qmt::DiagramSceneController *diagramSceneController = nullptr;
|
||||
};
|
||||
@@ -392,6 +279,16 @@ ComponentViewController::~ComponentViewController()
|
||||
delete d;
|
||||
}
|
||||
|
||||
void ComponentViewController::setModelUtilities(ModelUtilities *modelUtilities)
|
||||
{
|
||||
d->modelUtilities = modelUtilities;
|
||||
}
|
||||
|
||||
void ComponentViewController::setPackageViewController(PackageViewController *packageViewController)
|
||||
{
|
||||
d->packageViewController = packageViewController;
|
||||
}
|
||||
|
||||
void ComponentViewController::setPxNodeUtilties(PxNodeUtilities *pxnodeUtilities)
|
||||
{
|
||||
d->pxnodeUtilities = pxnodeUtilities;
|
||||
@@ -416,7 +313,9 @@ void ComponentViewController::updateIncludeDependencies(qmt::MPackage *rootPacka
|
||||
{
|
||||
d->diagramSceneController->modelController()->startResetModel();
|
||||
UpdateIncludeDependenciesVisitor visitor;
|
||||
visitor.setPackageViewController(d->packageViewController);
|
||||
visitor.setModelController(d->diagramSceneController->modelController());
|
||||
visitor.setModelUtilities(d->modelUtilities);
|
||||
visitor.updateFilePaths();
|
||||
rootPackage->accept(&visitor);
|
||||
d->diagramSceneController->modelController()->finishResetModel(true);
|
||||
|
@@ -38,6 +38,8 @@ class DiagramSceneController;
|
||||
namespace ModelEditor {
|
||||
namespace Internal {
|
||||
|
||||
class ModelUtilities;
|
||||
class PackageViewController;
|
||||
class PxNodeUtilities;
|
||||
|
||||
class ComponentViewController :
|
||||
@@ -50,6 +52,8 @@ public:
|
||||
explicit ComponentViewController(QObject *parent = nullptr);
|
||||
~ComponentViewController();
|
||||
|
||||
void setModelUtilities(ModelUtilities *modelUtilities);
|
||||
void setPackageViewController(PackageViewController *packageViewController);
|
||||
void setPxNodeUtilties(PxNodeUtilities *pxnodeUtilities);
|
||||
void setDiagramSceneController(qmt::DiagramSceneController *diagramSceneController);
|
||||
|
||||
|
@@ -23,7 +23,9 @@ SOURCES += \
|
||||
modeleditor_plugin.cpp \
|
||||
modelindexer.cpp \
|
||||
modelsmanager.cpp \
|
||||
modelutilities.cpp \
|
||||
openelementvisitor.cpp \
|
||||
packageviewcontroller.cpp \
|
||||
pxnodecontroller.cpp \
|
||||
pxnodeutilities.cpp \
|
||||
settingscontroller.cpp \
|
||||
@@ -48,7 +50,9 @@ HEADERS += \
|
||||
modeleditor_plugin.h \
|
||||
modelindexer.h \
|
||||
modelsmanager.h \
|
||||
modelutilities.h \
|
||||
openelementvisitor.h \
|
||||
packageviewcontroller.h \
|
||||
pxnodecontroller.h \
|
||||
pxnodeutilities.h \
|
||||
settingscontroller.h \
|
||||
|
@@ -59,8 +59,12 @@ QtcPlugin {
|
||||
"modelindexer.h",
|
||||
"modelsmanager.cpp",
|
||||
"modelsmanager.h",
|
||||
"modelutilities.cpp",
|
||||
"modelutilities.h",
|
||||
"openelementvisitor.cpp",
|
||||
"openelementvisitor.h",
|
||||
"packageviewcontroller.cpp",
|
||||
"packageviewcontroller.h",
|
||||
"pxnodecontroller.cpp",
|
||||
"pxnodecontroller.h",
|
||||
"pxnodeutilities.cpp",
|
||||
|
85
src/plugins/modeleditor/modelutilities.cpp
Normal file
85
src/plugins/modeleditor/modelutilities.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 Jochen Becher
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "modelutilities.h"
|
||||
|
||||
#include "qmt/model/mobject.h"
|
||||
#include "qmt/model/mdependency.h"
|
||||
#include "qmt/model/mpackage.h"
|
||||
|
||||
namespace ModelEditor {
|
||||
namespace Internal {
|
||||
|
||||
ModelUtilities::ModelUtilities(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
ModelUtilities::~ModelUtilities()
|
||||
{
|
||||
}
|
||||
|
||||
bool ModelUtilities::haveDependency(const qmt::MObject *source,
|
||||
const qmt::MObject *target, bool inverted)
|
||||
{
|
||||
qmt::MDependency::Direction aToB = qmt::MDependency::AToB;
|
||||
qmt::MDependency::Direction bToA = qmt::MDependency::BToA;
|
||||
if (inverted) {
|
||||
aToB = qmt::MDependency::BToA;
|
||||
bToA = qmt::MDependency::AToB;
|
||||
}
|
||||
for (const qmt::Handle<qmt::MRelation> &handle : source->relations()) {
|
||||
if (auto dependency = dynamic_cast<qmt::MDependency *>(handle.target())) {
|
||||
if (dependency->source() == source->uid()
|
||||
&& dependency->target() == target->uid()
|
||||
&& (dependency->direction() == aToB
|
||||
|| dependency->direction() == qmt::MDependency::Bidirectional)) {
|
||||
return true;
|
||||
}
|
||||
if (dependency->source() == target->uid()
|
||||
&& dependency->target() == source->uid()
|
||||
&& (dependency->direction() == bToA
|
||||
|| dependency->direction() == qmt::MDependency::Bidirectional)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!inverted)
|
||||
return haveDependency(target, source, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModelUtilities::haveDependency(const qmt::MObject *source,
|
||||
const QList<qmt::MPackage *> &targets)
|
||||
{
|
||||
foreach (const qmt::MPackage *target, targets) {
|
||||
if (haveDependency(source, target))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ModelEditor
|
51
src/plugins/modeleditor/modelutilities.h
Normal file
51
src/plugins/modeleditor/modelutilities.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 Jochen Becher
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace qmt {
|
||||
class MObject;
|
||||
class MPackage;
|
||||
}
|
||||
|
||||
namespace ModelEditor {
|
||||
namespace Internal {
|
||||
|
||||
class ModelUtilities : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ModelUtilities(QObject *parent = nullptr);
|
||||
~ModelUtilities();
|
||||
|
||||
bool haveDependency(const qmt::MObject *source, const qmt::MObject *target,
|
||||
bool inverted = false);
|
||||
bool haveDependency(const qmt::MObject *source, const QList<qmt::MPackage *> &targets);
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ModelEditor
|
157
src/plugins/modeleditor/packageviewcontroller.cpp
Normal file
157
src/plugins/modeleditor/packageviewcontroller.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 Jochen Becher
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "packageviewcontroller.h"
|
||||
|
||||
#include "modelutilities.h"
|
||||
|
||||
#include "qmt/model/mpackage.h"
|
||||
#include "qmt/model/mdependency.h"
|
||||
#include "qmt/model_controller/modelcontroller.h"
|
||||
|
||||
namespace ModelEditor {
|
||||
namespace Internal {
|
||||
|
||||
class PackageViewController::PackageViewControllerPrivate {
|
||||
public:
|
||||
qmt::ModelController *m_modelController = nullptr;
|
||||
ModelUtilities *m_modelUtilities = nullptr;
|
||||
};
|
||||
|
||||
PackageViewController::PackageViewController(QObject *parent)
|
||||
: QObject(parent),
|
||||
d(new PackageViewControllerPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
PackageViewController::~PackageViewController()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void PackageViewController::setModelController(qmt::ModelController *modelController)
|
||||
{
|
||||
d->m_modelController = modelController;
|
||||
}
|
||||
|
||||
void PackageViewController::setModelUtilities(ModelUtilities *modelUtilities)
|
||||
{
|
||||
d->m_modelUtilities = modelUtilities;
|
||||
}
|
||||
|
||||
void PackageViewController::createAncestorDependencies(qmt::MObject *object1, qmt::MObject *object2)
|
||||
{
|
||||
// search ancestors sharing a common owner
|
||||
QList<qmt::MPackage *> componentAncestors;
|
||||
auto ancestor = dynamic_cast<qmt::MPackage *>(object1->owner());
|
||||
while (ancestor) {
|
||||
componentAncestors.append(ancestor);
|
||||
ancestor = dynamic_cast<qmt::MPackage *>(ancestor->owner());
|
||||
}
|
||||
QList<qmt::MPackage *> includeComponentAncestors;
|
||||
ancestor = dynamic_cast<qmt::MPackage *>(object2->owner());
|
||||
while (ancestor) {
|
||||
includeComponentAncestors.append(ancestor);
|
||||
ancestor = dynamic_cast<qmt::MPackage *>(ancestor->owner());
|
||||
}
|
||||
|
||||
int componentHighestAncestorIndex = componentAncestors.size() - 1;
|
||||
int includeComponentHighestAncestorIndex = includeComponentAncestors.size() - 1;
|
||||
QMT_ASSERT(componentAncestors.at(componentHighestAncestorIndex) == includeComponentAncestors.at(includeComponentHighestAncestorIndex), return);
|
||||
while (componentHighestAncestorIndex > 0 && includeComponentHighestAncestorIndex > 0) {
|
||||
if (componentAncestors.at(componentHighestAncestorIndex) != includeComponentAncestors.at(includeComponentHighestAncestorIndex))
|
||||
break;
|
||||
--componentHighestAncestorIndex;
|
||||
--includeComponentHighestAncestorIndex;
|
||||
}
|
||||
|
||||
// add dependency between parent packages with same stereotype
|
||||
int index1 = 0;
|
||||
int includeComponentLowestIndex = 0;
|
||||
while (index1 <= componentHighestAncestorIndex
|
||||
&& includeComponentLowestIndex <= includeComponentHighestAncestorIndex) {
|
||||
if (!componentAncestors.at(index1)->stereotypes().isEmpty()) {
|
||||
int index2 = includeComponentLowestIndex;
|
||||
while (index2 <= includeComponentHighestAncestorIndex) {
|
||||
if (haveMatchingStereotypes(componentAncestors.at(index1), includeComponentAncestors.at(index2))) {
|
||||
if (!d->m_modelUtilities->haveDependency(componentAncestors.at(index1), includeComponentAncestors.at(index2))) {
|
||||
auto dependency = new qmt::MDependency;
|
||||
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
||||
// TODO set stereotype for testing purpose
|
||||
dependency->setStereotypes(QStringList() << "same stereotype");
|
||||
dependency->setDirection(qmt::MDependency::AToB);
|
||||
dependency->setSource(componentAncestors.at(index1)->uid());
|
||||
dependency->setTarget(includeComponentAncestors.at(index2)->uid());
|
||||
d->m_modelController->addRelation(componentAncestors.at(index1), dependency);
|
||||
}
|
||||
includeComponentLowestIndex = index2 + 1;
|
||||
break;
|
||||
}
|
||||
++index2;
|
||||
}
|
||||
}
|
||||
++index1;
|
||||
}
|
||||
|
||||
// add dependency between topmost packages with common owner
|
||||
if (componentAncestors.at(componentHighestAncestorIndex) != includeComponentAncestors.at(includeComponentHighestAncestorIndex)) {
|
||||
if (!d->m_modelUtilities->haveDependency(componentAncestors.at(componentHighestAncestorIndex), includeComponentAncestors)) {
|
||||
auto dependency = new qmt::MDependency;
|
||||
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
||||
// TODO set stereotype for testing purpose
|
||||
dependency->setStereotypes(QStringList() << "ancestor");
|
||||
dependency->setDirection(qmt::MDependency::AToB);
|
||||
dependency->setSource(componentAncestors.at(componentHighestAncestorIndex)->uid());
|
||||
dependency->setTarget(includeComponentAncestors.at(includeComponentHighestAncestorIndex)->uid());
|
||||
d->m_modelController->addRelation(componentAncestors.at(componentHighestAncestorIndex), dependency);
|
||||
}
|
||||
}
|
||||
|
||||
// add dependency between parent packages
|
||||
if (componentHighestAncestorIndex > 0 && includeComponentHighestAncestorIndex > 0) { // check for valid parents
|
||||
if (componentAncestors.at(0) != includeComponentAncestors.at(0)) {
|
||||
if (!d->m_modelUtilities->haveDependency(componentAncestors.at(0), includeComponentAncestors)) {
|
||||
auto dependency = new qmt::MDependency;
|
||||
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
||||
// TODO set stereotype for testing purpose
|
||||
dependency->setStereotypes(QStringList() << "parents");
|
||||
dependency->setDirection(qmt::MDependency::AToB);
|
||||
dependency->setSource(componentAncestors.at(0)->uid());
|
||||
dependency->setTarget(includeComponentAncestors.at(0)->uid());
|
||||
d->m_modelController->addRelation(componentAncestors.at(0), dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PackageViewController::haveMatchingStereotypes(const qmt::MObject *object1,
|
||||
const qmt::MObject *object2)
|
||||
{
|
||||
return !(object1->stereotypes().toSet() & object2->stereotypes().toSet()).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ModelEditor
|
61
src/plugins/modeleditor/packageviewcontroller.h
Normal file
61
src/plugins/modeleditor/packageviewcontroller.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 Jochen Becher
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace qmt {
|
||||
class MObject;
|
||||
class ModelController;
|
||||
}
|
||||
|
||||
namespace ModelEditor {
|
||||
namespace Internal {
|
||||
|
||||
class ModelUtilities;
|
||||
|
||||
class PackageViewController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
class PackageViewControllerPrivate;
|
||||
|
||||
public:
|
||||
explicit PackageViewController(QObject *parent = nullptr);
|
||||
~PackageViewController();
|
||||
|
||||
void setModelController(qmt::ModelController *modelController);
|
||||
void setModelUtilities(ModelUtilities *modelUtilities);
|
||||
|
||||
void createAncestorDependencies(qmt::MObject *object1, qmt::MObject *object2);
|
||||
|
||||
private:
|
||||
bool haveMatchingStereotypes(const qmt::MObject *object1, const qmt::MObject *object2);
|
||||
|
||||
PackageViewControllerPrivate *d;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ModelEditor
|
@@ -28,6 +28,8 @@
|
||||
#include "pxnodeutilities.h"
|
||||
#include "componentviewcontroller.h"
|
||||
#include "classviewcontroller.h"
|
||||
#include "modelutilities.h"
|
||||
#include "packageviewcontroller.h"
|
||||
|
||||
#include "qmt/model/mpackage.h"
|
||||
#include "qmt/model/mclass.h"
|
||||
@@ -92,6 +94,8 @@ class PxNodeController::PxNodeControllerPrivate
|
||||
{
|
||||
public:
|
||||
PxNodeUtilities *pxnodeUtilities = nullptr;
|
||||
ModelUtilities *modelUtilities = nullptr;
|
||||
PackageViewController *packageViewController = nullptr;
|
||||
ComponentViewController *componentViewController = nullptr;
|
||||
ClassViewController *classViewController = nullptr;
|
||||
qmt::DiagramSceneController *diagramSceneController = nullptr;
|
||||
@@ -103,8 +107,13 @@ PxNodeController::PxNodeController(QObject *parent)
|
||||
d(new PxNodeControllerPrivate)
|
||||
{
|
||||
d->pxnodeUtilities = new PxNodeUtilities(this);
|
||||
d->modelUtilities = new ModelUtilities(this);
|
||||
d->packageViewController = new PackageViewController(this);
|
||||
d->packageViewController->setModelUtilities(d->modelUtilities);
|
||||
d->componentViewController = new ComponentViewController(this);
|
||||
d->componentViewController->setPxNodeUtilties(d->pxnodeUtilities);
|
||||
d->componentViewController->setPackageViewController(d->packageViewController);
|
||||
d->componentViewController->setModelUtilities(d->modelUtilities);
|
||||
d->classViewController = new ClassViewController(this);
|
||||
}
|
||||
|
||||
@@ -123,6 +132,7 @@ void PxNodeController::setDiagramSceneController(
|
||||
{
|
||||
d->diagramSceneController = diagramSceneController;
|
||||
d->pxnodeUtilities->setDiagramSceneController(diagramSceneController);
|
||||
d->packageViewController->setModelController(diagramSceneController->modelController());
|
||||
d->componentViewController->setDiagramSceneController(diagramSceneController);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user