AbstractCommand *NodeElement::changeParentCommand(const Id &newParent, const QPointF &position) const { EditorViewScene *evScene = dynamic_cast<EditorViewScene *>(scene()); Element *oldParentElem = dynamic_cast<Element *>(parentItem()); const Id oldParent = oldParentElem ? oldParentElem->id() : evScene->rootItemId(); if (oldParent == newParent) { return nullptr; } const QPointF oldPos = mResizeCommand ? mResizeCommand->geometryBeforeDrag().topLeft() : mPos; const QPointF oldScenePos = oldParentElem ? oldParentElem->mapToScene(oldPos) : oldPos; // Without pre-translating into new position parent gets wrong child coords // when redo happens and resizes when he doesn`t need it. // So we mush pre-translate child into new scene position first, but when // it lays in some container it also resizes. So we need to change parent to // root, then translate into a new position and change parent to a new one. // Also that element itself doesn`t change position in change parent command // so using translation command ChangeParentCommand *changeParentToSceneCommand = new ChangeParentCommand(mLogicalAssistApi, mGraphicalAssistApi, false , id(), oldParent, evScene->rootItemId(), oldPos, oldScenePos); AbstractCommand *translateCommand = ResizeCommand::create(this, mContents , position, mContents, oldScenePos); ChangeParentCommand *result = new ChangeParentCommand( mLogicalAssistApi, mGraphicalAssistApi, false , id(), evScene->rootItemId(), newParent, position, position); result->addPreAction(changeParentToSceneCommand); result->addPreAction(translateCommand); return result; }
void EmbeddedLinker::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (mPressed) { mPressed = false; EditorViewScene *scene = dynamic_cast<EditorViewScene*>(master->scene()); if (!scene) { return; } const QString type = "qrm:/" + master->id().editor() + "/" + master->id().diagram() + "/" + edgeType.element(); if (scene->mainWindow()->manager()->hasElement(Id::loadFromString(type))) { master->setConnectingState(true); Id edgeId = scene->createElement(type, event->scenePos()); mEdge = dynamic_cast<EdgeElement*>(scene->getElem(edgeId)); } if (mEdge){ QPointF point = mapToItem(master, event->pos()); mEdge->placeStartTo(mEdge->mapFromItem(master, master->getNearestPort(point))); mEdge->placeEndTo(mEdge->mapFromScene(mapToScene(event->pos()))); } } if (mEdge != NULL) { mEdge->arrangeSrcAndDst(); mEdge->placeEndTo(mEdge->mapFromScene(mapToScene(event->pos()))); } }
void NodeElement::updateChildrenOrder() { QStringList ids; if (mGraphicalAssistApi.properties(mId).contains("childrenOrder")) { ids = mGraphicalAssistApi.graphicalRepoApi().property(mId, "childrenOrder").toStringList(); } EditorViewScene *evScene = dynamic_cast<EditorViewScene *>(scene()); if (evScene) { QStringList idsForRemoving; for (const QString &id : ids) { if (!evScene->getNodeById(Id::loadFromString(id))) { idsForRemoving.append(id); } } for (const QString &id : idsForRemoving) { ids.removeAll(id); } } QList<NodeElement *> children = childNodes(); for (NodeElement *child : children) { if (!ids.contains(child->id().toString())) { ids << child->id().toString(); } } mGraphicalAssistApi.mutableGraphicalRepoApi().setProperty(mId, "childrenOrder", ids); }
void EmbeddedLinker::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { hide(); EditorViewScene* scene = dynamic_cast<EditorViewScene*>(master->scene()); if ((scene) && (mEdge)) { mEdge->hide(); NodeElement *under = dynamic_cast<NodeElement*>(scene->itemAt(event->scenePos())); mEdge->show(); int result = 0; UML::NodeElement* target; if (!under) { result = scene->launchEdgeMenu(mEdge, master, event->scenePos()); if (result == -1) mEdge = NULL; else if ((result == +1) && (scene->getLastCreated())) { target = dynamic_cast<UML::NodeElement*>(scene->getLastCreated()); if (target) { mEdge->placeEndTo(mapFromItem(target,target->getNearestPort(target->pos()))); mEdge->connectToPort(); //it provokes to move target somehow, so it needs to place edge end and connect to port again mEdge->placeEndTo(mapFromItem(target,target->getNearestPort(target->pos()))); } } } if (result != -1) mEdge->connectToPort(); } }
void EmbeddedLinker::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { hide(); master->selectionState(false); EditorViewScene* scene = dynamic_cast<EditorViewScene*>(master->scene()); if (!mPressed && scene && mEdge) { mEdge->hide(); QPointF const &eScenePos = event->scenePos(); NodeElement *under = dynamic_cast<NodeElement*>(scene->itemAt(eScenePos)); mEdge->show(); int result = 0; if (!under) { result = scene->launchEdgeMenu(mEdge, master, eScenePos); NodeElement *target = dynamic_cast<NodeElement*>(scene->getLastCreated()); if (result == -1) { mEdge = NULL; } else if ((result == +1) && target) { QPointF const &posRelativeToTheTarget = target->mapFromScene(eScenePos); mEdge->placeEndTo(mapFromItem(target, target->getNearestPort(posRelativeToTheTarget))); mEdge->connectToPort(); //it provokes to move target somehow, so it needs to place edge end and connect to port again mEdge->placeEndTo(mapFromItem(target, target->getNearestPort(posRelativeToTheTarget))); mEdge->adjustLink(); } } if (result != -1) { mEdge->connectToPort(); } } }
void SceneGridHandler::delUnusedLines() { EditorViewScene *evScene = dynamic_cast<EditorViewScene *>(mNode->scene()); evScene->deleteFromForeground(mGuidesPixmap); delete mGuidesPixmap; mGuidesPixmap = NULL; mLines.clear(); }
void NodeElement::recalculateHighlightedNode(const QPointF &mouseScenePos) { // in case of unresizable item use switch // Determing parent using corner position, not mouse coordinates QPointF newParentInnerPoint = mouseScenePos; switch (mDragState) { case TopLeft: newParentInnerPoint = scenePos(); break; case Top: newParentInnerPoint = scenePos() + QPointF(mContents.width() / 2, 0); break; case TopRight: newParentInnerPoint = scenePos() + QPointF(mContents.width(), 0); break; case Left: newParentInnerPoint = scenePos() + QPointF(0, mContents.height() / 2); break; case Right: newParentInnerPoint = scenePos() + QPointF(mContents.width(), mContents.height() / 2); break; case BottomLeft: newParentInnerPoint = scenePos() + QPointF(0, mContents.height()); break; case Bottom: newParentInnerPoint = scenePos() + QPointF(mContents.width() / 2, mContents.height()); break; case BottomRight: newParentInnerPoint = scenePos() + QPointF(mContents.width(), mContents.height()); break; case None: break; } EditorViewScene *evScene = dynamic_cast<EditorViewScene*>(scene()); NodeElement *newParent = evScene->findNewParent(newParentInnerPoint, this); // it would be nice optimization to do nothing in case of // mHighlightedNode == newParent, but it's unapplicable here because // of element could be moved inside his parent if (newParent) { if (mHighlightedNode) { mHighlightedNode->erasePlaceholder(false); } mHighlightedNode = newParent; mHighlightedNode->drawPlaceholder(EditorViewScene::getPlaceholder(), mouseScenePos); } else if (mHighlightedNode != nullptr) { mHighlightedNode->erasePlaceholder(true); mHighlightedNode = nullptr; } }
void MiniMap::setCurrentScene() { mEditorView = mWindow->getCurrentTab(); if (mEditorView == NULL) { return; } EditorViewScene *editorViewScene = static_cast<EditorViewScene *>(mEditorView->scene()); if (editorViewScene->mainWindow() != NULL) { setScene(editorViewScene); // can affect zoom - need to change it if we make another desision about it connect(editorViewScene, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(showScene())); } }
QList<NodeElement *> ResizeHandler::sortedChildrenList() const { QList<NodeElement *> result; IdList childrenIds = mTargetNode.sortedChildren(); EditorViewScene *evScene = dynamic_cast<EditorViewScene *>(mTargetNode.scene()); for (const Id &id : childrenIds) { NodeElement *child = evScene->getNodeById(id); if (child) { result << child; } } return result; }
void EmbeddedLinker::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { updateMasterEdges(); hide(); mMaster->selectionState(false); EditorViewScene* scene = dynamic_cast<EditorViewScene*>(mMaster->scene()); if (!mPressed && scene && mEdge) { mEdge->hide(); QPointF const &eScenePos = event->scenePos(); NodeElement *under = dynamic_cast<NodeElement*>(scene->itemAt(eScenePos, QTransform())); mEdge->show(); int result = 0; commands::CreateElementCommand *createElementFromMenuCommand = NULL; if (!under) { result = scene->launchEdgeMenu(mEdge, mMaster, eScenePos, &createElementFromMenuCommand); NodeElement *target = dynamic_cast<NodeElement*>(scene->getLastCreated()); if (result == -1) { mEdge = NULL; } else if ((result == 1) && target) { mEdge->setDst(target); target->storeGeometry(); } } if (result != -1) { mEdge->connectToPort(); mEdge->adjustNeighborLinks(); mEdge->correctArrow(); mEdge->correctInception(); mEdge->adjustNeighborLinks(); // This will restore edge state after undo/redo commands::ReshapeEdgeCommand *reshapeEdge = new commands::ReshapeEdgeCommand(mEdge); reshapeEdge->startTracking(); reshapeEdge->stopTracking(); reshapeEdge->setUndoEnabled(false); if (createElementFromMenuCommand) { createElementFromMenuCommand->addPostAction(reshapeEdge); mCreateEdgeCommand->addPostAction(createElementFromMenuCommand); } else { mCreateEdgeCommand->addPostAction(reshapeEdge); } } } mPressed = false; mEdge = NULL; }
void EmbeddedLinker::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { mTimer->start(400); if (mPressed) { mPressed = false; EditorViewScene *scene = dynamic_cast<EditorViewScene*>(mMaster->scene()); if (!scene) { return; } QString const type = "qrm:/" + mMaster->id().editor() + "/" + mMaster->id().diagram() + "/" + mEdgeType.element(); if (scene->mainWindow()->editorManager().hasElement(Id::loadFromString(type))) { mMaster->setConnectingState(true); // FIXME: I am raw. return strange pos() and inside me a small trash Id edgeId = scene->createElement(type, event->scenePos(), true, &mCreateEdgeCommand); mEdge = dynamic_cast<EdgeElement*>(scene->getElem(edgeId)); } if (mEdge) { mMaster->setZValue(1); mEdge->setSrc(mMaster); mEdge->setDst(NULL); mEdge->highlight(); mEdge->tuneForLinker(); mEdge->placeEndTo(mEdge->mapFromScene(mapToScene(event->pos()))); mMaster->arrangeLinks(); mMaster->adjustLinks(); } } if (mEdge) { if (mTimeOfUpdate == 14) { mTimeOfUpdate = 0; mEdge->adjustNeighborLinks(); mEdge->arrangeSrcAndDst(); } else { mTimeOfUpdate++; } mEdge->placeEndTo(mEdge->mapFromScene(mapToScene(event->pos()))); } }
void EmbeddedLinker::mousePressEvent(QGraphicsSceneMouseEvent *event) { EditorViewScene *scene = dynamic_cast<EditorViewScene*>(master->scene()); if (scene) { const QString type = "qrm:/" + master->uuid().editor() + "/" + master->uuid().diagram() + "/" + edgeType.element(); if (scene->mainWindow()->manager()->hasElement(Id::loadFromString(type))) { master->setConnectingState(true); Id *edgeId = scene->createElement(type, event->scenePos()); mEdge = dynamic_cast<EdgeElement*>(scene->getElem(*edgeId)); } if (mEdge) { master->setSelected(false); QPointF point = mapToItem(master,event->pos()); mEdge->placeStartTo(mEdge->mapFromItem(master,master->getNearestPort(point))); mEdge->placeEndTo(mapToItem(mEdge,event->pos())); } } }
NodeElement *CopyHandler::clone(bool toCursorPos, bool searchForParents) { EditorViewScene *evscene = dynamic_cast<EditorViewScene *>(mNode.scene()); qReal::Id typeId = mNode.id().type(); qReal::Id resultId = evscene->createElement(typeId.toString(), QPointF(), searchForParents); NodeElement *result = dynamic_cast<NodeElement *>(evscene->getElem(resultId)); copyProperties(*result, mNode); copyChildren(*result, mNode); QRectF contents = mNode.contentsRect(); if (toCursorPos) { contents.moveTo(evscene->getMousePos()); result->setGeometry(contents); result->storeGeometry(); } else { contents.moveTo(mNode.pos()); result->setGeometry(contents); } return result; }
void NodeElement::initRenderedDiagram() { if (!mIsExpanded || mLogicalAssistApi.logicalRepoApi().outgoingExplosion(logicalId()) == Id()) { return; } EditorViewScene *evScene = dynamic_cast<EditorViewScene *>(scene()); if (!evScene) { return; } const Id diagram = mLogicalAssistApi.logicalRepoApi().outgoingExplosion(logicalId()); const Id graphicalDiagram = mGraphicalAssistApi.graphicalIdsByLogicalId(diagram)[0]; EditorView view(evScene->models(), evScene->controller(), evScene->customizer(), graphicalDiagram); view.mutableScene().setNeedDrawGrid(false); view.mutableMvIface().configure(mGraphicalAssistApi, mLogicalAssistApi, mModels.exploser()); view.mutableMvIface().setModel(evScene->models().graphicalModel()); view.mutableMvIface().setLogicalModel(evScene->models().logicalModel()); view.mutableMvIface().setRootIndex(mGraphicalAssistApi.indexById(graphicalDiagram)); QRectF sceneRect = view.editorViewScene().itemsBoundingRect(); QImage image(sceneRect.size().toSize(), QImage::Format_RGB32); QPainter painter(&image); QBrush brush(Qt::SolidPattern); brush.setColor(Qt::white); painter.setBrush(brush); painter.setPen(QPen(Qt::white)); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing); sceneRect.moveTo(QPointF()); painter.drawRect(sceneRect); view.mutableScene().render(&painter); mRenderedDiagram = image; }
void NodeElement::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (dynamic_cast<NodeElement *>(scene()->mouseGrabberItem()) == this) { ungrabMouse(); } if (event->button() == Qt::RightButton) { event->accept(); return; } deleteGuides(); storeGeometry(); if (scene() && (scene()->selectedItems().size() == 1) && isSelected()) { setVisibleEmbeddedLinkers(true); } if (mDragState == None) { Element::mouseReleaseEvent(event); } EditorViewScene *evScene = dynamic_cast<EditorViewScene *>(scene()); commands::InsertIntoEdgeCommand *insertCommand = new commands::InsertIntoEdgeCommand( *evScene, mModels, id(), id(), Id::rootId(), event->scenePos(), boundingRect().bottomRight(), false); bool shouldProcessResize = true; // we should use mHighlightedNode to determine if there is a highlighted node // insert current element into them and set mHighlightedNode to nullptr // but because of mouseRelease twice triggering we can't do it // This may cause more bugs if (flags() & ItemIsMovable) { if (mHighlightedNode) { NodeElement *newParent = mHighlightedNode; Element *insertBefore = mHighlightedNode->getPlaceholderNextElement(); mHighlightedNode->erasePlaceholder(false); // commented because of bug with double event sending (see #204) // mHighlightedNode = nullptr; QPointF newPos = mapToItem(newParent, mapFromScene(scenePos())); AbstractCommand *parentCommand = changeParentCommand(newParent->id(), newPos); mController->execute(parentCommand); // Position change already processed in change parent command shouldProcessResize = parentCommand == nullptr; setPos(newPos); if (insertBefore) { mGraphicalAssistApi.stackBefore(id(), insertBefore->id()); } newParent->resize(); while (newParent) { newParent->mContents = newParent->mContents.normalized(); newParent->storeGeometry(); newParent = dynamic_cast<NodeElement*>(newParent->parentItem()); } } else { AbstractCommand *parentCommand = changeParentCommand(evScene->rootItemId(), scenePos()); mController->execute(parentCommand); // Position change already processed in change parent command shouldProcessResize = parentCommand == nullptr; } } for (EdgeElement* edge : mEdgeList) { edge->layOut(); if (SettingsManager::value("ActivateGrid").toBool()) { edge->alignToGrid(); } } if (shouldProcessResize && mResizeCommand) { mResizeCommand->addPostAction(insertCommand); endResize(); } updateBySelection(); mDragState = None; }
void EmbeddedLinker::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { hide(); mMaster->selectionState(false); EditorViewScene* scene = dynamic_cast<EditorViewScene*>(mMaster->scene()); if (!mPressed && scene && mEdge) { mEdge->hide(); QPointF const &eScenePos = event->scenePos(); NodeElement *under = dynamic_cast<NodeElement*>(scene->itemAt(eScenePos, QTransform())); mEdge->show(); int result = 0; commands::CreateElementCommand *createElementFromMenuCommand = NULL; if (!under) { result = scene->launchEdgeMenu(mEdge, mMaster, eScenePos, false, &createElementFromMenuCommand); } else { bool canBeConnected = false; foreach(PossibleEdge const &pEdge, mEdge->src()->getPossibleEdges()) { if (pEdge.first.second.element() == under->id().element()) { canBeConnected = true; } else { // pEdge.second.first is true, if edge can connect items in only one direction. if (!pEdge.second.first) { canBeConnected = (pEdge.first.first.element() == under->id().element()); } } } if (under->isContainer()) { result = scene->launchEdgeMenu(mEdge, mMaster, eScenePos, canBeConnected, &createElementFromMenuCommand); } else { if (!canBeConnected) { result = -1; } } } NodeElement *target = dynamic_cast<NodeElement*>(scene->getLastCreated()); if (result == -1) { mEdge = NULL; } else if ((result == 1) && target) { mEdge->setDst(target); target->storeGeometry(); } if (result != -1) { mEdge->connectToPort(); updateMasterEdge(); // This will restore edge state after undo/redo commands::ReshapeEdgeCommand *reshapeEdge = new commands::ReshapeEdgeCommand(mEdge); reshapeEdge->startTracking(); reshapeEdge->stopTracking(); reshapeEdge->setUndoEnabled(false); if (createElementFromMenuCommand) { createElementFromMenuCommand->addPostAction(reshapeEdge); mCreateEdgeCommand->addPostAction(createElementFromMenuCommand); } else { mCreateEdgeCommand->addPostAction(reshapeEdge); } } }