ModelEditor: Remove diagram's specific document and editor

Only one document is created per .qmodel file and only one editor is
opened (splitting is not yet supported). The editor shows one diagram,
another diagram can be shown from the model tree.

Change-Id: Icd8211c14cb09203c52769a8ea1c90edb741ae51
Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
This commit is contained in:
Jochen Becher
2015-09-21 12:11:02 +02:00
parent 1c7fb225db
commit 64760f0a8d
36 changed files with 1145 additions and 2290 deletions

View File

@@ -110,7 +110,7 @@ DiagramSceneModel::DiagramSceneModel(QObject *parent)
_style_controller(0),
_stereotype_controller(0),
_diagram(0),
_graphics_scene(new DiagramGraphicsScene(this, this)),
_graphics_scene(new DiagramGraphicsScene(this)),
_latch_controller(new LatchController(this)),
_busy(NOT_BUSY),
_origin_item(new OriginItem()),
@@ -134,6 +134,7 @@ DiagramSceneModel::~DiagramSceneModel()
if (_diagram_controller) {
disconnect(_diagram_controller, 0, this, 0);
}
_graphics_scene->deleteLater();
}
void DiagramSceneModel::setDiagramController(DiagramController *diagram_controller)

View File

@@ -131,11 +131,6 @@ void DiagramsManager::setStereotypeController(StereotypeController *stereotype_c
_stereotype_controller = stereotype_controller;
}
MDiagram *DiagramsManager::getCurrentDiagram() const
{
return _diagrams_view ? _diagrams_view->getCurrentDiagram() : 0;
}
DiagramSceneModel *DiagramsManager::bindDiagramSceneModel(MDiagram *diagram)
{
if (!_diagram_uid_to_managed_diagram_map.contains(diagram->getUid())) {

View File

@@ -93,8 +93,6 @@ public:
void setStereotypeController(StereotypeController *stereotype_controller);
MDiagram *getCurrentDiagram() const;
public:
DiagramSceneModel *bindDiagramSceneModel(MDiagram *diagram);

View File

@@ -43,8 +43,6 @@ public:
public:
virtual MDiagram *getCurrentDiagram() const = 0;
virtual void openDiagram(MDiagram *) = 0;
virtual void closeDiagram(const MDiagram *) = 0;

View File

@@ -61,12 +61,6 @@ void DiagramsView::setDiagramsManager(DiagramsManager *diagrams_manager)
_diagrams_manager = diagrams_manager;
}
MDiagram *DiagramsView::getCurrentDiagram() const
{
DiagramView *diagram_view = dynamic_cast<DiagramView *>(currentWidget());
return getDiagram(diagram_view);
}
void DiagramsView::openDiagram(MDiagram *diagram)
{
QMT_CHECK(diagram);

View File

@@ -72,8 +72,6 @@ public:
void setDiagramsManager(DiagramsManager *diagrams_manager);
MDiagram *getCurrentDiagram() const;
public slots:
void openDiagram(MDiagram *diagram);

View File

@@ -67,7 +67,8 @@ void DiagramView::setDiagramSceneModel(DiagramSceneModel *diagram_scene_model)
{
setScene(0);
_diagram_scene_model = diagram_scene_model;
setScene(_diagram_scene_model->getGraphicsScene());
if (diagram_scene_model)
setScene(_diagram_scene_model->getGraphicsScene());
}
void DiagramView::dragEnterEvent(QDragEnterEvent *event)

View File

@@ -57,12 +57,6 @@ void StackedDiagramsView::setDiagramsManager(DiagramsManager *diagrams_manager)
_diagrams_manager = diagrams_manager;
}
MDiagram *StackedDiagramsView::getCurrentDiagram() const
{
DiagramView *diagram_view = dynamic_cast<DiagramView *>(currentWidget());
return getDiagram(diagram_view);
}
void StackedDiagramsView::openDiagram(MDiagram *diagram)
{
QMT_CHECK(diagram);

View File

@@ -72,8 +72,6 @@ public:
void setDiagramsManager(DiagramsManager *diagrams_manager);
MDiagram *getCurrentDiagram() const;
public slots:
void openDiagram(MDiagram *diagram);

View File

@@ -147,10 +147,9 @@ bool DocumentController::isDiagramClipboardEmpty() const
return _diagram_clipboard->isEmpty();
}
bool DocumentController::hasCurrentDiagramSelection() const
bool DocumentController::hasDiagramSelection(const MDiagram *diagram) const
{
QMT_CHECK(_diagrams_manager->getCurrentDiagram());
return _diagrams_manager->getDiagramSceneModel(_diagrams_manager->getCurrentDiagram())->hasSelection();
return _diagrams_manager->getDiagramSceneModel(diagram)->hasSelection();
}
void DocumentController::cutFromModel(const MSelection &selection)
@@ -159,10 +158,8 @@ void DocumentController::cutFromModel(const MSelection &selection)
emit modelClipboardChanged(isModelClipboardEmpty());
}
void DocumentController::cutFromCurrentDiagram()
void DocumentController::cutFromDiagram(MDiagram *diagram)
{
MDiagram *diagram = _diagrams_manager->getCurrentDiagram();
QMT_CHECK(diagram);
*_diagram_clipboard = _diagram_controller->cutElements(_diagrams_manager->getDiagramSceneModel(diagram)->getSelectedElements(), diagram);
emit diagramClipboardChanged(isDiagramClipboardEmpty());
}
@@ -173,18 +170,15 @@ void DocumentController::copyFromModel(const MSelection &selection)
emit modelClipboardChanged(isModelClipboardEmpty());
}
void DocumentController::copyFromCurrentDiagram()
void DocumentController::copyFromDiagram(const qmt::MDiagram *diagram)
{
MDiagram *diagram = _diagrams_manager->getCurrentDiagram();
QMT_CHECK(diagram);
*_diagram_clipboard = _diagram_controller->copyElements(_diagrams_manager->getDiagramSceneModel(diagram)->getSelectedElements(), diagram);
emit diagramClipboardChanged(isDiagramClipboardEmpty());
}
void DocumentController::copyCurrentDiagram()
void DocumentController::copyDiagram(const MDiagram *diagram)
{
QMT_CHECK(_diagrams_manager->getCurrentDiagram());
_diagrams_manager->getDiagramSceneModel(_diagrams_manager->getCurrentDiagram())->copyToClipboard();
_diagrams_manager->getDiagramSceneModel(diagram)->copyToClipboard();
}
void DocumentController::pasteIntoModel(MObject *model_object)
@@ -194,10 +188,9 @@ void DocumentController::pasteIntoModel(MObject *model_object)
}
}
void DocumentController::pasteIntoCurrentDiagram()
void DocumentController::pasteIntoDiagram(MDiagram *diagram)
{
QMT_CHECK(_diagrams_manager->getCurrentDiagram());
_diagram_controller->pasteElements(*_diagram_clipboard, _diagrams_manager->getCurrentDiagram());
_diagram_controller->pasteElements(*_diagram_clipboard, diagram);
}
void DocumentController::deleteFromModel(const MSelection &selection)
@@ -205,27 +198,22 @@ void DocumentController::deleteFromModel(const MSelection &selection)
_model_controller->deleteElements(selection);
}
void DocumentController::deleteFromCurrentDiagram()
void DocumentController::deleteFromDiagram(MDiagram *diagram)
{
MDiagram *current_diagram = _diagrams_manager->getCurrentDiagram();
QMT_CHECK(current_diagram);
if (_diagrams_manager->getDiagramSceneModel(current_diagram)->hasSelection()) {
DSelection dselection = _diagrams_manager->getDiagramSceneModel(current_diagram)->getSelectedElements();
_diagram_scene_controller->deleteFromDiagram(dselection, current_diagram);
if (_diagrams_manager->getDiagramSceneModel(diagram)->hasSelection()) {
DSelection dselection = _diagrams_manager->getDiagramSceneModel(diagram)->getSelectedElements();
_diagram_scene_controller->deleteFromDiagram(dselection, diagram);
}
}
void DocumentController::removeFromCurrentDiagram()
void DocumentController::removeFromDiagram(MDiagram *diagram)
{
MDiagram *diagram = _diagrams_manager->getCurrentDiagram();
QMT_CHECK(diagram);
_diagram_controller->deleteElements(_diagrams_manager->getDiagramSceneModel(diagram)->getSelectedElements(), diagram);
}
void DocumentController::selectAllOnCurrentDiagram()
void DocumentController::selectAllOnDiagram(MDiagram *diagram)
{
QMT_CHECK(_diagrams_manager->getCurrentDiagram());
_diagrams_manager->getDiagramSceneModel(_diagrams_manager->getCurrentDiagram())->selectAllElements();
_diagrams_manager->getDiagramSceneModel(diagram)->selectAllElements();
}
MPackage *DocumentController::createNewPackage(MPackage *parent)

View File

@@ -108,31 +108,31 @@ public:
bool isDiagramClipboardEmpty() const;
bool hasCurrentDiagramSelection() const;
bool hasDiagramSelection(const qmt::MDiagram *diagram) const;
public:
void cutFromModel(const MSelection &selection);
Q_SLOT void cutFromCurrentDiagram();
void cutFromDiagram(MDiagram *diagram);
void copyFromModel(const MSelection &selection);
Q_SLOT void copyFromCurrentDiagram();
void copyFromDiagram(const MDiagram *diagram);
Q_SLOT void copyCurrentDiagram();
void copyDiagram(const MDiagram *diagram);
void pasteIntoModel(MObject *model_object);
Q_SLOT void pasteIntoCurrentDiagram();
void pasteIntoDiagram(MDiagram *diagram);
void deleteFromModel(const MSelection &selection);
Q_SLOT void deleteFromCurrentDiagram();
void deleteFromDiagram(MDiagram *diagram);
Q_SLOT void removeFromCurrentDiagram();
void removeFromDiagram(MDiagram *diagram);
Q_SLOT void selectAllOnCurrentDiagram();
void selectAllOnDiagram(MDiagram *diagram);
public:

View File

@@ -1,942 +0,0 @@
/***************************************************************************
**
** 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 "abstracteditor.h"
#include "actionhandler.h"
#include "diagramsviewmanager.h"
#include "documentinterface.h"
#include "dragtool.h"
#include "editordiagramview.h"
#include "elementtasks.h"
#include "extdocumentcontroller.h"
#include "modeleditor_constants.h"
#include "modeleditor_plugin.h"
#include "modelsmanager.h"
#include "openelementvisitor.h"
#include "uicontroller.h"
#include "qmt/controller/undocontroller.h"
#include "qmt/diagram/dpackage.h"
#include "qmt/diagram_controller/diagramcontroller.h"
#include "qmt/diagram_controller/dselection.h"
#include "qmt/diagram_scene/diagramscenemodel.h"
#include "qmt/diagram_ui/diagram_mime_types.h"
#include "qmt/diagram_ui/diagramsmanager.h"
#include "qmt/model/mpackage.h"
#include "qmt/model/mclass.h"
#include "qmt/model/mcomponent.h"
#include "qmt/model/mcanvasdiagram.h"
#include "qmt/model_controller/modelcontroller.h"
#include "qmt/model_controller/mselection.h"
#include "qmt/model_ui/treemodel.h"
#include "qmt/model_ui/treemodelmanager.h"
#include "qmt/model_widgets_ui/modeltreeview.h"
#include "qmt/model_widgets_ui/propertiesview.h"
#include "qmt/stereotype/shapepaintvisitor.h"
#include "qmt/stereotype/stereotypecontroller.h"
#include "qmt/stereotype/stereotypeicon.h"
#include "qmt/stereotype/toolbar.h"
#include "qmt/style/style.h"
#include "qmt/style/stylecontroller.h"
#include "qmt/tasks/diagramscenecontroller.h"
#include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/minisplitter.h>
#include <coreplugin/actionmanager/commandbutton.h>
#include <utils/styledbar.h>
#include <utils/qtcassert.h>
#include <QAction>
#include <QDir>
#include <QEvent>
#include <QFileInfo>
#include <QFrame>
#include <QHBoxLayout>
#include <QMap>
#include <QPainter>
#include <QPixmap>
#include <QScrollArea>
#include <QToolBox>
#include <QUndoStack>
#include <QVBoxLayout>
#include <QWidget>
#include <QStyleFactory>
#include <QDebug>
namespace ModelEditor {
namespace Internal {
class AbstractEditor::AbstractEditorPrivate
{
public:
UiController *uiController = 0;
ActionHandler *actionHandler = 0;
DocumentInterface *document = 0;
qmt::PropertiesView *propertiesView = 0;
Core::MiniSplitter *rightSplitter = 0;
QWidget *leftGroup = 0;
QHBoxLayout *leftGroupLayout = 0;
QToolBox *leftToolBox = 0;
EditorDiagramView *diagramView = 0;
DiagramsViewManager *diagramsViewManager = 0;
Core::MiniSplitter *rightHorizSplitter = 0;
qmt::ModelTreeView *modelTreeView = 0;
qmt::TreeModelManager *modelTreeViewServant = 0;
QScrollArea *propertiesScrollArea = 0;
QWidget *propertiesGroupWidget = 0;
QWidget *toolbar = 0;
SelectedArea selectedArea = NOTHING_SELECTED;
};
AbstractEditor::AbstractEditor(UiController *uiController, ActionHandler *actionHandler,
QWidget *parent)
: IEditor(parent),
d(new AbstractEditorPrivate)
{
d->uiController = uiController;
d->actionHandler = actionHandler;
}
AbstractEditor::~AbstractEditor()
{
if (d->document) {
ExtDocumentController *documentController = d->document->documentController();
qmt::DiagramsManager *diagramsManager = documentController->getDiagramsManager();
qmt::MDiagram *diagram = documentController->getModelController()->findObject<qmt::MDiagram>(d->document->diagramUid());
QTC_CHECK(diagram);
diagramsManager->unbindDiagramSceneModel(diagram);
}
delete d->toolbar;
delete d;
}
void AbstractEditor::init(QWidget *parent)
{
// create and configure properties view
d->propertiesView = new qmt::PropertiesView(this);
// create and configure editor ui
d->rightSplitter = new Core::MiniSplitter(parent);
connect(d->rightSplitter, &QSplitter::splitterMoved,
this, &AbstractEditor::onRightSplitterMoved);
connect(d->uiController, &UiController::rightSplitterChanged,
this, &AbstractEditor::onRightSplitterChanged);
d->leftGroup = new QWidget(d->rightSplitter);
d->leftGroupLayout = new QHBoxLayout(d->leftGroup);
d->leftGroupLayout->setContentsMargins(0, 0, 0, 0);
d->leftGroupLayout->setSpacing(0);
d->leftToolBox = new QToolBox(d->leftGroup);
// Windows style does not truncate the tab label to a very small width (GTK+ does)
static QStyle *windowsStyle = QStyleFactory().create(QStringLiteral("Windows"));
if (windowsStyle)
d->leftToolBox->setStyle(windowsStyle);
// TODO improve this (and the diagram colors) for use with dark theme
d->leftToolBox->setStyleSheet(
QLatin1String("QToolBox::tab {"
" margin-left: 2px;"
" background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
" stop: 0 #E1E1E1, stop: 0.4 #DDDDDD,"
" stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3);"
" color: #606060;"
"}"
""
"QToolBox::tab:selected {"
" font: italic;"
" color: black;"
"}"));
QFont font;
font.setPointSizeF(font.pointSizeF() * 0.8);
d->leftToolBox->setFont(font);
d->diagramView = new EditorDiagramView(d->leftGroup);
d->diagramView->setVisible(false);
d->leftGroupLayout->addWidget(d->leftToolBox, 0);
auto frame = new QFrame(d->leftGroup);
frame->setFrameShape(QFrame::VLine);
d->leftGroupLayout->addWidget(frame, 0);
d->leftGroupLayout->addWidget(d->diagramView, 1);
d->rightHorizSplitter = new Core::MiniSplitter(d->rightSplitter);
d->rightHorizSplitter->setOrientation(Qt::Vertical);
connect(d->rightHorizSplitter, &QSplitter::splitterMoved,
this, &AbstractEditor::onRightHorizSplitterMoved);
connect(d->uiController, &UiController::rightHorizSplitterChanged,
this, &AbstractEditor::onRightHorizSplitterChanged);
d->modelTreeView = new qmt::ModelTreeView(d->rightHorizSplitter);
d->modelTreeView->setFrameShape(QFrame::NoFrame);
d->modelTreeViewServant = new qmt::TreeModelManager(this);
d->modelTreeViewServant->setModelTreeView(d->modelTreeView);
d->propertiesScrollArea = new QScrollArea(d->rightHorizSplitter);
d->propertiesScrollArea->setFrameShape(QFrame::NoFrame);
d->propertiesScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
d->propertiesScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
d->propertiesScrollArea->setWidgetResizable(true);
d->rightHorizSplitter->insertWidget(0, d->modelTreeView);
d->rightHorizSplitter->insertWidget(1, d->propertiesScrollArea);
d->rightHorizSplitter->setStretchFactor(0, 2); // magic stretch factors for equal sizing
d->rightHorizSplitter->setStretchFactor(1, 3);
d->rightSplitter->insertWidget(0, d->leftGroup);
d->rightSplitter->insertWidget(1, d->rightHorizSplitter);
d->rightSplitter->setStretchFactor(0, 1);
d->rightSplitter->setStretchFactor(1, 0);
setWidget(d->rightSplitter);
// restore splitter sizes afer any stretch factor has been set as fallback
if (d->uiController->hasRightSplitterState())
d->rightSplitter->restoreState(d->uiController->rightSplitterState());
if (d->uiController->hasRightHorizSplitterState())
d->rightHorizSplitter->restoreState(d->uiController->rightHorizSplitterState());
// create and configure toolbar
d->toolbar = new QWidget();
auto toolbarLayout = new QHBoxLayout(d->toolbar);
toolbarLayout->setContentsMargins(0, 0, 0, 0);
toolbarLayout->setSpacing(0);
toolbarLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
toolbarLayout->addWidget(createToolbarCommandButton(
Constants::ACTION_ADD_PACKAGE, [this]() { onAddPackage(); },
QIcon(QStringLiteral(":/modelinglib/48x48/package.png")),
tr("Add Package"), d->toolbar));
toolbarLayout->addWidget(createToolbarCommandButton(
Constants::ACTION_ADD_COMPONENT, [this]() { onAddComponent(); },
QIcon(QStringLiteral(":/modelinglib/48x48/component.png")),
tr("Add Component"), d->toolbar));
toolbarLayout->addWidget(createToolbarCommandButton(
Constants::ACTION_ADD_CLASS, [this]() { onAddClass(); },
QIcon(QStringLiteral(":/modelinglib/48x48/class.png")),
tr("Add Class"), d->toolbar));
toolbarLayout->addWidget(createToolbarCommandButton(
Constants::ACTION_ADD_CANVAS_DIAGRAM, [this]() { onAddCanvasDiagram(); },
QIcon(QStringLiteral(":/modelinglib/48x48/canvas-diagram.png")),
tr("Add Canvas Diagram"), d->toolbar));
toolbarLayout->addItem(new QSpacerItem(20, 0));
}
void AbstractEditor::setDocument(DocumentInterface *document)
{
QTC_CHECK(!d->document);
d->document = document;
initToolbars();
ExtDocumentController *documentController = d->document->documentController();
d->diagramView->setPxNodeController(documentController->pxNodeController());
QTC_CHECK(!d->diagramsViewManager);
d->diagramsViewManager = ModelEditorPlugin::modelsManager()->findDiagramsViewManager(documentController);
documentController->getDiagramsManager()->setDiagramsView(d->diagramsViewManager);
d->propertiesView->setDiagramController(documentController->getDiagramController());
d->propertiesView->setModelController(documentController->getModelController());
d->propertiesView->setStereotypeController(documentController->getStereotypeController());
d->propertiesView->setStyleController(documentController->getStyleController());
d->modelTreeView->setTreeModel(documentController->getSortedTreeModel());
d->modelTreeView->setElementTasks(documentController->elementTasks());
d->modelTreeViewServant->setTreeModel(documentController->getTreeModel());
connect(documentController, &qmt::DocumentController::diagramClipboardChanged,
this, &AbstractEditor::onDiagramClipboardChanged, Qt::QueuedConnection);
connect(documentController->getUndoController()->getUndoStack(), &QUndoStack::canUndoChanged,
this, &AbstractEditor::onCanUndoChanged, Qt::QueuedConnection);
connect(documentController->getUndoController()->getUndoStack(), &QUndoStack::canRedoChanged,
this, &AbstractEditor::onCanRedoChanged, Qt::QueuedConnection);
connect(documentController->getTreeModel(), &qmt::TreeModel::modelReset,
this, &AbstractEditor::onTreeModelReset, Qt::QueuedConnection);
connect(documentController->getDiagramController(), &qmt::DiagramController::modified,
this, &AbstractEditor::onDiagramModified, Qt::QueuedConnection);
connect(documentController->getDiagramsManager(), &qmt::DiagramsManager::diagramSelectionChanged,
this, &AbstractEditor::onDiagramSelectionChanged, Qt::QueuedConnection);
connect(documentController->getDiagramsManager(), &qmt::DiagramsManager::diagramActivated,
this, &AbstractEditor::onDiagramActivated, Qt::QueuedConnection);
connect(documentController->getDiagramSceneController(), &qmt::DiagramSceneController::newElementCreated,
this, &AbstractEditor::onNewElementCreated, Qt::QueuedConnection);
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
this, &AbstractEditor::onCurrentEditorChanged, Qt::QueuedConnection);
connect(d->modelTreeView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &AbstractEditor::onTreeViewSelectionChanged, Qt::QueuedConnection);
connect(d->modelTreeView, &qmt::ModelTreeView::treeViewActivated,
this, &AbstractEditor::onTreeViewActivated, Qt::QueuedConnection);
connect(d->modelTreeView, &QAbstractItemView::doubleClicked,
this, &AbstractEditor::onTreeViewDoubleClicked, Qt::QueuedConnection);
updateSelectedArea(NOTHING_SELECTED);
// select diagram in model tree view
qmt::MDiagram *diagram = documentController->getModelController()->findObject<qmt::MDiagram>(d->document->diagramUid());
QTC_CHECK(diagram);
QModelIndex modelIndex = documentController->getTreeModel()->getIndex(diagram);
if (modelIndex.isValid())
d->modelTreeView->selectFromSourceModelIndex(modelIndex);
}
QWidget *AbstractEditor::toolBar()
{
return d->toolbar;
}
qmt::MDiagram *AbstractEditor::editorDiagram() const
{
if (!d->diagramView->getDiagramSceneModel())
return 0;
return d->diagramView->getDiagramSceneModel()->getDiagram();
}
void AbstractEditor::undo()
{
d->document->documentController()->getUndoController()->getUndoStack()->undo();
}
void AbstractEditor::redo()
{
d->document->documentController()->getUndoController()->getUndoStack()->redo();
}
void AbstractEditor::cut()
{
ExtDocumentController *documentController = d->document->documentController();
switch (d->selectedArea) {
case NOTHING_SELECTED:
break;
case DIAGRAM_SELECTED:
documentController->cutFromCurrentDiagram();
break;
case TREE_VIEW_SELECTED:
documentController->cutFromModel(d->modelTreeViewServant->getSelectedObjects());
break;
}
}
void AbstractEditor::copy()
{
ExtDocumentController *documentController = d->document->documentController();
switch (d->selectedArea) {
case NOTHING_SELECTED:
break;
case DIAGRAM_SELECTED:
if (documentController->hasCurrentDiagramSelection())
documentController->copyFromCurrentDiagram();
else
documentController->copyCurrentDiagram();
break;
case TREE_VIEW_SELECTED:
documentController->copyFromModel(d->modelTreeViewServant->getSelectedObjects());
break;
}
}
void AbstractEditor::paste()
{
ExtDocumentController *documentController = d->document->documentController();
switch (d->selectedArea) {
case NOTHING_SELECTED:
break;
case DIAGRAM_SELECTED:
documentController->pasteIntoCurrentDiagram();
break;
case TREE_VIEW_SELECTED:
documentController->pasteIntoModel(d->modelTreeViewServant->getSelectedObject());
break;
}
}
void AbstractEditor::removeSelectedElements()
{
switch (d->selectedArea) {
case NOTHING_SELECTED:
break;
case DIAGRAM_SELECTED:
d->document->documentController()->removeFromCurrentDiagram();
break;
case TREE_VIEW_SELECTED:
break;
}
}
void AbstractEditor::deleteSelectedElements()
{
ExtDocumentController *documentController = d->document->documentController();
switch (d->selectedArea) {
case NOTHING_SELECTED:
break;
case DIAGRAM_SELECTED:
documentController->deleteFromCurrentDiagram();
break;
case TREE_VIEW_SELECTED:
documentController->deleteFromModel(d->modelTreeViewServant->getSelectedObjects());
break;
}
}
void AbstractEditor::selectAll()
{
d->document->documentController()->selectAllOnCurrentDiagram();
}
void AbstractEditor::editProperties()
{
d->propertiesView->editSelectedElement();
}
qmt::MPackage *AbstractEditor::guessSelectedPackage() const
{
qmt::MPackage *package = 0;
switch (d->selectedArea) {
case NOTHING_SELECTED:
package = d->modelTreeViewServant->getSelectedPackage();
break;
case DIAGRAM_SELECTED:
{
qmt::DocumentController *documentController = d->document->documentController();
qmt::DiagramsManager *diagramsManager = documentController->getDiagramsManager();
qmt::MDiagram *diagram = editorDiagram();
qmt::DSelection selection = diagramsManager->getDiagramSceneModel(diagram)->getSelectedElements();
if (selection.getIndices().size() == 1) {
qmt::DPackage *diagramElement = documentController->getDiagramController()->findElement<qmt::DPackage>(selection.getIndices().at(0).getElementKey(), diagram);
if (diagramElement)
package = documentController->getModelController()->findObject<qmt::MPackage>(diagramElement->getModelUid());
}
break;
}
case TREE_VIEW_SELECTED:
package = d->modelTreeViewServant->getSelectedPackage();
break;
}
return package;
}
void AbstractEditor::updateSelectedArea(SelectedArea selectedArea)
{
d->selectedArea = selectedArea;
qmt::DocumentController *documentController = d->document->documentController();
bool canCutCopyDelete = false;
bool canRemove = false;
bool canPaste = false;
bool canSelectAll = false;
bool canCopyDiagram = false;
QList<qmt::MElement *> propertiesModelElements;
QList<qmt::DElement *> propertiesDiagramElements;
qmt::MDiagram *propertiesDiagram = 0;
qmt::MDiagram *activeDiagram = documentController->getDiagramsManager()->getCurrentDiagram();
if (activeDiagram != editorDiagram())
return;
switch (d->selectedArea) {
case NOTHING_SELECTED:
canSelectAll = activeDiagram && !activeDiagram->getDiagramElements().isEmpty();
break;
case DIAGRAM_SELECTED:
{
QTC_ASSERT(activeDiagram, break);
bool hasSelection = documentController->getDiagramsManager()->getDiagramSceneModel(activeDiagram)->hasSelection();
canCutCopyDelete = hasSelection;
canRemove = hasSelection;
canPaste = !documentController->isDiagramClipboardEmpty();
canSelectAll = !activeDiagram->getDiagramElements().isEmpty();
canCopyDiagram = !hasSelection;
if (hasSelection) {
qmt::DSelection selection = documentController->getDiagramsManager()->getDiagramSceneModel(activeDiagram)->getSelectedElements();
if (!selection.isEmpty()) {
foreach (qmt::DSelection::Index index, selection.getIndices()) {
qmt::DElement *diagramElement = documentController->getDiagramController()->findElement(index.getElementKey(), activeDiagram);
if (diagramElement)
propertiesDiagramElements.append(diagramElement);
}
if (!propertiesDiagramElements.isEmpty())
propertiesDiagram = activeDiagram;
}
}
break;
}
case TREE_VIEW_SELECTED:
{
bool hasSelection = !d->modelTreeViewServant->getSelectedObjects().isEmpty();
bool hasSingleSelection = d->modelTreeViewServant->getSelectedObjects().getIndices().size() == 1;
canCutCopyDelete = hasSelection && !d->modelTreeViewServant->isRootPackageSelected();
canPaste = hasSingleSelection && !documentController->isModelClipboardEmpty();
canSelectAll = activeDiagram && !activeDiagram->getDiagramElements().isEmpty();
QModelIndexList indexes = d->modelTreeView->getSelectedSourceModelIndexes();
if (!indexes.isEmpty()) {
foreach (const QModelIndex &propertiesIndex, indexes) {
if (propertiesIndex.isValid()) {
qmt::MElement *modelElement = documentController->getTreeModel()->getElement(propertiesIndex);
if (modelElement)
propertiesModelElements.append(modelElement);
}
}
}
break;
}
}
d->actionHandler->cutAction()->setEnabled(canCutCopyDelete);
d->actionHandler->copyAction()->setEnabled(canCutCopyDelete || canCopyDiagram);
d->actionHandler->pasteAction()->setEnabled(canPaste);
d->actionHandler->removeAction()->setEnabled(canRemove);
d->actionHandler->deleteAction()->setEnabled(canCutCopyDelete);
d->actionHandler->selectAllAction()->setEnabled(canSelectAll);
if (!propertiesModelElements.isEmpty())
showProperties(propertiesModelElements);
else if (!propertiesDiagramElements.isEmpty())
showProperties(propertiesDiagram, propertiesDiagramElements);
else
clearProperties();
}
void AbstractEditor::showProperties(const QList<qmt::MElement *> &modelElements)
{
if (modelElements != d->propertiesView->getSelectedModelElements()) {
clearProperties();
if (modelElements.size() > 0) {
d->propertiesView->setSelectedModelElements(modelElements);
d->propertiesGroupWidget = d->propertiesView->getWidget();
d->propertiesScrollArea->setWidget(d->propertiesGroupWidget);
}
}
}
void AbstractEditor::showProperties(qmt::MDiagram *diagram,
const QList<qmt::DElement *> &diagramElements)
{
if (diagram != d->propertiesView->getSelectedDiagram()
|| diagramElements != d->propertiesView->getSelectedDiagramElements())
{
clearProperties();
if (diagram && diagramElements.size() > 0) {
d->propertiesView->setSelectedDiagramElements(diagramElements, diagram);
d->propertiesGroupWidget = d->propertiesView->getWidget();
d->propertiesScrollArea->setWidget(d->propertiesGroupWidget);
}
}
}
void AbstractEditor::clearProperties()
{
d->propertiesView->clearSelection();
if (d->propertiesGroupWidget) {
QWidget *scrollWidget = d->propertiesScrollArea->takeWidget();
Q_UNUSED(scrollWidget); // avoid warning in release mode
QTC_CHECK(scrollWidget == d->propertiesGroupWidget);
d->propertiesGroupWidget->deleteLater();
d->propertiesGroupWidget = 0;
}
}
void AbstractEditor::openDiagram(qmt::MDiagram *diagram)
{
QTC_ASSERT(diagram, return);
d->document->documentController()->getDiagramsManager()->openDiagram(diagram);
}
void AbstractEditor::showDiagram(qmt::MDiagram *diagram)
{
if (diagram) {
qmt::DiagramSceneModel *diagramSceneModel = d->document->documentController()->getDiagramsManager()->bindDiagramSceneModel(diagram);
QTC_ASSERT(diagramSceneModel, return);
QTC_ASSERT(d->diagramView, return);
d->diagramView->setDiagramSceneModel(diagramSceneModel);
d->diagramView->setVisible(true);
}
}
void AbstractEditor::expandModelTreeToDepth(int depth)
{
d->modelTreeView->expandToDepth(depth);
}
QWidget *AbstractEditor::createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
const QIcon &icon, const QString &toolTipBase,
QWidget *parent)
{
auto button = new Core::CommandButton(id, parent);
button->setIcon(icon);
button->setToolTipBase(toolTipBase);
connect(button, &Core::CommandButton::clicked, this, slot);
return button;
}
/*!
Tries to change the \a button icon to the icon specified by \a name
from the current theme. Returns \c true if icon is updated, \c false
otherwise.
*/
bool AbstractEditor::updateButtonIconByTheme(QAbstractButton *button, const QString &name)
{
QTC_ASSERT(button, return false);
QTC_ASSERT(!name.isEmpty(), return false);
if (QIcon::hasThemeIcon(name)) {
button->setIcon(QIcon::fromTheme(name));
return true;
}
return false;
}
void AbstractEditor::onAddPackage()
{
ExtDocumentController *documentController = d->document->documentController();
qmt::MPackage *package = documentController->createNewPackage(d->modelTreeViewServant->getSelectedPackage());
d->modelTreeView->selectFromSourceModelIndex(documentController->getTreeModel()->getIndex(package));
metaObject()->invokeMethod(this, "onEditSelectedElement", Qt::QueuedConnection);
}
void AbstractEditor::onAddComponent()
{
ExtDocumentController *documentController = d->document->documentController();
qmt::MComponent *component = documentController->createNewComponent(d->modelTreeViewServant->getSelectedPackage());
d->modelTreeView->selectFromSourceModelIndex(documentController->getTreeModel()->getIndex(component));
metaObject()->invokeMethod(this, "onEditSelectedElement", Qt::QueuedConnection);
}
void AbstractEditor::onAddClass()
{
ExtDocumentController *documentController = d->document->documentController();
qmt::MClass *klass = documentController->createNewClass(d->modelTreeViewServant->getSelectedPackage());
d->modelTreeView->selectFromSourceModelIndex(documentController->getTreeModel()->getIndex(klass));
metaObject()->invokeMethod(this, "onEditSelectedElement", Qt::QueuedConnection);
}
void AbstractEditor::onAddCanvasDiagram()
{
ExtDocumentController *documentController = d->document->documentController();
qmt::MDiagram *diagram = documentController->createNewCanvasDiagram(d->modelTreeViewServant->getSelectedPackage());
d->modelTreeView->selectFromSourceModelIndex(documentController->getTreeModel()->getIndex(diagram));
metaObject()->invokeMethod(this, "onEditSelectedElement", Qt::QueuedConnection);
}
void AbstractEditor::onCurrentEditorChanged(Core::IEditor *editor)
{
if (this == editor) {
QUndoStack *undo_stack = d->document->documentController()->getUndoController()->getUndoStack();
d->actionHandler->undoAction()->setDisabled(!undo_stack->canUndo());
d->actionHandler->redoAction()->setDisabled(!undo_stack->canRedo());
updateSelectedArea(NOTHING_SELECTED);
}
}
void AbstractEditor::onCanUndoChanged(bool canUndo)
{
if (this == Core::EditorManager::currentEditor())
d->actionHandler->undoAction()->setEnabled(canUndo);
}
void AbstractEditor::onCanRedoChanged(bool canRedo)
{
if (this == Core::EditorManager::currentEditor())
d->actionHandler->redoAction()->setEnabled(canRedo);
}
void AbstractEditor::onTreeModelReset()
{
updateSelectedArea(NOTHING_SELECTED);
}
void AbstractEditor::onTreeViewSelectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
Q_UNUSED(selected);
Q_UNUSED(deselected);
updateSelectedArea(TREE_VIEW_SELECTED);
}
void AbstractEditor::onTreeViewActivated()
{
updateSelectedArea(TREE_VIEW_SELECTED);
}
void AbstractEditor::onTreeViewDoubleClicked(const QModelIndex &index)
{
ExtDocumentController *documentController = d->document->documentController();
QModelIndex treeModelIndex = d->modelTreeView->mapToSourceModelIndex(index);
qmt::MElement *melement = documentController->getTreeModel()->getElement(treeModelIndex);
// double click on package is already used for toggeling tree
if (melement && !dynamic_cast<qmt::MPackage *>(melement))
documentController->elementTasks()->openElement(melement);
}
void AbstractEditor::onCurrentDiagramChanged(const qmt::MDiagram *diagram)
{
if (diagram) {
QTC_CHECK(diagram == d->document->documentController()->getDiagramsManager()->getCurrentDiagram());
updateSelectedArea(DIAGRAM_SELECTED);
} else {
updateSelectedArea(NOTHING_SELECTED);
}
}
void AbstractEditor::onDiagramActivated(const qmt::MDiagram *diagram)
{
Q_UNUSED(diagram);
updateSelectedArea(DIAGRAM_SELECTED);
}
void AbstractEditor::onDiagramClipboardChanged(bool isEmpty)
{
Q_UNUSED(isEmpty);
if (this == Core::EditorManager::currentEditor())
updateSelectedArea(d->selectedArea);
}
void AbstractEditor::onNewElementCreated(qmt::DElement *element, qmt::MDiagram *diagram)
{
if (diagram == editorDiagram()) {
ExtDocumentController *documentController = d->document->documentController();
documentController->getDiagramsManager()->getDiagramSceneModel(diagram)->selectElement(element);
qmt::MElement *melement = documentController->getModelController()->findElement(element->getModelUid());
if (!(melement && melement->getFlags().testFlag(qmt::MElement::REVERSE_ENGINEERED)))
metaObject()->invokeMethod(this, "onEditSelectedElement", Qt::QueuedConnection);
}
}
void AbstractEditor::onDiagramSelectionChanged(const qmt::MDiagram *diagram)
{
if (diagram == editorDiagram())
updateSelectedArea(DIAGRAM_SELECTED);
}
void AbstractEditor::onDiagramModified(const qmt::MDiagram *diagram)
{
Q_UNUSED(diagram);
updateSelectedArea(d->selectedArea);
}
void AbstractEditor::onEditSelectedElement()
{
// TODO introduce similar method for selected elements in model tree
// currently this method is called on adding new elements in model tree
// but the method is a no-op in that case.
qmt::MDiagram *diagram = d->propertiesView->getSelectedDiagram();
QList<qmt::DElement *> elements = d->propertiesView->getSelectedDiagramElements();
if (diagram && !elements.isEmpty()) {
qmt::DElement *element = elements.at(0);
if (element) {
qmt::DiagramSceneModel *diagramSceneModel = d->document->documentController()->getDiagramsManager()->getDiagramSceneModel(diagram);
if (diagramSceneModel->isElementEditable(element)) {
diagramSceneModel->editElement(element);
return;
}
}
d->propertiesView->editSelectedElement();
}
}
void AbstractEditor::onRightSplitterMoved(int pos, int index)
{
Q_UNUSED(pos);
Q_UNUSED(index);
d->uiController->onRightSplitterChanged(d->rightSplitter->saveState());
}
void AbstractEditor::onRightSplitterChanged(const QByteArray &state)
{
d->rightSplitter->restoreState(state);
}
void AbstractEditor::onRightHorizSplitterMoved(int pos, int index)
{
Q_UNUSED(pos);
Q_UNUSED(index);
d->uiController->onRightHorizSplitterChanged(d->rightHorizSplitter->saveState());
}
void AbstractEditor::onRightHorizSplitterChanged(const QByteArray &state)
{
d->rightHorizSplitter->restoreState(state);
}
void AbstractEditor::initToolbars()
{
QHash<QString, QWidget *> toolBars;
// TODO add toolbars sorted by prio
qmt::DocumentController *documentController = d->document->documentController();
qmt::StereotypeController *stereotypeController = documentController->getStereotypeController();
foreach (const qmt::Toolbar &toolbar, stereotypeController->getToolbars()) {
QWidget *toolBar = toolBars.value(toolbar.getId());
QLayout *toolBarLayout = 0;
if (!toolBar) {
toolBar = new QWidget(d->leftToolBox);
toolBarLayout = new QVBoxLayout(toolBar);
toolBarLayout->setContentsMargins(2, 2, 2, 2);
toolBarLayout->setSpacing(6);
d->leftToolBox->addItem(toolBar, toolbar.getId());
toolBars.insert(toolbar.getId(), toolBar);
} else {
toolBarLayout = toolBar->layout();
QTC_ASSERT(toolBarLayout, return);
}
foreach (const qmt::Toolbar::Tool &tool, toolbar.getTools()) {
switch (tool._tool_type) {
case qmt::Toolbar::TOOLTYPE_TOOL:
{
QString iconPath;
qmt::StereotypeIcon::Element stereotypeIconElement = qmt::StereotypeIcon::ELEMENT_ANY;
qmt::StyleEngine::ElementType styleEngineElementType = qmt::StyleEngine::TYPE_OTHER;
if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_PACKAGE)) {
iconPath = QStringLiteral(":/modelinglib/48x48/package.png");
stereotypeIconElement = qmt::StereotypeIcon::ELEMENT_PACKAGE;
styleEngineElementType = qmt::StyleEngine::TYPE_PACKAGE;
} else if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_COMPONENT)) {
iconPath = QStringLiteral(":/modelinglib/48x48/component.png");
stereotypeIconElement = qmt::StereotypeIcon::ELEMENT_COMPONENT;
styleEngineElementType = qmt::StyleEngine::TYPE_COMPONENT;
} else if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_CLASS)) {
iconPath = QStringLiteral(":/modelinglib/48x48/class.png");
stereotypeIconElement = qmt::StereotypeIcon::ELEMENT_CLASS;
styleEngineElementType = qmt::StyleEngine::TYPE_CLASS;
} else if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_ITEM)) {
iconPath = QStringLiteral(":/modelinglib/48x48/item.png");
stereotypeIconElement = qmt::StereotypeIcon::ELEMENT_ITEM;
styleEngineElementType = qmt::StyleEngine::TYPE_ITEM;
} else if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_ANNOTATION)) {
iconPath = QStringLiteral(":/modelinglib/48x48/annotation.png");
styleEngineElementType = qmt::StyleEngine::TYPE_ANNOTATION;
} else if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_BOUNDARY)) {
iconPath = QStringLiteral(":/modelinglib/48x48/boundary.png");
styleEngineElementType = qmt::StyleEngine::TYPE_BOUNDARY;
}
QIcon icon;
if (!tool._stereotype.isEmpty() && stereotypeIconElement != qmt::StereotypeIcon::ELEMENT_ANY) {
const qmt::Style *style = documentController->getStyleController()->adaptStyle(styleEngineElementType);
icon = stereotypeController->createIcon(
stereotypeIconElement, QStringList() << tool._stereotype,
QString(), style, QSize(48, 48), QMarginsF(3.0, 2.0, 3.0, 4.0));
}
if (icon.isNull())
icon = QIcon(iconPath);
if (!icon.isNull()) {
toolBarLayout->addWidget(new DragTool(icon, tool._name, tool._element_type,
tool._stereotype, toolBar));
}
break;
}
case qmt::Toolbar::TOOLTYPE_SEPARATOR:
{
auto horizLine1 = new QFrame(d->leftToolBox);
horizLine1->setFrameShape(QFrame::HLine);
toolBarLayout->addWidget(horizLine1);
break;
}
}
}
}
// fallback if no toolbar was defined
if (!toolBars.isEmpty()) {
QString generalId = QStringLiteral("General");
auto toolBar = new QWidget(d->leftToolBox);
auto toolBarLayout = new QVBoxLayout(toolBar);
toolBarLayout->setContentsMargins(2, 2, 2, 2);
toolBarLayout->setSpacing(6);
d->leftToolBox->insertItem(0, toolBar, generalId);
toolBars.insert(generalId, toolBar);
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/package.png")),
tr("Package"), QLatin1String(qmt::ELEMENT_TYPE_PACKAGE),
QString(), toolBar));
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/component.png")),
tr("Component"), QLatin1String(qmt::ELEMENT_TYPE_COMPONENT),
QString(), toolBar));
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/class.png")),
tr("Class"), QLatin1String(qmt::ELEMENT_TYPE_CLASS),
QString(), toolBar));
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/item.png")),
tr("Item"), QLatin1String(qmt::ELEMENT_TYPE_ITEM),
QString(), toolBar));
auto horizLine1 = new QFrame(d->leftToolBox);
horizLine1->setFrameShape(QFrame::HLine);
toolBarLayout->addWidget(horizLine1);
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/annotation.png")),
tr("Annotation"), QLatin1String(qmt::ELEMENT_TYPE_ANNOTATION),
QString(), toolBar));
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/boundary.png")),
tr("Boundary"), QLatin1String(qmt::ELEMENT_TYPE_BOUNDARY),
QString(), toolBar));
}
// add stretch to all layouts and calculate width of tool bar
int maxWidth = 48;
foreach (QWidget *toolBar, toolBars) {
QTC_ASSERT(toolBar, continue);
auto layout = dynamic_cast<QBoxLayout *>(toolBar->layout());
QTC_ASSERT(layout, continue);
layout->addStretch(1);
toolBar->adjustSize();
if (maxWidth < toolBar->width())
maxWidth = toolBar->width();
}
d->leftToolBox->setFixedWidth(maxWidth);
d->leftToolBox->setCurrentIndex(0);
}
} // namespace Internal
} // namespace ModelEditor

