bool InsertIntoEdgeCommand::execute() { if (mCreateCommand) { mCreateCommand->redo(); mFirstId = mCreateCommand->result(); mLastId = mCreateCommand->result(); } EdgeElement *edge = mRemoveOldEdge ? mScene.getEdgeById(mOldEdge) : mScene.edgeForInsertion(mPos); if (!edge) { return true; } NodeElement *oldSrc = edge->src(); NodeElement *oldDst = edge->dst(); if (oldSrc && oldDst && oldSrc->id() != mFirstId && oldDst->id() != mLastId) { mParentId = (mParentId == Id::rootId()) ? mScene.rootItemId() : mParentId; Id type = edge->id().type(); initCommand(mCreateFirst, type); initCommand(mCreateSecond, type); makeLink(mCreateFirst, oldSrc, mScene.getNodeById(mFirstId)); makeLink(mCreateSecond, mScene.getNodeById(mLastId), oldDst); mConfiguration = mGraphicalAssistApi.configuration(edge->id()); if (!mRemoveOldEdge) { mRemoveOldEdge = new RemoveElementCommand(mLogicalAssistApi, mGraphicalAssistApi, mExploser , mScene.rootItemId(), mParentId, edge->id(), mIsLogical , mGraphicalAssistApi.name(edge->id()), mGraphicalAssistApi.position(edge->id())); } mRemoveOldEdge->redo(); mElementShifting.clear(); mScene.resolveOverlaps(mScene.getNodeById(mLastId), mPos, mShift, mElementShifting); mScene.resolveOverlaps(mScene.getNodeById(mFirstId), mPos, mShift, mElementShifting); } return true; }
void CopyHandler::copyChildren(NodeElement const &destination, NodeElement const &source) const { foreach (QGraphicsItem * const child, source.childItems()) { NodeElement * const element = dynamic_cast<NodeElement *>(child); if (!element) { continue; } CopyHandler copyHandler(*element, mGraphicalAssistApi); NodeElement const * const copyOfChild = copyHandler.clone(); mGraphicalAssistApi.changeParent(copyOfChild->id(), destination.id(), element->pos()); } }
void ResizeCommand::makeHierarchySnapshot(NodeElement *node, QMap<Id, QRectF> &target) { // Here we remembering all binded items geometries. // Binded items are just element`s hierarchy: // all parents and children (siblings are not considered) makeChildrenSnapshot(node, target); for (NodeElement *parentElement = node; parentElement; parentElement = dynamic_cast<NodeElement *>(parentElement->parentItem())) { target.insert(parentElement->id(), geometryOf(parentElement)); addEdges(parentElement); } }
void EditorViewMViface::handleNodeElementsForRowsInserted( const QList<QPair<NodeElement *, QPersistentModelIndex> > &nodes , const QModelIndex &parent ) { for (const QPair<NodeElement *, QPersistentModelIndex> &p : nodes) { NodeElement *elem = p.first; QPersistentModelIndex current = p.second; Id currentId = current.data(roles::idRole).value<Id>(); bool needToProcessChildren = true; if (elem) { QPointF ePos = model()->data(current, roles::positionRole).toPointF(); // setting position before parent definition 'itemChange' to work correctly elem->setPos(ePos); elem->setGeometry(mGraphicalAssistApi->configuration(elem->id()).boundingRect().translated(ePos.toPoint())); handleAddingSequenceForRowsInserted(parent, elem, current); handleElemDataForRowsInserted(elem, current); if (currentId.element() == "Class" && mGraphicalAssistApi->children(currentId).empty()) { needToProcessChildren = false; for (int i = 0; i < 2; i++) { QString curChildElementType = (i == 0) ? "MethodsContainer" : "FieldsContainer"; Id newUuid = Id("Kernel_metamodel", "Kernel", curChildElementType, QUuid::createUuid().toString()); mGraphicalAssistApi->createElement(currentId, newUuid , false, "(anonymous something)", QPointF(0, 0)); } } } if (needToProcessChildren && model()->hasChildren(current)) { rowsInserted(current, 0, model()->rowCount(current) - 1); } if (elem) { elem->alignToGrid(); } } }
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 CopyHandler::copyProperties(NodeElement const &destination, NodeElement const &source) const { mGraphicalAssistApi.copyProperties(destination.id(), source.id()); }
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); } } }