Example #1
0
void GraphicalModelView::rowsInserted(const QModelIndex &parent, int start, int end)
{
	const QPersistentModelIndex parentIndex = parent.sibling(parent.row(), 0);
	Id parentLogicalId = parentIndex.data(roles::logicalIdRole).value<Id>();

	for (int row = start; row <= end; ++row) {
		const QPersistentModelIndex current = model()->index(row, 0, parent);
		const Id logicalId = current.data(roles::logicalIdRole).value<Id>();
		if (parentLogicalId.isNull() || parentLogicalId.editor() != "MetaEditor"
				|| logicalId.editor() != "MetaEditor")
		{
			parentLogicalId = Id::rootId();
		}

		const QString name = current.data(Qt::DisplayRole).toString();
		if (logicalId.isNull()) {
			// No logical Id for this item, so logical model shouldn't care
			// about it.
			continue;
		}

		// Add this element to a root for now. To be able to do something
		// useful, we need to establish a correspondence between logical
		// and graphical model hierarchy. It is not always easy since
		// some elements have no correspondences in another model, and tree
		// structures may be very different by themselves.
		LogicalModel * const logicalModel = static_cast<LogicalModel *>(mModel);

		const bool isEdge = mModel->editorManagerInterface().isNodeOrEdge(logicalId.editor(), logicalId.element());

		ElementInfo elementInfo(logicalId, logicalId, parentLogicalId, Id(), {{"name", name}}, {}, Id(), isEdge);
		logicalModel->addElementToModel(elementInfo);
	}
}
void SuggestToCreateDiagramWidget::addItem(Id const &editor, Id const &diagram)
{
	EditorInterface *editorInterface = mMainWindow->manager()->editorInterface(editor.editor());

	QString const diagramName = editorInterface->diagramName(diagram.diagram());
	QString const diagramNodeName = editorInterface->diagramNodeName(diagram.diagram());

	if (diagramNodeName.isEmpty()) {
		return;
	}
	ListWidget::addItem(diagramName
			, "qrm:/" + editor.editor() + "/" + diagram.diagram() + "/" + diagramNodeName
			, tr("editor: ") + editor.editor() + tr(", diagram: ") + diagram.diagram());
}
Example #3
0
void RefactoringApplier::changeElementInModel(const Id &changeFromId, const Id &changeToId)
{
	if (mLogicalModelApi.isLogicalId(changeFromId)) {
		return;
	}
	if (!refactoringElements.contains(changeToId.element())) {
		IdList const inLinks = mGraphicalModelApi.mutableGraphicalRepoApi().incomingLinks(changeFromId);
		IdList const outLinks = mGraphicalModelApi.mutableGraphicalRepoApi().outgoingLinks(changeFromId);
		Id const parentId = mGraphicalModelApi.mutableGraphicalRepoApi().parent(changeFromId);
		QVariant const position = mGraphicalModelApi.mutableGraphicalRepoApi().position(changeFromId);
		bool const isFromLogicalModel = false;
		QString const refactoringsMetamodel = "RefactoringsMetamodel";
		QString newEditor = changeToId.editor();
		newEditor.chop(refactoringsMetamodel.length());
		Id const newId = Id(newEditor, changeToId.diagram(), changeToId.element(), QUuid::createUuid().toString());
		Id const newElementId = mGraphicalModelApi.createElement(parentId, newId
				, isFromLogicalModel, "ololo", position.toPointF());
		for (Id idLink : inLinks) {
			mGraphicalModelApi.mutableGraphicalRepoApi().setTo(idLink, newElementId);
		}
		for (Id idLink : outLinks) {
			mGraphicalModelApi.mutableGraphicalRepoApi().setFrom(idLink, newElementId);
		}
		mGraphicalModelApi.mutableGraphicalRepoApi().removeChild(parentId, changeFromId);
		mGraphicalModelApi.mutableGraphicalRepoApi().removeElement(changeFromId);
	}
}
Example #4
0
void Exploser::refreshPalette(gui::PaletteTreeWidget * const tree, Id const &diagram)
{
	QList<QPair<QString, QList<gui::PaletteElement>>> groups;
	QMap<QString, QString> descriptions;
	descriptions[mUserGroupTitle] = mUserGroupDescription;

	IdList const childTypes = mApi.editorManagerInterface().elements(diagram);

	for (Id const &child : childTypes) {
		QList<Explosion> const explosions = mApi.editorManagerInterface().explosions(child);

		for (Explosion const &explosion : explosions) {
			if (!explosion.isReusable()) {
				continue;
			}

			Id const targetNodeOrGroup = explosion.target();
			Id target;
			if (mApi.editorManagerInterface().isNodeOrEdge(targetNodeOrGroup.editor(), targetNodeOrGroup.element())) {
				target = targetNodeOrGroup;
			} else {
				Pattern const pattern = mApi.editorManagerInterface().getPatternByName(targetNodeOrGroup.element());
				target = Id(targetNodeOrGroup.editor(), targetNodeOrGroup.diagram(), pattern.rootType());
			}

			IdList const allTargets = mApi.logicalRepoApi().elementsByType(target.element(), true);
			QList<gui::PaletteElement> groupElements;
			for (Id const &targetInstance : allTargets) {
				if (mApi.isLogicalId(targetInstance)) {
					groupElements << gui::PaletteElement(child
							, mApi.logicalRepoApi().name(targetInstance)
							, QString(), mApi.editorManagerInterface().icon(child)
							, mApi.editorManagerInterface().iconSize(child)
							, targetInstance);
				}
			}

			if (!groupElements.isEmpty()) {
				groups << qMakePair(mUserGroupTitle, groupElements);
			}
		}
	}

	tree->addGroups(groups, descriptions, true, mApi.editorManagerInterface().friendlyName(diagram), true);
}
Example #5
0
void PaletteToolbox::addItemType(Id const &id, QString const &name, QString const &description, QIcon const &icon)
{
	Id category(id.editor(), id.diagram());
	QWidget *tab = mTabs[mCategories[category]];
	Q_ASSERT(tab);

	DraggableElement *element = new DraggableElement(id, name, description, icon, this);
	tab->layout()->addWidget(element);
}
Example #6
0
TEST(IdsTest, gettersTest) {
	Id id = Id::loadFromString("qrm:/editor/diagram/element/id");

	EXPECT_EQ(id.editor(), "editor");
	EXPECT_EQ(id.diagram(), "diagram");
	EXPECT_EQ(id.element(), "element");
	EXPECT_EQ(id.id(), "id");
	EXPECT_EQ(id.type() ,Id("editor", "diagram", "element"));
}
Id LogicalModelAssistApi::createElement(const Id &parent, const Id &type)
{
	Q_ASSERT(type.idSize() == 3);
	Q_ASSERT(parent.idSize() == 4);

	const Id newElementId = type.sameTypeId();
	const QString elementFriendlyName = mModelsAssistApi.editorManagerInterface().friendlyName(type);
	const bool isEdge = mModelsAssistApi.editorManagerInterface().isNodeOrEdge(
			newElementId.editor(), newElementId.element()) == -1;
	ElementInfo newElement(newElementId, Id(), parent, Id(), {{"name", elementFriendlyName}}, {}, Id(), isEdge);
	mLogicalModel.addElementToModel(newElement);
	return newElementId;
}
Example #8
0
Id ModelsAssistApi::createElement(Id const &parent, Id const &id, Id const &logicalId
		, bool isFromLogicalModel, QString const &name, QPointF const &position)
{
	Q_ASSERT(parent.idSize() == 4);
	Id newId = id;
	Id realLogicalId = logicalId;
	if (isFromLogicalModel) {
		realLogicalId = id;
		newId = Id(id.editor(), id.diagram(), id.element(), QUuid::createUuid().toString());
	}
	mModel.addElementToModel(parent, newId, realLogicalId, name, position);
	return newId;
}
SaveConvertionManager::GraphicalFilter SaveConvertionManager::graphicalRecreate(
		const SaveConvertionManager::GraphicalReplacer &replacer
		, const SaveConvertionManager::GraphicalConstructor &constructor)
{
	return [replacer, constructor](const Id &block, GraphicalModelAssistInterface &graphicalApi) {
		// Just iterating throught the elements on some diagram, ignoring the diagram itself.
		if (isDiagramType(block)) {
			return false;
		}

		// For each element trying to find out what to replace it with.
		const Id newType = replacer(block, graphicalApi);
		if (newType.isNull()) {
			// Not every element be replaced, concrete implementation must decide it.
			return false;
		}

		// Then creating new element of some type...
		const Id newBlock = Id::createElementId(newType.editor(), newType.diagram(), newType.element());
		graphicalApi.createElement(graphicalApi.parent(block)
				, newBlock
				, false
				, graphicalApi.name(block)
				, graphicalApi.position(block)
				, graphicalApi.logicalId(block));
		// And initializing it...
		constructor(newBlock, block, graphicalApi);

		const bool isEdge = isEdgeType(block);
		if (isEdge) {
			// If out element is edge then connecting it to same elements as the old one was connected
			graphicalApi.setFrom(newBlock, graphicalApi.from(block));
			graphicalApi.setTo(newBlock, graphicalApi.to(block));
		} else {
			// Replacing old node in all incomming and outgoing edges of the old node with the new one.
			for (const Id &edge : graphicalApi.graphicalRepoApi().outgoingLinks(block)) {
				graphicalApi.mutableGraphicalRepoApi().setProperty(edge, "from", newBlock.toVariant());
			}

			for (const Id &edge : graphicalApi.graphicalRepoApi().incomingLinks(block)) {
				graphicalApi.mutableGraphicalRepoApi().setProperty(edge, "to", newBlock.toVariant());
			}
		}

		// And finally disposing of outdated entity.
		graphicalApi.removeElement(block);
		return true;
	};
}
Example #10
0
void ExploserView::createAddExplosionMenu(const Element * const element
		, QMenu &contextMenu, QList<Explosion> const &explosions
		, const Id &alreadyConnectedElement) const
{
	bool hasAnyActions = false;
	const QString menuName = alreadyConnectedElement.isNull()
			? mCustomizer.addExplosionMenuName()
			: mCustomizer.changeExplosionMenuName();
	QMenu *addExplosionMenu = new QMenu(menuName);

	for (const Explosion &explosion : explosions) {
		for (const Id &elementId : mLogicalApi.logicalRepoApi().logicalElements(explosion.target())) {
			if (alreadyConnectedElement == elementId) {
				continue;
			}
			QAction *action = addExplosionMenu->addAction(mLogicalApi.logicalRepoApi().name(elementId));
			hasAnyActions = true;
			connect(action, SIGNAL(triggered()), SLOT(addExplosionActionTriggered()));
			QList<QVariant> tag;
			tag << element->logicalId().toVariant() << elementId.toVariant();
			action->setData(tag);
		}
	}

	if (hasAnyActions) {
		addExplosionMenu->addSeparator();
	}

	for (const Explosion &explosion : explosions) {
		const Id diagramType = mLogicalApi.editorManagerInterface().findElementByType(explosion.target().element());
		const QString name = mLogicalApi.editorManagerInterface().friendlyName(diagramType);
		const QString editorName = mLogicalApi.editorManagerInterface().friendlyName(Id(diagramType.editor()));
		QAction *action = addExplosionMenu->addAction(tr("New ") + editorName + "/" + name);
		hasAnyActions = true;
		connect(action, SIGNAL(triggered()), SLOT(addExplosionActionTriggered()));
		action->setData(QVariantList() << element->logicalId().toVariant() << diagramType.toVariant());
	}
	contextMenu.addMenu(addExplosionMenu);

	if (alreadyConnectedElement != Id()) {
		QAction * const gotoAction = contextMenu.addAction(mCustomizer.goToConnectedMenuName()
				, this, SLOT(goToActionTriggered()));
		gotoAction->setData(alreadyConnectedElement.toVariant());
	}
}
	virtual QStringList callMethod(
			EditorManagerInterface *editorManagerInterface
			, const Id &editorId
			, const Id &diagramId
			, const Id &elementId
			, const QString &propertyName
			) const
	{
		Q_UNUSED(elementId);
		Q_UNUSED(propertyName);
		const QString &editorName = editorId.editor();
		const QString &diagramName = diagramId.diagram();

		mResult = callFunction([editorManagerInterface, editorName, diagramName]()
				{ return editorManagerInterface->elements(editorName, diagramName); });

		return editorManagerInterface->elements(editorName, diagramName);
	}
	virtual QStringList callMethod(
			EditorManagerInterface *editorManagerInterface
			, const Id &editorId
			, const Id &diagramId
			, const Id &elementId
			, const QString &propertyName
			) const
	{
		Q_UNUSED(diagramId);
		Q_UNUSED(propertyName);
		const QString &editorName = editorId.editor();
		const QString &elementName = elementId.element();
		mResult = callFunction([editorManagerInterface, editorName, elementName]()
				{ return editorManagerInterface->isNodeOrEdge(editorName, elementName); });

		return ConvertingMethods::convertIntIntoStringList(
				editorManagerInterface->isNodeOrEdge(editorName, elementName));
	}
