1 // SUPERV SUPERVGUI : GUI for Supervisor component
3 // Copyright (C) 2003 OPEN CASCADE
5 // File : SUPERVGUI_GanvasNodePrs.cxx
6 // Author : Natalia KOPNOVA
9 #include "SUPERVGUI_CanvasLink.h"
10 #include "SUPERVGUI_Canvas.h"
11 #include "SUPERVGUI_CanvasPort.h"
12 #include "SUPERVGUI_Main.h"
17 #include <sys/timeb.h>
20 #define DRAW_COLOR Qt::black
21 #define SELECT_COLOR Qt::magenta
22 #define SKETCH_COLOR Qt::darkGreen
23 #define STREAM_COLOR Qt::darkRed // QColor(0, 64, 128) // Qt::blue
28 SUPERVGUI_CanvasLink::SUPERVGUI_CanvasLink(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV::Link_ptr theLink):
37 if (theLink && !SUPERV_isNull(theLink)) {
38 myLink = SUPERV::Link::_duplicate(theLink);
40 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
41 setName(aCanvas->getLinkName(theLink));
43 myInputPort = aCanvas->getPort(myLink->InPort());
44 if (myInputPort) myInputPort->addLink(this);
46 myOutputPort = aCanvas->getPort(myLink->OutPort());
47 if (myOutputPort) myOutputPort->addLink(this);
49 if (myInputPort->isStream())
50 myColor = STREAM_COLOR;
56 connect(this, SIGNAL(objectCreatedDeleted()), myMain, SLOT(onObjectCreatedDeleted()));
59 SUPERVGUI_CanvasLink::~SUPERVGUI_CanvasLink()
61 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
65 if (myInputPort) myInputPort->removeLink(this);
66 if (myOutputPort) myOutputPort->removeLink(this);
69 void SUPERVGUI_CanvasLink::createPrs()
71 if (myLink && !SUPERV_isNull(myLink)) {
73 addPoint(myInputPort->getConnectionPoint());
75 if (!myMain->getCanvas()->isControlView()) {
77 for (CORBA::Long i = 0; i < myLink->CoordsSize(); i++) {
78 myLink->Coords(i+1, x, y);
79 addPoint(QPoint(x, y), i+1);
83 addPoint(myOutputPort->getConnectionPoint());
86 setColor(myHilighted ? SELECT_COLOR : myColor);
89 void SUPERVGUI_CanvasLink::addPoint(const QPoint& thePoint, const int& theIndex)
91 SUPERVGUI_CanvasPointPrs* aPoint;
93 aPoint = new SUPERVGUI_CanvasPointPrs(myMain->getCanvas(), this, theIndex);
94 aPoint->setColor(myColor);
95 aPoint->move(thePoint.x(), thePoint.y());
98 SUPERVGUI_CanvasPointPrs* aPrev = (SUPERVGUI_CanvasPointPrs*) myPrs.last();
100 SUPERVGUI_CanvasEdgePrs* anEdge = new SUPERVGUI_CanvasEdgePrs(myMain->getCanvas(), this);
101 anEdge->setColor(myColor);
102 myPrs.append(anEdge);
104 aPoint = new SUPERVGUI_CanvasPointPrs(myMain->getCanvas(), this, theIndex);
105 aPoint->setColor(myColor);
106 aPoint->move(thePoint.x(), thePoint.y());
108 aPrev->setOutEdge(anEdge);
109 aPoint->setInEdge(anEdge);
111 myPrs.append(aPoint);
114 void SUPERVGUI_CanvasLink::setSelectedObject(QCanvasItem* theItem, const QPoint& thePoint)
116 mySelectedItem = theItem;
117 mySelectedPoint = thePoint;
120 QPopupMenu* SUPERVGUI_CanvasLink::getPopupMenu(QWidget* theParent)
122 QPopupMenu* popup = new QPopupMenu(theParent);
124 anItem = popup->insertItem(tr("MSG_DELLINK"), this, SLOT(remove()));
126 (myInputPort->getEngine()->Kind() != SUPERV::EndSwitchParameter ||
127 myInputPort->getEngine()->Node()->Kind() != SUPERV::EndSwitchNode))
128 if (myInputPort->getEngine()->Kind() == SUPERV::LoopParameter ||
129 myOutputPort && myOutputPort->getEngine()->Kind() == SUPERV::LoopParameter)
130 popup->setItemEnabled(anItem, false);
132 popup->insertSeparator();
133 if (mySelectedItem) {
134 anItem = popup->insertItem(tr("MSG_ADD_POINT"), this, SLOT(addPoint()));
135 if (mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint)
136 popup->setItemEnabled(anItem, false);
138 anItem = popup->insertItem(tr("MSG_DEL_POINT"), this, SLOT(removePoint()));
139 if (mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge)
140 popup->setItemEnabled(anItem, false);
145 void SUPERVGUI_CanvasLink::show()
147 if (myPrs.isEmpty()) createPrs();
149 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
154 void SUPERVGUI_CanvasLink::merge()
156 // remove old presentation
157 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
166 void SUPERVGUI_CanvasLink::setHilighted(bool state)
169 setColor(myHilighted ? SELECT_COLOR : myColor);
170 if (!myPrs.isEmpty()) {
171 bool disp = myPrs.first()->isVisible();
173 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
174 (*it)->hide(); (*it)->show();
176 myMain->getCanvas()->update();
181 void SUPERVGUI_CanvasLink::moveByPort(SUPERVGUI_CanvasPort* thePort, int dx, int dy)
183 if (myInputPort && myInputPort == thePort) {
184 myPrs.first()->moveBy(dx, dy);
187 if (myOutputPort && myOutputPort == thePort) {
188 myPrs.last()->moveBy(dx, dy);
193 void SUPERVGUI_CanvasLink::moveByPort(SUPERVGUI_CanvasPort* thePort)
195 QPoint p = thePort->getConnectionPoint();
196 if (myInputPort && myInputPort == thePort) {
197 myPrs.first()->move(p.x(), p.y());
200 if (myOutputPort && myOutputPort == thePort) {
201 myPrs.last()->move(p.x(), p.y());
206 void SUPERVGUI_CanvasLink::setColor(const QColor& theColor)
208 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
209 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
210 ((SUPERVGUI_CanvasPointPrs*)(*it))->setColor(theColor);
212 else if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
213 ((SUPERVGUI_CanvasEdgePrs*)(*it))->setColor(theColor);
218 void SUPERVGUI_CanvasLink::remove() {
219 // IPAL9369 : check the dataflow readiness to modify
220 if ( !myMain->ReadyToModify() ) // null dataflow or executing, ..
223 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
226 SUPERVGUI_CanvasPortIn* aPort = 0;
227 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
228 if (myLink && !SUPERV_isNull(myLink)) {
230 if (myInputPort->getEngine()->IsParam() || myInputPort->getEngine()->IsInLine()) {
231 aValue = QString(myInputPort->getEngine()->ToString());
232 aPort = (SUPERVGUI_CanvasPortIn*) myInputPort;
237 emit objectCreatedDeleted(); // mkr : PAL8237
241 if (aPort && !aValue.isEmpty() && myMain->getDataflow()->GraphLevel() == 0) {
242 aPort->setValue(aValue);
247 void SUPERVGUI_CanvasLink::addPoint() {
248 if (mySelectedItem && mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
249 SUPERVGUI_CanvasEdgePrs* anEdge = (SUPERVGUI_CanvasEdgePrs*) mySelectedItem;
252 QCanvasItemList::Iterator it;
253 for (it = myPrs.begin(); it != myPrs.end(); ++it) {
254 if ((*it) == anEdge) break;
256 if (it != myPrs.begin()) {
258 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
259 anIndex = aPoint->getIndex()+1;
260 if (anIndex < 1) anIndex = 1;
262 if (myLink && !SUPERV_isNull(myLink)) {
263 myLink->AddCoord(anIndex, mySelectedPoint.x(), mySelectedPoint.y());
264 emit objectCreatedDeleted(); // mkr : PAL8237
267 myMain->getCanvas()->update();
271 void SUPERVGUI_CanvasLink::removePoint() {
272 if (mySelectedItem && mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
273 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) mySelectedItem;
274 if (myLink && !SUPERV_isNull(myLink)) {
275 myLink->RemoveCoord(aPoint->getIndex());
276 emit objectCreatedDeleted(); // mkr : PAL8237
279 myMain->getCanvas()->update();
283 QString SUPERVGUI_CanvasLink::getToolTipText() const {
285 if (myInputPort && myOutputPort)
286 aTTT = myOutputPort->getEngine()->Node()->Name() + QString(" : ") +
287 myOutputPort->getEngine()->Name() + QString(" => ") +
288 myInputPort->getEngine()->Node()->Name() + QString(" : ") +
289 myInputPort->getEngine()->Name();
294 //===============================================================================
295 // SUPERVGUI_CanvasStreamLink: new link to be created
296 //===============================================================================
297 SUPERVGUI_CanvasStreamLink::SUPERVGUI_CanvasStreamLink(QObject* theParent, SUPERVGUI_Main* theMain,
298 SUPERV::StreamLink_ptr theLink):
299 SUPERVGUI_CanvasLink(theParent, theMain, theLink)
301 if (theLink && !SUPERV_isNull(theLink)) {
302 myStreamLink = SUPERV::StreamLink::_duplicate(theLink);
307 void SUPERVGUI_CanvasStreamLink::remove() {
309 SUPERVGUI_CanvasPortIn* aPort = 0;
310 SUPERVGUI_Canvas* aCanvas = getMain()->getCanvas();
311 if (myStreamLink && !SUPERV_isNull(myStreamLink)) {
312 if (getInputPort()) {
313 if (getInputPort()->getEngine()->IsParam() || getInputPort()->getEngine()->IsInLine()) {
314 aPort = (SUPERVGUI_CanvasPortIn*) getInputPort();
315 aValue = QString(aPort->getEngine()->ToString());
318 myStreamLink->destroy();
321 if (aPort && !aValue.isEmpty()) {
322 aPort->setValue(aValue);
328 //===============================================================================
329 // SUPERVGUI_CanvasLinkBuilder: new link to be created
330 //===============================================================================
331 SUPERVGUI_CanvasLinkBuilder::SUPERVGUI_CanvasLinkBuilder(QObject* theParent, SUPERVGUI_Main* theMain,
332 SUPERVGUI_CanvasPort* thePort):
333 SUPERVGUI_CanvasLink(theParent, theMain),
338 myPort->addLink(this);
339 addPoint(myPort->getConnectionPoint());
341 myColor = SKETCH_COLOR;
344 SUPERVGUI_CanvasLinkBuilder::~SUPERVGUI_CanvasLinkBuilder()
346 if (myFloatingEdge) delete myFloatingEdge;
347 if (myPort) myPort->removeLink(this);
350 bool SUPERVGUI_CanvasLinkBuilder::canCreateEngine(SUPERVGUI_CanvasPort* thePort)
352 if (thePort && myPort) {
353 SUPERVGUI_CanvasPort* aInPort;
354 SUPERVGUI_CanvasPort* aOutPort;
356 // check if ports are couple of input and output
357 if (myPort->getEngine()->IsInput()) {
359 if (thePort->getEngine()->IsInput())
365 if (!thePort->getEngine()->IsInput())
370 // control if nodes are different, not the same node
371 QString aInNode(aInPort->getEngine()->Node()->Name());
372 QString aOutNode(aOutPort->getEngine()->Node()->Name());
373 if (aInNode.compare(aOutNode) == 0) // linking outport and inport of the same node
376 // control types of ports
377 int aInKind = aInPort->getEngine()->Kind();
378 int aOutKind = aOutPort->getEngine()->Kind();
380 // connect stream port with stream port only
381 if ((aInKind == SUPERV::DataStreamParameter && aOutKind != SUPERV::DataStreamParameter) ||
382 (aOutKind == SUPERV::DataStreamParameter && aInKind != SUPERV::DataStreamParameter))
385 // asv : 15.12.04 : NOT allow to connect Gate-to-InLine --> it does not make sence!
386 // Out Gate port can be connected only to In Gate port
387 if ( aOutKind == SUPERV::GateParameter && aInKind != SUPERV::GateParameter )
390 // In Gate can be connected to (receive links from) Gate port and InLine ports (important for Switch nodes)
391 if ( aInKind == SUPERV::GateParameter && aOutKind != SUPERV::GateParameter && aOutKind != SUPERV::InLineParameter )
394 // asv : 15.12.04 : PAL7374, p.2.2 "Bugs and Improvements": multiple links into Gate port
395 // for InGate it's OK to accept more than 1 link
396 // THESE NEEDS REVISION, ALSO DON'T ALLOW MANY LINKS TO "DEFAULT" PORT OF EndSwitch
397 //if ( aInPort->getEngine()->IsLinked() && aInKind != SUPERV::GateParameter )
399 // control if port is already linked except for input inline ports of end switch node (check for EndSwitchParameter)
400 // and "Default" port of Switch node (check for aNode->isEndSwitch()). "Default" port is linked by default, but we
401 // let it to be "re-linked" to another port.
402 const bool isEndSwitch = ( aInKind == SUPERV::EndSwitchParameter || aInPort->getEngine()->Node()->IsEndSwitch() );
403 if ( !isEndSwitch && aInPort->getEngine()->IsLinked() )
411 void SUPERVGUI_CanvasLinkBuilder::setCoords(SUPERV::Link_ptr theLink)
414 QCanvasItemList::Iterator it;
416 if (myPort->getEngine()->IsInput()) {
417 it = myPrs.begin(); ++it; // ignore the first point
418 for (; it != myPrs.end(); ++it) {
419 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
420 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
425 it = myPrs.end(); --it;
426 for (; it != myPrs.begin(); --it) {
427 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
428 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
435 void SUPERVGUI_CanvasLinkBuilder::addNextPoint(const QPoint& thePoint, bool theOrtho)
437 if (myFloatingEdge) myFloatingEdge->hide();
439 if (!theOrtho || myPrs.empty()) {
443 SUPERVGUI_CanvasPointPrs* aPrev = (SUPERVGUI_CanvasPointPrs*) myPrs.last();
444 int x = (int)aPrev->x(); int y = (int)aPrev->y();
445 if (thePoint.x() != x && thePoint.y() != y) {
446 addPoint(QPoint(thePoint.x(), y), -2);
453 void SUPERVGUI_CanvasLinkBuilder::setFloatPoint(const QPoint& thePoint)
455 if (!myFloatingEdge) {
456 myFloatingEdge = new QCanvasLine(getMain()->getCanvas());
457 myFloatingEdge->setPen(QPen(myColor, LINE_WIDTH));
459 if (!myPrs.empty()) {
460 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
461 thePoint.x(), thePoint.y());
462 myFloatingEdge->show();
466 void SUPERVGUI_CanvasLinkBuilder::removeLastPoint()
468 if (myPrs.count() > 1) {
469 QPoint aLast((int)myPrs.last()->x(), (int)myPrs.last()->y());
470 QCanvasItemList::Iterator it = myPrs.end();
471 bool removed = false;
473 for (; it != myPrs.begin(); --it) {
474 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
475 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
476 if (aPoint->getIndex() == -1 && removed) break;
478 QCanvasItem* anItem = (*it);
479 it = myPrs.remove(it);
484 if (myFloatingEdge) {
485 QPoint aPoint = myFloatingEdge->endPoint();
486 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
487 aPoint.x(), aPoint.y());
490 setFloatPoint(aLast);
495 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort, int dx, int dy)
497 if (myPort && myPort == thePort) {
498 myPrs.first()->moveBy(dx, dy);
503 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort)
505 QPoint p = thePort->getConnectionPoint();
506 if (myPort && myPort == thePort) {
507 myPrs.first()->move(p.x(), p.y());
513 //===============================================================================
514 // SUPERVGUI_CanvasPointPrs: link point presentation
515 //===============================================================================
516 SUPERVGUI_CanvasPointPrs::SUPERVGUI_CanvasPointPrs(QCanvas* theCanvas,
517 SUPERVGUI_CanvasLink* theLink,
518 const int& theIndex):
519 QCanvasEllipse(theCanvas),
520 myLink(theLink), myIndex(theIndex),
521 myInEdge(0), myOutEdge(0), myMoving(false)
523 setSize(POINT_SIZE, POINT_SIZE);
527 int SUPERVGUI_CanvasPointPrs::rtti() const
529 return SUPERVGUI_Canvas::Rtti_LinkPoint;
532 void SUPERVGUI_CanvasPointPrs::setInEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
535 theEdge->setFromPoint(this);
538 void SUPERVGUI_CanvasPointPrs::setOutEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
541 theEdge->setToPoint(this);
544 void SUPERVGUI_CanvasPointPrs::moveBy(double dx, double dy)
546 QCanvasEllipse::moveBy(dx, dy);
547 if (myInEdge) myInEdge->setFromPoint(this);
548 if (myOutEdge) myOutEdge->setToPoint(this);
549 //resize canvas view if mouse is outside
550 int w = (int)(x()+dx) + width() + GRAPH_MARGIN;
551 int h = (int)(y()+dy) + height() + GRAPH_MARGIN;
552 if (canvas()->width() > w) w = canvas()->width();
553 if (canvas()->height() > h) h = canvas()->height();
554 if (canvas()->width() < w || canvas()->height() < h) canvas()->resize(w, h);
555 if (myIndex > 0 && isMoving()) {
556 myLink->getEngine()->ChangeCoord(myIndex, (int)x(), (int)y());
560 void SUPERVGUI_CanvasPointPrs::setColor(const QColor& theColor)
565 //===============================================================================
566 // SUPERVGUI_CanvasEdgePrs: link edge presentation
567 //===============================================================================
568 SUPERVGUI_CanvasEdgePrs::SUPERVGUI_CanvasEdgePrs(QCanvas* theCanvas,
569 SUPERVGUI_CanvasLink* theLink):
570 QCanvasLine(theCanvas),
576 int SUPERVGUI_CanvasEdgePrs::rtti() const
578 return SUPERVGUI_Canvas::Rtti_LinkEdge;
581 void SUPERVGUI_CanvasEdgePrs::setFromPoint(SUPERVGUI_CanvasPointPrs* thePoint)
583 myStartPoint = thePoint;
584 setPoints((int)(thePoint->x()), (int)(thePoint->y()), endPoint().x(), endPoint().y());
587 void SUPERVGUI_CanvasEdgePrs::setToPoint(SUPERVGUI_CanvasPointPrs* thePoint)
589 myEndPoint = thePoint;
590 setPoints(startPoint().x(), startPoint().y(), (int)(thePoint->x()), (int)(thePoint->y()));
593 void SUPERVGUI_CanvasEdgePrs::setColor(const QColor& theColor)
595 setPen(QPen(theColor, LINE_WIDTH));
598 void SUPERVGUI_CanvasEdgePrs::moveBy(double dx, double dy)
600 //mkr: for moving segment of link
601 if (myStartPoint && myEndPoint) {
602 myStartPoint->setMoving(true);
603 myStartPoint->moveBy(dx, dy);
605 myEndPoint->setMoving(true);
606 myEndPoint->moveBy(dx,dy);