diff --git a/src/libs/3rdparty/modeling/qmt/diagram_scene/diagramscenemodel.cpp b/src/libs/3rdparty/modeling/qmt/diagram_scene/diagramscenemodel.cpp index 9a51a905856..25ffdfb98bd 100644 --- a/src/libs/3rdparty/modeling/qmt/diagram_scene/diagramscenemodel.cpp +++ b/src/libs/3rdparty/modeling/qmt/diagram_scene/diagramscenemodel.cpp @@ -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) diff --git a/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsmanager.cpp b/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsmanager.cpp index 346263c6789..843fdec4301 100644 --- a/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsmanager.cpp +++ b/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsmanager.cpp @@ -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())) { diff --git a/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsmanager.h b/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsmanager.h index 38b29cfc23e..7830cbbe3d3 100644 --- a/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsmanager.h +++ b/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsmanager.h @@ -93,8 +93,6 @@ public: void setStereotypeController(StereotypeController *stereotype_controller); - MDiagram *getCurrentDiagram() const; - public: DiagramSceneModel *bindDiagramSceneModel(MDiagram *diagram); diff --git a/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsviewinterface.h b/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsviewinterface.h index c1f72539ea9..b2ab6709273 100644 --- a/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsviewinterface.h +++ b/src/libs/3rdparty/modeling/qmt/diagram_ui/diagramsviewinterface.h @@ -43,8 +43,6 @@ public: public: - virtual MDiagram *getCurrentDiagram() const = 0; - virtual void openDiagram(MDiagram *) = 0; virtual void closeDiagram(const MDiagram *) = 0; diff --git a/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramsview.cpp b/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramsview.cpp index fee299b0ba7..fd4923ee482 100644 --- a/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramsview.cpp +++ b/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramsview.cpp @@ -61,12 +61,6 @@ void DiagramsView::setDiagramsManager(DiagramsManager *diagrams_manager) _diagrams_manager = diagrams_manager; } -MDiagram *DiagramsView::getCurrentDiagram() const -{ - DiagramView *diagram_view = dynamic_cast(currentWidget()); - return getDiagram(diagram_view); -} - void DiagramsView::openDiagram(MDiagram *diagram) { QMT_CHECK(diagram); diff --git a/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramsview.h b/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramsview.h index dc8810a7dc2..dbf94da1b31 100644 --- a/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramsview.h +++ b/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramsview.h @@ -72,8 +72,6 @@ public: void setDiagramsManager(DiagramsManager *diagrams_manager); - MDiagram *getCurrentDiagram() const; - public slots: void openDiagram(MDiagram *diagram); diff --git a/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramview.cpp b/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramview.cpp index 98e7f85266e..e9e4d0ccb28 100644 --- a/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramview.cpp +++ b/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/diagramview.cpp @@ -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) diff --git a/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/stackeddiagramsview.cpp b/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/stackeddiagramsview.cpp index 2624eae506e..65f4285090f 100644 --- a/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/stackeddiagramsview.cpp +++ b/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/stackeddiagramsview.cpp @@ -57,12 +57,6 @@ void StackedDiagramsView::setDiagramsManager(DiagramsManager *diagrams_manager) _diagrams_manager = diagrams_manager; } -MDiagram *StackedDiagramsView::getCurrentDiagram() const -{ - DiagramView *diagram_view = dynamic_cast(currentWidget()); - return getDiagram(diagram_view); -} - void StackedDiagramsView::openDiagram(MDiagram *diagram) { QMT_CHECK(diagram); diff --git a/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/stackeddiagramsview.h b/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/stackeddiagramsview.h index c7323361ba6..8bf12522b97 100644 --- a/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/stackeddiagramsview.h +++ b/src/libs/3rdparty/modeling/qmt/diagram_widgets_ui/stackeddiagramsview.h @@ -72,8 +72,6 @@ public: void setDiagramsManager(DiagramsManager *diagrams_manager); - MDiagram *getCurrentDiagram() const; - public slots: void openDiagram(MDiagram *diagram); diff --git a/src/libs/3rdparty/modeling/qmt/document_controller/documentcontroller.cpp b/src/libs/3rdparty/modeling/qmt/document_controller/documentcontroller.cpp index c56bd1152d9..b399727044b 100644 --- a/src/libs/3rdparty/modeling/qmt/document_controller/documentcontroller.cpp +++ b/src/libs/3rdparty/modeling/qmt/document_controller/documentcontroller.cpp @@ -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) diff --git a/src/libs/3rdparty/modeling/qmt/document_controller/documentcontroller.h b/src/libs/3rdparty/modeling/qmt/document_controller/documentcontroller.h index 2ed61016c18..6fde5a305ec 100644 --- a/src/libs/3rdparty/modeling/qmt/document_controller/documentcontroller.h +++ b/src/libs/3rdparty/modeling/qmt/document_controller/documentcontroller.h @@ -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: diff --git a/src/plugins/modeleditor/abstracteditor.cpp b/src/plugins/modeleditor/abstracteditor.cpp deleted file mode 100644 index dd9fec7c011..00000000000 --- a/src/plugins/modeleditor/abstracteditor.cpp +++ /dev/null @@ -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 -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -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(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(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(selection.getIndices().at(0).getElementKey(), diagram); - if (diagramElement) - package = documentController->getModelController()->findObject(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 propertiesModelElements; - QList 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 &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 &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 &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(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 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 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(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 diff --git a/src/plugins/modeleditor/abstracteditor.h b/src/plugins/modeleditor/abstracteditor.h deleted file mode 100644 index b1e0b14fcd1..00000000000 --- a/src/plugins/modeleditor/abstracteditor.h +++ /dev/null @@ -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 - -#include - -#include - -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 &modelElements); - void showProperties(qmt::MDiagram *diagram, const QList &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 &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 diff --git a/src/plugins/modeleditor/actionhandler.cpp b/src/plugins/modeleditor/actionhandler.cpp index b2667fe474b..f248d00aa97 100644 --- a/src/plugins/modeleditor/actionhandler.cpp +++ b/src/plugins/modeleditor/actionhandler.cpp @@ -31,7 +31,7 @@ #include "actionhandler.h" #include "modeleditor_constants.h" -#include "abstracteditor.h" +#include "modeleditor.h" #include #include @@ -147,63 +147,63 @@ void ActionHandler::createEditPropertiesShortcut(const Core::Id &shortcutId) void ActionHandler::undo() { - auto editor = dynamic_cast(Core::EditorManager::currentEditor()); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (editor) editor->undo(); } void ActionHandler::redo() { - auto editor = dynamic_cast(Core::EditorManager::currentEditor()); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (editor) editor->redo(); } void ActionHandler::cut() { - auto editor = dynamic_cast(Core::EditorManager::currentEditor()); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (editor) editor->cut(); } void ActionHandler::copy() { - auto editor = dynamic_cast(Core::EditorManager::currentEditor()); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (editor) editor->copy(); } void ActionHandler::paste() { - auto editor = dynamic_cast(Core::EditorManager::currentEditor()); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (editor) editor->paste(); } void ActionHandler::removeSelectedElements() { - auto editor = dynamic_cast(Core::EditorManager::currentEditor()); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (editor) editor->removeSelectedElements(); } void ActionHandler::deleteSelectedElements() { - auto editor = dynamic_cast(Core::EditorManager::currentEditor()); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (editor) editor->deleteSelectedElements(); } void ActionHandler::selectAll() { - auto editor = dynamic_cast(Core::EditorManager::currentEditor()); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (editor) editor->selectAll(); } void ActionHandler::onEditProperties() { - auto editor = dynamic_cast(Core::EditorManager::currentEditor()); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (editor) editor->editProperties(); } diff --git a/src/plugins/modeleditor/diagramdocument.cpp b/src/plugins/modeleditor/diagramdocument.cpp deleted file mode 100644 index 0e071c1c5d6..00000000000 --- a/src/plugins/modeleditor/diagramdocument.cpp +++ /dev/null @@ -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 - -#include - -#include - -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(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(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 diff --git a/src/plugins/modeleditor/diagramdocument.h b/src/plugins/modeleditor/diagramdocument.h deleted file mode 100644 index 503c4f070b6..00000000000 --- a/src/plugins/modeleditor/diagramdocument.h +++ /dev/null @@ -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 -#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 diff --git a/src/plugins/modeleditor/diagrameditor.cpp b/src/plugins/modeleditor/diagrameditor.cpp deleted file mode 100644 index 9a70b833d3c..00000000000 --- a/src/plugins/modeleditor/diagrameditor.cpp +++ /dev/null @@ -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 - -#include - -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(d->document->diagramUid()); - QTC_ASSERT(diagram, return); - showDiagram(diagram); - - expandModelTreeToDepth(0); -} - -} // namespace Internal -} // namespace ModelEditor diff --git a/src/plugins/modeleditor/diagrameditor.h b/src/plugins/modeleditor/diagrameditor.h deleted file mode 100644 index 71a9a721984..00000000000 --- a/src/plugins/modeleditor/diagrameditor.h +++ /dev/null @@ -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 diff --git a/src/plugins/modeleditor/diagrameditorfactory.cpp b/src/plugins/modeleditor/diagrameditorfactory.cpp deleted file mode 100644 index 0c9cbe1e345..00000000000 --- a/src/plugins/modeleditor/diagrameditorfactory.cpp +++ /dev/null @@ -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 - -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 diff --git a/src/plugins/modeleditor/diagrameditorfactory.h b/src/plugins/modeleditor/diagrameditorfactory.h deleted file mode 100644 index 4b650897e03..00000000000 --- a/src/plugins/modeleditor/diagrameditorfactory.h +++ /dev/null @@ -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 - -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 diff --git a/src/plugins/modeleditor/diagramsviewmanager.cpp b/src/plugins/modeleditor/diagramsviewmanager.cpp index f844ef2006d..8bae2b1b64e 100644 --- a/src/plugins/modeleditor/diagramsviewmanager.cpp +++ b/src/plugins/modeleditor/diagramsviewmanager.cpp @@ -30,7 +30,7 @@ #include "diagramsviewmanager.h" -#include "abstracteditor.h" +#include "modeleditor.h" #include #include @@ -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(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) diff --git a/src/plugins/modeleditor/diagramsviewmanager.h b/src/plugins/modeleditor/diagramsviewmanager.h index 69235d45956..05febcdd071 100644 --- a/src/plugins/modeleditor/diagramsviewmanager.h +++ b/src/plugins/modeleditor/diagramsviewmanager.h @@ -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; diff --git a/src/plugins/modeleditor/documentinterface.h b/src/plugins/modeleditor/documentinterface.h deleted file mode 100644 index efa5770d5f4..00000000000 --- a/src/plugins/modeleditor/documentinterface.h +++ /dev/null @@ -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 diff --git a/src/plugins/modeleditor/extdocumentcontroller.cpp b/src/plugins/modeleditor/extdocumentcontroller.cpp index 7797a56f3c6..70195294b29 100644 --- a/src/plugins/modeleditor/extdocumentcontroller.cpp +++ b/src/plugins/modeleditor/extdocumentcontroller.cpp @@ -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); diff --git a/src/plugins/modeleditor/modeldocument.cpp b/src/plugins/modeleditor/modeldocument.cpp index 8814559a25a..928b958f220 100644 --- a/src/plugins/modeleditor/modeldocument.cpp +++ b/src/plugins/modeleditor/modeldocument.cpp @@ -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(d->diagramUid); - if (diagram) - setPreferredDisplayName(tr("%1 [%2]").arg(diagram->getName()).arg(filePath().fileName())); - else - setPreferredDisplayName(QString()); -} - } // namespace Internal } // namespace ModelEditor diff --git a/src/plugins/modeleditor/modeldocument.h b/src/plugins/modeleditor/modeldocument.h index dc422700475..f2c5d65e5b7 100644 --- a/src/plugins/modeleditor/modeldocument.h +++ b/src/plugins/modeleditor/modeldocument.h @@ -32,7 +32,8 @@ #define MODELDOCUMENT_H #include -#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; }; diff --git a/src/plugins/modeleditor/modeleditor.cpp b/src/plugins/modeleditor/modeleditor.cpp index e2a66ac98d3..abcf374066d 100644 --- a/src/plugins/modeleditor/modeleditor.cpp +++ b/src/plugins/modeleditor/modeleditor.cpp @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include 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("" + "
" + "
Open a diagram
" + "
" + "
" + "
• Double-click on diagram in model tree
" + "
• Select \"Open Diagram\" from package's context menu in model tree
" + "
" + "
" + ""); + 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(selection.getIndices().at(0).getElementKey(), diagram); + if (diagramElement) + package = documentController->getModelController()->findObject(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 propertiesModelElements; + QList 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 &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 &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 &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(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 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 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(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); } diff --git a/src/plugins/modeleditor/modeleditor.h b/src/plugins/modeleditor/modeleditor.h index 9cfcf05236c..86859522c51 100644 --- a/src/plugins/modeleditor/modeleditor.h +++ b/src/plugins/modeleditor/modeleditor.h @@ -31,13 +31,39 @@ #ifndef MODELDIAGRAMEDITOR_H #define MODELDIAGRAMEDITOR_H -#include "abstracteditor.h" +#include + +#include + +#include + +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 &modelElements); + void showProperties(qmt::MDiagram *diagram, const QList &diagramElements); + void clearProperties(); + void expandModelTreeToDepth(int depth); + QWidget *createToolbarCommandButton(const Core::Id &id, const std::function &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; diff --git a/src/plugins/modeleditor/modeleditor.pro b/src/plugins/modeleditor/modeleditor.pro index 6832fe2b277..a58bf9bee9c 100644 --- a/src/plugins/modeleditor/modeleditor.pro +++ b/src/plugins/modeleditor/modeleditor.pro @@ -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 \ diff --git a/src/plugins/modeleditor/modeleditor.qbs b/src/plugins/modeleditor/modeleditor.qbs index cad53935343..47ba97441fe 100644 --- a/src/plugins/modeleditor/modeleditor.qbs +++ b/src/plugins/modeleditor/modeleditor.qbs @@ -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", diff --git a/src/plugins/modeleditor/modeleditor_constants.h b/src/plugins/modeleditor/modeleditor_constants.h index baee8643079..f6f39d117e9 100644 --- a/src/plugins/modeleditor/modeleditor_constants.h +++ b/src/plugins/modeleditor/modeleditor_constants.h @@ -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"; diff --git a/src/plugins/modeleditor/modeleditor_plugin.cpp b/src/plugins/modeleditor/modeleditor_plugin.cpp index ef917e149dd..65e5e7315e1 100644 --- a/src/plugins/modeleditor/modeleditor_plugin.cpp +++ b/src/plugins/modeleditor/modeleditor_plugin.cpp @@ -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()); } diff --git a/src/plugins/modeleditor/modelindexer.cpp b/src/plugins/modeleditor/modelindexer.cpp index a0b346dc39f..8a437f28e26 100644 --- a/src/plugins/modeleditor/modelindexer.cpp +++ b/src/plugins/modeleditor/modelindexer.cpp @@ -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 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 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 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; diff --git a/src/plugins/modeleditor/modelsmanager.cpp b/src/plugins/modeleditor/modelsmanager.cpp index 37c6dbddc49..dd9d60deba8 100644 --- a/src/plugins/modeleditor/modelsmanager.cpp +++ b/src/plugins/modeleditor/modelsmanager.cpp @@ -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 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 ModelsManager::collectAllDocumentControllers() const -{ - QList 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(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 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(editor)) { + modelEditor->showDiagram(diagram); + } + return; + } + } +} + } // namespace Internal } // namespace ModelEditor diff --git a/src/plugins/modeleditor/modelsmanager.h b/src/plugins/modeleditor/modelsmanager.h index 26c2854c6e1..7756116a5f9 100644 --- a/src/plugins/modeleditor/modelsmanager.h +++ b/src/plugins/modeleditor/modelsmanager.h @@ -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 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; }; diff --git a/src/plugins/modeleditor/resources/modeleditor.mimetypes.xml b/src/plugins/modeleditor/resources/modeleditor.mimetypes.xml index 20d50c5a78f..45119429353 100644 --- a/src/plugins/modeleditor/resources/modeleditor.mimetypes.xml +++ b/src/plugins/modeleditor/resources/modeleditor.mimetypes.xml @@ -5,10 +5,4 @@ Qt Creator Model File - - - Qt Creator Diagram Reference File - - -