// Copyright (C) 2016 Jochen Becher // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once #include "qmt/infrastructure/uid.h" #include #include namespace qmt { class UndoController; class ModelController; class MElement; class MObject; class MDiagram; class MRelation; class DSelection; class DContainer; class DReferences; class DElement; class DRelation; class QMT_EXPORT DiagramController : public QObject { Q_OBJECT public: enum UpdateAction { UpdateGeometry, // update only position and size of element UpdateMajor, // a major update of the element which will create a separate undo command UpdateMinor // a minor update of the element which may be merged with other minor updates in one undo command }; private: class Clone; class DiagramUndoCommand; class UpdateElementCommand; class AbstractAddRemCommand; class AddElementsCommand; class RemoveElementsCommand; class FindDiagramsVisitor; public: explicit DiagramController(QObject *parent = nullptr); ~DiagramController() override; signals: void beginResetAllDiagrams(); void endResetAllDiagrams(); void beginResetDiagram(const qmt::MDiagram *diagram); void endResetDiagram(const qmt::MDiagram *diagram); void beginUpdateElement(int row, const qmt::MDiagram *diagram); void endUpdateElement(int row, const qmt::MDiagram *diagram); void beginInsertElement(int row, const qmt::MDiagram *diagram); void endInsertElement(int row, const qmt::MDiagram *diagram); void beginRemoveElement(int row, const qmt::MDiagram *diagram); void endRemoveElement(int row, const qmt::MDiagram *diagram); void modified(const qmt::MDiagram *diagram); void diagramAboutToBeRemoved(const qmt::MDiagram *diagram); public: ModelController *modelController() const { return m_modelController; } void setModelController(ModelController *modelController); UndoController *undoController() const { return m_undoController; } void setUndoController(UndoController *undoController); QList allDiagrams() const { return m_allDiagrams; } private: MDiagram *findDiagram(const Uid &diagramKey) const; public: void addElement(DElement *element, MDiagram *diagram); void removeElement(DElement *element, MDiagram *diagram); DElement *findElement(const Uid &key, const MDiagram *diagram) const; template T *findElement(const Uid &key, const MDiagram *diagram) const { return dynamic_cast(findElement(key, diagram)); } bool hasDelegate(const MElement *modelElement, const MDiagram *diagram) const; DElement *findDelegate(const MElement *modelElement, const MDiagram *diagram) const; template T *findDelegate(const MElement *modelElement, const MDiagram *diagram) const { return dynamic_cast(findDelegate(modelElement, diagram)); } void startUpdateElement(DElement *element, MDiagram *diagram, UpdateAction updateAction); void finishUpdateElement(DElement *element, MDiagram *diagram, bool cancelled); void breakUndoChain(); DContainer cutElements(const DSelection &diagramSelection, MDiagram *diagram); DContainer copyElements(const DSelection &diagramSelection, const MDiagram *diagram); void pasteElements(const DReferences &diagramContainer, MDiagram *diagram); void deleteElements(const DSelection &diagramSelection, MDiagram *diagram); private: void onBeginResetModel(); void onEndResetModel(); void onBeginUpdateObject(int row, const MObject *parent); void onEndUpdateObject(int row, const MObject *parent); void onBeginInsertObject(int row, const MObject *owner); void onEndInsertObject(int row, const MObject *owner); void onBeginRemoveObject(int row, const MObject *parent); void onEndRemoveObject(int row, const MObject *parent); void onBeginMoveObject(int formerRow, const MObject *formerOwner); void onEndMoveObject(int row, const MObject *owner); void onBeginUpdateRelation(int row, const MObject *owner); void onEndUpdateRelation(int row, const MObject *owner); void onBeginRemoveRelation(int row, const MObject *owner); void onEndRemoveRelation(int row, const MObject *owner); void onBeginMoveRelation(int formerRow, const MObject *formerOwner); void onEndMoveRelation(int row, const MObject *owner); void deleteElements(const DSelection &diagramSelection, MDiagram *diagram, const QString &commandLabel); DElement *findElementOnAnyDiagram(const Uid &uid); void removeObjects(MObject *modelObject); void removeRelations(MRelation *modelRelation); void removeRelations(DElement *element, MDiagram *diagram); void renewElementKey(DElement *element, QHash *renewedKeys); void updateRelationKeys(DRelation *relation, const QHash &renewedKeys); void updateElementFromModel(DElement *element, const MDiagram *diagram, bool emitUpdateSignal); void diagramModified(MDiagram *diagram); DReferences simplify(const DSelection &diagramSelection, const MDiagram *diagram); MElement *delegatedElement(const DElement *element) const; bool isDelegatedElementOnDiagram(const DElement *element, const MDiagram *diagram) const; bool areRelationEndsOnDiagram(const DRelation *relation, const MDiagram *diagram) const; void updateAllDiagramsList(); void verifyDiagramsIntegrity(); void verifyDiagramIntegrity(const MDiagram *diagram); ModelController *m_modelController = nullptr; UndoController *m_undoController = nullptr; QList m_allDiagrams; }; } // namespace qmt