2016-01-15 14:57:40 +01:00
|
|
|
/****************************************************************************
|
2015-08-31 18:06:36 +02:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 Jochen Becher
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2015-08-31 18:06:36 +02:00
|
|
|
**
|
|
|
|
|
** 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
|
2016-01-15 14:57:40 +01:00
|
|
|
** 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.
|
2015-08-31 18:06:36 +02:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** 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.
|
2015-08-31 18:06:36 +02:00
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "componentviewcontroller.h"
|
|
|
|
|
|
|
|
|
|
#include "pxnodeutilities.h"
|
|
|
|
|
|
|
|
|
|
#include "qmt/controller/namecontroller.h"
|
|
|
|
|
#include "qmt/model_controller/mchildrenvisitor.h"
|
|
|
|
|
#include "qmt/model_controller/modelcontroller.h"
|
|
|
|
|
#include "qmt/model/mcomponent.h"
|
|
|
|
|
#include "qmt/model/mdependency.h"
|
|
|
|
|
#include "qmt/model/mpackage.h"
|
|
|
|
|
#include "qmt/tasks/diagramscenecontroller.h"
|
|
|
|
|
|
|
|
|
|
#include <cpptools/cppmodelmanager.h>
|
|
|
|
|
#include <cplusplus/CppDocument.h>
|
|
|
|
|
|
|
|
|
|
#include <projectexplorer/session.h>
|
|
|
|
|
#include <projectexplorer/projectnodes.h>
|
|
|
|
|
#include <projectexplorer/project.h>
|
|
|
|
|
|
|
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
|
|
|
|
#include <QFileInfo>
|
|
|
|
|
|
|
|
|
|
// TODO this class is experimental and not finished. Code needs fixes and to be cleaned up!
|
|
|
|
|
|
|
|
|
|
namespace ModelEditor {
|
|
|
|
|
namespace Internal {
|
|
|
|
|
|
|
|
|
|
class FindComponentFromFilePath :
|
|
|
|
|
public qmt::MChildrenVisitor
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
void setFilePath(const QString &filePath);
|
|
|
|
|
qmt::MComponent *component() const { return m_bestComponent; }
|
|
|
|
|
void visitMComponent(qmt::MComponent *component);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
QString m_elementName;
|
|
|
|
|
QStringList m_elementsPath;
|
|
|
|
|
int m_maxPathLength = 0;
|
|
|
|
|
qmt::MComponent *m_bestComponent = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void FindComponentFromFilePath::setFilePath(const QString &filePath)
|
|
|
|
|
{
|
|
|
|
|
m_elementName = qmt::NameController::convertFileNameToElementName(filePath);
|
|
|
|
|
QFileInfo fileInfo(filePath);
|
|
|
|
|
m_elementsPath = qmt::NameController::buildElementsPath(fileInfo.path(), false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FindComponentFromFilePath::visitMComponent(qmt::MComponent *component)
|
|
|
|
|
{
|
2015-11-04 22:44:41 +01:00
|
|
|
if (component->name() == m_elementName) {
|
2015-08-31 18:06:36 +02:00
|
|
|
QStringList elementPath;
|
2015-11-04 22:44:41 +01:00
|
|
|
const qmt::MObject *ancestor = component->owner();
|
2015-08-31 18:06:36 +02:00
|
|
|
while (ancestor) {
|
2015-11-04 22:44:41 +01:00
|
|
|
elementPath.prepend(ancestor->name());
|
|
|
|
|
ancestor = ancestor->owner();
|
2015-08-31 18:06:36 +02:00
|
|
|
}
|
|
|
|
|
int i = elementPath.size() - 1;
|
|
|
|
|
int j = m_elementsPath.size() - 1;
|
|
|
|
|
while (i >= 0 && j >= 0 && elementPath.at(i) == m_elementsPath.at(j)) {
|
|
|
|
|
--i;
|
|
|
|
|
--j;
|
|
|
|
|
}
|
|
|
|
|
int pathLength = elementPath.size() - 1 - i;
|
|
|
|
|
if (pathLength > m_maxPathLength) {
|
|
|
|
|
m_maxPathLength = pathLength;
|
|
|
|
|
m_bestComponent = component;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
visitMObject(component);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class UpdateIncludeDependenciesVisitor :
|
|
|
|
|
public qmt::MChildrenVisitor
|
|
|
|
|
{
|
|
|
|
|
class Node
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
Node() = default;
|
|
|
|
|
Node(const QString &filePath, const QStringList &elementPath)
|
|
|
|
|
: m_filePath(filePath),
|
|
|
|
|
m_elementPath(elementPath)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString m_filePath;
|
|
|
|
|
QStringList m_elementPath;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
void setModelController(qmt::ModelController *modelController);
|
|
|
|
|
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:
|
|
|
|
|
qmt::ModelController *m_modelController = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void UpdateIncludeDependenciesVisitor::setModelController(qmt::ModelController *modelController)
|
|
|
|
|
{
|
|
|
|
|
m_modelController = modelController;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UpdateIncludeDependenciesVisitor::visitMComponent(qmt::MComponent *component)
|
|
|
|
|
{
|
|
|
|
|
CppTools::CppModelManager *cppModelManager = CppTools::CppModelManager::instance();
|
|
|
|
|
CPlusPlus::Snapshot snapshot = cppModelManager->snapshot();
|
|
|
|
|
|
|
|
|
|
QStringList filePaths = findFilePathOfComponent(component);
|
|
|
|
|
foreach (const QString &filePath, filePaths) {
|
|
|
|
|
CPlusPlus::Document::Ptr document = snapshot.document(filePath);
|
|
|
|
|
if (document) {
|
|
|
|
|
foreach (const CPlusPlus::Document::Include &include, document->resolvedIncludes()) {
|
|
|
|
|
QString includeFilePath = include.resolvedFileName();
|
|
|
|
|
qmt::MComponent *includeComponent = findComponentFromFilePath(includeFilePath);
|
|
|
|
|
if (includeComponent && includeComponent != component) {
|
|
|
|
|
// add dependency between components
|
|
|
|
|
if (!haveDependency(component, includeComponent)) {
|
|
|
|
|
auto dependency = new qmt::MDependency;
|
2015-11-04 23:34:44 +01:00
|
|
|
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
2015-08-31 18:06:36 +02:00
|
|
|
dependency->setStereotypes(QStringList() << QStringLiteral("include"));
|
2015-11-04 23:34:44 +01:00
|
|
|
dependency->setDirection(qmt::MDependency::AToB);
|
2015-11-04 22:44:41 +01:00
|
|
|
dependency->setSource(component->uid());
|
|
|
|
|
dependency->setTarget(includeComponent->uid());
|
2015-08-31 18:06:36 +02:00
|
|
|
m_modelController->addRelation(component, dependency);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// search ancestors sharing a common owner
|
|
|
|
|
QList<qmt::MPackage *> componentAncestors;
|
2015-11-04 22:44:41 +01:00
|
|
|
auto ancestor = dynamic_cast<qmt::MPackage *>(component->owner());
|
2015-08-31 18:06:36 +02:00
|
|
|
while (ancestor) {
|
|
|
|
|
componentAncestors.append(ancestor);
|
2015-11-04 22:44:41 +01:00
|
|
|
ancestor = dynamic_cast<qmt::MPackage *>(ancestor->owner());
|
2015-08-31 18:06:36 +02:00
|
|
|
}
|
|
|
|
|
QList<qmt::MPackage *> includeComponentAncestors;
|
2015-11-04 22:44:41 +01:00
|
|
|
ancestor = dynamic_cast<qmt::MPackage *>(includeComponent->owner());
|
2015-08-31 18:06:36 +02:00
|
|
|
while (ancestor) {
|
|
|
|
|
includeComponentAncestors.append(ancestor);
|
2015-11-04 22:44:41 +01:00
|
|
|
ancestor = dynamic_cast<qmt::MPackage *>(ancestor->owner());
|
2015-08-31 18:06:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int componentHighestAncestorIndex = componentAncestors.size() - 1;
|
|
|
|
|
int includeComponentHighestAncestorIndex = includeComponentAncestors.size() - 1;
|
|
|
|
|
QTC_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) {
|
2015-11-04 22:44:41 +01:00
|
|
|
if (!componentAncestors.at(index1)->stereotypes().isEmpty()) {
|
2015-08-31 18:06:36 +02:00
|
|
|
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;
|
2015-11-04 23:34:44 +01:00
|
|
|
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
2015-08-31 18:06:36 +02:00
|
|
|
dependency->setStereotypes(QStringList() << QStringLiteral("same stereotype"));
|
2015-11-04 23:34:44 +01:00
|
|
|
dependency->setDirection(qmt::MDependency::AToB);
|
2015-11-04 22:44:41 +01:00
|
|
|
dependency->setSource(componentAncestors.at(index1)->uid());
|
|
|
|
|
dependency->setTarget(includeComponentAncestors.at(index2)->uid());
|
2015-08-31 18:06:36 +02:00
|
|
|
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;
|
2015-11-04 23:34:44 +01:00
|
|
|
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
2015-08-31 18:06:36 +02:00
|
|
|
dependency->setStereotypes(QStringList() << QStringLiteral("ancestor"));
|
2015-11-04 23:34:44 +01:00
|
|
|
dependency->setDirection(qmt::MDependency::AToB);
|
2015-11-04 22:44:41 +01:00
|
|
|
dependency->setSource(componentAncestors.at(componentHighestAncestorIndex)->uid());
|
|
|
|
|
dependency->setTarget(includeComponentAncestors.at(includeComponentHighestAncestorIndex)->uid());
|
2015-08-31 18:06:36 +02:00
|
|
|
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;
|
2015-11-04 23:34:44 +01:00
|
|
|
dependency->setFlags(qmt::MElement::ReverseEngineered);
|
2015-08-31 18:06:36 +02:00
|
|
|
dependency->setStereotypes(QStringList() << QStringLiteral("parents"));
|
2015-11-04 23:34:44 +01:00
|
|
|
dependency->setDirection(qmt::MDependency::AToB);
|
2015-11-04 22:44:41 +01:00
|
|
|
dependency->setSource(componentAncestors.at(0)->uid());
|
|
|
|
|
dependency->setTarget(includeComponentAncestors.at(0)->uid());
|
2015-08-31 18:06:36 +02:00
|
|
|
m_modelController->addRelation(componentAncestors.at(0), dependency);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
visitMObject(component);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool UpdateIncludeDependenciesVisitor::haveMatchingStereotypes(const qmt::MObject *object1,
|
|
|
|
|
const qmt::MObject *object2)
|
|
|
|
|
{
|
2015-11-04 22:44:41 +01:00
|
|
|
return !(object1->stereotypes().toSet() & object2->stereotypes().toSet()).isEmpty();
|
2015-08-31 18:06:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList UpdateIncludeDependenciesVisitor::findFilePathOfComponent(const qmt::MComponent *component)
|
|
|
|
|
{
|
|
|
|
|
QMultiHash<QString, Node> filePaths;
|
|
|
|
|
foreach (const ProjectExplorer::Project *project, ProjectExplorer::SessionManager::projects()) {
|
|
|
|
|
ProjectExplorer::ProjectNode *projectNode = project->rootProjectNode();
|
|
|
|
|
if (projectNode)
|
|
|
|
|
collectElementPaths(projectNode, &filePaths);
|
|
|
|
|
}
|
|
|
|
|
QStringList elementPath;
|
2015-11-04 22:44:41 +01:00
|
|
|
const qmt::MObject *ancestor = component->owner();
|
2015-08-31 18:06:36 +02:00
|
|
|
while (ancestor) {
|
2015-11-04 22:44:41 +01:00
|
|
|
elementPath.prepend(ancestor->name());
|
|
|
|
|
ancestor = ancestor->owner();
|
2015-08-31 18:06:36 +02:00
|
|
|
}
|
|
|
|
|
QStringList bestFilePaths;
|
|
|
|
|
int maxPathLength = 1;
|
2015-11-04 22:44:41 +01:00
|
|
|
foreach (const Node &node, filePaths.values(component->name())) {
|
2015-08-31 18:06:36 +02:00
|
|
|
int i = elementPath.size() - 1;
|
|
|
|
|
int j = node.m_elementPath.size() - 1;
|
|
|
|
|
while (i >= 0 && j >= 0 && elementPath.at(i) == node.m_elementPath.at(j)) {
|
|
|
|
|
--i;
|
|
|
|
|
--j;
|
|
|
|
|
}
|
|
|
|
|
int pathLength = elementPath.size() - 1 - i;
|
|
|
|
|
if (pathLength > maxPathLength)
|
|
|
|
|
bestFilePaths.clear();
|
|
|
|
|
if (pathLength >= maxPathLength) {
|
|
|
|
|
maxPathLength = pathLength;
|
|
|
|
|
bestFilePaths.append(node.m_filePath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return bestFilePaths;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UpdateIncludeDependenciesVisitor::collectElementPaths(const ProjectExplorer::FolderNode *folderNode,
|
|
|
|
|
QMultiHash<QString, Node> *filePathsMap)
|
|
|
|
|
{
|
|
|
|
|
foreach (const ProjectExplorer::FileNode *fileNode, folderNode->fileNodes()) {
|
2015-10-29 17:53:47 +01:00
|
|
|
QString elementName = qmt::NameController::convertFileNameToElementName(fileNode->filePath().toString());
|
2015-10-29 18:03:28 +01:00
|
|
|
QFileInfo fileInfo = fileNode->filePath().toFileInfo();
|
2015-08-31 18:06:36 +02:00
|
|
|
QString nodePath = fileInfo.path();
|
|
|
|
|
QStringList elementsPath = qmt::NameController::buildElementsPath(nodePath, false);
|
2015-10-29 17:53:47 +01:00
|
|
|
filePathsMap->insertMulti(elementName, Node(fileNode->filePath().toString(), elementsPath));
|
2015-08-31 18:06:36 +02:00
|
|
|
}
|
|
|
|
|
foreach (const ProjectExplorer::FolderNode *subNode, folderNode->subFolderNodes())
|
|
|
|
|
collectElementPaths(subNode, filePathsMap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qmt::MComponent *UpdateIncludeDependenciesVisitor::findComponentFromFilePath(const QString &filePath)
|
|
|
|
|
{
|
|
|
|
|
FindComponentFromFilePath visitor;
|
|
|
|
|
visitor.setFilePath(filePath);
|
2015-11-04 22:44:41 +01:00
|
|
|
m_modelController->rootPackage()->accept(&visitor);
|
2015-08-31 18:06:36 +02:00
|
|
|
return visitor.component();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool UpdateIncludeDependenciesVisitor::haveDependency(const qmt::MObject *source,
|
|
|
|
|
const qmt::MObject *target, bool inverted)
|
|
|
|
|
{
|
2015-11-04 23:34:44 +01:00
|
|
|
qmt::MDependency::Direction aToB = qmt::MDependency::AToB;
|
|
|
|
|
qmt::MDependency::Direction bToA = qmt::MDependency::BToA;
|
2015-08-31 18:06:36 +02:00
|
|
|
if (inverted) {
|
2015-11-04 23:34:44 +01:00
|
|
|
aToB = qmt::MDependency::BToA;
|
|
|
|
|
bToA = qmt::MDependency::AToB;
|
2015-08-31 18:06:36 +02:00
|
|
|
}
|
2015-11-04 22:44:41 +01:00
|
|
|
foreach (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
|
2015-11-04 23:34:44 +01:00
|
|
|
|| dependency->direction() == qmt::MDependency::Bidirectional)) {
|
2015-08-31 18:06:36 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
2015-11-04 22:44:41 +01:00
|
|
|
if (dependency->source() == target->uid()
|
|
|
|
|
&& dependency->target() == source->uid()
|
|
|
|
|
&& (dependency->direction() == bToA
|
2015-11-04 23:34:44 +01:00
|
|
|
|| dependency->direction() == qmt::MDependency::Bidirectional)) {
|
2015-08-31 18:06:36 +02:00
|
|
|
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:
|
|
|
|
|
PxNodeUtilities *pxnodeUtilities = 0;
|
|
|
|
|
qmt::DiagramSceneController *diagramSceneController = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ComponentViewController::ComponentViewController(QObject *parent)
|
|
|
|
|
: QObject(parent),
|
|
|
|
|
d(new ComponentViewControllerPrivate)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ComponentViewController::~ComponentViewController()
|
|
|
|
|
{
|
|
|
|
|
delete d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ComponentViewController::setPxNodeUtilties(PxNodeUtilities *pxnodeUtilities)
|
|
|
|
|
{
|
|
|
|
|
d->pxnodeUtilities = pxnodeUtilities;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ComponentViewController::setDiagramSceneController(qmt::DiagramSceneController *diagramSceneController)
|
|
|
|
|
{
|
|
|
|
|
d->diagramSceneController = diagramSceneController;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ComponentViewController::createComponentModel(const ProjectExplorer::FolderNode *folderNode,
|
|
|
|
|
qmt::MDiagram *diagram,
|
|
|
|
|
const QString anchorFolder)
|
|
|
|
|
{
|
|
|
|
|
foreach (const ProjectExplorer::FileNode *fileNode, folderNode->fileNodes()) {
|
2015-10-29 17:53:47 +01:00
|
|
|
QString componentName = qmt::NameController::convertFileNameToElementName(fileNode->filePath().toString());
|
2015-08-31 18:06:36 +02:00
|
|
|
qmt::MComponent *component = 0;
|
|
|
|
|
bool isSource = false;
|
2015-10-29 17:53:47 +01:00
|
|
|
CppTools::ProjectFile::Kind kind = CppTools::ProjectFile::classify(fileNode->filePath().toString());
|
2015-08-31 18:06:36 +02:00
|
|
|
switch (kind) {
|
|
|
|
|
case CppTools::ProjectFile::CHeader:
|
|
|
|
|
case CppTools::ProjectFile::CSource:
|
|
|
|
|
case CppTools::ProjectFile::CXXHeader:
|
|
|
|
|
case CppTools::ProjectFile::CXXSource:
|
|
|
|
|
case CppTools::ProjectFile::ObjCSource:
|
|
|
|
|
case CppTools::ProjectFile::ObjCHeader:
|
|
|
|
|
case CppTools::ProjectFile::ObjCXXSource:
|
|
|
|
|
case CppTools::ProjectFile::ObjCXXHeader:
|
|
|
|
|
case CppTools::ProjectFile::CudaSource:
|
|
|
|
|
case CppTools::ProjectFile::OpenCLSource:
|
|
|
|
|
isSource = true;
|
|
|
|
|
break;
|
|
|
|
|
case CppTools::ProjectFile::Unclassified:
|
|
|
|
|
isSource = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (isSource) {
|
|
|
|
|
component = new qmt::MComponent;
|
2015-11-04 23:34:44 +01:00
|
|
|
component->setFlags(qmt::MElement::ReverseEngineered);
|
2015-08-31 18:06:36 +02:00
|
|
|
component->setName(componentName);
|
|
|
|
|
}
|
|
|
|
|
if (component) {
|
|
|
|
|
QStringList relativeElements = qmt::NameController::buildElementsPath(
|
|
|
|
|
d->pxnodeUtilities->calcRelativePath(fileNode, anchorFolder), false);
|
|
|
|
|
if (d->pxnodeUtilities->findSameObject(relativeElements, component)) {
|
|
|
|
|
delete component;
|
|
|
|
|
} else {
|
|
|
|
|
qmt::MPackage *requestedRootPackage = d->diagramSceneController->findSuitableParentPackage(0, diagram);
|
|
|
|
|
qmt::MPackage *bestParentPackage = d->pxnodeUtilities->createBestMatchingPackagePath(requestedRootPackage, relativeElements);
|
2015-11-04 22:44:41 +01:00
|
|
|
d->diagramSceneController->modelController()->addObject(bestParentPackage, component);
|
2015-08-31 18:06:36 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (const ProjectExplorer::FolderNode *subNode, folderNode->subFolderNodes())
|
|
|
|
|
createComponentModel(subNode, diagram, anchorFolder);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ComponentViewController::updateIncludeDependencies(qmt::MPackage *rootPackage)
|
|
|
|
|
{
|
|
|
|
|
UpdateIncludeDependenciesVisitor visitor;
|
2015-11-04 22:44:41 +01:00
|
|
|
visitor.setModelController(d->diagramSceneController->modelController());
|
2015-08-31 18:06:36 +02:00
|
|
|
rootPackage->accept(&visitor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace ModelEditor
|