1 // SUPERV SUPERVGUI : GUI for Supervisor component
3 // Copyright (C) 2003 OPEN CASCADE
5 // File : SUPERVGUI_GanvasNodePrs.cxx
6 // Author : Natalia KOPNOVA
10 #include "SUPERVGUI_CanvasLink.h"
11 #include "SUPERVGUI_Canvas.h"
12 #include "SUPERVGUI_CanvasPort.h"
13 #include "SUPERVGUI_Main.h"
18 #include <sys/timeb.h>
21 #define DRAW_COLOR Qt::black
22 #define SELECT_COLOR Qt::magenta
23 #define SKETCH_COLOR Qt::darkGreen
24 #define STREAM_COLOR Qt::darkRed // QColor(0, 64, 128) // Qt::blue
29 SUPERVGUI_CanvasLink::SUPERVGUI_CanvasLink(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV::Link_ptr theLink):
38 if (theLink && !SUPERV_isNull(theLink)) {
39 myLink = SUPERV::Link::_duplicate(theLink);
41 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
42 setName(aCanvas->getLinkName(theLink));
44 myInputPort = aCanvas->getPort(myLink->InPort());
45 if (myInputPort) myInputPort->addLink(this);
47 myOutputPort = aCanvas->getPort(myLink->OutPort());
48 if (myOutputPort) myOutputPort->addLink(this);
50 if (myInputPort->isStream())
51 myColor = STREAM_COLOR;
57 SUPERVGUI_CanvasLink::~SUPERVGUI_CanvasLink()
59 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
63 if (myInputPort) myInputPort->removeLink(this);
64 if (myOutputPort) myOutputPort->removeLink(this);
67 void SUPERVGUI_CanvasLink::createPrs()
69 if (myLink && !SUPERV_isNull(myLink)) {
71 addPoint(myInputPort->getConnectionPoint());
73 if (!myMain->getCanvas()->isControlView()) {
75 for (int i = 0; i < myLink->CoordsSize(); i++) {
76 myLink->Coords(i+1, x, y);
77 addPoint(QPoint(x, y), i+1);
81 addPoint(myOutputPort->getConnectionPoint());
84 setColor(myHilighted ? SELECT_COLOR : myColor);
87 void SUPERVGUI_CanvasLink::addPoint(const QPoint& thePoint, const int& theIndex)
89 SUPERVGUI_CanvasPointPrs* aPoint;
91 aPoint = new SUPERVGUI_CanvasPointPrs(myMain->getCanvas(), this, theIndex);
92 aPoint->setColor(myColor);
93 aPoint->move(thePoint.x(), thePoint.y());
96 SUPERVGUI_CanvasPointPrs* aPrev = (SUPERVGUI_CanvasPointPrs*) myPrs.last();
98 SUPERVGUI_CanvasEdgePrs* anEdge = new SUPERVGUI_CanvasEdgePrs(myMain->getCanvas(), this);
99 anEdge->setColor(myColor);
100 myPrs.append(anEdge);
102 aPoint = new SUPERVGUI_CanvasPointPrs(myMain->getCanvas(), this, theIndex);
103 aPoint->setColor(myColor);
104 aPoint->move(thePoint.x(), thePoint.y());
106 aPrev->setOutEdge(anEdge);
107 aPoint->setInEdge(anEdge);
109 myPrs.append(aPoint);
112 void SUPERVGUI_CanvasLink::setSelectedObject(QCanvasItem* theItem, const QPoint& thePoint)
114 mySelectedItem = theItem;
115 mySelectedPoint = thePoint;
118 QPopupMenu* SUPERVGUI_CanvasLink::getPopupMenu(QWidget* theParent)
120 QPopupMenu* popup = new QPopupMenu(theParent);
122 anItem = popup->insertItem(tr("MSG_DELLINK"), this, SLOT(remove()));
124 (myInputPort->getEngine()->Kind() != SUPERV::EndSwitchParameter ||
125 myInputPort->getEngine()->Node()->Kind() != SUPERV::EndSwitchNode))
126 if (myInputPort->getEngine()->Kind() == SUPERV::LoopParameter ||
127 myOutputPort && myOutputPort->getEngine()->Kind() == SUPERV::LoopParameter)
128 popup->setItemEnabled(anItem, false);
130 popup->insertSeparator();
131 if (mySelectedItem) {
132 anItem = popup->insertItem(tr("MSG_ADD_POINT"), this, SLOT(addPoint()));
133 if (mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint)
134 popup->setItemEnabled(anItem, false);
136 anItem = popup->insertItem(tr("MSG_DEL_POINT"), this, SLOT(removePoint()));
137 if (mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge)
138 popup->setItemEnabled(anItem, false);
143 void SUPERVGUI_CanvasLink::show()
145 if (myPrs.isEmpty()) createPrs();
147 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
152 void SUPERVGUI_CanvasLink::merge()
154 // remove old presentation
155 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
164 void SUPERVGUI_CanvasLink::setHilighted(bool state)
167 setColor(myHilighted ? SELECT_COLOR : myColor);
168 if (!myPrs.isEmpty()) {
169 bool disp = myPrs.first()->isVisible();
171 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
172 (*it)->hide(); (*it)->show();
174 myMain->getCanvas()->update();
179 void SUPERVGUI_CanvasLink::moveByPort(SUPERVGUI_CanvasPort* thePort, int dx, int dy)
181 if (myInputPort && myInputPort == thePort) {
182 myPrs.first()->moveBy(dx, dy);
185 if (myOutputPort && myOutputPort == thePort) {
186 myPrs.last()->moveBy(dx, dy);
191 void SUPERVGUI_CanvasLink::moveByPort(SUPERVGUI_CanvasPort* thePort)
193 QPoint p = thePort->getConnectionPoint();
194 if (myInputPort && myInputPort == thePort) {
195 myPrs.first()->move(p.x(), p.y());
198 if (myOutputPort && myOutputPort == thePort) {
199 myPrs.last()->move(p.x(), p.y());
204 void SUPERVGUI_CanvasLink::setColor(const QColor& theColor)
206 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
207 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
208 ((SUPERVGUI_CanvasPointPrs*)(*it))->setColor(theColor);
210 else if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
211 ((SUPERVGUI_CanvasEdgePrs*)(*it))->setColor(theColor);
216 void SUPERVGUI_CanvasLink::remove() {
217 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
220 SUPERVGUI_CanvasPortIn* aPort = 0;
221 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
222 if (myLink && !SUPERV_isNull(myLink)) {
224 if (myInputPort->getEngine()->IsParam() || myInputPort->getEngine()->IsInLine()) {
225 aValue = QString(myInputPort->getEngine()->ToString());
226 aPort = (SUPERVGUI_CanvasPortIn*) myInputPort;
232 if (aPort && !aValue.isEmpty() && myMain->getDataflow()->GraphLevel() == 0) {
233 aPort->setValue(aValue);
238 void SUPERVGUI_CanvasLink::addPoint() {
239 if (mySelectedItem && mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
240 SUPERVGUI_CanvasEdgePrs* anEdge = (SUPERVGUI_CanvasEdgePrs*) mySelectedItem;
243 QCanvasItemList::Iterator it;
244 for (it = myPrs.begin(); it != myPrs.end(); ++it) {
245 if ((*it) == anEdge) break;
247 if (it != myPrs.begin()) {
249 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
250 anIndex = aPoint->getIndex()+1;
251 if (anIndex < 1) anIndex = 1;
253 if (myLink && !SUPERV_isNull(myLink))
254 myLink->AddCoord(anIndex, mySelectedPoint.x(), mySelectedPoint.y());
256 myMain->getCanvas()->update();
260 void SUPERVGUI_CanvasLink::removePoint() {
261 if (mySelectedItem && mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
262 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) mySelectedItem;
263 if (myLink && !SUPERV_isNull(myLink))
264 myLink->RemoveCoord(aPoint->getIndex());
266 myMain->getCanvas()->update();
271 //===============================================================================
272 // SUPERVGUI_CanvasStreamLink: new link to be created
273 //===============================================================================
274 SUPERVGUI_CanvasStreamLink::SUPERVGUI_CanvasStreamLink(QObject* theParent, SUPERVGUI_Main* theMain,
275 SUPERV::StreamLink_ptr theLink):
276 SUPERVGUI_CanvasLink(theParent, theMain, theLink)
278 if (theLink && !SUPERV_isNull(theLink)) {
279 myStreamLink = SUPERV::StreamLink::_duplicate(theLink);
284 void SUPERVGUI_CanvasStreamLink::remove() {
286 SUPERVGUI_CanvasPortIn* aPort = 0;
287 SUPERVGUI_Canvas* aCanvas = getMain()->getCanvas();
288 if (myStreamLink && !SUPERV_isNull(myStreamLink)) {
289 if (getInputPort()) {
290 if (getInputPort()->getEngine()->IsParam() || getInputPort()->getEngine()->IsInLine()) {
291 aPort = (SUPERVGUI_CanvasPortIn*) getInputPort();
292 aValue = QString(aPort->getEngine()->ToString());
295 myStreamLink->destroy();
298 if (aPort && !aValue.isEmpty()) {
299 aPort->setValue(aValue);
305 //===============================================================================
306 // SUPERVGUI_CanvasLinkBuilder: new link to be created
307 //===============================================================================
308 SUPERVGUI_CanvasLinkBuilder::SUPERVGUI_CanvasLinkBuilder(QObject* theParent, SUPERVGUI_Main* theMain,
309 SUPERVGUI_CanvasPort* thePort):
310 SUPERVGUI_CanvasLink(theParent, theMain),
315 myPort->addLink(this);
316 addPoint(myPort->getConnectionPoint());
318 myColor = SKETCH_COLOR;
321 SUPERVGUI_CanvasLinkBuilder::~SUPERVGUI_CanvasLinkBuilder()
323 if (myFloatingEdge) delete myFloatingEdge;
324 if (myPort) myPort->removeLink(this);
327 bool SUPERVGUI_CanvasLinkBuilder::canCreateEngine(SUPERVGUI_CanvasPort* thePort)
330 if (thePort && myPort) {
331 SUPERVGUI_CanvasPort* aInPort;
332 SUPERVGUI_CanvasPort* aOutPort;
334 // check if ports are couple of input and output
335 if (myPort->getEngine()->IsInput()) {
337 if (thePort->getEngine()->IsInput())
343 if (!thePort->getEngine()->IsInput())
348 // control if node is different
349 QString aInNode(aInPort->getEngine()->Node()->Name());
350 QString aOutNode(aOutPort->getEngine()->Node()->Name());
351 if (aInNode.compare(aOutNode) == 0)
354 // control if no port is "Default"
355 QString aInName(aInPort->getEngine()->Name());
356 QString aOutName(aOutPort->getEngine()->Name());
357 if (aInName.compare("Default") == 0 ||
358 aOutName.compare("Default") == 0)
361 // control types of ports
362 int aInKind = aInPort->getEngine()->Kind();
363 int aOutKind = aOutPort->getEngine()->Kind();
365 // connect stream port with stream port only
366 if ((aInKind == SUPERV::DataStreamParameter && aOutKind != SUPERV::DataStreamParameter) ||
367 (aOutKind == SUPERV::DataStreamParameter && aInKind != SUPERV::DataStreamParameter))
370 // asv : 15.12.04 : NOT allow to connect Gate-to-InLine --> it does not make sence!
371 // Out Gate port can be connected only to In Gate port
372 if ( aOutKind == SUPERV::GateParameter && aInKind != SUPERV::GateParameter )
375 // In Gate can be connected to (receive links from) Gate port and InLine ports (important for Switch nodes)
376 if ( aInKind == SUPERV::GateParameter && aOutKind != SUPERV::GateParameter && aOutKind != SUPERV::InLineParameter )
379 // control if port is already linked except for input port of end switch node
380 if (!(aInKind == SUPERV::EndSwitchParameter ||
381 aInPort->getEngine()->Node()->Kind() == SUPERV::EndSwitchNode)) {
382 // asv : 15.12.04 : PAL7374, p.2.2 "Bugs and Improvements": multiple links into Gate port
383 // for InGate it's OK to accept more than 1 link
384 if ( aInPort->getEngine()->IsLinked() && aInKind != SUPERV::GateParameter )
393 void SUPERVGUI_CanvasLinkBuilder::setCoords(SUPERV::Link_ptr theLink)
396 QCanvasItemList::Iterator it;
398 if (myPort->getEngine()->IsInput()) {
399 it = myPrs.begin(); ++it; // ignore the first point
400 for (; it != myPrs.end(); ++it) {
401 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
402 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
407 it = myPrs.end(); --it;
408 for (; it != myPrs.begin(); --it) {
409 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
410 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
417 void SUPERVGUI_CanvasLinkBuilder::addNextPoint(const QPoint& thePoint, bool theOrtho)
419 if (myFloatingEdge) myFloatingEdge->hide();
421 if (!theOrtho || myPrs.empty()) {
425 SUPERVGUI_CanvasPointPrs* aPrev = (SUPERVGUI_CanvasPointPrs*) myPrs.last();
426 int x = (int)aPrev->x(); int y = (int)aPrev->y();
427 if (thePoint.x() != x && thePoint.y() != y) {
428 addPoint(QPoint(thePoint.x(), y), -2);
435 void SUPERVGUI_CanvasLinkBuilder::setFloatPoint(const QPoint& thePoint)
437 if (!myFloatingEdge) {
438 myFloatingEdge = new QCanvasLine(getMain()->getCanvas());
439 myFloatingEdge->setPen(QPen(myColor, LINE_WIDTH));
441 if (!myPrs.empty()) {
442 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
443 thePoint.x(), thePoint.y());
444 myFloatingEdge->show();
448 void SUPERVGUI_CanvasLinkBuilder::removeLastPoint()
450 if (myPrs.count() > 1) {
451 QPoint aLast((int)myPrs.last()->x(), (int)myPrs.last()->y());
452 QCanvasItemList::Iterator it = myPrs.end();
453 bool removed = false;
455 for (; it != myPrs.begin(); --it) {
456 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
457 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
458 if (aPoint->getIndex() == -1 && removed) break;
460 QCanvasItem* anItem = (*it);
461 it = myPrs.remove(it);
466 if (myFloatingEdge) {
467 QPoint aPoint = myFloatingEdge->endPoint();
468 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
469 aPoint.x(), aPoint.y());
472 setFloatPoint(aLast);
477 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort, int dx, int dy)
479 if (myPort && myPort == thePort) {
480 myPrs.first()->moveBy(dx, dy);
485 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort)
487 QPoint p = thePort->getConnectionPoint();
488 if (myPort && myPort == thePort) {
489 myPrs.first()->move(p.x(), p.y());
495 //===============================================================================
496 // SUPERVGUI_CanvasPointPrs: link point presentation
497 //===============================================================================
498 SUPERVGUI_CanvasPointPrs::SUPERVGUI_CanvasPointPrs(QCanvas* theCanvas,
499 SUPERVGUI_CanvasLink* theLink,
500 const int& theIndex):
501 QCanvasEllipse(theCanvas),
502 myLink(theLink), myIndex(theIndex),
503 myInEdge(0), myOutEdge(0), myMoving(false)
505 setSize(POINT_SIZE, POINT_SIZE);
509 int SUPERVGUI_CanvasPointPrs::rtti() const
511 return SUPERVGUI_Canvas::Rtti_LinkPoint;
514 void SUPERVGUI_CanvasPointPrs::setInEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
517 theEdge->setFromPoint(this);
520 void SUPERVGUI_CanvasPointPrs::setOutEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
523 theEdge->setToPoint(this);
526 void SUPERVGUI_CanvasPointPrs::moveBy(double dx, double dy)
528 QCanvasEllipse::moveBy(dx, dy);
529 if (myInEdge) myInEdge->setFromPoint(this);
530 if (myOutEdge) myOutEdge->setToPoint(this);
531 //resize canvas view if mouse is outside
532 int w = (int)(x()+dx) + width() + GRAPH_MARGIN;
533 int h = (int)(y()+dy) + height() + GRAPH_MARGIN;
534 if (canvas()->width() > w) w = canvas()->width();
535 if (canvas()->height() > h) h = canvas()->height();
536 if (canvas()->width() < w || canvas()->height() < h) canvas()->resize(w, h);
537 if (myIndex > 0 && isMoving()) {
538 myLink->getEngine()->ChangeCoord(myIndex, (int)x(), (int)y());
542 void SUPERVGUI_CanvasPointPrs::setColor(const QColor& theColor)
547 //===============================================================================
548 // SUPERVGUI_CanvasEdgePrs: link edge presentation
549 //===============================================================================
550 SUPERVGUI_CanvasEdgePrs::SUPERVGUI_CanvasEdgePrs(QCanvas* theCanvas,
551 SUPERVGUI_CanvasLink* theLink):
552 QCanvasLine(theCanvas),
558 int SUPERVGUI_CanvasEdgePrs::rtti() const
560 return SUPERVGUI_Canvas::Rtti_LinkEdge;
563 void SUPERVGUI_CanvasEdgePrs::setFromPoint(SUPERVGUI_CanvasPointPrs* thePoint)
565 myStartPoint = thePoint;
566 setPoints((int)(thePoint->x()), (int)(thePoint->y()), endPoint().x(), endPoint().y());
569 void SUPERVGUI_CanvasEdgePrs::setToPoint(SUPERVGUI_CanvasPointPrs* thePoint)
571 myEndPoint = thePoint;
572 setPoints(startPoint().x(), startPoint().y(), (int)(thePoint->x()), (int)(thePoint->y()));
575 void SUPERVGUI_CanvasEdgePrs::setColor(const QColor& theColor)
577 setPen(QPen(theColor, LINE_WIDTH));
580 void SUPERVGUI_CanvasEdgePrs::moveBy(double dx, double dy)
582 //mkr: for moving segment of link
583 if (myStartPoint && myEndPoint) {
584 myStartPoint->setMoving(true);
585 myStartPoint->moveBy(dx, dy);
587 myEndPoint->setMoving(true);
588 myEndPoint->moveBy(dx,dy);