View File

@@ -1,144 +0,0 @@
/***************************************************************************
**
** 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 ABSTRACTEDITOR_H
#define ABSTRACTEDITOR_H
#include <coreplugin/editormanager/ieditor.h>
#include <QAbstractButton>
#include <functional>
QT_BEGIN_NAMESPACE
class QItemSelection;
QT_END_NAMESPACE
namespace qmt {
class MElement;
class MPackage;
class MDiagram;
class DElement;
class DocumentController;
}
namespace ModelEditor {
namespace Internal {
class UiController;
class ActionHandler;
class DiagramsViewManager;
class DocumentInterface;
enum SelectedArea {
NOTHING_SELECTED,
DIAGRAM_SELECTED,
TREE_VIEW_SELECTED
};
class AbstractEditor :
public Core::IEditor
{
Q_OBJECT
class AbstractEditorPrivate;
public:
explicit AbstractEditor(UiController *uiController, ActionHandler *actionHandler,
QWidget *parent = 0);
~AbstractEditor();
protected:
void init(QWidget *parent);
void setDocument(DocumentInterface *document);
public:
QWidget *toolBar() override;
qmt::MDiagram *editorDiagram() const;
void undo();
void redo();
void cut();
void copy();
void paste();
void removeSelectedElements();
void deleteSelectedElements();
void selectAll();
void editProperties();
qmt::MPackage *guessSelectedPackage() const;
protected:
void updateSelectedArea(SelectedArea selectedArea);
void showProperties(const QList<qmt::MElement *> &modelElements);
void showProperties(qmt::MDiagram *diagram, const QList<qmt::DElement *> &diagramElements);
void clearProperties();
void openDiagram(qmt::MDiagram *diagram);
void showDiagram(qmt::MDiagram *diagram);
void expandModelTreeToDepth(int depth);
QWidget *createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
const QIcon &icon,
const QString &toolTipBase, QWidget *parent);
bool updateButtonIconByTheme(QAbstractButton *button, const QString &name);
private slots:
void onAddPackage();
void onAddComponent();
void onAddClass();
void onAddCanvasDiagram();
void onCurrentEditorChanged(Core::IEditor *editor);
void onCanUndoChanged(bool canUndo);
void onCanRedoChanged(bool canRedo);
void onTreeModelReset();
void onTreeViewSelectionChanged(const QItemSelection &selected,
const QItemSelection &deselected);
void onTreeViewActivated();
void onTreeViewDoubleClicked(const QModelIndex &index);
void onCurrentDiagramChanged(const qmt::MDiagram *diagram);
void onDiagramActivated(const qmt::MDiagram *diagram);
void onDiagramClipboardChanged(bool isEmpty);
void onNewElementCreated(qmt::DElement *element, qmt::MDiagram *diagram);
void onDiagramSelectionChanged(const qmt::MDiagram *diagram);
void onDiagramModified(const qmt::MDiagram *diagram);
void onEditSelectedElement();
void onRightSplitterMoved(int pos, int index);
void onRightSplitterChanged(const QByteArray &state);
void onRightHorizSplitterMoved(int pos, int index);
void onRightHorizSplitterChanged(const QByteArray &state);
private:
void initToolbars();
private:
AbstractEditorPrivate *d;
};
} // namespace Internal
} // namespace ModelEditor
#endif // ABSTRACTEDITOR_H

View File

@@ -31,7 +31,7 @@
#include "actionhandler.h"
#include "modeleditor_constants.h"
#include "abstracteditor.h"
#include "modeleditor.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/actionmanager/actionmanager.h>
@@ -147,63 +147,63 @@ void ActionHandler::createEditPropertiesShortcut(const Core::Id &shortcutId)
void ActionHandler::undo()
{
auto editor = dynamic_cast<AbstractEditor *>(Core::EditorManager::currentEditor());
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->undo();
}
void ActionHandler::redo()
{
auto editor = dynamic_cast<AbstractEditor *>(Core::EditorManager::currentEditor());
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->redo();
}
void ActionHandler::cut()
{
auto editor = dynamic_cast<AbstractEditor *>(Core::EditorManager::currentEditor());
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->cut();
}
void ActionHandler::copy()
{
auto editor = dynamic_cast<AbstractEditor *>(Core::EditorManager::currentEditor());
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->copy();
}
void ActionHandler::paste()
{
auto editor = dynamic_cast<AbstractEditor *>(Core::EditorManager::currentEditor());
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->paste();
}
void ActionHandler::removeSelectedElements()
{
auto editor = dynamic_cast<AbstractEditor *>(Core::EditorManager::currentEditor());
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->removeSelectedElements();
}
void ActionHandler::deleteSelectedElements()
{
auto editor = dynamic_cast<AbstractEditor *>(Core::EditorManager::currentEditor());
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->deleteSelectedElements();
}
void ActionHandler::selectAll()
{
auto editor = dynamic_cast<AbstractEditor *>(Core::EditorManager::currentEditor());
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->selectAll();
}
void ActionHandler::onEditProperties()
{
auto editor = dynamic_cast<AbstractEditor *>(Core::EditorManager::currentEditor());
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->editProperties();
}

View File

@@ -1,210 +0,0 @@
/***************************************************************************
**
** 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 "diagramdocument.h"
#include "modeleditor_constants.h"
#include "modeleditor_plugin.h"
#include "modelsmanager.h"
#include "modeldocument.h"
#include "extdocumentcontroller.h"
#include "qmt/serializer/diagramreferenceserializer.h"
#include "qmt/project_controller/projectcontroller.h"
#include "qmt/project/project.h"
#include "qmt/model_controller/modelcontroller.h"
#include "qmt/model/mdiagram.h"
#include "qmt/controller/namecontroller.h"
#include <coreplugin/documentmanager.h>
#include <utils/fileutils.h>
#include <QFileInfo>
namespace ModelEditor {
namespace Internal {
class DiagramDocument::DiagramDocumentPrivate {
public:
ExtDocumentController *documentController = 0;
qmt::Uid diagramUid;
};
DiagramDocument::DiagramDocument(QObject *parent)
: Core::IDocument(parent),
d(new DiagramDocumentPrivate)
{
setId(Constants::DIAGRAM_EDITOR_ID);
setMimeType(QLatin1String(Constants::MIME_TYPE_DIAGRAM_REFERENCE));
}
DiagramDocument::~DiagramDocument()
{
if (d->documentController)
ModelEditorPlugin::modelsManager()->release(d->documentController, this);
delete d;
}
bool DiagramDocument::save(QString *errorString, const QString &name, bool autoSave)
{
Q_UNUSED(autoSave);
if (!d->documentController) {
*errorString = tr("No model loaded. Cannot save diagram's model file.");
return false;
}
// "Save As" is not allowed"
if (!name.isEmpty() && name != filePath().toString()) {
*errorString = tr("Cannot save diagrams to file.");
return false;
}
ModelDocument *modelDocument = ModelEditorPlugin::modelsManager()->findModelDocument(d->documentController);
if (modelDocument) {
Core::DocumentManager::saveDocument(modelDocument);
} else {
try {
if (d->documentController->getProjectController()->isModified())
d->documentController->getProjectController()->save();
} catch (const qmt::Exception &ex) {
*errorString = ex.getErrorMsg();
return false;
}
}
onDiagramRenamed();
return true;
}
bool DiagramDocument::setContents(const QByteArray &contents)
{
// load reference file
qmt::DiagramReferenceSerializer serializer;
qmt::DiagramReferenceSerializer::Reference reference = serializer.load(contents);
// this should never fail because the contents was generated from actual model and diagram
d->documentController = ModelEditorPlugin::modelsManager()->findOrLoadModel(reference._model_uid, this);
if (!d->documentController)
return false;
d->diagramUid = reference._diagram_uid;
qmt::MDiagram *diagram = d->documentController->getModelController()->findObject<qmt::MDiagram>(d->diagramUid);
if (!diagram)
return false;
connect(d->documentController, &qmt::DocumentController::changed, this, &IDocument::changed);
setTemporary(true);
// set document's file path to avoid asking for file path on saving document
// TODO encode model and diagram UIDs in path
// (allowing open from file name in DiagramEditor which is called
// if diagram shall be opened from navigation history)
QFileInfo fileInfo(d->documentController->getProjectController()->getProject()->getFileName());
QString filePath = fileInfo.path() + QStringLiteral("/")
+ qmt::NameController::convertElementNameToBaseFileName(diagram->getName())
+ QStringLiteral(".qdiagram");
setFilePath(Utils::FileName::fromString(filePath));
onDiagramRenamed();
emit contentSet();
return true;
}
bool DiagramDocument::isFileReadOnly() const
{
ModelDocument *modelDocument = ModelEditorPlugin::modelsManager()->findModelDocument(d->documentController);
if (modelDocument)
return modelDocument->isFileReadOnly();
if (isTemporary())
return false;
return Core::IDocument::isFileReadOnly();
}
QString DiagramDocument::defaultPath() const
{
return QLatin1String(".");
}
QString DiagramDocument::suggestedFileName() const
{
return tr("diagram.qdiagram");
}
bool DiagramDocument::isModified() const
{
return d->documentController ? d->documentController->getProjectController()->isModified() : false;
}
bool DiagramDocument::isSaveAsAllowed() const
{
return false;
}
bool DiagramDocument::reload(QString *errorString, Core::IDocument::ReloadFlag flag,
Core::IDocument::ChangeType type)
{
if (flag == FlagIgnore)
return true;
if (type == TypePermissions) {
emit changed();
return true;
}
*errorString = tr("Cannot reload diagram file.");
return false;
}
ExtDocumentController *DiagramDocument::documentController() const
{
return d->documentController;
}
qmt::Uid DiagramDocument::diagramUid() const
{
return d->diagramUid;
}
void DiagramDocument::onDiagramRenamed()
{
qmt::MDiagram *diagram = d->documentController->getModelController()->findObject<qmt::MDiagram>(d->diagramUid);
if (diagram) {
QFileInfo fileInfo(d->documentController->getProjectController()->getProject()->getFileName());
setPreferredDisplayName(tr("%1 [%2]").arg(diagram->getName()).arg(fileInfo.fileName()));
} else {
setPreferredDisplayName(QString());
}
}
} // namespace Internal
} // namespace ModelEditor

View File

@@ -1,76 +0,0 @@
/***************************************************************************
**
** 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 DIAGRAMDOCUMENT_H
#define DIAGRAMDOCUMENT_H
#include <coreplugin/idocument.h>
#include "documentinterface.h"
namespace ModelEditor {
namespace Internal {
class DiagramDocument :
public Core::IDocument,
public DocumentInterface
{
Q_OBJECT
class DiagramDocumentPrivate;
public:
explicit DiagramDocument(QObject *parent = 0);
~DiagramDocument();
signals:
void contentSet();
public:
bool save(QString *errorString, const QString &name, bool autoSave) override;
bool setContents(const QByteArray &contents) override;
bool isFileReadOnly() const override;
QString defaultPath() const override;
QString suggestedFileName() const override;
bool isModified() const override;
bool isSaveAsAllowed() const override;
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
ExtDocumentController *documentController() const override;
qmt::Uid diagramUid() const override;
void onDiagramRenamed();
private:
DiagramDocumentPrivate *d;
};
} // namespace Internal
} // namespace ModelEditor
#endif // DIAGRAMDOCUMENT_H

View File

@@ -1,89 +0,0 @@
/***************************************************************************
**
** 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 "diagrameditor.h"
#include "modeleditor_constants.h"
#include "diagramdocument.h"
#include "extdocumentcontroller.h"
#include "qmt/model/mdiagram.h"
#include "qmt/model_controller/modelcontroller.h"
#include "qmt/project/project.h"
#include "qmt/project_controller/projectcontroller.h"
#include <utils/qtcassert.h>
#include <QFileInfo>
namespace ModelEditor {
namespace Internal {
class DiagramEditor::DiagramEditorPrivate
{
public:
DiagramDocument *document = 0;
};
DiagramEditor::DiagramEditor(UiController *uiController, ActionHandler *actionHandler,
QWidget *parent)
: AbstractEditor(uiController, actionHandler, parent),
d(new DiagramEditorPrivate)
{
setContext(Core::Context(Constants::DIAGRAM_EDITOR_ID));
d->document = new DiagramDocument(this);
connect(d->document, &DiagramDocument::contentSet, this, &DiagramEditor::onContentSet);
init(parent);
}
DiagramEditor::~DiagramEditor()
{
delete d;
}
Core::IDocument *DiagramEditor::document()
{
return d->document;
}
void DiagramEditor::onContentSet()
{
setDocument(d->document);
// open diagram
qmt::MDiagram *diagram = d->document->documentController()->getModelController()->findObject<qmt::MDiagram>(d->document->diagramUid());
QTC_ASSERT(diagram, return);
showDiagram(diagram);
expandModelTreeToDepth(0);
}
} // namespace Internal
} // namespace ModelEditor

View File

@@ -1,62 +0,0 @@
/***************************************************************************
**
** 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 DIAGRAMEDITOR_H
#define DIAGRAMEDITOR_H
#include "abstracteditor.h"
namespace ModelEditor {
namespace Internal {
class DiagramEditor :
public AbstractEditor
{
Q_OBJECT
class DiagramEditorPrivate;
public:
explicit DiagramEditor(UiController *uiController, ActionHandler *actionHandler,
QWidget *parent = 0);
~DiagramEditor();
Core::IDocument *document() override;
private slots:
void onContentSet();
private:
DiagramEditorPrivate *d;
};
} // namespace Internal
} // namespace ModelEditor
#endif // DIAGRAMEDITOR_H

View File

@@ -1,78 +0,0 @@
/***************************************************************************
**
** 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 "diagrameditorfactory.h"
#include "modeleditor_constants.h"
#include "actionhandler.h"
#include "diagrameditor.h"
#include <QApplication>
namespace ModelEditor {
namespace Internal {
class DiagramEditorFactory::DiagramEditorFactoryPrivate
{
public:
UiController *uiController = 0;
ActionHandler *actionHandler = 0;
};
DiagramEditorFactory::DiagramEditorFactory(UiController *uiController, QObject *parent)
: Core::IEditorFactory(parent),
d(new DiagramEditorFactoryPrivate)
{
setId(Constants::DIAGRAM_EDITOR_ID);
setDisplayName(qApp->translate("OpenWith::Editors", Constants::DIAGRAM_EDITOR_DISPLAY_NAME));
addMimeType(Constants::MIME_TYPE_DIAGRAM_REFERENCE);
d->uiController = uiController;
d->actionHandler = new ActionHandler(Core::Context(Constants::DIAGRAM_EDITOR_ID), this);
}
DiagramEditorFactory::~DiagramEditorFactory()
{
delete d;
}
Core::IEditor *DiagramEditorFactory::createEditor()
{
return new DiagramEditor(d->uiController, d->actionHandler);
}
void DiagramEditorFactory::extensionsInitialized()
{
d->actionHandler->createActions();
d->actionHandler->createEditPropertiesShortcut(
Constants::SHORTCUT_DIAGRAM_EDITOR_EDIT_PROPERTIES);
}
} // namespace Internal
} // namespace ModelEditor

View File

@@ -1,62 +0,0 @@
/***************************************************************************
**
** 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 DIAGRAMEDITORFACTORY_H
#define DIAGRAMEDITORFACTORY_H
#include <coreplugin/editormanager/ieditorfactory.h>
namespace ModelEditor {
namespace Internal {
class UiController;
class DiagramEditorFactory :
public Core::IEditorFactory
{
Q_OBJECT
class DiagramEditorFactoryPrivate;
public:
explicit DiagramEditorFactory(UiController *uiController, QObject *parent = 0);
~DiagramEditorFactory();
Core::IEditor *createEditor() override;
void extensionsInitialized();
private:
DiagramEditorFactoryPrivate *d;
};
} // namespace Internal
} // namespace ModelEditor
#endif // DIAGRAMEDITORFACTORY_H

View File

@@ -30,7 +30,7 @@
#include "diagramsviewmanager.h"
#include "abstracteditor.h"
#include "modeleditor.h"
#include <coreplugin/editormanager/editormanager.h>
#include <utils/qtcassert.h>
@@ -40,40 +40,24 @@
namespace ModelEditor {
namespace Internal {
// TODO eliminate this class - realize interface in class ModelsManager.
DiagramsViewManager::DiagramsViewManager(QObject *parent)
: QObject(parent)
{
// TODO connect to EditorManager if active editor changed;
// then emit currentDiagramChanged eventually
}
qmt::MDiagram *DiagramsViewManager::getCurrentDiagram() const
{
// TODO currentEditor() is not good enough in case of split editors
// (drag&drop can be done in non-current editor but expects current diagram != 0)
Core::IEditor *editor = Core::EditorManager::currentEditor();
auto abstractEditor = dynamic_cast<AbstractEditor *>(editor);
if (!abstractEditor)
return 0;
return abstractEditor->editorDiagram();
}
void DiagramsViewManager::openDiagram(qmt::MDiagram *diagram)
{
emit openEditor(diagram);
emit openNewDiagram(diagram);
}
void DiagramsViewManager::closeDiagram(const qmt::MDiagram *diagram)
{
emit closeEditor(diagram);
emit closeOpenDiagram(diagram);
}
void DiagramsViewManager::closeAllDiagrams()
{
// should never be called in this realization
QTC_CHECK(false);
emit closeAllOpenDiagrams();
}
void DiagramsViewManager::onDiagramRenamed(const qmt::MDiagram *diagram)

View File

@@ -56,18 +56,12 @@ public:
~DiagramsViewManager() = default;
signals:
void currentDiagramChanged(const qmt::MDiagram *diagram);
// This signal is never emitted but exists for API compatibility to other realizations
// of qmt::DiagramsViewInterface. The signal is not needed in the context of ModelEditor plugin
void someDiagramOpened(bool);
void openEditor(const qmt::MDiagram *diagram);
void closeEditor(const qmt::MDiagram *diagram);
void openNewDiagram(qmt::MDiagram *diagram);
void closeOpenDiagram(const qmt::MDiagram *diagram);
void closeAllOpenDiagrams();
void diagramRenamed(const qmt::MDiagram *diagram);
public:
qmt::MDiagram *getCurrentDiagram() const override;
void openDiagram(qmt::MDiagram *diagram) override;
void closeDiagram(const qmt::MDiagram *diagram) override;
void closeAllDiagrams() override;

View File

@@ -1,51 +0,0 @@
/***************************************************************************
**
** 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 DOCUMENTINTERFACE_H
#define DOCUMENTINTERFACE_H
#include "qmt/infrastructure/uid.h"
namespace ModelEditor {
namespace Internal {
class ExtDocumentController;
class DocumentInterface {
public:
virtual ~DocumentInterface() { }
virtual ExtDocumentController *documentController() const = 0;
virtual qmt::Uid diagramUid() const = 0;
};
} // namespace Internal
} // namespace ModelEditor
#endif // DOCUMENTINTERFACE_H

View File

@@ -53,7 +53,6 @@ ExtDocumentController::ExtDocumentController(QObject *parent)
{
d->elementTasks = new ElementTasks;
d->pxNodeController = new PxNodeController(this);
// TODO use more specific dependency
d->elementTasks->setDocumentController(this);
getDiagramSceneController()->setElementTasks(d->elementTasks);

View File

@@ -52,7 +52,6 @@ namespace Internal {
class ModelDocument::ModelDocumentPrivate {
public:
ExtDocumentController *documentController = 0;
qmt::Uid diagramUid;
};
ModelDocument::ModelDocument(QObject *parent)
@@ -66,7 +65,7 @@ ModelDocument::ModelDocument(QObject *parent)
ModelDocument::~ModelDocument()
{
if (d->documentController)
ModelEditorPlugin::modelsManager()->release(d->documentController, this);
ModelEditorPlugin::modelsManager()->releaseModel(d->documentController);
delete d;
}
@@ -103,7 +102,6 @@ bool ModelDocument::save(QString *errorString, const QString &name, bool autoSav
emit changed();
}
onDiagramRenamed();
return true;
}
@@ -145,48 +143,22 @@ ExtDocumentController *ModelDocument::documentController() const
return d->documentController;
}
qmt::Uid ModelDocument::diagramUid() const
{
return d->diagramUid;
}
bool ModelDocument::load(QString *errorString, const QString &fileName)
{
d->documentController = ModelEditorPlugin::modelsManager()->findModelByFileName(fileName, this);
if (d->documentController) {
connect(d->documentController, &qmt::DocumentController::changed,
this, &IDocument::changed);
setFilePath(Utils::FileName::fromString(d->documentController->getProjectController()->getProject()->getFileName()));
} else {
d->documentController = ModelEditorPlugin::modelsManager()->createModel(this);
connect(d->documentController, &qmt::DocumentController::changed,
this, &IDocument::changed);
d->documentController = ModelEditorPlugin::modelsManager()->createModel(this);
connect(d->documentController, &qmt::DocumentController::changed, this, &IDocument::changed);
try {
d->documentController->loadProject(fileName);
setFilePath(Utils::FileName::fromString(d->documentController->getProjectController()->getProject()->getFileName()));
} catch (const qmt::Exception &ex) {
*errorString = ex.getErrorMsg();
return false;
}
try {
d->documentController->loadProject(fileName);
setFilePath(Utils::FileName::fromString(d->documentController->getProjectController()->getProject()->getFileName()));
} catch (const qmt::Exception &ex) {
*errorString = ex.getErrorMsg();
return false;
}
qmt::MDiagram *rootDiagram = d->documentController->findOrCreateRootDiagram();
d->diagramUid = rootDiagram->getUid();
onDiagramRenamed();
emit contentSet();
return true;
}
void ModelDocument::onDiagramRenamed()
{
qmt::MDiagram *diagram = d->documentController->getModelController()->findObject<qmt::MDiagram>(d->diagramUid);
if (diagram)
setPreferredDisplayName(tr("%1 [%2]").arg(diagram->getName()).arg(filePath().fileName()));
else
setPreferredDisplayName(QString());
}
} // namespace Internal
} // namespace ModelEditor

View File

@@ -32,7 +32,8 @@
#define MODELDOCUMENT_H
#include <coreplugin/idocument.h>
#include "documentinterface.h"
namespace qmt { class Uid; }
namespace ModelEditor {
namespace Internal {
@@ -40,8 +41,7 @@ namespace Internal {
class ExtDocumentController;
class ModelDocument :
public Core::IDocument,
public DocumentInterface
public Core::IDocument
{
Q_OBJECT
class ModelDocumentPrivate;
@@ -63,13 +63,10 @@ public:
bool isSaveAsAllowed() const override;
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
ExtDocumentController *documentController() const override;
qmt::Uid diagramUid() const override;
ExtDocumentController *documentController() const;
bool load(QString *errorString, const QString &fileName);
void onDiagramRenamed();
private:
ModelDocumentPrivate *d;
};

View File

@@ -30,15 +30,68 @@
#include "modeleditor.h"
#include "modeleditor_constants.h"
#include "modeldocument.h"
#include "actionhandler.h"
#include "diagramsviewmanager.h"
#include "dragtool.h"
#include "editordiagramview.h"
#include "elementtasks.h"
#include "extdocumentcontroller.h"
#include "modeldocument.h"
#include "modeleditor_constants.h"
#include "modeleditor_plugin.h"
#include "modelsmanager.h"
#include "openelementvisitor.h"
#include "uicontroller.h"
#include "qmt/controller/undocontroller.h"
#include "qmt/diagram/dpackage.h"
#include "qmt/diagram_controller/diagramcontroller.h"
#include "qmt/diagram_controller/dselection.h"
#include "qmt/diagram_scene/diagramscenemodel.h"
#include "qmt/diagram_ui/diagram_mime_types.h"
#include "qmt/diagram_ui/diagramsmanager.h"
#include "qmt/model/mpackage.h"
#include "qmt/model/mclass.h"
#include "qmt/model/mcomponent.h"
#include "qmt/model/mcanvasdiagram.h"
#include "qmt/model_controller/modelcontroller.h"
#include "qmt/model_controller/mselection.h"
#include "qmt/model_ui/treemodel.h"
#include "qmt/model_ui/treemodelmanager.h"
#include "qmt/model_widgets_ui/modeltreeview.h"
#include "qmt/model_widgets_ui/propertiesview.h"
#include "qmt/stereotype/shapepaintvisitor.h"
#include "qmt/stereotype/stereotypecontroller.h"
#include "qmt/stereotype/stereotypeicon.h"
#include "qmt/stereotype/toolbar.h"
#include "qmt/style/style.h"
#include "qmt/style/stylecontroller.h"
#include "qmt/tasks/diagramscenecontroller.h"
#include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/minisplitter.h>
#include <coreplugin/actionmanager/commandbutton.h>
#include <utils/styledbar.h>
#include <utils/qtcassert.h>
#include <QAction>
#include <QDir>
#include <QEvent>
#include <QFileInfo>
#include <QFrame>
#include <QHBoxLayout>
#include <QLabel>
#include <QMap>
#include <QPainter>
#include <QPixmap>
#include <QScrollArea>
#include <QStackedWidget>
#include <QStyleFactory>
#include <QTimer>
#include <QToolBox>
#include <QUndoStack>
#include <QVBoxLayout>
namespace ModelEditor {
namespace Internal {
@@ -46,14 +99,34 @@ namespace Internal {
class ModelEditor::ModelEditorPrivate
{
public:
UiController *uiController = 0;
ActionHandler *actionHandler = 0;
ModelDocument *document = 0;
qmt::PropertiesView *propertiesView = 0;
Core::MiniSplitter *rightSplitter = 0;
QWidget *leftGroup = 0;
QHBoxLayout *leftGroupLayout = 0;
QToolBox *leftToolBox = 0;
QStackedWidget *diagramStack = 0;
EditorDiagramView *diagramView = 0;
QLabel *noDiagramLabel = 0;
DiagramsViewManager *diagramsViewManager = 0;
Core::MiniSplitter *rightHorizSplitter = 0;
qmt::ModelTreeView *modelTreeView = 0;
qmt::TreeModelManager *modelTreeViewServant = 0;
QScrollArea *propertiesScrollArea = 0;
QWidget *propertiesGroupWidget = 0;
QWidget *toolbar = 0;
SelectedArea selectedArea = SelectedArea::Nothing;
};
ModelEditor::ModelEditor(UiController *uiController, ActionHandler *actionHandler, QWidget *parent)
: AbstractEditor(uiController, actionHandler, parent),
: IEditor(parent),
d(new ModelEditorPrivate)
{
setContext(Core::Context(Constants::MODEL_EDITOR_ID));
d->uiController = uiController;
d->actionHandler = actionHandler;
d->document = new ModelDocument(this);
connect(d->document, &ModelDocument::contentSet, this, &ModelEditor::onContentSet);
init(parent);
@@ -61,6 +134,8 @@ ModelEditor::ModelEditor(UiController *uiController, ActionHandler *actionHandle
ModelEditor::~ModelEditor()
{
closeCurrentDiagram();
delete d->toolbar;
delete d;
}
@@ -69,13 +144,854 @@ Core::IDocument *ModelEditor::document()
return d->document;
}
QWidget *ModelEditor::toolBar()
{
return d->toolbar;
}
void ModelEditor::init(QWidget *parent)
{
// create and configure properties view
d->propertiesView = new qmt::PropertiesView(this);
// create and configure editor ui
d->rightSplitter = new Core::MiniSplitter(parent);
connect(d->rightSplitter, &QSplitter::splitterMoved,
this, &ModelEditor::onRightSplitterMoved);
connect(d->uiController, &UiController::rightSplitterChanged,
this, &ModelEditor::onRightSplitterChanged);
d->leftGroup = new QWidget(d->rightSplitter);
d->leftGroupLayout = new QHBoxLayout(d->leftGroup);
d->leftGroupLayout->setContentsMargins(0, 0, 0, 0);
d->leftGroupLayout->setSpacing(0);
d->leftToolBox = new QToolBox(d->leftGroup);
// Windows style does not truncate the tab label to a very small width (GTK+ does)
static QStyle *windowsStyle = QStyleFactory().create(QStringLiteral("Windows"));
if (windowsStyle)
d->leftToolBox->setStyle(windowsStyle);
// TODO improve this (and the diagram colors) for use with dark theme
d->leftToolBox->setStyleSheet(
QLatin1String("QToolBox::tab {"
" margin-left: 2px;"
" background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
" stop: 0 #E1E1E1, stop: 0.4 #DDDDDD,"
" stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3);"
" color: #606060;"
"}"
""
"QToolBox::tab:selected {"
" font: italic;"
" color: black;"
"}"));
QFont font = d->leftToolBox->font();
font.setPointSizeF(font.pointSizeF() * 0.8);
d->leftToolBox->setFont(font);
d->diagramStack = new QStackedWidget(d->leftGroup);
d->diagramView = new EditorDiagramView(d->diagramStack);
d->diagramStack->addWidget(d->diagramView);
d->noDiagramLabel = new QLabel(d->diagramStack);
const QString placeholderText = tr("<html><body style=\"color:#909090; font-size:14px\">"
"<div align='center'>"
"<div style=\"font-size:20px\">Open a diagram</div>"
"<table><tr><td>"
"<hr/>"
"<div style=\"margin-top: 5px\">&bull; Double-click on diagram in model tree</div>"
"<div style=\"margin-top: 5px\">&bull; Select \"Open Diagram\" from package's context menu in model tree</div>"
"</td></tr></table>"
"</div>"
"</body></html>");
d->noDiagramLabel->setText(placeholderText);
d->diagramStack->addWidget(d->noDiagramLabel);
d->diagramStack->setCurrentWidget(d->noDiagramLabel);
d->leftGroupLayout->addWidget(d->leftToolBox, 0);
auto frame = new QFrame(d->leftGroup);
frame->setFrameShape(QFrame::VLine);
d->leftGroupLayout->addWidget(frame, 0);
d->leftGroupLayout->addWidget(d->diagramStack, 1);
d->rightHorizSplitter = new Core::MiniSplitter(d->rightSplitter);
d->rightHorizSplitter->setOrientation(Qt::Vertical);
connect(d->rightHorizSplitter, &QSplitter::splitterMoved,
this, &ModelEditor::onRightHorizSplitterMoved);
connect(d->uiController, &UiController::rightHorizSplitterChanged,
this, &ModelEditor::onRightHorizSplitterChanged);
d->modelTreeView = new qmt::ModelTreeView(d->rightHorizSplitter);
d->modelTreeView->setFrameShape(QFrame::NoFrame);
d->modelTreeViewServant = new qmt::TreeModelManager(this);
d->modelTreeViewServant->setModelTreeView(d->modelTreeView);
d->propertiesScrollArea = new QScrollArea(d->rightHorizSplitter);
d->propertiesScrollArea->setFrameShape(QFrame::NoFrame);
d->propertiesScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
d->propertiesScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
d->propertiesScrollArea->setWidgetResizable(true);
d->rightHorizSplitter->insertWidget(0, d->modelTreeView);
d->rightHorizSplitter->insertWidget(1, d->propertiesScrollArea);
d->rightHorizSplitter->setStretchFactor(0, 2); // magic stretch factors for equal sizing
d->rightHorizSplitter->setStretchFactor(1, 3);
d->rightSplitter->insertWidget(0, d->leftGroup);
d->rightSplitter->insertWidget(1, d->rightHorizSplitter);
d->rightSplitter->setStretchFactor(0, 1);
d->rightSplitter->setStretchFactor(1, 0);
setWidget(d->rightSplitter);
// restore splitter sizes after any stretch factor has been set as fallback
if (d->uiController->hasRightSplitterState())
d->rightSplitter->restoreState(d->uiController->rightSplitterState());
if (d->uiController->hasRightHorizSplitterState())
d->rightHorizSplitter->restoreState(d->uiController->rightHorizSplitterState());
// create and configure toolbar
d->toolbar = new QWidget();
auto toolbarLayout = new QHBoxLayout(d->toolbar);
toolbarLayout->setContentsMargins(0, 0, 0, 0);
toolbarLayout->setSpacing(0);
toolbarLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
toolbarLayout->addWidget(createToolbarCommandButton(
Constants::ACTION_ADD_PACKAGE, [this]() { onAddPackage(); },
QIcon(QStringLiteral(":/modelinglib/48x48/package.png")),
tr("Add Package"), d->toolbar));
toolbarLayout->addWidget(createToolbarCommandButton(
Constants::ACTION_ADD_COMPONENT, [this]() { onAddComponent(); },
QIcon(QStringLiteral(":/modelinglib/48x48/component.png")),
tr("Add Component"), d->toolbar));
toolbarLayout->addWidget(createToolbarCommandButton(
Constants::ACTION_ADD_CLASS, [this]() { onAddClass(); },
QIcon(QStringLiteral(":/modelinglib/48x48/class.png")),
tr("Add Class"), d->toolbar));
toolbarLayout->addWidget(createToolbarCommandButton(
Constants::ACTION_ADD_CANVAS_DIAGRAM, [this]() { onAddCanvasDiagram(); },
QIcon(QStringLiteral(":/modelinglib/48x48/canvas-diagram.png")),
tr("Add Canvas Diagram"), d->toolbar));
toolbarLayout->addItem(new QSpacerItem(20, 0));
}
void ModelEditor::initDocument()
{
initToolbars();
ExtDocumentController *documentController = d->document->documentController();
d->diagramView->setPxNodeController(documentController->pxNodeController());
QTC_CHECK(!d->diagramsViewManager);
d->diagramsViewManager = new DiagramsViewManager(this);
//connect(diagramsViewManager, &DiagramsViewManager::someDiagramOpened,
// documentController->getDiagramsManager(), &qmt::DiagramsManager::someDiagramOpened);
connect(d->diagramsViewManager, &DiagramsViewManager::openNewDiagram,
this, &ModelEditor::showDiagram);
connect(d->diagramsViewManager, &DiagramsViewManager::closeOpenDiagram,
this, &ModelEditor::closeDiagram);
connect(d->diagramsViewManager, &DiagramsViewManager::closeAllOpenDiagrams,
this, &ModelEditor::closeAllDiagrams);
documentController->getDiagramsManager()->setDiagramsView(d->diagramsViewManager);
d->propertiesView->setDiagramController(documentController->getDiagramController());
d->propertiesView->setModelController(documentController->getModelController());
d->propertiesView->setStereotypeController(documentController->getStereotypeController());
d->propertiesView->setStyleController(documentController->getStyleController());
d->modelTreeView->setTreeModel(documentController->getSortedTreeModel());
d->modelTreeView->setElementTasks(documentController->elementTasks());
d->modelTreeViewServant->setTreeModel(documentController->getTreeModel());
connect(documentController, &qmt::DocumentController::diagramClipboardChanged,
this, &ModelEditor::onDiagramClipboardChanged, Qt::QueuedConnection);
connect(documentController->getUndoController()->getUndoStack(), &QUndoStack::canUndoChanged,
this, &ModelEditor::onCanUndoChanged, Qt::QueuedConnection);
connect(documentController->getUndoController()->getUndoStack(), &QUndoStack::canRedoChanged,
this, &ModelEditor::onCanRedoChanged, Qt::QueuedConnection);
connect(documentController->getTreeModel(), &qmt::TreeModel::modelReset,
this, &ModelEditor::onTreeModelReset, Qt::QueuedConnection);
connect(documentController->getDiagramController(), &qmt::DiagramController::modified,
this, &ModelEditor::onDiagramModified, Qt::QueuedConnection);
connect(documentController->getDiagramsManager(), &qmt::DiagramsManager::diagramSelectionChanged,
this, &ModelEditor::onDiagramSelectionChanged, Qt::QueuedConnection);
connect(documentController->getDiagramsManager(), &qmt::DiagramsManager::diagramActivated,
this, &ModelEditor::onDiagramActivated, Qt::QueuedConnection);
connect(documentController->getDiagramSceneController(), &qmt::DiagramSceneController::newElementCreated,
this, &ModelEditor::onNewElementCreated, Qt::QueuedConnection);
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
this, &ModelEditor::onCurrentEditorChanged, Qt::QueuedConnection);
connect(d->modelTreeView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &ModelEditor::onTreeViewSelectionChanged, Qt::QueuedConnection);
connect(d->modelTreeView, &qmt::ModelTreeView::treeViewActivated,
this, &ModelEditor::onTreeViewActivated, Qt::QueuedConnection);
connect(d->modelTreeView, &QAbstractItemView::doubleClicked,
this, &ModelEditor::onTreeViewDoubleClicked, Qt::QueuedConnection);
updateSelectedArea(SelectedArea::Nothing);
}
qmt::MDiagram *ModelEditor::currentDiagram() const
{
if (!d->diagramView->getDiagramSceneModel())
return 0;
return d->diagramView->getDiagramSceneModel()->getDiagram();
}
void ModelEditor::showDiagram(qmt::MDiagram *diagram)
{
closeCurrentDiagram();
if (diagram) {
qmt::DiagramSceneModel *diagramSceneModel = d->document->documentController()->getDiagramsManager()->bindDiagramSceneModel(diagram);
d->diagramView->setDiagramSceneModel(diagramSceneModel);
d->diagramStack->setCurrentWidget(d->diagramView);
}
}
void ModelEditor::undo()
{
d->document->documentController()->getUndoController()->getUndoStack()->undo();
}
void ModelEditor::redo()
{
d->document->documentController()->getUndoController()->getUndoStack()->redo();
}
void ModelEditor::cut()
{
ExtDocumentController *documentController = d->document->documentController();
switch (d->selectedArea) {
case SelectedArea::Nothing:
break;
case SelectedArea::Diagram:
documentController->cutFromDiagram(currentDiagram());
break;
case SelectedArea::TreeView:
documentController->cutFromModel(d->modelTreeViewServant->getSelectedObjects());
break;
}
}
void ModelEditor::copy()
{
ExtDocumentController *documentController = d->document->documentController();
switch (d->selectedArea) {
case SelectedArea::Nothing:
break;
case SelectedArea::Diagram:
if (documentController->hasDiagramSelection(currentDiagram()))
documentController->copyFromDiagram(currentDiagram());
else
documentController->copyDiagram(currentDiagram());
break;
case SelectedArea::TreeView:
documentController->copyFromModel(d->modelTreeViewServant->getSelectedObjects());
break;
}
}
void ModelEditor::paste()
{
ExtDocumentController *documentController = d->document->documentController();
switch (d->selectedArea) {
case SelectedArea::Nothing:
break;
case SelectedArea::Diagram:
documentController->pasteIntoDiagram(currentDiagram());
break;
case SelectedArea::TreeView:
documentController->pasteIntoModel(d->modelTreeViewServant->getSelectedObject());
break;
}
}
void ModelEditor::removeSelectedElements()
{
switch (d->selectedArea) {
case SelectedArea::Nothing:
break;
case SelectedArea::Diagram:
d->document->documentController()->removeFromDiagram(currentDiagram());
break;
case SelectedArea::TreeView:
break;
}
}
void ModelEditor::deleteSelectedElements()
{
ExtDocumentController *documentController = d->document->documentController();
switch (d->selectedArea) {
case SelectedArea::Nothing:
break;
case SelectedArea::Diagram:
documentController->deleteFromDiagram(currentDiagram());
break;
case SelectedArea::TreeView:
documentController->deleteFromModel(d->modelTreeViewServant->getSelectedObjects());
break;
}
}
void ModelEditor::selectAll()
{
d->document->documentController()->selectAllOnDiagram(currentDiagram());
}
void ModelEditor::editProperties()
{
d->propertiesView->editSelectedElement();
}
qmt::MPackage *ModelEditor::guessSelectedPackage() const
{
qmt::MPackage *package = 0;
switch (d->selectedArea) {
case SelectedArea::Nothing:
package = d->modelTreeViewServant->getSelectedPackage();
break;
case SelectedArea::Diagram:
{
qmt::DocumentController *documentController = d->document->documentController();
qmt::DiagramsManager *diagramsManager = documentController->getDiagramsManager();
qmt::MDiagram *diagram = currentDiagram();
qmt::DSelection selection = diagramsManager->getDiagramSceneModel(diagram)->getSelectedElements();
if (selection.getIndices().size() == 1) {
qmt::DPackage *diagramElement = documentController->getDiagramController()->findElement<qmt::DPackage>(selection.getIndices().at(0).getElementKey(), diagram);
if (diagramElement)
package = documentController->getModelController()->findObject<qmt::MPackage>(diagramElement->getModelUid());
}
break;
}
case SelectedArea::TreeView:
package = d->modelTreeViewServant->getSelectedPackage();
break;
}
return package;
}
void ModelEditor::updateSelectedArea(SelectedArea selectedArea)
{
d->selectedArea = selectedArea;
qmt::DocumentController *documentController = d->document->documentController();
bool canCutCopyDelete = false;
bool canRemove = false;
bool canPaste = false;
bool canSelectAll = false;
bool canCopyDiagram = false;
QList<qmt::MElement *> propertiesModelElements;
QList<qmt::DElement *> propertiesDiagramElements;
qmt::MDiagram *propertiesDiagram = 0;
qmt::MDiagram *activeDiagram = currentDiagram();
switch (d->selectedArea) {
case SelectedArea::Nothing:
canSelectAll = activeDiagram && !activeDiagram->getDiagramElements().isEmpty();
break;
case SelectedArea::Diagram:
{
if (activeDiagram) {
bool hasSelection = documentController->getDiagramsManager()->getDiagramSceneModel(activeDiagram)->hasSelection();
canCutCopyDelete = hasSelection;
canRemove = hasSelection;
canPaste = !documentController->isDiagramClipboardEmpty();
canSelectAll = !activeDiagram->getDiagramElements().isEmpty();
canCopyDiagram = !hasSelection;
if (hasSelection) {
qmt::DSelection selection = documentController->getDiagramsManager()->getDiagramSceneModel(activeDiagram)->getSelectedElements();
if (!selection.isEmpty()) {
foreach (qmt::DSelection::Index index, selection.getIndices()) {
qmt::DElement *diagramElement = documentController->getDiagramController()->findElement(index.getElementKey(), activeDiagram);
if (diagramElement)
propertiesDiagramElements.append(diagramElement);
}
if (!propertiesDiagramElements.isEmpty())
propertiesDiagram = activeDiagram;
}
}
}
break;
}
case SelectedArea::TreeView:
{
bool hasSelection = !d->modelTreeViewServant->getSelectedObjects().isEmpty();
bool hasSingleSelection = d->modelTreeViewServant->getSelectedObjects().getIndices().size() == 1;
canCutCopyDelete = hasSelection && !d->modelTreeViewServant->isRootPackageSelected();
canPaste = hasSingleSelection && !documentController->isModelClipboardEmpty();
canSelectAll = activeDiagram && !activeDiagram->getDiagramElements().isEmpty();
QModelIndexList indexes = d->modelTreeView->getSelectedSourceModelIndexes();
if (!indexes.isEmpty()) {
foreach (const QModelIndex &propertiesIndex, indexes) {
if (propertiesIndex.isValid()) {
qmt::MElement *modelElement = documentController->getTreeModel()->getElement(propertiesIndex);
if (modelElement)
propertiesModelElements.append(modelElement);
}
}
}
break;
}
}
d->actionHandler->cutAction()->setEnabled(canCutCopyDelete);
d->actionHandler->copyAction()->setEnabled(canCutCopyDelete || canCopyDiagram);
d->actionHandler->pasteAction()->setEnabled(canPaste);
d->actionHandler->removeAction()->setEnabled(canRemove);
d->actionHandler->deleteAction()->setEnabled(canCutCopyDelete);
d->actionHandler->selectAllAction()->setEnabled(canSelectAll);
if (!propertiesModelElements.isEmpty())
showProperties(propertiesModelElements);
else if (!propertiesDiagramElements.isEmpty())
showProperties(propertiesDiagram, propertiesDiagramElements);
else
clearProperties();
}
void ModelEditor::showProperties(const QList<qmt::MElement *> &modelElements)
{
if (modelElements != d->propertiesView->getSelectedModelElements()) {
clearProperties();
if (modelElements.size() > 0) {
d->propertiesView->setSelectedModelElements(modelElements);
d->propertiesGroupWidget = d->propertiesView->getWidget();
d->propertiesScrollArea->setWidget(d->propertiesGroupWidget);
}
}
}
void ModelEditor::showProperties(qmt::MDiagram *diagram,
const QList<qmt::DElement *> &diagramElements)
{
if (diagram != d->propertiesView->getSelectedDiagram()
|| diagramElements != d->propertiesView->getSelectedDiagramElements())
{
clearProperties();
if (diagram && diagramElements.size() > 0) {
d->propertiesView->setSelectedDiagramElements(diagramElements, diagram);
d->propertiesGroupWidget = d->propertiesView->getWidget();
d->propertiesScrollArea->setWidget(d->propertiesGroupWidget);
}
}
}
void ModelEditor::clearProperties()
{
d->propertiesView->clearSelection();
if (d->propertiesGroupWidget) {
QWidget *scrollWidget = d->propertiesScrollArea->takeWidget();
Q_UNUSED(scrollWidget); // avoid warning in release mode
QTC_CHECK(scrollWidget == d->propertiesGroupWidget);
d->propertiesGroupWidget->deleteLater();
d->propertiesGroupWidget = 0;
}
}
void ModelEditor::expandModelTreeToDepth(int depth)
{
d->modelTreeView->expandToDepth(depth);
}
QWidget *ModelEditor::createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
const QIcon &icon, const QString &toolTipBase,
QWidget *parent)
{
auto button = new Core::CommandButton(id, parent);
button->setIcon(icon);
button->setToolTipBase(toolTipBase);
connect(button, &Core::CommandButton::clicked, this, slot);
return button;
}
/*!
Tries to change the \a button icon to the icon specified by \a name
from the current theme. Returns \c true if icon is updated, \c false
otherwise.
*/
bool ModelEditor::updateButtonIconByTheme(QAbstractButton *button, const QString &name)
{
QTC_ASSERT(button, return false);
QTC_ASSERT(!name.isEmpty(), return false);
if (QIcon::hasThemeIcon(name)) {
button->setIcon(QIcon::fromTheme(name));
return true;
}
return false;
}
void ModelEditor::onAddPackage()
{
ExtDocumentController *documentController = d->document->documentController();
qmt::MPackage *package = documentController->createNewPackage(d->modelTreeViewServant->getSelectedPackage());
d->modelTreeView->selectFromSourceModelIndex(documentController->getTreeModel()->getIndex(package));
QTimer::singleShot(0, this, [this]() { onEditSelectedElement(); });
}
void ModelEditor::onAddComponent()
{
ExtDocumentController *documentController = d->document->documentController();
qmt::MComponent *component = documentController->createNewComponent(d->modelTreeViewServant->getSelectedPackage());
d->modelTreeView->selectFromSourceModelIndex(documentController->getTreeModel()->getIndex(component));
QTimer::singleShot(0, this, [this]() { onEditSelectedElement(); });
}
void ModelEditor::onAddClass()
{
ExtDocumentController *documentController = d->document->documentController();
qmt::MClass *klass = documentController->createNewClass(d->modelTreeViewServant->getSelectedPackage());
d->modelTreeView->selectFromSourceModelIndex(documentController->getTreeModel()->getIndex(klass));
QTimer::singleShot(0, this, [this]() { onEditSelectedElement(); });
}
void ModelEditor::onAddCanvasDiagram()
{
ExtDocumentController *documentController = d->document->documentController();
qmt::MDiagram *diagram = documentController->createNewCanvasDiagram(d->modelTreeViewServant->getSelectedPackage());
d->modelTreeView->selectFromSourceModelIndex(documentController->getTreeModel()->getIndex(diagram));
QTimer::singleShot(0, this, [this]() { onEditSelectedElement(); });
}
void ModelEditor::onCurrentEditorChanged(Core::IEditor *editor)
{
if (this == editor) {
QUndoStack *undo_stack = d->document->documentController()->getUndoController()->getUndoStack();
d->actionHandler->undoAction()->setDisabled(!undo_stack->canUndo());
d->actionHandler->redoAction()->setDisabled(!undo_stack->canRedo());
updateSelectedArea(SelectedArea::Nothing);
}
}
void ModelEditor::onCanUndoChanged(bool canUndo)
{
if (this == Core::EditorManager::currentEditor())
d->actionHandler->undoAction()->setEnabled(canUndo);
}
void ModelEditor::onCanRedoChanged(bool canRedo)
{
if (this == Core::EditorManager::currentEditor())
d->actionHandler->redoAction()->setEnabled(canRedo);
}
void ModelEditor::onTreeModelReset()
{
updateSelectedArea(SelectedArea::Nothing);
}
void ModelEditor::onTreeViewSelectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
Q_UNUSED(selected);
Q_UNUSED(deselected);
updateSelectedArea(SelectedArea::TreeView);
}
void ModelEditor::onTreeViewActivated()
{
updateSelectedArea(SelectedArea::TreeView);
}
void ModelEditor::onTreeViewDoubleClicked(const QModelIndex &index)
{
ExtDocumentController *documentController = d->document->documentController();
QModelIndex treeModelIndex = d->modelTreeView->mapToSourceModelIndex(index);
qmt::MElement *melement = documentController->getTreeModel()->getElement(treeModelIndex);
// double click on package is already used for toggeling tree
if (melement && !dynamic_cast<qmt::MPackage *>(melement))
documentController->elementTasks()->openElement(melement);
}
void ModelEditor::onCurrentDiagramChanged(const qmt::MDiagram *diagram)
{
if (diagram == currentDiagram()) {
updateSelectedArea(SelectedArea::Diagram);
} else {
updateSelectedArea(SelectedArea::Nothing);
}
}
void ModelEditor::onDiagramActivated(const qmt::MDiagram *diagram)
{
Q_UNUSED(diagram);
updateSelectedArea(SelectedArea::Diagram);
}
void ModelEditor::onDiagramClipboardChanged(bool isEmpty)
{
Q_UNUSED(isEmpty);
if (this == Core::EditorManager::currentEditor())
updateSelectedArea(d->selectedArea);
}
void ModelEditor::onNewElementCreated(qmt::DElement *element, qmt::MDiagram *diagram)
{
if (diagram == currentDiagram()) {
ExtDocumentController *documentController = d->document->documentController();
documentController->getDiagramsManager()->getDiagramSceneModel(diagram)->selectElement(element);
qmt::MElement *melement = documentController->getModelController()->findElement(element->getModelUid());
if (!(melement && melement->getFlags().testFlag(qmt::MElement::REVERSE_ENGINEERED)))
QTimer::singleShot(0, this, [this]() { onEditSelectedElement(); });
}
}
void ModelEditor::onDiagramSelectionChanged(const qmt::MDiagram *diagram)
{
if (diagram == currentDiagram())
updateSelectedArea(SelectedArea::Diagram);
}
void ModelEditor::onDiagramModified(const qmt::MDiagram *diagram)
{
Q_UNUSED(diagram);
updateSelectedArea(d->selectedArea);
}
void ModelEditor::onEditSelectedElement()
{
// TODO introduce similar method for selected elements in model tree
// currently this method is called on adding new elements in model tree
// but the method is a no-op in that case.
qmt::MDiagram *diagram = d->propertiesView->getSelectedDiagram();
QList<qmt::DElement *> elements = d->propertiesView->getSelectedDiagramElements();
if (diagram && !elements.isEmpty()) {
qmt::DElement *element = elements.at(0);
if (element) {
qmt::DiagramSceneModel *diagramSceneModel = d->document->documentController()->getDiagramsManager()->getDiagramSceneModel(diagram);
if (diagramSceneModel->isElementEditable(element)) {
diagramSceneModel->editElement(element);
return;
}
}
d->propertiesView->editSelectedElement();
}
}
void ModelEditor::onRightSplitterMoved(int pos, int index)
{
Q_UNUSED(pos);
Q_UNUSED(index);
d->uiController->onRightSplitterChanged(d->rightSplitter->saveState());
}
void ModelEditor::onRightSplitterChanged(const QByteArray &state)
{
d->rightSplitter->restoreState(state);
}
void ModelEditor::onRightHorizSplitterMoved(int pos, int index)
{
Q_UNUSED(pos);
Q_UNUSED(index);
d->uiController->onRightHorizSplitterChanged(d->rightHorizSplitter->saveState());
}
void ModelEditor::onRightHorizSplitterChanged(const QByteArray &state)
{
d->rightHorizSplitter->restoreState(state);
}
void ModelEditor::initToolbars()
{
QHash<QString, QWidget *> toolBars;
// TODO add toolbars sorted by prio
qmt::DocumentController *documentController = d->document->documentController();
qmt::StereotypeController *stereotypeController = documentController->getStereotypeController();
foreach (const qmt::Toolbar &toolbar, stereotypeController->getToolbars()) {
QWidget *toolBar = toolBars.value(toolbar.getId());
QLayout *toolBarLayout = 0;
if (!toolBar) {
toolBar = new QWidget(d->leftToolBox);
toolBarLayout = new QVBoxLayout(toolBar);
toolBarLayout->setContentsMargins(2, 2, 2, 2);
toolBarLayout->setSpacing(6);
d->leftToolBox->addItem(toolBar, toolbar.getId());
toolBars.insert(toolbar.getId(), toolBar);
} else {
toolBarLayout = toolBar->layout();
QTC_ASSERT(toolBarLayout, continue);
}
foreach (const qmt::Toolbar::Tool &tool, toolbar.getTools()) {
switch (tool._tool_type) {
case qmt::Toolbar::TOOLTYPE_TOOL:
{
QString iconPath;
qmt::StereotypeIcon::Element stereotypeIconElement = qmt::StereotypeIcon::ELEMENT_ANY;
qmt::StyleEngine::ElementType styleEngineElementType = qmt::StyleEngine::TYPE_OTHER;
if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_PACKAGE)) {
iconPath = QStringLiteral(":/modelinglib/48x48/package.png");
stereotypeIconElement = qmt::StereotypeIcon::ELEMENT_PACKAGE;
styleEngineElementType = qmt::StyleEngine::TYPE_PACKAGE;
} else if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_COMPONENT)) {
iconPath = QStringLiteral(":/modelinglib/48x48/component.png");
stereotypeIconElement = qmt::StereotypeIcon::ELEMENT_COMPONENT;
styleEngineElementType = qmt::StyleEngine::TYPE_COMPONENT;
} else if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_CLASS)) {
iconPath = QStringLiteral(":/modelinglib/48x48/class.png");
stereotypeIconElement = qmt::StereotypeIcon::ELEMENT_CLASS;
styleEngineElementType = qmt::StyleEngine::TYPE_CLASS;
} else if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_ITEM)) {
iconPath = QStringLiteral(":/modelinglib/48x48/item.png");
stereotypeIconElement = qmt::StereotypeIcon::ELEMENT_ITEM;
styleEngineElementType = qmt::StyleEngine::TYPE_ITEM;
} else if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_ANNOTATION)) {
iconPath = QStringLiteral(":/modelinglib/48x48/annotation.png");
styleEngineElementType = qmt::StyleEngine::TYPE_ANNOTATION;
} else if (tool._element_type == QLatin1String(qmt::ELEMENT_TYPE_BOUNDARY)) {
iconPath = QStringLiteral(":/modelinglib/48x48/boundary.png");
styleEngineElementType = qmt::StyleEngine::TYPE_BOUNDARY;
}
QIcon icon;
if (!tool._stereotype.isEmpty() && stereotypeIconElement != qmt::StereotypeIcon::ELEMENT_ANY) {
const qmt::Style *style = documentController->getStyleController()->adaptStyle(styleEngineElementType);
icon = stereotypeController->createIcon(
stereotypeIconElement, QStringList() << tool._stereotype,
QString(), style, QSize(48, 48), QMarginsF(3.0, 2.0, 3.0, 4.0));
}
if (icon.isNull())
icon = QIcon(iconPath);
if (!icon.isNull()) {
toolBarLayout->addWidget(new DragTool(icon, tool._name, tool._element_type,
tool._stereotype, toolBar));
}
break;
}
case qmt::Toolbar::TOOLTYPE_SEPARATOR:
{
auto horizLine1 = new QFrame(d->leftToolBox);
horizLine1->setFrameShape(QFrame::HLine);
toolBarLayout->addWidget(horizLine1);
break;
}
}
}
}
// fallback if no toolbar was defined
if (!toolBars.isEmpty()) {
QString generalId = QStringLiteral("General");
auto toolBar = new QWidget(d->leftToolBox);
auto toolBarLayout = new QVBoxLayout(toolBar);
toolBarLayout->setContentsMargins(2, 2, 2, 2);
toolBarLayout->setSpacing(6);
d->leftToolBox->insertItem(0, toolBar, generalId);
toolBars.insert(generalId, toolBar);
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/package.png")),
tr("Package"), QLatin1String(qmt::ELEMENT_TYPE_PACKAGE),
QString(), toolBar));
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/component.png")),
tr("Component"), QLatin1String(qmt::ELEMENT_TYPE_COMPONENT),
QString(), toolBar));
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/class.png")),
tr("Class"), QLatin1String(qmt::ELEMENT_TYPE_CLASS),
QString(), toolBar));
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/item.png")),
tr("Item"), QLatin1String(qmt::ELEMENT_TYPE_ITEM),
QString(), toolBar));
auto horizLine1 = new QFrame(d->leftToolBox);
horizLine1->setFrameShape(QFrame::HLine);
toolBarLayout->addWidget(horizLine1);
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/annotation.png")),
tr("Annotation"), QLatin1String(qmt::ELEMENT_TYPE_ANNOTATION),
QString(), toolBar));
toolBarLayout->addWidget(
new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/boundary.png")),
tr("Boundary"), QLatin1String(qmt::ELEMENT_TYPE_BOUNDARY),
QString(), toolBar));
}
// add stretch to all layouts and calculate width of tool bar
int maxWidth = 48;
foreach (QWidget *toolBar, toolBars) {
QTC_ASSERT(toolBar, continue);
auto layout = qobject_cast<QBoxLayout *>(toolBar->layout());
QTC_ASSERT(layout, continue);
layout->addStretch(1);
toolBar->adjustSize();
if (maxWidth < toolBar->width())
maxWidth = toolBar->width();
}
d->leftToolBox->setFixedWidth(maxWidth);
d->leftToolBox->setCurrentIndex(0);
}
void ModelEditor::closeCurrentDiagram()
{
ExtDocumentController *documentController = d->document->documentController();
qmt::DiagramsManager *diagramsManager = documentController->getDiagramsManager();
qmt::DiagramSceneModel *sceneModel = d->diagramView->getDiagramSceneModel();
if (sceneModel) {
qmt::MDiagram *diagram = sceneModel->getDiagram();
if (diagram) {
d->diagramStack->setCurrentWidget(d->noDiagramLabel);
d->diagramView->setDiagramSceneModel(0);
diagramsManager->unbindDiagramSceneModel(diagram);
}
}
}
void ModelEditor::closeDiagram(const qmt::MDiagram *diagram)
{
ExtDocumentController *documentController = d->document->documentController();
qmt::DiagramsManager *diagramsManager = documentController->getDiagramsManager();
qmt::DiagramSceneModel *sceneModel = d->diagramView->getDiagramSceneModel();
if (sceneModel && diagram == sceneModel->getDiagram()) {
d->diagramStack->setCurrentWidget(d->noDiagramLabel);
d->diagramView->setDiagramSceneModel(0);
diagramsManager->unbindDiagramSceneModel(diagram);
}
}
void ModelEditor::closeAllDiagrams()
{
closeCurrentDiagram();
}
void ModelEditor::onContentSet()
{
setDocument(d->document);
initDocument();
// open diagram
qmt::MDiagram *rootDiagram = d->document->documentController()->findOrCreateRootDiagram();
ExtDocumentController *documentController = d->document->documentController();
qmt::MDiagram *rootDiagram = documentController->findOrCreateRootDiagram();
showDiagram(rootDiagram);
// select diagram in model tree view
QModelIndex modelIndex = documentController->getTreeModel()->getIndex(rootDiagram);
if (modelIndex.isValid())
d->modelTreeView->selectFromSourceModelIndex(modelIndex);
expandModelTreeToDepth(0);
}

