29 #include "sheetview.h"
30 #include <QDragEnterEvent>
32 #include <QGraphicsScene>
33 #include <QGraphicsRectItem>
35 #include <QMessageBox>
37 #include <QApplication>
48 #include <arcs/arcscompositecomponent.h>
50 #include "graphicscomponentitem.h"
51 #include "graphicslinkitem.h"
52 #include "orderconnectionsdialog.h"
65 #define MAX(A,B) (((A)>(B))?(A):(B))
69 #define MIN(A,B) (((A)<(B))?(A):(B))
74 SheetView::SheetView(
ARCSSheet& s, QWidget *parent) : QGraphicsView(parent),sheet(s)
76 setScene(
new QGraphicsScene(
this));
80 setResizeAnchor(QGraphicsView::NoAnchor);
81 setTransformationAnchor(QGraphicsView::NoAnchor);
83 setSceneRect(viewport()->rect());
84 setAlignment(Qt::AlignLeft|Qt::AlignTop);
87 rectSelection =
new QGraphicsRectItem();
88 scene()->addItem(rectSelection);
89 rectSelection->setPen(QPen(Qt::darkGreen));
90 rectSelection->setBrush(QBrush(QColor(0,255,0,63)));
91 rectSelection->setVisible(
false);
95 actionSelectAll =
new QAction(
"Select all",
this);
96 actionSelectAll->setShortcuts(QKeySequence::SelectAll);
97 connect(actionSelectAll,SIGNAL(triggered()),
this,SLOT(selectAll()));
98 actionCopy =
new QAction(
"&Copy",
this);
99 actionCopy->setShortcuts(QKeySequence::Copy);
100 connect(actionCopy,SIGNAL(triggered()),
this,SLOT(copy()));
101 actionPaste =
new QAction(
"&Paste",
this);
102 actionPaste->setShortcuts(QKeySequence::Paste);
103 connect(actionPaste,SIGNAL(triggered()),
this,SLOT(paste()));
104 actionDelete =
new QAction(
"Delete selection",
this);
105 actionDelete->setShortcuts(QKeySequence::Delete);
106 connect(actionDelete,SIGNAL(triggered()),
this,SLOT(deleteSelection()));
107 QAction* sep1 =
new QAction(
this);
108 sep1->setSeparator(
true);
109 QAction* sep2 =
new QAction(
this);
110 sep2->setSeparator(
true);
112 actionOrderInvocations =
new QAction(
"Order invocations...",
this);
113 connect(actionOrderInvocations,SIGNAL(triggered()),
this,SLOT(orderInvocations()));
114 actionOrderConnections =
new QAction(
"Order connections...",
this);
115 connect(actionOrderConnections,SIGNAL(triggered()),
this,SLOT(orderConnections()));
118 addAction(actionOrderConnections);
119 addAction(actionOrderInvocations);
121 addAction(actionCopy);
122 addAction(actionPaste);
123 addAction(actionDelete);
125 addAction(actionSelectAll);
132 SheetView::~SheetView()
139 void SheetView::layoutSheet()
144 QString list = sheet.
getProperty(
"component-list");
149 componentList = actualComponents;
151 componentList = list.split(
';').toSet().unite(actualComponents.toSet()).intersect(sheet.getContext()->
getComponentList().toSet()).toList();
155 for (i=0; i < componentList.count(); i++)
159 scene()->addItem(gci);
160 QString pos = sheet.
getProperty(componentList[i]+
"-pos");
162 gci->setPos(pos.section(
",",0,0).toFloat(),pos.section(
",",1,1).toFloat());
164 QString slts = sheet.
getProperty(componentList[i]+
"-slots");
167 QStringList slotList = slts.split(
";");
168 for (j=0; j < slotList.count(); j++ )
169 gci->addSlot(slotList[j],
false);
171 QString sgnls = sheet.
getProperty(componentList[i]+
"-signals");
172 if (!sgnls.isEmpty())
174 QStringList signalList = sgnls.split(
";");
175 for (j=0; j < signalList.count(); j++ )
176 gci->addSignal(signalList[j],
false);
185 QStringList destinations;
186 QStringList signalList;
187 QStringList slotList;
188 QStringList invocationTypes;
189 QStringList invocationValues;
191 for (i=0; i< sources.count(); i++)
198 if (srcGComponent && dstGComponent)
203 srcGComponent->addSignal(signalList[i]);
204 sgnPort = srcGComponent->getSignalPort(signalList[i]);
210 dstGComponent->addSlot(slotList[i]);
211 sltPort = dstGComponent->getSlotPort(slotList[i]);
215 if (sgnPort && sltPort)
218 link->setSource(sgnPort);
219 sgnPort->addLink(link);
220 link->setDestination(sltPort);
221 sltPort->addLink(link);
229 sheet.
getPreconnects(destinations,slotList,invocationTypes,invocationValues);
230 layoutInvocations(GraphicsInvocationItem::Pre,destinations,slotList,invocationTypes,invocationValues);
231 sheet.
getPostconnects(destinations,slotList,invocationTypes,invocationValues);
232 layoutInvocations(GraphicsInvocationItem::Post,destinations,slotList,invocationTypes,invocationValues);
233 sheet.
getCleanups(destinations,slotList,invocationTypes,invocationValues);
234 layoutInvocations(GraphicsInvocationItem::Cleanup,destinations,slotList,invocationTypes,invocationValues);
237 sheet.
setProperty(
"component-list",componentList.join(
";"));
238 if (componentList.count() == 0)
239 actionSelectAll->setEnabled(
false);
240 actionCopy->setEnabled(
false);
241 actionDelete->setEnabled(
false);
244 scene()->setSceneRect(sceneRect().united(scene()->itemsBoundingRect()));
245 setSceneRect(scene()->sceneRect());
250 for (
int i=0; i < destinations.count(); i++)
253 switch (invocationType)
255 case GraphicsInvocationItem::Pre:
256 init = &sheet.getPreConnect(destinations[i],slotList[i],typeList[i],valueList[i]);
258 case GraphicsInvocationItem::Post:
259 init = &sheet.getPostConnect(destinations[i],slotList[i],typeList[i],valueList[i]);
261 case GraphicsInvocationItem::Cleanup:
262 init = &sheet.getCleanup(destinations[i],slotList[i],typeList[i],valueList[i]);
272 dstGComponent->addSlot(slotList[i]);
273 sltPort = dstGComponent->getSlotPort(slotList[i]);
275 if (sltPort && init )
286 void SheetView::dragEnterEvent(QDragEnterEvent *event)
288 if (event->mimeData()->hasFormat(
"text/plain"))
289 if (event->source()->property(
"appId") == this->property(
"appId"))
290 event->acceptProposedAction();
293 void SheetView::dragMoveEvent(QDragMoveEvent *event)
295 if (event->mimeData()->hasFormat(
"text/plain"))
296 if (event->source()->property(
"appId") == this->property(
"appId"))
297 event->acceptProposedAction();
301 void SheetView::dropEvent(QDropEvent *event)
303 if (event->source()->property(
"appId") != this->property(
"appId"))
307 event->acceptProposedAction();
312 void SheetView::updateSheet()
319 void SheetView::clearScene()
324 QList<QGraphicsItem*> itemList = scene()->items();
325 for (i=0; i < itemList.count();i++)
327 if (itemList[i]->type() == GraphicsComponentItem::Type)
332 itemList = scene()->items();
338 itemList = scene()->items();
339 for (i=0; i < itemList.count();i++)
341 if (itemList[i]->type() == GraphicsPortItem::Type)
346 itemList = scene()->items();
351 itemList = scene()->items();
352 for (i=0; i < itemList.count(); i++)
354 if (itemList[i]->type() == GraphicsInvocationItem::Type)
359 itemList = scene()->items();
365 if (itemList[i]->type() == GraphicsLinkItem::Type )
370 itemList = scene()->items();
378 actionSelectAll->setEnabled(
false);
379 actionCopy->setEnabled(
false);
397 std::cerr <<
"component not found" << std::endl;
404 if (componentList.contains(name))
407 componentList.append(name);
408 sheet.
setProperty(
"component-list",componentList.join(
";"));
412 QTransform tr = transform();
414 gci->setPos(mapToScene(tr.map(p)));
416 scene()->addItem(gci);
418 sheet.
setProperty(name+
"-pos",QString::number(gci->pos().x())+
","+QString::number(gci->pos().y()));
420 scene()->setSceneRect(sceneRect().united(scene()->itemsBoundingRect()));
421 setSceneRect(scene()->sceneRect());
422 actionSelectAll->setEnabled(
true);
430 QList<QGraphicsItem*> items = scene()->items();
431 for (
int i=0; i<items.count(); i++)
433 if (items[i]->type() == GraphicsComponentItem::Type)
436 if (gItem->getComponent()->
getProperty(
"id").toString() == name)
445 void SheetView::mouseMoveEvent(QMouseEvent *event)
447 if (event->buttons() & Qt::LeftButton)
449 scene()->setSceneRect(sceneRect().united(scene()->itemsBoundingRect()));
450 setSceneRect(scene()->sceneRect());
451 if (rectSelection->isVisible())
453 QTransform tr = transform();
454 QPointF endPos = mapToScene(tr.map(event->pos()));
456 QPointF lowerLeft( MIN(rectSelection->x(),endPos.x()), MIN(rectSelection->y(),endPos.y()) );
457 QPointF upperRight(MAX(rectSelection->x(),endPos.x()), MAX(rectSelection->y(),endPos.y()) );
459 rectSelection->setRect(QRectF(lowerLeft - rectSelection->pos(), upperRight - rectSelection->pos()));
464 QGraphicsView::mouseMoveEvent(event);
468 void SheetView::mousePressEvent(QMouseEvent *event)
471 if (event->buttons() & Qt::LeftButton)
473 QTransform tr = transform();
475 QPointF posStart = mapToScene(tr.map(event->pos()));
477 QList<QGraphicsItem*> items = scene()->items(posStart);
482 rectSelection->setVisible(
true);
483 rectSelection->setRect(0,0,2,2);
484 rectSelection->setPos(posStart);
491 QGraphicsView::mousePressEvent(event);
495 void SheetView::mouseReleaseEvent(QMouseEvent *event)
497 if (rectSelection->isVisible())
499 QList<QGraphicsItem*> items = scene()->items(rectSelection->mapToScene(rectSelection->rect()));
500 for (
int i = 0; i< items.count(); i++)
502 if (items[i] != rectSelection)
503 items[i]->setSelected(
true);
506 QGraphicsView::mouseReleaseEvent(event);
507 rectSelection->setVisible(
false);
509 actionCopy->setEnabled(scene()->selectedItems().count());
510 actionDelete->setEnabled(scene()->selectedItems().count());
513 void SheetView::contextMenuEvent(QContextMenuEvent *event)
515 QTransform tr = transform();
516 QPointF posStart = mapToScene(tr.map(event->pos()));
517 QList<QGraphicsItem*> items = scene()->items(posStart);
520 if (items.count() != 0)
522 QGraphicsView::contextMenuEvent(event);
527 menu.addActions(this->actions());
528 menu.exec(event->globalPos());
533 void SheetView::deleteSelection()
540 QList<QGraphicsItem*> itemList = scene()->selectedItems();
541 itemList = scene()->selectedItems();
544 for (i=0; i < itemList.count();i++)
546 if (itemList[i]->type() == GraphicsComponentItem::Type)
549 name = item->getComponent()->
getProperty(
"id").toString();
550 componentList.removeAll(name);
551 item->markForDeletion();
554 itemList = scene()->selectedItems();
558 sheet.
setProperty(
"component-list",componentList.join(
";"));
561 itemList = scene()->selectedItems();
562 for (i=0; i < itemList.count();i++)
564 if (itemList[i]->type() == GraphicsPortItem::Type)
567 item->markForDeletion();
570 itemList = scene()->selectedItems();
577 itemList = scene()->selectedItems();
578 for (i=0; i < itemList.count(); i++)
580 if (itemList[i]->type() == GraphicsInvocationItem::Type)
583 item->markForDeletion();
586 itemList = scene()->selectedItems();
592 if (itemList[i]->type() == GraphicsLinkItem::Type )
595 item->markForDeletion();
598 itemList = scene()->selectedItems();
604 actionCopy->setEnabled(scene()->selectedItems().count());
605 actionDelete->setEnabled(scene()->selectedItems().count());
606 actionSelectAll->setEnabled(
false);
609 void SheetView::clearSelection()
611 QList<QGraphicsItem*> items = scene()->selectedItems();
612 for (
int i=0; i< items.count(); i++)
613 items[i]->setSelected(
false);
615 actionCopy->setEnabled(scene()->selectedItems().count());
616 actionDelete->setEnabled(scene()->selectedItems().count());
620 void SheetView::selectAll()
622 QList<QGraphicsItem*> items = scene()->items();
623 for (
int i=0; i< items.count(); i++)
624 items[i]->setSelected(
true);
626 actionCopy->setEnabled(scene()->selectedItems().count());
627 actionDelete->setEnabled(scene()->selectedItems().count());
647 QList<QGraphicsItem*> selectedItems = scene()->selectedItems();
649 for (i=0; i < selectedItems.count(); i++)
651 if (selectedItems[i]->type() == GraphicsComponentItem::Type)
655 std::cerr <<
"problem creating component " << qPrintable(origComponent->
getProperty(
"id").toString()) << std::endl;
660 copySheet->
setProperty(
"component-list",copiedComponents.join(
";"));
662 for (i=0; i < copiedComponents.count(); i++ )
665 QString propertyString = sheet.
getProperty(copiedComponents[i]+
"-pos");
666 QPointF pos = QPointF(propertyString.section(
",",0,0).toFloat(),
667 propertyString.section(
",",1,1).toFloat()) ;
668 pos -= mapToScene(0,0);
669 copySheet->
setProperty(copiedComponents[i]+
"-pos",QString::number(pos.x())+
","+QString::number(pos.y()));
677 for (i=0; i< selectedItems.count(); i++)
679 if (selectedItems[i]->type() == GraphicsLinkItem::Type)
682 QString origSource = origLink->getSourceName();
683 QString origDestination = origLink->getDestinationName();
684 if (copiedComponents.contains(origSource) && copiedComponents.contains(origDestination))
689 copyLink.setCoordinates(origLink->getCoordinates());
690 std::cout <<
"Connection append" << std::endl;
693 if (selectedItems[i]->type() == GraphicsInvocationItem::Type)
697 QString origDestination = origInvocation.getDestinationName();
698 if (copiedComponents.contains(origDestination))
700 switch(origInvocationType)
702 case GraphicsInvocationItem::Pre:
705 case GraphicsInvocationItem::Post:
708 case GraphicsInvocationItem::Cleanup:
712 std::cout <<
"invocation append" << std::endl;
719 QClipboard *clipboard = QApplication::clipboard();
722 clipboard->setText(copyText);
732 void SheetView::paste()
736 QClipboard *clipboard = QApplication::clipboard();
737 QString dataString = clipboard->text();
738 QPointF offsetPos = mapToScene(0,0);
740 QRectF rect = sceneRect();
741 std::cout <<
"offsetPos: " << offsetPos.x() <<
", " << offsetPos.y() << std::endl;
742 std::cout <<
"sceneRect: " << rect.x() <<
", " << rect.y() <<
": " << rect.width() <<
"x" << rect.height() << std::endl;
752 ARCSContext* incomingContext = incomingSheet->getContext();
756 QMap<QString,QString> renamedComponents;
759 for (i=0; i < incomingComponents.count(); i++)
761 QString candidateComponent = incomingComponents[i];
763 while (actualComponents.contains(candidateComponent) || renamedComponents.contains(candidateComponent))
766 candidateComponent +=
"_";
768 if (actualComponents.contains(incomingComponents[i]))
769 renamedComponents[incomingComponents[i]] = candidateComponent;
771 std::cout <<
"Adding one component" << std::endl;
775 QString propertyString;
776 if (! (propertyString =incomingSheet->
getProperty(incomingComponents[i] +
"-slots")).isEmpty())
777 sheet.
setProperty(candidateComponent+
"-slots",propertyString);
778 if (! (propertyString =incomingSheet->
getProperty(incomingComponents[i] +
"-signals")).isEmpty())
779 sheet.
setProperty(candidateComponent+
"-signals",propertyString);
780 if (! (propertyString =incomingSheet->
getProperty(incomingComponents[i] +
"-pos")).isEmpty())
782 QPointF pos = QPointF(propertyString.section(
",",0,0).toFloat(),
783 propertyString.section(
",",1,1).toFloat()) + offsetPos ;
785 QString::number(pos.x())+
","+QString::number(pos.y()));
791 QStringList destinations;
792 QStringList signalList;
793 QStringList slotList;
794 QStringList invocationTypes;
795 QStringList invocationValues;
796 QString source, destination;
797 incomingSheet->
getConnections(sources,signalList,destinations,slotList);
798 for (i=0; i< sources.count(); i++)
801 source = (renamedComponents.contains(sources[i]))?renamedComponents[sources[i]]:sources[i];
802 destination = (renamedComponents.contains(destinations[i]))?renamedComponents[destinations[i]]:destinations[i];
804 QList<QPointF> coords = c.getCoordinates();
805 for (j=0; j< 4 ; j++)
807 coords[i] += offsetPos;
809 cbis.setCoordinates(c.getCoordinates());
812 incomingSheet->
getPreconnects(destinations,slotList,invocationTypes,invocationValues);
813 for (i=0; i< destinations.count();i++)
815 destination = (renamedComponents.contains(destinations[i]))?renamedComponents[destinations[i]]:destinations[i];
816 sheet.
addPreconnect(destination, slotList[i], invocationTypes[i], invocationValues[i]);
818 incomingSheet->
getPostconnects(destinations,slotList,invocationTypes,invocationValues);
819 for (i=0; i< destinations.count();i++)
821 destination = (renamedComponents.contains(destinations[i]))?renamedComponents[destinations[i]]:destinations[i];
822 sheet.
addPostconnect(destination, slotList[i], invocationTypes[i], invocationValues[i]);
824 incomingSheet->
getCleanups(destinations,slotList,invocationTypes,invocationValues);
825 for (i=0; i< destinations.count();i++)
827 destination = (renamedComponents.contains(destinations[i]))?renamedComponents[destinations[i]]:destinations[i];
828 sheet.
addCleanup(destination, slotList[i], invocationTypes[i], invocationValues[i]);
838 scene()->clearSelection();
839 for(i=0; i < incomingComponents.count(); i++)
841 if (renamedComponents.contains(incomingComponents[i]))
842 findComponentByName(renamedComponents[incomingComponents[i]])->setSelected(
true);
844 findComponentByName(incomingComponents[i])->setSelected(
true);
847 emit requestApplicationUpdate();
849 actionCopy->setEnabled(scene()->selectedItems().count());
850 actionDelete->setEnabled(scene()->selectedItems().count());
851 actionSelectAll->setEnabled(
true);
854 void SheetView::orderInvocations()
861 void SheetView::orderConnections()
virtual QString toString()
Defines a basic seralization mechanism.
ARCSInit & addCleanup(QString dst, QString slt, QString t, QString val)
Adds a cleanup invocation to the sheet structure.
Class defining a composite component i.e. a component made of components.
virtual QString toString()=0
Defines a basic seralization mechanism.
virtual bool parseString(QString s)
Defines a basic seralization mechanism.
void addComponent(QPoint p, QString name)
void setSheet(ARCSSheet ref)
Sets the sheet to use as an internal description of embedded components.
QString getProperty(QString name)
QStringList getComponentList()
ARCSSheet * getSheet()
Returns the internal structure of this composite component described as a sheet.
ARCSInit & addPreconnect(QString dst, QString slt, QString t, QString val)
Adds a pre-connection initialisation to the sheet structure.
Desribes an initialization over a component.
bool addComponent(QString name, QString className, QString contents=QString::null)
Adds a component to the list.
void setProperty(QString name, QString value)
QVariant getProperty(QString name)
Gets a meta-property from this component.
void getCleanups(QStringList &destinations, QStringList &slts, QStringList &types, QStringList &values)
Allows to retrieve cleanup invocations.
Class handling the generic description of a component.
QStringList getComponentList()
Retrieves the list of components that are used in this sheet.
ARCSAbstractComponent * getComponent(QString name)
Retrieves a component by its id.
void getConnections(QStringList &sources, QStringList &signls, QStringList &destinations, QStringList &slts)
Allows to retrieve connections.
void getPostconnects(QStringList &destinations, QStringList &slts, QStringList &types, QStringList &values)
Allows to retrieve postconnection invocations.
This class manages components and constants in a given context.
ARCSConnection & addConnection(QString src, QString sgn, QString dst, QString slt, bool q=false, bool head=false)
Adds a connection to the sheet structure.
ARCSConnection & getConnection(QString source, QString sgn, QString dst, QString slt)
returns a reference to a connection in the sheet structure
ARCSInit & addPostconnect(QString dst, QString slt, QString t, QString val)
Adds a post-connection initialisation to the sheet structure.
Maintains connections between objects.
void getPreconnects(QStringList &destinations, QStringList &slts, QStringList &types, QStringList &values)
Allows to retrieve preconnection invocations.