Bug Summary

File:OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp
Warning:line 8326, column 43
Called C++ object pointer is null

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1/*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-CurrentYear, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
14 * ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the Open Source Modelica
17 * Consortium (OSMC) Public License (OSMC-PL) are obtained
18 * from OSMC, either from the above address,
19 * from the URLs: http://www.ida.liu.se/projects/OpenModelica or
20 * http://www.openmodelica.org, and in the OpenModelica distribution.
21 * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
22 *
23 * This program is distributed WITHOUT ANY WARRANTY; without
24 * even the implied warranty of MERCHANTABILITY or FITNESS
25 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
26 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
27 *
28 * See the full OSMC Public License conditions for more details.
29 *
30 */
31/*
32 * @author Adeel Asghar <adeel.asghar@liu.se>
33 */
34
35#include "Modeling/ModelWidgetContainer.h"
36#include "MainWindow.h"
37#include "LibraryTreeWidget.h"
38#include "ItemDelegate.h"
39#include "Options/OptionsDialog.h"
40#include "MessagesWidget.h"
41#include "DocumentationWidget.h"
42#include "Annotations/ShapePropertiesDialog.h"
43#include "Component/ComponentProperties.h"
44#include "Commands.h"
45#include "TLM/FetchInterfaceDataDialog.h"
46#include "Options/NotificationsDialog.h"
47#include "ModelicaClassDialog.h"
48#include "TLM/TLMCoSimulationDialog.h"
49#include "Git/GitCommands.h"
50#if !defined(WITHOUT_OSG)
51#include "Animation/ThreeDViewer.h"
52#endif
53#include "OMS/OMSProxy.h"
54#include "OMS/ModelDialog.h"
55#include "OMS/BusDialog.h"
56#include "OMS/SystemSimulationInformationDialog.h"
57#include "Util/ResourceCache.h"
58#include "Plotting/PlotWindowContainer.h"
59
60#include <QNetworkReply>
61#include <QMessageBox>
62#include <QMenu>
63#include <QMenuBar>
64#include <QGraphicsDropShadowEffect>
65#include <QButtonGroup>
66#include <QDockWidget>
67#include <QPrinter>
68#include <QPrintDialog>
69#include <QDesktopServices>
70#include <QClipboard>
71
72/*!
73 * \class GraphicsScene
74 * \brief The GraphicsScene class is a container for graphicsl components in a simulationmodel.
75 */
76/*!
77 * \brief GraphicsScene::GraphicsScene
78 * \param viewType
79 * \param pModelWidget
80 */
81GraphicsScene::GraphicsScene(StringHandler::ViewType viewType, ModelWidget *pModelWidget)
82 : QGraphicsScene(pModelWidget), mViewType(viewType)
83{
84 mpModelWidget = pModelWidget;
85}
86
87/*!
88 * \class GraphicsView
89 * \brief The GraphicsView class is a class which display the content of a scene of components.
90 */
91/*!
92 * \brief GraphicsView::GraphicsView
93 * \param viewType
94 * \param pModelWidget
95 * \param visualizationView
96 */
97GraphicsView::GraphicsView(StringHandler::ViewType viewType, ModelWidget *pModelWidget, bool visualizationView)
98 : QGraphicsView(pModelWidget), mViewType(viewType), mVisualizationView(visualizationView), mSkipBackground(false)
99{
100 /* Ticket #3275
101 * Set the scroll bars policy to always on to avoid unnecessary resize events.
102 */
103 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
104 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
105 setFrameShape(QFrame::StyledPanel);
106 setDragMode(QGraphicsView::RubberBandDrag);
107 setAcceptDrops(true);
108 setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
109 setMouseTracking(true);
110 mpModelWidget = pModelWidget;
111 // set the coOrdinate System
112 mCoOrdinateSystem = CoOrdinateSystem();
113 // if it is a new model then use the values from options
114 if (!mpModelWidget->getLibraryTreeItem()->isSaved()) {
115 GraphicalViewsPage *pGraphicalViewsPage;
116 pGraphicalViewsPage = OptionsDialog::instance()->getGraphicalViewsPage();
117 const qreal left = (mViewType == StringHandler::Icon) ? pGraphicalViewsPage->getIconViewExtentLeft() : pGraphicalViewsPage->getDiagramViewExtentLeft();
118 const qreal bottom = (mViewType == StringHandler::Icon) ? pGraphicalViewsPage->getIconViewExtentBottom() : pGraphicalViewsPage->getDiagramViewExtentBottom();
119 const qreal right = (mViewType == StringHandler::Icon) ? pGraphicalViewsPage->getIconViewExtentRight() : pGraphicalViewsPage->getDiagramViewExtentRight();
120 const qreal top = (mViewType == StringHandler::Icon) ? pGraphicalViewsPage->getIconViewExtentTop() : pGraphicalViewsPage->getDiagramViewExtentTop();
121 if (!qFuzzyCompare(left, -100) || !qFuzzyCompare(bottom, -100) || !qFuzzyCompare(right, 100) || !qFuzzyCompare(top, 100)) {
122 mCoOrdinateSystem.setLeft(left);
123 mCoOrdinateSystem.setBottom(bottom);
124 mCoOrdinateSystem.setRight(right);
125 mCoOrdinateSystem.setTop(top);
126 }
127
128 const bool preserveAspectRatio = (mViewType == StringHandler::Icon) ? pGraphicalViewsPage->getIconViewPreserveAspectRation() : pGraphicalViewsPage->getDiagramViewPreserveAspectRation();
129 if (!preserveAspectRatio) {
130 mCoOrdinateSystem.setPreserveAspectRatio(preserveAspectRatio);
131 }
132
133 const qreal initialScale = (mViewType == StringHandler::Icon) ? pGraphicalViewsPage->getIconViewScaleFactor() : pGraphicalViewsPage->getDiagramViewScaleFactor();
134 if (!qFuzzyCompare(initialScale, 0.1)) {
135 mCoOrdinateSystem.setInitialScale(initialScale);
136 }
137
138 const qreal horizontal = (mViewType == StringHandler::Icon) ? pGraphicalViewsPage->getIconViewGridHorizontal() : pGraphicalViewsPage->getDiagramViewGridHorizontal();
139 const qreal vertical = (mViewType == StringHandler::Icon) ? pGraphicalViewsPage->getIconViewGridVertical() : pGraphicalViewsPage->getDiagramViewGridVertical();
140 if (!qFuzzyCompare(horizontal, 2) || !qFuzzyCompare(vertical, 2)) {
141 mCoOrdinateSystem.setHorizontal(horizontal);
142 mCoOrdinateSystem.setVertical(vertical);
143 }
144 setExtentRectangle(mCoOrdinateSystem.getExtentRectangle());
145 } else { // when opening a model use the default Modelica specification values
146 setExtentRectangle(mCoOrdinateSystem.getExtentRectangle());
147 }
148 mMergedCoOrdinateSystem = mCoOrdinateSystem;
149 scale(1.0, -1.0); // invert the drawing area.
150 setIsCustomScale(false);
151 setAddClassAnnotationNeeded(false);
152 setIsCreatingConnection(false);
153 setIsCreatingTransition(false);
154 mIsCreatingLineShape = false;
155 mIsCreatingPolygonShape = false;
156 mIsCreatingRectangleShape = false;
157 mIsCreatingEllipseShape = false;
158 mIsCreatingTextShape = false;
159 mIsCreatingBitmapShape = false;
160 mIsPanning = false;
161 mLastMouseEventPos = QPoint(0, 0);
162 mpClickedComponent = 0;
163 mpClickedState = 0;
164 setIsMovingComponentsAndShapes(false);
165 setRenderingLibraryPixmap(false);
166 mComponentsList.clear();
167 mOutOfSceneComponentsList.clear();
168 mConnectionsList.clear();
169 mOutOfSceneConnectionsList.clear();
170 mTransitionsList.clear();
171 mOutOfSceneTransitionsList.clear();
172 mInitialStatesList.clear();
173 mOutOfSceneInitialStatesList.clear();
174 mShapesList.clear();
175 mOutOfSceneShapesList.clear();
176 mInheritedComponentsList.clear();
177 mInheritedConnectionsList.clear();
178 mInheritedShapesList.clear();
179 mpConnectionLineAnnotation = 0;
180 mpTransitionLineAnnotation = 0;
181 mpLineShapeAnnotation = 0;
182 mpPolygonShapeAnnotation = 0;
183 mpRectangleShapeAnnotation = 0;
184 mpEllipseShapeAnnotation = 0;
185 mpTextShapeAnnotation = 0;
186 mpBitmapShapeAnnotation = 0;
187 createActions();
188 mAllItems.clear();
189}
190
191bool GraphicsView::isCreatingShape()
192{
193 return isCreatingLineShape() ||
194 isCreatingPolygonShape() ||
195 isCreatingRectangleShape() ||
196 isCreatingEllipseShape() ||
197 isCreatingBitmapShape() ||
198 isCreatingTextShape();
199}
200
201void GraphicsView::setExtentRectangle(const QRectF rectangle)
202{
203 // Yes the top of the rectangle is bottom for us since the coordinate system is inverted.
204 qreal left = rectangle.left();
205 qreal bottom = rectangle.top();
206 qreal right = rectangle.right();
207 qreal top = rectangle.bottom();
208 /* Ticket:4340 Extend vertical space
209 * Make the drawing area 25% bigger than the actual size. So we can better use the panning feature.
210 */
211 QRectF sceneRectangle(left * 1.5, bottom * 1.5, qFabs(left - right) * 1.5, qFabs(bottom - top) * 1.5);
212 setSceneRect(sceneRectangle);
213 centerOn(sceneRectangle.center());
214}
215
216void GraphicsView::setIsCreatingConnection(const bool enable)
217{
218 mIsCreatingConnection = enable;
219 setIsCreatingPrologue(enable);
220}
221
222void GraphicsView::setIsCreatingTransition(const bool enable)
223{
224 mIsCreatingTransition = enable;
225 setIsCreatingPrologue(enable);
226}
227
228void GraphicsView::setIsCreatingLineShape(const bool enable)
229{
230 mIsCreatingLineShape = enable;
231 setIsCreatingPrologue(enable);
232 updateUndoRedoActions(enable);
233}
234
235void GraphicsView::setIsCreatingPolygonShape(const bool enable)
236{
237 mIsCreatingPolygonShape = enable;
238 setIsCreatingPrologue(enable);
239 updateUndoRedoActions(enable);
240}
241
242void GraphicsView::setIsCreatingRectangleShape(const bool enable)
243{
244 mIsCreatingRectangleShape = enable;
245 setIsCreatingPrologue(enable);
246 updateUndoRedoActions(enable);
247}
248
249void GraphicsView::setIsCreatingEllipseShape(const bool enable)
250{
251 mIsCreatingEllipseShape = enable;
252 setIsCreatingPrologue(enable);
253 updateUndoRedoActions(enable);
254}
255
256void GraphicsView::setIsCreatingTextShape(const bool enable)
257{
258 mIsCreatingTextShape = enable;
259 setIsCreatingPrologue(enable);
260 updateUndoRedoActions(enable);
261}
262
263void GraphicsView::setIsCreatingBitmapShape(const bool enable)
264{
265 mIsCreatingBitmapShape = enable;
266 setIsCreatingPrologue(enable);
267 updateUndoRedoActions(enable);
268}
269
270void GraphicsView::setIsCreatingPrologue(const bool enable)
271{
272 setDragModeInternal(enable);
273 setItemsFlags(!enable);
274}
275
276void GraphicsView::setIsPanning(const bool enable)
277{
278 mIsPanning = enable;
279 setDragModeInternal(enable, true);
280 setItemsFlags(!enable);
281}
282
283void GraphicsView::setDragModeInternal(bool enable, bool updateCursor)
284{
285 if (enable) {
286 setDragMode(QGraphicsView::NoDrag);
287 if (updateCursor) {
288 viewport()->setCursor(Qt::ClosedHandCursor);
289 }
290 } else {
291 setDragMode(QGraphicsView::RubberBandDrag);
292 if (updateCursor) {
293 viewport()->unsetCursor();
294 }
295 }
296}
297
298void GraphicsView::setItemsFlags(bool enable)
299{
300 // set components, shapes and connection flags accordingly
301 foreach(Component *pComponent, mComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
302 pComponent->setComponentFlags(enable);
303 }
304 foreach(ShapeAnnotation *pShapeAnnotation, mShapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mShapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (ShapeAnnotation
*pShapeAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
305 pShapeAnnotation->setShapeFlags(enable);
306 }
307 foreach(LineAnnotation *pLineAnnotation, mConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pLineAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
308 pLineAnnotation->setShapeFlags(enable);
309 }
310}
311
312/*!
313 * \brief GraphicsView::updateUndoRedoActions
314 * Updates the Undo Redo actions depending shape(s) creation state.
315 * \param enable
316 */
317void GraphicsView::updateUndoRedoActions(bool enable)
318{
319 if (enable) {
320 MainWindow::instance()->getUndoAction()->setEnabled(!enable);
321 MainWindow::instance()->getRedoAction()->setEnabled(!enable);
322 } else {
323 mpModelWidget->updateUndoRedoActions();
324 }
325}
326
327bool GraphicsView::addComponent(QString className, QPointF position)
328{
329 MainWindow *pMainWindow = MainWindow::instance();
330 LibraryTreeItem *pLibraryTreeItem = pMainWindow->getLibraryWidget()->getLibraryTreeModel()->findLibraryTreeItem(className);
331 if (!pLibraryTreeItem) {
332 return false;
333 }
334 // if we are dropping something on meta-model editor then we can skip Modelica stuff.
335 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::CompositeModel) {
336 if (!pLibraryTreeItem->isSaved()) {
337 QMessageBox::information(pMainWindow, QString(Helper::applicationName).append(" - ").append(Helper::information),
338 tr("The class <b>%1</b> is not saved. You can only drag & drop saved classes.")
339 .arg(pLibraryTreeItem->getNameStructure()), Helper::ok);
340 return false;
341 } else {
342 // item not to be dropped on itself; if dropping an item on itself
343 if (isClassDroppedOnItself(pLibraryTreeItem)) {
344 return false;
345 }
346 QString name = getUniqueComponentName(StringHandler::toCamelCase(pLibraryTreeItem->getName()));
347 ComponentInfo *pComponentInfo = new ComponentInfo;
348 QFileInfo fileInfo(pLibraryTreeItem->getFileName());
349 // create StartCommand depending on the external model file extension.
350 if (fileInfo.suffix().compare("mo") == 0) {
351 pComponentInfo->setStartCommand("StartTLMOpenModelica");
352 } else if (fileInfo.suffix().compare("in") == 0) {
353 pComponentInfo->setStartCommand("StartTLMBeast");
354 } else if (fileInfo.suffix().compare("hmf") == 0) {
355 pComponentInfo->setStartCommand("StartTLMHopsan");
356 } else if (fileInfo.suffix().compare("fmu") == 0) {
357 pComponentInfo->setStartCommand("StartTLMFmiWrapper");
358 } else if (fileInfo.suffix().compare("slx") == 0) {
359 pComponentInfo->setStartCommand("StartTLMSimulink");
360 } else {
361 pComponentInfo->setStartCommand("");
362 }
363 pComponentInfo->setModelFile(fileInfo.fileName());
364 addComponentToView(name, pLibraryTreeItem, "", position, pComponentInfo, true, false, true);
365 return true;
366 }
367 } else {
368 // Only allow drag & drop of Modelica LibraryTreeItem on a Modelica LibraryTreeItem
369 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() != pLibraryTreeItem->getLibraryType()) {
370 QMessageBox::information(pMainWindow, QString("%1 - %2").arg(Helper::applicationName, Helper::information),
371 tr("You can only drag & drop Modelica models."), Helper::ok);
372 return false;
373 }
374 StringHandler::ModelicaClasses type = pLibraryTreeItem->getRestriction();
375 OptionsDialog *pOptionsDialog = OptionsDialog::instance();
376 // item not to be dropped on itself; if dropping an item on itself
377 if (isClassDroppedOnItself(pLibraryTreeItem)) {
378 return false;
379 } else { // check if the model is partial
380 if (pLibraryTreeItem->isPartial()) {
381 if (pOptionsDialog->getNotificationsPage()->getReplaceableIfPartialCheckBox()->isChecked()) {
382 NotificationsDialog *pNotificationsDialog = new NotificationsDialog(NotificationsDialog::ReplaceableIfPartial,
383 NotificationsDialog::InformationIcon,
384 MainWindow::instance());
385 pNotificationsDialog->setNotificationLabelString(GUIMessages::getMessage(GUIMessages::MAKE_REPLACEABLE_IF_PARTIAL)
386 .arg(StringHandler::getModelicaClassType(type).toLower()).arg(pLibraryTreeItem->getName()));
387 if (!pNotificationsDialog->exec()) {
388 return false;
389 }
390 }
391 }
392 // get the model defaultComponentPrefixes
393 QString defaultPrefix = pMainWindow->getOMCProxy()->getDefaultComponentPrefixes(pLibraryTreeItem->getNameStructure());
394 // get the model defaultComponentName
395 QString defaultName = pMainWindow->getOMCProxy()->getDefaultComponentName(pLibraryTreeItem->getNameStructure());
396 QString name;
397 if (!defaultName.isEmpty()) {
398 name = getUniqueComponentName(StringHandler::toCamelCase(defaultName));
399 } else {
400 name = getUniqueComponentName(StringHandler::toCamelCase(pLibraryTreeItem->getName()));
401 }
402 // Allow user to change the component name if always ask for component name settings is true.
403 if (pOptionsDialog->getNotificationsPage()->getAlwaysAskForDraggedComponentName()->isChecked()) {
404 ComponentNameDialog *pComponentNameDialog = new ComponentNameDialog(name, this, pMainWindow);
405 if (pComponentNameDialog->exec()) {
406 name = pComponentNameDialog->getComponentName();
407 pComponentNameDialog->deleteLater();
408 } else {
409 pComponentNameDialog->deleteLater();
410 return false;
411 }
412 }
413 // if we or user has changed the default name
414 if (!defaultName.isEmpty() && name.compare(defaultName) != 0) {
415 // show the information to the user if we have changed the name of some inner component.
416 if (defaultPrefix.contains("inner")) {
417 if (pOptionsDialog->getNotificationsPage()->getInnerModelNameChangedCheckBox()->isChecked()) {
418 NotificationsDialog *pNotificationsDialog = new NotificationsDialog(NotificationsDialog::InnerModelNameChanged,
419 NotificationsDialog::InformationIcon,
420 MainWindow::instance());
421 pNotificationsDialog->setNotificationLabelString(GUIMessages::getMessage(GUIMessages::INNER_MODEL_NAME_CHANGED)
422 .arg(defaultName).arg(name));
423 if (!pNotificationsDialog->exec()) {
424 return false;
425 }
426 }
427 }
428 }
429 ComponentInfo *pComponentInfo = new ComponentInfo;
430 pComponentInfo->applyDefaultPrefixes(defaultPrefix);
431 // if dropping an item on the diagram layer
432 if (mViewType == StringHandler::Diagram) {
433 // if item is a class, model, block, connector or record. then we can drop it to the graphicsview
434 if ((type == StringHandler::Class) || (type == StringHandler::Model) || (type == StringHandler::Block) ||
435 (type == StringHandler::ExpandableConnector) || (type == StringHandler::Connector) || (type == StringHandler::Record)) {
436 addComponentToView(name, pLibraryTreeItem, "", position, pComponentInfo, true, false, true);
437 return true;
438 } else {
439 QMessageBox::information(pMainWindow, QString(Helper::applicationName).append(" - ").append(Helper::information),
440 GUIMessages::getMessage(GUIMessages::DIAGRAM_VIEW_DROP_MSG).arg(pLibraryTreeItem->getNameStructure())
441 .arg(StringHandler::getModelicaClassType(type)), Helper::ok);
442 return false;
443 }
444 } else if (mViewType == StringHandler::Icon) { // if dropping an item on the icon layer
445 // if item is a connector. then we can drop it to the graphicsview
446 if (type == StringHandler::Connector || type == StringHandler::ExpandableConnector) {
447 addComponentToView(name, pLibraryTreeItem, "", position, pComponentInfo, true, false, true);
448 return true;
449 } else {
450 QMessageBox::information(pMainWindow, QString(Helper::applicationName).append(" - ").append(Helper::information),
451 GUIMessages::getMessage(GUIMessages::ICON_VIEW_DROP_MSG).arg(pLibraryTreeItem->getNameStructure())
452 .arg(StringHandler::getModelicaClassType(type)), Helper::ok);
453 return false;
454 }
455 }
456 }
457 }
458 return false;
459}
460
461/*!
462 * \brief GraphicsView::addComponentToView
463 * Adds the Component to the Graphical Views.
464 * \param name
465 * \param pLibraryTreeItem
466 * \param annotation
467 * \param position
468 * \param pComponentInfo
469 * \param addObject
470 * \param openingClass
471 * \param emitComponentAdded
472 */
473void GraphicsView::addComponentToView(QString name, LibraryTreeItem *pLibraryTreeItem, QString annotation, QPointF position,
474 ComponentInfo *pComponentInfo, bool addObject, bool openingClass, bool emitComponentAdded)
475{
476 AddComponentCommand *pAddComponentCommand;
477 pAddComponentCommand = new AddComponentCommand(name, pLibraryTreeItem, annotation, position, pComponentInfo, addObject, openingClass, this);
478 mpModelWidget->getUndoStack()->push(pAddComponentCommand);
479 if (emitComponentAdded) {
480 mpModelWidget->getLibraryTreeItem()->emitComponentAdded(pAddComponentCommand->getComponent());
481 }
482 if (!openingClass) {
483 mpModelWidget->updateModelText();
484 }
485}
486
487void GraphicsView::addComponentToClass(Component *pComponent)
488{
489 if (mpModelWidget->getLibraryTreeItem()->getLibraryType()== LibraryTreeItem::Modelica) {
490 MainWindow *pMainWindow = MainWindow::instance();
491 // Add the component to model in OMC.
492 /* Ticket:4132
493 * Always send the full path so that addComponent API doesn't fail when it makes a call to getDefaultPrefixes.
494 * I updated the addComponent API to make path relative.
495 */
496 pMainWindow->getOMCProxy()->addComponent(pComponent->getName(), pComponent->getComponentInfo()->getClassName(),
497 mpModelWidget->getLibraryTreeItem()->getNameStructure(), pComponent->getPlacementAnnotation());
498 LibraryTreeModel *pLibraryTreeModel = pMainWindow->getLibraryWidget()->getLibraryTreeModel();
499 // get the toplevel class of dragged component
500 QString packageName = StringHandler::getFirstWordBeforeDot(pComponent->getLibraryTreeItem()->getNameStructure());
501 LibraryTreeItem *pPackageLibraryTreeItem = pLibraryTreeModel->findLibraryTreeItem(packageName);
502 // get the top level class of current class
503 QString topLevelClassName = StringHandler::getFirstWordBeforeDot(mpModelWidget->getLibraryTreeItem()->getNameStructure());
504 LibraryTreeItem *pTopLevelLibraryTreeItem = pLibraryTreeModel->findLibraryTreeItem(topLevelClassName);
505 if (pPackageLibraryTreeItem && pTopLevelLibraryTreeItem) {
506 // get uses annotation of the toplevel class
507 QList<QList<QString > > usesAnnotation = pMainWindow->getOMCProxy()->getUses(pTopLevelLibraryTreeItem->getNameStructure());
508 QStringList newUsesAnnotation;
509 for (int i = 0 ; i < usesAnnotation.size() ; i++) {
510 if (usesAnnotation.at(i).at(0).compare(packageName) == 0) {
511 return; // if the package is already in uses annotation of class then simply return without doing anything.
512 } else {
513 newUsesAnnotation.append(QString("%1(version=\"%2\")").arg(usesAnnotation.at(i).at(0)).arg(usesAnnotation.at(i).at(1)));
514 }
515 }
516 // if the package has version only then add the uses annotation
517 if (!pPackageLibraryTreeItem->mClassInformation.version.isEmpty() &&
518 // Do not add a uses-annotation to itself
519 pTopLevelLibraryTreeItem->getNameStructure() != packageName) {
520 newUsesAnnotation.append(QString("%1(version=\"%2\")").arg(packageName).arg(pPackageLibraryTreeItem->mClassInformation.version));
521 QString usesAnnotationString = QString("annotate=$annotation(uses(%1))").arg(newUsesAnnotation.join(","));
522 pMainWindow->getOMCProxy()->addClassAnnotation(pTopLevelLibraryTreeItem->getNameStructure(), usesAnnotationString);
523 }
524 }
525 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType()== LibraryTreeItem::CompositeModel) {
526 // add SubModel Element
527 CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpModelWidget->getEditor());
528 pCompositeModelEditor->addSubModel(pComponent);
529 /* We need to iterate over Component childrens
530 * because if user deletes a submodel for which interfaces are already fetched
531 * then undoing the delete operation reaches here and we should add the interfaces back.
532 */
533 foreach (Component *pInterfaceComponent, pComponent->getComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pComponent
->getComponentsList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pInterfaceComponent = *_container_.i; _container_
.control; _container_.control = 0)
{
534 pCompositeModelEditor->addInterface(pInterfaceComponent, pComponent->getName());
535 }
536 }
537}
538
539/*!
540 * \brief GraphicsView::deleteComponent
541 * Delete the component and its corresponding connections from the components list and OMC.
542 * \param component is the object to be deleted.
543 */
544void GraphicsView::deleteComponent(Component *pComponent)
545{
546 // First Remove the connections associated to this component
547 int i = 0;
548 while(i != mConnectionsList.size()) {
549 QString startComponentName = StringHandler::getFirstWordBeforeDot(mConnectionsList[i]->getStartComponentName());
550 if (startComponentName.contains("[")) {
551 startComponentName = startComponentName.mid(0, startComponentName.indexOf("["));
552 }
553 QString endComponentName = StringHandler::getFirstWordBeforeDot(mConnectionsList[i]->getEndComponentName());
554 if (endComponentName.contains("[")) {
555 endComponentName = endComponentName.mid(0, endComponentName.indexOf("["));
556 }
557 if (startComponentName == pComponent->getName() || endComponentName == pComponent->getName()) {
558 deleteConnection(mConnectionsList[i]);
559 i = 0; //Restart iteration if map has changed
560 } else {
561 ++i;
562 }
563 }
564 pComponent->setSelected(false);
565 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
566 mpModelWidget->getUndoStack()->push(new DeleteSubModelCommand(pComponent, this));
567 } else {
568 mpModelWidget->getUndoStack()->push(new DeleteComponentCommand(pComponent, this));
569 }
570
571}
572
573/*!
574 * \brief GraphicsView::deleteComponentObject
575 * Deletes the Component.
576 * \param pComponent
577 */
578void GraphicsView::deleteComponentFromClass(Component *pComponent)
579{
580 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
581 OMCProxy *pOMCProxy = MainWindow::instance()->getOMCProxy();
582 // delete the component from OMC
583 pOMCProxy->deleteComponent(pComponent->getName(), mpModelWidget->getLibraryTreeItem()->getNameStructure());
584 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType()== LibraryTreeItem::CompositeModel) {
585 CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpModelWidget->getEditor());
586 pCompositeModelEditor->deleteSubModel(pComponent->getName());
587 }
588}
589
590/*!
591 * \brief GraphicsView::getComponentObject
592 * Finds the Component
593 * \param componentName
594 * \return
595 */
596Component* GraphicsView::getComponentObject(QString componentName)
597{
598 // look in inherited components
599 foreach (Component *pInheritedComponent, mInheritedComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInheritedComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pInheritedComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
600 if (pInheritedComponent->getName().compare(componentName) == 0) {
601 return pInheritedComponent;
602 }
603 }
604 // look in components
605 foreach (Component *pComponent, mComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
606 if (pComponent->getName().compare(componentName) == 0) {
607 return pComponent;
608 }
609 }
610 return 0;
611}
612
613/*!
614 * \brief GraphicsView::getUniqueComponentName
615 * Creates a unique component name.
616 * \param componentName
617 * \param number
618 * \return
619 */
620QString GraphicsView::getUniqueComponentName(QString componentName, int number)
621{
622 QString name = componentName;
623 if (number > 0) {
624 name = QString("%1%2").arg(componentName).arg(number);
625 }
626
627 if (!checkComponentName(name)) {
628 name = getUniqueComponentName(componentName, ++number);
629 }
630 return name;
631}
632
633/*!
634 * \brief GraphicsView::checkComponentName
635 * Checks the component name against the Modelica keywords as well.
636 * Checks if the component with the same name already exists or not.
637 * \param componentName
638 * \return
639 */
640bool GraphicsView::checkComponentName(QString componentName)
641{
642 // if component name is any keyword of Modelica
643 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
644 if (ModelicaHighlighter::getKeywords().contains(componentName)) {
645 return false;
646 }
647 }
648 // if component with same name exists
649 foreach (Component *pComponent, mComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
650 if (pComponent->getName().compare(componentName, Qt::CaseSensitive) == 0) {
651 return false;
652 }
653 }
654 return true;
655}
656
657/*!
658 * \brief updateConnectionIndexes
659 * Updates the connection indexes in the connection name with the passed index.
660 * \param connectionComponentName
661 * \param componentConnectionIndex
662 * \return
663 */
664QString updateConnectionIndexes(const QString &connectionComponentName, int &componentConnectionIndex) {
665 QString newConnectionComponentName = "";
666 int endIndex = connectionComponentName.lastIndexOf(']');
667 int startIndex = connectionComponentName.lastIndexOf('[', endIndex);
668 if (startIndex > -1 && endIndex > -1) {
669 newConnectionComponentName = connectionComponentName.left(startIndex);
670 newConnectionComponentName += "[";
671 QStringList range = connectionComponentName.mid(startIndex + 1, endIndex - startIndex - 1).split(':');
672 if (range.size() > 1) {
673 newConnectionComponentName += QString("%1:%2").arg(componentConnectionIndex).arg(componentConnectionIndex + (range.at(1).toInt() - range.at(0).toInt()));
674 componentConnectionIndex = componentConnectionIndex + (range.at(1).toInt() - range.at(0).toInt());
675 } else {
676 newConnectionComponentName += QString("%1").arg(componentConnectionIndex);
677 }
678 newConnectionComponentName += "]";
679 }
680 return newConnectionComponentName;
681}
682
683/*!
684 * \brief GraphicsView::addConnectionToClass
685 * Adds the connection to class.
686 * \param pConnectionLineAnnotation - the connection to add.
687 * \param deleteUndo - True when undo of a delete connection is called.
688 * \return
689 */
690bool GraphicsView::addConnectionToClass(LineAnnotation *pConnectionLineAnnotation, bool deleteUndo)
691{
692 if (mpModelWidget->getLibraryTreeItem()->getLibraryType()== LibraryTreeItem::CompositeModel) {
693 CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpModelWidget->getEditor());
694 if (pCompositeModelEditor) {
695 pCompositeModelEditor->createConnection(pConnectionLineAnnotation);
696 }
697 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType()== LibraryTreeItem::OMS) {
698 // if TLM connection
699 bool connectionSuccessful = false;
700 if (pConnectionLineAnnotation->getOMSConnectionType() == oms_connection_tlm) {
701 connectionSuccessful = OMSProxy::instance()->addTLMConnection(pConnectionLineAnnotation->getStartComponentName(), pConnectionLineAnnotation->getEndComponentName(),
702 pConnectionLineAnnotation->getDelay().toDouble(), pConnectionLineAnnotation->getAlpha().toDouble(),
703 pConnectionLineAnnotation->getZf().toDouble(), pConnectionLineAnnotation->getZfr().toDouble());
704 } else {
705 connectionSuccessful = OMSProxy::instance()->addConnection(pConnectionLineAnnotation->getStartComponentName(), pConnectionLineAnnotation->getEndComponentName());
706 }
707 if (connectionSuccessful) {
708 pConnectionLineAnnotation->updateOMSConnection();
709 return true;
710 } else {
711 removeCurrentConnection();
712 return false;
713 }
714 } else {
715 MainWindow *pMainWindow = MainWindow::instance();
716 // update connectorSizing on start component if exists
717 bool isStartComponentConnectorSizing = GraphicsView::updateComponentConnectorSizingParameter(this, mpModelWidget->getLibraryTreeItem()->getNameStructure(), pConnectionLineAnnotation->getStartComponent());
718 // update connectorSizing on end component if exists
719 bool isEndComponentConnectorSizing = GraphicsView::updateComponentConnectorSizingParameter(this, mpModelWidget->getLibraryTreeItem()->getNameStructure(), pConnectionLineAnnotation->getEndComponent());
720 if (deleteUndo) {
721 if (isStartComponentConnectorSizing) {
722 int connectionIndex = numberOfComponentConnections(pConnectionLineAnnotation->getStartComponent(), pConnectionLineAnnotation) + 1;
723 QString newStartComponentName = updateConnectionIndexes(pConnectionLineAnnotation->getStartComponentName(), connectionIndex);
724 if (!newStartComponentName.isEmpty()) {
725 pConnectionLineAnnotation->setStartComponentName(newStartComponentName);
726 pConnectionLineAnnotation->updateToolTip();
727 }
728 }
729 if (isEndComponentConnectorSizing) {
730 int connectionIndex = numberOfComponentConnections(pConnectionLineAnnotation->getEndComponent(), pConnectionLineAnnotation) + 1;
731 QString newEndComponentName = updateConnectionIndexes(pConnectionLineAnnotation->getEndComponentName(), connectionIndex);
732 if (!newEndComponentName.isEmpty()) {
733 pConnectionLineAnnotation->setEndComponentName(newEndComponentName);
734 pConnectionLineAnnotation->updateToolTip();
735 }
736 }
737 }
738 // add connection
739 if (pMainWindow->getOMCProxy()->addConnection(pConnectionLineAnnotation->getStartComponentName(), pConnectionLineAnnotation->getEndComponentName(),
740 mpModelWidget->getLibraryTreeItem()->getNameStructure(), QString("annotate=").append(pConnectionLineAnnotation->getShapeAnnotation()))) {
741 /* Ticket #2450
742 * Do not check for the ports compatibility via instantiatemodel. Just let the user create the connection.
743 */
744 //pMainWindow->getOMCProxy()->instantiateModelSucceeds(mpModelWidget->getNameStructure());
745 }
746 }
747 return true;
748}
749
750/*!
751 * \brief componentIndexesRangeInConnection
752 * Returns the component array index in connection.
753 * It could be just index or range e.g., 1:3
754 * \param connectionComponentName
755 * \return
756 */
757QStringList componentIndexesRangeInConnection(const QString &connectionComponentName)
758{
759 int endIndex = connectionComponentName.lastIndexOf(']');
760 int startIndex = connectionComponentName.lastIndexOf('[', endIndex);
761 if (startIndex > -1 && endIndex > -1) {
762 return connectionComponentName.mid(startIndex + 1, endIndex - startIndex - 1).split(':');
763 }
764 return QStringList();
765}
766
767/*!
768 * \brief componentIndexInConnection
769 * Return the component array index used in connection.
770 * If the index is range then the start of range is returned e.g., 1:3 returns 1 and 2:4 returns 2.
771 * \param connectionComponentName
772 * \return
773 */
774int componentIndexInConnection(const QString &connectionComponentName)
775{
776 QStringList range = componentIndexesRangeInConnection(connectionComponentName);
777 return range.value(0, "0").toInt();
778}
779
780/*!
781 * \brief GraphicsView::deleteConnectionFromClass
782 * Deletes the connection from class.
783 * \param pConnectionLineAnnotation - the connection to delete.
784 */
785void GraphicsView::deleteConnectionFromClass(LineAnnotation *pConnectionLineAnnotation)
786{
787 MainWindow *pMainWindow = MainWindow::instance();
788 if (mpModelWidget->getLibraryTreeItem()->getLibraryType()== LibraryTreeItem::CompositeModel) {
789 CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpModelWidget->getEditor());
790 pCompositeModelEditor->deleteConnection(pConnectionLineAnnotation->getStartComponentName(), pConnectionLineAnnotation->getEndComponentName());
791 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType()== LibraryTreeItem::OMS) {
792 OMSProxy::instance()->deleteConnection(pConnectionLineAnnotation->getStartComponentName(), pConnectionLineAnnotation->getEndComponentName());
793 } else {
794 // delete the connection
795 if (pMainWindow->getOMCProxy()->deleteConnection(pConnectionLineAnnotation->getStartComponentName(), pConnectionLineAnnotation->getEndComponentName(), mpModelWidget->getLibraryTreeItem()->getNameStructure())) {
796 // update connectorSizing on start component if exists
797 bool isStartComponentConnectorSizing = GraphicsView::updateComponentConnectorSizingParameter(this, mpModelWidget->getLibraryTreeItem()->getNameStructure(), pConnectionLineAnnotation->getStartComponent());
798 // update connectorSizing on end component if exists
799 bool isEndComponentConnectorSizing = GraphicsView::updateComponentConnectorSizingParameter(this, mpModelWidget->getLibraryTreeItem()->getNameStructure(), pConnectionLineAnnotation->getEndComponent());
800 // if the component is connectorSizing then get the index used in deleted connection
801 int startConnectionIndex = 0;
802 if (isStartComponentConnectorSizing) {
803 startConnectionIndex = componentIndexInConnection(pConnectionLineAnnotation->getStartComponentName());
804 }
805 int endConnectionIndex = 0;
806 if (isEndComponentConnectorSizing) {
807 endConnectionIndex = componentIndexInConnection(pConnectionLineAnnotation->getEndComponentName());
808 }
809 if (isStartComponentConnectorSizing || isEndComponentConnectorSizing) {
810 // update the connections if some middle connectorSizing connection is removed
811 foreach (LineAnnotation *pOtherConnectionLineAnnotation, mConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pOtherConnectionLineAnnotation = *_container_.i; _container_
.control; _container_.control = 0)
{
812 // if deleted connection then continue
813 if (pOtherConnectionLineAnnotation == pConnectionLineAnnotation) {
814 continue;
815 }
816 bool updateConnection = false;
817 // start component matches
818 QString startComponentName = pOtherConnectionLineAnnotation->getStartComponentName();
819 if (pOtherConnectionLineAnnotation->getStartComponent() == pConnectionLineAnnotation->getStartComponent()) {
820 if (componentIndexInConnection(startComponentName) > startConnectionIndex) {
821 pOtherConnectionLineAnnotation->setStartComponentName(updateConnectionIndexes(startComponentName, startConnectionIndex));
822 startConnectionIndex++;
823 updateConnection = true;
824 }
825 }
826 if (pOtherConnectionLineAnnotation->getStartComponent() == pConnectionLineAnnotation->getEndComponent()) {
827 if (componentIndexInConnection(startComponentName) > endConnectionIndex) {
828 pOtherConnectionLineAnnotation->setStartComponentName(updateConnectionIndexes(startComponentName, endConnectionIndex));
829 endConnectionIndex++;
830 updateConnection = true;
831 }
832 }
833 // end component matches
834 QString endComponentName = pOtherConnectionLineAnnotation->getEndComponentName();
835 if (pOtherConnectionLineAnnotation->getEndComponent() == pConnectionLineAnnotation->getEndComponent()) {
836 if (componentIndexInConnection(endComponentName) > endConnectionIndex) {
837 pOtherConnectionLineAnnotation->setEndComponentName(updateConnectionIndexes(endComponentName, endConnectionIndex));
838 endConnectionIndex++;
839 updateConnection = true;
840 }
841 }
842 if (pOtherConnectionLineAnnotation->getEndComponent() == pConnectionLineAnnotation->getStartComponent()) {
843 if (componentIndexInConnection(endComponentName) > startConnectionIndex) {
844 pOtherConnectionLineAnnotation->setEndComponentName(updateConnectionIndexes(endComponentName, startConnectionIndex));
845 startConnectionIndex++;
846 updateConnection = true;
847 }
848 }
849 // update the connection with updated connectorSizing indexes.
850 if (updateConnection) {
851 pMainWindow->getOMCProxy()->updateConnectionNames(mpModelWidget->getLibraryTreeItem()->getNameStructure(), startComponentName, endComponentName,
852 pOtherConnectionLineAnnotation->getStartComponentName(), pOtherConnectionLineAnnotation->getEndComponentName());
853 pOtherConnectionLineAnnotation->updateToolTip();
854 }
855 }
856 }
857 }
858 }
859}
860
861/*!
862 * \brief GraphicsView::updateConnectionInClass
863 * Updates a connection in a class.
864 * \param pConnectonLineAnnotation
865 */
866void GraphicsView::updateConnectionInClass(LineAnnotation *pConnectionLineAnnotation)
867{
868 if (mpModelWidget->getLibraryTreeItem()->getLibraryType()== LibraryTreeItem::CompositeModel) {
869 CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpModelWidget->getEditor());
870 if (pCompositeModelEditor) {
871 pCompositeModelEditor->updateConnection(pConnectionLineAnnotation);
872 }
873 }
874}
875
876/*!
877 * \brief GraphicsView::removeConnectionsFromView
878 * Removes the connections from the view.
879 */
880void GraphicsView::removeConnectionsFromView()
881{
882 foreach (LineAnnotation *pConnectionLineAnnotation, mConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pConnectionLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
883 deleteConnectionFromList(pConnectionLineAnnotation);
884 removeItem(pConnectionLineAnnotation);
885 }
886}
887
888/*!
889 * \brief GraphicsView::numberOfComponentConnections
890 * Counts the number of connections of the component.
891 * \param pComponent
892 * \param pExcludeConnectionLineAnnotation
893 * \return
894 */
895int GraphicsView::numberOfComponentConnections(Component *pComponent, LineAnnotation *pExcludeConnectionLineAnnotation)
896{
897 int connections = 0;
898 foreach (LineAnnotation *pConnectionLineAnnotation, mConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pConnectionLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
899 if (pExcludeConnectionLineAnnotation && pExcludeConnectionLineAnnotation == pConnectionLineAnnotation) {
900 continue;
901 }
902 if (pConnectionLineAnnotation->getStartComponent() == pComponent || pConnectionLineAnnotation->getEndComponent() == pComponent) {
903 // always count one connection if we are in here. Then look for array connections.
904 connections++;
905 QString connectionComponentName;
906 if (pConnectionLineAnnotation->getStartComponent() == pComponent) {
907 connectionComponentName = pConnectionLineAnnotation->getStartComponentName();
908 } else {
909 connectionComponentName = pConnectionLineAnnotation->getEndComponentName();
910 }
911 QStringList range = componentIndexesRangeInConnection(connectionComponentName);
912 if (range.size() > 1) {
913 connections += (range.at(1).toInt() - range.at(0).toInt());
914 }
915 }
916 }
917 return connections;
918}
919
920/*!
921 * \brief GraphicsView::addTransitionToClass
922 * Adds the transition to class.
923 * \param pTransitionLineAnnotation - the transition to add.
924 */
925void GraphicsView::addTransitionToClass(LineAnnotation *pTransitionLineAnnotation)
926{
927 OMCProxy *pOMCProxy = MainWindow::instance()->getOMCProxy();
928 if (pOMCProxy->addTransition(mpModelWidget->getLibraryTreeItem()->getNameStructure(), pTransitionLineAnnotation->getStartComponentName(),
929 pTransitionLineAnnotation->getEndComponentName(), pTransitionLineAnnotation->getCondition(),
930 pTransitionLineAnnotation->getImmediate(), pTransitionLineAnnotation->getReset(),
931 pTransitionLineAnnotation->getSynchronize(), pTransitionLineAnnotation->getPriority(),
932 QString("annotate=$annotation(%1,%2)").arg(pTransitionLineAnnotation->getShapeAnnotation())
933 .arg(pTransitionLineAnnotation->getTextAnnotation()->getShapeAnnotation()))) {
934 }
935}
936
937/*!
938 * \brief GraphicsView::deleteTransitionFromClass
939 * Deletes the transition from class.
940 * \param pTransitionLineAnnotation - the transition to delete.
941 */
942void GraphicsView::deleteTransitionFromClass(LineAnnotation *pTransitionLineAnnotation)
943{
944 OMCProxy *pOMCProxy = MainWindow::instance()->getOMCProxy();
945 pOMCProxy->deleteTransition(mpModelWidget->getLibraryTreeItem()->getNameStructure(), pTransitionLineAnnotation->getStartComponentName(),
946 pTransitionLineAnnotation->getEndComponentName(), pTransitionLineAnnotation->getCondition(),
947 pTransitionLineAnnotation->getImmediate(), pTransitionLineAnnotation->getReset(),
948 pTransitionLineAnnotation->getSynchronize(), pTransitionLineAnnotation->getPriority());
949}
950
951/*!
952 * \brief GraphicsView::removeTransitionsFromView
953 * Removes the transitions from the view.
954 */
955void GraphicsView::removeTransitionsFromView()
956{
957 foreach (LineAnnotation *pTransitionLineAnnotation, mTransitionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mTransitionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pTransitionLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
958 deleteTransitionFromList(pTransitionLineAnnotation);
959 removeItem(pTransitionLineAnnotation);
960 }
961}
962
963/*!
964 * \brief GraphicsView::addInitialStateToClass
965 * Adds the initial state to class.
966 * \param pInitialStateLineAnnotation - the initial state to add.
967 */
968void GraphicsView::addInitialStateToClass(LineAnnotation *pInitialStateLineAnnotation)
969{
970 OMCProxy *pOMCProxy = MainWindow::instance()->getOMCProxy();
971 if (pOMCProxy->addInitialState(mpModelWidget->getLibraryTreeItem()->getNameStructure(),
972 pInitialStateLineAnnotation->getStartComponentName(),
973 QString("annotate=").append(pInitialStateLineAnnotation->getShapeAnnotation()))) {
974 }
975}
976
977/*!
978 * \brief GraphicsView::deleteInitialStateFromClass
979 * Deletes the initial state from class.
980 * \param pInitialStateLineAnnotation - the initial state to delete.
981 */
982void GraphicsView::deleteInitialStateFromClass(LineAnnotation *pInitialStateLineAnnotation)
983{
984 OMCProxy *pOMCProxy = MainWindow::instance()->getOMCProxy();
985 pOMCProxy->deleteInitialState(mpModelWidget->getLibraryTreeItem()->getNameStructure(), pInitialStateLineAnnotation->getStartComponentName());
986}
987
988/*!
989 * \brief GraphicsView::removeInitialStatesFromView
990 * Removes the initial states from the view.
991 */
992void GraphicsView::removeInitialStatesFromView()
993{
994 foreach (LineAnnotation *pInitialStateLineAnnotation, mInitialStatesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInitialStatesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pInitialStateLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
995 deleteInitialStateFromList(pInitialStateLineAnnotation);
996 removeItem(pInitialStateLineAnnotation);
997 }
998}
999
1000/*!
1001 * \brief GraphicsView::addShapeToList
1002 * \param pShape
1003 * \param index
1004 */
1005void GraphicsView::addShapeToList(ShapeAnnotation *pShape, int index)
1006{
1007 if (index <= -1) {
1008 mShapesList.append(pShape);
1009 } else {
1010 mShapesList.insert(index, pShape);
1011 }
1012}
1013
1014/*!
1015 * \brief GraphicsView::deleteShape
1016 * Deletes the shape from the icon/diagram layer.
1017 * \param pShapeAnnotation
1018 */
1019void GraphicsView::deleteShape(ShapeAnnotation *pShapeAnnotation)
1020{
1021 pShapeAnnotation->setSelected(false);
1022 mpModelWidget->getUndoStack()->push(new DeleteShapeCommand(pShapeAnnotation));
1023}
1024
1025/*!
1026 * \brief GraphicsView::deleteShapeFromList
1027 * \param pShape
1028 * \return
1029 */
1030int GraphicsView::deleteShapeFromList(ShapeAnnotation *pShape)
1031{
1032 int index = mShapesList.indexOf(pShape);
1033 mShapesList.removeOne(pShape);
1034 return index;
1035}
1036
1037/*!
1038 * \brief GraphicsView::reOrderShapes
1039 * Reorders the shapes.
1040 */
1041void GraphicsView::reOrderShapes()
1042{
1043 int zValue = 0;
1044 // set stacking order for inherited shapes
1045 foreach (ShapeAnnotation *pShapeAnnotation, mInheritedShapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInheritedShapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (ShapeAnnotation
*pShapeAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
1046 zValue++;
1047 pShapeAnnotation->setZValue(zValue);
1048 }
1049 // set stacking order for shapes.
1050 foreach (ShapeAnnotation *pShapeAnnotation, mShapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mShapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (ShapeAnnotation
*pShapeAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
1051 zValue++;
1052 pShapeAnnotation->setZValue(zValue);
1053 }
1054}
1055
1056/*!
1057 * \brief GraphicsView::bringToFront
1058 * \param pShape
1059 * Brings the shape to front of all other shapes.
1060 */
1061void GraphicsView::bringToFront(ShapeAnnotation *pShape)
1062{
1063 deleteShapeFromList(pShape);
1064 int i = 0;
1065 // update the shapes z index
1066 for (; i < mShapesList.size() ; i++) {
1067 mShapesList.at(i)->setZValue(i + 1);
1068 }
1069 pShape->setZValue(i + 1);
1070 mShapesList.append(pShape);
1071 // update class annotation.
1072 addClassAnnotation();
1073}
1074
1075/*!
1076 * \brief GraphicsView::bringForward
1077 * \param pShape
1078 * Brings the shape one level forward.
1079 */
1080void GraphicsView::bringForward(ShapeAnnotation *pShape)
1081{
1082 int shapeIndex = mShapesList.indexOf(pShape);
1083 if (shapeIndex == -1 || shapeIndex == mShapesList.size() - 1) { // if the shape is already at top.
1084 return;
1085 }
1086 // swap the shapes in the list
1087 mShapesList.swap(shapeIndex, shapeIndex + 1);
1088 // update the shapes z index
1089 for (int i = 0 ; i < mShapesList.size() ; i++) {
1090 mShapesList.at(i)->setZValue(i + 1);
1091 }
1092 // update class annotation.
1093 addClassAnnotation();
1094}
1095
1096/*!
1097 * \brief GraphicsView::sendToBack
1098 * \param pShape
1099 * Sends the shape to back of all other shapes.
1100 */
1101void GraphicsView::sendToBack(ShapeAnnotation *pShape)
1102{
1103 deleteShapeFromList(pShape);
1104 int i = 0;
1105 pShape->setZValue(i + 1);
1106 mShapesList.prepend(pShape);
1107 // update the shapes z index
1108 for (i = 1 ; i < mShapesList.size() ; i++) {
1109 mShapesList.at(i)->setZValue(i + 1);
1110 }
1111 // update class annotation.
1112 addClassAnnotation();
1113}
1114
1115/*!
1116 * \brief GraphicsView::sendBackward
1117 * \param pShape
1118 * Sends the shape one level backward.
1119 */
1120void GraphicsView::sendBackward(ShapeAnnotation *pShape)
1121{
1122 int shapeIndex = mShapesList.indexOf(pShape);
1123 if (shapeIndex <= 0) { // if the shape is already at bottom.
1124 return;
1125 }
1126 // swap the shapes in the list
1127 mShapesList.swap(shapeIndex - 1, shapeIndex);
1128 // update the shapes z index
1129 for (int i = 0 ; i < mShapesList.size() ; i++) {
1130 mShapesList.at(i)->setZValue(i + 1);
1131 }
1132 // update class annotation.
1133 addClassAnnotation();
1134}
1135
1136/*!
1137 * \brief GraphicsView::clearGraphicsView
1138 * Clears everything from the GraphicsView.
1139 */
1140void GraphicsView::clearGraphicsView()
1141{
1142 removeAllShapes();
1143 removeOutOfSceneShapes();
1144 removeAllConnections();
1145 removeOutOfSceneConnections();
1146 removeAllTransitions();
1147 removeOutOfSceneTransitions();
1148 removeAllInitialStates();
1149 removeOutOfSceneInitialStates();
1150 removeClassComponents();
1151 removeOutOfSceneClassComponents();
1152 removeInheritedClassShapes();
1153 removeInheritedClassConnections();
1154 removeInheritedClassComponents();
1155 scene()->clear();
1156 mAllItems.clear();
1157}
1158
1159/*!
1160 * \brief GraphicsView::removeClassComponents
1161 * Removes all the class components.
1162 */
1163void GraphicsView::removeClassComponents()
1164{
1165 foreach (Component *pComponent, mComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
1166 pComponent->removeChildren();
1167 deleteComponentFromList(pComponent);
1168 removeItem(pComponent->getOriginItem());
1169 delete pComponent->getOriginItem();
1170 removeItem(pComponent);
1171 pComponent->emitDeleted();
1172 delete pComponent;
1173 }
1174}
1175
1176/*!
1177 * \brief GraphicsView::removeOutOfSceneClassComponents
1178 * Removes all the class components that are not deleted but are removed from scene.
1179 */
1180void GraphicsView::removeOutOfSceneClassComponents()
1181{
1182 foreach (Component *pComponent, mOutOfSceneComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mOutOfSceneComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
1183 pComponent->removeChildren();
1184 deleteComponentFromOutOfSceneList(pComponent);
1185 delete pComponent->getOriginItem();
1186 pComponent->emitDeleted();
1187 delete pComponent;
1188 }
1189}
1190
1191/*!
1192 * \brief GraphicsView::removeInheritedClassShapes
1193 * Removes all the inherited class shapes.
1194 */
1195void GraphicsView::removeInheritedClassShapes()
1196{
1197 foreach (ShapeAnnotation *pShapeAnnotation, mInheritedShapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInheritedShapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (ShapeAnnotation
*pShapeAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
1198 deleteInheritedShapeFromList(pShapeAnnotation);
1199 removeItem(pShapeAnnotation);
1200 removeItem(pShapeAnnotation->getOriginItem());
1201 delete pShapeAnnotation;
1202 }
1203}
1204
1205/*!
1206 * \brief GraphicsView::removeInheritedClassComponents
1207 * Removes all the class inherited components.
1208 */
1209void GraphicsView::removeInheritedClassComponents()
1210{
1211 foreach (Component *pComponent, mInheritedComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInheritedComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
1212 pComponent->removeChildren();
1213 deleteInheritedComponentFromList(pComponent);
1214 removeItem(pComponent->getOriginItem());
1215 delete pComponent->getOriginItem();
1216 removeItem(pComponent);
1217 pComponent->emitDeleted();
1218 delete pComponent;
1219 }
1220}
1221
1222/*!
1223 * \brief GraphicsView::removeInheritedClassConnections
1224 * Removes all the class inherited class connections.
1225 */
1226void GraphicsView::removeInheritedClassConnections()
1227{
1228 foreach (LineAnnotation *pConnectionLineAnnotation, mInheritedConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInheritedConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pConnectionLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
1229 deleteInheritedConnectionFromList(pConnectionLineAnnotation);
1230 removeItem(pConnectionLineAnnotation);
1231 delete pConnectionLineAnnotation;
1232 }
1233}
1234
1235/*!
1236 * \brief GraphicsView::removeOutOfSceneShapes
1237 * Removes all the shapes that are not deleted but are removed from scene.
1238 */
1239void GraphicsView::removeOutOfSceneShapes()
1240{
1241 foreach (ShapeAnnotation *pShapeAnnotation, mOutOfSceneShapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mOutOfSceneShapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (ShapeAnnotation
*pShapeAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
1242 deleteShapeFromOutOfSceneList(pShapeAnnotation);
1243 delete pShapeAnnotation;
1244 }
1245}
1246
1247/*!
1248 * \brief GraphicsView::removeOutOfSceneConnections
1249 * Removes all the connections that are not deleted but are removed from scene.
1250 */
1251void GraphicsView::removeOutOfSceneConnections()
1252{
1253 foreach (LineAnnotation *pLineAnnotation, mOutOfSceneConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mOutOfSceneConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pLineAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
1254 deleteConnectionFromOutOfSceneList(pLineAnnotation);
1255 delete pLineAnnotation;
1256 }
1257}
1258
1259/*!
1260 * \brief GraphicsView::removeOutOfSceneTransitions
1261 * Removes all the class transitions that are not deleted but are removed from scene.
1262 */
1263void GraphicsView::removeOutOfSceneTransitions()
1264{
1265 foreach (LineAnnotation *pLineAnnotation, mOutOfSceneTransitionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mOutOfSceneTransitionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pLineAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
1266 deleteTransitionFromOutOfSceneList(pLineAnnotation);
1267 delete pLineAnnotation;
1268 }
1269}
1270
1271/*!
1272 * \brief GraphicsView::removeOutOfSceneInitialStates
1273 * Removes all the initial states that are not deleted but are removed from scene.
1274 */
1275void GraphicsView::removeOutOfSceneInitialStates()
1276{
1277 foreach (LineAnnotation *pLineAnnotation, mOutOfSceneInitialStatesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mOutOfSceneInitialStatesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pLineAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
1278 deleteInitialStateFromOutOfSceneList(pLineAnnotation);
1279 delete pLineAnnotation;
1280 }
1281}
1282
1283void GraphicsView::createLineShape(QPointF point)
1284{
1285 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) {
1286 return;
1287 }
1288
1289 if (!isCreatingLineShape()) {
1290 mpLineShapeAnnotation = new LineAnnotation("", this);
1291 mpModelWidget->getUndoStack()->push(new AddShapeCommand(mpLineShapeAnnotation));
1292 setIsCreatingLineShape(true);
1293 mpLineShapeAnnotation->addPoint(point);
1294 mpLineShapeAnnotation->addPoint(point);
1295 } else { // if we are already creating a line then only add one point.
1296 mpLineShapeAnnotation->addPoint(point);
1297 }
1298}
1299
1300void GraphicsView::createPolygonShape(QPointF point)
1301{
1302 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) {
1303 return;
1304 }
1305
1306 if (!isCreatingPolygonShape()) {
1307 mpPolygonShapeAnnotation = new PolygonAnnotation("", this);
1308 mpModelWidget->getUndoStack()->push(new AddShapeCommand(mpPolygonShapeAnnotation));
1309 setIsCreatingPolygonShape(true);
1310 mpPolygonShapeAnnotation->addPoint(point);
1311 mpPolygonShapeAnnotation->addPoint(point);
1312 mpPolygonShapeAnnotation->addPoint(point);
1313 } else { // if we are already creating a polygon then only add one point.
1314 mpPolygonShapeAnnotation->addPoint(point);
1315 }
1316}
1317
1318void GraphicsView::createRectangleShape(QPointF point)
1319{
1320 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) {
1321 return;
1322 }
1323
1324 if (!isCreatingRectangleShape()) {
1325 mpRectangleShapeAnnotation = new RectangleAnnotation("", this);
1326 mpModelWidget->getUndoStack()->push(new AddShapeCommand(mpRectangleShapeAnnotation));
1327 setIsCreatingRectangleShape(true);
1328 mpRectangleShapeAnnotation->replaceExtent(0, point);
1329 mpRectangleShapeAnnotation->replaceExtent(1, point);
1330 } else { // if we are already creating a rectangle then finish creating it.
1331 finishDrawingRectangleShape();
1332 }
1333}
1334
1335void GraphicsView::createEllipseShape(QPointF point)
1336{
1337 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) {
1338 return;
1339 }
1340
1341 if (!isCreatingEllipseShape()) {
1342 mpEllipseShapeAnnotation = new EllipseAnnotation("", this);
1343 mpModelWidget->getUndoStack()->push(new AddShapeCommand(mpEllipseShapeAnnotation));
1344 setIsCreatingEllipseShape(true);
1345 mpEllipseShapeAnnotation->replaceExtent(0, point);
1346 mpEllipseShapeAnnotation->replaceExtent(1, point);
1347 } else { // if we are already creating an ellipse then finish creating it.
1348 finishDrawingEllipseShape();
1349 }
1350}
1351
1352void GraphicsView::createTextShape(QPointF point)
1353{
1354 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) {
1355 return;
1356 }
1357
1358 if (!isCreatingTextShape()) {
1359 mpTextShapeAnnotation = new TextAnnotation("", this);
1360 mpModelWidget->getUndoStack()->push(new AddShapeCommand(mpTextShapeAnnotation));
1361 setIsCreatingTextShape(true);
1362 mpTextShapeAnnotation->setTextString("text");
1363 mpTextShapeAnnotation->replaceExtent(0, point);
1364 mpTextShapeAnnotation->replaceExtent(1, point);
1365 } else { // if we are already creating a text then finish creating it.
1366 finishDrawingTextShape();
1367 }
1368}
1369
1370void GraphicsView::createBitmapShape(QPointF point)
1371{
1372 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) {
1373 return;
1374 }
1375
1376 if (!isCreatingBitmapShape()) {
1377 mpBitmapShapeAnnotation = new BitmapAnnotation(mpModelWidget->getLibraryTreeItem()->getFileName(), "", this);
1378 mpModelWidget->getUndoStack()->push(new AddShapeCommand(mpBitmapShapeAnnotation));
1379 setIsCreatingBitmapShape(true);
1380 mpBitmapShapeAnnotation->replaceExtent(0, point);
1381 mpBitmapShapeAnnotation->replaceExtent(1, point);
1382 } else { // if we are already creating a bitmap then finish creating it.
1383 finishDrawingBitmapShape();
1384 }
1385}
1386
1387/*!
1388 * \brief GraphicsView::finishDrawingGenericShape
1389 * This function is called when shape creation operation is cancelled.
1390 * So we want to unselect the shapes in this case except for Text and Bitmap
1391 * since they have their respective pop-up dialogs which doesn't lead to selection and focus issue.
1392 */
1393void GraphicsView::finishDrawingGenericShape()
1394{
1395 if (mIsCreatingLineShape){
1396 finishDrawingLineShape();
1397 mpLineShapeAnnotation->setSelected(false);
1398 } else if (mIsCreatingPolygonShape) {
1399 finishDrawingPolygonShape();
1400 mpPolygonShapeAnnotation->setSelected(false);
1401 } else if (mIsCreatingRectangleShape) {
1402 finishDrawingRectangleShape();
1403 mpRectangleShapeAnnotation->setSelected(false);
1404 } else if (mIsCreatingEllipseShape) {
1405 finishDrawingEllipseShape();
1406 mpEllipseShapeAnnotation->setSelected(false);
1407 } else if (mIsCreatingTextShape) {
1408 finishDrawingTextShape();
1409 } else /*Otherwise we have a bitmap*/{
1410 finishDrawingBitmapShape();
1411 }
1412}
1413
1414void GraphicsView::finishDrawingLineShape(bool removeLastAddedPoint)
1415{
1416 setIsCreatingLineShape(false);
1417 if (removeLastAddedPoint) {
1418 mpLineShapeAnnotation->removePoint(mpLineShapeAnnotation->getPoints().size() - 1);
1419 }
1420 setOriginAdjustAndInitialize(mpLineShapeAnnotation);
1421 mpLineShapeAnnotation->setSelected(true);
1422 uncheckAllShapeDrawingActions();
1423 checkEmitUpdateSelect(false, mpLineShapeAnnotation);
1424}
1425
1426void GraphicsView::finishDrawingPolygonShape(bool removeLastAddedPoint)
1427{
1428 setIsCreatingPolygonShape(false);
1429 if (removeLastAddedPoint) {
1430 mpPolygonShapeAnnotation->removePoint(mpPolygonShapeAnnotation->getPoints().size() - 1);
1431 }
1432 setOriginAdjustAndInitialize(mpPolygonShapeAnnotation);
1433 mpPolygonShapeAnnotation->setSelected(true);
1434 uncheckAllShapeDrawingActions();
1435 checkEmitUpdateSelect(false, mpPolygonShapeAnnotation);
1436}
1437
1438void GraphicsView::finishDrawingRectangleShape()
1439{
1440 setIsCreatingRectangleShape(false);
1441 setOriginAdjustAndInitialize(mpRectangleShapeAnnotation);
1442 mpRectangleShapeAnnotation->setSelected(true);
1443 uncheckAllShapeDrawingActions();
1444 checkEmitUpdateSelect(false, mpRectangleShapeAnnotation);
1445}
1446
1447void GraphicsView::finishDrawingEllipseShape()
1448{
1449 setIsCreatingEllipseShape(false);
1450 setOriginAdjustAndInitialize(mpEllipseShapeAnnotation);
1451 mpEllipseShapeAnnotation->setSelected(true);
1452 uncheckAllShapeDrawingActions();
1453 checkEmitUpdateSelect(false, mpEllipseShapeAnnotation);
1454}
1455
1456void GraphicsView::finishDrawingTextShape()
1457{
1458 setIsCreatingTextShape(false);
1459 setOriginAdjustAndInitialize(mpTextShapeAnnotation);
1460 uncheckAllShapeDrawingActions();
1461 checkEmitUpdateSelect(true, mpTextShapeAnnotation);
1462}
1463
1464void GraphicsView::finishDrawingBitmapShape() {
1465 setIsCreatingBitmapShape(false);
1466 setOriginAdjustAndInitialize(mpBitmapShapeAnnotation);
1467 uncheckAllShapeDrawingActions();
1468 checkEmitUpdateSelect(true, mpBitmapShapeAnnotation);
1469}
1470
1471void GraphicsView::checkEmitUpdateSelect(const bool showPropertiesAndSelect, ShapeAnnotation* shapeAnnotation)
1472{
1473 MainWindow *pMainWindow = MainWindow::instance();
1474 pMainWindow->getConnectModeAction()->setChecked(true);
1475 mpModelWidget->getLibraryTreeItem()->emitShapeAdded(shapeAnnotation, this);
1476 if (showPropertiesAndSelect) {
1477 shapeAnnotation->showShapeProperties();
1478 // set the focus back on GraphicsView once the shape properties dialog is closed.
1479 setFocus(Qt::ActiveWindowFocusReason);
1480 }
1481 mpModelWidget->updateClassAnnotationIfNeeded();
1482 mpModelWidget->updateModelText();
1483 if (showPropertiesAndSelect) {
1484 shapeAnnotation->setSelected(true);
1485 }
1486}
1487
1488void GraphicsView::setOriginAdjustAndInitialize(ShapeAnnotation* shapeAnnotation)
1489{
1490 shapeAnnotation->setOrigin(shapeAnnotation->sceneBoundingRect().center());
1491 adjustInitializeDraw(shapeAnnotation);
1492}
1493
1494void GraphicsView::setOriginAdjustAndInitialize(PolygonAnnotation* shapeAnnotation)
1495{
1496 shapeAnnotation->setOrigin(roundPoint(shapeAnnotation->sceneBoundingRect().center()));
1497 adjustInitializeDraw(shapeAnnotation);
1498}
1499
1500void GraphicsView::adjustInitializeDraw(ShapeAnnotation* shapeAnnotation)
1501{
1502 if (dynamic_cast<LineAnnotation*>(shapeAnnotation) || dynamic_cast<PolygonAnnotation*>(shapeAnnotation)) {
1503 shapeAnnotation->adjustPointsWithOrigin();
1504 } else {
1505 shapeAnnotation->adjustExtentsWithOrigin();
1506 }
1507 shapeAnnotation->drawCornerItems();
1508 shapeAnnotation->applyTransformation();
1509}
1510
1511/*!
1512 * \brief GraphicsView::itemsBoundingRect
1513 * Gets the bounding rectangle of all the items added to the view, excluding background and so on
1514 * \return
1515 */
1516QRectF GraphicsView::itemsBoundingRect()
1517{
1518 QRectF rect;
1519 foreach (Component *pComponent, mComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
1520 rect |= pComponent->itemsBoundingRect();
1521 }
1522 foreach (QGraphicsItem *item, mShapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mShapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QGraphicsItem
*item = *_container_.i; _container_.control; _container_.control
= 0)
{
1523 if (TextAnnotation *pTextAnnotation = dynamic_cast<TextAnnotation*>(item)) {
1524 rect |= pTextAnnotation->mExportBoundingRect;
1525 } else {
1526 rect |= item->sceneBoundingRect();
1527 }
1528 }
1529 foreach (QGraphicsItem *item, mConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QGraphicsItem
*item = *_container_.i; _container_.control; _container_.control
= 0)
{
1530 rect |= item->sceneBoundingRect();
1531 }
1532 foreach (Component *pComponent, mInheritedComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInheritedComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
1533 rect |= pComponent->itemsBoundingRect();
1534 }
1535 foreach (QGraphicsItem *item, mInheritedShapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInheritedShapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QGraphicsItem
*item = *_container_.i; _container_.control; _container_.control
= 0)
{
1536 rect |= item->sceneBoundingRect();
1537 }
1538 foreach (QGraphicsItem *item, mInheritedConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInheritedConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QGraphicsItem
*item = *_container_.i; _container_.control; _container_.control
= 0)
{
1539 rect |= item->sceneBoundingRect();
1540 }
1541 qreal x1, y1, x2, y2;
1542 rect.getCoords(&x1, &y1, &x2, &y2);
1543 rect.setCoords(x1 -5, y1 -5, x2 + 5, y2 + 5);
1544 return mapFromScene(rect).boundingRect();
1545}
1546
1547QPointF GraphicsView::snapPointToGrid(QPointF point)
1548{
1549 qreal stepX = mMergedCoOrdinateSystem.getHorizontalGridStep();
1550 qreal stepY = mMergedCoOrdinateSystem.getVerticalGridStep();
1551 point.setX(stepX * qFloor((point.x() / stepX) + 0.5));
1552 point.setY(stepY * qFloor((point.y() / stepY) + 0.5));
1553 return point;
1554}
1555
1556QPointF GraphicsView::movePointByGrid(QPointF point, QPointF origin, bool useShiftModifier)
1557{
1558 qreal stepX = mMergedCoOrdinateSystem.getHorizontalGridStep() * ((useShiftModifier && QApplication::keyboardModifiers().testFlag(Qt::ShiftModifier)) ? 5 : 1);
1559 qreal stepY = mMergedCoOrdinateSystem.getVerticalGridStep() * ((useShiftModifier && QApplication::keyboardModifiers().testFlag(Qt::ShiftModifier)) ? 5 : 1);
1560 if (useShiftModifier && QApplication::keyboardModifiers().testFlag(Qt::ShiftModifier)) {
1561 int modX = (int)qFabs(origin.x()) % (int)stepX;
1562 int modY = (int)qFabs(origin.y()) % (int)stepY;
1563 if (modX != 0) {
1564 if ((point.x() < 0 && origin.x() > 0) || (point.x() > 0 && origin.x() < 0)) {
1565 stepX = modX;
1566 } else if ((point.x() > 0 && origin.x() > 0) || (point.x() < 0 && origin.x() < 0)) {
1567 stepX = stepX - modX;
1568 }
1569 }
1570 if (modY != 0) {
1571 if ((point.y() < 0 && origin.y() > 0) || (point.y() > 0 && origin.y() < 0)) {
1572 stepY = modY;
1573 } else if ((point.y() > 0 && origin.y() > 0) || (point.y() < 0 && origin.y() < 0)) {
1574 stepY = stepY - modY;
1575 }
1576 }
1577 }
1578 point.setX(qRound(point.x() / stepX) * stepX);
1579 point.setY(qRound(point.y() / stepY) * stepY);
1580 return point;
1581}
1582
1583QPointF GraphicsView::roundPoint(QPointF point)
1584{
1585 qreal divisor = 0.5;
1586 qreal x = (fmod(point.x(), divisor) == 0) ? point.x() : qRound(point.x());
1587 qreal y = (fmod(point.y(), divisor) == 0) ? point.y() : qRound(point.y());
1588 return QPointF(x, y);
1589}
1590
1591/*!
1592 * \brief GraphicsView::hasIconAnnotation
1593 * Checks if class has annotation.
1594 * \return
1595 */
1596bool GraphicsView::hasAnnotation()
1597{
1598 // check inherited shapes and components
1599 if (!mInheritedShapesList.isEmpty()) {
1600 return true;
1601 }
1602 foreach (Component *pInheritedComponent, mInheritedComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInheritedComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pInheritedComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
1603 if (pInheritedComponent->hasShapeAnnotation(pInheritedComponent) && pInheritedComponent->isVisible()) {
1604 return true;
1605 }
1606 }
1607 // check shapes and components
1608 if (!mShapesList.isEmpty()) {
1609 return true;
1610 }
1611 foreach (Component *pComponent, mComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
1612 if (pComponent->hasShapeAnnotation(pComponent) && pComponent->isVisible()) {
1613 return true;
1614 }
1615 }
1616 return false;
1617}
1618
1619/*!
1620 * \brief GraphicsView::addItem
1621 * Adds the QGraphicsItem from GraphicsView
1622 * \param pGraphicsItem
1623 */
1624void GraphicsView::addItem(QGraphicsItem *pGraphicsItem)
1625{
1626 if (!mAllItems.contains(pGraphicsItem)) {
1627 mAllItems.insert(pGraphicsItem);
1628 scene()->addItem(pGraphicsItem);
1629 }
1630}
1631
1632/*!
1633 * \brief GraphicsView::removeItem
1634 * Removes the QGraphicsItem from GraphicsView
1635 * \param pGraphicsItem
1636 */
1637void GraphicsView::removeItem(QGraphicsItem *pGraphicsItem)
1638{
1639 if (mAllItems.contains(pGraphicsItem)) {
1640 mAllItems.remove(pGraphicsItem);
1641 scene()->removeItem(pGraphicsItem);
1642 }
1643}
1644
1645/*!
1646 * \brief GraphicsView::fitInView
1647 * Fits the view.
1648 */
1649void GraphicsView::fitInViewInternal()
1650{
1651 // only resize the view if user has not set any custom scaling like zoom in and zoom out.
1652 if (!isCustomScale()) {
1653 // make the fitInView rectangle bigger so that the scene rectangle will show up properly on the screen.
1654 QRectF extentRectangle = mMergedCoOrdinateSystem.getExtentRectangle();
1655 qreal x1, y1, x2, y2;
1656 extentRectangle.getCoords(&x1, &y1, &x2, &y2);
1657 extentRectangle.setCoords(x1 -5, y1 -5, x2 + 5, y2 + 5);
1658 fitInView(extentRectangle, Qt::KeepAspectRatio);
1659 }
1660}
1661
1662/*!
1663 * \brief GraphicsView::createActions
1664 * Creates the actions for the GraphicsView.
1665 */
1666void GraphicsView::createActions()
1667{
1668 bool isSystemLibrary = mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView();
1669 // Graphics View Properties Action
1670 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
1671 mpPropertiesAction = new QAction(Helper::systemSimulationInformation, this);
1672 } else {
1673 mpPropertiesAction = new QAction(Helper::properties, this);
1674 }
1675 connect(mpPropertiesAction, SIGNAL(triggered())"2""triggered()", SLOT(showGraphicsViewProperties())"1""showGraphicsViewProperties()");
1676 // rename Action
1677 mpRenameAction = new QAction(Helper::rename, this);
1678 mpRenameAction->setStatusTip(Helper::renameTip);
1679 connect(mpRenameAction, SIGNAL(triggered())"2""triggered()", SLOT(showRenameDialog())"1""showRenameDialog()");
1680 // Simulation Params Action
1681 mpSimulationParamsAction = new QAction(ResourceCache::getIcon(":/Resources/icons/simulation-parameters.svg"), Helper::simulationParams, this);
1682 mpSimulationParamsAction->setStatusTip(Helper::simulationParamsTip);
1683 connect(mpSimulationParamsAction, SIGNAL(triggered())"2""triggered()", SLOT(showSimulationParamsDialog())"1""showSimulationParamsDialog()");
1684 // Actions for shapes and Components
1685 // Manhattanize Action
1686 mpManhattanizeAction = new QAction(tr("Manhattanize"), this);
1687 mpManhattanizeAction->setStatusTip(tr("Manhattanize the lines"));
1688 mpManhattanizeAction->setDisabled(isSystemLibrary);
1689 connect(mpManhattanizeAction, SIGNAL(triggered())"2""triggered()", SLOT(manhattanizeItems())"1""manhattanizeItems()");
1690 // Delete Action
1691 mpDeleteAction = new QAction(ResourceCache::getIcon(":/Resources/icons/delete.svg"), Helper::deleteStr, this);
1692 mpDeleteAction->setStatusTip(tr("Deletes the item"));
1693 mpDeleteAction->setShortcut(QKeySequence::Delete);
1694 mpDeleteAction->setDisabled(isSystemLibrary);
1695 connect(mpDeleteAction, SIGNAL(triggered())"2""triggered()", SLOT(deleteItems())"1""deleteItems()");
1696 // cut action
1697 mpCutAction = new QAction(ResourceCache::getIcon(":/Resources/icons/cut.svg"), tr("Cut"), this);
1698 mpCutAction->setShortcut(QKeySequence("Ctrl+x"));
1699 mpCutAction->setDisabled(isSystemLibrary);
1700 connect(mpCutAction, SIGNAL(triggered())"2""triggered()", SLOT(cutItems())"1""cutItems()");
1701 // copy action
1702 mpCopyAction = new QAction(ResourceCache::getIcon(":/Resources/icons/copy.svg"), Helper::copy, this);
1703 mpCopyAction->setShortcut(QKeySequence("Ctrl+c"));
1704 connect(mpCopyAction, SIGNAL(triggered())"2""triggered()", SLOT(copyItems())"1""copyItems()");
1705 // paste action
1706 mpPasteAction = new QAction(ResourceCache::getIcon(":/Resources/icons/paste.svg"), tr("Paste"), this);
1707 mpPasteAction->setShortcut(QKeySequence("Ctrl+v"));
1708 mpPasteAction->setDisabled(isSystemLibrary);
1709 connect(mpPasteAction, SIGNAL(triggered())"2""triggered()", SLOT(pasteItems())"1""pasteItems()");
1710 // Duplicate Action
1711 mpDuplicateAction = new QAction(ResourceCache::getIcon(":/Resources/icons/duplicate.svg"), Helper::duplicate, this);
1712 mpDuplicateAction->setStatusTip(Helper::duplicateTip);
1713 mpDuplicateAction->setShortcut(QKeySequence("Ctrl+d"));
1714 mpDuplicateAction->setDisabled(isSystemLibrary);
1715 connect(mpDuplicateAction, SIGNAL(triggered())"2""triggered()", SLOT(duplicateItems())"1""duplicateItems()");
1716 // Bring To Front Action
1717 mpBringToFrontAction = new QAction(ResourceCache::getIcon(":/Resources/icons/bring-to-front.svg"), tr("Bring to Front"), this);
1718 mpBringToFrontAction->setStatusTip(tr("Brings the item to front"));
1719 mpBringToFrontAction->setDisabled(isSystemLibrary);
1720 mpBringToFrontAction->setDisabled(true);
1721 // Bring Forward Action
1722 mpBringForwardAction = new QAction(ResourceCache::getIcon(":/Resources/icons/bring-forward.svg"), tr("Bring Forward"), this);
1723 mpBringForwardAction->setStatusTip(tr("Brings the item one level forward"));
1724 mpBringForwardAction->setDisabled(isSystemLibrary);
1725 mpBringForwardAction->setDisabled(true);
1726 // Send To Back Action
1727 mpSendToBackAction = new QAction(ResourceCache::getIcon(":/Resources/icons/send-to-back.svg"), tr("Send to Back"), this);
1728 mpSendToBackAction->setStatusTip(tr("Sends the item to back"));
1729 mpSendToBackAction->setDisabled(isSystemLibrary);
1730 mpSendToBackAction->setDisabled(true);
1731 // Send Backward Action
1732 mpSendBackwardAction = new QAction(ResourceCache::getIcon(":/Resources/icons/send-backward.svg"), tr("Send Backward"), this);
1733 mpSendBackwardAction->setStatusTip(tr("Sends the item one level backward"));
1734 mpSendBackwardAction->setDisabled(isSystemLibrary);
1735 mpSendBackwardAction->setDisabled(true);
1736 // Rotate ClockWise Action
1737 mpRotateClockwiseAction = new QAction(ResourceCache::getIcon(":/Resources/icons/rotateclockwise.svg"), tr("Rotate Clockwise"), this);
1738 mpRotateClockwiseAction->setStatusTip(tr("Rotates the item clockwise"));
1739 mpRotateClockwiseAction->setShortcut(QKeySequence("Ctrl+r"));
1740 mpRotateClockwiseAction->setDisabled(isSystemLibrary);
1741 connect(mpRotateClockwiseAction, SIGNAL(triggered())"2""triggered()", SLOT(rotateClockwise())"1""rotateClockwise()");
1742 // Rotate Anti-ClockWise Action
1743 mpRotateAntiClockwiseAction = new QAction(ResourceCache::getIcon(":/Resources/icons/rotateanticlockwise.svg"), tr("Rotate Anticlockwise"), this);
1744 mpRotateAntiClockwiseAction->setStatusTip(tr("Rotates the item anticlockwise"));
1745 mpRotateAntiClockwiseAction->setShortcut(QKeySequence("Ctrl+Shift+r"));
1746 mpRotateAntiClockwiseAction->setDisabled(isSystemLibrary);
1747 connect(mpRotateAntiClockwiseAction, SIGNAL(triggered())"2""triggered()", SLOT(rotateAntiClockwise())"1""rotateAntiClockwise()");
1748 // Flip Horizontal Action
1749 mpFlipHorizontalAction = new QAction(ResourceCache::getIcon(":/Resources/icons/flip-horizontal.svg"), tr("Flip Horizontal"), this);
1750 mpFlipHorizontalAction->setStatusTip(tr("Flips the item horizontally"));
1751 mpFlipHorizontalAction->setShortcut(QKeySequence("h"));
1752 mpFlipHorizontalAction->setDisabled(isSystemLibrary);
1753 connect(mpFlipHorizontalAction, SIGNAL(triggered())"2""triggered()", SLOT(flipHorizontal())"1""flipHorizontal()");
1754 // Flip Vertical Action
1755 mpFlipVerticalAction = new QAction(ResourceCache::getIcon(":/Resources/icons/flip-vertical.svg"), tr("Flip Vertical"), this);
1756 mpFlipVerticalAction->setStatusTip(tr("Flips the item vertically"));
1757 mpFlipVerticalAction->setShortcut(QKeySequence("v"));
1758 mpFlipVerticalAction->setDisabled(isSystemLibrary);
1759 connect(mpFlipVerticalAction, SIGNAL(triggered())"2""triggered()", SLOT(flipVertical())"1""flipVertical()");
1760 // set initial state Action
1761 mpSetInitialStateAction = new QAction(tr("Set Initial State"), this);
1762 mpSetInitialStateAction->setStatusTip(tr("Sets the state as initial state"));
1763 connect(mpSetInitialStateAction, SIGNAL(triggered())"2""triggered()", SLOT(setInitialState())"1""setInitialState()");
1764 // cancel transition Action
1765 mpCancelTransitionAction = new QAction(tr("Cancel Transition"), this);
1766 mpCancelTransitionAction->setStatusTip(tr("Cancels the current transition"));
1767 connect(mpCancelTransitionAction, SIGNAL(triggered())"2""triggered()", SLOT(cancelTransition())"1""cancelTransition()");
1768}
1769
1770/*!
1771 * \brief GraphicsView::isItemDroppedOnItself
1772 * Checks if item is dropped on itself.
1773 * \param pLibraryTreeItem
1774 * \return
1775 */
1776bool GraphicsView::isClassDroppedOnItself(LibraryTreeItem *pLibraryTreeItem)
1777{
1778 OptionsDialog *pOptionsDialog = OptionsDialog::instance();
1779 if (mpModelWidget->getLibraryTreeItem()->getNameStructure().compare(pLibraryTreeItem->getNameStructure()) == 0) {
1780 if (pOptionsDialog->getNotificationsPage()->getItemDroppedOnItselfCheckBox()->isChecked()) {
1781 NotificationsDialog *pNotificationsDialog = new NotificationsDialog(NotificationsDialog::ItemDroppedOnItself,
1782 NotificationsDialog::InformationIcon,
1783 MainWindow::instance());
1784 pNotificationsDialog->exec();
1785 }
1786 return true;
1787 }
1788 return false;
1789}
1790
1791/*!
1792 * \brief GraphicsView::isAnyItemSelectedAndEditable
1793 * If the class is system library then returns false.
1794 * Checks all the selected items. If the selected item is not inherited then returns true otherwise false.
1795 * \param key
1796 * \return
1797 */
1798bool GraphicsView::isAnyItemSelectedAndEditable(int key)
1799{
1800 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) {
1801 return false;
1802 }
1803 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
1804 if (mpModelWidget->getLibraryTreeItem()->isComponentElement()) {
1805 switch (key) {
1806 case Qt::Key_Delete:
1807 case Qt::Key_R: // rotate
1808 case Qt::Key_H: // horizontal flip
1809 case Qt::Key_V: // vertical flip
1810 return false;
1811 default:
1812 break;
1813 }
1814 }
1815 }
1816 bool selectedAndEditable = false;
1817 QList<QGraphicsItem*> selectedItems = scene()->selectedItems();
1818 for (int i = 0 ; i < selectedItems.size() ; i++) {
1819 // check the selected components.
1820 Component *pComponent = dynamic_cast<Component*>(selectedItems.at(i));
1821 if (pComponent && !pComponent->isInheritedComponent()) {
1822 return true;
1823 }
1824 // check the selected connections and shapes.
1825 ShapeAnnotation *pShapeAnnotation = dynamic_cast<ShapeAnnotation*>(selectedItems.at(i));
1826 if (pShapeAnnotation && !pShapeAnnotation->isInheritedShape()) {
1827 LineAnnotation *pLineAnnotation = dynamic_cast<LineAnnotation*>(pShapeAnnotation);
1828 // if the shape is connection line then we only return true for certain cases.
1829 if (pLineAnnotation && pLineAnnotation->getLineType() == LineAnnotation::ConnectionType) {
1830 switch (key) {
1831 case Qt::Key_Delete:
1832 selectedAndEditable = true;
1833 break;
1834 default:
1835 selectedAndEditable = false;
1836 break;
1837 }
1838 } else {
1839 return true;
1840 }
1841 }
1842 }
1843 return selectedAndEditable;
1844}
1845
1846/*!
1847 * \brief GraphicsView::getComponentFromQGraphicsItem
1848 * \param pGraphicsItem
1849 * A QGraphicsItem can be a Component or a ShapeAnnotation inside a Component.
1850 * \return
1851 */
1852Component *GraphicsView::getComponentFromQGraphicsItem(QGraphicsItem *pGraphicsItem)
1853{
1854 if (pGraphicsItem) {
1855 Component *pComponent = dynamic_cast<Component*>(pGraphicsItem);
1856 if (!pComponent && pGraphicsItem->parentItem()) {
1857 pComponent = dynamic_cast<Component*>(pGraphicsItem->parentItem());
1858 }
1859 return pComponent;
1860 }
1861 return 0;
1862}
1863
1864/*!
1865 * \brief GraphicsView::componentAtPosition
1866 * Returns the first component at the position.
1867 * \param position
1868 * \return
1869 */
1870Component *GraphicsView::componentAtPosition(QPoint position)
1871{
1872 QList<QGraphicsItem*> graphicsItems = items(position);
1873 foreach (QGraphicsItem *pGraphicsItem, graphicsItems)for (auto _container_ = QtPrivate::qMakeForeachContainer(graphicsItems
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QGraphicsItem
*pGraphicsItem = *_container_.i; _container_.control; _container_
.control = 0)
{
1874 Component *pComponent = getComponentFromQGraphicsItem(pGraphicsItem);
1875 if (pComponent) {
1876 Component *pRootComponent = pComponent->getRootParentComponent();
1877 if (pRootComponent && pRootComponent->getLibraryTreeItem() && !pRootComponent->getLibraryTreeItem()->isNonExisting()) {
1878 return pRootComponent;
1879 }
1880 }
1881 }
1882 return 0;
1883}
1884
1885/*!
1886 * \brief GraphicsView::connectorComponentAtPosition
1887 * Returns the connector component at the position.
1888 * \param position
1889 * \return
1890 */
1891Component* GraphicsView::connectorComponentAtPosition(QPoint position)
1892{
1893 /* Ticket:4215
1894 * Allow making connection from the connectors which are under some other shape or component.
1895 * itemAt() only returns the top level item.
1896 * Use items() to get all items at position and then return the first connector component from the list.
1897 */
1898 QList<QGraphicsItem*> graphicsItems = items(position);
1899 foreach (QGraphicsItem *pGraphicsItem, graphicsItems)for (auto _container_ = QtPrivate::qMakeForeachContainer(graphicsItems
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QGraphicsItem
*pGraphicsItem = *_container_.i; _container_.control; _container_
.control = 0)
{
1900 Component *pComponent = getComponentFromQGraphicsItem(pGraphicsItem);
1901 if (pComponent) {
1902 Component *pRootComponent = pComponent->getRootParentComponent();
1903 if (pRootComponent && pRootComponent->isSelected()) {
1904 return 0;
1905 } else if (pRootComponent && !pRootComponent->isSelected()) {
1906 if (MainWindow::instance()->getConnectModeAction()->isChecked() && mViewType == StringHandler::Diagram &&
1907 !(mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) &&
1908 ((pComponent->getLibraryTreeItem() && pComponent->getLibraryTreeItem()->isConnector()) ||
1909 (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::CompositeModel &&
1910 pComponent->getComponentType() == Component::Port) ||
1911 (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS &&
1912 (pComponent->getLibraryTreeItem()->getOMSConnector() || pComponent->getLibraryTreeItem()->getOMSBusConnector()
1913 || pComponent->getLibraryTreeItem()->getOMSTLMBusConnector() || pComponent->getComponentType() == Component::Port)))) {
1914 return pComponent;
1915 }
1916 }
1917 }
1918 }
1919 return 0;
1920}
1921
1922/*!
1923 * \brief GraphicsView::stateComponentAtPosition
1924 * Returns the state component at the position.
1925 * \param position
1926 * \return
1927 */
1928Component* GraphicsView::stateComponentAtPosition(QPoint position)
1929{
1930 QList<QGraphicsItem*> graphicsItems = items(position);
1931 foreach (QGraphicsItem *pGraphicsItem, graphicsItems)for (auto _container_ = QtPrivate::qMakeForeachContainer(graphicsItems
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QGraphicsItem
*pGraphicsItem = *_container_.i; _container_.control; _container_
.control = 0)
{
1932 Component *pComponent = getComponentFromQGraphicsItem(pGraphicsItem);
1933 if (pComponent) {
1934 Component *pRootComponent = pComponent->getRootParentComponent();
1935 if (pRootComponent && !pRootComponent->isSelected()) {
1936 if (MainWindow::instance()->getTransitionModeAction()->isChecked() && mViewType == StringHandler::Diagram &&
1937 !(mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) &&
1938 ((pComponent->getLibraryTreeItem() && pComponent->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica &&
1939 !pComponent->getLibraryTreeItem()->isNonExisting() && pComponent->getLibraryTreeItem()->isState()))) {
1940 return pComponent;
1941 }
1942 }
1943 }
1944 }
1945 return 0;
1946}
1947
1948/*!
1949 * \brief GraphicsView::updateComponentConnectorSizingParameter
1950 * Updates the component's connectorSizing parameter via the modifier.
1951 * \param pGraphicsView
1952 * \param className
1953 * \param pComponent
1954 * \return
1955 */
1956bool GraphicsView::updateComponentConnectorSizingParameter(GraphicsView *pGraphicsView, QString className, Component *pComponent)
1957{
1958 // if connectorSizing then set a new value for the connectorSizing parameter.
1959 if (pComponent->isConnectorSizing()) {
1960 QString parameter = pComponent->getComponentInfo()->getArrayIndex();
1961 int numberOfComponentConnections = pGraphicsView->numberOfComponentConnections(pComponent);
1962 QString modifierKey = QString("%1.%2").arg(pComponent->getRootParentComponent()->getName()).arg(parameter);
1963 MainWindow::instance()->getOMCProxy()->setComponentModifierValue(className, modifierKey, QString::number(numberOfComponentConnections));
1964 return true;
1965 }
1966 return false;
1967}
1968
1969/*!
1970 * \brief GraphicsView::addConnection
1971 * Adds the connection to GraphicsView.
1972 * \param pComponent
1973 */
1974void GraphicsView::addConnection(Component *pComponent)
1975{
1976 // When clicking the start component
1977 if (!isCreatingConnection()) {
1978 QPointF startPos;
1979 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
1980 startPos = roundPoint(pComponent->mapToScene(pComponent->boundingRect().center()));
1981 } else {
1982 startPos = snapPointToGrid(pComponent->mapToScene(pComponent->boundingRect().center()));
1983 }
1984 mpConnectionLineAnnotation = new LineAnnotation(LineAnnotation::ConnectionType, pComponent, this);
1985 setIsCreatingConnection(true);
1986 mpConnectionLineAnnotation->addPoint(startPos);
1987 mpConnectionLineAnnotation->addPoint(startPos);
1988 mpConnectionLineAnnotation->addPoint(startPos);
1989 /* Ticket:4196
1990 * If we are starting connection from expandable connector or (array && !connectorSizing) connector
1991 * then set the line thickness to 0.5
1992 */
1993 Component *pRootParentComponent = pComponent->getParentComponent() ? pComponent->getRootParentComponent() : 0;
1994 if (pComponent->isExpandableConnector()
1995 || (pComponent->isArray() && !pComponent->isConnectorSizing())
1996 || (pRootParentComponent && (pRootParentComponent->isExpandableConnector() || (pRootParentComponent->isArray() && !pRootParentComponent->isConnectorSizing())))) {
1997 mpConnectionLineAnnotation->setLineThickness(0.5);
1998 }
1999 } else { // When clicking the end component
2000 mpConnectionLineAnnotation->setEndComponent(pComponent);
2001 // update the last point to the center of component
2002 QPointF newPos;
2003 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
2004 newPos = roundPoint(pComponent->mapToScene(pComponent->boundingRect().center()));
2005 } else {
2006 newPos = snapPointToGrid(pComponent->mapToScene(pComponent->boundingRect().center()));
2007 }
2008 mpConnectionLineAnnotation->updateEndPoint(newPos);
2009 // check if connection is valid
2010 Component *pStartComponent = mpConnectionLineAnnotation->getStartComponent();
2011 MainWindow *pMainWindow = MainWindow::instance();
2012 if (pStartComponent == pComponent) {
2013 QMessageBox::information(pMainWindow, QString(Helper::applicationName).append(" - ").append(Helper::information),
2014 GUIMessages::getMessage(GUIMessages::SAME_COMPONENT_CONNECT), Helper::ok);
2015 removeCurrentConnection();
2016 } else {
2017 /* Ticket:4956
2018 * Only set the connection line thickness to 0.5 when both connectors are either expandable or (array && !connectorSizing).
2019 * Otherwise set it to 0.25 i.e., default.
2020 */
2021 Component *pStartRootParentComponent = pStartComponent->getParentComponent() ? pStartComponent->getRootParentComponent() : 0;
2022 Component *pRootParentComponent = pComponent->getParentComponent() ? pComponent->getRootParentComponent() : 0;
2023
2024 if ((pStartComponent->isExpandableConnector() || (pStartComponent->isArray() && !pStartComponent->isConnectorSizing())
2025 || (pStartRootParentComponent && (pStartRootParentComponent->isExpandableConnector() || (pStartRootParentComponent->isArray() && !pStartRootParentComponent->isConnectorSizing()))))
2026 && (pComponent->isExpandableConnector() || (pComponent->isArray() && !pComponent->isConnectorSizing())
2027 || (pRootParentComponent && (pRootParentComponent->isExpandableConnector() || (pRootParentComponent->isArray() && !pRootParentComponent->isConnectorSizing()))))) {
2028 mpConnectionLineAnnotation->setLineThickness(0.5);
2029 } else {
2030 /* Ticket:4956
2031 * If the start connector is either expandable or array and the end connector is not then change the line color to end connector.
2032 */
2033 if ((pStartComponent->isExpandableConnector() || pStartComponent->isArray()
2034 || (pStartRootParentComponent && (pStartRootParentComponent->isExpandableConnector() || pStartRootParentComponent->isArray())))
2035 && (!(pComponent->isExpandableConnector() || pComponent->isArray()
2036 || (pRootParentComponent && (pRootParentComponent->isExpandableConnector() || pRootParentComponent->isArray()))))) {
2037 if (pComponent->getLibraryTreeItem()) {
2038 if (!pComponent->getLibraryTreeItem()->getModelWidget()) {
2039 MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->showModelWidget(pComponent->getLibraryTreeItem(), false);
2040 }
2041 ShapeAnnotation *pShapeAnnotation;
2042 if (pComponent->getLibraryTreeItem()->getModelWidget()->getIconGraphicsView()
2043 && pComponent->getLibraryTreeItem()->getModelWidget()->getIconGraphicsView()->getShapesList().size() > 0) {
2044 pShapeAnnotation = pComponent->getLibraryTreeItem()->getModelWidget()->getIconGraphicsView()->getShapesList().at(0);
2045 mpConnectionLineAnnotation->setLineColor(pShapeAnnotation->getLineColor());
2046 } else if (pComponent->getShapesList().size() > 0) {
2047 ShapeAnnotation *pShapeAnnotation = pComponent->getShapesList().at(0);
2048 mpConnectionLineAnnotation->setLineColor(pShapeAnnotation->getLineColor());
2049 }
2050 }
2051 }
2052 mpConnectionLineAnnotation->setLineThickness(0.25);
2053 }
2054 // check if any of starting or ending components are array
2055 bool showConnectionArrayDialog = false;
2056 if ((pStartComponent->isExpandableConnector() || (pStartComponent->isArray() && !pStartComponent->isConnectorSizing())
2057 || (pStartRootParentComponent && (pStartRootParentComponent->isExpandableConnector() || (pStartRootParentComponent->isArray() && !pStartRootParentComponent->isConnectorSizing()))))
2058 || (pComponent->isExpandableConnector() || (pComponent->isArray() && !pComponent->isConnectorSizing())
2059 || (pRootParentComponent && (pRootParentComponent->isExpandableConnector() || (pRootParentComponent->isArray() && !pRootParentComponent->isConnectorSizing()))))) {
2060 showConnectionArrayDialog = true;
2061 }
2062 // check if any starting or ending components are bus
2063 bool showBusConnectionDialog = false;
2064 if ((pStartComponent->getLibraryTreeItem() && pStartComponent->getLibraryTreeItem()->getOMSBusConnector())
2065 || (pComponent->getLibraryTreeItem() && pComponent->getLibraryTreeItem()->getOMSBusConnector())) {
2066 showBusConnectionDialog = true;
2067 }
2068 // if connectorSizing annotation is set then don't show the CreateConnectionDialog
2069 if (showConnectionArrayDialog) {
2070 CreateConnectionDialog *pConnectionArray = new CreateConnectionDialog(this, mpConnectionLineAnnotation, MainWindow::instance());
2071 // if user cancels the array connection
2072 if (!pConnectionArray->exec()) {
2073 removeCurrentConnection();
2074 }
2075 } else if (showBusConnectionDialog) {
2076 BusConnectionDialog *pBusConnectionDialog = new BusConnectionDialog(this, mpConnectionLineAnnotation);
2077 // if user cancels the bus connection
2078 if (!pBusConnectionDialog->exec()) {
2079 removeCurrentConnection();
2080 }
2081 } else if ((pStartComponent->getLibraryTreeItem() && pStartComponent->getLibraryTreeItem()->getOMSTLMBusConnector())
2082 && (pComponent->getLibraryTreeItem() && pComponent->getLibraryTreeItem()->getOMSTLMBusConnector())) {
2083 TLMConnectionDialog *pTLMBusConnectionDialog = new TLMConnectionDialog(this, mpConnectionLineAnnotation);
2084 // if user cancels the tlm bus connection
2085 if (!pTLMBusConnectionDialog->exec()) {
2086 removeCurrentConnection();
2087 }
2088 } else {
2089 QString startComponentName, endComponentName;
2090 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
2091 if (pStartComponent->getLibraryTreeItem()) {
2092 startComponentName = pStartComponent->getLibraryTreeItem()->getNameStructure();
2093 }
2094 if (pComponent->getLibraryTreeItem()) {
2095 endComponentName = pComponent->getLibraryTreeItem()->getNameStructure();
2096 }
2097 } else {
2098 int numberOfStartComponentConnections = numberOfComponentConnections(pStartComponent);
2099 if (pStartComponent->getParentComponent()) {
2100 if (pStartComponent->isConnectorSizing()) {
2101 startComponentName = QString("%1.%2[%3]").arg(pStartComponent->getRootParentComponent()->getName()).arg(pStartComponent->getName()).arg(++numberOfStartComponentConnections);
2102 } else {
2103 startComponentName = QString("%1.%2").arg(pStartComponent->getRootParentComponent()->getName()).arg(pStartComponent->getName());
2104 }
2105 } else {
2106 if (pStartComponent->isConnectorSizing()) {
2107 startComponentName = QString("%1[%2]").arg(pStartComponent->getName()).arg(++numberOfStartComponentConnections);
2108 } else {
2109 startComponentName = pStartComponent->getName();
2110 }
2111 }
2112 int numberOfEndComponentConnections = numberOfComponentConnections(pComponent);
2113 if (pComponent->getParentComponent()) {
2114 if (pComponent->isConnectorSizing()) {
2115 endComponentName = QString("%1.%2[%3]").arg(pComponent->getRootParentComponent()->getName()).arg(pComponent->getName()).arg(++numberOfEndComponentConnections);
2116 } else {
2117 endComponentName = QString("%1.%2").arg(pComponent->getRootParentComponent()->getName()).arg(pComponent->getName());
2118 }
2119 } else {
2120 if (pComponent->isConnectorSizing()) {
2121 endComponentName = QString("%1[%2]").arg(pComponent->getName()).arg(++numberOfEndComponentConnections);
2122 } else {
2123 endComponentName = pComponent->getName();
2124 }
2125 }
2126 }
2127 mpConnectionLineAnnotation->setStartComponentName(startComponentName);
2128 mpConnectionLineAnnotation->setEndComponentName(endComponentName);
2129 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::CompositeModel) {
2130 CompositeModelEditor* editor = dynamic_cast<CompositeModelEditor*>(mpModelWidget->getEditor());
2131 if (!editor->okToConnect(mpConnectionLineAnnotation)) {
2132 removeCurrentConnection();
2133 }
2134 else {
2135 CompositeModelConnectionAttributes *pCompositeModelConnectionAttributes;
2136 pCompositeModelConnectionAttributes = new CompositeModelConnectionAttributes(this, mpConnectionLineAnnotation, false, MainWindow::instance());
2137 // if user cancels the array connection
2138 if (!pCompositeModelConnectionAttributes->exec()) {
2139 removeCurrentConnection();
2140 }
2141 }
2142 } else {
2143 mpModelWidget->getUndoStack()->push(new AddConnectionCommand(mpConnectionLineAnnotation, true));
2144 mpModelWidget->getLibraryTreeItem()->emitConnectionAdded(mpConnectionLineAnnotation);
2145 mpModelWidget->updateModelText();
2146 }
2147 }
2148 setIsCreatingConnection(false);
2149 }
2150 }
2151}
2152
2153/*!
2154 * \brief GraphicsView::removeCurrentConnection
2155 * Removes the current connecting connector from the model.
2156 */
2157void GraphicsView::removeCurrentConnection()
2158{
2159 if (isCreatingConnection()) {
2160 setIsCreatingConnection(false);
2161 removeItem(mpConnectionLineAnnotation);
2162 delete mpConnectionLineAnnotation;
2163 mpConnectionLineAnnotation = 0;
2164 }
2165}
2166
2167void GraphicsView::addTransition(Component *pComponent)
2168{
2169 // When clicking the start state
2170 if (!isCreatingTransition()) {
2171 QPointF startPos = snapPointToGrid(pComponent->mapToScene(pComponent->boundingRect().center()));
2172 mpTransitionLineAnnotation = new LineAnnotation(LineAnnotation::TransitionType, pComponent, this);
2173 mpTransitionLineAnnotation->getTextAnnotation()->setVisible(false);
2174 setIsCreatingTransition(true);
2175 mpTransitionLineAnnotation->addPoint(startPos);
2176 mpTransitionLineAnnotation->addPoint(startPos);
2177 mpTransitionLineAnnotation->addPoint(startPos);
2178 } else if (isCreatingTransition()) { // When clicking the end state
2179 mpTransitionLineAnnotation->setEndComponent(pComponent);
2180 // Remove reduntant points so that Liang Barsky algorithm can work well.
2181 mpTransitionLineAnnotation->removeRedundantPointsGeometriesAndCornerItems();
2182 QList<QPointF> points = mpTransitionLineAnnotation->getPoints();
2183 // Find the start state intersection point.
2184 QRectF sceneRectF = mpTransitionLineAnnotation->getStartComponent()->sceneBoundingRect();
2185 QList<QPointF> newPos = Utilities::liangBarskyClipper(sceneRectF.topLeft().x(), sceneRectF.topLeft().y(),
2186 sceneRectF.bottomRight().x(), sceneRectF.bottomRight().y(),
2187 points.at(0).x(), points.at(0).y(),
2188 points.at(1).x(), points.at(1).y());
2189 mpTransitionLineAnnotation->updateStartPoint(snapPointToGrid(newPos.at(1)));
2190 // Find the end state intersection point.
2191 sceneRectF = pComponent->sceneBoundingRect();
2192 newPos = Utilities::liangBarskyClipper(sceneRectF.topLeft().x(), sceneRectF.topLeft().y(),
2193 sceneRectF.bottomRight().x(), sceneRectF.bottomRight().y(),
2194 points.at(points.size() - 2).x(), points.at(points.size() - 2).y(),
2195 points.at(points.size() - 1).x(), points.at(points.size() - 1).y());
2196 mpTransitionLineAnnotation->updateEndPoint(snapPointToGrid(newPos.at(0)));
2197 mpTransitionLineAnnotation->update();
2198 // check if connection is valid
2199 Component *pStartComponent = mpTransitionLineAnnotation->getStartComponent();
2200 if (pStartComponent == pComponent) {
2201 QMessageBox::information(MainWindow::instance(), QString(Helper::applicationName).append(" - ").append(Helper::information),
2202 GUIMessages::getMessage(GUIMessages::SAME_COMPONENT_CONNECT), Helper::ok);
2203 removeCurrentTransition();
2204 } else {
2205 QString startComponentName, endComponentName;
2206 if (pStartComponent->getParentComponent()) {
2207 startComponentName = QString(pStartComponent->getRootParentComponent()->getName()).append(".").append(pStartComponent->getName());
2208 } else {
2209 startComponentName = pStartComponent->getName();
2210 }
2211 if (pComponent->getParentComponent()) {
2212 endComponentName = QString(pComponent->getRootParentComponent()->getName()).append(".").append(pComponent->getName());
2213 } else {
2214 endComponentName = pComponent->getName();
2215 }
2216 mpTransitionLineAnnotation->setStartComponentName(startComponentName);
2217 mpTransitionLineAnnotation->setEndComponentName(endComponentName);
2218 CreateOrEditTransitionDialog *pCreateOrEditTransitionDialog = new CreateOrEditTransitionDialog(this, mpTransitionLineAnnotation, false,
2219 MainWindow::instance());
2220 if (!pCreateOrEditTransitionDialog->exec()) {
2221 removeCurrentTransition();
2222 }
2223 }
2224 setIsCreatingTransition(false);
2225 }
2226}
2227
2228/*!
2229 * \brief GraphicsView::removeCurrentTransition
2230 * Removes the current connecting transition from the model.
2231 */
2232void GraphicsView::removeCurrentTransition()
2233{
2234 if (isCreatingTransition()) {
2235 setIsCreatingTransition(false);
2236 delete mpTransitionLineAnnotation;
2237 mpTransitionLineAnnotation = 0;
2238 }
2239}
2240
2241/*!
2242 * \brief GraphicsView::deleteConnection
2243 * Deletes the connection from the class.
2244 * \param pConnectionLineAnnotation - is a pointer to the connection to delete.
2245 */
2246void GraphicsView::deleteConnection(LineAnnotation *pConnectionLineAnnotation)
2247{
2248 pConnectionLineAnnotation->setSelected(false);
2249 // if deleting a bus connection
2250 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
2251 if (pConnectionLineAnnotation->getStartComponent()->getLibraryTreeItem()
2252 && pConnectionLineAnnotation->getStartComponent()->getLibraryTreeItem()->getOMSBusConnector()
2253 && pConnectionLineAnnotation->getEndComponent()->getLibraryTreeItem()
2254 && pConnectionLineAnnotation->getEndComponent()->getLibraryTreeItem()->getOMSBusConnector()) {
2255 oms_busconnector_t *pStartBus = pConnectionLineAnnotation->getStartComponent()->getLibraryTreeItem()->getOMSBusConnector();
2256 oms_busconnector_t *pEndBus = pConnectionLineAnnotation->getEndComponent()->getLibraryTreeItem()->getOMSBusConnector();
2257 // start bus connectors
2258 QStringList startBusConnectors;
2259 if (pStartBus->connectors) {
2260 for (int i = 0; pStartBus->connectors[i] ; ++i) {
2261 startBusConnectors.append(QString(pStartBus->connectors[i]));
2262 }
2263 }
2264 // end bus connectors
2265 QStringList endBusConnectors;
2266 if (pEndBus->connectors) {
2267 for (int i = 0; pEndBus->connectors[i] ; ++i) {
2268 endBusConnectors.append(QString(pEndBus->connectors[i]));
2269 }
2270 }
2271 // Delete the atomic connections before deleting the actual bus connection.
2272 foreach (LineAnnotation *pAtomicConnectionLineAnnotation, mConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pAtomicConnectionLineAnnotation = *_container_.i; _container_
.control; _container_.control = 0)
{
2273 if (pAtomicConnectionLineAnnotation->getOMSConnectionType() == oms_connection_single) {
2274 if (pStartBus->connectors) {
2275 for (int i = 0; pStartBus->connectors[i] ; ++i) {
2276 if (startBusConnectors.contains(pAtomicConnectionLineAnnotation->getStartComponent()->getName())
2277 && endBusConnectors.contains(pAtomicConnectionLineAnnotation->getEndComponent()->getName())) {
2278 mpModelWidget->getUndoStack()->push(new DeleteConnectionCommand(pAtomicConnectionLineAnnotation));
2279 break;
2280 }
2281 }
2282 }
2283 }
2284 }
2285 }
2286 }
2287 // Delete the connection
2288 mpModelWidget->getUndoStack()->push(new DeleteConnectionCommand(pConnectionLineAnnotation));
2289}
2290
2291/*!
2292 * \brief GraphicsView::deleteTransition
2293 * Deletes the transition from the class.
2294 * \param pTransitionLineAnnotation - is a pointer to the transition to delete.
2295 */
2296void GraphicsView::deleteTransition(LineAnnotation *pTransitionLineAnnotation)
2297{
2298 pTransitionLineAnnotation->setSelected(false);
2299 mpModelWidget->getUndoStack()->push(new DeleteTransitionCommand(pTransitionLineAnnotation));
2300}
2301
2302/*!
2303 * \brief GraphicsView::deleteInitialState
2304 * Deletes an initial state from the class.
2305 * \param pInitialLineAnnotation - is a pointer to the initial state to delete.
2306 */
2307void GraphicsView::deleteInitialState(LineAnnotation *pInitialLineAnnotation)
2308{
2309 pInitialLineAnnotation->setSelected(false);
2310 mpModelWidget->getUndoStack()->push(new DeleteInitialStateCommand(pInitialLineAnnotation));
2311}
2312
2313//! Resets zoom factor to 100%.
2314//! @see zoomIn()
2315//! @see zoomOut()
2316void GraphicsView::resetZoom()
2317{
2318 resetMatrix();
2319 scale(1.0, -1.0);
2320 setIsCustomScale(false);
2321 resizeEvent(new QResizeEvent(QSize(0,0), QSize(0,0)));
2322}
2323
2324//! Increases zoom factor by 12%.
2325//! @see resetZoom()
2326//! @see zoomOut()
2327void GraphicsView::zoomIn()
2328{
2329 // zoom in limitation max: 1000%
2330 if (matrix().m11() < 34 && matrix().m22() > -34) {
2331 setIsCustomScale(true);
2332 scale(1.12, 1.12);
2333 }
2334}
2335
2336//! Decreases zoom factor by 12%.
2337//! @see resetZoom()
2338//! @see zoomIn()
2339void GraphicsView::zoomOut()
2340{
2341 // zoom out limitation min: 10%
2342 if (matrix().m11() > 0.2 && matrix().m22() < -0.2) {
2343 setIsCustomScale(true);
2344 scale(1/1.12, 1/1.12);
2345 }
2346}
2347
2348/*!
2349 * \brief GraphicsView::selectAll
2350 * Selects all shapes, components and connectors.
2351 */
2352void GraphicsView::selectAll()
2353{
2354 foreach (QGraphicsItem *pGraphicsItem, items())for (auto _container_ = QtPrivate::qMakeForeachContainer(items
()); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QGraphicsItem
*pGraphicsItem = *_container_.i; _container_.control; _container_
.control = 0)
{
2355 pGraphicsItem->setSelected(true);
2356 }
2357}
2358
2359/*!
2360 * \brief GraphicsView::cutItems
2361 * Slot activated when mpCutAction triggered SIGNAL is raised.
2362 */
2363void GraphicsView::cutItems()
2364{
2365 copyItems(true);
2366}
2367
2368/*!
2369 * \brief GraphicsView::copyItems
2370 * Slot activated when mpCopyAction triggered SIGNAL is raised.
2371 */
2372void GraphicsView::copyItems()
2373{
2374 copyItems(false);
2375}
2376
2377/*!
2378 * \brief GraphicsView::copyItems
2379 * Copies the selected items to the clipboard.
2380 * \param cut - flag to know if we should cut the items or not.
2381 */
2382void GraphicsView::copyItems(bool cut)
2383{
2384 QList<QGraphicsItem*> selectedItems = scene()->selectedItems();
2385 if (!selectedItems.isEmpty()) {
2386 QStringList components, connections, shapes, allItems;
2387 connections << "equation";
2388 MimeData *pMimeData = new MimeData;
2389 for (int i = 0 ; i < selectedItems.size() ; i++) {
2390 if (Component *pComponent = dynamic_cast<Component*>(selectedItems.at(i))) {
2391 // we need to get the modifiers here instead of inside pasteItems() because in case of cut the component is removed and then we can't fetch the modifiers.
2392 pComponent->getComponentInfo()->getModifiersMap(MainWindow::instance()->getOMCProxy(), pComponent->getGraphicsView()->getModelWidget()->getLibraryTreeItem()->getNameStructure(), pComponent);
2393 pMimeData->addComponent(pComponent);
2394 components << QString("%1 %2%3 %4;").arg(pComponent->getComponentInfo()->getClassName(), pComponent->getName(), "", pComponent->getPlacementAnnotation(true));
2395 } else if (ShapeAnnotation *pShapeAnnotation = dynamic_cast<ShapeAnnotation*>(selectedItems.at(i))) {
2396 LineAnnotation *pLineAnnotation = dynamic_cast<LineAnnotation*>(selectedItems.at(i));
2397 if (pLineAnnotation && pLineAnnotation->getLineType() == LineAnnotation::ConnectionType) {
2398 // Only consider the connection for copying if both the start and the end components are selected.
2399 if (pLineAnnotation->getStartComponent()->getRootParentComponent()->isSelected() && pLineAnnotation->getEndComponent()->getRootParentComponent()->isSelected()) {
2400 pMimeData->addConnection(pLineAnnotation);
2401 connections << QString("connect(%1, %2) annotation %3;").arg(pLineAnnotation->getStartComponentName(), pLineAnnotation->getEndComponentName(), pLineAnnotation->getShapeAnnotation());
2402 }
2403 } else {
2404 pMimeData->addShape(pShapeAnnotation);
2405 shapes << pShapeAnnotation->getShapeAnnotation();
2406 }
2407 }
2408 }
2409 allItems << components << connections << (shapes.isEmpty() ? "" : QString("annotation (%1)").arg(shapes.join(", ")));
2410 pMimeData->setText(allItems.join("\n"));
2411 QApplication::clipboard()->setMimeData(pMimeData);
2412 // if cut flag is set
2413 if (cut) {
2414 deleteItems();
2415 }
2416 }
2417}
2418
2419/*!
2420 * \brief GraphicsView::modelicaGraphicsViewContextMenu
2421 * Creates a context menu for Modelica class.
2422 * \param pMenu
2423 */
2424void GraphicsView::modelicaGraphicsViewContextMenu(QMenu *pMenu)
2425{
2426 if (!isVisualizationView()) {
2427 QMenu *pExportMenu = pMenu->addMenu(Helper::exportt);
2428 pExportMenu->addAction(MainWindow::instance()->getExportToClipboardAction());
2429 pExportMenu->addAction(MainWindow::instance()->getExportAsImageAction());
2430 pExportMenu->addAction(MainWindow::instance()->getExportToOMNotebookAction());
2431 pMenu->addSeparator();
2432 mpPasteAction->setEnabled(QApplication::clipboard()->mimeData()->hasFormat(Helper::cutCopyPasteFormat) && qobject_cast<const MimeData*>(QApplication::clipboard()->mimeData()));
2433 pMenu->addAction(mpPasteAction);
2434 pMenu->addSeparator();
2435 pMenu->addAction(MainWindow::instance()->getPrintModelAction());
2436 pMenu->addSeparator();
2437 }
2438 pMenu->addAction(mpPropertiesAction);
2439}
2440
2441/*!
2442 * \brief GraphicsView::modelicaOneShapeContextMenu
2443 * Creates a context menu for Modelica class when one shape is right clicked.
2444 * \param pShapeAnnotation
2445 * \param pMenu
2446 */
2447void GraphicsView::modelicaOneShapeContextMenu(ShapeAnnotation *pShapeAnnotation, QMenu *pMenu)
2448{
2449 LineAnnotation *pLineAnnotation = dynamic_cast<LineAnnotation*>(pShapeAnnotation);
2450 pMenu->addAction(pShapeAnnotation->getShapePropertiesAction());
2451 pMenu->addSeparator();
2452 pMenu->addAction(mpDeleteAction);
2453 pMenu->addSeparator();
2454 pMenu->addAction(mpCutAction);
2455 pMenu->addAction(mpCopyAction);
2456 if (pLineAnnotation && pLineAnnotation->getLineType() == LineAnnotation::ConnectionType) {
2457 // nothing special for connection
2458 } else if (pLineAnnotation && pLineAnnotation->getLineType() == LineAnnotation::TransitionType) {
2459 pMenu->addSeparator();
2460 pMenu->addAction(pShapeAnnotation->getEditTransitionAction());
2461 } else if (pLineAnnotation && pLineAnnotation->getLineType() == LineAnnotation::ShapeType) {
2462 pMenu->addAction(mpDuplicateAction);
2463 pMenu->addSeparator();
2464 pMenu->addAction(mpManhattanizeAction);
2465 } else {
2466 pMenu->addAction(mpDuplicateAction);
2467 pMenu->addSeparator();
2468 pMenu->addAction(mpRotateClockwiseAction);
2469 pMenu->addAction(mpRotateAntiClockwiseAction);
2470 pMenu->addSeparator();
2471 pMenu->addAction(mpBringToFrontAction);
2472 pMenu->addAction(mpBringForwardAction);
2473 pMenu->addAction(mpSendToBackAction);
2474 pMenu->addAction(mpSendBackwardAction);
2475 }
2476}
2477
2478/*!
2479 * \brief GraphicsView::modelicaOneComponentContextMenu
2480 * Creates a context menu for Modelica class when one component is right clicked.
2481 * \param pComponent
2482 * \param pMenu
2483 */
2484void GraphicsView::modelicaOneComponentContextMenu(Component *pComponent, QMenu *pMenu)
2485{
2486 pMenu->addAction(pComponent->getParametersAction());
2487 pMenu->addAction(pComponent->getAttributesAction());
2488 pMenu->addSeparator();
2489 pMenu->addAction(pComponent->getOpenClassAction());
2490 pMenu->addSeparator();
2491 pMenu->addAction(mpDeleteAction);
2492 pMenu->addSeparator();
2493 pMenu->addAction(mpCutAction);
2494 pMenu->addAction(mpCopyAction);
2495 pMenu->addAction(mpDuplicateAction);
2496 pMenu->addSeparator();
2497 pMenu->addAction(mpRotateClockwiseAction);
2498 pMenu->addAction(mpRotateAntiClockwiseAction);
2499 pMenu->addAction(mpFlipHorizontalAction);
2500 pMenu->addAction(mpFlipVerticalAction);
2501}
2502
2503/*!
2504 * \brief GraphicsView::modelicaMultipleItemsContextMenu
2505 * Creates a context menu for Modelica class when multiple items are right clicked.
2506 * \param pMenu
2507 */
2508void GraphicsView::modelicaMultipleItemsContextMenu(QMenu *pMenu)
2509{
2510 pMenu->addAction(mpDeleteAction);
2511 pMenu->addSeparator();
2512 pMenu->addAction(mpCutAction);
2513 pMenu->addAction(mpCopyAction);
2514 pMenu->addAction(mpDuplicateAction);
2515 pMenu->addSeparator();
2516 pMenu->addAction(mpRotateClockwiseAction);
2517 pMenu->addAction(mpRotateAntiClockwiseAction);
2518}
2519
2520/*!
2521 * \brief GraphicsView::compositeModelGraphicsViewContextMenu
2522 * Creates a context menu for Composite model.
2523 * \param pMenu
2524 */
2525void GraphicsView::compositeModelGraphicsViewContextMenu(QMenu *pMenu)
2526{
2527 QMenu *pExportMenu = pMenu->addMenu(Helper::exportt);
2528 pExportMenu->addAction(MainWindow::instance()->getExportToClipboardAction());
2529 pExportMenu->addAction(MainWindow::instance()->getExportAsImageAction());
2530 pMenu->addSeparator();
2531 pMenu->addAction(MainWindow::instance()->getPrintModelAction());
2532 pMenu->addSeparator();
2533 pMenu->addAction(mpRenameAction);
2534 pMenu->addSeparator();
2535 pMenu->addAction(mpSimulationParamsAction);
2536}
2537
2538/*!
2539 * \brief GraphicsView::compositeModelOneShapeContextMenu
2540 * Creates a context menu for Composite model when one shape is right clicked.
2541 * \param pShapeAnnotation
2542 * \param pMenu
2543 */
2544void GraphicsView::compositeModelOneShapeContextMenu(ShapeAnnotation *pShapeAnnotation, QMenu *pMenu)
2545{
2546 pMenu->addAction(pShapeAnnotation->getShapeAttributesAction());
2547 //Only show align interfaces action for bidirectional connections
2548 LineAnnotation *pConnectionLineAnnotation = dynamic_cast<LineAnnotation*>(pShapeAnnotation);
2549 if (pConnectionLineAnnotation) {
2550 QString startName = pConnectionLineAnnotation->getStartComponentName();
2551 QString endName = pConnectionLineAnnotation->getEndComponentName();
2552 CompositeModelEditor *pEditor = dynamic_cast<CompositeModelEditor*>(mpModelWidget->getEditor());
2553 if (pEditor && pEditor->getInterfaceCausality(startName) == StringHandler::getTLMCausality(StringHandler::TLMBidirectional) &&
2554 pEditor->getInterfaceCausality(endName) == StringHandler::getTLMCausality(StringHandler::TLMBidirectional)) {
2555 pMenu->addSeparator();
2556 pMenu->addAction(pShapeAnnotation->getAlignInterfacesAction());
2557 }
2558 }
2559 pMenu->addSeparator();
2560 pMenu->addAction(mpDeleteAction);
2561}
2562
2563/*!
2564 * \brief GraphicsView::compositeModelOneComponentContextMenu
2565 * Creates a context menu for Composite model when one component is right clicked.
2566 * \param pComponent
2567 * \param pMenu
2568 */
2569void GraphicsView::compositeModelOneComponentContextMenu(Component *pComponent, QMenu *pMenu)
2570{
2571 pMenu->addAction(pComponent->getFetchInterfaceDataAction());
2572 pMenu->addSeparator();
2573 pMenu->addAction(pComponent->getSubModelAttributesAction());
2574 pMenu->addSeparator();
2575 pMenu->addAction(mpDeleteAction);
2576 pMenu->addSeparator();
2577 pMenu->addAction(mpRotateClockwiseAction);
2578 pMenu->addAction(mpRotateAntiClockwiseAction);
2579 pMenu->addAction(mpFlipHorizontalAction);
2580 pMenu->addAction(mpFlipVerticalAction);
2581}
2582
2583/*!
2584 * \brief GraphicsView::compositeModelMultipleItemsContextMenu
2585 * Creates a context menu for Composite model when multiple items are right clicked.
2586 * \param pMenu
2587 */
2588void GraphicsView::compositeModelMultipleItemsContextMenu(QMenu *pMenu)
2589{
2590 pMenu->addAction(mpDeleteAction);
2591 pMenu->addSeparator();
2592 pMenu->addAction(mpRotateClockwiseAction);
2593 pMenu->addAction(mpRotateAntiClockwiseAction);
2594 pMenu->addAction(mpFlipHorizontalAction);
2595 pMenu->addAction(mpFlipVerticalAction);
2596}
2597
2598/*!
2599 * \brief GraphicsView::omsGraphicsViewContextMenu
2600 * Creates a context menu for OMSimulator model.
2601 * \param pMenu
2602 */
2603void GraphicsView::omsGraphicsViewContextMenu(QMenu *pMenu)
2604{
2605 QMenu *pExportMenu = pMenu->addMenu(Helper::exportt);
2606 pExportMenu->addAction(MainWindow::instance()->getExportToClipboardAction());
2607 pExportMenu->addAction(MainWindow::instance()->getExportAsImageAction());
2608 pMenu->addSeparator();
2609 pMenu->addAction(MainWindow::instance()->getPrintModelAction());
2610 pMenu->addSeparator();
2611 if (mpModelWidget->getLibraryTreeItem()->isTopLevel() || mpModelWidget->getLibraryTreeItem()->isSystemElement()) {
2612 pMenu->addSeparator();
2613 pMenu->addAction(MainWindow::instance()->getAddSystemAction());
2614 if (mpModelWidget->getLibraryTreeItem()->isTopLevel()) {
2615 pMenu->addSeparator();
2616 pMenu->addAction(mpPropertiesAction);
2617 }
2618 }
2619 if (mpModelWidget->getLibraryTreeItem()->isSystemElement() || mpModelWidget->getLibraryTreeItem()->isComponentElement()) {
2620 pMenu->addSeparator();
2621 pMenu->addAction(MainWindow::instance()->getAddOrEditIconAction());
2622 pMenu->addAction(MainWindow::instance()->getDeleteIconAction());
2623 pMenu->addSeparator();
2624 pMenu->addAction(MainWindow::instance()->getAddConnectorAction());
2625 pMenu->addAction(MainWindow::instance()->getAddBusAction());
2626 pMenu->addAction(MainWindow::instance()->getAddTLMBusAction());
2627 if (mpModelWidget->getLibraryTreeItem()->isSystemElement()) {
2628 pMenu->addSeparator();
2629 pMenu->addAction(MainWindow::instance()->getAddSubModelAction());
2630 pMenu->addSeparator();
2631 pMenu->addAction(mpPropertiesAction);
2632 }
2633 }
2634}
2635
2636/*!
2637 * \brief GraphicsView::omsOneShapeContextMenu
2638 * Creates a context menu for OMSimulator model when one shape is right clicked.
2639 * \param pShapeAnnotation
2640 * \param pMenu
2641 */
2642void GraphicsView::omsOneShapeContextMenu(ShapeAnnotation *pShapeAnnotation, QMenu *pMenu)
2643{
2644 BitmapAnnotation *pBitmapAnnotation = dynamic_cast<BitmapAnnotation*>(pShapeAnnotation);
2645 if (pBitmapAnnotation && mpModelWidget->getLibraryTreeItem()->getOMSElement()) {
2646 pMenu->addAction(MainWindow::instance()->getAddOrEditIconAction());
2647 pMenu->addAction(MainWindow::instance()->getDeleteIconAction());
2648 }
2649}
2650
2651/*!
2652 * \brief GraphicsView::omsOneComponentContextMenu
2653 * Creates a context menu for OMSimulator model when one component is right clicked.
2654 * \param pComponent
2655 * \param pMenu
2656 */
2657void GraphicsView::omsOneComponentContextMenu(Component *pComponent, QMenu *pMenu)
2658{
2659 if (pComponent->getLibraryTreeItem()->isSystemElement() || pComponent->getLibraryTreeItem()->isComponentElement()) {
2660 pMenu->addAction(pComponent->getElementPropertiesAction());
2661 }
2662 pMenu->addSeparator();
2663 pMenu->addAction(mpDeleteAction);
2664 pMenu->addSeparator();
2665 pMenu->addAction(mpRotateClockwiseAction);
2666 pMenu->addAction(mpRotateAntiClockwiseAction);
2667 pMenu->addAction(mpFlipHorizontalAction);
2668 pMenu->addAction(mpFlipVerticalAction);
2669}
2670
2671/*!
2672 * \brief GraphicsView::omsMultipleItemsContextMenu
2673 * Creates a context menu for OMSimulator model when multiple items are right clicked.
2674 * \param pMenu
2675 */
2676void GraphicsView::omsMultipleItemsContextMenu(QMenu *pMenu)
2677{
2678 pMenu->addAction(mpDeleteAction);
2679 pMenu->addSeparator();
2680 pMenu->addAction(mpRotateClockwiseAction);
2681 pMenu->addAction(mpRotateAntiClockwiseAction);
2682 pMenu->addAction(mpFlipHorizontalAction);
2683 pMenu->addAction(mpFlipVerticalAction);
2684}
2685
2686/*!
2687 * \brief replaceComponentNameInConnection
2688 * Helper function to GraphicsView::pasteItems(). Updates the connections component names if the component name is changed during paste operation.
2689 * \param oldConnectionComponentName
2690 * \param newConnectionComponentName
2691 * \return
2692 */
2693QString replaceComponentNameInConnection(const QString &oldConnectionComponentName, const QString &newConnectionComponentName)
2694{
2695 QString connectionComponentName;
2696 QStringList connectionComponentList = oldConnectionComponentName.split(".");
2697 if (connectionComponentList.size() > 1) {
2698 connectionComponentName = QString("%1.%2").arg(newConnectionComponentName, connectionComponentList.at(1));
2699 } else {
2700 connectionComponentName = connectionComponentList.at(0);
2701 if (connectionComponentName.contains("[")) {
2702 connectionComponentName = QString("%1%2").arg(newConnectionComponentName, connectionComponentName.mid(connectionComponentName.indexOf("[")));
2703 } else {
2704 connectionComponentName = newConnectionComponentName;
2705 }
2706 }
2707 return connectionComponentName;
2708}
2709
2710/*!
2711 * \brief GraphicsView::pasteItems
2712 * Slot activated when mpPasteAction triggered SIGNAL is raised.
2713 * Reads the items from the clipboard and adds them to the view.
2714 */
2715void GraphicsView::pasteItems()
2716{
2717 QClipboard *pClipboard = QApplication::clipboard();
2718 if (pClipboard->mimeData()->hasFormat(Helper::cutCopyPasteFormat)) {
2719 if (const MimeData *pMimeData = qobject_cast<const MimeData*>(pClipboard->mimeData())) {
2720 mpModelWidget->beginMacro("Paste items from clipboard");
2721 // map to store
2722 QMap<Component*, QString> renamedComponents;
2723 // paste the components
2724 foreach (Component *pComponent, pMimeData->getComponents())for (auto _container_ = QtPrivate::qMakeForeachContainer(pMimeData
->getComponents()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pComponent = *_container_.i; _container_.control
; _container_.control = 0)
{
2725 QString name = pComponent->getName();
2726 if (!checkComponentName(name)) {
2727 name = getUniqueComponentName(StringHandler::toCamelCase(pComponent->getLibraryTreeItem()->getName()));
2728 renamedComponents.insert(pComponent, name);
2729 }
2730 ComponentInfo *pComponentInfo = new ComponentInfo(pComponent->getComponentInfo());
2731 pComponentInfo->setName(name);
2732 addComponentToView(name, pComponent->getLibraryTreeItem(), pComponent->getOMCPlacementAnnotation(QPointF(0, 0)), QPointF(0, 0), pComponentInfo, true, true, true);
2733 Component *pNewComponent = mComponentsList.last();
2734 pNewComponent->setSelected(true);
2735 }
2736 // paste the connections
2737 foreach (LineAnnotation *pConnectionLineAnnotation, pMimeData->getConnections())for (auto _container_ = QtPrivate::qMakeForeachContainer(pMimeData
->getConnections()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (LineAnnotation *pConnectionLineAnnotation = *_container_
.i; _container_.control; _container_.control = 0)
{
2738 QString startComponentName = pConnectionLineAnnotation->getStartComponentName();
2739 if (renamedComponents.contains(pConnectionLineAnnotation->getStartComponent()->getRootParentComponent())) {
2740 startComponentName = replaceComponentNameInConnection(startComponentName, renamedComponents.value(pConnectionLineAnnotation->getStartComponent()->getRootParentComponent()));
2741 }
2742 QString endComponentName = pConnectionLineAnnotation->getEndComponentName();
2743 if (renamedComponents.contains(pConnectionLineAnnotation->getEndComponent()->getRootParentComponent())) {
2744 endComponentName = replaceComponentNameInConnection(endComponentName, renamedComponents.value(pConnectionLineAnnotation->getEndComponent()->getRootParentComponent()));
2745 }
2746 QStringList connectionList;
2747 connectionList << startComponentName << endComponentName << QString("");
2748 QString connectionAnnotation = pConnectionLineAnnotation->getOMCShapeAnnotationWithShapeName();
2749 mpModelWidget->addConnection(connectionList, connectionAnnotation, true, true);
2750 }
2751 // paste the shapes
2752 QStringList shapes;
2753 foreach (ShapeAnnotation *pShapeAnnotation, pMimeData->getShapes())for (auto _container_ = QtPrivate::qMakeForeachContainer(pMimeData
->getShapes()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (ShapeAnnotation *pShapeAnnotation = *_container_.i; _container_
.control; _container_.control = 0)
{
2754 shapes << pShapeAnnotation->getOMCShapeAnnotationWithShapeName();
2755 }
2756 if (!shapes.isEmpty()) {
2757 mpModelWidget->drawModelIconDiagramShapes(shapes, this, true);
2758 }
2759 // update the model text
2760 mpModelWidget->updateClassAnnotationIfNeeded();
2761 mpModelWidget->updateModelText();
2762 mpModelWidget->endMacro();
2763 }
2764 }
2765}
2766
2767/*!
2768 * \brief GraphicsView::clearSelection
2769 * Clears the selection of all shapes, components and connectors.
2770 * Selects the passed item if its valid.
2771 * \param pSelectGraphicsItem
2772 */
2773void GraphicsView::clearSelection(QGraphicsItem *pSelectGraphicsItem)
2774{
2775 foreach (QGraphicsItem *pGraphicsItem, items())for (auto _container_ = QtPrivate::qMakeForeachContainer(items
()); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QGraphicsItem
*pGraphicsItem = *_container_.i; _container_.control; _container_
.control = 0)
{
2776 pGraphicsItem->setSelected(false);
2777 }
2778 // only select the item if it is valid
2779 if (pSelectGraphicsItem) {
2780 pSelectGraphicsItem->setSelected(true);
2781 }
2782}
2783
2784/*!
2785 * \brief GraphicsView::addClassAnnotation
2786 * Adds the annotation string of Icon and Diagram layer to the model. Also creates the model icon in the tree.
2787 * If some custom models are cross referenced then update them accordingly.
2788 * \param alwaysAdd - if false then skip the OMCProxy::addClassAnnotation() if annotation is empty.
2789 */
2790void GraphicsView::addClassAnnotation(bool alwaysAdd)
2791{
2792 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) {
2793 return;
2794 }
2795 MainWindow *pMainWindow = MainWindow::instance();
2796 // coordinate system
2797 QStringList coOrdinateSystemList;
2798 qreal x1 = mCoOrdinateSystem.getLeft();
2799 qreal y1 = mCoOrdinateSystem.getBottom();
2800 qreal x2 = mCoOrdinateSystem.getRight();
2801 qreal y2 = mCoOrdinateSystem.getTop();
2802 if (mCoOrdinateSystem.hasLeft() && mCoOrdinateSystem.hasBottom() && mCoOrdinateSystem.hasRight() && mCoOrdinateSystem.hasTop()) {
2803 coOrdinateSystemList.append(QString("extent={{%1, %2}, {%3, %4}}").arg(x1).arg(y1).arg(x2).arg(y2));
2804 }
2805 // add the preserveAspectRatio
2806 if (mCoOrdinateSystem.hasPreserveAspectRatio()) {
2807 coOrdinateSystemList.append(QString("preserveAspectRatio=%1").arg(mCoOrdinateSystem.getPreserveAspectRatio() ? "true" : "false"));
2808 }
2809 // add the initial scale
2810 if (mCoOrdinateSystem.hasInitialScale()) {
2811 coOrdinateSystemList.append(QString("initialScale=%1").arg(mCoOrdinateSystem.getInitialScale()));
2812 }
2813 // add the grid
2814 if (mCoOrdinateSystem.hasHorizontal() && mCoOrdinateSystem.hasVertical()) {
2815 coOrdinateSystemList.append(QString("grid={%1, %2}").arg(mCoOrdinateSystem.getHorizontal()).arg(mCoOrdinateSystem.getVertical()));
2816 }
2817 // graphics annotations
2818 QStringList graphicsList;
2819 if (mShapesList.size() > 0) {
2820 foreach (ShapeAnnotation *pShapeAnnotation, mShapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mShapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (ShapeAnnotation
*pShapeAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
2821 /* Don't add the inherited shape to the addClassAnnotation. */
2822 if (!pShapeAnnotation->isInheritedShape()) {
2823 graphicsList.append(pShapeAnnotation->getShapeAnnotation());
2824 }
2825 }
2826 }
2827 // build the annotation string
2828 QString annotationString;
2829 QString viewType = (mViewType == StringHandler::Icon) ? "Icon" : "Diagram";
2830 if (coOrdinateSystemList.size() > 0 && graphicsList.size() > 0) {
2831 annotationString = QString("annotate=%1(coordinateSystem=CoordinateSystem(%2), graphics={%3})").arg(viewType)
2832 .arg(coOrdinateSystemList.join(",")).arg(graphicsList.join(","));
2833 } else if (coOrdinateSystemList.size() > 0) {
2834 annotationString = QString("annotate=%1(coordinateSystem=CoordinateSystem(%2))").arg(viewType).arg(coOrdinateSystemList.join(","));
2835 } else if (graphicsList.size() > 0) {
2836 annotationString = QString("annotate=%1(graphics={%2})").arg(viewType).arg(graphicsList.join(","));
2837 } else {
2838 annotationString = QString("annotate=%1()").arg(viewType);
2839 /* Ticket #3731
2840 * Return from here since we don't want empty Icon & Diagram annotations.
2841 */
2842 if (!alwaysAdd) {
2843 return;
2844 }
2845 }
2846 // add the class annotation to model through OMC
2847 if (pMainWindow->getOMCProxy()->addClassAnnotation(mpModelWidget->getLibraryTreeItem()->getNameStructure(), annotationString)) {
2848 /* When something is added/changed in the icon layer then update the LibraryTreeItem in the Library Browser */
2849 if (mViewType == StringHandler::Icon) {
2850 mpModelWidget->getLibraryTreeItem()->handleIconUpdated();
2851 }
2852 } else {
2853 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica,
2854 tr("Error in class annotation ") + pMainWindow->getOMCProxy()->getResult(),
2855 Helper::scriptingKind, Helper::errorLevel));
2856 }
2857}
2858
2859/*!
2860 * \brief GraphicsView::showGraphicsViewProperties
2861 * Opens the GraphicsViewProperties dialog.
2862 */
2863void GraphicsView::showGraphicsViewProperties()
2864{
2865 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
2866 GraphicsViewProperties *pGraphicsViewProperties = new GraphicsViewProperties(this);
2867 pGraphicsViewProperties->exec();
2868 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
2869 ModelWidget *pModelWidget = 0;
2870 if (mpModelWidget->getLibraryTreeItem()->isTopLevel()) {
2871 if (mpModelWidget->getLibraryTreeItem()->childrenSize() > 0) {
2872 LibraryTreeItem *pSystemLibraryTreeItem = mpModelWidget->getLibraryTreeItem()->childAt(0);
2873 if (pSystemLibraryTreeItem && pSystemLibraryTreeItem->getModelWidget()) {
2874 pModelWidget = pSystemLibraryTreeItem->getModelWidget();
2875 }
2876 }
2877 } else {
2878 pModelWidget = mpModelWidget;
2879 }
2880 if (pModelWidget) {
2881 SystemSimulationInformationDialog *pSystemSimulationInformationDialog = new SystemSimulationInformationDialog(pModelWidget);
2882 pSystemSimulationInformationDialog->exec();
2883 }
2884 }
2885}
2886
2887/*!
2888 * \brief GraphicsView::showSimulationParamsDialog
2889 * Opens the CompositeModelSimulationParamsDialog.
2890 */
2891void GraphicsView::showSimulationParamsDialog()
2892{
2893 CompositeModelSimulationParamsDialog *pCompositeModelSimulationParamsDialog = new CompositeModelSimulationParamsDialog(this);
2894 pCompositeModelSimulationParamsDialog->exec();
2895}
2896
2897/*!
2898 * \brief GraphicsView::showRenameDialog
2899 * Opens the RenameItemDialog.
2900 */
2901void GraphicsView::showRenameDialog()
2902{
2903 RenameItemDialog *pRenameItemDialog;
2904 pRenameItemDialog = new RenameItemDialog(mpModelWidget->getLibraryTreeItem(), MainWindow::instance());
2905 pRenameItemDialog->exec();
2906}
2907
2908/*!
2909 * \brief GraphicsView::manhattanizeItems
2910 * Manhattanize the selected items by emitting GraphicsView::manhattanize() SIGNAL.
2911 */
2912void GraphicsView::manhattanizeItems()
2913{
2914 mpModelWidget->beginMacro("Manhattanize");
2915 emit manhattanize();
2916 mpModelWidget->updateClassAnnotationIfNeeded();
2917 mpModelWidget->updateModelText();
2918 mpModelWidget->endMacro();
2919}
2920
2921/*!
2922 * \brief GraphicsView::deleteItems
2923 * Deletes the selected items by emitting GraphicsView::deleteSignal() SIGNAL.
2924 */
2925void GraphicsView::deleteItems()
2926{
2927 mpModelWidget->beginMacro("Delete items");
2928 emit deleteSignal();
2929 mpModelWidget->updateClassAnnotationIfNeeded();
2930 mpModelWidget->updateModelText();
2931 mpModelWidget->endMacro();
2932}
2933
2934/*!
2935 * \brief GraphicsView::duplicateItems
2936 * Duplicates the selected items by emitting GraphicsView::mouseDuplicate() SIGNAL.
2937 */
2938void GraphicsView::duplicateItems()
2939{
2940 mpModelWidget->beginMacro("Duplicate by mouse");
2941 emit mouseDuplicate();
2942 mpModelWidget->updateClassAnnotationIfNeeded();
2943 mpModelWidget->updateModelText();
2944 mpModelWidget->endMacro();
2945}
2946
2947/*!
2948 * \brief GraphicsView::rotateClockwise
2949 * Rotates the selected items clockwise by emitting GraphicsView::mouseRotateClockwise() SIGNAL.
2950 */
2951void GraphicsView::rotateClockwise()
2952{
2953 mpModelWidget->beginMacro("Rotate clockwise by mouse");
2954 emit mouseRotateClockwise();
2955 mpModelWidget->updateClassAnnotationIfNeeded();
2956 mpModelWidget->updateModelText();
2957 mpModelWidget->endMacro();
2958}
2959
2960/*!
2961 * \brief GraphicsView::rotateAntiClockwise
2962 * Rotates the selected items anti clockwise by emitting GraphicsView::mouseRotateAntiClockwise() SIGNAL.
2963 */
2964void GraphicsView::rotateAntiClockwise()
2965{
2966 mpModelWidget->beginMacro("Rotate anti clockwise by mouse");
2967 emit mouseRotateAntiClockwise();
2968 mpModelWidget->updateClassAnnotationIfNeeded();
2969 mpModelWidget->updateModelText();
2970 mpModelWidget->endMacro();
2971}
2972
2973/*!
2974 * \brief GraphicsView::flipHorizontal
2975 * Flips the selected items horizontally emitting GraphicsView::mouseFlipHorizontal() SIGNAL.
2976 */
2977void GraphicsView::flipHorizontal()
2978{
2979 mpModelWidget->beginMacro("Flip horizontal by mouse");
2980 emit mouseFlipHorizontal();
2981 mpModelWidget->updateClassAnnotationIfNeeded();
2982 mpModelWidget->updateModelText();
2983 mpModelWidget->endMacro();
2984}
2985
2986/*!
2987 * \brief GraphicsView::flipVertical
2988 * Flips the selected items vertically emitting GraphicsView::mouseFlipVertical() SIGNAL.
2989 */
2990void GraphicsView::flipVertical()
2991{
2992 mpModelWidget->beginMacro("Flip vertical by mouse");
2993 emit mouseFlipVertical();
2994 mpModelWidget->updateClassAnnotationIfNeeded();
2995 mpModelWidget->updateModelText();
2996 mpModelWidget->endMacro();
2997}
2998
2999/*!
3000 * \brief GraphicsView::setInitialState
3001 * Sets the state as initial.
3002 */
3003void GraphicsView::setInitialState()
3004{
3005 if (mpTransitionLineAnnotation) {
3006 QString startComponentName;
3007 if (mpTransitionLineAnnotation->getStartComponent()->getParentComponent()) {
3008 startComponentName = QString(mpTransitionLineAnnotation->getStartComponent()->getRootParentComponent()->getName()).append(".")
3009 .append(mpTransitionLineAnnotation->getStartComponent()->getName());
3010 } else {
3011 startComponentName = mpTransitionLineAnnotation->getStartComponent()->getName();
3012 }
3013 mpTransitionLineAnnotation->setStartComponentName(startComponentName);
3014 mpTransitionLineAnnotation->setEndComponentName("");
3015 mpTransitionLineAnnotation->setLineType(LineAnnotation::InitialStateType);
3016 mpModelWidget->getUndoStack()->push(new AddInitialStateCommand(mpTransitionLineAnnotation, true));
3017 mpModelWidget->updateModelText();
3018 setIsCreatingTransition(false);
3019 }
3020}
3021
3022/*!
3023 * \brief GraphicsView::cancelTransition
3024 * Cancels the current transition.
3025 */
3026void GraphicsView::cancelTransition()
3027{
3028 if (mpTransitionLineAnnotation) {
3029 removeCurrentTransition();
3030 }
3031}
3032
3033/*!
3034 * \brief GraphicsView::dragMoveEvent
3035 * Defines what happens when dragged and moved an object in a GraphicsView.
3036 * \param event - contains information of the drag operation.
3037 */
3038void GraphicsView::dragMoveEvent(QDragMoveEvent *event)
3039{
3040 // check if the class is system library or a package or a OMSimulator model
3041 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView() ||
3042 mpModelWidget->getLibraryTreeItem()->getRestriction() == StringHandler::Package ||
3043 mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
3044 event->ignore();
3045 return;
3046 }
3047 // read the mime data from the event
3048 if (event->mimeData()->hasFormat(Helper::modelicaComponentFormat) || event->mimeData()->hasFormat(Helper::modelicaFileFormat)) {
3049 event->setDropAction(Qt::CopyAction);
3050 event->accept();
3051 } else {
3052 event->ignore();
3053 }
3054}
3055
3056/*!
3057 * \brief GraphicsView::dropEvent
3058 * Defines what happens when an object is dropped in a GraphicsView.
3059 * \param event - contains information of the drop operation.
3060 */
3061void GraphicsView::dropEvent(QDropEvent *event)
3062{
3063 setFocus();
3064 MainWindow *pMainWindow = MainWindow::instance();
3065 // check mimeData
3066 if (!event->mimeData()->hasFormat(Helper::modelicaComponentFormat) && !event->mimeData()->hasFormat(Helper::modelicaFileFormat)) {
3067 event->ignore();
3068 return;
3069 } else if (event->mimeData()->hasFormat(Helper::modelicaFileFormat)) {
3070 pMainWindow->openDroppedFile(event->mimeData());
3071 event->accept();
3072 } else if (event->mimeData()->hasFormat(Helper::modelicaComponentFormat)) {
3073 // check if the class is system library
3074 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) {
3075 event->ignore();
3076 return;
3077 }
3078 QByteArray itemData = event->mimeData()->data(Helper::modelicaComponentFormat);
3079 QDataStream dataStream(&itemData, QIODevice::ReadOnly);
3080 QString className;
3081 dataStream >> className;
3082 if (addComponent(className, mapToScene(event->pos()))) {
3083 event->accept();
3084 } else {
3085 event->ignore();
3086 }
3087 } else {
3088 event->ignore();
3089 }
3090}
3091
3092void GraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
3093{
3094 if (mSkipBackground) {
3095 return;
3096 }
3097 QPen grayPen(QBrush(QColor(192, 192, 192)), 0);
3098 QPen lightGrayPen(QBrush(QColor(229, 229, 229)), 0);
3099 if (mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView()) {
3100 painter->setBrush(QBrush(Qt::white, Qt::SolidPattern));
3101 } else if (mViewType == StringHandler::Icon) {
3102 painter->setBrush(QBrush(QColor(229, 244, 255), Qt::SolidPattern));
3103 } else {
3104 painter->setBrush(QBrush(QColor(242, 242, 242), Qt::SolidPattern));
3105 }
3106 // draw scene rectangle white background
3107 painter->setPen(Qt::NoPen);
3108 painter->drawRect(rect);
3109 painter->setBrush(QBrush(Qt::white, Qt::SolidPattern));
3110 painter->drawRect(mMergedCoOrdinateSystem.getExtentRectangle());
3111 if (mpModelWidget->getModelWidgetContainer()->isShowGridLines() && !(mpModelWidget->getLibraryTreeItem()->isSystemLibrary() || isVisualizationView())) {
3112 painter->setBrush(Qt::NoBrush);
3113 painter->setPen(lightGrayPen);
3114 /* Draw left half vertical lines */
3115 int horizontalGridStep = mMergedCoOrdinateSystem.getHorizontalGridStep() * 10;
3116 qreal xAxisStep = 0;
3117 qreal yAxisStep = rect.y();
3118 xAxisStep -= horizontalGridStep;
3119 while (xAxisStep > rect.left()) {
3120 painter->drawLine(QPointF(xAxisStep, yAxisStep), QPointF(xAxisStep, rect.bottom()));
3121 xAxisStep -= horizontalGridStep;
3122 }
3123 /* Draw right half vertical lines */
3124 xAxisStep = 0;
3125 while (xAxisStep < rect.right()) {
3126 painter->drawLine(QPointF(xAxisStep, yAxisStep), QPointF(xAxisStep, rect.bottom()));
3127 xAxisStep += horizontalGridStep;
3128 }
3129 /* Draw left half horizontal lines */
3130 int verticalGridStep = mMergedCoOrdinateSystem.getVerticalGridStep() * 10;
3131 xAxisStep = rect.x();
3132 yAxisStep = 0;
3133 yAxisStep += verticalGridStep;
3134 while (yAxisStep < rect.bottom()) {
3135 painter->drawLine(QPointF(xAxisStep, yAxisStep), QPointF(rect.right(), yAxisStep));
3136 yAxisStep += verticalGridStep;
3137 }
3138 /* Draw right half horizontal lines */
3139 yAxisStep = 0;
3140 while (yAxisStep > rect.top()) {
3141 painter->drawLine(QPointF(xAxisStep, yAxisStep), QPointF(rect.right(), yAxisStep));
3142 yAxisStep -= verticalGridStep;
3143 }
3144 /* set the middle horizontal and vertical line gray */
3145 painter->setPen(grayPen);
3146 painter->drawLine(QPointF(rect.left(), 0), QPointF(rect.right(), 0));
3147 painter->drawLine(QPointF(0, rect.top()), QPointF(0, rect.bottom()));
3148 }
3149 // draw scene rectangle
3150 painter->setPen(grayPen);
3151 painter->drawRect(mMergedCoOrdinateSystem.getExtentRectangle());
3152}
3153
3154//! Defines what happens when clicking in a GraphicsView.
3155//! @param event contains information of the mouse click operation.
3156void GraphicsView::mousePressEvent(QMouseEvent *event)
3157{
3158 if (event->button() == Qt::RightButton) {
3159 return;
3160 }
3161 // if user is starting panning.
3162 if (QApplication::keyboardModifiers() == Qt::ControlModifier) {
3163 setIsPanning(true);
3164 mLastMouseEventPos = event->pos();
3165 QGraphicsView::mousePressEvent(event);
3166 return;
3167 }
3168 MainWindow *pMainWindow = MainWindow::instance();
3169 QPointF snappedPoint = snapPointToGrid(mapToScene(event->pos()));
3170 bool eventConsumed = false;
3171 // if left button presses and we are creating a connector
3172 if (isCreatingConnection()) {
3173 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
3174 mpConnectionLineAnnotation->addPoint(roundPoint(mapToScene(event->pos())));
3175 } else {
3176 mpConnectionLineAnnotation->addPoint(snappedPoint);
3177 }
3178 eventConsumed = true;
3179 } else if (isCreatingTransition()) {
3180 mpTransitionLineAnnotation->addPoint(snappedPoint);
3181 eventConsumed = true;
3182 } else if (pMainWindow->getLineShapeAction()->isChecked()) {
3183 /* if line shape tool button is checked then create a line */
3184 createLineShape(snappedPoint);
3185 eventConsumed = true;
3186 } else if (pMainWindow->getPolygonShapeAction()->isChecked()) {
3187 /* if polygon shape tool button is checked then create a polygon */
3188 createPolygonShape(snappedPoint);
3189 eventConsumed = true;
3190 } else if (pMainWindow->getRectangleShapeAction()->isChecked()) {
3191 /* if rectangle shape tool button is checked then create a rectangle */
3192 createRectangleShape(snappedPoint);
3193 eventConsumed = true;
3194 } else if (pMainWindow->getEllipseShapeAction()->isChecked()) {
3195 /* if ellipse shape tool button is checked then create an ellipse */
3196 createEllipseShape(snappedPoint);
3197 eventConsumed = true;
3198 } else if (pMainWindow->getTextShapeAction()->isChecked()) {
3199 /* if text shape tool button is checked then create a text */
3200 createTextShape(snappedPoint);
3201 eventConsumed = true;
3202 } else if (pMainWindow->getBitmapShapeAction()->isChecked()) {
3203 /* if bitmap shape tool button is checked then create a bitmap */
3204 createBitmapShape(snappedPoint);
3205 eventConsumed = true;
3206 } else if (dynamic_cast<ResizerItem*>(itemAt(event->pos()))) {
3207 // do nothing if resizer item is clicked. It will be handled in its class mousePressEvent();
3208 } else if (dynamic_cast<CornerItem*>(itemAt(event->pos()))) {
3209 // do nothing if cornet item is clicked. It will be handled in its class mousePressEvent();
3210 } else {
3211 // this flag is just used to have separate identity for if statement in mouse release event of graphicsview
3212 setIsMovingComponentsAndShapes(true);
3213 // save the position of all components
3214 foreach (Component *pComponent, mComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
3215 pComponent->setOldPosition(pComponent->pos());
3216 pComponent->setOldScenePosition(pComponent->scenePos());
3217 }
3218 // save the position of all shapes
3219 foreach (ShapeAnnotation *pShapeAnnotation, mShapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mShapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (ShapeAnnotation
*pShapeAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
3220 pShapeAnnotation->setOldScenePosition(pShapeAnnotation->scenePos());
3221 }
3222 // save annotations of all connections
3223 foreach (LineAnnotation *pConnectionLineAnnotation, mConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pConnectionLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
3224 pConnectionLineAnnotation->setOldAnnotation(pConnectionLineAnnotation->getOMCShapeAnnotation());
3225 }
3226 // save annotations of all transitions
3227 foreach (LineAnnotation *pTransitionLineAnnotation, mTransitionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mTransitionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pTransitionLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
3228 pTransitionLineAnnotation->setOldAnnotation(pTransitionLineAnnotation->getOMCShapeAnnotation());
3229 }
3230 // save annotations of all initial states
3231 foreach (LineAnnotation *pInitialStateLineAnnotation, mInitialStatesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInitialStatesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pInitialStateLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
3232 pInitialStateLineAnnotation->setOldAnnotation(pInitialStateLineAnnotation->getOMCShapeAnnotation());
3233 }
3234 }
3235 // if some item is clicked
3236 if (Component *pComponent = connectorComponentAtPosition(event->pos())) {
3237 if (!isCreatingConnection()) {
3238 mpClickedComponent = pComponent;
3239 } else if (isCreatingConnection()) {
3240 addConnection(pComponent); // end the connection
3241 eventConsumed = true; // consume the event so that connection line or end component will not become selected
3242 }
3243 } else if (Component *pComponent = stateComponentAtPosition(event->pos())) {
3244 if (!isCreatingTransition()) {
3245 mpClickedState = pComponent;
3246 } else if (isCreatingTransition()) {
3247 addTransition(pComponent); // end the transition
3248 eventConsumed = true; // consume the event so that transition line or end component will not become selected
3249 }
3250 }
3251 if (!eventConsumed) {
3252 /* Ticket:4379 Select multiple objects with [Shift] key (not with [Control] key)
3253 * To provide multi select we switch the shift key with control.
3254 */
3255 if (event->modifiers() & Qt::ShiftModifier) {
3256 event->setModifiers((event->modifiers() & ~Qt::ShiftModifier) | Qt::ControlModifier);
3257 }
3258 QGraphicsView::mousePressEvent(event);
3259 }
3260 setFocus(Qt::ActiveWindowFocusReason);
3261}
3262
3263/*!
3264 * \brief GraphicsView::mouseMoveEvent
3265 * Defines what happens when the mouse is moving in a GraphicsView.
3266 * \param event contains information of the mouse moving operation.
3267 */
3268void GraphicsView::mouseMoveEvent(QMouseEvent *event)
3269{
3270 // if we are in panning mode
3271 if (isPanning()) {
3272 QScrollBar *pHorizontalScrollBar = horizontalScrollBar();
3273 QScrollBar *pVerticalScrollBar = verticalScrollBar();
3274 QPoint delta = event->pos() - mLastMouseEventPos;
3275 mLastMouseEventPos = event->pos();
3276 pHorizontalScrollBar->setValue(pHorizontalScrollBar->value() + (isRightToLeft() ? delta.x() : -delta.x()));
3277 pVerticalScrollBar->setValue(pVerticalScrollBar->value() - delta.y());
3278 QGraphicsView::mouseMoveEvent(event);
3279 return;
3280 }
3281 // update the position label
3282 Label *pPositionLabel = MainWindow::instance()->getPositionLabel();
3283 pPositionLabel->setText(QString("X: %1, Y: %2").arg(QString::number(qRound(mapToScene(event->pos()).x())))
3284 .arg(QString::number(qRound(mapToScene(event->pos()).y()))));
3285 QPointF snappedPoint = snapPointToGrid(mapToScene(event->pos()));
3286 // if user mouse over connector show Qt::CrossCursor.
3287 bool setCrossCursor = false;
3288 if (connectorComponentAtPosition(event->pos()) || stateComponentAtPosition(event->pos())) {
3289 setCrossCursor = true;
3290 /* If setOverrideCursor() has been called twice, calling restoreOverrideCursor() will activate the first cursor set.
3291 * Calling this function a second time restores the original widgets' cursors.
3292 * So we only set the cursor if it is not already Qt::CrossCursor.
3293 */
3294 if (!QApplication::overrideCursor() || QApplication::overrideCursor()->shape() != Qt::CrossCursor) {
3295 QApplication::setOverrideCursor(Qt::CrossCursor);
3296 }
3297 }
3298 // if user mouse is not on connector then reset the cursor.
3299 if (!setCrossCursor && QApplication::overrideCursor()) {
3300 QApplication::restoreOverrideCursor();
3301 }
3302 //If creating connector, the end port shall be updated to the mouse position.
3303 if (isCreatingConnection()) {
3304 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
3305 mpConnectionLineAnnotation->updateEndPoint(roundPoint(mapToScene(event->pos())));
3306 } else {
3307 mpConnectionLineAnnotation->updateEndPoint(snappedPoint);
3308 }
3309 } else if (isCreatingTransition()) {
3310 mpTransitionLineAnnotation->updateEndPoint(snappedPoint);
3311 } else if (isCreatingLineShape()) {
3312 mpLineShapeAnnotation->updateEndPoint(snappedPoint);
3313 } else if (isCreatingPolygonShape()) {
3314 mpPolygonShapeAnnotation->updateEndPoint(snappedPoint);
3315 } else if (isCreatingRectangleShape()) {
3316 mpRectangleShapeAnnotation->updateExtent(1, snappedPoint);
3317 } else if (isCreatingEllipseShape()) {
3318 mpEllipseShapeAnnotation->updateExtent(1, snappedPoint);
3319 } else if (isCreatingTextShape()) {
3320 mpTextShapeAnnotation->updateExtent(1, snappedPoint);
3321 } else if (isCreatingBitmapShape()) {
3322 mpBitmapShapeAnnotation->updateExtent(1, snappedPoint);
3323 } else if (mpClickedComponent) {
3324 addConnection(mpClickedComponent); // start the connection
3325 if (mpClickedComponent) { // if we creating a connection then don't select the starting component.
3326 mpClickedComponent->setSelected(false);
3327 }
3328 } else if (mpClickedState) {
3329 addTransition(mpClickedState); // start the transition
3330 if (mpClickedState) { // if we creating a transition then don't select the starting state.
3331 mpClickedState->setSelected(false);
3332 }
3333 }
3334 QGraphicsView::mouseMoveEvent(event);
3335}
3336
3337void GraphicsView::mouseReleaseEvent(QMouseEvent *event)
3338{
3339 if (event->button() == Qt::RightButton) {
3340 return;
3341 }
3342 setIsPanning(false);
3343 mpClickedComponent = 0;
3344 mpClickedState = 0;
3345
3346 if (isMovingComponentsAndShapes()) {
3347 setIsMovingComponentsAndShapes(false);
3348 bool hasComponentMoved = false;
3349 bool hasShapeMoved = false;
3350 bool beginMacro = false;
3351 // if component position is really changed then update component annotation
3352 foreach (Component *pComponent, mComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (Component
*pComponent = *_container_.i; _container_.control; _container_
.control = 0)
{
3353 if (pComponent->getOldPosition() != pComponent->pos()) {
3354 if (!beginMacro) {
3355 mpModelWidget->beginMacro("Move items by mouse");
3356 beginMacro = true;
3357 }
3358 Transformation oldTransformation = pComponent->mTransformation;
3359 QPointF positionDifference = pComponent->scenePos() - pComponent->getOldScenePosition();
3360 pComponent->mTransformation.adjustPosition(positionDifference.x(), positionDifference.y());
3361 pComponent->updateComponentTransformations(oldTransformation, true);
3362 hasComponentMoved = true;
3363 }
3364 }
3365 // if shape position is changed then update class annotation
3366 foreach (ShapeAnnotation *pShapeAnnotation, mShapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mShapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (ShapeAnnotation
*pShapeAnnotation = *_container_.i; _container_.control; _container_
.control = 0)
{
3367 if (pShapeAnnotation->getOldScenePosition() != pShapeAnnotation->scenePos()) {
3368 if (!beginMacro) {
3369 mpModelWidget->beginMacro("Move items by mouse");
3370 beginMacro = true;
3371 }
3372 QPointF positionDifference = pShapeAnnotation->scenePos() - pShapeAnnotation->getOldScenePosition();
3373 pShapeAnnotation->moveShape(positionDifference.x(), positionDifference.y());
3374 hasShapeMoved = true;
3375 }
3376 }
3377 if (hasShapeMoved) {
3378 addClassAnnotation();
3379 }
3380 if (hasComponentMoved || hasShapeMoved) {
3381 mpModelWidget->updateModelText();
3382 }
3383 // if we have started he undo stack macro then we should end it.
3384 if (beginMacro) {
3385 mpModelWidget->endMacro();
3386 }
3387 }
3388 /* Ticket:4379 Select multiple objects with [Shift] key (not with [Control] key)
3389 * To provide multi select we switch the shift key with control.
3390 * Yes we need to do this in both mousePressEvent and mouseReleaseEvent.
3391 */
3392 if (event->modifiers() & Qt::ShiftModifier) {
3393 event->setModifiers((event->modifiers() & ~Qt::ShiftModifier) | Qt::ControlModifier);
3394 }
3395 QGraphicsView::mouseReleaseEvent(event);
3396}
3397
3398bool GraphicsView::handleDoubleClickOnComponent(QMouseEvent *event)
3399{
3400 QGraphicsItem *pGraphicsItem = itemAt(event->pos());
3401 bool shouldEnactQTDoubleClick = true;
3402 Component *pComponent = getComponentFromQGraphicsItem(pGraphicsItem);
3403 if (pComponent) {
3404 shouldEnactQTDoubleClick = false;
3405 Component *pRootComponent = pComponent->getRootParentComponent();
3406 if (pRootComponent) {
3407 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::CompositeModel) {
3408 pRootComponent->showSubModelAttributes();
3409 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
3410 removeCurrentConnection();
3411 pRootComponent->handleOMSComponentDoubleClick();
3412 } else {
3413 removeCurrentConnection();
3414 removeCurrentTransition();
3415 /* ticket:4401 Open component class with shift + double click */
3416 if (QApplication::keyboardModifiers() == Qt::ShiftModifier) {
3417 pRootComponent->openClass();
3418 } else {
3419 pRootComponent->showParameters();
3420 }
3421 }
3422 }
3423 }
3424 return shouldEnactQTDoubleClick;
3425}
3426
3427
3428void GraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
3429{
3430 const bool removeLastAddedPoint = true;
3431 if (isCreatingLineShape()) {
3432 finishDrawingLineShape(removeLastAddedPoint);
3433 setFocus(Qt::ActiveWindowFocusReason);
3434 return;
3435 } else if (isCreatingPolygonShape()) {
3436 finishDrawingPolygonShape(removeLastAddedPoint);
3437 setFocus(Qt::ActiveWindowFocusReason);
3438 return;
3439 }
3440 ShapeAnnotation *pShapeAnnotation = dynamic_cast<ShapeAnnotation*>(itemAt(event->pos()));
3441 /* Double click on Component also end up here.
3442 * But we don't have GraphicsView for the shapes inside the Component so we can go out of this block.
3443 */
3444 if (!isCreatingConnection() && !isCreatingTransition() && pShapeAnnotation && pShapeAnnotation->getGraphicsView()) {
3445 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
3446 LineAnnotation *pTransitionLineAnnotation = dynamic_cast<LineAnnotation*>(pShapeAnnotation);
3447 if (pTransitionLineAnnotation && pTransitionLineAnnotation->getLineType() == LineAnnotation::TransitionType) {
3448 pShapeAnnotation->editTransition();
3449 } else {
3450 pShapeAnnotation->showShapeProperties();
3451 }
3452 return;
3453 }
3454 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
3455 LineAnnotation *pConnectionLineAnnotation = dynamic_cast<LineAnnotation*>(pShapeAnnotation);
3456 if (pConnectionLineAnnotation && pConnectionLineAnnotation->getLineType() == LineAnnotation::ConnectionType) {
3457 pConnectionLineAnnotation->showOMSConnection();
3458 }
3459 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::CompositeModel) {
3460 pShapeAnnotation->showShapeAttributes();
3461 return;
3462 }
3463 }
3464 if (!handleDoubleClickOnComponent(event)) {
3465 return;
3466 }
3467 QGraphicsView::mouseDoubleClickEvent(event);
3468}
3469
3470/*!
3471 * \brief GraphicsView::focusOutEvent
3472 * \param event
3473 */
3474void GraphicsView::focusOutEvent(QFocusEvent *event)
3475{
3476 // makesure we reset the Qt::CrossCursor
3477 if (QApplication::overrideCursor() && QApplication::overrideCursor()->shape() == Qt::CrossCursor) {
3478 QApplication::restoreOverrideCursor();
3479 }
3480 /*If we get a focus out event while drawing. Stop drawing.*/
3481 if (isCreatingShape()) {
3482 finishDrawingGenericShape();
3483 }
3484 QGraphicsView::focusOutEvent(event);
3485}
3486
3487void GraphicsView::keyPressEvent(QKeyEvent *event)
3488{
3489 // save annotations of all connections
3490 foreach (LineAnnotation *pConnectionLineAnnotation, mConnectionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mConnectionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pConnectionLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
3491 pConnectionLineAnnotation->setOldAnnotation(pConnectionLineAnnotation->getOMCShapeAnnotation());
3492 }
3493 // save annotations of all transitions
3494 foreach (LineAnnotation *pTransitionLineAnnotation, mTransitionsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mTransitionsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pTransitionLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
3495 pTransitionLineAnnotation->setOldAnnotation(pTransitionLineAnnotation->getOMCShapeAnnotation());
3496 }
3497 // save annotations of all initial states
3498 foreach (LineAnnotation *pInitialStateLineAnnotation, mInitialStatesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInitialStatesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pInitialStateLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
3499 pInitialStateLineAnnotation->setOldAnnotation(pInitialStateLineAnnotation->getOMCShapeAnnotation());
3500 }
3501 bool shiftModifier = event->modifiers().testFlag(Qt::ShiftModifier);
3502 bool controlModifier = event->modifiers().testFlag(Qt::ControlModifier);
3503 if (event->key() == Qt::Key_Delete && isAnyItemSelectedAndEditable(event->key())) {
3504 deleteItems();
3505 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_Up && isAnyItemSelectedAndEditable(event->key())) {
3506 mpModelWidget->beginMacro("Move up by key press");
3507 emit keyPressUp();
3508 mpModelWidget->endMacro();
3509 } else if (shiftModifier && !controlModifier && event->key() == Qt::Key_Up && isAnyItemSelectedAndEditable(event->key())) {
3510 mpModelWidget->beginMacro("Move shift up by key press");
3511 emit keyPressShiftUp();
3512 mpModelWidget->endMacro();
3513 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_Up && isAnyItemSelectedAndEditable(event->key())) {
3514 mpModelWidget->beginMacro("Move control up by key press");
3515 emit keyPressCtrlUp();
3516 mpModelWidget->endMacro();
3517 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_Down && isAnyItemSelectedAndEditable(event->key())) {
3518 mpModelWidget->beginMacro("Move down by key press");
3519 emit keyPressDown();
3520 mpModelWidget->endMacro();
3521 } else if (shiftModifier && !controlModifier && event->key() == Qt::Key_Down && isAnyItemSelectedAndEditable(event->key())) {
3522 mpModelWidget->beginMacro("Move shift down by key press");
3523 emit keyPressShiftDown();
3524 mpModelWidget->endMacro();
3525 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_Down && isAnyItemSelectedAndEditable(event->key())) {
3526 mpModelWidget->beginMacro("Move control down by key press");
3527 emit keyPressCtrlDown();
3528 mpModelWidget->endMacro();
3529 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_Left && isAnyItemSelectedAndEditable(event->key())) {
3530 mpModelWidget->beginMacro("Move left by key press");
3531 emit keyPressLeft();
3532 mpModelWidget->endMacro();
3533 } else if (shiftModifier && !controlModifier && event->key() == Qt::Key_Left && isAnyItemSelectedAndEditable(event->key())) {
3534 mpModelWidget->beginMacro("Move shift left by key press");
3535 emit keyPressShiftLeft();
3536 mpModelWidget->endMacro();
3537 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_Left && isAnyItemSelectedAndEditable(event->key())) {
3538 mpModelWidget->beginMacro("Move control left by key press");
3539 emit keyPressCtrlLeft();
3540 mpModelWidget->endMacro();
3541 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_Right && isAnyItemSelectedAndEditable(event->key())) {
3542 mpModelWidget->beginMacro("Move right by key press");
3543 emit keyPressRight();
3544 mpModelWidget->endMacro();
3545 } else if (shiftModifier && !controlModifier && event->key() == Qt::Key_Right && isAnyItemSelectedAndEditable(event->key())) {
3546 mpModelWidget->beginMacro("Move shift right by key press");
3547 emit keyPressShiftRight();
3548 mpModelWidget->endMacro();
3549 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_Right && isAnyItemSelectedAndEditable(event->key())) {
3550 mpModelWidget->beginMacro("Move control right by key press");
3551 emit keyPressCtrlRight();
3552 mpModelWidget->endMacro();
3553 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_A) {
3554 selectAll();
3555 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_X && isAnyItemSelectedAndEditable(event->key()) && mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
3556 cutItems();
3557 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_C && mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
3558 copyItems();
3559 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_V && mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
3560 pasteItems();
3561 } else if (controlModifier && event->key() == Qt::Key_D && isAnyItemSelectedAndEditable(event->key())) {
3562 mpModelWidget->beginMacro("Duplicate by key press");
3563 emit keyPressDuplicate();
3564 mpModelWidget->endMacro();
3565 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_R && isAnyItemSelectedAndEditable(event->key())) {
3566 mpModelWidget->beginMacro("Rotate clockwise by key press");
3567 emit keyPressRotateClockwise();
3568 mpModelWidget->endMacro();
3569 } else if (shiftModifier && controlModifier && event->key() == Qt::Key_R && isAnyItemSelectedAndEditable(event->key())) {
3570 mpModelWidget->beginMacro("Rotate anti clockwise by key press");
3571 emit keyPressRotateAntiClockwise();
3572 mpModelWidget->endMacro();
3573 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_H && isAnyItemSelectedAndEditable(event->key())) {
3574 mpModelWidget->beginMacro("Flip horizontal by key press");
3575 emit keyPressFlipHorizontal();
3576 mpModelWidget->endMacro();
3577 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_V && isAnyItemSelectedAndEditable(event->key())) {
3578 mpModelWidget->beginMacro("Flip vertical by key press");
3579 emit keyPressFlipVertical();
3580 mpModelWidget->endMacro();
3581 } else if (shiftModifier && !controlModifier && (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)) {
3582 /* ticket:4401 Open component class with shift + Enter */
3583 QList<QGraphicsItem*> selectedItems = scene()->selectedItems();
3584 if (selectedItems.size() == 1) {
3585 Component *pComponent = dynamic_cast<Component*>(selectedItems.at(0));
3586 if (pComponent) {
3587 Component *pRootComponent = pComponent->getRootParentComponent();
3588 if (pRootComponent) {
3589 pRootComponent->openClass();
3590 }
3591 }
3592 }
3593 } else if (event->key() == Qt::Key_Escape && isCreatingConnection()) {
3594 removeCurrentConnection();
3595 } else if (event->key() == Qt::Key_Escape && isCreatingTransition()) {
3596 removeCurrentTransition();
3597 } else if (event->key() == Qt::Key_Escape && isCreatingShape()) {
3598 finishDrawingGenericShape();
3599 } else {
3600 QGraphicsView::keyPressEvent(event);
3601 }
3602}
3603
3604void GraphicsView::uncheckAllShapeDrawingActions()
3605{
3606 MainWindow *pMainWindow = MainWindow::instance();
3607 pMainWindow->toggleShapesButton();
3608}
3609
3610//! Defines what shall happen when a key is released.
3611//! @param event contains information about the keypress operation.
3612void GraphicsView::keyReleaseEvent(QKeyEvent *event)
3613{
3614 /* if user has pressed and hold the key. */
3615 if (event->isAutoRepeat()) {
3616 return QGraphicsView::keyReleaseEvent(event);
3617 }
3618 bool shiftModifier = event->modifiers().testFlag(Qt::ShiftModifier);
3619 bool controlModifier = event->modifiers().testFlag(Qt::ControlModifier);
3620 /* handle keys */
3621 if (!shiftModifier && !controlModifier && event->key() == Qt::Key_Up && isAnyItemSelectedAndEditable(event->key())) {
3622 mpModelWidget->updateClassAnnotationIfNeeded();
3623 mpModelWidget->updateModelText();
3624 } else if (shiftModifier && !controlModifier && event->key() == Qt::Key_Up && isAnyItemSelectedAndEditable(event->key())) {
3625 mpModelWidget->updateClassAnnotationIfNeeded();
3626 mpModelWidget->updateModelText();
3627 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_Up && isAnyItemSelectedAndEditable(event->key())) {
3628 mpModelWidget->updateClassAnnotationIfNeeded();
3629 mpModelWidget->updateModelText();
3630 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_Down && isAnyItemSelectedAndEditable(event->key())) {
3631 mpModelWidget->updateClassAnnotationIfNeeded();
3632 mpModelWidget->updateModelText();
3633 } else if (shiftModifier && !controlModifier && event->key() == Qt::Key_Down && isAnyItemSelectedAndEditable(event->key())) {
3634 mpModelWidget->updateClassAnnotationIfNeeded();
3635 mpModelWidget->updateModelText();
3636 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_Down && isAnyItemSelectedAndEditable(event->key())) {
3637 mpModelWidget->updateClassAnnotationIfNeeded();
3638 mpModelWidget->updateModelText();
3639 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_Left && isAnyItemSelectedAndEditable(event->key())) {
3640 mpModelWidget->updateClassAnnotationIfNeeded();
3641 mpModelWidget->updateModelText();
3642 } else if (shiftModifier && !controlModifier && event->key() == Qt::Key_Left && isAnyItemSelectedAndEditable(event->key())) {
3643 mpModelWidget->updateClassAnnotationIfNeeded();
3644 mpModelWidget->updateModelText();
3645 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_Left && isAnyItemSelectedAndEditable(event->key())) {
3646 mpModelWidget->updateClassAnnotationIfNeeded();
3647 mpModelWidget->updateModelText();
3648 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_Right && isAnyItemSelectedAndEditable(event->key())) {
3649 mpModelWidget->updateClassAnnotationIfNeeded();
3650 mpModelWidget->updateModelText();
3651 } else if (shiftModifier && !controlModifier && event->key() == Qt::Key_Right && isAnyItemSelectedAndEditable(event->key())) {
3652 mpModelWidget->updateClassAnnotationIfNeeded();
3653 mpModelWidget->updateModelText();
3654 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_Right && isAnyItemSelectedAndEditable(event->key())) {
3655 mpModelWidget->updateClassAnnotationIfNeeded();
3656 mpModelWidget->updateModelText();
3657 } else if (controlModifier && event->key() == Qt::Key_D && isAnyItemSelectedAndEditable(event->key())) {
3658 mpModelWidget->updateClassAnnotationIfNeeded();
3659 mpModelWidget->updateModelText();
3660 } else if (!shiftModifier && controlModifier && event->key() == Qt::Key_R && isAnyItemSelectedAndEditable(event->key())) {
3661 mpModelWidget->updateClassAnnotationIfNeeded();
3662 mpModelWidget->updateModelText();
3663 } else if (shiftModifier && controlModifier && event->key() == Qt::Key_R && isAnyItemSelectedAndEditable(event->key())) {
3664 mpModelWidget->updateClassAnnotationIfNeeded();
3665 mpModelWidget->updateModelText();
3666 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_H && isAnyItemSelectedAndEditable(event->key())) {
3667 mpModelWidget->updateClassAnnotationIfNeeded();
3668 mpModelWidget->updateModelText();
3669 } else if (!shiftModifier && !controlModifier && event->key() == Qt::Key_V && isAnyItemSelectedAndEditable(event->key())) {
3670 mpModelWidget->updateClassAnnotationIfNeeded();
3671 mpModelWidget->updateModelText();
3672 } else {
3673 QGraphicsView::keyReleaseEvent(event);
3674 }
3675}
3676
3677void GraphicsView::contextMenuEvent(QContextMenuEvent *event)
3678{
3679 /* If we are creating the connection OR creating any shape then don't show context menu */
3680 if (isCreatingShape() || isCreatingConnection() || isCreatingTransition()) {
3681 return;
3682 }
3683 // if creating a transition
3684 if (isCreatingTransition()) {
3685 QMenu menu(MainWindow::instance());
3686 menu.addAction(mpSetInitialStateAction);
3687 menu.addSeparator();
3688 menu.addAction(mpCancelTransitionAction);
3689 menu.exec(event->globalPos());
3690 return;
3691 }
3692 // if some item is right clicked then don't show graphics view context menu
3693 if (!itemAt(event->pos())) {
3694 QMenu menu;
3695 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
3696 modelicaGraphicsViewContextMenu(&menu);
3697 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::CompositeModel) {
3698 compositeModelGraphicsViewContextMenu(&menu);
3699 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
3700 omsGraphicsViewContextMenu(&menu);
3701 }
3702 menu.exec(event->globalPos());
3703 return; // return from it because at a time we only want one context menu.
3704 } else { // if we click on some item.
3705 bool oneShapeSelected = false;
3706 bool oneComponentSelected = false;
3707 // if a shape is right clicked
3708 ShapeAnnotation *pShapeAnnotation = dynamic_cast<ShapeAnnotation*>(itemAt(event->pos()));
3709 Component *pComponent = 0;
3710 if (pShapeAnnotation && pShapeAnnotation->getGraphicsView()) {
3711 if (!pShapeAnnotation->isSelected()) {
3712 clearSelection(pShapeAnnotation);
3713 }
3714 oneShapeSelected = scene()->selectedItems().size() == 1;
3715 } else {
3716 // if a component is right clicked
3717 pComponent = componentAtPosition(event->pos());
3718 if (pComponent) {
3719 if (!pComponent->isSelected()) {
3720 clearSelection(pComponent);
3721 }
3722 oneComponentSelected = scene()->selectedItems().size() == 1;
3723 }
3724 }
3725 // construct context menu now
3726 QMenu menu;
3727 if (oneShapeSelected) {
3728 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
3729 modelicaOneShapeContextMenu(pShapeAnnotation, &menu);
3730 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::CompositeModel) {
3731 compositeModelOneShapeContextMenu(pShapeAnnotation, &menu);
3732 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
3733 omsOneShapeContextMenu(pShapeAnnotation, &menu);
3734 }
3735 } else if (oneComponentSelected) {
3736 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
3737 modelicaOneComponentContextMenu(pComponent, &menu);
3738 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::CompositeModel) {
3739 compositeModelOneComponentContextMenu(pComponent, &menu);
3740 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
3741 // No context menu for component of type OMS connector i.e., input/output signal or OMS bus connector.
3742 if (pComponent->getLibraryTreeItem() && pComponent->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS
3743 && (pComponent->getLibraryTreeItem()->getOMSConnector()
3744 || pComponent->getLibraryTreeItem()->getOMSBusConnector()
3745 || pComponent->getLibraryTreeItem()->getOMSTLMBusConnector())) {
3746 return;
3747 }
3748 omsOneComponentContextMenu(pComponent, &menu);
3749 }
3750 } else {
3751 if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
3752 modelicaMultipleItemsContextMenu(&menu);
3753 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::CompositeModel) {
3754 compositeModelMultipleItemsContextMenu(&menu);
3755 } else if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
3756 omsMultipleItemsContextMenu(&menu);
3757 }
3758 }
3759 // enable/disable common actions based on if any inherited item is selected
3760 bool noInheritedItemSelected = true;
3761 QList<QGraphicsItem*> graphicsItems = scene()->selectedItems();
3762 foreach (QGraphicsItem *pGraphicsItem, graphicsItems)for (auto _container_ = QtPrivate::qMakeForeachContainer(graphicsItems
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QGraphicsItem
*pGraphicsItem = *_container_.i; _container_.control; _container_
.control = 0)
{
3763 Component *pComponent = getComponentFromQGraphicsItem(pGraphicsItem);
3764 if (pComponent) {
3765 Component *pRootComponent = pComponent->getRootParentComponent();
3766 if (pRootComponent && pRootComponent->isInheritedComponent() && pRootComponent->isSelected()) {
3767 noInheritedItemSelected = false;
3768 }
3769 } else if (ShapeAnnotation *pShapeAnnotation = dynamic_cast<ShapeAnnotation*>(pGraphicsItem)) {
3770 if (pShapeAnnotation->isInheritedShape() && pShapeAnnotation->isSelected()) {
3771 noInheritedItemSelected = false;
3772 }
3773 }
3774 }
3775 mpManhattanizeAction->setEnabled(noInheritedItemSelected);
3776 mpDeleteAction->setEnabled(noInheritedItemSelected);
3777 mpCutAction->setEnabled(noInheritedItemSelected);
3778 mpDuplicateAction->setEnabled(noInheritedItemSelected);
3779 mpRotateClockwiseAction->setEnabled(noInheritedItemSelected);
3780 mpRotateAntiClockwiseAction->setEnabled(noInheritedItemSelected);
3781 mpFlipHorizontalAction->setEnabled(noInheritedItemSelected);
3782 mpFlipVerticalAction->setEnabled(noInheritedItemSelected);
3783 menu.exec(event->globalPos());
3784 return; // return from it because at a time we only want one context menu.
3785 }
3786 QGraphicsView::contextMenuEvent(event);
3787}
3788
3789void GraphicsView::resizeEvent(QResizeEvent *event)
3790{
3791 fitInViewInternal();
3792 QGraphicsView::resizeEvent(event);
3793}
3794
3795/*!
3796 * \brief GraphicsView::wheelEvent
3797 * Reimplementation of QGraphicsView::wheelEvent.
3798 * Allows zooming with mouse.
3799 * \param event
3800 */
3801void GraphicsView::wheelEvent(QWheelEvent *event)
3802{
3803 int numDegrees = event->delta() / 8;
3804 int numSteps = numDegrees * 3;
3805 bool controlModifier = event->modifiers().testFlag(Qt::ControlModifier);
3806 bool shiftModifier = event->modifiers().testFlag(Qt::ShiftModifier);
3807 // If Ctrl key is pressed and user has scrolled vertically then Zoom In/Out based on the scroll distance.
3808 if (event->orientation() == Qt::Vertical && controlModifier) {
3809 if (event->delta() > 0) {
3810 zoomIn();
3811 } else {
3812 zoomOut();
3813 }
3814 } else if ((event->orientation() == Qt::Horizontal) || (event->orientation() == Qt::Vertical && shiftModifier)) {
3815 // If Shift key is pressed and user has scrolled vertically then scroll the horizontal scrollbars.
3816 // If user has scrolled horizontally then scroll the horizontal scrollbars.
3817 horizontalScrollBar()->setValue(horizontalScrollBar()->value() - numSteps);
3818 } else if (event->orientation() == Qt::Vertical) {
3819 // If user has scrolled vertically then scroll the vertical scrollbars.
3820 verticalScrollBar()->setValue(verticalScrollBar()->value() - numSteps);
3821 } else {
3822 QGraphicsView::wheelEvent(event);
3823 }
3824}
3825
3826/*!
3827 * \brief GraphicsView::leaveEvent
3828 * Reimplementation of QGraphicsView::leaveEvent.
3829 * Clears the position label in the status bar.
3830 * \param event
3831 */
3832void GraphicsView::leaveEvent(QEvent *event)
3833{
3834 // clear the position label
3835 MainWindow::instance()->getPositionLabel()->clear();
3836 QGraphicsView::leaveEvent(event);
3837}
3838
3839WelcomePageWidget::WelcomePageWidget(QWidget *pParent)
3840 : QWidget(pParent)
3841{
3842 // main frame
3843 mpMainFrame = new QFrame;
3844 mpMainFrame->setContentsMargins(0, 0, 0, 0);
3845 mpMainFrame->setStyleSheet("QFrame{color:gray;}");
3846 // top frame
3847 mpTopFrame = new QFrame;
3848 mpTopFrame->setStyleSheet("QFrame{background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #828282, stop: 1 #5e5e5e);}");
3849 // top frame pixmap
3850 mpPixmapLabel = new Label;
3851 QPixmap pixmap(":/Resources/icons/omedit.png");
3852 mpPixmapLabel->setPixmap(pixmap.scaled(75, 72, Qt::KeepAspectRatio, Qt::SmoothTransformation));
3853 mpPixmapLabel->setStyleSheet("background-color : transparent;");
3854 // top frame heading
3855 mpHeadingLabel = Utilities::getHeadingLabel(QString(Helper::applicationName).append(" - ").append(Helper::applicationIntroText));
3856 mpHeadingLabel->setStyleSheet("background-color : transparent; color : white;");
3857#ifndef Q_OS_MAC
3858 mpHeadingLabel->setGraphicsEffect(new QGraphicsDropShadowEffect);
3859#endif
3860 mpHeadingLabel->setElideMode(Qt::ElideMiddle);
3861 // top frame layout
3862 QHBoxLayout *topFrameLayout = new QHBoxLayout;
3863 topFrameLayout->setAlignment(Qt::AlignLeft);
3864 topFrameLayout->addWidget(mpPixmapLabel);
3865 topFrameLayout->addWidget(mpHeadingLabel);
3866 mpTopFrame->setLayout(topFrameLayout);
3867 // RecentFiles Frame
3868 mpRecentFilesFrame = new QFrame;
3869 mpRecentFilesFrame->setFrameShape(QFrame::StyledPanel);
3870 mpRecentFilesFrame->setStyleSheet("QFrame{background-color: white;}");
3871 // recent items list
3872 mpRecentFilesLabel = Utilities::getHeadingLabel(tr("Recent Files"));
3873 mpNoRecentFileLabel = new Label(tr("No recent files found."));
3874 mpRecentItemsList = new QListWidget;
3875 mpRecentItemsList->setObjectName("RecentItemsList");
3876 mpRecentItemsList->setContentsMargins(0, 0, 0, 0);
3877 mpRecentItemsList->setSpacing(5);
3878 mpRecentItemsList->setFrameStyle(QFrame::NoFrame);
3879 mpRecentItemsList->setViewMode(QListView::ListMode);
3880 mpRecentItemsList->setMovement(QListView::Static);
3881 mpRecentItemsList->setIconSize(Helper::iconSize);
3882 mpRecentItemsList->setCurrentRow(0, QItemSelectionModel::Select);
3883 connect(mpRecentItemsList, SIGNAL(itemClicked(QListWidgetItem*))"2""itemClicked(QListWidgetItem*)", SLOT(openRecentFileItem(QListWidgetItem*))"1""openRecentFileItem(QListWidgetItem*)");
3884 mpClearRecentFilesListButton = new QPushButton(tr("Clear Recent Files"));
3885 mpClearRecentFilesListButton->setStyleSheet("QPushButton{padding: 5px 15px 5px 15px;}");
3886 connect(mpClearRecentFilesListButton, SIGNAL(clicked())"2""clicked()", MainWindow::instance(), SLOT(clearRecentFilesList())"1""clearRecentFilesList()");
3887 // RecentFiles Frame layout
3888 QVBoxLayout *recentFilesFrameVBLayout = new QVBoxLayout;
3889 recentFilesFrameVBLayout->addWidget(mpRecentFilesLabel);
3890 recentFilesFrameVBLayout->addWidget(mpNoRecentFileLabel);
3891 recentFilesFrameVBLayout->addWidget(mpRecentItemsList);
3892 QHBoxLayout *recentFilesHBLayout = new QHBoxLayout;
3893 recentFilesHBLayout->addWidget(mpClearRecentFilesListButton, 0, Qt::AlignLeft);
3894 recentFilesFrameVBLayout->addLayout(recentFilesHBLayout);
3895 mpRecentFilesFrame->setLayout(recentFilesFrameVBLayout);
3896 // LatestNews Frame
3897 mpLatestNewsFrame = new QFrame;
3898 mpLatestNewsFrame->setFrameShape(QFrame::StyledPanel);
3899 mpLatestNewsFrame->setStyleSheet("QFrame{background-color: white;}");
3900 /* Read the show latest news settings */
3901 if (!OptionsDialog::instance()->getGeneralSettingsPage()->getShowLatestNewsCheckBox()->isChecked()) {
3902 mpLatestNewsFrame->setVisible(false);
3903 }
3904 // latest news
3905 mpLatestNewsLabel = Utilities::getHeadingLabel(tr("Latest News"));
3906 mpNoLatestNewsLabel = new Label;
3907 mpLatestNewsListWidget = new QListWidget;
3908 mpLatestNewsListWidget->setObjectName("LatestNewsList");
3909 mpLatestNewsListWidget->setContentsMargins(0, 0, 0, 0);
3910 mpLatestNewsListWidget->setSpacing(5);
3911 mpLatestNewsListWidget->setFrameStyle(QFrame::NoFrame);
3912 mpLatestNewsListWidget->setViewMode(QListView::ListMode);
3913 mpLatestNewsListWidget->setMovement(QListView::Static);
3914 mpLatestNewsListWidget->setIconSize(Helper::iconSize);
3915 mpLatestNewsListWidget->setCurrentRow(0, QItemSelectionModel::Select);
3916 mpReloadLatestNewsButton = new QPushButton(Helper::reload);
3917 mpReloadLatestNewsButton->setStyleSheet("QPushButton{padding: 5px 15px 5px 15px;}");
3918 connect(mpReloadLatestNewsButton, SIGNAL(clicked())"2""clicked()", SLOT(addLatestNewsListItems())"1""addLatestNewsListItems()");
3919 mpVisitWebsiteLabel = new Label(tr("For more details visit our website <u><a href=\"http://www.openmodelica.org\">www.openmodelica.org</a></u>"));
3920 mpVisitWebsiteLabel->setTextFormat(Qt::RichText);
3921 mpVisitWebsiteLabel->setTextInteractionFlags(mpVisitWebsiteLabel->textInteractionFlags() | Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
3922 mpVisitWebsiteLabel->setOpenExternalLinks(true);
3923 connect(mpLatestNewsListWidget, SIGNAL(itemClicked(QListWidgetItem*))"2""itemClicked(QListWidgetItem*)", SLOT(openLatestNewsItem(QListWidgetItem*))"1""openLatestNewsItem(QListWidgetItem*)");
3924 // Latest News Frame layout
3925 QVBoxLayout *latestNewsFrameVBLayout = new QVBoxLayout;
3926 latestNewsFrameVBLayout->addWidget(mpLatestNewsLabel);
3927 latestNewsFrameVBLayout->addWidget(mpNoLatestNewsLabel);
3928 latestNewsFrameVBLayout->addWidget(mpLatestNewsListWidget);
3929 QHBoxLayout *latestNewsFrameHBLayout = new QHBoxLayout;
3930 latestNewsFrameHBLayout->addWidget(mpReloadLatestNewsButton, 0, Qt::AlignLeft);
3931 latestNewsFrameHBLayout->addWidget(mpVisitWebsiteLabel, 0, Qt::AlignRight);
3932 latestNewsFrameVBLayout->addLayout(latestNewsFrameHBLayout);
3933 mpLatestNewsFrame->setLayout(latestNewsFrameVBLayout);
3934 // create http object for request
3935 mpLatestNewsNetworkAccessManager = new QNetworkAccessManager;
3936 connect(mpLatestNewsNetworkAccessManager, SIGNAL(finished(QNetworkReply*))"2""finished(QNetworkReply*)", SLOT(readLatestNewsXML(QNetworkReply*))"1""readLatestNewsXML(QNetworkReply*)");
3937 addLatestNewsListItems();
3938 // splitter
3939 mpSplitter = new QSplitter;
3940 /* Read the welcome page view settings */
3941 switch (OptionsDialog::instance()->getGeneralSettingsPage()->getWelcomePageView()){
3942 case 2:
3943 mpSplitter->setOrientation(Qt::Vertical);
3944 break;
3945 case 1:
3946 default:
3947 mpSplitter->setOrientation(Qt::Horizontal);
3948 break;
3949 }
3950 mpSplitter->setChildrenCollapsible(false);
3951 mpSplitter->setHandleWidth(4);
3952 mpSplitter->setContentsMargins(0, 0, 0, 0);
3953 mpSplitter->addWidget(mpRecentFilesFrame);
3954 mpSplitter->addWidget(mpLatestNewsFrame);
3955 // Read the welcome page splitter state
3956 QSettings *pSettings = Utilities::getApplicationSettings();
3957 mpSplitter->restoreState(pSettings->value("welcomePage/splitterState").toByteArray());
3958 // bottom frame
3959 mpBottomFrame = new QFrame;
3960 mpBottomFrame->setStyleSheet("QFrame{background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #828282, stop: 1 #5e5e5e);}");
3961 // bottom frame create and open buttons buttons
3962 mpCreateModelButton = new QPushButton(Helper::createNewModelicaClass);
3963 mpCreateModelButton->setStyleSheet("QPushButton{padding: 5px 15px 5px 15px;}");
3964 connect(mpCreateModelButton, SIGNAL(clicked())"2""clicked()", MainWindow::instance(), SLOT(createNewModelicaClass())"1""createNewModelicaClass()");
3965 mpOpenModelButton = new QPushButton(Helper::openModelicaFiles);
3966 mpOpenModelButton->setStyleSheet("QPushButton{padding: 5px 15px 5px 15px;}");
3967 connect(mpOpenModelButton, SIGNAL(clicked())"2""clicked()", MainWindow::instance(), SLOT(openModelicaFile())"1""openModelicaFile()");
3968 // bottom frame layout
3969 QHBoxLayout *bottomFrameLayout = new QHBoxLayout;
3970 bottomFrameLayout->addWidget(mpCreateModelButton, 0, Qt::AlignLeft);
3971 bottomFrameLayout->addWidget(mpOpenModelButton, 0, Qt::AlignRight);
3972 mpBottomFrame->setLayout(bottomFrameLayout);
3973 // vertical layout for frames
3974 QVBoxLayout *verticalLayout = new QVBoxLayout;
3975 verticalLayout->setSpacing(4);
3976 verticalLayout->setContentsMargins(0, 0, 0, 0);
3977 verticalLayout->addWidget(mpTopFrame, 0, Qt::AlignTop);
3978 verticalLayout->addWidget(mpSplitter, 1);
3979 verticalLayout->addWidget(mpBottomFrame, 0, Qt::AlignBottom);
3980 // main frame layout
3981 mpMainFrame->setLayout(verticalLayout);
3982 QHBoxLayout *layout = new QHBoxLayout;
3983 layout->setContentsMargins(0, 0, 0, 0);
3984 layout->addWidget(mpMainFrame);
3985 setLayout(layout);
3986}
3987
3988void WelcomePageWidget::addRecentFilesListItems()
3989{
3990 // remove list items first
3991 mpRecentItemsList->clear();
3992 QSettings *pSettings = Utilities::getApplicationSettings();
3993 QList<QVariant> files = pSettings->value("recentFilesList/files").toList();
3994 int numRecentFiles = qMin(files.size(), (int)MainWindow::instance()->MaxRecentFiles);
3995 for (int i = 0; i < numRecentFiles; ++i)
3996 {
3997 RecentFile recentFile = qvariant_cast<RecentFile>(files[i]);
3998 QListWidgetItem *listItem = new QListWidgetItem(mpRecentItemsList);
3999 listItem->setIcon(ResourceCache::getIcon(":/Resources/icons/next.svg"));
4000 listItem->setText(recentFile.fileName);
4001 listItem->setData(Qt::UserRole, recentFile.encoding);
4002 }
4003 if (files.size() > 0)
4004 mpNoRecentFileLabel->setVisible(false);
4005 else
4006 mpNoRecentFileLabel->setVisible(true);
4007}
4008
4009QFrame* WelcomePageWidget::getLatestNewsFrame()
4010{
4011 return mpLatestNewsFrame;
4012}
4013
4014QSplitter* WelcomePageWidget::getSplitter()
4015{
4016 return mpSplitter;
4017}
4018
4019void WelcomePageWidget::addLatestNewsListItems()
4020{
4021 mpLatestNewsListWidget->clear();
4022 /* if show latest news settings is not set then don't fetch the latest news items. */
4023 if (OptionsDialog::instance()->getGeneralSettingsPage()->getShowLatestNewsCheckBox()->isChecked())
4024 {
4025 QUrl newsUrl("https://openmodelica.org/index.php?option=com_content&view=category&id=23&format=feed&amp;type=rss");
4026 QNetworkReply *pNetworkReply = mpLatestNewsNetworkAccessManager->get(QNetworkRequest(newsUrl));
4027 pNetworkReply->ignoreSslErrors();
4028 }
4029}
4030
4031void WelcomePageWidget::readLatestNewsXML(QNetworkReply *pNetworkReply)
4032{
4033 if (pNetworkReply->error() == QNetworkReply::HostNotFoundError)
4034 {
4035 mpNoLatestNewsLabel->setVisible(true);
4036 mpNoLatestNewsLabel->setText(tr("Sorry, no internet no news items."));
4037 }
4038 else if (pNetworkReply->error() == QNetworkReply::NoError)
4039 {
4040 QByteArray response(pNetworkReply->readAll());
4041 QXmlStreamReader xml(response);
4042 int count = 0;
4043 QString title, link;
4044 while (!xml.atEnd())
4045 {
4046 mpNoLatestNewsLabel->setVisible(false);
4047 xml.readNext();
4048 if (xml.tokenType() == QXmlStreamReader::StartElement)
4049 {
4050 if (xml.name() == "item")
4051 {
4052 while (!xml.atEnd())
4053 {
4054 xml.readNext();
4055 if (xml.tokenType() == QXmlStreamReader::StartElement)
4056 {
4057 if (xml.name() == "title")
4058 title = xml.readElementText();
4059 if (xml.name() == "link")
4060 {
4061 link = xml.readElementText();
4062 if (count >= (int)MainWindow::instance()->MaxRecentFiles)
4063 break;
4064 count++;
4065 QListWidgetItem *listItem = new QListWidgetItem(mpLatestNewsListWidget);
4066 listItem->setIcon(ResourceCache::getIcon(":/Resources/icons/next.svg"));
4067 listItem->setText(title);
4068 listItem->setData(Qt::UserRole, link);
4069 break;
4070 }
4071 }
4072 }
4073 }
4074 }
4075 if (count >= (int)MainWindow::instance()->MaxRecentFiles)
4076 break;
4077 }
4078 }
4079 else
4080 {
4081 mpNoLatestNewsLabel->setVisible(true);
4082 mpNoLatestNewsLabel->setText(QString(Helper::error).append(" - ").append(pNetworkReply->errorString()));
4083 }
4084}
4085
4086void WelcomePageWidget::openRecentFileItem(QListWidgetItem *pItem)
4087{
4088 MainWindow::instance()->getLibraryWidget()->openFile(pItem->text(), pItem->data(Qt::UserRole).toString(), true, true);
4089}
4090
4091void WelcomePageWidget::openLatestNewsItem(QListWidgetItem *pItem)
4092{
4093 QUrl url(pItem->data(Qt::UserRole).toString());
4094 QDesktopServices::openUrl(url);
4095}
4096
4097/*!
4098 * \class UndoStack
4099 * \brief Subclass QUndoStack.\n
4100 * We need to handle which commands to push to the stack.
4101 */
4102/*!
4103 * \brief UndoStack::UndoStack
4104 * \param parent
4105 */
4106UndoStack::UndoStack(QObject *parent)
4107 : QUndoStack(parent)
4108{
4109 mEnabled = true;
4110}
4111
4112/*!
4113 * \brief UndoStack::push
4114 * \param cmd
4115 */
4116void UndoStack::push(UndoCommand *cmd)
4117{
4118 /* We only push the commands to the stack when its enabled.
4119 * When the stack is not enabled we don't push the command but we do execute the command.
4120 * Most of such cases are when loading and opening a class. The operations performed at that time are not needed on the stack.
4121 * This is needed since we don't want to call clear on the stack.
4122 */
4123 if (isEnabled()) {
4124 /* If the stack is enabled then call the command redo function to check if the command fails or not.
4125 * If the command fails then delete it and don't push to the stack.
4126 * If the command doesn't fail then disable it and push to the stack. We need to disable it since QUndoStack::push() calls the
4127 * command redo function and we already called redo once so we don't want to call it here.
4128 * Enable the command after the push is done.
4129 */
4130 cmd->redoInternal();
4131 if (cmd->isFailed()) {
4132 delete cmd;
4133 } else {
4134 cmd->setEnabled(false);
4135 QUndoStack::push(cmd);
4136 cmd->setEnabled(true);
4137 }
4138 } else {
4139 cmd->redo();
4140 }
4141}
4142
4143ModelWidget::ModelWidget(LibraryTreeItem* pLibraryTreeItem, ModelWidgetContainer *pModelWidgetContainer)
4144 : QWidget(pModelWidgetContainer), mpModelWidgetContainer(pModelWidgetContainer), mpLibraryTreeItem(pLibraryTreeItem),
4145 mComponentsLoaded(false), mDiagramViewLoaded(false), mConnectionsLoaded(false), mCreateModelWidgetComponents(false),
4146 mExtendsModifiersLoaded(false), mDerivedClassModifiersLoaded(false)
4147{
4148 // create widgets based on library type
4149 if (mpLibraryTreeItem->getLibraryType() == LibraryTreeItem::Modelica) {
4150 // icon graphics framework
4151 mpIconGraphicsScene = new GraphicsScene(StringHandler::Icon, this);
4152 mpIconGraphicsView = new GraphicsView(StringHandler::Icon, this);
4153 mpIconGraphicsView->setScene(mpIconGraphicsScene);
4154 mpIconGraphicsView->hide();
4155 // diagram graphics framework
4156 mpDiagramGraphicsScene = new GraphicsScene(StringHandler::Diagram, this);
4157 mpDiagramGraphicsView = new GraphicsView(StringHandler::Diagram, this);
4158 mpDiagramGraphicsView->setScene(mpDiagramGraphicsScene);
4159 mpDiagramGraphicsView->hide();
4160 // Undo stack for model
4161 mpUndoStack = new UndoStack;
4162 connect(mpUndoStack, SIGNAL(canUndoChanged(bool))"2""canUndoChanged(bool)", SLOT(handleCanUndoChanged(bool))"1""handleCanUndoChanged(bool)");
4163 connect(mpUndoStack, SIGNAL(canRedoChanged(bool))"2""canRedoChanged(bool)", SLOT(handleCanRedoChanged(bool))"1""handleCanRedoChanged(bool)");
4164 if (MainWindow::instance()->isDebug()) {
4165 mpUndoView = new QUndoView(mpUndoStack);
4166 }
4167 mpEditor = 0;
4168 getModelInheritedClasses();
4169 drawModelInheritedClassShapes(this, StringHandler::Icon);
4170 getModelIconDiagramShapes(StringHandler::Icon);
4171 /* Ticket:2960
4172 * Just a workaround to make browsing faster.
4173 * We don't get the components here i.e items are shown without connectors in the Libraries Browser.
4174 * Fetch the components when we really need to draw them.
4175 */
4176 /*! @todo Uncomment the following code once we have new faster frontend and remove the flag mComponentsLoaded. */
4177 // drawModelInheritedClassComponents(this, StringHandler::Icon);
4178 // getModelComponents();
4179 // drawModelIconComponents();
4180 } else if (mpLibraryTreeItem->getLibraryType() == LibraryTreeItem::OMS) {
4181 // icon graphics framework
4182 if (mpLibraryTreeItem->isSystemElement() || mpLibraryTreeItem->isComponentElement()) {
4183 mpIconGraphicsScene = new GraphicsScene(StringHandler::Icon, this);
4184 mpIconGraphicsView = new GraphicsView(StringHandler::Icon, this);
4185 mpIconGraphicsView->setScene(mpIconGraphicsScene);
4186 mpIconGraphicsView->hide();
4187 } else {
4188 mpIconGraphicsScene = 0;
4189 mpIconGraphicsView = 0;
4190 }
4191 // diagram graphics framework
4192 mpDiagramGraphicsScene = new GraphicsScene(StringHandler::Diagram, this);
4193 mpDiagramGraphicsView = new GraphicsView(StringHandler::Diagram, this);
4194 mpDiagramGraphicsView->setScene(mpDiagramGraphicsScene);
4195 mpDiagramGraphicsView->hide();
4196 // Undo stack for model
4197 mpUndoStack = new UndoStack;
4198 connect(mpUndoStack, SIGNAL(canUndoChanged(bool))"2""canUndoChanged(bool)", SLOT(handleCanUndoChanged(bool))"1""handleCanUndoChanged(bool)");
4199 connect(mpUndoStack, SIGNAL(canRedoChanged(bool))"2""canRedoChanged(bool)", SLOT(handleCanRedoChanged(bool))"1""handleCanRedoChanged(bool)");
4200 if (MainWindow::instance()->isDebug()) {
4201 mpUndoView = new QUndoView(mpUndoStack);
4202 }
4203 mpEditor = 0;
4204 mpUndoStack->setEnabled(false);
4205 drawOMSModelIconElements();
4206 mpUndoStack->setEnabled(true);
4207 } else {
4208 // icon graphics framework
4209 mpIconGraphicsScene = 0;
4210 mpIconGraphicsView = 0;
4211 // diagram graphics framework
4212 mpDiagramGraphicsScene = 0;
4213 mpDiagramGraphicsView = 0;
4214 // undo stack for model
4215 mpUndoStack = 0;
4216 if (MainWindow::instance()->isDebug()) {
4217 mpUndoView = 0;
4218 }
4219 mpEditor = 0;
4220 }
4221 // Read the file for LibraryTreeItem::Text
4222 if (mpLibraryTreeItem->getLibraryType() == LibraryTreeItem::Text && !mpLibraryTreeItem->isFilePathValid()) {
4223 QString contents = "";
4224 QFile file(mpLibraryTreeItem->getFileName());
4225 if (!file.open(QIODevice::ReadOnly)) {
4226 // QMessageBox::critical(mpLibraryWidget->MainWindow::instance(), QString(Helper::applicationName).append(" - ").append(Helper::error),
4227 // GUIMessages::getMessage(GUIMessages::ERROR_OPENING_FILE).arg(pLibraryTreeItem->getFileName())
4228 // .arg(file.errorString()), Helper::ok);
4229 } else {
4230 contents = QString(file.readAll());
4231 file.close();
4232 }
4233 mpLibraryTreeItem->setClassText(contents);
4234 }
4235}
4236
4237/*!
4238 * \brief ModelWidget::getExtendsModifiersMap
4239 * Returns a extends modifier map for extends class
4240 * \param extendsClass
4241 * \return
4242 */
4243QMap<QString, QString> ModelWidget::getExtendsModifiersMap(QString extendsClass)
4244{
4245 if (!mExtendsModifiersLoaded) {
4246 foreach (LibraryTreeItem *pLibraryTreeItem, mInheritedClassesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mInheritedClassesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LibraryTreeItem
*pLibraryTreeItem = *_container_.i; _container_.control; _container_
.control = 0)
{
4247 fetchExtendsModifiers(pLibraryTreeItem->getNameStructure());
4248 }
4249 mExtendsModifiersLoaded = true;
4250 }
4251 return mExtendsModifiersMap.value(extendsClass);
4252}
4253
4254/*!
4255 * \brief ModelWidget::getDerivedClassModifiersMap
4256 * Returns a derived class modifiers map
4257 * \param derivedClass
4258 * \return
4259 */
4260QMap<QString, QString> ModelWidget::getDerivedClassModifiersMap()
4261{
4262 if (!mDerivedClassModifiersLoaded) {
4263 mDerivedClassModifiersMap.clear();
4264 OMCProxy *pOMCProxy = MainWindow::instance()->getOMCProxy();
4265 QStringList derivedClassModifierNames = pOMCProxy->getDerivedClassModifierNames(mpLibraryTreeItem->getNameStructure());
4266 foreach (QString derivedClassModifierName, derivedClassModifierNames)for (auto _container_ = QtPrivate::qMakeForeachContainer(derivedClassModifierNames
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString derivedClassModifierName
= *_container_.i; _container_.control; _container_.control =
0)
{
4267 // if we have already read the record modifier then continue
4268 if (mDerivedClassModifiersMap.contains(derivedClassModifierName)) {
4269 continue;
4270 }
4271 mDerivedClassModifiersMap.insert(derivedClassModifierName, pOMCProxy->getDerivedClassModifierValue(mpLibraryTreeItem->getNameStructure(), derivedClassModifierName));
4272 }
4273 mDerivedClassModifiersLoaded = true;
4274 }
4275 return mDerivedClassModifiersMap;
4276}
4277
4278/*!
4279 * \brief ModelWidget::fetchExtendsModifiers
4280 * Gets the extends modifiers and their values.
4281 * \param extendsClass
4282 */
4283void ModelWidget::fetchExtendsModifiers(QString extendsClass)
4284{
4285 mExtendsModifiersMap.clear();
4286 OMCProxy *pOMCProxy = MainWindow::instance()->getOMCProxy();
4287 QStringList extendsModifiersList = pOMCProxy->getExtendsModifierNames(mpLibraryTreeItem->getNameStructure(), extendsClass);
4288 QMap<QString, QString> extendsModifiersMap;
4289 foreach (QString extendsModifier, extendsModifiersList)for (auto _container_ = QtPrivate::qMakeForeachContainer(extendsModifiersList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString extendsModifier
= *_container_.i; _container_.control; _container_.control =
0)
{
4290 QString extendsModifierValue = pOMCProxy->getExtendsModifierValue(mpLibraryTreeItem->getNameStructure(), extendsClass, extendsModifier);
4291 extendsModifiersMap.insert(extendsModifier, extendsModifierValue);
4292 }
4293 mExtendsModifiersMap.insert(extendsClass, extendsModifiersMap);
4294}
4295
4296/*!
4297 * \brief ModelWidget::reDrawModelWidgetInheritedClasses
4298 * Redraws the class inherited classes shapes, components and connections.
4299 */
4300void ModelWidget::reDrawModelWidgetInheritedClasses()
4301{
4302 mpIconGraphicsView->removeInheritedClassShapes();
4303 drawModelInheritedClassShapes(this, StringHandler::Icon);
4304 mpIconGraphicsView->reOrderShapes();
4305 if (mComponentsLoaded) {
4306 mpIconGraphicsView->removeInheritedClassComponents();
4307 drawModelInheritedClassComponents(this, StringHandler::Icon);
4308 }
4309 if (mDiagramViewLoaded) {
4310 mpDiagramGraphicsView->removeInheritedClassShapes();
4311 drawModelInheritedClassShapes(this, StringHandler::Diagram);
4312 mpDiagramGraphicsView->reOrderShapes();
4313 mpDiagramGraphicsView->removeInheritedClassComponents();
4314 drawModelInheritedClassComponents(this, StringHandler::Diagram);
4315 }
4316 if (mConnectionsLoaded) {
4317 mpDiagramGraphicsView->removeInheritedClassConnections();
4318 drawModelInheritedClassConnections(this);
4319 }
4320}
4321
4322/*!
4323 * \brief ModelWidget::drawModelIconDiagramShapes
4324 * Draws the model shapes.
4325 * \param shapes
4326 * \param pGraphicsView
4327 */
4328void ModelWidget::drawModelIconDiagramShapes(QStringList shapes, GraphicsView *pGraphicsView, bool select)
4329{
4330 foreach (QString shape, shapes)for (auto _container_ = QtPrivate::qMakeForeachContainer(shapes
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString shape
= *_container_.i; _container_.control; _container_.control =
0)
{
4331 ShapeAnnotation *pShapeAnnotation = 0;
4332 if (shape.startsWith("Line")) {
4333 shape = shape.mid(QString("Line").length());
4334 shape = StringHandler::removeFirstLastParentheses(shape);
4335 pShapeAnnotation = new LineAnnotation(shape, pGraphicsView);
4336 } else if (shape.startsWith("Polygon")) {
4337 shape = shape.mid(QString("Polygon").length());
4338 shape = StringHandler::removeFirstLastParentheses(shape);
4339 pShapeAnnotation = new PolygonAnnotation(shape, pGraphicsView);
4340 } else if (shape.startsWith("Rectangle")) {
4341 shape = shape.mid(QString("Rectangle").length());
4342 shape = StringHandler::removeFirstLastParentheses(shape);
4343 pShapeAnnotation = new RectangleAnnotation(shape, pGraphicsView);
4344 } else if (shape.startsWith("Ellipse")) {
4345 shape = shape.mid(QString("Ellipse").length());
4346 shape = StringHandler::removeFirstLastParentheses(shape);
4347 pShapeAnnotation = new EllipseAnnotation(shape, pGraphicsView);
4348 } else if (shape.startsWith("Text")) {
4349 shape = shape.mid(QString("Text").length());
4350 shape = StringHandler::removeFirstLastParentheses(shape);
4351 pShapeAnnotation = new TextAnnotation(shape, pGraphicsView);
4352 } else if (shape.startsWith("Bitmap")) {
4353 /* create the bitmap shape */
4354 shape = shape.mid(QString("Bitmap").length());
4355 shape = StringHandler::removeFirstLastParentheses(shape);
4356 pShapeAnnotation = new BitmapAnnotation(mpLibraryTreeItem->mClassInformation.fileName, shape, pGraphicsView);
4357 }
4358 if (pShapeAnnotation) {
4359 pShapeAnnotation->drawCornerItems();
4360 pShapeAnnotation->setCornerItemsActiveOrPassive();
4361 pShapeAnnotation->applyTransformation();
4362 mpUndoStack->push(new AddShapeCommand(pShapeAnnotation));
4363 if (select) {
4364 pShapeAnnotation->setSelected(true);
4365 }
4366 }
4367 }
4368}
4369
4370/*!
4371 * \brief ModelWidget::createNonExistingInheritedShape
4372 * Creates a red cross for non-existing inherited class shape.
4373 * \param pGraphicsView
4374 * \return
4375 */
4376ShapeAnnotation* ModelWidget::createNonExistingInheritedShape(GraphicsView *pGraphicsView)
4377{
4378 LineAnnotation *pLineAnnotation = new LineAnnotation(pGraphicsView);
4379 pLineAnnotation->drawCornerItems();
4380 pLineAnnotation->setCornerItemsActiveOrPassive();
4381 pLineAnnotation->applyTransformation();
4382 return pLineAnnotation;
4383}
4384
4385/*!
4386 * \brief ModelWidget::createInheritedShape
4387 * Creates the inherited class shape.
4388 * \param pShapeAnnotation
4389 * \param pGraphicsView
4390 * \return
4391 */
4392ShapeAnnotation* ModelWidget::createInheritedShape(ShapeAnnotation *pShapeAnnotation, GraphicsView *pGraphicsView)
4393{
4394 if (dynamic_cast<LineAnnotation*>(pShapeAnnotation)) {
4395 LineAnnotation *pLineAnnotation = new LineAnnotation(pShapeAnnotation, pGraphicsView);
4396 pLineAnnotation->drawCornerItems();
4397 pLineAnnotation->setCornerItemsActiveOrPassive();
4398 pLineAnnotation->applyTransformation();
4399 return pLineAnnotation;
4400 } else if (dynamic_cast<PolygonAnnotation*>(pShapeAnnotation)) {
4401 PolygonAnnotation *pPolygonAnnotation = new PolygonAnnotation(pShapeAnnotation, pGraphicsView);
4402 pPolygonAnnotation->drawCornerItems();
4403 pPolygonAnnotation->setCornerItemsActiveOrPassive();
4404 pPolygonAnnotation->applyTransformation();
4405 return pPolygonAnnotation;
4406 } else if (dynamic_cast<RectangleAnnotation*>(pShapeAnnotation)) {
4407 RectangleAnnotation *pRectangleAnnotation = new RectangleAnnotation(pShapeAnnotation, pGraphicsView);
4408 pRectangleAnnotation->drawCornerItems();
4409 pRectangleAnnotation->setCornerItemsActiveOrPassive();
4410 pRectangleAnnotation->applyTransformation();
4411 return pRectangleAnnotation;
4412 } else if (dynamic_cast<EllipseAnnotation*>(pShapeAnnotation)) {
4413 EllipseAnnotation *pEllipseAnnotation = new EllipseAnnotation(pShapeAnnotation, pGraphicsView);
4414 pEllipseAnnotation->drawCornerItems();
4415 pEllipseAnnotation->setCornerItemsActiveOrPassive();
4416 pEllipseAnnotation->applyTransformation();
4417 return pEllipseAnnotation;
4418 } else if (dynamic_cast<TextAnnotation*>(pShapeAnnotation)) {
4419 TextAnnotation *pTextAnnotation = new TextAnnotation(pShapeAnnotation, pGraphicsView);
4420 pTextAnnotation->drawCornerItems();
4421 pTextAnnotation->setCornerItemsActiveOrPassive();
4422 pTextAnnotation->applyTransformation();
4423 return pTextAnnotation;
4424 } else if (dynamic_cast<BitmapAnnotation*>(pShapeAnnotation)) {
4425 BitmapAnnotation *pBitmapAnnotation = new BitmapAnnotation(pShapeAnnotation, pGraphicsView);
4426 pBitmapAnnotation->drawCornerItems();
4427 pBitmapAnnotation->setCornerItemsActiveOrPassive();
4428 pBitmapAnnotation->applyTransformation();
4429 return pBitmapAnnotation;
4430 }
4431 return 0;
4432}
4433
4434/*!
4435 * \brief ModelWidget::createInheritedComponent
4436 * Creates the inherited component.
4437 * \param pComponent
4438 * \param pGraphicsView
4439 * \return
4440 */
4441Component* ModelWidget::createInheritedComponent(Component *pComponent, GraphicsView *pGraphicsView)
4442{
4443 return new Component(pComponent, pGraphicsView);
4444}
4445
4446/*!
4447 * \brief ModelWidget::createInheritedConnection
4448 * Creates the inherited connection.
4449 * \param pConnectionLineAnnotation
4450 * \return
4451 */
4452LineAnnotation* ModelWidget::createInheritedConnection(LineAnnotation *pConnectionLineAnnotation)
4453{
4454 LineAnnotation *pInheritedConnectionLineAnnotation = new LineAnnotation(pConnectionLineAnnotation, mpDiagramGraphicsView);
4455 pInheritedConnectionLineAnnotation->setToolTip(QString("<b>connect</b>(%1, %2)<br /><br />%3 %4")
4456 .arg(pInheritedConnectionLineAnnotation->getStartComponentName())
4457 .arg(pInheritedConnectionLineAnnotation->getEndComponentName())
4458 .arg(tr("Connection declared in"))
4459 .arg(pConnectionLineAnnotation->getGraphicsView()->getModelWidget()->getLibraryTreeItem()->getNameStructure()));
4460 pInheritedConnectionLineAnnotation->drawCornerItems();
4461 pInheritedConnectionLineAnnotation->setCornerItemsActiveOrPassive();
4462 pInheritedConnectionLineAnnotation->applyTransformation();
4463 // Add the start component connection details.
4464 Component *pStartComponent = pInheritedConnectionLineAnnotation->getStartComponent();
4465 if (pStartComponent->getRootParentComponent()) {
4466 pStartComponent->getRootParentComponent()->addConnectionDetails(pInheritedConnectionLineAnnotation);
4467 } else {
4468 pStartComponent->addConnectionDetails(pInheritedConnectionLineAnnotation);
4469 }
4470 // Add the end component connection details.
4471 Component *pEndComponent = pInheritedConnectionLineAnnotation->getEndComponent();
4472 if (pEndComponent->getParentComponent()) {
4473 pEndComponent->getParentComponent()->addConnectionDetails(pInheritedConnectionLineAnnotation);
4474 } else {
4475 pEndComponent->addConnectionDetails(pInheritedConnectionLineAnnotation);
4476 }
4477 return pInheritedConnectionLineAnnotation;
4478}
4479
4480/*!
4481 * \brief ModelWidget::loadComponents
4482 * Loads the model components if they are not loaded before.
4483 */
4484void ModelWidget::loadComponents()
4485{
4486 if (!mComponentsLoaded) {
4487 drawModelInheritedClassComponents(this, StringHandler::Icon);
4488 /* We use access.icon here since getComponents will return public components in that case
4489 * and we want to display them.
4490 */
4491 if (mpLibraryTreeItem->getAccess() >= LibraryTreeItem::icon) {
4492 getModelComponents();
4493 drawModelIconComponents();
4494 }
4495 mComponentsLoaded = true;
4496 }
4497}
4498
4499/*!
4500 * \brief ModelWidget::loadDiagramView
4501 * Loads the diagram view components if they are not loaded before.
4502 */
4503void ModelWidget::loadDiagramView()
4504{
4505 loadComponents();
4506 if (!mDiagramViewLoaded) {
4507 drawModelInheritedClassShapes(this, StringHandler::Diagram);
4508 getModelIconDiagramShapes(StringHandler::Diagram);
4509 drawModelInheritedClassComponents(this, StringHandler::Diagram);
4510 /* We use access.icon here since getComponents will return public components in that case
4511 * and we add them to diagram layer so that we can see and set the parameters in the parameters window.
4512 */
4513 if (mpLibraryTreeItem->getAccess() >= LibraryTreeItem::icon) {
4514 drawModelDiagramComponents();
4515 }
4516 mDiagramViewLoaded = true;
4517 /*! @note The following is not needed if we load the connectors alongwith the icon/diagram annotation.
4518 * We have disabled loading the connectors so user gets fast browsing of libraries.
4519 */
4520 mpLibraryTreeItem->handleIconUpdated();
4521 }
4522}
4523
4524/*!
4525 * \brief ModelWidget::loadConnections
4526 * Loads the model connections if they are not loaded before.
4527 */
4528void ModelWidget::loadConnections()
4529{
4530 if (!mConnectionsLoaded) {
4531 drawModelInheritedClassConnections(this);
4532 if (mpLibraryTreeItem->getAccess() >= LibraryTreeItem::diagram) {
4533 getModelConnections();
4534 getModelTransitions();
4535 getModelInitialStates();
4536 }
4537 mConnectionsLoaded = true;
4538 }
4539}
4540
4541/*!
4542 * \brief ModelWidget::getModelConnections
4543 * Gets the connections of the model and place them in the diagram GraphicsView.
4544 */
4545void ModelWidget::getModelConnections()
4546{
4547 // detect multiple declarations of a component instance
4548 detectMultipleDeclarations();
4549 // get the connections
4550 MainWindow *pMainWindow = MainWindow::instance();
4551 int connectionCount = pMainWindow->getOMCProxy()->getConnectionCount(mpLibraryTreeItem->getNameStructure());
4552 for (int i = 1 ; i <= connectionCount ; i++) {
4553 // get the connection from OMC
4554 QStringList connectionList = pMainWindow->getOMCProxy()->getNthConnection(mpLibraryTreeItem->getNameStructure(), i);
4555 QString connectionAnnotationString = pMainWindow->getOMCProxy()->getNthConnectionAnnotation(mpLibraryTreeItem->getNameStructure(), i);
4556 addConnection(connectionList, connectionAnnotationString, false, false);
4557 }
4558}
4559
4560void ModelWidget::addConnection(QStringList connectionList, QString connectionAnnotationString, bool addToOMC, bool select)
4561{
4562 MainWindow *pMainWindow = MainWindow::instance();
4563 LibraryTreeModel *pLibraryTreeModel = pMainWindow->getLibraryWidget()->getLibraryTreeModel();
4564 QString connectionString = QString("{%1}").arg(connectionList.join(","));
4565 // if the connectionString only contains two items then continue the loop,
4566 // because connection is not valid then
4567 if (connectionList.size() < 3) {
4568 return;
4569 }
4570 // get start and end components
4571 QStringList startComponentList = StringHandler::makeVariableParts(connectionList.at(0));
4572 QStringList endComponentList = StringHandler::makeVariableParts(connectionList.at(1));
4573 // get start component
4574 Component *pStartComponent = 0;
4575 if (startComponentList.size() > 0) {
4576 QString startComponentName = startComponentList.at(0);
4577 if (startComponentName.contains("[")) {
4578 startComponentName = startComponentName.mid(0, startComponentName.indexOf("["));
4579 }
4580 pStartComponent = mpDiagramGraphicsView->getComponentObject(startComponentName);
4581 }
4582 // get start connector
4583 Component *pStartConnectorComponent = 0;
4584 Component *pEndConnectorComponent = 0;
4585 if (pStartComponent) {
4586 // if a component type is connector then we only get one item in startComponentList
4587 // check the startcomponentlist
4588 if (startComponentList.size() < 2
4589 || (pStartComponent->getLibraryTreeItem()
4590 && pStartComponent->getLibraryTreeItem()->getRestriction() == StringHandler::ExpandableConnector)) {
4591 pStartConnectorComponent = pStartComponent;
4592 } else if (pStartComponent->getLibraryTreeItem()
4593 && !pLibraryTreeModel->findLibraryTreeItem(pStartComponent->getLibraryTreeItem()->getNameStructure())) {
4594 /* if class doesn't exist then connect with the red cross box */
4595 pStartConnectorComponent = pStartComponent;
4596 } else {
4597 // look for port from the parent component
4598 QString startComponentName = startComponentList.at(1);
4599 if (startComponentName.contains("[")) {
4600 startComponentName = startComponentName.mid(0, startComponentName.indexOf("["));
4601 }
4602 pStartConnectorComponent = getConnectorComponent(pStartComponent, startComponentName);
4603 }
4604 }
4605 // show error message if start component is not found.
4606 if (!pStartConnectorComponent) {
4607 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica,
4608 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_CONNECTION)
4609 .arg(connectionList.at(0)).arg(connectionString),
4610 Helper::scriptingKind, Helper::errorLevel));
4611 return;
4612 }
4613 // get end component
4614 Component *pEndComponent = 0;
4615 if (endComponentList.size() > 0) {
4616 QString endComponentName = endComponentList.at(0);
4617 if (endComponentName.contains("[")) {
4618 endComponentName = endComponentName.mid(0, endComponentName.indexOf("["));
4619 }
4620 pEndComponent = mpDiagramGraphicsView->getComponentObject(endComponentName);
4621 }
4622 // get the end connector
4623 if (pEndComponent) {
4624 // if a component type is connector then we only get one item in endComponentList
4625 // check the endcomponentlist
4626 if (endComponentList.size() < 2
4627 || (pEndComponent->getLibraryTreeItem()
4628 && pEndComponent->getLibraryTreeItem()->getRestriction() == StringHandler::ExpandableConnector)) {
4629 pEndConnectorComponent = pEndComponent;
4630 } else if (pEndComponent->getLibraryTreeItem()
4631 && !pLibraryTreeModel->findLibraryTreeItem(pEndComponent->getLibraryTreeItem()->getNameStructure())) {
4632 /* if class doesn't exist then connect with the red cross box */
4633 pEndConnectorComponent = pEndComponent;
4634 } else {
4635 QString endComponentName = endComponentList.at(1);
4636 if (endComponentName.contains("[")) {
4637 endComponentName = endComponentName.mid(0, endComponentName.indexOf("["));
4638 }
4639 pEndConnectorComponent = getConnectorComponent(pEndComponent, endComponentName);
4640 }
4641 }
4642 // show error message if end component is not found.
4643 if (!pEndConnectorComponent) {
4644 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica,
4645 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_CONNECTION)
4646 .arg(connectionList.at(1)).arg(connectionString),
4647 Helper::scriptingKind, Helper::errorLevel));
4648 return;
4649 }
4650 // connection annotation
4651 QStringList shapesList = StringHandler::getStrings(StringHandler::removeFirstLastCurlBrackets(connectionAnnotationString), '(', ')');
4652 // Now parse the shapes available in list
4653 QString lineShape = "";
4654 foreach (QString shape, shapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(shapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString shape
= *_container_.i; _container_.control; _container_.control =
0)
{
4655 if (shape.startsWith("Line")) {
4656 lineShape = shape.mid(QString("Line").length());
4657 lineShape = StringHandler::removeFirstLastParentheses(lineShape);
4658 break; // break the loop once we have got the line annotation.
4659 }
4660 }
4661 LineAnnotation *pConnectionLineAnnotation;
4662 pConnectionLineAnnotation = new LineAnnotation(lineShape, pStartConnectorComponent, pEndConnectorComponent, mpDiagramGraphicsView);
4663 pConnectionLineAnnotation->setStartComponentName(connectionList.at(0));
4664 pConnectionLineAnnotation->setEndComponentName(connectionList.at(1));
4665 if (select) {
4666 pConnectionLineAnnotation->setSelected(true);
4667 }
4668 mpUndoStack->push(new AddConnectionCommand(pConnectionLineAnnotation, addToOMC));
4669}
4670
4671/*!
4672 * \brief ModelWidget::loadWidgetComponents
4673 * Creates the widgets for the ModelWidget.
4674 */
4675void ModelWidget::createModelWidgetComponents()
4676{
4677 if (!mCreateModelWidgetComponents) {
4678 // icon view tool button
4679 mpIconViewToolButton = new QToolButton;
4680 mpIconViewToolButton->setText(Helper::iconView);
4681 mpIconViewToolButton->setIcon(ResourceCache::getIcon(":/Resources/icons/model.svg"));
4682 mpIconViewToolButton->setToolTip(Helper::iconView);
4683 mpIconViewToolButton->setAutoRaise(true);
4684 mpIconViewToolButton->setCheckable(true);
4685 // diagram view tool button
4686 mpDiagramViewToolButton = new QToolButton;
4687 mpDiagramViewToolButton->setText(Helper::diagramView);
4688 mpDiagramViewToolButton->setIcon(ResourceCache::getIcon(":/Resources/icons/modeling.png"));
4689 mpDiagramViewToolButton->setToolTip(Helper::diagramView);
4690 mpDiagramViewToolButton->setAutoRaise(true);
4691 mpDiagramViewToolButton->setCheckable(true);
4692 // modelica text view tool button
4693 mpTextViewToolButton = new QToolButton;
4694 mpTextViewToolButton->setText(Helper::textView);
4695 mpTextViewToolButton->setIcon(ResourceCache::getIcon(":/Resources/icons/modeltext.svg"));
4696 mpTextViewToolButton->setToolTip(Helper::textView);
4697 mpTextViewToolButton->setAutoRaise(true);
4698 mpTextViewToolButton->setCheckable(true);
4699 // documentation view tool button
4700 mpDocumentationViewToolButton = new QToolButton;
4701 mpDocumentationViewToolButton->setText(Helper::documentationView);
4702 mpDocumentationViewToolButton->setIcon(ResourceCache::getIcon(":/Resources/icons/info-icon.svg"));
4703 mpDocumentationViewToolButton->setToolTip(Helper::documentationView);
4704 mpDocumentationViewToolButton->setAutoRaise(true);
4705 // view buttons box
4706 mpViewsButtonGroup = new QButtonGroup;
4707 mpViewsButtonGroup->setExclusive(true);
4708 mpViewsButtonGroup->addButton(mpDiagramViewToolButton);
4709 mpViewsButtonGroup->addButton(mpIconViewToolButton);
4710 mpViewsButtonGroup->addButton(mpTextViewToolButton);
4711 mpViewsButtonGroup->addButton(mpDocumentationViewToolButton);
4712 // frame to contain view buttons
4713 QFrame *pViewButtonsFrame = new QFrame;
4714 QHBoxLayout *pViewButtonsHorizontalLayout = new QHBoxLayout;
4715 pViewButtonsHorizontalLayout->setContentsMargins(0, 0, 0, 0);
4716 pViewButtonsHorizontalLayout->setSpacing(0);
4717 pViewButtonsFrame->setLayout(pViewButtonsHorizontalLayout);
4718 // set Project Status Bar lables
4719 mpReadOnlyLabel = mpLibraryTreeItem->isReadOnly() ? new Label(Helper::readOnly) : new Label(tr("Writable"));
4720 mpModelicaTypeLabel = new Label;
4721 mpViewTypeLabel = new Label;
4722 mpModelClassPathLabel = new Label(mpLibraryTreeItem->getNameStructure());
4723 mpModelFilePathLabel = new Label(mpLibraryTreeItem->getFileName());
4724 mpModelFilePathLabel->setElideMode(Qt::ElideMiddle);
4725 // documentation view tool button
4726 mpFileLockToolButton = new QToolButton;
4727 mpFileLockToolButton->setIcon(ResourceCache::getIcon(mpLibraryTreeItem->isReadOnly() ? ":/Resources/icons/lock.svg" : ":/Resources/icons/unlock.svg"));
4728 mpFileLockToolButton->setText(mpLibraryTreeItem->isReadOnly() ? tr("Make writable") : tr("File is writable"));
4729 mpFileLockToolButton->setToolTip(mpFileLockToolButton->text());
4730 mpFileLockToolButton->setEnabled(mpLibraryTreeItem->isReadOnly() && !mpLibraryTreeItem->isSystemLibrary());
4731 mpFileLockToolButton->setAutoRaise(true);
4732 connect(mpFileLockToolButton, SIGNAL(clicked())"2""clicked()", SLOT(makeFileWritAble())"1""makeFileWritAble()");
4733 // create project status bar
4734 mpModelStatusBar = new QStatusBar;
4735 mpModelStatusBar->setObjectName("ModelStatusBar");
4736 mpModelStatusBar->setSizeGripEnabled(false);
4737 mpModelStatusBar->addPermanentWidget(pViewButtonsFrame, 0);
4738 // create the main layout
4739 QVBoxLayout *pMainLayout = new QVBoxLayout;
4740 pMainLayout->setContentsMargins(0, 0, 0, 0);
4741 pMainLayout->setSpacing(4);
4742 pMainLayout->addWidget(mpModelStatusBar);
4743 setLayout(pMainLayout);
4744 MainWindow *pMainWindow = MainWindow::instance();
4745 // show hide widgets based on library type
4746 if (mpLibraryTreeItem->getLibraryType() == LibraryTreeItem::Modelica) {
4747 connect(mpIconViewToolButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(showIconView(bool))"1""showIconView(bool)");
4748 connect(mpDiagramViewToolButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(showDiagramView(bool))"1""showDiagramView(bool)");
4749 connect(mpTextViewToolButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(showTextView(bool))"1""showTextView(bool)");
4750 connect(mpDocumentationViewToolButton, SIGNAL(clicked())"2""clicked()", SLOT(showDocumentationView())"1""showDocumentationView()");
4751 pViewButtonsHorizontalLayout->addWidget(mpIconViewToolButton);
4752 pViewButtonsHorizontalLayout->addWidget(mpDiagramViewToolButton);
4753 pViewButtonsHorizontalLayout->addWidget(mpTextViewToolButton);
4754 pViewButtonsHorizontalLayout->addWidget(mpDocumentationViewToolButton);
4755 mpModelicaTypeLabel->setText(StringHandler::getModelicaClassType(mpLibraryTreeItem->getRestriction()));
4756 mpViewTypeLabel->setText(StringHandler::getViewType(StringHandler::Diagram));
4757 // modelica text editor
4758 mpEditor = new ModelicaEditor(this);
4759 ModelicaHighlighter *pModelicaTextHighlighter = new ModelicaHighlighter(OptionsDialog::instance()->getModelicaEditorPage(),
4760 mpEditor->getPlainTextEdit());
4761 ModelicaEditor *pModelicaEditor = dynamic_cast<ModelicaEditor*>(mpEditor);
4762 pModelicaEditor->setPlainText(mpLibraryTreeItem->getClassText(pMainWindow->getLibraryWidget()->getLibraryTreeModel()), false);
4763 mpEditor->hide(); // set it hidden so that Find/Replace action can get correct value.
4764 connect(OptionsDialog::instance(), SIGNAL(modelicaEditorSettingsChanged())"2""modelicaEditorSettingsChanged()", pModelicaTextHighlighter, SLOT(settingsChanged())"1""settingsChanged()");
4765 mpModelStatusBar->addPermanentWidget(mpReadOnlyLabel, 0);
4766 mpModelStatusBar->addPermanentWidget(mpModelicaTypeLabel, 0);
4767 mpModelStatusBar->addPermanentWidget(mpViewTypeLabel, 0);
4768 mpModelStatusBar->addPermanentWidget(mpModelClassPathLabel, 0);
4769 mpModelStatusBar->addPermanentWidget(mpModelFilePathLabel, 1);
4770 mpModelStatusBar->addPermanentWidget(mpFileLockToolButton, 0);
4771 // set layout
4772 if (MainWindow::instance()->isDebug()) {
4773 pMainLayout->addWidget(mpUndoView);
4774 }
4775 pMainLayout->addWidget(mpDiagramGraphicsView, 1);
4776 pMainLayout->addWidget(mpIconGraphicsView, 1);
4777 mpUndoStack->clear();
4778 } else if (mpLibraryTreeItem->getLibraryType() == LibraryTreeItem::Text) {
4779 pViewButtonsHorizontalLayout->addWidget(mpTextViewToolButton);
4780 QFileInfo fileInfo(mpLibraryTreeItem->getFileName());
4781 if (Utilities::isCFile(fileInfo.suffix())) {
4782 mpEditor = new CEditor(this);
4783 CHighlighter *pCHighlighter = new CHighlighter(OptionsDialog::instance()->getCEditorPage(), mpEditor->getPlainTextEdit());
4784 CEditor *pCEditor = dynamic_cast<CEditor*>(mpEditor);
4785 pCEditor->setPlainText(mpLibraryTreeItem->getClassText(pMainWindow->getLibraryWidget()->getLibraryTreeModel()));
4786 mpEditor->hide();
4787 connect(OptionsDialog::instance(), SIGNAL(cEditorSettingsChanged())"2""cEditorSettingsChanged()", pCHighlighter, SLOT(settingsChanged())"1""settingsChanged()");
4788 } else if (Utilities::isModelicaFile(fileInfo.suffix())) {
4789 mpEditor = new MetaModelicaEditor(this);
4790 MetaModelicaHighlighter *pMetaModelicaHighlighter;
4791 pMetaModelicaHighlighter = new MetaModelicaHighlighter(OptionsDialog::instance()->getMetaModelicaEditorPage(),
4792 mpEditor->getPlainTextEdit());
4793 MetaModelicaEditor *pMetaModelicaEditor = dynamic_cast<MetaModelicaEditor*>(mpEditor);
4794 pMetaModelicaEditor->setPlainText(mpLibraryTreeItem->getClassText(pMainWindow->getLibraryWidget()->getLibraryTreeModel()));
4795 mpEditor->hide();
4796 connect(OptionsDialog::instance(), SIGNAL(metaModelicaEditorSettingsChanged())"2""metaModelicaEditorSettingsChanged()", pMetaModelicaHighlighter, SLOT(settingsChanged())"1""settingsChanged()");
4797 } else {
4798 mpEditor = new TextEditor(this);
4799 TextEditor *pTextEditor = dynamic_cast<TextEditor*>(mpEditor);
4800 pTextEditor->setPlainText(mpLibraryTreeItem->getClassText(pMainWindow->getLibraryWidget()->getLibraryTreeModel()));
4801 mpEditor->hide();
4802 }
4803 mpModelStatusBar->addPermanentWidget(mpReadOnlyLabel, 0);
4804 mpModelStatusBar->addPermanentWidget(mpModelFilePathLabel, 1);
4805 mpModelStatusBar->addPermanentWidget(mpFileLockToolButton, 0);
4806 // set layout
4807 pMainLayout->addWidget(mpModelStatusBar);
4808 } else if (mpLibraryTreeItem->getLibraryType() == LibraryTreeItem::CompositeModel) {
4809 connect(mpDiagramViewToolButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(showDiagramView(bool))"1""showDiagramView(bool)");
4810 connect(mpTextViewToolButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(showTextView(bool))"1""showTextView(bool)");
4811 pViewButtonsHorizontalLayout->addWidget(mpDiagramViewToolButton);
4812 pViewButtonsHorizontalLayout->addWidget(mpTextViewToolButton);
4813 // diagram graphics framework
4814 mpDiagramGraphicsScene = new GraphicsScene(StringHandler::Diagram, this);
4815 mpDiagramGraphicsView = new GraphicsView(StringHandler::Diagram, this);
4816 mpDiagramGraphicsView->setScene(mpDiagramGraphicsScene);
4817 mpDiagramGraphicsView->hide();
4818 // Undo stack for model
4819 mpUndoStack = new UndoStack;
4820 connect(mpUndoStack, SIGNAL(canUndoChanged(bool))"2""canUndoChanged(bool)", SLOT(handleCanUndoChanged(bool))"1""handleCanUndoChanged(bool)");
4821 connect(mpUndoStack, SIGNAL(canRedoChanged(bool))"2""canRedoChanged(bool)", SLOT(handleCanRedoChanged(bool))"1""handleCanRedoChanged(bool)");
4822 if (MainWindow::instance()->isDebug()) {
4823 mpUndoView = new QUndoView(mpUndoStack);
4824 }
4825 // create an xml editor for CompositeModel
4826 mpEditor = new CompositeModelEditor(this);
4827 CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpEditor);
4828 if (mpLibraryTreeItem->getFileName().isEmpty()) {
4829 QString defaultCompositeModelText = QString("<?xml version='1.0' encoding='UTF-8'?>\n"
4830 "<!-- The root node is the composite-model -->\n"
4831 "<Model Name=\"%1\">\n"
4832 " <!-- List of connected sub-models -->\n"
4833 " <SubModels/>\n"
4834 " <!-- List of TLM connections -->\n"
4835 " <Connections/>\n"
4836 " <!-- Parameters for the simulation -->\n"
4837 " <SimulationParams StartTime=\"0\" StopTime=\"1\" />\n"
4838 "</Model>").arg(mpLibraryTreeItem->getName());
4839 pCompositeModelEditor->setPlainText(defaultCompositeModelText, false);
4840 mpLibraryTreeItem->setClassText(defaultCompositeModelText);
4841 } else {
4842 pCompositeModelEditor->setPlainText(mpLibraryTreeItem->getClassText(pMainWindow->getLibraryWidget()->getLibraryTreeModel()), false);
4843 }
4844 CompositeModelHighlighter *pCompositeModelHighlighter = new CompositeModelHighlighter(OptionsDialog::instance()->getCompositeModelEditorPage(),
4845 mpEditor->getPlainTextEdit());
4846 mpEditor->hide(); // set it hidden so that Find/Replace action can get correct value.
4847 connect(OptionsDialog::instance(), SIGNAL(compositeModelEditorSettingsChanged())"2""compositeModelEditorSettingsChanged()", pCompositeModelHighlighter, SLOT(settingsChanged())"1""settingsChanged()");
4848 // only get the TLM submodels and connectors if the we are not creating a new class.
4849 if (!mpLibraryTreeItem->getFileName().isEmpty()) {
4850 getCompositeModelSubModels();
4851 getCompositeModelConnections();
4852 }
4853 mpDiagramGraphicsScene->clearSelection();
4854 mpModelStatusBar->addPermanentWidget(mpReadOnlyLabel, 0);
4855 mpModelStatusBar->addPermanentWidget(mpViewTypeLabel, 0);
4856 mpModelStatusBar->addPermanentWidget(mpModelFilePathLabel, 1);
4857 mpModelStatusBar->addPermanentWidget(mpFileLockToolButton, 0);
4858 // set layout
4859 pMainLayout->addWidget(mpModelStatusBar);
4860 if (MainWindow::instance()->isDebug()) {
4861 pMainLayout->addWidget(mpUndoView);
4862 }
4863 pMainLayout->addWidget(mpDiagramGraphicsView, 1);
4864 mpUndoStack->clear();
4865 } else if (mpLibraryTreeItem->getLibraryType() == LibraryTreeItem::OMS) {
4866 if (mpLibraryTreeItem->isSystemElement() || mpLibraryTreeItem->isComponentElement()) {
4867 connect(mpIconViewToolButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(showIconView(bool))"1""showIconView(bool)");
4868 pViewButtonsHorizontalLayout->addWidget(mpIconViewToolButton);
4869 }
4870 connect(mpDiagramViewToolButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(showDiagramView(bool))"1""showDiagramView(bool)");
4871 pViewButtonsHorizontalLayout->addWidget(mpDiagramViewToolButton);
4872 // Only the top level OMSimualtor models or systems or components will have the editor.
4873 if (mpLibraryTreeItem->isTopLevel() || mpLibraryTreeItem->isSystemElement() || mpLibraryTreeItem->isComponentElement()) {
4874 connect(mpTextViewToolButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(showTextView(bool))"1""showTextView(bool)");
4875 pViewButtonsHorizontalLayout->addWidget(mpTextViewToolButton);
4876 // create an editor
4877 mpEditor = new OMSimulatorEditor(this);
4878 mpEditor->getPlainTextEdit()->setReadOnly(true);
4879 OMSimulatorEditor *pOMSimulatorEditor = dynamic_cast<OMSimulatorEditor*>(mpEditor);
4880 pOMSimulatorEditor->setPlainText(mpLibraryTreeItem->getClassText(pMainWindow->getLibraryWidget()->getLibraryTreeModel()), false);
4881 OMSimulatorHighlighter *pOMSimulatorHighlighter = new OMSimulatorHighlighter(OptionsDialog::instance()->getOMSimulatorEditorPage(),
4882 mpEditor->getPlainTextEdit());
4883 mpEditor->hide(); // set it hidden so that Find/Replace action can get correct value.
4884 connect(OptionsDialog::instance(), SIGNAL(omsimulatorEditorSettingsChanged())"2""omsimulatorEditorSettingsChanged()", pOMSimulatorHighlighter, SLOT(settingsChanged())"1""settingsChanged()");
4885 }
4886 mpUndoStack->setEnabled(false);
4887 drawOMSModelDiagramElements();
4888 drawOMSModelConnections();
4889 mpUndoStack->setEnabled(true);
4890 mpDiagramGraphicsScene->clearSelection();
4891 mpModelStatusBar->addPermanentWidget(mpReadOnlyLabel, 0);
4892 mpModelStatusBar->addPermanentWidget(mpViewTypeLabel, 0);
4893 mpModelStatusBar->addPermanentWidget(mpModelFilePathLabel, 1);
4894 mpModelStatusBar->addPermanentWidget(mpFileLockToolButton, 0);
4895 // set layout
4896 pMainLayout->addWidget(mpModelStatusBar);
4897 if (MainWindow::instance()->isDebug()) {
4898 pMainLayout->addWidget(mpUndoView);
4899 }
4900 pMainLayout->addWidget(mpDiagramGraphicsView, 1);
4901 if (mpLibraryTreeItem->isSystemElement() || mpLibraryTreeItem->isComponentElement()) {
4902 pMainLayout->addWidget(mpIconGraphicsView, 1);
4903 }
4904 }
4905 if (mpEditor) {
4906 connect(mpEditor->getPlainTextEdit()->document(), SIGNAL(undoAvailable(bool))"2""undoAvailable(bool)", SLOT(handleCanUndoChanged(bool))"1""handleCanUndoChanged(bool)");
4907 connect(mpEditor->getPlainTextEdit()->document(), SIGNAL(redoAvailable(bool))"2""redoAvailable(bool)", SLOT(handleCanRedoChanged(bool))"1""handleCanRedoChanged(bool)");
4908 pMainLayout->addWidget(mpEditor, 1);
4909 }
4910 mCreateModelWidgetComponents = true;
4911 }
4912}
4913
4914/*!
4915 * \brief ModelWidget::drawOMSModelElement
4916 * Draws the OMS model element i.e, system, FMU or table.
4917 */
4918ShapeAnnotation* ModelWidget::drawOMSModelElement()
4919{
4920 if (mpLibraryTreeItem->getOMSElement()->geometry && mpLibraryTreeItem->getOMSElement()->geometry->iconSource) {
4921 // Draw bitmap with icon source
4922 QUrl url(mpLibraryTreeItem->getOMSElement()->geometry->iconSource);
4923 QFileInfo fileInfo(url.toLocalFile());
4924 BitmapAnnotation *pBitmapAnnotation = new BitmapAnnotation(fileInfo.absoluteFilePath(), mpIconGraphicsView);
4925 pBitmapAnnotation->drawCornerItems();
4926 pBitmapAnnotation->setCornerItemsActiveOrPassive();
4927 pBitmapAnnotation->applyTransformation();
4928 mpIconGraphicsView->addShapeToList(pBitmapAnnotation);
4929 mpIconGraphicsView->addItem(pBitmapAnnotation);
4930 return pBitmapAnnotation;
4931 } else {
4932 // Rectangle shape as base
4933 RectangleAnnotation *pRectangleAnnotation = new RectangleAnnotation(mpIconGraphicsView);
4934 if (mpLibraryTreeItem->isSystemElement()) {
4935 pRectangleAnnotation->setLineColor(QColor(128, 128, 0));
4936 pRectangleAnnotation->setFillColor(Qt::white);
4937 } else if (mpLibraryTreeItem->isFMUComponent()) {
4938 pRectangleAnnotation->setFillColor(Qt::white);
4939 } else if (mpLibraryTreeItem->isTableComponent()) {
4940 pRectangleAnnotation->setLinePattern(StringHandler::LineNone);
4941 if (mpLibraryTreeItem->getSubModelPath().endsWith(".csv")) {
4942 pRectangleAnnotation->setFillColor(QColor(0, 148, 21));
4943 } else {
4944 pRectangleAnnotation->setFillColor(QColor(3, 75, 220));
4945 }
4946 }
4947 pRectangleAnnotation->drawCornerItems();
4948 pRectangleAnnotation->setCornerItemsActiveOrPassive();
4949 pRectangleAnnotation->applyTransformation();
4950 mpIconGraphicsView->addShapeToList(pRectangleAnnotation);
4951 mpIconGraphicsView->addItem(pRectangleAnnotation);
4952 // Text for name
4953 TextAnnotation *pTextAnnotation = new TextAnnotation(mpIconGraphicsView);
4954 if (mpLibraryTreeItem->isSystemElement() || mpLibraryTreeItem->isFMUComponent()) {
4955 QList<QPointF> extents;
4956 extents << QPointF(-100, 80) << QPointF(100, 40);
4957 pTextAnnotation->setExtents(extents);
4958 if (mpLibraryTreeItem->isSystemElement()) {
4959 pTextAnnotation->setLineColor(QColor(128, 128, 0));
4960 }
4961 } else if (mpLibraryTreeItem->isTableComponent()) {
4962 pTextAnnotation->setLineColor(Qt::white);
4963 }
4964 pTextAnnotation->drawCornerItems();
4965 pTextAnnotation->setCornerItemsActiveOrPassive();
4966 pTextAnnotation->applyTransformation();
4967 mpIconGraphicsView->addShapeToList(pTextAnnotation);
4968 mpIconGraphicsView->addItem(pTextAnnotation);
4969 // Text for further information
4970 if (mpLibraryTreeItem->isSystemElement() || mpLibraryTreeItem->isFMUComponent()) {
4971 TextAnnotation *pInfoTextAnnotation = new TextAnnotation(mpIconGraphicsView);
4972 QList<QPointF> extents;
4973 extents << QPointF(-100, -40) << QPointF(100, -80);
4974 pInfoTextAnnotation->setExtents(extents);
4975 if (mpLibraryTreeItem->isSystemElement()) {
4976 pInfoTextAnnotation->setLineColor(QColor(128, 128, 0));
4977 pInfoTextAnnotation->setTextString(OMSProxy::getSystemTypeShortString(mpLibraryTreeItem->getSystemType()));
4978 } else {
4979 pInfoTextAnnotation->setTextString(QString("%1 %2").arg(OMSProxy::getFMUKindString(mpLibraryTreeItem->getFMUInfo()->fmiKind))
4980 .arg(QString(mpLibraryTreeItem->getFMUInfo()->fmiVersion)));
4981 }
4982 pInfoTextAnnotation->drawCornerItems();
4983 pInfoTextAnnotation->setCornerItemsActiveOrPassive();
4984 pInfoTextAnnotation->applyTransformation();
4985 mpIconGraphicsView->addShapeToList(pInfoTextAnnotation);
4986 mpIconGraphicsView->addItem(pInfoTextAnnotation);
4987 }
4988 return pRectangleAnnotation;
4989 }
4990}
4991
4992/*!
4993 * \brief ModelWidget::getConnectorComponent
4994 * Finds the Port Component within the Component.
4995 * \param pConnectorComponent
4996 * \param connectorName
4997 * \return
4998 */
4999Component* ModelWidget::getConnectorComponent(Component *pConnectorComponent, QString connectorName)
5000{
5001 Component *pConnectorComponentFound = 0;
5002 foreach (Component *pComponent, pConnectorComponent->getComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pConnectorComponent
->getComponentsList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pComponent = *_container_.i; _container_.control
; _container_.control = 0)
{
5003 if (pComponent->getName().compare(connectorName) == 0) {
5004 pConnectorComponentFound = pComponent;
5005 return pConnectorComponentFound;
5006 }
5007 foreach (Component *pInheritedComponent, pComponent->getInheritedComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pComponent
->getInheritedComponentsList()); _container_.control &&
_container_.i != _container_.e; ++_container_.i, _container_
.control ^= 1) for (Component *pInheritedComponent = *_container_
.i; _container_.control; _container_.control = 0)
{
5008 pConnectorComponentFound = getConnectorComponent(pInheritedComponent, connectorName);
5009 if (pConnectorComponentFound) {
5010 return pConnectorComponentFound;
5011 }
5012 }
5013 }
5014 /* if port is not found in components list then look into the inherited components list. */
5015 foreach (Component *pInheritedComponent, pConnectorComponent->getInheritedComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pConnectorComponent
->getInheritedComponentsList()); _container_.control &&
_container_.i != _container_.e; ++_container_.i, _container_
.control ^= 1) for (Component *pInheritedComponent = *_container_
.i; _container_.control; _container_.control = 0)
{
5016 pConnectorComponentFound = getConnectorComponent(pInheritedComponent, connectorName);
5017 if (pConnectorComponentFound) {
5018 return pConnectorComponentFound;
5019 }
5020 }
5021 return pConnectorComponentFound;
5022}
5023
5024void ModelWidget::clearGraphicsViews()
5025{
5026 /* remove everything from the icon view */
5027 if (mpIconGraphicsView) {
5028 mpIconGraphicsView->clearGraphicsView();
5029 }
5030 /* remove everything from the diagram view */
5031 if (mpDiagramGraphicsView) {
5032 mpDiagramGraphicsView->clearGraphicsView();
5033 }
5034}
5035
5036/*!
5037 * \brief ModelWidget::reDrawModelWidget
5038 * Redraws the ModelWidget.
5039 */
5040void ModelWidget::reDrawModelWidget()
5041{
5042 QApplication::setOverrideCursor(Qt::WaitCursor);
5043 clearGraphicsViews();
5044 /* get model components, connection and shapes. */
5045 if (getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::CompositeModel) {
5046 // read new CompositeModel name
5047 QString compositeModelName = getCompositeModelName();
5048 mpLibraryTreeItem->setName(compositeModelName);
5049 MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->updateLibraryTreeItem(mpLibraryTreeItem);
5050 setWindowTitle(compositeModelName);
5051 // get the submodels and connections
5052 getCompositeModelSubModels();
5053 getCompositeModelConnections();
5054 // clear the undo stack
5055 mpUndoStack->clear();
5056// if (mpEditor) {
5057// mpEditor->getPlainTextEdit()->document()->clearUndoRedoStacks();
5058// }
5059 } else if (getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) {
5060 MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->updateLibraryTreeItem(mpLibraryTreeItem);
5061 // get the submodels and connections
5062 drawOMSModelIconElements();
5063 drawOMSModelDiagramElements();
5064 drawOMSModelConnections();
5065 // clear the undo stack
5066 mpUndoStack->clear();
5067// if (mpEditor) {
5068// mpEditor->getPlainTextEdit()->document()->clearUndoRedoStacks();
5069// }
5070 } else {
5071 // Draw icon view
5072 mExtendsModifiersLoaded = false;
5073 mDerivedClassModifiersLoaded = false;
5074 // reset the CoOrdinateSystem
5075 if (mpIconGraphicsView) {
5076 mpIconGraphicsView->setCoOrdinateSystem(CoOrdinateSystem());
5077 }
5078 /* remove everything from the diagram view */
5079 if (mpDiagramGraphicsView) {
5080 mpDiagramGraphicsView->setCoOrdinateSystem(CoOrdinateSystem());
5081 }
5082 // remove saved inherited classes
5083 clearInheritedClasses();
5084 // get inherited classes
5085 getModelInheritedClasses();
5086 // Draw Icon shapes and inherited shapes
5087 drawModelInheritedClassShapes(this, StringHandler::Icon);
5088 getModelIconDiagramShapes(StringHandler::Icon);
5089 // clear the components and their annotations
5090 mComponentsList.clear();
5091 mComponentsAnnotationsList.clear();
5092 mComponentsLoaded = false;
5093 // get the model components
5094 loadComponents();
5095 // invalidate the simulation options
5096 mpLibraryTreeItem->mSimulationOptions.setIsValid(false);
5097 // update the icon
5098 mpLibraryTreeItem->handleIconUpdated();
5099 // Draw diagram view
5100 if (mDiagramViewLoaded) {
5101 // reset flags
5102 mDiagramViewLoaded = false;
5103 loadDiagramView();
5104 mConnectionsLoaded = false;
5105 loadConnections();
5106 }
5107 // if documentation view is visible then update it
5108 if (MainWindow::instance()->getDocumentationDockWidget()->isVisible()) {
5109 MainWindow::instance()->getDocumentationWidget()->showDocumentation(getLibraryTreeItem());
5110 }
5111 // clear the undo stack
5112 mpUndoStack->clear();
5113// if (mpEditor) {
5114// mpEditor->getPlainTextEdit()->document()->clearUndoRedoStacks();
5115// }
5116 updateViewButtonsBasedOnAccess();
5117 // announce the change.
5118 mpLibraryTreeItem->emitLoaded();
5119 }
5120 QApplication::restoreOverrideCursor();
5121}
5122
5123/*!
5124 * \brief ModelWidget::validateText
5125 * Validates the text of the editor.
5126 * \param pLibraryTreeItem
5127 * \return Returns true if validation is successful otherwise return false.
5128 */
5129bool ModelWidget::validateText(LibraryTreeItem **pLibraryTreeItem)
5130{
5131 if (ModelicaEditor *pModelicaEditor = dynamic_cast<ModelicaEditor*>(mpEditor)) {
5132 return pModelicaEditor->validateText(pLibraryTreeItem);
5133 } else if (CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpEditor)) {
5134 return pCompositeModelEditor->validateText();
5135 } else if (OMSimulatorEditor *pOMSimulatorEditor = dynamic_cast<OMSimulatorEditor*>(mpEditor)) {
5136 return pOMSimulatorEditor->validateText();
5137 } else {
5138 return true;
5139 }
5140}
5141
5142/*!
5143 * \brief ModelWidget::modelicaEditorTextChanged
5144 * Called when Modelica text has been changed by user manually.\n
5145 * Updates the LibraryTreeItem and ModelWidget with new changes.
5146 * \param pLibraryTreeItem
5147 * \return
5148 * \sa ModelicaEditor::getClassNames()
5149 */
5150bool ModelWidget::modelicaEditorTextChanged(LibraryTreeItem **pLibraryTreeItem)
5151{
5152 QString errorString;
5153 ModelicaEditor *pModelicaEditor = dynamic_cast<ModelicaEditor*>(mpEditor);
5154 QStringList classNames = pModelicaEditor->getClassNames(&errorString);
5155 LibraryTreeModel *pLibraryTreeModel = MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel();
5156 OMCProxy *pOMCProxy = MainWindow::instance()->getOMCProxy();
5157 QString modelicaText = pModelicaEditor->getPlainText();
5158 QString stringToLoad;
5159 LibraryTreeItem *pParentLibraryTreeItem = pLibraryTreeModel->getContainingFileParentLibraryTreeItem(mpLibraryTreeItem);
5160 if (pParentLibraryTreeItem != mpLibraryTreeItem) {
5161 stringToLoad = mpLibraryTreeItem->getClassTextBefore() + StringHandler::trimmedEnd(modelicaText) + "\n" + mpLibraryTreeItem->getClassTextAfter();
5162 } else {
5163 stringToLoad = modelicaText;
5164 }
5165 if (classNames.size() == 0) {
5166 /* if the error is occured in P.M and package is saved in one file.
5167 * then update the package contents with new invalid code because we open P when user clicks on the error message.
5168 */
5169 if (mpLibraryTreeItem->isInPackageOneFile()) {
5170 if (!pParentLibraryTreeItem->getModelWidget()) {
5171 pLibraryTreeModel->showModelWidget(pParentLibraryTreeItem, false);
5172 }
5173 pParentLibraryTreeItem->getModelWidget()->createModelWidgetComponents();
5174 pParentLibraryTreeItem->setClassText(stringToLoad);
5175 }
5176 if (!errorString.isEmpty()) {
5177 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, errorString, Helper::syntaxKind,
5178 Helper::errorLevel));
5179 }
5180 return false;
5181 }
5182 /* if no errors are found with the Modelica Text then load it in OMC */
5183 QString className = classNames.at(0);
5184 if (pParentLibraryTreeItem != mpLibraryTreeItem) {
5185 // only use OMCProxy::loadString merge when LibraryTreeItem::SaveFolderStructure i.e., package.mo
5186 if (!pOMCProxy->loadString(stringToLoad, pParentLibraryTreeItem->getFileName(), Helper::utf8, pParentLibraryTreeItem->getSaveContentsType() == LibraryTreeItem::SaveFolderStructure)) {
5187 return false;
5188 }
5189 } else {
5190 // only use OMCProxy::loadString merge when LibraryTreeItem::SaveFolderStructure i.e., package.mo
5191 if (!pOMCProxy->loadString(stringToLoad, mpLibraryTreeItem->getFileName(), Helper::utf8, mpLibraryTreeItem->getSaveContentsType() == LibraryTreeItem::SaveFolderStructure)) {
5192 return false;
5193 }
5194 }
5195 /* if user has changed the class contents then refresh it. */
5196 if (className.compare(mpLibraryTreeItem->getNameStructure()) == 0) {
5197 mpLibraryTreeItem->setClassInformation(pOMCProxy->getClassInformation(mpLibraryTreeItem->getNameStructure()));
5198 reDrawModelWidget();
5199 mpLibraryTreeItem->setClassText(modelicaText);
5200 if (mpLibraryTreeItem->isInPackageOneFile()) {
5201 pParentLibraryTreeItem->setClassText(stringToLoad);
5202 updateModelText();
5203 }
5204 // update child classes
5205 updateChildClasses(mpLibraryTreeItem);
5206 } else {
5207 /* if user has changed the class name then delete this class.
5208 * Update the LibraryTreeItem with new class name and then refresh it.
5209 */
5210 int row = mpLibraryTreeItem->row();
5211 /* if a class inside a package one file is renamed then it is already deleted by calling loadString using the whole package contents
5212 * so we tell unloadLibraryTreeItem to don't try deleteClass since it will only produce error
5213 */
5214 pLibraryTreeModel->unloadLibraryTreeItem(mpLibraryTreeItem, !mpLibraryTreeItem->isInPackageOneFile());
5215 mpLibraryTreeItem->setModelWidget(0);
5216 QString name = StringHandler::getLastWordAfterDot(className);
5217 LibraryTreeItem *pNewLibraryTreeItem = pLibraryTreeModel->createLibraryTreeItem(name, mpLibraryTreeItem->parent(), false, false, true, row);
5218 setWindowTitle(pNewLibraryTreeItem->getName() + (pNewLibraryTreeItem->isSaved() ? "" : "*"));
5219 setModelClassPathLabel(pNewLibraryTreeItem->getNameStructure());
5220 pNewLibraryTreeItem->setSaveContentsType(mpLibraryTreeItem->getSaveContentsType());
5221 pLibraryTreeModel->checkIfAnyNonExistingClassLoaded();
5222 // make the new created LibraryTreeItem selected
5223 QModelIndex modelIndex = pLibraryTreeModel->libraryTreeItemIndex(pNewLibraryTreeItem);
5224 LibraryTreeProxyModel *pLibraryTreeProxyModel = MainWindow::instance()->getLibraryWidget()->getLibraryTreeProxyModel();
5225 QModelIndex proxyIndex = pLibraryTreeProxyModel->mapFromSource(modelIndex);
5226 LibraryTreeView *pLibraryTreeView = MainWindow::instance()->getLibraryWidget()->getLibraryTreeView();
5227 pLibraryTreeView->selectionModel()->clearSelection();
5228 pLibraryTreeView->selectionModel()->select(proxyIndex, QItemSelectionModel::Select);
5229 // update class text
5230 pNewLibraryTreeItem->setModelWidget(this);
5231 pNewLibraryTreeItem->setClassText(modelicaText);
5232 setLibraryTreeItem(pNewLibraryTreeItem);
5233 setModelFilePathLabel(pNewLibraryTreeItem->getFileName());
5234 reDrawModelWidget();
5235 if (pNewLibraryTreeItem->isInPackageOneFile()) {
5236 pNewLibraryTreeItem->setClassText(stringToLoad);
5237 updateModelText();
5238 }
5239 *pLibraryTreeItem = pNewLibraryTreeItem;
5240 }
5241 return true;
5242}
5243
5244void ModelWidget::updateChildClasses(LibraryTreeItem *pLibraryTreeItem)
5245{
5246 MainWindow *pMainWindow = MainWindow::instance();
5247 LibraryTreeModel *pLibraryTreeModel = pMainWindow->getLibraryWidget()->getLibraryTreeModel();
5248 QStringList classNames = pMainWindow->getOMCProxy()->getClassNames(pLibraryTreeItem->getNameStructure());
5249 // first remove the classes that are removed by the user
5250 int i = 0;
5251 while(i != pLibraryTreeItem->childrenSize()) {
5252 LibraryTreeItem *pChildLibraryTreeItem = pLibraryTreeItem->child(i);
5253 if (!classNames.contains(pChildLibraryTreeItem->getName())) {
5254 pLibraryTreeModel->removeLibraryTreeItem(pChildLibraryTreeItem, LibraryTreeItem::Modelica);
5255 i = 0; //Restart iteration if list has changed
5256 } else {
5257 i++;
5258 }
5259 }
5260 // update and create any new classes
5261 int index = 0;
5262 foreach (QString className, classNames)for (auto _container_ = QtPrivate::qMakeForeachContainer(classNames
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString className
= *_container_.i; _container_.control; _container_.control =
0)
{
5263 QString classNameStructure = QString("%1.%2").arg(pLibraryTreeItem->getNameStructure()).arg(className);
5264 LibraryTreeItem *pChildLibraryTreeItem = pLibraryTreeModel->findLibraryTreeItem(classNameStructure);
5265 // if the class already exists then we update it if needed.
5266 if (pChildLibraryTreeItem) {
5267 if (pChildLibraryTreeItem->isInPackageOneFile()) {
5268 // update the class information
5269 pChildLibraryTreeItem->setClassInformation(pMainWindow->getOMCProxy()->getClassInformation(pChildLibraryTreeItem->getNameStructure()));
5270 if (pLibraryTreeItem->isExpanded()) {
5271 if (pChildLibraryTreeItem->getModelWidget()) {
5272 pChildLibraryTreeItem->getModelWidget()->reDrawModelWidget();
5273 pLibraryTreeModel->readLibraryTreeItemClassText(pChildLibraryTreeItem);
5274 }
5275 updateChildClasses(pChildLibraryTreeItem);
5276 }
5277 }
5278 } else if (!pChildLibraryTreeItem) { // if the class doesn't exists then create one.
5279 pLibraryTreeModel->createLibraryTreeItem(className, pLibraryTreeItem, false, false, true, index);
5280 pLibraryTreeModel->checkIfAnyNonExistingClassLoaded();
5281 }
5282 index++;
5283 }
5284}
5285
5286/*!
5287 * \brief ModelWidget::omsimulatorEditorTextChanged
5288 * Called when OMSimulatorEditor text has been changed by user manually.\n
5289 * Updates the LibraryTreeItem and ModelWidget with new changes.
5290 * \return
5291 */
5292bool ModelWidget::omsimulatorEditorTextChanged()
5293{
5294 OMSimulatorEditor *pOMSimulatorEditor = dynamic_cast<OMSimulatorEditor*>(mpEditor);
5295 QFileInfo fileInfo(mpLibraryTreeItem->getFileName());
5296 if (fileInfo.exists()) {
5297 OMSProxy::instance()->setWorkingDirectory(fileInfo.absoluteDir().absolutePath());
5298 }
5299 QString modelName;
5300 bool success = false;
5301 if (OMSProxy::instance()->parseString(pOMSimulatorEditor->getPlainTextEdit()->toPlainText(), &modelName)) {
5302 if (mpLibraryTreeItem->getNameStructure().compare(modelName) != 0
5303 && MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->findLibraryTreeItemOneLevel(modelName)) {
5304 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica,
5305 GUIMessages::getMessage(GUIMessages::MODEL_ALREADY_EXISTS)
5306 .arg("Composite model").arg(modelName).arg("scope"),
5307 Helper::scriptingKind, Helper::errorLevel));
5308 return false;
5309 }
5310 success = OMSProxy::instance()->loadString(pOMSimulatorEditor->getPlainTextEdit()->toPlainText(), &modelName);
5311 }
5312 if (fileInfo.exists()) {
5313 OMSProxy::instance()->setWorkingDirectory(OptionsDialog::instance()->getOMSimulatorPage()->getWorkingDirectory());
5314 }
5315 if (success) {
5316 // model name has changed
5317 if (mpLibraryTreeItem->getNameStructure().compare(modelName) != 0) {
5318 // unload the old model from OMSimulator
5319 OMSProxy::instance()->omsDelete(mpLibraryTreeItem->getNameStructure());
5320 // Update to the new name
5321 mpLibraryTreeItem->setName(modelName);
5322 mpLibraryTreeItem->setNameStructure(modelName);
5323 setWindowTitle(mpLibraryTreeItem->getName() + (mpLibraryTreeItem->isSaved() ? "" : "*"));
5324 setModelClassPathLabel(mpLibraryTreeItem->getNameStructure());
5325 }
5326 // Update the OMS element
5327 oms_element_t *pOMSElement = 0;
5328 OMSProxy::instance()->getElement(mpLibraryTreeItem->getNameStructure(), &pOMSElement);
5329 mpLibraryTreeItem->setOMSElement(pOMSElement);
5330 // remove the children
5331 int i = 0;
5332 while (i < mpLibraryTreeItem->childrenSize()) {
5333 MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->removeLibraryTreeItem(mpLibraryTreeItem->child(i), LibraryTreeItem::OMS);
5334 i = 0; //Restart iteration
5335 }
5336 // create the children
5337 QModelIndex modelIndex = MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->libraryTreeItemIndex(mpLibraryTreeItem);
5338 QModelIndex proxyIndex = MainWindow::instance()->getLibraryWidget()->getLibraryTreeProxyModel()->mapFromSource(modelIndex);
5339 MainWindow::instance()->getLibraryWidget()->getLibraryTreeView()->collapse(proxyIndex);
5340 mpLibraryTreeItem->setExpanded(false);
5341 MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->createLibraryTreeItems(mpLibraryTreeItem);
5342 reDrawModelWidget();
5343 mpLibraryTreeItem->setClassText(pOMSimulatorEditor->getPlainTextEdit()->toPlainText());
5344 return true;
5345 } else {
5346 return false;
5347 }
5348}
5349
5350/*!
5351 * \brief ModelWidget::clearSelection
5352 * Clears the selection Icon and Diagram layers.
5353 */
5354void ModelWidget::clearSelection()
5355{
5356 if (mpIconGraphicsView) {
5357 mpIconGraphicsView->clearSelection();
5358 }
5359 if (mpDiagramGraphicsView) {
5360 mpDiagramGraphicsView->clearSelection();
5361 }
5362}
5363
5364/*!
5365 * \brief ModelWidget::updateClassAnnotationIfNeeded
5366 * Updates the class annotation for both icon and diagram views if needed.
5367 */
5368void ModelWidget::updateClassAnnotationIfNeeded()
5369{
5370 if (mpLibraryTreeItem->getLibraryType() == LibraryTreeItem::Modelica) {
5371 if (mpIconGraphicsView && mpIconGraphicsView->isAddClassAnnotationNeeded()) {
5372 mpIconGraphicsView->addClassAnnotation();
5373 mpIconGraphicsView->setAddClassAnnotationNeeded(false);
5374 }
5375 if (mpDiagramGraphicsView && mpDiagramGraphicsView->isAddClassAnnotationNeeded()) {
5376 mpDiagramGraphicsView->addClassAnnotation();
5377 mpDiagramGraphicsView->setAddClassAnnotationNeeded(false);
5378 }
5379 }
5380}
5381
5382/*!
5383 * \brief ModelWidget::updateModelText
5384 * Updates the Text of the class.
5385 */
5386void ModelWidget::updateModelText()
5387{
5388 LibraryTreeModel *pLibraryTreeModel = MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel();
5389 // Don't allow updating the child LibraryTreeItems of OMS model
5390 if (mpLibraryTreeItem->getLibraryType() == LibraryTreeItem::OMS && !mpLibraryTreeItem->isTopLevel()) {
5391 if (mpLibraryTreeItem->parent()->getModelWidget()) {
5392 mpLibraryTreeItem->parent()->getModelWidget()->updateModelText();
5393 } else {
5394 pLibraryTreeModel->updateLibraryTreeItemClassText(mpLibraryTreeItem->parent());
5395 }
5396 // set the library node not saved.
5397 mpLibraryTreeItem->setIsSaved(false);
5398 pLibraryTreeModel->updateLibraryTreeItem(mpLibraryTreeItem);
5399 if (mpLibraryTreeItem->isComponentElement()) {
5400 pLibraryTreeModel->updateOMSChildLibraryTreeItemClassText(mpLibraryTreeItem->parent());
5401 } else {
5402 pLibraryTreeModel->updateOMSChildLibraryTreeItemClassText(mpLibraryTreeItem);
5403 }
5404 return;
5405 }
5406 setWindowTitle(QString(mpLibraryTreeItem->getName()).append("*"));
5407 pLibraryTreeModel->updateLibraryTreeItemClassText(mpLibraryTreeItem);
5408#if !defined(WITHOUT_OSG)
5409 // update the ThreeDViewer Browser
5410 if (mpLibraryTreeItem->getLibraryType() == LibraryTreeItem::CompositeModel) {
5411 MainWindow::instance()->getModelWidgetContainer()->updateThreeDViewer(this);
5412 }
5413#endif
5414}
5415
5416/*!
5417 * \brief ModelWidget::updateModelicaTextManually
5418 * Updates the Parent Modelica class text after user has made changes manually in the text view.
5419 * \param contents
5420 */
5421void ModelWidget::updateModelicaTextManually(QString contents)
5422{
5423 setWindowTitle(QString(mpLibraryTreeItem->getName()).append("*"));
5424 LibraryTreeModel *pLibraryTreeModel = MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel();
5425 pLibraryTreeModel->updateLibraryTreeItemClassTextManually(mpLibraryTreeItem, contents);
5426}
5427
5428/*!
5429 * \brief ModelWidget::updateUndoRedoActions
5430 * Enables/disables the Undo/Redo actions based on the stack situation.
5431 */
5432void ModelWidget::updateUndoRedoActions()
5433{
5434 if (mpIconGraphicsView && mpIconGraphicsView->isVisible()) {
5435 MainWindow::instance()->getUndoAction()->setEnabled(mpUndoStack->canUndo());
5436 MainWindow::instance()->getRedoAction()->setEnabled(mpUndoStack->canRedo());
5437 } else if (mpDiagramGraphicsView && mpDiagramGraphicsView->isVisible()) {
5438 MainWindow::instance()->getUndoAction()->setEnabled(mpUndoStack->canUndo());
5439 MainWindow::instance()->getRedoAction()->setEnabled(mpUndoStack->canRedo());
5440 } else if (mpEditor && mpEditor->isVisible()) {
5441 MainWindow::instance()->getUndoAction()->setEnabled(mpEditor->getPlainTextEdit()->document()->isUndoAvailable());
5442 MainWindow::instance()->getRedoAction()->setEnabled(mpEditor->getPlainTextEdit()->document()->isRedoAvailable());
5443 } else {
5444 MainWindow::instance()->getUndoAction()->setEnabled(false);
5445 MainWindow::instance()->getRedoAction()->setEnabled(false);
5446 }
5447}
5448
5449/*!
5450 * \brief ModelWidget::writeCoSimulationResultFile
5451 * Writes the co-simulation csv result file for 3d viewer.
5452 * \param fileName
5453 */
5454bool ModelWidget::writeCoSimulationResultFile(QString fileName)
5455{
5456 // this function is only for meta-models
5457 if (mpLibraryTreeItem->getLibraryType() != LibraryTreeItem::CompositeModel) {
5458 return false;
5459 }
5460 // first remove the result file.
5461 if (QFile::exists(fileName)) {
5462 if (!QFile::remove(fileName)) {
5463 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica,
5464 GUIMessages::getMessage(GUIMessages::UNABLE_TO_DELETE_FILE).arg(fileName),
5465 Helper::scriptingKind, Helper::errorLevel));
5466 }
5467 }
5468 // write the result file.
5469 QFile file(fileName);
5470 if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
5471 QTextStream resultFile(&file);
5472 // set to UTF-8
5473 resultFile.setCodec(Helper::utf8.toUtf8().constData());
5474 resultFile.setGenerateByteOrderMark(false);
5475 // write result file header
5476 resultFile << "\"" << "time\",";
5477 int nActiveInterfaces = 0;
5478 foreach (Component *pSubModelComponent, mpDiagramGraphicsView->getComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(mpDiagramGraphicsView
->getComponentsList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pSubModelComponent = *_container_.i; _container_
.control; _container_.control = 0)
{
5479 foreach (Component *pInterfaceComponent, pSubModelComponent->getComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pSubModelComponent
->getComponentsList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pInterfaceComponent = *_container_.i; _container_
.control; _container_.control = 0)
{
5480 QString name = QString("%1.%2").arg(pSubModelComponent->getName()).arg(pInterfaceComponent->getName());
5481 /*!
5482 * \note Don't check for connection.
5483 * If we check for connection then only connected submodels can be seen in the ThreeDViewer Browser.
5484 */
5485 // foreach (LineAnnotation *pConnectionLineAnnotation, mpDiagramGraphicsView->getConnectionsList()) {
5486 // if ((pConnectionLineAnnotation->getStartComponentName().compare(name) == 0) ||
5487 // (pConnectionLineAnnotation->getEndComponentName().compare(name) == 0)) {
5488 // Comma between interfaces
5489 if (nActiveInterfaces > 0) {
5490 resultFile << ",";
5491 }
5492 resultFile << "\"" << name << ".R[cG][cG](1) [m]\",\"" << name << ".R[cG][cG](2) [m]\",\"" << name << ".R[cG][cG](3) [m]\","; // Position vector
5493 resultFile << "\"" << name << ".A(1,1) [-]\",\"" << name << ".A(1,2) [-]\",\"" << name << ".A(1,3) [-]\",\""
5494 << name << ".A(2,1) [-]\",\"" << name << ".A(2,2) [-]\",\"" << name << ".A(2,3) [-]\",\""
5495 << name << ".A(3,1) [-]\",\"" << name << ".A(3,2) [-]\",\"" << name << ".A(3,3) [-]\""; // Transformation matrix
5496 nActiveInterfaces++;
5497 // }
5498 // }
5499 }
5500 }
5501 // write just single data for result file
5502 resultFile << "\n" << "0,";
5503 nActiveInterfaces = 0;
5504 foreach (Component *pSubModelComponent, mpDiagramGraphicsView->getComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(mpDiagramGraphicsView
->getComponentsList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pSubModelComponent = *_container_.i; _container_
.control; _container_.control = 0)
{
5505 foreach (Component *pInterfaceComponent, pSubModelComponent->getComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pSubModelComponent
->getComponentsList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pInterfaceComponent = *_container_.i; _container_
.control; _container_.control = 0)
{
5506 /*!
5507 * \note Don't check for connection.
5508 * If we check for connection then only connected submodels can be seen in the ThreeDViewer Browser.
5509 */
5510 // QString name = QString("%1.%2").arg(pSubModelComponent->getName()).arg(pInterfaceComponent->getName());
5511 // foreach (LineAnnotation *pConnectionLineAnnotation, mpDiagramGraphicsView->getConnectionsList()) {
5512 // if ((pConnectionLineAnnotation->getStartComponentName().compare(name) == 0) ||
5513 // (pConnectionLineAnnotation->getEndComponentName().compare(name) == 0)) {
5514 // Comma between interfaces
5515 if (nActiveInterfaces > 0) {
5516 resultFile << ",";
5517 }
5518
5519 // get the submodel position
5520 double values[] = {0.0, 0.0, 0.0};
5521 QGenericMatrix<3, 1, double> cX_R_cG_cG(values);
5522 QStringList subModelPositionList = pSubModelComponent->getComponentInfo()->getPosition().split(",", QString::SkipEmptyParts);
5523 if (subModelPositionList.size() > 2) {
5524 cX_R_cG_cG(0, 0) = subModelPositionList.at(0).toDouble();
5525 cX_R_cG_cG(0, 1) = subModelPositionList.at(1).toDouble();
5526 cX_R_cG_cG(0, 2) = subModelPositionList.at(2).toDouble();
5527 }
5528 // get the submodel angle
5529 double subModelPhi[3] = {0.0, 0.0, 0.0};
5530 QStringList subModelAngleList = pSubModelComponent->getComponentInfo()->getAngle321().split(",", QString::SkipEmptyParts);
5531 if (subModelAngleList.size() > 2) {
5532 subModelPhi[0] = subModelAngleList.at(0).toDouble();
5533 subModelPhi[1] = subModelAngleList.at(1).toDouble();
5534 subModelPhi[2] = subModelAngleList.at(2).toDouble();
5535 }
5536 QGenericMatrix<3, 3, double> cX_A_cG = Utilities::getRotationMatrix(QGenericMatrix<3, 1, double>(subModelPhi));
5537 // get the interface position
5538 QGenericMatrix<3, 1, double> ci_R_cX_cX(values);
5539 QStringList interfacePositionList = pInterfaceComponent->getComponentInfo()->getPosition().split(",", QString::SkipEmptyParts);
5540 if (interfacePositionList.size() > 2) {
5541 ci_R_cX_cX(0, 0) = interfacePositionList.at(0).toDouble();
5542 ci_R_cX_cX(0, 1) = interfacePositionList.at(1).toDouble();
5543 ci_R_cX_cX(0, 2) = interfacePositionList.at(2).toDouble();
5544 }
5545 // get the interface angle
5546 double interfacePhi[3] = {0.0, 0.0, 0.0};
5547 QStringList interfaceAngleList = pInterfaceComponent->getComponentInfo()->getAngle321().split(",", QString::SkipEmptyParts);
5548 if (interfaceAngleList.size() > 2) {
5549 interfacePhi[0] = interfaceAngleList.at(0).toDouble();
5550 interfacePhi[1] = interfaceAngleList.at(1).toDouble();
5551 interfacePhi[2] = interfaceAngleList.at(2).toDouble();
5552 }
5553 QGenericMatrix<3, 3, double> ci_A_cX = Utilities::getRotationMatrix(QGenericMatrix<3, 1, double>(interfacePhi));
5554
5555 QGenericMatrix<3, 1, double> ci_R_cG_cG = cX_R_cG_cG + ci_R_cX_cX*cX_A_cG;
5556 QGenericMatrix<3, 3, double> ci_A_cG = ci_A_cX*cX_A_cG;
5557
5558 // write data
5559 resultFile << ci_R_cG_cG(0, 0) << "," << ci_R_cG_cG(0, 1) << "," << ci_R_cG_cG(0, 2) << ","; // Position vector
5560 resultFile << ci_A_cG(0, 0) << "," << ci_A_cG(0, 1) << "," << ci_A_cG(0, 2) << ","
5561 << ci_A_cG(1, 0) << "," << ci_A_cG(1, 1) << "," << ci_A_cG(1, 2) << ","
5562 << ci_A_cG(2, 0) << "," << ci_A_cG(2, 1) << "," << ci_A_cG(2, 2); // Transformation matrix
5563 nActiveInterfaces++;
5564 // }
5565 // }
5566 }
5567 }
5568 file.close();
5569 return true;
5570 } else {
5571 QString msg = GUIMessages::getMessage(GUIMessages::ERROR_OCCURRED).arg(GUIMessages::getMessage(GUIMessages::UNABLE_TO_SAVE_FILE)
5572 .arg(fileName).arg(file.errorString()));
5573 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, msg, Helper::scriptingKind,
5574 Helper::errorLevel));
5575 return false;
5576 }
5577}
5578
5579/*!
5580 * \brief ModelWidget::writeVisualXMLFile
5581 * Writes the visual xml file for 3d visualization.
5582 * \param fileName
5583 * \param canWriteVisualXMLFile
5584 * \return
5585 */
5586bool ModelWidget::writeVisualXMLFile(QString fileName, bool canWriteVisualXMLFile)
5587{
5588 // this function is only for meta-models
5589 if (mpLibraryTreeItem->getLibraryType() != LibraryTreeItem::CompositeModel) {
5590 return false;
5591 }
5592 // first remove the visual xml file.
5593 if (QFile::exists(fileName)) {
5594 if (!QFile::remove(fileName)) {
5595 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica,
5596 GUIMessages::getMessage(GUIMessages::UNABLE_TO_DELETE_FILE).arg(fileName),
5597 Helper::scriptingKind, Helper::errorLevel));
5598 }
5599 }
5600 // can we write visual xml file.
5601 if (!canWriteVisualXMLFile) {
5602 foreach (Component *pSubModelComponent, mpDiagramGraphicsView->getComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(mpDiagramGraphicsView
->getComponentsList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pSubModelComponent = *_container_.i; _container_
.control; _container_.control = 0)
{
5603 if (!pSubModelComponent->getComponentInfo()->getGeometryFile().isEmpty()) {
5604 canWriteVisualXMLFile = true;
5605 }
5606 }
5607 if (!canWriteVisualXMLFile) {
5608 return false;
5609 }
5610 }
5611 // write the visual xml file.
5612 QFile file(fileName);
5613 if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
5614 QTextStream visualFile(&file);
5615 // set to UTF-8
5616 visualFile.setCodec(Helper::utf8.toUtf8().constData());
5617 visualFile.setGenerateByteOrderMark(false);
5618
5619 visualFile << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
5620 visualFile << "<visualization>\n";
5621 visualFile << " <shape>\n";
5622 visualFile << " <ident>x-axis</ident>\n";
5623 visualFile << " <type>cylinder</type>\n";
5624 visualFile << " <T>\n";
5625 visualFile << " <exp>1.0</exp>\n";
5626 visualFile << " <exp>0.0</exp>\n";
5627 visualFile << " <exp>0.0</exp>\n";
5628 visualFile << " <exp>0.0</exp>\n";
5629 visualFile << " <exp>1.0</exp>\n";
5630 visualFile << " <exp>0.0</exp>\n";
5631 visualFile << " <exp>0.0</exp>\n";
5632 visualFile << " <exp>0.0</exp>\n";
5633 visualFile << " <exp>1.0</exp>\n";
5634 visualFile << " </T>\n";
5635 visualFile << " <r>\n";
5636 visualFile << " <exp>0.0</exp>\n";
5637 visualFile << " <exp>0.0</exp>\n";
5638 visualFile << " <exp>0.0</exp>\n";
5639 visualFile << " </r>\n";
5640 visualFile << " <r_shape>\n";
5641 visualFile << " <exp>0.0</exp>\n";
5642 visualFile << " <exp>0.0</exp>\n";
5643 visualFile << " <exp>0.0</exp>\n";
5644 visualFile << " </r_shape>\n";
5645 visualFile << " <lengthDir>\n";
5646 visualFile << " <exp>1.0</exp>\n";
5647 visualFile << " <exp>0.0</exp>\n";
5648 visualFile << " <exp>0.0</exp>\n";
5649 visualFile << " </lengthDir>\n";
5650 visualFile << " <widthDir>\n";
5651 visualFile << " <exp>0.0</exp>\n";
5652 visualFile << " <exp>1.0</exp>\n";
5653 visualFile << " <exp>0.0</exp>\n";
5654 visualFile << " </widthDir>\n";
5655 visualFile << " <length><exp>1.0</exp></length>\n";
5656 visualFile << " <width><exp>0.0025</exp></width>\n";
5657 visualFile << " <height><exp>0.0025</exp></height>\n";
5658 visualFile << " <extra><exp>0.0</exp></extra>\n";
5659 visualFile << " <color>\n";
5660 visualFile << " <exp>255.0</exp>\n";
5661 visualFile << " <exp>0.0</exp>\n";
5662 visualFile << " <exp>0.0</exp>\n";
5663 visualFile << " </color>\n";
5664 visualFile << " <specCoeff><exp>0.7</exp></specCoeff>\n";
5665 visualFile << " </shape>\n";
5666
5667 visualFile << " <shape>\n";
5668 visualFile << " <ident>y-axis</ident>\n";
5669 visualFile << " <type>cylinder</type>\n";
5670 visualFile << " <T>\n";
5671 visualFile << " <exp>1.0</exp>\n";
5672 visualFile << " <exp>0.0</exp>\n";
5673 visualFile << " <exp>0.0</exp>\n";
5674 visualFile << " <exp>0.0</exp>\n";
5675 visualFile << " <exp>1.0</exp>\n";
5676 visualFile << " <exp>0.0</exp>\n";
5677 visualFile << " <exp>0.0</exp>\n";
5678 visualFile << " <exp>0.0</exp>\n";
5679 visualFile << " <exp>1.0</exp>\n";
5680 visualFile << " </T>\n";
5681 visualFile << " <r>\n";
5682 visualFile << " <exp>0.0</exp>\n";
5683 visualFile << " <exp>0.0</exp>\n";
5684 visualFile << " <exp>0.0</exp>\n";
5685 visualFile << " </r>\n";
5686 visualFile << " <r_shape>\n";
5687 visualFile << " <exp>0.0</exp>\n";
5688 visualFile << " <exp>0.0</exp>\n";
5689 visualFile << " <exp>0.0</exp>\n";
5690 visualFile << " </r_shape>\n";
5691 visualFile << " <lengthDir>\n";
5692 visualFile << " <exp>0.0</exp>\n";
5693 visualFile << " <exp>1.0</exp>\n";
5694 visualFile << " <exp>0.0</exp>\n";
5695 visualFile << " </lengthDir>\n";
5696 visualFile << " <widthDir>\n";
5697 visualFile << " <exp>1.0</exp>\n";
5698 visualFile << " <exp>0.0</exp>\n";
5699 visualFile << " <exp>0.0</exp>\n";
5700 visualFile << " </widthDir>\n";
5701 visualFile << " <length><exp>1.0</exp></length>\n";
5702 visualFile << " <width><exp>0.0025</exp></width>\n";
5703 visualFile << " <height><exp>0.0025</exp></height>\n";
5704 visualFile << " <extra><exp>0.0</exp></extra>\n";
5705 visualFile << " <color>\n";
5706 visualFile << " <exp>0.0</exp>\n";
5707 visualFile << " <exp>255.0</exp>\n";
5708 visualFile << " <exp>0.0</exp>\n";
5709 visualFile << " </color>\n";
5710 visualFile << " <specCoeff><exp>0.7</exp></specCoeff>\n";
5711 visualFile << " </shape>\n";
5712
5713 visualFile << " <shape>\n";
5714 visualFile << " <ident>z-axis</ident>\n";
5715 visualFile << " <type>cylinder</type>\n";
5716 visualFile << " <T>\n";
5717 visualFile << " <exp>1.0</exp>\n";
5718 visualFile << " <exp>0.0</exp>\n";
5719 visualFile << " <exp>0.0</exp>\n";
5720 visualFile << " <exp>0.0</exp>\n";
5721 visualFile << " <exp>1.0</exp>\n";
5722 visualFile << " <exp>0.0</exp>\n";
5723 visualFile << " <exp>0.0</exp>\n";
5724 visualFile << " <exp>0.0</exp>\n";
5725 visualFile << " <exp>1.0</exp>\n";
5726 visualFile << " </T>\n";
5727 visualFile << " <r>\n";
5728 visualFile << " <exp>0.0</exp>\n";
5729 visualFile << " <exp>0.0</exp>\n";
5730 visualFile << " <exp>0.0</exp>\n";
5731 visualFile << " </r>\n";
5732 visualFile << " <r_shape>\n";
5733 visualFile << " <exp>0.0</exp>\n";
5734 visualFile << " <exp>0.0</exp>\n";
5735 visualFile << " <exp>0.0</exp>\n";
5736 visualFile << " </r_shape>\n";
5737 visualFile << " <lengthDir>\n";
5738 visualFile << " <exp>0.0</exp>\n";
5739 visualFile << " <exp>0.0</exp>\n";
5740 visualFile << " <exp>1.0</exp>\n";
5741 visualFile << " </lengthDir>\n";
5742 visualFile << " <widthDir>\n";
5743 visualFile << " <exp>0.0</exp>\n";
5744 visualFile << " <exp>1.0</exp>\n";
5745 visualFile << " <exp>0.0</exp>\n";
5746 visualFile << " </widthDir>\n";
5747 visualFile << " <length><exp>1.0</exp></length>\n";
5748 visualFile << " <width><exp>0.0025</exp></width>\n";
5749 visualFile << " <height><exp>0.0025</exp></height>\n";
5750 visualFile << " <extra><exp>0.0</exp></extra>\n";
5751 visualFile << " <color>\n";
5752 visualFile << " <exp>0.0</exp>\n";
5753 visualFile << " <exp>0.0</exp>\n";
5754 visualFile << " <exp>255.0</exp>\n";
5755 visualFile << " </color>\n";
5756 visualFile << " <specCoeff><exp>0.7</exp></specCoeff>\n";
5757 visualFile << " </shape>\n";
5758
5759 QList<QColor> colorsList;
5760 colorsList.append(QColor(Qt::red));
5761 colorsList.append(QColor(85,170,0)); // green
5762 colorsList.append(QColor(Qt::blue));
5763 colorsList.append(QColor(Qt::lightGray));
5764 colorsList.append(QColor(Qt::magenta));
5765 colorsList.append(QColor(Qt::yellow));
5766 colorsList.append(QColor(Qt::darkRed));
5767 colorsList.append(QColor(Qt::darkBlue));
5768 colorsList.append(QColor(Qt::darkGreen));
5769 colorsList.append(QColor(Qt::darkCyan));
5770 colorsList.append(QColor(Qt::darkMagenta));
5771 colorsList.append(QColor(Qt::darkYellow));
5772 // selected color
5773 QColor selectedColor(255, 192, 203); // pink
5774 int i = 0;
5775
5776 foreach (Component *pSubModelComponent, mpDiagramGraphicsView->getComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(mpDiagramGraphicsView
->getComponentsList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pSubModelComponent = *_container_.i; _container_
.control; _container_.control = 0)
{
5777 // if no geometry file then continue.
5778 if (pSubModelComponent->getComponentInfo()->getGeometryFile().isEmpty()) {
5779 continue;
5780 }
5781 bool visited = false;
5782 foreach (Component *pInterfaceComponent, pSubModelComponent->getComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pSubModelComponent
->getComponentsList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pInterfaceComponent = *_container_.i; _container_
.control; _container_.control = 0)
{
5783 QString name = QString("%1.%2").arg(pSubModelComponent->getName()).arg(pInterfaceComponent->getName());
5784
5785
5786
5787
5788 //Draw interface vectors
5789 bool interfaceSelected=false;
5790 foreach(LineAnnotation* pConnection, pInterfaceComponent->getGraphicsView()->getConnectionsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pInterfaceComponent
->getGraphicsView()->getConnectionsList()); _container_
.control && _container_.i != _container_.e; ++_container_
.i, _container_.control ^= 1) for (LineAnnotation* pConnection
= *_container_.i; _container_.control; _container_.control =
0)
{
5791 if(pConnection->isSelected()) {
5792 if(pConnection->getStartComponent() == pInterfaceComponent ||
5793 pConnection->getEndComponent() == pInterfaceComponent) {
5794 interfaceSelected = true;
5795 }
5796 }
5797 }
5798
5799 //Draw X-axis
5800 visualFile << " <shape>\n";
5801 visualFile << " <ident>" << name << ".x</ident>\n";
5802 visualFile << " <type>cylinder</type>\n";
5803 visualFile << " <T>\n";
5804 visualFile << " <cref>" << name << ".A(1,1) [-]</cref>\n";
5805 visualFile << " <cref>" << name << ".A(1,2) [-]</cref>\n";
5806 visualFile << " <cref>" << name << ".A(1,3) [-]</cref>\n";
5807 visualFile << " <cref>" << name << ".A(2,1) [-]</cref>\n";
5808 visualFile << " <cref>" << name << ".A(2,2) [-]</cref>\n";
5809 visualFile << " <cref>" << name << ".A(2,3) [-]</cref>\n";
5810 visualFile << " <cref>" << name << ".A(3,1) [-]</cref>\n";
5811 visualFile << " <cref>" << name << ".A(3,2) [-]</cref>\n";
5812 visualFile << " <cref>" << name << ".A(3,3) [-]</cref>\n";
5813 visualFile << " </T>\n";
5814 visualFile << " <r>\n";
5815 visualFile << " <cref>" << name << ".R[cG][cG](1) [m]</cref>\n";
5816 visualFile << " <cref>" << name << ".R[cG][cG](2) [m]</cref>\n";
5817 visualFile << " <cref>" << name << ".R[cG][cG](3) [m]</cref>\n";
5818 visualFile << " </r>\n";
5819 visualFile << " <r_shape>\n";
5820 visualFile << " <exp>0</exp>\n";
5821 visualFile << " <exp>0</exp>\n";
5822 visualFile << " <exp>0</exp>\n";
5823 visualFile << " </r_shape>\n";
5824 visualFile << " <lengthDir>\n";
5825 visualFile << " <exp>1</exp>\n";
5826 visualFile << " <exp>0</exp>\n";
5827 visualFile << " <exp>0</exp>\n";
5828 visualFile << " </lengthDir>\n";
5829 visualFile << " <widthDir>\n";
5830 visualFile << " <exp>0</exp>\n";
5831 visualFile << " <exp>1</exp>\n";
5832 visualFile << " <exp>0</exp>\n";
5833 visualFile << " </widthDir>\n";
5834 visualFile << " <length><exp>0.5</exp></length>\n";
5835 visualFile << " <width><exp>0.0025</exp></width>\n";
5836 visualFile << " <height><exp>0.0025</exp></height>\n";
5837 visualFile << " <extra><exp>0.0</exp></extra>\n";
5838 visualFile << " <color>\n";
5839 if(interfaceSelected) {
5840 visualFile << " <exp>" << selectedColor.red() << "</exp>\n";
5841 visualFile << " <exp>" << selectedColor.green() << "</exp>\n";
5842 visualFile << " <exp>" << selectedColor.blue() << "</exp>\n";
5843 } else {
5844 visualFile << " <exp>255</exp>\n";
5845 visualFile << " <exp>0</exp>\n";
5846 visualFile << " <exp>0</exp>\n";
5847 }
5848 visualFile << " </color>\n";
5849 visualFile << " <specCoeff><exp>0.7</exp></specCoeff>\n";
5850 visualFile << " </shape>\n";
5851
5852 //Draw Y-axis
5853 visualFile << " <shape>\n";
5854 visualFile << " <ident>" << name << ".x</ident>\n";
5855 visualFile << " <type>cylinder</type>\n";
5856 visualFile << " <T>\n";
5857 visualFile << " <cref>" << name << ".A(1,1) [-]</cref>\n";
5858 visualFile << " <cref>" << name << ".A(1,2) [-]</cref>\n";
5859 visualFile << " <cref>" << name << ".A(1,3) [-]</cref>\n";
5860 visualFile << " <cref>" << name << ".A(2,1) [-]</cref>\n";
5861 visualFile << " <cref>" << name << ".A(2,2) [-]</cref>\n";
5862 visualFile << " <cref>" << name << ".A(2,3) [-]</cref>\n";
5863 visualFile << " <cref>" << name << ".A(3,1) [-]</cref>\n";
5864 visualFile << " <cref>" << name << ".A(3,2) [-]</cref>\n";
5865 visualFile << " <cref>" << name << ".A(3,3) [-]</cref>\n";
5866 visualFile << " </T>\n";
5867 visualFile << " <r>\n";
5868 visualFile << " <cref>" << name << ".R[cG][cG](1) [m]</cref>\n";
5869 visualFile << " <cref>" << name << ".R[cG][cG](2) [m]</cref>\n";
5870 visualFile << " <cref>" << name << ".R[cG][cG](3) [m]</cref>\n";
5871 visualFile << " </r>\n";
5872 visualFile << " <r_shape>\n";
5873 visualFile << " <exp>0</exp>\n";
5874 visualFile << " <exp>0</exp>\n";
5875 visualFile << " <exp>0</exp>\n";
5876 visualFile << " </r_shape>\n";
5877 visualFile << " <lengthDir>\n";
5878 visualFile << " <exp>0</exp>\n";
5879 visualFile << " <exp>1</exp>\n";
5880 visualFile << " <exp>0</exp>\n";
5881 visualFile << " </lengthDir>\n";
5882 visualFile << " <widthDir>\n";
5883 visualFile << " <exp>0</exp>\n";
5884 visualFile << " <exp>0</exp>\n";
5885 visualFile << " <exp>1</exp>\n";
5886 visualFile << " </widthDir>\n";
5887 visualFile << " <length><exp>0.5</exp></length>\n";
5888 visualFile << " <width><exp>0.0025</exp></width>\n";
5889 visualFile << " <height><exp>0.0025</exp></height>\n";
5890 visualFile << " <extra><exp>0.0</exp></extra>\n";
5891 visualFile << " <color>\n";
5892 if(interfaceSelected) {
5893 visualFile << " <exp>" << selectedColor.red() << "</exp>\n";
5894 visualFile << " <exp>" << selectedColor.green() << "</exp>\n";
5895 visualFile << " <exp>" << selectedColor.blue() << "</exp>\n";
5896 } else {
5897 visualFile << " <exp>0</exp>\n";
5898 visualFile << " <exp>255</exp>\n";
5899 visualFile << " <exp>0</exp>\n";
5900 }
5901 visualFile << " </color>\n";
5902 visualFile << " <specCoeff><exp>0.7</exp></specCoeff>\n";
5903 visualFile << " </shape>\n";
5904
5905 //Draw Z-axis
5906 visualFile << " <shape>\n";
5907 visualFile << " <ident>" << name << ".x</ident>\n";
5908 visualFile << " <type>cylinder</type>\n";
5909 visualFile << " <T>\n";
5910 visualFile << " <cref>" << name << ".A(1,1) [-]</cref>\n";
5911 visualFile << " <cref>" << name << ".A(1,2) [-]</cref>\n";
5912 visualFile << " <cref>" << name << ".A(1,3) [-]</cref>\n";
5913 visualFile << " <cref>" << name << ".A(2,1) [-]</cref>\n";
5914 visualFile << " <cref>" << name << ".A(2,2) [-]</cref>\n";
5915 visualFile << " <cref>" << name << ".A(2,3) [-]</cref>\n";
5916 visualFile << " <cref>" << name << ".A(3,1) [-]</cref>\n";
5917 visualFile << " <cref>" << name << ".A(3,2) [-]</cref>\n";
5918 visualFile << " <cref>" << name << ".A(3,3) [-]</cref>\n";
5919 visualFile << " </T>\n";
5920 visualFile << " <r>\n";
5921 visualFile << " <cref>" << name << ".R[cG][cG](1) [m]</cref>\n";
5922 visualFile << " <cref>" << name << ".R[cG][cG](2) [m]</cref>\n";
5923 visualFile << " <cref>" << name << ".R[cG][cG](3) [m]</cref>\n";
5924 visualFile << " </r>\n";
5925 visualFile << " <r_shape>\n";
5926 visualFile << " <exp>0</exp>\n";
5927 visualFile << " <exp>0</exp>\n";
5928 visualFile << " <exp>0</exp>\n";
5929 visualFile << " </r_shape>\n";
5930 visualFile << " <lengthDir>\n";
5931 visualFile << " <exp>0</exp>\n";
5932 visualFile << " <exp>0</exp>\n";
5933 visualFile << " <exp>1</exp>\n";
5934 visualFile << " </lengthDir>\n";
5935 visualFile << " <widthDir>\n";
5936 visualFile << " <exp>1</exp>\n";
5937 visualFile << " <exp>0</exp>\n";
5938 visualFile << " <exp>0</exp>\n";
5939 visualFile << " </widthDir>\n";
5940 visualFile << " <length><exp>0.5</exp></length>\n";
5941 visualFile << " <width><exp>0.0025</exp></width>\n";
5942 visualFile << " <height><exp>0.0025</exp></height>\n";
5943 visualFile << " <extra><exp>0.0</exp></extra>\n";
5944 visualFile << " <color>\n";
5945 if(interfaceSelected) {
5946 visualFile << " <exp>" << selectedColor.red() << "</exp>\n";
5947 visualFile << " <exp>" << selectedColor.green() << "</exp>\n";
5948 visualFile << " <exp>" << selectedColor.blue() << "</exp>\n";
5949 } else {
5950 visualFile << " <exp>0</exp>\n";
5951 visualFile << " <exp>0</exp>\n";
5952 visualFile << " <exp>255</exp>\n";
5953 }
5954 visualFile << " </color>\n";
5955 visualFile << " <specCoeff><exp>0.7</exp></specCoeff>\n";
5956 visualFile << " </shape>\n";
5957 //End new code
5958
5959 if (visited) {
5960 break;
5961 }
5962 /*!
5963 * \note Don't check for connection.
5964 * If we check for connection then only connected submodels can be seen in the ThreeDViewer Browser.
5965 */
5966 // foreach (LineAnnotation *pConnectionLineAnnotation, mpDiagramGraphicsView->getConnectionsList()) {
5967 // if ((pConnectionLineAnnotation->getStartComponentName().compare(name) == 0) ||
5968 // (pConnectionLineAnnotation->getEndComponentName().compare(name) == 0)) {
5969 // get the angle
5970 double phi[3] = {0.0, 0.0, 0.0};
5971 QStringList angleList = pInterfaceComponent->getComponentInfo()->getAngle321().split(",", QString::SkipEmptyParts);
5972 if (angleList.size() > 2) {
5973 phi[0] = -angleList.at(0).toDouble();
5974 phi[1] = -angleList.at(1).toDouble();
5975 phi[2] = -angleList.at(2).toDouble();
5976 }
5977 QGenericMatrix<3, 3, double> T = Utilities::getRotationMatrix(QGenericMatrix<3, 1, double>(phi));
5978 // get the position
5979 double position[3] = {0.0, 0.0, 0.0};
5980 QStringList positionList = pInterfaceComponent->getComponentInfo()->getPosition().split(",", QString::SkipEmptyParts);
5981 if (positionList.size() > 2) {
5982 position[0] = positionList.at(0).toDouble();
5983 position[1] = positionList.at(1).toDouble();
5984 position[2] = positionList.at(2).toDouble();
5985 }
5986 QGenericMatrix<3, 1, double> r_shape;
5987 r_shape(0, 0) = -position[0];
5988 r_shape(0, 1) = -position[1];
5989 r_shape(0, 2) = -position[2];
5990 r_shape = r_shape*(T);
5991 double lengthDirArr[3] = {1.0, 0.0, 0.0};
5992 QGenericMatrix<3, 1, double> lengthDir(lengthDirArr);
5993 lengthDir = lengthDir*(T);
5994 double widthDirArr[3] = {0.0, 1.0, 0.0};
5995 QGenericMatrix<3, 1, double> widthDir(widthDirArr);
5996 widthDir = widthDir*(T);
5997
5998 visualFile << " <shape>\n";
5999 visualFile << " <ident>" << name << "</ident>\n";
6000 visualFile << " <type>file://" << pSubModelComponent->getComponentInfo()->getGeometryFile() << "</type>\n";
6001 visualFile << " <T>\n";
6002 visualFile << " <cref>" << name << ".A(1,1) [-]</cref>\n";
6003 visualFile << " <cref>" << name << ".A(1,2) [-]</cref>\n";
6004 visualFile << " <cref>" << name << ".A(1,3) [-]</cref>\n";
6005 visualFile << " <cref>" << name << ".A(2,1) [-]</cref>\n";
6006 visualFile << " <cref>" << name << ".A(2,2) [-]</cref>\n";
6007 visualFile << " <cref>" << name << ".A(2,3) [-]</cref>\n";
6008 visualFile << " <cref>" << name << ".A(3,1) [-]</cref>\n";
6009 visualFile << " <cref>" << name << ".A(3,2) [-]</cref>\n";
6010 visualFile << " <cref>" << name << ".A(3,3) [-]</cref>\n";
6011 visualFile << " </T>\n";
6012 visualFile << " <r>\n";
6013 visualFile << " <cref>" << name << ".R[cG][cG](1) [m]</cref>\n";
6014 visualFile << " <cref>" << name << ".R[cG][cG](2) [m]</cref>\n";
6015 visualFile << " <cref>" << name << ".R[cG][cG](3) [m]</cref>\n";
6016 visualFile << " </r>\n";
6017 visualFile << " <r_shape>\n";
6018 visualFile << " <exp>" << r_shape(0, 0) << "</exp>\n";
6019 visualFile << " <exp>" << r_shape(0, 1) << "</exp>\n";
6020 visualFile << " <exp>" << r_shape(0, 2) << "</exp>\n";
6021 visualFile << " </r_shape>\n";
6022 visualFile << " <lengthDir>\n";
6023 visualFile << " <exp>" << lengthDir(0, 0) << "</exp>\n";
6024 visualFile << " <exp>" << lengthDir(0, 1) << "</exp>\n";
6025 visualFile << " <exp>" << lengthDir(0, 2) << "</exp>\n";
6026 visualFile << " </lengthDir>\n";
6027 visualFile << " <widthDir>\n";
6028 visualFile << " <exp>" << widthDir(0, 0) << "</exp>\n";
6029 visualFile << " <exp>" << widthDir(0, 1) << "</exp>\n";
6030 visualFile << " <exp>" << widthDir(0, 2) << "</exp>\n";
6031 visualFile << " </widthDir>\n";
6032 visualFile << " <length><exp>0.0</exp></length>\n";
6033 visualFile << " <width><exp>0.0</exp></width>\n";
6034 visualFile << " <height><exp>0.0</exp></height>\n";
6035 visualFile << " <extra><exp>0.0</exp></extra>\n";
6036 visualFile << " <color>\n";
6037 if (pSubModelComponent->isSelected()) {
6038 visualFile << " <exp>" << selectedColor.red() << "</exp>\n";
6039 visualFile << " <exp>" << selectedColor.green() << "</exp>\n";
6040 visualFile << " <exp>" << selectedColor.blue() << "</exp>\n";
6041 } else {
6042 visualFile << " <exp>" << colorsList.at(i % colorsList.size()).red() << "</exp>\n";
6043 visualFile << " <exp>" << colorsList.at(i % colorsList.size()).green() << "</exp>\n";
6044 visualFile << " <exp>" << colorsList.at(i % colorsList.size()).blue() << "</exp>\n";
6045 }
6046 visualFile << " </color>\n";
6047 visualFile << " <specCoeff><exp>0.7</exp></specCoeff>\n";
6048 visualFile << " </shape>\n";
6049 // set the visited flag to true.
6050 visited = true;
6051 i++;
6052 break;
6053 // }
6054 // }
6055 }
6056 }
6057
6058 visualFile << "</visualization>\n";
6059 file.close();
6060 return true;
6061 } else {
6062 QString msg = GUIMessages::getMessage(GUIMessages::ERROR_OCCURRED).arg(GUIMessages::getMessage(GUIMessages::UNABLE_TO_SAVE_FILE)
6063 .arg(fileName).arg(file.errorString()));
6064 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, msg, Helper::scriptingKind,
6065 Helper::errorLevel));
6066 return false;
6067 }
6068}
6069
6070/*!
6071 * \brief ModelWidget::beginMacro
6072 * Tells the undo stack to consider all coming commands as one.\n
6073 * Also tells the text editor to mark all changes as one.
6074 * \param text
6075 */
6076void ModelWidget::beginMacro(const QString &text)
6077{
6078 mpUndoStack->beginMacro(text);
6079 if (mpEditor) {
6080 QTextCursor textCursor = mpEditor->getPlainTextEdit()->textCursor();
6081 textCursor.beginEditBlock();
6082 }
6083}
6084
6085/*!
6086 * \brief ModelWidget::endMacro
6087 * Tells the undo stack and text editor that the batch editing is finished.
6088 */
6089void ModelWidget::endMacro()
6090{
6091 mpUndoStack->endMacro();
6092 if (mpEditor) {
6093 mpEditor->setForceSetPlainText(true);
6094 QTextCursor textCursor = mpEditor->getPlainTextEdit()->textCursor();
6095 textCursor.endEditBlock();
6096 mpEditor->setForceSetPlainText(false);
6097 }
6098}
6099
6100/*!
6101 * \brief ModelWidget::updateViewButtonsBasedOnAccess
6102 * Update the view buttons i.e., icon, diagram and text based on the Access annotation.
6103 */
6104void ModelWidget::updateViewButtonsBasedOnAccess()
6105{
6106 if (mCreateModelWidgetComponents) {
6107 LibraryTreeItem::Access access = mpLibraryTreeItem->getAccess();
6108 switch (access) {
6109 case LibraryTreeItem::icon:
6110 mpIconViewToolButton->setChecked(true);
6111 mpDiagramViewToolButton->setEnabled(false);
6112 mpTextViewToolButton->setEnabled(false);
6113 mpDocumentationViewToolButton->setEnabled(false);
6114 break;
6115 case LibraryTreeItem::documentation:
6116 mpIconViewToolButton->setChecked(true);
6117 mpDiagramViewToolButton->setEnabled(false);
6118 mpTextViewToolButton->setEnabled(false);
6119 mpDocumentationViewToolButton->setEnabled(true);
6120 break;
6121 case LibraryTreeItem::diagram:
6122 if (mpTextViewToolButton->isChecked()) {
6123 mpDiagramViewToolButton->setChecked(true);
6124 }
6125 mpTextViewToolButton->setEnabled(false);
6126 mpDocumentationViewToolButton->setEnabled(true);
6127 break;
6128 case LibraryTreeItem::nonPackageText:
6129 case LibraryTreeItem::nonPackageDuplicate:
6130 if (mpLibraryTreeItem->getRestriction() == StringHandler::Package) {
6131 if (mpTextViewToolButton->isChecked()) {
6132 mpDiagramViewToolButton->setChecked(true);
6133 }
6134 mpTextViewToolButton->setEnabled(false);
6135 } else {
6136 mpDiagramViewToolButton->setEnabled(true);
6137 mpTextViewToolButton->setEnabled(true);
6138 }
6139 mpDocumentationViewToolButton->setEnabled(true);
6140 break;
6141 default:
6142 mpDiagramViewToolButton->setEnabled(true);
6143 mpTextViewToolButton->setEnabled(true);
6144 mpDocumentationViewToolButton->setEnabled(true);
6145 break;
6146 }
6147 }
6148}
6149
6150/*!
6151 * \brief ModelWidget::associateBusWithConnector
6152 * Associates the bus component with the connector component.
6153 * \param busName
6154 * \param connectorName
6155 */
6156void ModelWidget::associateBusWithConnector(QString busName, QString connectorName)
6157{
6158 associateBusWithConnector(busName, connectorName, mpIconGraphicsView);
6159 associateBusWithConnector(busName, connectorName, mpDiagramGraphicsView);
6160 // get the connector component
6161 Component *pConnectorComponent = mpIconGraphicsView->getComponentObject(connectorName);
6162 if (pConnectorComponent) {
6163 pConnectorComponent->emitDeleted();
6164 }
6165}
6166
6167/*!
6168 * \brief ModelWidget::dissociateBusWithConnector
6169 * Dissociate the bus component with the connector component.
6170 * \param busName
6171 * \param connectorName
6172 */
6173void ModelWidget::dissociateBusWithConnector(QString busName, QString connectorName)
6174{
6175 dissociateBusWithConnector(busName, connectorName, mpIconGraphicsView);
6176 dissociateBusWithConnector(busName, connectorName, mpDiagramGraphicsView);
6177 // get the connector component
6178 Component *pConnectorComponent = mpIconGraphicsView->getComponentObject(connectorName);
6179 if (pConnectorComponent) {
6180 pConnectorComponent->emitAdded();
6181 }
6182}
6183
6184/*!
6185 * \brief ModelWidget::associateBusWithConnectors
6186 * Associates the bus component with each of its connector component.
6187 * \param busName
6188 */
6189void ModelWidget::associateBusWithConnectors(QString busName)
6190{
6191 // get the bus component
6192 Component *pIconBusComponent = mpIconGraphicsView->getComponentObject(busName);
6193 associateBusWithConnectors(pIconBusComponent, mpIconGraphicsView);
6194 Component *pDiagramBusComponent = mpDiagramGraphicsView->getComponentObject(busName);
6195 associateBusWithConnectors(pDiagramBusComponent, mpDiagramGraphicsView);
6196}
6197
6198/*!
6199 * \brief ModelWidget::toOMSensJson
6200 * Creates a list of QVariant containing the model information needed by OMSens.
6201 * Currently only works for REAL types (OMSens currently have similar limitations)
6202 * \return
6203 */
6204QList<QVariant> ModelWidget::toOMSensData()
6205{
6206 QList<QVariant> omSensData;
6207 if (!mpDiagramGraphicsView) {
6208 return omSensData;
6209 }
6210 QStringList inputVariables;
6211 QStringList outputVariables;
6212 QStringList parameters;
6213 QStringList auxVariables;
6214 const QString modelicaBlocksInterfacesRealInput = "Modelica.Blocks.Interfaces.RealInput";
6215 const QString modelicaBlocksInterfacesRealOutput = "Modelica.Blocks.Interfaces.RealOutput";
6216 QList<Component*> pInheritedAndComposedComponents;
6217 QList<Component*> pTopMostComponents = mpDiagramGraphicsView->getComponentsList() + mpDiagramGraphicsView->getInheritedComponentsList();
6218 for (Component *pComponent : pTopMostComponents) {
6219 pInheritedAndComposedComponents = pComponent->getComponentsList() + pComponent->getInheritedComponentsList();
6220 pInheritedAndComposedComponents.append(pComponent);
6221 for (auto component : pInheritedAndComposedComponents) {
6222 ComponentInfo *pComponentInfo = component->getComponentInfo();
6223 auto causality = pComponentInfo->getCausality();
6224 auto variability = pComponentInfo->getVariablity();
6225 const bool classNameIsReal = pComponentInfo->getClassName().compare(QStringLiteral("Real")([]() noexcept -> QString { enum { Size = sizeof(u"" "Real"
)/2 - 1 }; static const QStaticStringData<Size> qstring_literal
= { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "Real"
}; QStringDataPtr holder = { qstring_literal.data_ptr() }; const
QString qstring_literal_temp(holder); return qstring_literal_temp
; }())
) == 0;
6226 if (causality.compare(QStringLiteral("input")([]() noexcept -> QString { enum { Size = sizeof(u"" "input"
)/2 - 1 }; static const QStaticStringData<Size> qstring_literal
= { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "input"
}; QStringDataPtr holder = { qstring_literal.data_ptr() }; const
QString qstring_literal_temp(holder); return qstring_literal_temp
; }())
) == 0) {
6227 if (classNameIsReal || pComponentInfo->getClassName().compare(modelicaBlocksInterfacesRealInput) == 0) {
6228 inputVariables.append(pComponentInfo->getName());
6229 }
6230 } else if (causality.compare(QStringLiteral("output")([]() noexcept -> QString { enum { Size = sizeof(u"" "output"
)/2 - 1 }; static const QStaticStringData<Size> qstring_literal
= { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "output"
}; QStringDataPtr holder = { qstring_literal.data_ptr() }; const
QString qstring_literal_temp(holder); return qstring_literal_temp
; }())
) == 0) {
6231 if (classNameIsReal || pComponentInfo->getClassName().compare(modelicaBlocksInterfacesRealOutput) == 0) {
6232 outputVariables.append(pComponentInfo->getName());
6233 }
6234 } else if(classNameIsReal && variability.compare(QStringLiteral("parameter")([]() noexcept -> QString { enum { Size = sizeof(u"" "parameter"
)/2 - 1 }; static const QStaticStringData<Size> qstring_literal
= { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "parameter"
}; QStringDataPtr holder = { qstring_literal.data_ptr() }; const
QString qstring_literal_temp(holder); return qstring_literal_temp
; }())
) == 0) {
6235 parameters.append(pComponentInfo->getName());
6236 } /* Otherwise we are dealing with an auxiliarly variable */else if (classNameIsReal) {
6237 auxVariables.append(pComponentInfo->getName());
6238 }
6239 }
6240 }
6241 omSensData << inputVariables << outputVariables << auxVariables << parameters << mpLibraryTreeItem->getFileName() << mpLibraryTreeItem->getNameStructure();
6242 return omSensData;
6243}
6244
6245/*!
6246 * \brief ModelWidget::getIconDiagramMap
6247 * Parses the IconMap/DiagramMap annotation and returns the IconDiagramMap object.
6248 * \param mapAnnotation
6249 * \return
6250 */
6251IconDiagramMap ModelWidget::getIconDiagramMap(QString mapAnnotation)
6252{
6253 IconDiagramMap map;
6254 QStringList mapAnnotationValues = StringHandler::getStrings(StringHandler::removeFirstLastCurlBrackets(mapAnnotation));
6255 if (mapAnnotationValues.length() == 6) {
6256 QPointF point1, point2;
6257 point1.setX(mapAnnotationValues.at(1).toFloat());
6258 point1.setY(mapAnnotationValues.at(2).toFloat());
6259 point2.setX(mapAnnotationValues.at(3).toFloat());
6260 point2.setY(mapAnnotationValues.at(4).toFloat());
6261 map.mExtent.clear();
6262 map.mExtent.append(point1);
6263 map.mExtent.append(point2);
6264 map.mPrimitivesVisible = mapAnnotationValues.at(5).compare("true") == 0;
6265 }
6266 return map;
6267}
6268
6269/*!
6270 * \brief ModelWidget::getModelInheritedClasses
6271 * Gets the class inherited classes.
6272 */
6273void ModelWidget::getModelInheritedClasses()
6274{
6275 MainWindow *pMainWindow = MainWindow::instance();
6276 LibraryTreeModel *pLibraryTreeModel = pMainWindow->getLibraryWidget()->getLibraryTreeModel();
6277 // get the inherited classes of the class
6278 QList<QString> inheritedClasses = pMainWindow->getOMCProxy()->getInheritedClasses(mpLibraryTreeItem->getNameStructure());
6279 int index = 1;
6280 foreach (QString inheritedClass, inheritedClasses)for (auto _container_ = QtPrivate::qMakeForeachContainer(inheritedClasses
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString inheritedClass
= *_container_.i; _container_.control; _container_.control =
0)
{
6281 /* If the inherited class is one of the builtin type such as Real we can
6282 * stop here, because the class can not contain any classes, etc.
6283 * Also check for cyclic loops.
6284 */
6285 if (!(pMainWindow->getOMCProxy()->isBuiltinType(inheritedClass) || inheritedClass.compare(mpLibraryTreeItem->getNameStructure()) == 0)) {
6286 LibraryTreeItem *pInheritedLibraryTreeItem = pLibraryTreeModel->findLibraryTreeItem(inheritedClass);
6287 if (!pInheritedLibraryTreeItem) {
6288 pInheritedLibraryTreeItem = pLibraryTreeModel->createNonExistingLibraryTreeItem(inheritedClass);
6289 }
6290 if (!pInheritedLibraryTreeItem->isNonExisting() && !pInheritedLibraryTreeItem->getModelWidget()) {
6291 pLibraryTreeModel->showModelWidget(pInheritedLibraryTreeItem, false);
6292 }
6293 mpLibraryTreeItem->addInheritedClass(pInheritedLibraryTreeItem);
6294 addInheritedClass(pInheritedLibraryTreeItem);
6295 // get the icon and diagram map of inherited class
6296 IconDiagramMap iconMap = getIconDiagramMap(pMainWindow->getOMCProxy()->getNthInheritedClassIconMapAnnotation(mpLibraryTreeItem->getNameStructure(), index));
6297 mInheritedClassesIconMap.insert(index, iconMap);
6298 IconDiagramMap diagramMap = getIconDiagramMap(pMainWindow->getOMCProxy()->getNthInheritedClassDiagramMapAnnotation(mpLibraryTreeItem->getNameStructure(), index));
6299 mInheritedClassesDiagramMap.insert(index, diagramMap);
6300 }
6301 index++;
6302 }
6303}
6304
6305/*!
6306 * \brief ModelWidget::parseModelInheritedClass
6307 * Parses the inherited class shape and draws its items on the appropriate view.
6308 * \param pModelWidget
6309 * \param viewType
6310 */
6311void ModelWidget::drawModelInheritedClassShapes(ModelWidget *pModelWidget, StringHandler::ViewType viewType)
6312{
6313 int index = 1;
6314 foreach (LibraryTreeItem *pLibraryTreeItem, pModelWidget->getInheritedClassesList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pModelWidget
->getInheritedClassesList()); _container_.control &&
_container_.i != _container_.e; ++_container_.i, _container_
.control ^= 1) for (LibraryTreeItem *pLibraryTreeItem = *_container_
.i; _container_.control; _container_.control = 0)
{
6315 if (!pLibraryTreeItem->isNonExisting()) {
6316 if (!pLibraryTreeItem->getModelWidget()) {
6317 MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->showModelWidget(pLibraryTreeItem, false);
6318 }
6319 drawModelInheritedClassShapes(pLibraryTreeItem->getModelWidget(), viewType);
6320 }
6321 GraphicsView *pInheritedGraphicsView, *pGraphicsView;
6322 if (pLibraryTreeItem->isNonExisting()) {
6323 if (viewType == StringHandler::Icon) {
6324 mpIconGraphicsView->addInheritedShapeToList(createNonExistingInheritedShape(mpIconGraphicsView));
6325 } else {
6326 mpDiagramGraphicsView->addInheritedShapeToList(createNonExistingInheritedShape(mpDiagramGraphicsView));
6327 }
6328 } else {
6329 bool primitivesVisible = true;
6330 if (viewType == StringHandler::Icon) {
6331 pInheritedGraphicsView = pLibraryTreeItem->getModelWidget()->getIconGraphicsView();
6332 pGraphicsView = mpIconGraphicsView;
6333 primitivesVisible = pModelWidget->getInheritedClassIconMap().value(index).mPrimitivesVisible;
6334 } else {
6335 pLibraryTreeItem->getModelWidget()->loadDiagramView();
6336 pInheritedGraphicsView = pLibraryTreeItem->getModelWidget()->getDiagramGraphicsView();
6337 pGraphicsView = mpDiagramGraphicsView;
6338 primitivesVisible = pModelWidget->getInheritedClassDiagramMap().value(index).mPrimitivesVisible;
6339 }
6340 // loop through the inherited class shapes
6341 foreach (ShapeAnnotation *pShapeAnnotation, pInheritedGraphicsView->getShapesList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pInheritedGraphicsView
->getShapesList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (ShapeAnnotation *pShapeAnnotation = *_container_.i; _container_
.control; _container_.control = 0)
{
6342 if (primitivesVisible) {
6343 pGraphicsView->addInheritedShapeToList(createInheritedShape(pShapeAnnotation, pGraphicsView));
6344 }
6345 }
6346 }
6347 index++;
6348 }
6349}
6350
6351/*!
6352 * \brief ModelWidget::getModelIconDiagramShapes
6353 * Gets the Modelica model icon & diagram shapes.
6354 * Parses the Modelica icon/diagram annotation and creates shapes for it on appropriate GraphicsView.
6355 * \param viewType
6356 */
6357void ModelWidget::getModelIconDiagramShapes(StringHandler::ViewType viewType)
6358{
6359 OMCProxy *pOMCProxy = MainWindow::instance()->getOMCProxy();
6360 GraphicsView *pGraphicsView = 0;
6361 QString annotationString;
6362 if (viewType == StringHandler::Icon) {
6363 pGraphicsView = mpIconGraphicsView;
6364 if (mpLibraryTreeItem->getAccess() >= LibraryTreeItem::icon) {
6365 annotationString = pOMCProxy->getIconAnnotation(mpLibraryTreeItem->getNameStructure());
6366 }
6367 } else {
6368 pGraphicsView = mpDiagramGraphicsView;
6369 if (mpLibraryTreeItem->getAccess() >= LibraryTreeItem::diagram) {
6370 annotationString = pOMCProxy->getDiagramAnnotation(mpLibraryTreeItem->getNameStructure());
6371 }
6372 }
6373 annotationString = StringHandler::removeFirstLastCurlBrackets(annotationString);
6374 QStringList list = StringHandler::getStrings(annotationString);
6375
6376 /* From Modelica Specification Version 3.5-dev
6377 * The coordinate system (including preserveAspectRatio) of a class is defined by the following priority:
6378 * 1. The coordinate system annotation given in the class (if specified).
6379 * 2. The coordinate systems of the first base-class where the extent on the extends-clause specifies a
6380 * null-region (if any). Note that null-region is the default for base-classes, see section 18.6.3.
6381 * 3. The default coordinate system CoordinateSystem(extent={{-100, -100}, {100, 100}}).
6382 *
6383 * Following is the first case.
6384 */
6385 if (list.size() >= 8) {
6386 CoOrdinateSystem coOrdinateSystem = pGraphicsView->getCoOrdinateSystem();
6387 coOrdinateSystem.setLeft(list.at(0));
6388 coOrdinateSystem.setBottom(list.at(1));
6389 coOrdinateSystem.setRight(list.at(2));
6390 coOrdinateSystem.setTop(list.at(3));
6391 coOrdinateSystem.setPreserveAspectRatio(list.at(4));
6392 coOrdinateSystem.setInitialScale(list.at(5));
6393 coOrdinateSystem.setHorizontal(list.at(6));
6394 coOrdinateSystem.setVertical(list.at(7));
6395 pGraphicsView->setCoOrdinateSystem(coOrdinateSystem);
6396 }
6397 // draw the CoOrdinateSystem
6398 drawModelCoOrdinateSystem(pGraphicsView);
6399 // read the shapes
6400 if (list.size() < 9)
6401 return;
6402 QStringList shapesList = StringHandler::getStrings(StringHandler::removeFirstLastCurlBrackets(list.at(8)), '(', ')');
6403 drawModelIconDiagramShapes(shapesList, pGraphicsView, false);
6404}
6405
6406void ModelWidget::drawModelCoOrdinateSystem(GraphicsView *pGraphicsView)
6407{
6408 // start with the local CoOrdinateSystem
6409 pGraphicsView->mMergedCoOrdinateSystem = pGraphicsView->getCoOrdinateSystem();
6410 // if local CoOrdinateSystem is not complete then try to complete the merged CoOrdinateSystem.
6411 if (!pGraphicsView->getCoOrdinateSystem().isComplete()) {
6412 readCoOrdinateSystemFromInheritedClass(this, pGraphicsView);
6413 }
6414
6415 pGraphicsView->setExtentRectangle(pGraphicsView->mMergedCoOrdinateSystem.getExtentRectangle());
6416 pGraphicsView->resize(pGraphicsView->size());
6417}
6418
6419void ModelWidget::readCoOrdinateSystemFromInheritedClass(ModelWidget *pModelWidget, GraphicsView *pGraphicsView)
6420{
6421 /* From Modelica Specification Version 3.5-dev
6422 * The coordinate system (including preserveAspectRatio) of a class is defined by the following priority:
6423 * 1. The coordinate system annotation given in the class (if specified).
6424 * 2. The coordinate systems of the first base-class where the extent on the extends-clause specifies a
6425 * null-region (if any). Note that null-region is the default for base-classes, see section 18.6.3.
6426 * 3. The default coordinate system CoordinateSystem(extent={{-100, -100}, {100, 100}}).
6427 *
6428 * Following is the second case.
6429 */
6430 foreach (LibraryTreeItem *pLibraryTreeItem, pModelWidget->getInheritedClassesList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pModelWidget
->getInheritedClassesList()); _container_.control &&
_container_.i != _container_.e; ++_container_.i, _container_
.control ^= 1) for (LibraryTreeItem *pLibraryTreeItem = *_container_
.i; _container_.control; _container_.control = 0)
{
6431 if (!pLibraryTreeItem->isNonExisting()) {
6432 GraphicsView *pInheritedGraphicsView;
6433 if (pGraphicsView->getViewType() == StringHandler::Icon) {
6434 pInheritedGraphicsView = pLibraryTreeItem->getModelWidget()->getIconGraphicsView();
6435 } else {
6436 pInheritedGraphicsView = pLibraryTreeItem->getModelWidget()->getDiagramGraphicsView();
6437 }
6438
6439 if (!pGraphicsView->mMergedCoOrdinateSystem.hasLeft() && pInheritedGraphicsView->mMergedCoOrdinateSystem.hasLeft()) {
6440 pGraphicsView->mMergedCoOrdinateSystem.setLeft(pInheritedGraphicsView->mMergedCoOrdinateSystem.getLeft());
6441 }
6442 if (!pGraphicsView->mMergedCoOrdinateSystem.hasBottom() && pInheritedGraphicsView->mMergedCoOrdinateSystem.hasBottom()) {
6443 pGraphicsView->mMergedCoOrdinateSystem.setBottom(pInheritedGraphicsView->mMergedCoOrdinateSystem.getBottom());
6444 }
6445 if (!pGraphicsView->mMergedCoOrdinateSystem.hasRight() && pInheritedGraphicsView->mMergedCoOrdinateSystem.hasRight()) {
6446 pGraphicsView->mMergedCoOrdinateSystem.setRight(pInheritedGraphicsView->mMergedCoOrdinateSystem.getRight());
6447 }
6448 if (!pGraphicsView->mMergedCoOrdinateSystem.hasTop() && pInheritedGraphicsView->mMergedCoOrdinateSystem.hasTop()) {
6449 pGraphicsView->mMergedCoOrdinateSystem.setTop(pInheritedGraphicsView->mMergedCoOrdinateSystem.getTop());
6450 }
6451 if (!pGraphicsView->mMergedCoOrdinateSystem.hasPreserveAspectRatio() && pInheritedGraphicsView->mMergedCoOrdinateSystem.hasPreserveAspectRatio()) {
6452 pGraphicsView->mMergedCoOrdinateSystem.setPreserveAspectRatio(pInheritedGraphicsView->mMergedCoOrdinateSystem.getPreserveAspectRatio());
6453 }
6454 if (!pGraphicsView->mMergedCoOrdinateSystem.hasInitialScale() && pInheritedGraphicsView->mMergedCoOrdinateSystem.hasInitialScale()) {
6455 pGraphicsView->mMergedCoOrdinateSystem.setInitialScale(pInheritedGraphicsView->mMergedCoOrdinateSystem.getInitialScale());
6456 }
6457 if (!pGraphicsView->mMergedCoOrdinateSystem.hasHorizontal() && pInheritedGraphicsView->mMergedCoOrdinateSystem.hasHorizontal()) {
6458 pGraphicsView->mMergedCoOrdinateSystem.setHorizontal(pInheritedGraphicsView->mMergedCoOrdinateSystem.getHorizontal());
6459 }
6460 if (!pGraphicsView->mMergedCoOrdinateSystem.hasVertical() && pInheritedGraphicsView->mMergedCoOrdinateSystem.hasVertical()) {
6461 pGraphicsView->mMergedCoOrdinateSystem.setVertical(pInheritedGraphicsView->mMergedCoOrdinateSystem.getVertical());
6462 }
6463 }
6464 break; // we only check the coordinate system of the first inherited class. See the comment in the start of the function i.e., "The coordinate systems of the first base-class ..."
6465 }
6466}
6467
6468/*!
6469 * \brief ModelWidget::drawModelInheritedClassComponents
6470 * Loops through the class inhertited classes and draws the components for all.
6471 * \param pModelWidget
6472 * \param viewType
6473 */
6474void ModelWidget::drawModelInheritedClassComponents(ModelWidget *pModelWidget, StringHandler::ViewType viewType)
6475{
6476 foreach (LibraryTreeItem *pLibraryTreeItem, pModelWidget->getInheritedClassesList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pModelWidget
->getInheritedClassesList()); _container_.control &&
_container_.i != _container_.e; ++_container_.i, _container_
.control ^= 1) for (LibraryTreeItem *pLibraryTreeItem = *_container_
.i; _container_.control; _container_.control = 0)
{
6477 if (!pLibraryTreeItem->isNonExisting()) {
6478 drawModelInheritedClassComponents(pLibraryTreeItem->getModelWidget(), viewType);
6479 GraphicsView *pInheritedGraphicsView, *pGraphicsView;
6480 if (viewType == StringHandler::Icon) {
6481 pLibraryTreeItem->getModelWidget()->loadComponents();
6482 pInheritedGraphicsView = pLibraryTreeItem->getModelWidget()->getIconGraphicsView();
6483 pGraphicsView = mpIconGraphicsView;
6484 } else {
6485 pLibraryTreeItem->getModelWidget()->loadDiagramView();
6486 pInheritedGraphicsView = pLibraryTreeItem->getModelWidget()->getDiagramGraphicsView();
6487 pGraphicsView = mpDiagramGraphicsView;
6488 }
6489 foreach (Component *pInheritedComponent, pInheritedGraphicsView->getComponentsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pInheritedGraphicsView
->getComponentsList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (Component *pInheritedComponent = *_container_.i; _container_
.control; _container_.control = 0)
{
6490 pGraphicsView->addInheritedComponentToList(createInheritedComponent(pInheritedComponent, pGraphicsView));
6491 }
6492 }
6493 }
6494}
6495
6496/*!
6497 * \brief ModelWidget::getModelComponents
6498 * Gets the components of the model and their annotations.
6499 */
6500void ModelWidget::getModelComponents()
6501{
6502 MainWindow *pMainWindow = MainWindow::instance();
6503 // get the components
6504 mComponentsList = pMainWindow->getOMCProxy()->getComponents(mpLibraryTreeItem->getNameStructure());
6505 // get the components annotations
6506 if (!mComponentsList.isEmpty()) {
6507 mComponentsAnnotationsList = pMainWindow->getOMCProxy()->getComponentAnnotations(mpLibraryTreeItem->getNameStructure());
6508 }
6509}
6510
6511/*!
6512 * \brief ModelWidget::drawModelIconComponents
6513 * Draw the components for icon view and place them in the icon GraphicsView.
6514 */
6515void ModelWidget::drawModelIconComponents()
6516{
6517 MainWindow *pMainWindow = MainWindow::instance();
6518 int i = 0;
6519 foreach (ComponentInfo *pComponentInfo, mComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (ComponentInfo
*pComponentInfo = *_container_.i; _container_.control; _container_
.control = 0)
{
6520 // if the component type is one of the builtin type then don't try to load it here. we load it when loading diagram view.
6521 if (pMainWindow->getOMCProxy()->isBuiltinType(pComponentInfo->getClassName())) {
6522 i++;
6523 continue;
6524 }
6525 LibraryTreeItem *pLibraryTreeItem = 0;
6526 LibraryTreeModel *pLibraryTreeModel = pMainWindow->getLibraryWidget()->getLibraryTreeModel();
6527 pLibraryTreeItem = pLibraryTreeModel->findLibraryTreeItem(pComponentInfo->getClassName());
6528 if (!pLibraryTreeItem) {
6529 pLibraryTreeItem = pLibraryTreeModel->createNonExistingLibraryTreeItem(pComponentInfo->getClassName());
6530 }
6531 // we only load and draw connectors here. Other components are drawn when loading diagram view.
6532 if (pLibraryTreeItem->isConnector()) {
6533 if (!pLibraryTreeItem->isNonExisting() && !pLibraryTreeItem->getModelWidget()) {
6534 pLibraryTreeModel->showModelWidget(pLibraryTreeItem, false);
6535 }
6536 QString annotation = mComponentsAnnotationsList.size() > i ? mComponentsAnnotationsList.at(i) : "";
6537 if (StringHandler::getPlacementAnnotation(annotation).isEmpty()) {
6538 annotation = StringHandler::removeFirstLastCurlBrackets(annotation);
6539 annotation = QString("{%1, Placement(false,0.0,0.0,-10.0,-10.0,10.0,10.0,0.0,-,-,-,-,-,-,)}").arg(annotation);
6540 }
6541 mpIconGraphicsView->addComponentToView(pComponentInfo->getName(), pLibraryTreeItem, annotation, QPointF(0, 0), pComponentInfo, false, true, false);
6542 }
6543 i++;
6544 }
6545}
6546
6547/*!
6548 * \brief ModelWidget::drawModelDiagramComponents
6549 * Draw the components for diagram view and place them in the diagram GraphicsView.
6550 */
6551void ModelWidget::drawModelDiagramComponents()
6552{
6553 MainWindow *pMainWindow = MainWindow::instance();
6554 int i = 0;
6555 foreach (ComponentInfo *pComponentInfo, mComponentsList)for (auto _container_ = QtPrivate::qMakeForeachContainer(mComponentsList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (ComponentInfo
*pComponentInfo = *_container_.i; _container_.control; _container_
.control = 0)
{
6556 LibraryTreeItem *pLibraryTreeItem = 0;
6557 // if the component type is one of the builtin type then don't try to load it.
6558 if (!pMainWindow->getOMCProxy()->isBuiltinType(pComponentInfo->getClassName())) {
6559 LibraryTreeModel *pLibraryTreeModel = pMainWindow->getLibraryWidget()->getLibraryTreeModel();
6560 pLibraryTreeItem = pLibraryTreeModel->findLibraryTreeItem(pComponentInfo->getClassName());
6561 if (!pLibraryTreeItem) {
6562 pLibraryTreeItem = pLibraryTreeModel->createNonExistingLibraryTreeItem(pComponentInfo->getClassName());
6563 }
6564 // we only load and draw non-connectors here. Connector components are drawn in drawModelIconComponents().
6565 if (pLibraryTreeItem->isConnector()) {
6566 i++;
6567 continue;
6568 }
6569 if (!pLibraryTreeItem->isNonExisting() && !pLibraryTreeItem->getModelWidget()) {
6570 pLibraryTreeModel->showModelWidget(pLibraryTreeItem, false);
6571 }
6572 }
6573 QString annotation = mComponentsAnnotationsList.size() > i ? mComponentsAnnotationsList.at(i) : "";
6574 if (StringHandler::getPlacementAnnotation(annotation).isEmpty()) {
6575 annotation = StringHandler::removeFirstLastCurlBrackets(annotation);
6576 annotation = QString("{%1, Placement(false,0.0,0.0,-10.0,-10.0,10.0,10.0,0.0,-,-,-,-,-,-,)}").arg(annotation);
6577 }
6578 mpDiagramGraphicsView->addComponentToView(pComponentInfo->getName(), pLibraryTreeItem, annotation, QPointF(0, 0), pComponentInfo, false, true, false);
6579 i++;
6580 }
6581}
6582
6583/*!
6584 * \brief ModelWidget::drawModelInheritedClassConnections
6585 * Loops through the class inhertited classes and draws the connections for all.
6586 * \param pModelWidget
6587 */
6588void ModelWidget::drawModelInheritedClassConnections(ModelWidget *pModelWidget)
6589{
6590 foreach (LibraryTreeItem *pLibraryTreeItem, pModelWidget->getInheritedClassesList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pModelWidget
->getInheritedClassesList()); _container_.control &&
_container_.i != _container_.e; ++_container_.i, _container_
.control ^= 1) for (LibraryTreeItem *pLibraryTreeItem = *_container_
.i; _container_.control; _container_.control = 0)
{
6591 if (!pLibraryTreeItem->isNonExisting()) {
6592 drawModelInheritedClassConnections(pLibraryTreeItem->getModelWidget());
6593 pLibraryTreeItem->getModelWidget()->loadConnections();
6594 foreach (LineAnnotation *pConnectionLineAnnotation, pLibraryTreeItem->getModelWidget()->getDiagramGraphicsView()->getConnectionsList())for (auto _container_ = QtPrivate::qMakeForeachContainer(pLibraryTreeItem
->getModelWidget()->getDiagramGraphicsView()->getConnectionsList
()); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (LineAnnotation
*pConnectionLineAnnotation = *_container_.i; _container_.control
; _container_.control = 0)
{
6595 mpDiagramGraphicsView->addInheritedConnectionToList(createInheritedConnection(pConnectionLineAnnotation));
6596 }
6597 }
6598 }
6599}
6600
6601/*!
6602 * \brief ModelWidget::getModelTransitions
6603 * Gets the transitions of the model and place them in the diagram GraphicsView.
6604 */
6605void ModelWidget::getModelTransitions()
6606{
6607 QList<QList<QString>> transitions = MainWindow::instance()->getOMCProxy()->getTransitions(mpLibraryTreeItem->getNameStructure());
6608 for (int i = 0 ; i < transitions.size() ; i++) {
6609 QStringList transition = transitions.at(i);
6610 // get start component
6611 Component *pStartComponent = mpDiagramGraphicsView->getComponentObject(transition.at(0));
6612 // show error message if start component is not found.
6613 if (!pStartComponent) {
6614 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica,
6615 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_TRANSITION)
6616 .arg(transition.at(0)).arg(transition.join(",")),
6617 Helper::scriptingKind, Helper::errorLevel));
6618 continue;
6619 }
6620 // get end component
6621 Component *pEndComponent = mpDiagramGraphicsView->getComponentObject(transition.at(1));
6622 // show error message if end component is not found.
6623 if (!pEndComponent) {
6624 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica,
6625 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_TRANSITION)
6626 .arg(transition.at(1)).arg(transition.join(",")),
6627 Helper::scriptingKind, Helper::errorLevel));
6628 continue;
6629 }
6630 // get the transition annotations
6631 QStringList shapesList = StringHandler::getStrings(transition.at(7), '(', ')');
6632 // Now parse the shapes available in list
6633 QString lineShape, textShape = "";
6634 foreach (QString shape, shapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(shapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString shape
= *_container_.i; _container_.control; _container_.control =
0)
{
6635 if (shape.startsWith("Line")) {
6636 lineShape = shape.mid(QString("Line").length());
6637 lineShape = StringHandler::removeFirstLastParentheses(lineShape);
6638 } else if (shape.startsWith("Text")) {
6639 textShape = shape.mid(QString("Text").length());
6640 textShape = StringHandler::removeFirstLastParentheses(textShape);
6641 }
6642 }
6643 LineAnnotation *pTransitionLineAnnotation;
6644 pTransitionLineAnnotation = new LineAnnotation(lineShape, textShape, pStartComponent, pEndComponent, transition.at(2), transition.at(3),
6645 transition.at(4), transition.at(5), transition.at(6), mpDiagramGraphicsView);
6646 pTransitionLineAnnotation->setStartComponentName(transition.at(0));
6647 pTransitionLineAnnotation->setEndComponentName(transition.at(1));
6648 mpUndoStack->push(new AddTransitionCommand(pTransitionLineAnnotation, false));
6649 }
6650}
6651
6652/*!
6653 * \brief ModelWidget::getModelInitialStates
6654 * Gets the initial states of the model and place them in the diagram GraphicsView.
6655 */
6656void ModelWidget::getModelInitialStates()
6657{
6658 QList<QList<QString>> initialStates = MainWindow::instance()->getOMCProxy()->getInitialStates(mpLibraryTreeItem->getNameStructure());
6659 for (int i = 0 ; i < initialStates.size() ; i++) {
6660 QStringList initialState = initialStates.at(i);
6661 // get initial state component
6662 Component *pInitialStateComponent = mpDiagramGraphicsView->getComponentObject(initialState.at(0));
6663 // show error message if initial state component is not found.
6664 if (!pInitialStateComponent) {
6665 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica,
6666 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_INITIALSTATE)
6667 .arg(initialState.at(0)).arg(initialState.join(",")),
6668 Helper::scriptingKind, Helper::errorLevel));
6669 continue;
6670 }
6671 // get the transition annotations
6672 QStringList shapesList = StringHandler::getStrings(initialState.at(1), '(', ')');
6673 // Now parse the shapes available in list
6674 QString lineShape = "";
6675 foreach (QString shape, shapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(shapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString shape
= *_container_.i; _container_.control; _container_.control =
0)
{
6676 if (shape.startsWith("Line")) {
6677 lineShape = shape.mid(QString("Line").length());
6678 lineShape = StringHandler::removeFirstLastParentheses(lineShape);
6679 }
6680 }
6681 LineAnnotation *pInitialStateLineAnnotation;
6682 pInitialStateLineAnnotation = new LineAnnotation(lineShape, pInitialStateComponent, mpDiagramGraphicsView);
6683 pInitialStateLineAnnotation->setStartComponentName(initialState.at(0));
6684 pInitialStateLineAnnotation->setEndComponentName("");
6685 mpUndoStack->push(new AddInitialStateCommand(pInitialStateLineAnnotation, false));
6686 }
6687}
6688
6689/*!
6690 * \brief ModelWidget::getMetaModelSubModels
6691 * \brief ModelWidget::detectMultipleDeclarations
6692 * detect multiple declarations of a component instance
6693 */
6694void ModelWidget::detectMultipleDeclarations()
6695{
6696 for (int i = 0 ; i < mComponentsList.size() ; i++) {
6697 for (int j = 0 ; j < mComponentsList.size() ; j++) {
6698 if (i == j) {
6699 j++;
6700 continue;
6701 }
6702 if (mComponentsList[i]->getName().compare(mComponentsList[j]->getName()) == 0) {
6703 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica,
6704 GUIMessages::getMessage(GUIMessages::MULTIPLE_DECLARATIONS_COMPONENT)
6705 .arg(mComponentsList[i]->getName()),
6706 Helper::scriptingKind, Helper::errorLevel));
6707 return;
6708 }
6709 }
6710 }
6711}
6712
6713/*!
6714 * \brief ModelWidget::getCompositeModelName
6715 * Gets the CompositeModel name.
6716 * \return
6717 */
6718QString ModelWidget::getCompositeModelName()
6719{
6720 CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpEditor);
6721 return pCompositeModelEditor->getCompositeModelName();
6722}
6723
6724/*!
6725 * \brief ModelWidget::getCompositeModelSubModels
6726 * Gets the submodels of the TLM and place them in the diagram GraphicsView.
6727 */
6728void ModelWidget::getCompositeModelSubModels()
6729{
6730 QFileInfo fileInfo(mpLibraryTreeItem->getFileName());
6731 CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpEditor);
6732 if (pCompositeModelEditor) {
6733 QDomNodeList subModels = pCompositeModelEditor->getSubModels();
6734 for (int i = 0; i < subModels.size(); i++) {
6735 QString transformation;
6736 QDomElement subModel = subModels.at(i).toElement();
6737 QDomNodeList subModelChildren = subModel.childNodes();
6738 for (int j = 0 ; j < subModelChildren.size() ; j++) {
6739 QDomElement annotationElement = subModelChildren.at(j).toElement();
6740 if (annotationElement.tagName().compare("Annotation") == 0) {
6741 transformation = "Placement(";
6742 transformation.append(annotationElement.attribute("Visible")).append(",");
6743 transformation.append(StringHandler::removeFirstLastCurlBrackets(annotationElement.attribute("Origin"))).append(",");
6744 transformation.append(StringHandler::removeFirstLastCurlBrackets(annotationElement.attribute("Extent"))).append(",");
6745 transformation.append(StringHandler::removeFirstLastCurlBrackets(annotationElement.attribute("Rotation"))).append(",");
6746 transformation.append("-,-,-,-,-,-,");
6747 }
6748 }
6749 // add the component to the the diagram view.
6750 LibraryTreeModel *pLibraryTreeModel = MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel();
6751 LibraryTreeItem *pLibraryTreeItem = pLibraryTreeModel->findLibraryTreeItem(subModel.attribute("Name"));
6752 // get the attibutes of the submodel
6753 ComponentInfo *pComponentInfo = new ComponentInfo;
6754 pComponentInfo->setName(subModel.attribute("Name"));
6755 pComponentInfo->setStartCommand(subModel.attribute("StartCommand"));
6756 bool exactStep;
6757 if ((subModel.attribute("ExactStep").toLower().compare("1") == 0)
6758 || (subModel.attribute("ExactStep").toLower().compare("true") == 0)) {
6759 exactStep = true;
6760 } else {
6761 exactStep = false;
6762 }
6763 pComponentInfo->setExactStep(exactStep);
6764 pComponentInfo->setModelFile(subModel.attribute("ModelFile"));
6765 QString absoluteModelFilePath = QString("%1/%2/%3").arg(fileInfo.absolutePath()).arg(subModel.attribute("Name"))
6766 .arg(subModel.attribute("ModelFile"));
6767 // if ModelFile doesn't exist
6768 if (!QFile::exists(absoluteModelFilePath)) {
6769 QString msg = tr("Unable to find ModelFile <b>%1</b> for SubModel <b>%2</b>. The file location should be <b>%3</b>.")
6770 .arg(subModel.attribute("ModelFile")).arg(subModel.attribute("Name")).arg(absoluteModelFilePath);
6771 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, msg, Helper::scriptingKind,
6772 Helper::errorLevel));
6773 }
6774 // Geometry File
6775 if (!subModel.attribute("GeometryFile").isEmpty()) {
6776 QString absoluteGeometryFilePath = QString("%1/%2/%3").arg(fileInfo.absolutePath()).arg(subModel.attribute("Name"))
6777 .arg(subModel.attribute("GeometryFile"));
6778 pComponentInfo->setGeometryFile(absoluteGeometryFilePath);
6779 // if GeometryFile doesn't exist
6780 if (!QFile::exists(absoluteGeometryFilePath)) {
6781 QString msg = tr("Unable to find GeometryFile <b>%1</b> for SubModel <b>%2</b>. The file location should be <b>%3</b>.")
6782 .arg(subModel.attribute("GeometryFile")).arg(subModel.attribute("Name")).arg(absoluteGeometryFilePath);
6783 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, msg, Helper::scriptingKind,
6784 Helper::errorLevel));
6785 }
6786 }
6787 pComponentInfo->setPosition(subModel.attribute("Position"));
6788 pComponentInfo->setAngle321(subModel.attribute("Angle321"));
6789 // add submodel as component to view.
6790 mpDiagramGraphicsView->addComponentToView(subModel.attribute("Name"), pLibraryTreeItem, transformation, QPointF(0.0, 0.0), pComponentInfo, false, true, false);
6791 }
6792 }
6793}
6794
6795/*!
6796 * \brief ModelWidget::getCompositeModelConnections
6797 * Reads the TLM connections and draws them.
6798 */
6799void ModelWidget::getCompositeModelConnections()
6800{
6801 MessagesWidget *pMessagesWidget = MessagesWidget::instance();
6802 CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpEditor);
6803 QDomNodeList connections = pCompositeModelEditor->getConnections();
6804 for (int i = 0; i < connections.size(); i++) {
6805 QDomElement connection = connections.at(i).toElement();
6806 // get start submodel
6807 QStringList startConnectionList = connection.attribute("From").split(".");
6808 if (startConnectionList.size() < 2) {
6809 continue;
6810 }
6811 Component *pStartSubModelComponent = mpDiagramGraphicsView->getComponentObject(startConnectionList.at(0));
6812 if (!pStartSubModelComponent) {
6813 pMessagesWidget->addGUIMessage(MessageItem(MessageItem::Modelica,
6814 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_CONNECTION).arg(startConnectionList.at(0))
6815 .arg(connection.attribute("From")), Helper::scriptingKind, Helper::errorLevel));
6816 continue;
6817 }
6818 // get start interface point
6819 Component *pStartInterfacePointComponent = getConnectorComponent(pStartSubModelComponent, startConnectionList.at(1));
6820 if (!pStartInterfacePointComponent) {
6821 pMessagesWidget->addGUIMessage(MessageItem(MessageItem::Modelica,
6822 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_CONNECTION).arg(startConnectionList.at(1))
6823 .arg(connection.attribute("From")), Helper::scriptingKind, Helper::errorLevel));
6824 continue;
6825 }
6826 // get end submodel
6827 QStringList endConnectionList = connection.attribute("To").split(".");
6828 if (endConnectionList.size() < 2) {
6829 continue;
6830 }
6831 Component *pEndSubModelComponent = mpDiagramGraphicsView->getComponentObject(endConnectionList.at(0));
6832 if (!pEndSubModelComponent) {
6833 pMessagesWidget->addGUIMessage(MessageItem(MessageItem::Modelica,
6834 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_CONNECTION).arg(endConnectionList.at(0))
6835 .arg(connection.attribute("To")), Helper::scriptingKind, Helper::errorLevel));
6836 continue;
6837 }
6838 // get end interface point
6839 Component *pEndInterfacePointComponent = getConnectorComponent(pEndSubModelComponent, endConnectionList.at(1));
6840 if (!pEndInterfacePointComponent) {
6841 pMessagesWidget->addGUIMessage(MessageItem(MessageItem::Modelica,
6842 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_CONNECTION).arg(endConnectionList.at(1))
6843 .arg(connection.attribute("To")), Helper::scriptingKind, Helper::errorLevel));
6844 continue;
6845 }
6846 // default connection annotation
6847 QString annotation = QString("{Line(true,{0.0,0.0},0,%1,{0,0,0},LinePattern.Solid,0.25,{Arrow.None,Arrow.None},3,Smooth.None)}");
6848 QStringList shapesList;
6849 bool annotationFound = false;
6850 // check if connection has annotaitons defined
6851 QDomNodeList connectionChildren = connection.childNodes();
6852 for (int j = 0 ; j < connectionChildren.size() ; j++) {
6853 QDomElement annotationElement = connectionChildren.at(j).toElement();
6854 if (annotationElement.tagName().compare("Annotation") == 0) {
6855 annotationFound = true;
6856 shapesList = StringHandler::getStrings(StringHandler::removeFirstLastCurlBrackets(QString(annotation).arg(annotationElement.attribute("Points"))), '(', ')');
6857 }
6858 }
6859 if (!annotationFound) {
6860 QString point = QString("{%1,%2}");
6861 QStringList points;
6862 QPointF startPoint = pStartInterfacePointComponent->mapToScene(pStartInterfacePointComponent->boundingRect().center());
6863 points.append(point.arg(startPoint.x()).arg(startPoint.y()));
6864 QPointF endPoint = pEndInterfacePointComponent->mapToScene(pEndInterfacePointComponent->boundingRect().center());
6865 points.append(point.arg(endPoint.x()).arg(endPoint.y()));
6866 QString pointsString = QString("{%1}").arg(points.join(","));
6867 shapesList = StringHandler::getStrings(StringHandler::removeFirstLastCurlBrackets(QString(annotation).arg(pointsString)), '(', ')');
6868 }
6869 // Now parse the shapes available in list
6870 QString lineShape = "";
6871 foreach (QString shape, shapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(shapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString shape
= *_container_.i; _container_.control; _container_.control =
0)
{
6872 if (shape.startsWith("Line")) {
6873 lineShape = shape.mid(QString("Line").length());
6874 lineShape = StringHandler::removeFirstLastParentheses(lineShape);
6875 break; // break the loop once we have got the line annotation.
6876 }
6877 }
6878 LineAnnotation *pConnectionLineAnnotation = new LineAnnotation(lineShape, pStartInterfacePointComponent, pEndInterfacePointComponent,
6879 mpDiagramGraphicsView);
6880 pConnectionLineAnnotation->setStartComponentName(connection.attribute("From"));
6881 pConnectionLineAnnotation->setEndComponentName(connection.attribute("To"));
6882 pConnectionLineAnnotation->setDelay(connection.attribute("Delay"));
6883 pConnectionLineAnnotation->setZf(connection.attribute("Zf"));
6884 pConnectionLineAnnotation->setZfr(connection.attribute("Zfr"));
6885 pConnectionLineAnnotation->setAlpha(connection.attribute("alpha"));
6886 // check if interfaces are aligned
6887 bool aligned = pCompositeModelEditor->interfacesAligned(pConnectionLineAnnotation->getStartComponentName(),
6888 pConnectionLineAnnotation->getEndComponentName());
6889 pConnectionLineAnnotation->setAligned(aligned);
6890
6891 CompositeModelEditor *pEditor = dynamic_cast<CompositeModelEditor*>(mpEditor);
6892 if(pEditor->getInterfaceCausality(pConnectionLineAnnotation->getEndComponentName()) ==
6893 StringHandler::getTLMCausality(StringHandler::TLMInput)) {
6894 pConnectionLineAnnotation->setLinePattern(StringHandler::LineDash);
6895 pConnectionLineAnnotation->setEndArrow(StringHandler::ArrowFilled);
6896 //pConnectionLineAnnotation->update();
6897 //pConnectionLineAnnotation->handleComponentMoved();
6898 }
6899 else if(pEditor->getInterfaceCausality(pConnectionLineAnnotation->getEndComponentName()) ==
6900 StringHandler::getTLMCausality(StringHandler::TLMOutput)) {
6901 pConnectionLineAnnotation->setLinePattern(StringHandler::LineDash);
6902 pConnectionLineAnnotation->setStartArrow(StringHandler::ArrowFilled);
6903 //pConnectionLineAnnotation->update();
6904 //pConnectionLineAnnotation->handleComponentMoved();
6905 }
6906
6907 mpUndoStack->push(new AddConnectionCommand(pConnectionLineAnnotation, false));
6908 }
6909}
6910
6911void ModelWidget::drawOMSModelIconElements()
6912{
6913 if (mpLibraryTreeItem->isTopLevel()) {
6914 return;
6915 } else if (mpLibraryTreeItem->isSystemElement() || mpLibraryTreeItem->isComponentElement()) {
6916 drawOMSModelElement();
6917 // draw connectors
6918 for (int i = 0 ; i < mpLibraryTreeItem->childrenSize() ; i++) {
6919 LibraryTreeItem *pChildLibraryTreeItem = mpLibraryTreeItem->childAt(i);
6920 if (pChildLibraryTreeItem->getOMSConnector()
6921 && (pChildLibraryTreeItem->getOMSConnector()->causality == oms_causality_input
6922 || pChildLibraryTreeItem->getOMSConnector()->causality == oms_causality_output)) {
6923 double x = 0.5;
6924 double y = 0.5;
6925 if (pChildLibraryTreeItem->getOMSConnector()->geometry) {
6926 x = pChildLibraryTreeItem->getOMSConnector()->geometry->x;
6927 y = pChildLibraryTreeItem->getOMSConnector()->geometry->y;
6928 }
6929 QString annotation = QString("Placement(true,%1,%2,-10.0,-10.0,10.0,10.0,0,%1,%2,-10.0,-10.0,10.0,10.0,)")
6930 .arg(Utilities::mapToCoOrdinateSystem(x, 0, 1, -100, 100))
6931 .arg(Utilities::mapToCoOrdinateSystem(y, 0, 1, -100, 100));
6932 AddConnectorCommand *pAddConnectorCommand = new AddConnectorCommand(pChildLibraryTreeItem->getName(), pChildLibraryTreeItem,
6933 annotation, mpIconGraphicsView, true,
6934 pChildLibraryTreeItem->getOMSConnector()->causality,
6935 pChildLibraryTreeItem->getOMSConnector()->type);
6936 mpUndoStack->push(pAddConnectorCommand);
6937 } else if (pChildLibraryTreeItem->getOMSBusConnector()) {
6938 double x = 0.5;
6939 double y = 0.5;
6940 if (pChildLibraryTreeItem->getOMSBusConnector()->geometry) {
6941 x = pChildLibraryTreeItem->getOMSBusConnector()->geometry->x;
6942 y = pChildLibraryTreeItem->getOMSBusConnector()->geometry->y;
6943 }
6944 QString annotation = QString("Placement(true,%1,%2,-10.0,-10.0,10.0,10.0,0,%1,%2,-10.0,-10.0,10.0,10.0,)")
6945 .arg(Utilities::mapToCoOrdinateSystem(x, 0, 1, -100, 100))
6946 .arg(Utilities::mapToCoOrdinateSystem(y, 0, 1, -100, 100));
6947 AddBusCommand *pAddBusCommand = new AddBusCommand(pChildLibraryTreeItem->getName(), pChildLibraryTreeItem,
6948 annotation, mpIconGraphicsView, true);
6949 mpUndoStack->push(pAddBusCommand);
6950 // assoicated the bus component with each of its connector component
6951 associateBusWithConnectors(pChildLibraryTreeItem->getName());
6952 } else if (pChildLibraryTreeItem->getOMSTLMBusConnector()) {
6953 double x = 0.5;
6954 double y = 0.5;
6955 if (pChildLibraryTreeItem->getOMSTLMBusConnector()->geometry) {
6956 x = pChildLibraryTreeItem->getOMSTLMBusConnector()->geometry->x;
6957 y = pChildLibraryTreeItem->getOMSTLMBusConnector()->geometry->y;
6958 }
6959 QString annotation = QString("Placement(true,%1,%2,-10.0,-10.0,10.0,10.0,0,%1,%2,-10.0,-10.0,10.0,10.0,)")
6960 .arg(Utilities::mapToCoOrdinateSystem(x, 0, 1, -100, 100))
6961 .arg(Utilities::mapToCoOrdinateSystem(y, 0, 1, -100, 100));
6962 AddTLMBusCommand *pAddTLMBusCommand = new AddTLMBusCommand(pChildLibraryTreeItem->getName(), pChildLibraryTreeItem,
6963 annotation, mpIconGraphicsView, true,
6964 pChildLibraryTreeItem->getOMSTLMBusConnector()->domain,
6965 pChildLibraryTreeItem->getOMSTLMBusConnector()->dimensions,
6966 pChildLibraryTreeItem->getOMSTLMBusConnector()->interpolation);
6967 mpUndoStack->push(pAddTLMBusCommand);
6968 // assoicated the bus component with each of its connector component
6969 associateBusWithConnectors(pChildLibraryTreeItem->getName());
6970 }
6971 }
6972 }
6973}
6974
6975void ModelWidget::drawOMSModelDiagramElements()
6976{
6977 if (mpLibraryTreeItem->isTopLevel() || mpLibraryTreeItem->isSystemElement()) {
6978 for (int i = 0 ; i < mpLibraryTreeItem->childrenSize() ; i++) {
6979 LibraryTreeItem *pChildLibraryTreeItem = mpLibraryTreeItem->childAt(i);
6980 /* We only draw the elements here
6981 * Connectors are already drawn as part of ModelWidget::drawOMSModelIconElements();
6982 */
6983 if (pChildLibraryTreeItem->getOMSElement() && pChildLibraryTreeItem->getOMSElement()->geometry) {
6984 // check if we have zero width and height
6985 double x1, y1, x2, y2;
6986 x1 = pChildLibraryTreeItem->getOMSElement()->geometry->x1;
6987 y1 = pChildLibraryTreeItem->getOMSElement()->geometry->y1;
6988 x2 = pChildLibraryTreeItem->getOMSElement()->geometry->x2;
6989 y2 = pChildLibraryTreeItem->getOMSElement()->geometry->y2;
6990 double width = x2 - x1;
6991 double height = y2 - y1;
6992 if (width <= 0 && height <= 0) {
6993 x1 = -10.0;
6994 y1 = -10.0;
6995 x2 = 10.0;
6996 y2 = 10.0;
6997 }
6998 // Load the ModelWidget if not loaded already
6999 if (!pChildLibraryTreeItem->getModelWidget()) {
7000 MainWindow::instance()->getLibraryWidget()->getLibraryTreeModel()->showModelWidget(pChildLibraryTreeItem, false);
7001 }
7002
7003 QString annotation = QString("Placement(true,-,-,%1,%2,%3,%4,%5,-,-,-,-,-,-,)")
7004 .arg(x1).arg(y1)
7005 .arg(x2).arg(y2)
7006 .arg(pChildLibraryTreeItem->getOMSElement()->geometry->rotation);
7007
7008 if (pChildLibraryTreeItem->isSystemElement()) {
7009 AddSystemCommand *pAddSystemCommand = new AddSystemCommand(pChildLibraryTreeItem->getName(), pChildLibraryTreeItem,
7010 annotation, mpDiagramGraphicsView, true,
7011 pChildLibraryTreeItem->getSystemType());
7012 mpUndoStack->push(pAddSystemCommand);
7013 } else if (pChildLibraryTreeItem->isComponentElement()) {
7014 AddSubModelCommand *pAddSubModelCommand = new AddSubModelCommand(pChildLibraryTreeItem->getName(), "", "", pChildLibraryTreeItem,
7015 annotation, true, mpDiagramGraphicsView);
7016 mpUndoStack->push(pAddSubModelCommand);
7017 }
7018 }
7019 }
7020 }
7021}
7022
7023/*!
7024 * \brief ModelWidget::drawOMSModelConnections
7025 * Gets the OMSimulator model connections and draws them.
7026 */
7027void ModelWidget::drawOMSModelConnections()
7028{
7029 if (mpLibraryTreeItem->isSystemElement()) {
7030 MessagesWidget *pMessagesWidget = MessagesWidget::instance();
7031 oms_connection_t** pConnections = NULL__null;
7032 if (OMSProxy::instance()->getConnections(mpLibraryTreeItem->getNameStructure(), &pConnections)) {
7033 for (int i = 0 ; pConnections[i] ; i++) {
7034 // get start component
7035 QStringList startConnectionList = StringHandler::makeVariableParts(QString(pConnections[i]->conA));
7036 if (startConnectionList.size() < 1) {
7037 continue;
7038 }
7039 Component *pStartComponent = mpDiagramGraphicsView->getComponentObject(startConnectionList.at(0));
7040 if (!pStartComponent) {
7041 pMessagesWidget->addGUIMessage(MessageItem(MessageItem::Modelica,
7042 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_CONNECTION)
7043 .arg(startConnectionList.at(0)).arg(pConnections[i]->conA),
7044 Helper::scriptingKind, Helper::errorLevel));
7045 continue;
7046 }
7047 Component *pStartConnectorComponent, *pStartBusConnectorComponent;
7048 if (startConnectionList.size() > 1) {
7049 // get start connector component
7050 QString startConnectorName = StringHandler::removeFirstWordAfterDot(QString(pConnections[i]->conA));
7051 pStartConnectorComponent = getConnectorComponent(pStartComponent, startConnectorName);
7052 if (!pStartConnectorComponent) {
7053 pMessagesWidget->addGUIMessage(MessageItem(MessageItem::Modelica,
7054 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_CONNECTION)
7055 .arg(startConnectorName).arg(pConnections[i]->conA),
7056 Helper::scriptingKind, Helper::errorLevel));
7057 continue;
7058 }
7059 pStartBusConnectorComponent = pStartConnectorComponent;
7060 // if the connector is part of a bus connector
7061 if (pStartConnectorComponent->isInBus()) {
7062 pStartBusConnectorComponent = getConnectorComponent(pStartComponent, pStartConnectorComponent->getBusComponent()->getName());
7063 }
7064 } else {
7065 pStartConnectorComponent = pStartComponent;
7066 pStartBusConnectorComponent = pStartConnectorComponent;
7067 // if the connector is part of a bus connector
7068 if (pStartConnectorComponent->isInBus()) {
7069 pStartBusConnectorComponent = pStartConnectorComponent->getBusComponent();
7070 }
7071 }
7072
7073 // get end component
7074 QStringList endConnectionList = StringHandler::makeVariableParts(QString(pConnections[i]->conB));
7075 if (endConnectionList.size() < 1) {
7076 continue;
7077 }
7078 Component *pEndComponent = mpDiagramGraphicsView->getComponentObject(endConnectionList.at(0));
7079 if (!pEndComponent) {
7080 pMessagesWidget->addGUIMessage(MessageItem(MessageItem::Modelica,
7081 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_CONNECTION)
7082 .arg(endConnectionList.at(0)).arg(pConnections[i]->conB),
7083 Helper::scriptingKind, Helper::errorLevel));
7084 continue;
7085 }
7086 Component *pEndConnectorComponent, *pEndBusConnectorComponent;
7087 if (endConnectionList.size() > 1) {
7088 // get end connector component
7089 QString endConnectorName = StringHandler::removeFirstWordAfterDot(QString(pConnections[i]->conB));
7090 pEndConnectorComponent = getConnectorComponent(pEndComponent, endConnectorName);
7091 if (!pEndConnectorComponent) {
7092 pMessagesWidget->addGUIMessage(MessageItem(MessageItem::Modelica,
7093 GUIMessages::getMessage(GUIMessages::UNABLE_FIND_COMPONENT_IN_CONNECTION)
7094 .arg(endConnectorName).arg(pConnections[i]->conB),
7095 Helper::scriptingKind, Helper::errorLevel));
7096 continue;
7097 }
7098 pEndBusConnectorComponent = pEndConnectorComponent;
7099 // if the connector is part of a bus connector
7100 if (pEndConnectorComponent->isInBus()) {
7101 pEndBusConnectorComponent = getConnectorComponent(pEndComponent, pEndConnectorComponent->getBusComponent()->getName());
7102 }
7103 } else {
7104 pEndConnectorComponent = pEndComponent;
7105 pEndBusConnectorComponent = pEndConnectorComponent;
7106 // if the connector is part of a bus connector
7107 if (pEndConnectorComponent->isInBus()) {
7108 pEndBusConnectorComponent = pEndConnectorComponent->getBusComponent();
7109 }
7110 }
7111
7112 // default connection annotation
7113 QString annotation = QString("{Line(true,{0.0,0.0},0,%1,{0,0,0},LinePattern.Solid,0.25,{Arrow.None,Arrow.None},3,Smooth.None)}");
7114 QStringList shapesList;
7115 QString point = QString("{%1,%2}");
7116 QStringList points;
7117 if (pConnections[i]->geometry && pConnections[i]->geometry->n > 0) {
7118 for (unsigned int j = 0 ; j < pConnections[i]->geometry->n ; j++) {
7119 points.append(point.arg(pConnections[i]->geometry->pointsX[j]).arg(pConnections[i]->geometry->pointsY[j]));
7120 }
7121 }
7122 QPointF startPoint = pStartBusConnectorComponent->mapToScene(pStartBusConnectorComponent->boundingRect().center());
7123 points.prepend(point.arg(startPoint.x()).arg(startPoint.y()));
7124 QPointF endPoint = pEndBusConnectorComponent->mapToScene(pEndBusConnectorComponent->boundingRect().center());
7125 points.append(point.arg(endPoint.x()).arg(endPoint.y()));
7126 QString pointsString = QString("{%1}").arg(points.join(","));
7127 shapesList = StringHandler::getStrings(StringHandler::removeFirstLastCurlBrackets(QString(annotation).arg(pointsString)), '(', ')');
7128 // Now parse the shapes available in list
7129 QString lineShape = "";
7130 foreach (QString shape, shapesList)for (auto _container_ = QtPrivate::qMakeForeachContainer(shapesList
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString shape
= *_container_.i; _container_.control; _container_.control =
0)
{
7131 if (shape.startsWith("Line")) {
7132 lineShape = shape.mid(QString("Line").length());
7133 lineShape = StringHandler::removeFirstLastParentheses(lineShape);
7134 break; // break the loop once we have got the line annotation.
7135 }
7136 }
7137
7138 LineAnnotation *pConnectionLineAnnotation = new LineAnnotation(lineShape, pStartBusConnectorComponent,
7139 pEndBusConnectorComponent, mpDiagramGraphicsView);
7140 if (pStartConnectorComponent->getLibraryTreeItem()) {
7141 pConnectionLineAnnotation->setStartComponentName(pStartConnectorComponent->getLibraryTreeItem()->getNameStructure());
7142 }
7143 if (pEndConnectorComponent->getLibraryTreeItem()) {
7144 pConnectionLineAnnotation->setEndComponentName(pEndConnectorComponent->getLibraryTreeItem()->getNameStructure());
7145 }
7146 pConnectionLineAnnotation->setOMSConnectionType(pConnections[i]->type);
7147 mpUndoStack->push(new AddConnectionCommand(pConnectionLineAnnotation, false));
7148 // Check if the connectors of the connection belongs to a bus
7149 if (pStartConnectorComponent->isInBus() && pEndConnectorComponent->isInBus()) {
7150 pConnectionLineAnnotation->setVisible(false);
7151 }
7152 // Check if bus connection
7153 if (pConnections[i]->type == oms_connection_bus || pConnections[i]->type == oms_connection_tlm) {
7154 pConnectionLineAnnotation->setLineThickness(0.5);
7155 }
7156 }
7157 }
7158 }
7159}
7160
7161/*!
7162 * \brief ModelWidget::associateBusWithConnector
7163 * Helper function for ModelWidget::associateBusWithConnector(busName, connectorName)
7164 * \param busName
7165 * \param connectorName
7166 * \param pGraphicsView
7167 */
7168void ModelWidget::associateBusWithConnector(QString busName, QString connectorName, GraphicsView *pGraphicsView)
7169{
7170 // get the bus component
7171 Component *pBusComponent = pGraphicsView->getComponentObject(busName);
7172 // get the connector component
7173 Component *pConnectorComponent = pGraphicsView->getComponentObject(connectorName);
7174 if (pBusComponent && pConnectorComponent) {
7175 pConnectorComponent->setBusComponent(pBusComponent);
7176 }
7177}
7178
7179/*!
7180 * \brief ModelWidget::dissociateBusWithConnector
7181 * Helper function for ModelWidget::dissociateBusWithConnector(busName, connectorName)
7182 * \param busName
7183 * \param connectorName
7184 * \param pGraphicsView
7185 */
7186void ModelWidget::dissociateBusWithConnector(QString busName, QString connectorName, GraphicsView *pGraphicsView)
7187{
7188 // get the bus component
7189 Component *pBusComponent = pGraphicsView->getComponentObject(busName);
7190 Component *pConnectorComponent = pGraphicsView->getComponentObject(connectorName);
7191 if (pBusComponent && pConnectorComponent) {
7192 pConnectorComponent->setBusComponent(0);
7193 }
7194}
7195
7196/*!
7197 * \brief ModelWidget::associateBusWithConnectors
7198 * Helper function for ModelWidget::associateBusWithConnectors(busName)
7199 * \param pBusComponent
7200 * \param pGraphicsView
7201 */
7202void ModelWidget::associateBusWithConnectors(Component *pBusComponent, GraphicsView *pGraphicsView)
7203{
7204 if (pBusComponent && pBusComponent->getLibraryTreeItem() && pBusComponent->getLibraryTreeItem()->getOMSBusConnector()) {
7205 oms_busconnector_t *pBusConnector = pBusComponent->getLibraryTreeItem()->getOMSBusConnector();
7206 if (pBusConnector->connectors) {
7207 for (int i = 0 ; pBusConnector->connectors[i] ; i++) {
7208 Component *pConnectorComponent = pGraphicsView->getComponentObject(QString(pBusConnector->connectors[i]));
7209 if (pConnectorComponent) {
7210 pConnectorComponent->setBusComponent(pBusComponent);
7211 }
7212 }
7213 }
7214 } else if (pBusComponent && pBusComponent->getLibraryTreeItem() && pBusComponent->getLibraryTreeItem()->getOMSTLMBusConnector()) {
7215 oms_tlmbusconnector_t *pTLMBusConnector = pBusComponent->getLibraryTreeItem()->getOMSTLMBusConnector();
7216 if (pTLMBusConnector->connectornames) {
7217 for (int i = 0 ; pTLMBusConnector->connectornames[i] ; i++) {
7218 Component *pConnectorComponent = pGraphicsView->getComponentObject(QString(pTLMBusConnector->connectornames[i]));
7219 if (pConnectorComponent) {
7220 pConnectorComponent->setBusComponent(pBusComponent);
7221 }
7222 }
7223 }
7224 }
7225}
7226
7227/*!
7228 * \brief ModelWidget::showIconView
7229 * \param checked
7230 * Slot activated when mpIconViewToolButton toggled SIGNAL is raised. Shows the icon view.
7231 */
7232void ModelWidget::showIconView(bool checked)
7233{
7234 // validate the modelica text before switching to icon view
7235 if (checked) {
7236 if (!validateText(&mpLibraryTreeItem)) {
7237 mpTextViewToolButton->setChecked(true);
7238 return;
7239 }
7240 }
7241 QMdiSubWindow *pSubWindow = mpModelWidgetContainer->getCurrentMdiSubWindow();
7242 if (pSubWindow) {
7243 pSubWindow->setWindowIcon(ResourceCache::getIcon(":/Resources/icons/model.svg"));
7244 }
7245 mpModelWidgetContainer->currentModelWidgetChanged(mpModelWidgetContainer->getCurrentMdiSubWindow());
7246 mpIconGraphicsView->setFocus(Qt::ActiveWindowFocusReason);
7247 if (!checked || (checked && mpIconGraphicsView->isVisible())) {
7248 return;
7249 }
7250 mpViewTypeLabel->setText(StringHandler::getViewType(StringHandler::Icon));
7251 mpDiagramGraphicsView->hide();
7252 if (mpEditor) {
7253 mpEditor->hide();
7254 }
7255 mpIconGraphicsView->show();
7256 mpIconGraphicsView->setFocus();
7257 mpModelWidgetContainer->setPreviousViewType(StringHandler::Icon);
7258 updateUndoRedoActions();
7259 MainWindow::instance()->getPositionLabel()->clear();
7260}
7261
7262/*!
7263 * \brief ModelWidget::showDiagramView
7264 * \param checked
7265 * Slot activated when mpDiagramViewToolButton toggled SIGNAL is raised. Shows the diagram view.
7266 */
7267void ModelWidget::showDiagramView(bool checked)
7268{
7269 // validate the modelica text before switching to diagram view
7270 if (checked) {
7271 if (!validateText(&mpLibraryTreeItem)) {
7272 mpTextViewToolButton->setChecked(true);
7273 return;
7274 }
7275 }
7276 QMdiSubWindow *pSubWindow = mpModelWidgetContainer->getCurrentMdiSubWindow();
7277 if (pSubWindow) {
7278 pSubWindow->setWindowIcon(ResourceCache::getIcon(":/Resources/icons/modeling.png"));
7279 }
7280 mpModelWidgetContainer->currentModelWidgetChanged(mpModelWidgetContainer->getCurrentMdiSubWindow());
7281 mpDiagramGraphicsView->setFocus(Qt::ActiveWindowFocusReason);
7282 if (!checked || (checked && mpDiagramGraphicsView->isVisible())) {
7283 return;
7284 }
7285 mpViewTypeLabel->setText(StringHandler::getViewType(StringHandler::Diagram));
7286 if (mpIconGraphicsView) {
7287 mpIconGraphicsView->hide();
7288 }
7289 if (mpEditor) {
7290 mpEditor->hide();
7291 }
7292 mpDiagramGraphicsView->show();
7293 mpDiagramGraphicsView->setFocus();
7294 mpModelWidgetContainer->setPreviousViewType(StringHandler::Diagram);
7295 updateUndoRedoActions();
7296 MainWindow::instance()->getPositionLabel()->clear();
7297}
7298
7299/*!
7300 * \brief ModelWidget::showTextView
7301 * \param checked
7302 * Slot activated when mpTextViewToolButton toggled SIGNAL is raised. Shows the text view.
7303 */
7304void ModelWidget::showTextView(bool checked)
7305{
7306 if (!checked || (checked && mpEditor->isVisible())) {
7307 return;
7308 }
7309 if (QMdiSubWindow *pSubWindow = mpModelWidgetContainer->getCurrentMdiSubWindow()) {
7310 pSubWindow->setWindowIcon(ResourceCache::getIcon(":/Resources/icons/modeltext.svg"));
7311 }
7312 mpModelWidgetContainer->currentModelWidgetChanged(mpModelWidgetContainer->getCurrentMdiSubWindow());
7313 mpViewTypeLabel->setText(StringHandler::getViewType(StringHandler::ModelicaText));
7314 if (mpIconGraphicsView) {
7315 mpIconGraphicsView->hide();
7316 }
7317 mpDiagramGraphicsView->hide();
7318 if (mpEditor) {
7319 mpEditor->show();
7320 mpEditor->getPlainTextEdit()->setFocus(Qt::ActiveWindowFocusReason);
7321 mpEditor->getPlainTextEdit()->updateCursorPosition();
7322 }
7323 mpModelWidgetContainer->setPreviousViewType(StringHandler::ModelicaText);
7324 updateUndoRedoActions();
7325}
7326
7327void ModelWidget::makeFileWritAble()
7328{
7329 const QString &fileName = mpLibraryTreeItem->getFileName();
7330 const bool permsOk = QFile::setPermissions(fileName, QFile::permissions(fileName) | QFile::WriteUser);
7331 if (!permsOk)
7332 QMessageBox::warning(this, tr("Cannot Set Permissions"), tr("Cannot set permissions to writable."));
7333 else
7334 {
7335 mpLibraryTreeItem->setReadOnly(false);
7336 mpFileLockToolButton->setText(tr("File is writable"));
7337 mpFileLockToolButton->setIcon(ResourceCache::getIcon(":/Resources/icons/unlock.svg"));
7338 mpFileLockToolButton->setEnabled(false);
7339 mpFileLockToolButton->setToolTip(mpFileLockToolButton->text());
7340 }
7341}
7342
7343void ModelWidget::showDocumentationView()
7344{
7345 // validate the modelica text before switching to documentation view
7346 if (!validateText(&mpLibraryTreeItem)) {
7347 mpTextViewToolButton->setChecked(true);
7348 return;
7349 }
7350 MainWindow::instance()->getDocumentationWidget()->showDocumentation(getLibraryTreeItem());
7351 bool state = MainWindow::instance()->getDocumentationDockWidget()->blockSignals(true);
7352 MainWindow::instance()->getDocumentationDockWidget()->show();
7353 MainWindow::instance()->getDocumentationDockWidget()->blockSignals(state);
7354}
7355
7356/*!
7357 * \brief ModelWidget::compositeModelEditorTextChanged
7358 * Called when CompositeModelEditor text has been changed by user manually.\n
7359 * Updates the LibraryTreeItem and ModelWidget with new changes.
7360 * \return
7361 */
7362bool ModelWidget::compositeModelEditorTextChanged()
7363{
7364 MessageHandler *pMessageHandler = new MessageHandler;
7365 Utilities::parseCompositeModelText(pMessageHandler, mpEditor->getPlainTextEdit()->toPlainText());
7366 if (pMessageHandler->isFailed()) {
7367 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::CompositeModel, getLibraryTreeItem()->getName(), false,
7368 pMessageHandler->line(), pMessageHandler->column(), 0, 0,
7369 pMessageHandler->statusMessage(), Helper::syntaxKind, Helper::errorLevel));
7370 delete pMessageHandler;
7371 return false;
7372 }
7373 delete pMessageHandler;
7374 // update the xml document with new accepted text.
7375 CompositeModelEditor *pCompositeModelEditor = dynamic_cast<CompositeModelEditor*>(mpEditor);
7376 pCompositeModelEditor->setXmlDocumentContent(mpEditor->getPlainTextEdit()->toPlainText());
7377 /* get the model components and connectors */
7378 reDrawModelWidget();
7379 return true;
7380}
7381
7382/*!
7383 * \brief ModelWidget::handleCanUndoChanged
7384 * Enables/disables the Edit menu Undo action depending on the stack situation.
7385 * \param canUndo
7386 */
7387void ModelWidget::handleCanUndoChanged(bool canUndo)
7388{
7389 Q_UNUSED(canUndo)(void)canUndo;;
7390 updateUndoRedoActions();
7391}
7392
7393/*!
7394 * \brief ModelWidget::handleCanRedoChanged
7395 * Enables/disables the Edit menu Redo action depending on the stack situation.
7396 * \param canRedo
7397 */
7398void ModelWidget::handleCanRedoChanged(bool canRedo)
7399{
7400 Q_UNUSED(canRedo)(void)canRedo;;
7401 updateUndoRedoActions();
7402}
7403
7404void ModelWidget::closeEvent(QCloseEvent *event)
7405{
7406 Q_UNUSED(event)(void)event;;
7407 mpModelWidgetContainer->removeSubWindow(this);
7408}
7409
7410/*!
7411 * \brief addCloseActionsToSubWindowSystemMenu
7412 * Adds the "Close All Windows" and "Close All Windows But This" actions to QMdiSubWindow system menu.
7413 */
7414void addCloseActionsToSubWindowSystemMenu(QMdiSubWindow *pMdiSubWindow)
7415{
7416 /* ticket:3295 Add the "Close All Windows" and "Close All Windows But This" to system menu. */
7417 QMenu *pMenu = pMdiSubWindow->systemMenu();
7418 pMenu->addAction(MainWindow::instance()->getCloseAllWindowsAction());
7419 pMenu->addAction(MainWindow::instance()->getCloseAllWindowsButThisAction());
7420}
7421
7422ModelWidgetContainer::ModelWidgetContainer(QWidget *pParent)
7423 : QMdiArea(pParent), mPreviousViewType(StringHandler::NoView), mShowGridLines(true)
7424{
7425 setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
7426 setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
7427 setActivationOrder(QMdiArea::ActivationHistoryOrder);
7428 setDocumentMode(true);
7429#if QT_VERSION((5<<16)|(9<<8)|(5)) >= 0x040800
7430 setTabsClosable(true);
7431#endif
7432 if (OptionsDialog::instance()->getGeneralSettingsPage()->getModelingViewMode().compare(Helper::subWindow) == 0) {
7433 setViewMode(QMdiArea::SubWindowView);
7434 } else {
7435 setViewMode(QMdiArea::TabbedView);
7436 }
7437 // create a Model Swicther Dialog
7438 mpModelSwitcherDialog = new QDialog(this, Qt::Popup);
7439 mpRecentModelsList = new QListWidget(this);
7440 mpRecentModelsList->setItemDelegate(new ItemDelegate(mpRecentModelsList));
7441 mpRecentModelsList->setTextElideMode(Qt::ElideMiddle);
7442 mpRecentModelsList->setViewMode(QListView::ListMode);
7443 mpRecentModelsList->setMovement(QListView::Static);
7444 connect(mpRecentModelsList, SIGNAL(itemClicked(QListWidgetItem*))"2""itemClicked(QListWidgetItem*)", SLOT(openRecentModelWidget(QListWidgetItem*))"1""openRecentModelWidget(QListWidgetItem*)");
7445 QGridLayout *pModelSwitcherLayout = new QGridLayout;
7446 pModelSwitcherLayout->setContentsMargins(0, 0, 0, 0);
7447 pModelSwitcherLayout->addWidget(mpRecentModelsList, 0, 0);
7448 mpModelSwitcherDialog->setLayout(pModelSwitcherLayout);
7449 mpLastActiveSubWindow = 0;
7450 // install QApplication event filter to handle the ctrl+tab and ctrl+shift+tab
7451 QApplication::instance()->installEventFilter(this);
7452 connect(this, SIGNAL(subWindowActivated(QMdiSubWindow*))"2""subWindowActivated(QMdiSubWindow*)", SLOT(currentModelWidgetChanged(QMdiSubWindow*))"1""currentModelWidgetChanged(QMdiSubWindow*)");
7453 connect(this, SIGNAL(subWindowActivated(QMdiSubWindow*))"2""subWindowActivated(QMdiSubWindow*)", MainWindow::instance(), SLOT(updateModelSwitcherMenu(QMdiSubWindow*))"1""updateModelSwitcherMenu(QMdiSubWindow*)");
7454 connect(this, SIGNAL(subWindowActivated(QMdiSubWindow*))"2""subWindowActivated(QMdiSubWindow*)", SLOT(updateThreeDViewer(QMdiSubWindow*))"1""updateThreeDViewer(QMdiSubWindow*)");
7455 // add actions
7456 connect(MainWindow::instance()->getSaveAction(), SIGNAL(triggered())"2""tr