View File

@@ -31,13 +31,39 @@
#ifndef MODELDIAGRAMEDITOR_H
#define MODELDIAGRAMEDITOR_H
#include "abstracteditor.h"
#include <coreplugin/editormanager/ieditor.h>
#include <QAbstractButton>
#include <functional>
QT_BEGIN_NAMESPACE
class QItemSelection;
QT_END_NAMESPACE
namespace qmt {
class MElement;
class MPackage;
class MDiagram;
class DElement;
class DocumentController;
}
namespace ModelEditor {
namespace Internal {
class UiController;
class ActionHandler;
class DiagramsViewManager;
enum class SelectedArea {
Nothing,
Diagram,
TreeView
};
class ModelEditor :
public AbstractEditor
public Core::IEditor
{
Q_OBJECT
class ModelEditorPrivate;
@@ -48,9 +74,66 @@ public:
~ModelEditor();
Core::IDocument *document() override;
QWidget *toolBar() override;
private slots:
void onContentSet();
qmt::MDiagram *currentDiagram() const;
void showDiagram(qmt::MDiagram *diagram);
void undo();
void redo();
void cut();
void copy();
void paste();
void removeSelectedElements();
void deleteSelectedElements();
void selectAll();
void editProperties();
qmt::MPackage *guessSelectedPackage() const;
private:
void init(QWidget *parent);
void initDocument();
void updateSelectedArea(SelectedArea selectedArea);
void showProperties(const QList<qmt::MElement *> &modelElements);
void showProperties(qmt::MDiagram *diagram, const QList<qmt::DElement *> &diagramElements);
void clearProperties();
void expandModelTreeToDepth(int depth);
QWidget *createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
const QIcon &icon,
const QString &toolTipBase, QWidget *parent);
bool updateButtonIconByTheme(QAbstractButton *button, const QString &name);
void onAddPackage();
void onAddComponent();
void onAddClass();
void onAddCanvasDiagram();
void onCurrentEditorChanged(Core::IEditor *editor);
void onCanUndoChanged(bool canUndo);
void onCanRedoChanged(bool canRedo);
void onTreeModelReset();
void onTreeViewSelectionChanged(const QItemSelection &selected,
const QItemSelection &deselected);
void onTreeViewActivated();
void onTreeViewDoubleClicked(const QModelIndex &index);
void onCurrentDiagramChanged(const qmt::MDiagram *diagram);
void onDiagramActivated(const qmt::MDiagram *diagram);
void onDiagramClipboardChanged(bool isEmpty);
void onNewElementCreated(qmt::DElement *element, qmt::MDiagram *diagram);
void onDiagramSelectionChanged(const qmt::MDiagram *diagram);
void onDiagramModified(const qmt::MDiagram *diagram);
Q_SLOT void onEditSelectedElement();
void onRightSplitterMoved(int pos, int index);
void onRightSplitterChanged(const QByteArray &state);
void onRightHorizSplitterMoved(int pos, int index);
void onRightHorizSplitterChanged(const QByteArray &state);
void initToolbars();
void closeCurrentDiagram();
void closeDiagram(const qmt::MDiagram *diagram);
void closeAllDiagrams();
Q_SLOT void onContentSet();
private:
ModelEditorPrivate *d;

View File

@@ -27,13 +27,9 @@ QT += core gui widgets
#}
SOURCES += \
abstracteditor.cpp \
actionhandler.cpp \
classviewcontroller.cpp \
componentviewcontroller.cpp \
diagramdocument.cpp \
diagrameditor.cpp \
diagrameditorfactory.cpp \
diagramsviewmanager.cpp \
dragtool.cpp \
editordiagramview.cpp \
@@ -53,15 +49,10 @@ SOURCES += \
uicontroller.cpp
HEADERS += \
abstracteditor.h \
actionhandler.h \
classviewcontroller.h \
componentviewcontroller.h \
diagramdocument.h \
diagrameditorfactory.h \
diagrameditor.h \
diagramsviewmanager.h \
documentinterface.h \
dragtool.h \
editordiagramview.h \
elementtasks.h \

View File

@@ -19,23 +19,14 @@ QtcPlugin {
]
files: [
"abstracteditor.cpp",
"abstracteditor.h",
"actionhandler.cpp",
"actionhandler.h",
"classviewcontroller.cpp",
"classviewcontroller.h",
"componentviewcontroller.cpp",
"componentviewcontroller.h",
"diagramdocument.cpp",
"diagramdocument.h",
"diagrameditor.cpp",
"diagrameditorfactory.cpp",
"diagrameditorfactory.h",
"diagrameditor.h",
"diagramsviewmanager.cpp",
"diagramsviewmanager.h",
"documentinterface.h",
"dragtool.cpp",
"dragtool.h",
"editordiagramview.cpp",

View File

@@ -37,9 +37,6 @@ namespace Constants {
const char MODEL_EDITOR_ID[] = "Editors.ModelEditor";
const char MODEL_EDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("OpenWith::Editors", "Model Editor");
const char DIAGRAM_EDITOR_ID[] = "Editors.DiagramEditor";
const char DIAGRAM_EDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("OpenWith::Editors", "Model Editor");
const char REMOVE_SELECTED_ELEMENTS[] = "ModelEditor.RemoveSelectedElements";
const char DELETE_SELECTED_ELEMENTS[] = "ModelEditor.DeleteSelectedElements";
const char ACTION_ADD_PACKAGE[] = "ModelEditor.Action.AddPackage";
@@ -52,15 +49,12 @@ const char ACTION_EXPLORER_OPEN_DIAGRAM[] = "ModelEditor.Action.Explorer.OpenDia
const char SHORTCUT_MODEL_EDITOR_EDIT_PROPERTIES[] =
"ModelEditor.ModelEditor.Shortcut.EditProperties";
const char SHORTCUT_DIAGRAM_EDITOR_EDIT_PROPERTIES[] =
"ModelEditor.DiagramEditor.Shortcut.EditProperties";
const char WIZARD_CATEGORY[] = "O.Model";
const char WIZARD_TR_CATEGORY[] = QT_TRANSLATE_NOOP("Modeling", "Modeling");
const char WIZARD_MODEL_ID[] = "SA.Model";
const char MIME_TYPE_MODEL[] = "text/vnd.qtcreator.model";
const char MIME_TYPE_DIAGRAM_REFERENCE[] = "text/vnd.qtcreator.diagram-reference";
// Settings entries
const char SETTINGS_GROUP[] = "ModelEditorPlugin";

View File

@@ -30,7 +30,6 @@
#include "modeleditor_plugin.h"
#include "diagrameditorfactory.h"
#include "modeleditorfactory.h"
#include "modelsmanager.h"
#include "settingscontroller.h"
@@ -72,7 +71,6 @@ public:
ModelsManager *modelsManager = 0;
UiController *uiController = 0;
ModelEditorFactory *modelFactory = 0;
DiagramEditorFactory *diagramFactory = 0;
SettingsController *settingsController = 0;
};
@@ -110,9 +108,6 @@ bool ModelEditorPlugin::initialize(const QStringList &arguments, QString *errorS
d->modelFactory = new ModelEditorFactory(d->uiController, this);
addAutoReleasedObject(d->modelFactory);
d->diagramFactory = new DiagramEditorFactory(d->uiController, this);
addAutoReleasedObject(d->diagramFactory);
d->settingsController = new SettingsController(this);
addAutoReleasedObject(d->settingsController);
@@ -130,7 +125,6 @@ void ModelEditorPlugin::extensionsInitialized()
// In the extensionsInitialized method, a plugin can be sure that all
// plugins that depend on it are completely initialized.
d->modelFactory->extensionsInitialized();
d->diagramFactory->extensionsInitialized();
d->settingsController->load(Core::ICore::settings());
}

View File

@@ -71,27 +71,18 @@ class ModelIndexer::QueuedFile
const ModelIndexer::QueuedFile &rhs);
public:
enum FileType {
UNKNOWN_FILE_TYPE,
MODEL_FILE,
// TODO remove type because it is not longer used
DIAGRAM_FILE
};
QueuedFile() = default;
QueuedFile(const QString &file, ProjectExplorer::Project *project)
: m_file(file),
m_project(project),
m_fileType(UNKNOWN_FILE_TYPE)
m_project(project)
{
}
QueuedFile(const QString &file, ProjectExplorer::Project *project, FileType fileType,
QueuedFile(const QString &file, ProjectExplorer::Project *project,
const QDateTime &lastModified)
: m_file(file),
m_project(project),
m_fileType(fileType),
m_lastModified(lastModified)
{
}
@@ -99,13 +90,11 @@ public:
bool isValid() const { return !m_file.isEmpty() && m_project; }
QString file() const { return m_file; }
ProjectExplorer::Project *project() const { return m_project; }
FileType fileType() const { return m_fileType; }
QDateTime lastModified() const { return m_lastModified; }
private:
QString m_file;
ProjectExplorer::Project *m_project = 0;
FileType m_fileType = UNKNOWN_FILE_TYPE;
QDateTime m_lastModified;
};
@@ -287,88 +276,46 @@ void ModelIndexer::IndexerThread::onFilesQueued()
ModelIndexer::QueuedFile queuedFile = m_indexer->d->filesQueue.takeFirst();
m_indexer->d->queuedFilesSet.remove(queuedFile);
qCDebug(logger) << "handle queued file " << queuedFile.file()
<< "from project " << queuedFile.project()->displayName();
<< "from project " << queuedFile.project()->displayName();
switch (queuedFile.fileType()) {
case ModelIndexer::QueuedFile::UNKNOWN_FILE_TYPE:
QTC_CHECK(false);
break;
case ModelIndexer::QueuedFile::MODEL_FILE:
{
bool scanModel = false;
IndexedModel *indexedModel = m_indexer->d->indexedModels.value(queuedFile.file());
if (!indexedModel) {
qCDebug(logger) << "create new indexed model";
indexedModel = new IndexedModel(queuedFile.file(),
queuedFile.lastModified());
indexedModel->addOwningProject(queuedFile.project());
m_indexer->d->indexedModels.insert(queuedFile.file(), indexedModel);
scanModel = true;
} else if (queuedFile.lastModified() > indexedModel->lastModified()) {
qCDebug(logger) << "update indexed model";
indexedModel->addOwningProject(queuedFile.project());
indexedModel->reset(queuedFile.lastModified());
scanModel = true;
}
if (scanModel) {
locker.unlock();
// load model file
qmt::ProjectSerializer projectSerializer;
qmt::Project project;
projectSerializer.load(queuedFile.file(), &project);
locker.relock();
indexedModel->setModelUid(project.getUid());
// add indexedModel to set of indexedModelsByUid
QSet<IndexedModel *> indexedModels = m_indexer->d->indexedModelsByUid.value(project.getUid());
indexedModels.insert(indexedModel);
m_indexer->d->indexedModelsByUid.insert(project.getUid(), indexedModels);
// collect all diagrams of model
DiagramsCollectorVisitor visitor(indexedModel);
project.getRootPackage()->accept(&visitor);
if (m_indexer->d->defaultModelFiles.contains(queuedFile)) {
m_indexer->d->defaultModelFiles.remove(queuedFile);
// check if model has a diagram which could be opened
qmt::FindRootDiagramVisitor diagramVisitor;
project.getRootPackage()->accept(&diagramVisitor);
if (diagramVisitor.getDiagram())
emit m_indexer->openDefaultModel(project.getUid());
}
}
break;
bool scanModel = false;
IndexedModel *indexedModel = m_indexer->d->indexedModels.value(queuedFile.file());
if (!indexedModel) {
qCDebug(logger) << "create new indexed model";
indexedModel = new IndexedModel(queuedFile.file(),
queuedFile.lastModified());
indexedModel->addOwningProject(queuedFile.project());
m_indexer->d->indexedModels.insert(queuedFile.file(), indexedModel);
scanModel = true;
} else if (queuedFile.lastModified() > indexedModel->lastModified()) {
qCDebug(logger) << "update indexed model";
indexedModel->addOwningProject(queuedFile.project());
indexedModel->reset(queuedFile.lastModified());
scanModel = true;
}
case ModelIndexer::QueuedFile::DIAGRAM_FILE:
{
bool scanFile = false;
IndexedDiagramReference *indexedDiagramReference = m_indexer->d->indexedDiagramReferences.value(queuedFile.file());
if (!indexedDiagramReference) {
qCDebug(logger) << "create new indexed diagram reference";
indexedDiagramReference = new IndexedDiagramReference(
queuedFile.file(), queuedFile.lastModified());
indexedDiagramReference->addOwningProject(queuedFile.project());
m_indexer->d->indexedDiagramReferences.insert(
queuedFile.file(), indexedDiagramReference);
scanFile = true;
} else if (queuedFile.lastModified() > indexedDiagramReference->lastModified()) {
qCDebug(logger) << "update indexed diagram reference";
indexedDiagramReference->addOwningProject(queuedFile.project());
indexedDiagramReference->reset(queuedFile.lastModified());
scanFile = true;
if (scanModel) {
locker.unlock();
// load model file
qmt::ProjectSerializer projectSerializer;
qmt::Project project;
projectSerializer.load(queuedFile.file(), &project);
locker.relock();
indexedModel->setModelUid(project.getUid());
// add indexedModel to set of indexedModelsByUid
QSet<IndexedModel *> indexedModels = m_indexer->d->indexedModelsByUid.value(project.getUid());
indexedModels.insert(indexedModel);
m_indexer->d->indexedModelsByUid.insert(project.getUid(), indexedModels);
// collect all diagrams of model
DiagramsCollectorVisitor visitor(indexedModel);
project.getRootPackage()->accept(&visitor);
if (m_indexer->d->defaultModelFiles.contains(queuedFile)) {
m_indexer->d->defaultModelFiles.remove(queuedFile);
// check if model has a diagram which could be opened
qmt::FindRootDiagramVisitor diagramVisitor;
project.getRootPackage()->accept(&diagramVisitor);
if (diagramVisitor.getDiagram())
emit m_indexer->openDefaultModel(project.getUid());
}
if (scanFile) {
locker.unlock();
// load diagram reference file
qmt::DiagramReferenceSerializer diagramReferenceSerializer;
qmt::DiagramReferenceSerializer::Reference reference = diagramReferenceSerializer.load(queuedFile.file());
locker.relock();
indexedDiagramReference->setModelUid(reference._model_uid);
indexedDiagramReference->setDiagramUid(reference._diagram_uid);
// add indexedDiagram_reference to set of indexedDiagramRefrerencesByUid
QSet<IndexedDiagramReference *> indexedDiagramReferences = m_indexer->d->indexedDiagramReferencesByDiagramUid.value(reference._diagram_uid);
indexedDiagramReferences.insert(indexedDiagramReference);
m_indexer->d->indexedDiagramReferencesByDiagramUid.insert(reference._diagram_uid, indexedDiagramReferences);
}
break;
}
}
}
}
@@ -449,13 +396,8 @@ void ModelIndexer::scanProject(ProjectExplorer::Project *project)
foreach (const QString &file, files) {
QFileInfo fileInfo(file);
Utils::MimeType mimeType = Utils::MimeDatabase().mimeTypeForFile(fileInfo);
QueuedFile::FileType fileType = QueuedFile::UNKNOWN_FILE_TYPE;
if (mimeType.name() == QLatin1String(Constants::MIME_TYPE_MODEL))
fileType = QueuedFile::MODEL_FILE;
else if (mimeType.name() == QLatin1String(Constants::MIME_TYPE_DIAGRAM_REFERENCE))
fileType = QueuedFile::DIAGRAM_FILE;
if (fileType != QueuedFile::UNKNOWN_FILE_TYPE) {
QueuedFile queuedFile(file, project, fileType, fileInfo.lastModified());
if (mimeType.name() == QLatin1String(Constants::MIME_TYPE_MODEL)) {
QueuedFile queuedFile(file, project, fileInfo.lastModified());
filesQueue.append(queuedFile);
filesSet.insert(queuedFile);
}
@@ -504,8 +446,7 @@ void ModelIndexer::scanProject(ProjectExplorer::Project *project)
// auto-open model file only if project is already configured
if (!defaultModelFile.isEmpty() && !project->targets().isEmpty()) {
d->defaultModelFiles.insert(QueuedFile(defaultModelFile, project,
QueuedFile::MODEL_FILE, QDateTime()));
d->defaultModelFiles.insert(QueuedFile(defaultModelFile, project, QDateTime()));
}
}
@@ -553,7 +494,7 @@ void ModelIndexer::removeModelFile(const QString &file, ProjectExplorer::Project
IndexedModel *indexedModel = d->indexedModels.value(file);
if (indexedModel && indexedModel->owningProjects().contains(project)) {
qCDebug(logger) << "remove model file " << file
<< " from project " << project->displayName();
<< " from project " << project->displayName();
indexedModel->removeOwningProject(project);
if (indexedModel->owningProjects().isEmpty()) {
qCDebug(logger) << "delete indexed model " << project->displayName();
@@ -581,7 +522,7 @@ void ModelIndexer::removeDiagramReferenceFile(const QString &file,
if (indexedDiagramReference) {
QTC_CHECK(indexedDiagramReference->owningProjects().contains(project));
qCDebug(logger) << "remove diagram reference file "
<< file << " from project " << project->displayName();
<< file << " from project " << project->displayName();
indexedDiagramReference->removeOwningProject(project);
if (indexedDiagramReference->owningProjects().isEmpty()) {
qCDebug(logger) << "delete indexed diagram reference from " << file;

View File

@@ -31,13 +31,12 @@
#include "modelsmanager.h"
#include "diagramsviewmanager.h"
#include "modeldocument.h"
#include "diagramdocument.h"
#include "diagrameditor.h"
#include "extdocumentcontroller.h"
#include "modeldocument.h"
#include "modeleditor_constants.h"
#include "modeleditor.h"
#include "modelindexer.h"
#include "pxnodecontroller.h"
#include "modeleditor_constants.h"
#include "qmt/config/configcontroller.h"
#include "qmt/diagram_scene/diagramscenemodel.h"
@@ -74,22 +73,15 @@ class ModelsManager::ManagedModel
{
public:
ManagedModel() = default;
ManagedModel(ExtDocumentController *m_documentController,
DiagramsViewManager *m_diagramsViewManager, ModelDocument *m_modelDocument);
ManagedModel(ExtDocumentController *m_documentController,ModelDocument *m_modelDocument);
int m_counter = 0;
ExtDocumentController *m_documentController = 0;
DiagramsViewManager *m_diagramsViewManager = 0;
ModelDocument *m_modelDocument = 0;
QList<DiagramDocument *> m_diagramDocuments;
};
ModelsManager::ManagedModel::ManagedModel(ExtDocumentController *documentController,
DiagramsViewManager *diagramsViewManager,
ModelDocument *modelDocument)
: m_counter(1),
m_documentController(documentController),
m_diagramsViewManager(diagramsViewManager),
: m_documentController(documentController),
m_modelDocument(modelDocument)
{
}
@@ -130,7 +122,7 @@ ModelsManager::ModelsManager(QObject *parent)
projecTreeContext);
folderContainer->addAction(cmd, Constants::EXPLORER_GROUP_MODELING);
connect(d->openDiagramContextMenuItem, &QAction::triggered,
this, &ModelsManager::onOpenDiagram);
this, &ModelsManager::onOpenDiagramFromProjectExplorer);
connect(ProjectExplorer::ProjectTree::instance(), &ProjectExplorer::ProjectTree::aboutToShowContextMenu,
this, &ModelsManager::onAboutToShowContextMenu);
}
@@ -138,22 +130,10 @@ ModelsManager::ModelsManager(QObject *parent)
ModelsManager::~ModelsManager()
{
QTC_CHECK(d->managedModels.isEmpty());
delete d->modelIndexer;
delete d;
}
bool ModelsManager::isDiagramOpen(const qmt::Uid &modelUid, const qmt::Uid &diagramUid) const
{
foreach (const ManagedModel &managedModel, d->managedModels) {
if (managedModel.m_documentController->getProjectController()->getProject()->getUid() == modelUid) {
foreach (const DiagramDocument *diagramDocument, managedModel.m_diagramDocuments) {
if (diagramDocument->diagramUid() == diagramUid)
return true;
}
}
}
return false;
}
ExtDocumentController *ModelsManager::createModel(ModelDocument *modelDocument)
{
auto documentController = new ExtDocumentController(this);
@@ -162,260 +142,31 @@ ExtDocumentController *ModelsManager::createModel(ModelDocument *modelDocument)
// TODO error output on reading definition files
documentController->getConfigController()->readStereotypeDefinitions(dir.path());
auto diagramsViewManager = new DiagramsViewManager(this);
connect(diagramsViewManager, &DiagramsViewManager::someDiagramOpened,
documentController->getDiagramsManager(), &qmt::DiagramsManager::someDiagramOpened);
connect(diagramsViewManager, &DiagramsViewManager::openEditor,
this, [=](const qmt::MDiagram *diagram) { this->onOpenEditor(documentController, diagram); });
connect(diagramsViewManager, &DiagramsViewManager::closeEditor,
this, [=](const qmt::MDiagram *diagram) { this->onCloseEditor(documentController, diagram); });
connect(diagramsViewManager, &DiagramsViewManager::diagramRenamed,
this, [=](const qmt::MDiagram *diagram) { this->onDiagramRenamed(documentController, diagram); });
d->managedModels.append(ManagedModel(documentController, diagramsViewManager, modelDocument));
d->managedModels.append(ManagedModel(documentController, modelDocument));
return documentController;
}
ExtDocumentController *ModelsManager::findModelByFileName(const QString &fileName,
ModelDocument *modelDocument)
{
Utils::FileName fileName1 = Utils::FileName::fromString(fileName);
for (int i = 0; i < d->managedModels.size(); ++i) {
ManagedModel *managedModel = &d->managedModels[i];
Utils::FileName fileName2 = Utils::FileName::fromString(managedModel->m_documentController->getProjectController()->getProject()->getFileName());
if (fileName1 == fileName2) {
if (managedModel->m_modelDocument != modelDocument) {
QTC_CHECK(!managedModel->m_modelDocument);
managedModel->m_modelDocument = modelDocument;
++managedModel->m_counter;
}
return managedModel->m_documentController;
}
}
return 0;
}
ExtDocumentController *ModelsManager::findOrLoadModel(const qmt::Uid &modelUid,
DiagramDocument *diagramDocument)
{
for (int i = 0; i < d->managedModels.size(); ++i) {
ManagedModel *managedModel = &d->managedModels[i];
if (managedModel->m_documentController->getProjectController()->getProject()->getUid() == modelUid) {
++managedModel->m_counter;
QTC_CHECK(!managedModel->m_diagramDocuments.contains(diagramDocument));
managedModel->m_diagramDocuments.append(diagramDocument);
return managedModel->m_documentController;
}
}
QString modelFile = d->modelIndexer->findModel(modelUid);
if (modelFile.isEmpty())
return 0;
qmt::DocumentController *documentController = createModel(0);
documentController->loadProject(modelFile);
for (int i = 0; i < d->managedModels.size(); ++i) {
ManagedModel *managedModel = &d->managedModels[i];
if (managedModel->m_documentController->getProjectController()->getProject()->getUid() == modelUid) {
// the counter was already set to 1 in createModel(0)
QTC_CHECK(managedModel->m_counter == 1);
QTC_CHECK(!managedModel->m_diagramDocuments.contains(diagramDocument));
managedModel->m_diagramDocuments.append(diagramDocument);
return managedModel->m_documentController;
}
}
QTC_ASSERT(false, return 0);
return 0;
}
void ModelsManager::release(ExtDocumentController *documentController, ModelDocument *modelDocument)
{
Q_UNUSED(modelDocument); // avoid warning in release mode
for (int i = 0; i < d->managedModels.size(); ++i) {
ManagedModel *managedModel = &d->managedModels[i];
if (managedModel->m_documentController == documentController) {
QTC_CHECK(managedModel->m_counter > 0);
--managedModel->m_counter;
QTC_CHECK(managedModel->m_modelDocument == modelDocument);
managedModel->m_modelDocument = 0;
if (!managedModel->m_counter) {
delete managedModel->m_diagramsViewManager;
delete managedModel->m_documentController;
d->managedModels.removeAt(i);
}
return;
}
}
QTC_CHECK(false);
}
void ModelsManager::release(ExtDocumentController *documentController,
DiagramDocument *diagramDocument)
void ModelsManager::releaseModel(ExtDocumentController *documentController)
{
for (int i = 0; i < d->managedModels.size(); ++i) {
ManagedModel *managedModel = &d->managedModels[i];
if (managedModel->m_documentController == documentController) {
QTC_CHECK(managedModel->m_counter > 0);
--managedModel->m_counter;
QTC_CHECK(managedModel->m_diagramDocuments.contains(diagramDocument));
managedModel->m_diagramDocuments.removeOne(diagramDocument);
if (!managedModel->m_counter) {
delete managedModel->m_diagramsViewManager;
delete managedModel->m_documentController;
d->managedModels.removeAt(i);
}
delete managedModel->m_documentController;
d->managedModels.removeAt(i);
return;
}
}
QTC_CHECK(false);
}
DiagramsViewManager *ModelsManager::findDiagramsViewManager(
ExtDocumentController *documentController) const
{
foreach (const ManagedModel &managedModel, d->managedModels) {
if (managedModel.m_documentController == documentController)
return managedModel.m_diagramsViewManager;
}
QTC_CHECK(false);
return 0;
}
ModelDocument *ModelsManager::findModelDocument(
ExtDocumentController *documentController) const
{
foreach (const ManagedModel &managedModel, d->managedModels) {
if (managedModel.m_documentController == documentController)
return managedModel.m_modelDocument;
}
QTC_CHECK(false);
return 0;
}
QList<ExtDocumentController *> ModelsManager::collectAllDocumentControllers() const
{
QList<ExtDocumentController *> documents;
foreach (const ManagedModel &managedModel, d->managedModels) {
QTC_ASSERT(managedModel.m_documentController, continue);
documents.append(managedModel.m_documentController);
}
return documents;
}
void ModelsManager::openDiagram(const qmt::Uid &modelUid, const qmt::Uid &diagramUid)
{
foreach (const ManagedModel &managedModel, d->managedModels) {
if (managedModel.m_documentController->getProjectController()->getProject()->getUid() == modelUid) {
qmt::MDiagram *diagram = managedModel.m_documentController->getModelController()->findObject<qmt::MDiagram>(diagramUid);
QTC_ASSERT(diagram, continue);
onOpenEditor(managedModel.m_documentController, diagram);
}
}
}
void ModelsManager::onOpenEditor(ExtDocumentController *documentController,
const qmt::MDiagram *diagram)
{
foreach (const ManagedModel &managedModel, d->managedModels) {
if (managedModel.m_documentController == documentController) {
if (managedModel.m_modelDocument
&& managedModel.m_modelDocument->diagramUid() == diagram->getUid()) {
Core::EditorManager::activateEditorForDocument(managedModel.m_modelDocument);
return;
} else {
foreach (DiagramDocument *diagramDocument, managedModel.m_diagramDocuments) {
if (diagramDocument->diagramUid() == diagram->getUid()) {
Core::EditorManager::activateEditorForDocument(diagramDocument);
return;
}
}
}
}
}
// if diagram is root diagram open model file editor
if (diagram == documentController->findRootDiagram()) {
foreach (const ManagedModel &managedModel, d->managedModels) {
if (managedModel.m_documentController == documentController) {
QTC_CHECK(!managedModel.m_modelDocument);
Core::EditorManager::openEditor(documentController->getProjectController()->getProject()->getFileName());
return;
}
}
QTC_CHECK(false);
}
// search diagram in model index and open that file
QString documentReferenceFile =
d->modelIndexer->findDiagram(
documentController->getProjectController()->getProject()->getUid(),
diagram->getUid());
if (!documentReferenceFile.isEmpty()) {
Core::EditorManager::openEditor(documentReferenceFile);
} else {
// open new temporary diagram editor
qmt::DiagramReferenceSerializer serializer;
QByteArray contents = serializer.save(
documentController->getProjectController()->getProject(), diagram);
Core::IEditor *editor = Core::EditorManager::openEditorWithContents(
Core::Id(Constants::DIAGRAM_EDITOR_ID), 0, contents);
// bring editor to front
Core::EditorManager::activateEditor(editor);
}
}
void ModelsManager::onCloseEditor(ExtDocumentController *documentController,
const qmt::MDiagram *diagram)
{
bool closeDocument = false;
foreach (const ManagedModel &managedModel, d->managedModels) {
if (managedModel.m_documentController == documentController) {
if (managedModel.m_modelDocument
&& managedModel.m_modelDocument->diagramUid() == diagram->getUid()) {
d->documentsToBeClosed.append(managedModel.m_modelDocument);
closeDocument = true;
} else {
foreach (DiagramDocument *diagramDocument, managedModel.m_diagramDocuments) {
if (diagramDocument->diagramUid() == diagram->getUid()) {
d->documentsToBeClosed.append(diagramDocument);
closeDocument = true;
}
}
}
}
}
if (closeDocument) {
// TODO remove this or fix asynchronous call
// Closing documents later one must garuantee that no remaining events are executed
// maybe by using some deleteLater() trick? (create and deleteLater a QObject that
// will call onCloseDocumentsLater())
//QTimer::singleShot(0, this, SLOT(onCloseDocumentsLater()));
onCloseDocumentsLater();
}
}
void ModelsManager::onCloseDocumentsLater()
{
QList<Core::IDocument *> documents = d->documentsToBeClosed;
d->documentsToBeClosed.clear();
Core::EditorManager::closeDocuments(documents);
}
void ModelsManager::onDiagramRenamed(ExtDocumentController *documentController,
const qmt::MDiagram *diagram)
{
foreach (const ManagedModel &managedModel, d->managedModels) {
if (managedModel.m_documentController == documentController) {
if (managedModel.m_modelDocument
&& managedModel.m_modelDocument->diagramUid() == diagram->getUid()) {
managedModel.m_modelDocument->onDiagramRenamed();
} else {
foreach (DiagramDocument *diagramDocument, managedModel.m_diagramDocuments) {
if (diagramDocument->diagramUid() == diagram->getUid())
diagramDocument->onDiagramRenamed();
}
}
openDiagram(managedModel.m_documentController, diagram);
return;
}
}
}
@@ -441,13 +192,13 @@ void ModelsManager::onAboutToShowContextMenu(ProjectExplorer::Project *project,
d->openDiagramContextMenuItem->setVisible(canOpenDiagram);
}
void ModelsManager::onOpenDiagram()
void ModelsManager::onOpenDiagramFromProjectExplorer()
{
if (ProjectExplorer::ProjectTree::instance()->currentNode() == d->contextMenuOwnerNode) {
qmt::MDiagram *diagram = 0;
foreach (const ManagedModel &managedModel, d->managedModels) {
if ((diagram = managedModel.m_documentController->pxNodeController()->findDiagramForExplorerNode(d->contextMenuOwnerNode))) {
onOpenEditor(managedModel.m_documentController, diagram);
openDiagram(managedModel.m_documentController, diagram);
break;
}
}
@@ -461,5 +212,19 @@ void ModelsManager::onOpenDefaultModel(const qmt::Uid &modelUid)
Core::EditorManager::openEditor(modelFile);
}
void ModelsManager::openDiagram(ExtDocumentController *documentController,
qmt::MDiagram *diagram)
{
foreach (const ManagedModel &managedModel, d->managedModels) {
if (managedModel.m_documentController == documentController) {
Core::IEditor *editor = Core::EditorManager::activateEditorForDocument(managedModel.m_modelDocument);
if (auto modelEditor = qobject_cast<ModelEditor *>(editor)) {
modelEditor->showDiagram(diagram);
}
return;
}
}
}
} // namespace Internal
} // namespace ModelEditor

View File

@@ -41,6 +41,7 @@ class Node;
namespace qmt {
class Uid;
class MDiagram;
class DiagramsViewInterface;
}
namespace ModelEditor {
@@ -49,7 +50,6 @@ namespace Internal {
class ExtDocumentController;
class DiagramsViewManager;
class ModelDocument;
class DiagramDocument;
class ModelsManager :
public QObject
@@ -62,29 +62,18 @@ public:
explicit ModelsManager(QObject *parent = 0);
~ModelsManager();
bool isDiagramOpen(const qmt::Uid &modelUid, const qmt::Uid &diagramUid) const;
ExtDocumentController *createModel(ModelDocument *findModelDocument);
ExtDocumentController *findModelByFileName(const QString &fileName,
ModelDocument *findModelDocument);
ExtDocumentController *findOrLoadModel(const qmt::Uid &modelUid,
DiagramDocument *diagramDocument);
void release(ExtDocumentController *documentController, ModelDocument *findModelDocument);
void release(ExtDocumentController *documentController, DiagramDocument *diagramDocument);
DiagramsViewManager *findDiagramsViewManager(ExtDocumentController *documentController) const;
ModelDocument *findModelDocument(ExtDocumentController *documentController) const;
QList<ExtDocumentController *> collectAllDocumentControllers() const;
ExtDocumentController *createModel(ModelDocument *modelDocument);
void releaseModel(ExtDocumentController *documentController);
void openDiagram(const qmt::Uid &modelUid, const qmt::Uid &diagramUid);
private slots:
void onOpenEditor(ExtDocumentController *documentController, const qmt::MDiagram *diagram);
void onCloseEditor(ExtDocumentController *documentController, const qmt::MDiagram *diagram);
void onCloseDocumentsLater();
void onDiagramRenamed(ExtDocumentController *documentController, const qmt::MDiagram *diagram);
void onAboutToShowContextMenu(ProjectExplorer::Project *project, ProjectExplorer::Node *node);
void onOpenDiagram();
void onOpenDiagramFromProjectExplorer();
void onOpenDefaultModel(const qmt::Uid &modelUid);
private:
void openDiagram(ExtDocumentController *documentController, qmt::MDiagram *diagram);
private:
ModelsManagerPrivate *d;
};

View File

@@ -5,10 +5,4 @@
<comment>Qt Creator Model File</comment>
<glob pattern="*.qmodel"/>
</mime-type>
<mime-type type="text/vnd.qtcreator.diagram-reference">
<sub-class-of type="text/xml"/>
<comment>Qt Creator Diagram Reference File</comment>
<glob pattern="*.qdiagram"/>
</mime-type>
</mime-info>