Example #13
0
bool Model::isDiagram(Id const &id) const
{
	return ((id != ROOT_ID) && (id.element() == assistApi().editorManager().getEditorInterface(id.editor())->diagramNodeName(id.diagram())));
}
Example #14
0
bool SaveConvertionManager::isRobotsDiagram(const Id &element)
{
	const QStringList robotsDiagrams = { "RobotsDiagram", "SubprogramDiagram" };
	return element.editor() == editor() && robotsDiagrams.contains(element.diagram());
}
CreateGroupCommand::CreateGroupCommand(models::LogicalModelAssistApi &logicalApi
		, models::GraphicalModelAssistApi &graphicalApi
		, models::Exploser &exploser
		, const Id &logicalParent
		, const Id &graphicalParent
		, const Id &id
		, bool isFromLogicalModel
		, const QPointF &position)
	: mLogicalApi(logicalApi)
	, mGraphicalApi(graphicalApi)
	, mExploser(exploser)
	, mLogicalParent(logicalParent)
	, mGraphicalParent(graphicalParent)
	, mId(id)
	, mIsFromLogicalModel(isFromLogicalModel)
	, mPosition(position)
	, mPattern(graphicalApi.editorManagerInterface().getPatternByName(id.element()))
{
	const QPointF size = mPattern.size();

	// Pattern nodes create may have hierarchic structure. So we must create them in correct order
	// (parent first, child after). Cycles in hierarchy and nodes with incorrect parent id are fully ignored
	QList<GroupNode> toCreate = mPattern.nodes();
	QSet<QString> consideredNodes;
	QMap<QString, Id> createdNodesIds;
	// If group node has no parent then it has 'global' one
	createdNodesIds[QString()] = graphicalParent;
	bool somethingChangedThisIteration = true;
	while (!toCreate.isEmpty() && somethingChangedThisIteration) {
		somethingChangedThisIteration = false;
		for (const GroupNode &node : toCreate) {
			if (!node.parent.isEmpty() && !consideredNodes.contains(node.parent)) {
				continue;
			}

			const Id element(id.editor(), id.diagram(), node.type, QUuid::createUuid().toString());
			createdNodesIds[node.id] = element;
			if (node.id == mPattern.rootNode()) {
				mRootId = element;
			}

			const QPointF nodePos(position.x() - size.x() / 2 + node.position.x()
					, position.y() + node.position.y());
			CreateElementCommand *createNodeCommand = new CreateElementCommand(
					logicalApi, graphicalApi, exploser, logicalParent
					, createdNodesIds[node.parent], element, isFromLogicalModel
					, mLogicalApi.editorManagerInterface().friendlyName(element.type()), nodePos);
			mNodeCommands[node.id] = createNodeCommand;
			addPreAction(createNodeCommand);
			consideredNodes << node.id;
			toCreate.removeAll(node);
			somethingChangedThisIteration = true;
		}
	}
	// TODO: display here error if toCreate still non-empty

	for (const GroupEdge &edge : mPattern.edges()) {
		const Id element(id.editor(), id.diagram(), edge.type, QUuid::createUuid().toString());
		CreateElementCommand *createEdgeCommand = new CreateElementCommand(
					logicalApi, graphicalApi, exploser, logicalParent, graphicalParent, element, isFromLogicalModel
					, mLogicalApi.editorManagerInterface().friendlyName(element.type()), QPointF());
		mEdgeCommands.append(createEdgeCommand);
		addPreAction(createEdgeCommand);
	}
}