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 // connect gate port with gate or inline port
371 if (aInKind == SUPERV::GateParameter || aOutKind == SUPERV::GateParameter) {
372 if (aInKind != aOutKind &&
373 aInKind != SUPERV::InLineParameter &&
374 aOutKind != SUPERV::InLineParameter)
378 // control if port is already linked except for input port of end switch node
379 if (!(aInKind == SUPERV::EndSwitchParameter ||
380 aInPort->getEngine()->Node()->Kind() == SUPERV::EndSwitchNode)) {
381 if (aInPort->getEngine()->IsLinked())
389 void SUPERVGUI_CanvasLinkBuilder::setCoords(SUPERV::Link_ptr theLink)
392 QCanvasItemList::Iterator it;
394 if (myPort->getEngine()->IsInput()) {
395 it = myPrs.begin(); ++it; // ignore the first point
396 for (; it != myPrs.end(); ++it) {
397 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
398 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
403 it = myPrs.end(); --it;
404 for (; it != myPrs.begin(); --it) {
405 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
406 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
413 void SUPERVGUI_CanvasLinkBuilder::addNextPoint(const QPoint& thePoint, bool theOrtho)
415 if (myFloatingEdge) myFloatingEdge->hide();
417 if (!theOrtho || myPrs.empty()) {
421 SUPERVGUI_CanvasPointPrs* aPrev = (SUPERVGUI_CanvasPointPrs*) myPrs.last();
422 int x = (int)aPrev->x(); int y = (int)aPrev->y();
423 if (thePoint.x() != x && thePoint.y() != y) {
424 addPoint(QPoint(thePoint.x(), y), -2);
431 void SUPERVGUI_CanvasLinkBuilder::setFloatPoint(const QPoint& thePoint)
433 if (!myFloatingEdge) {
434 myFloatingEdge = new QCanvasLine(getMain()->getCanvas());
435 myFloatingEdge->setPen(QPen(myColor, LINE_WIDTH));
437 if (!myPrs.empty()) {
438 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
439 thePoint.x(), thePoint.y());
440 myFloatingEdge->show();
444 void SUPERVGUI_CanvasLinkBuilder::removeLastPoint()
446 if (myPrs.count() > 1) {
447 QPoint aLast((int)myPrs.last()->x(), (int)myPrs.last()->y());
448 QCanvasItemList::Iterator it = myPrs.end();
449 bool removed = false;
451 for (; it != myPrs.begin(); --it) {
452 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
453 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
454 if (aPoint->getIndex() == -1 && removed) break;
456 QCanvasItem* anItem = (*it);
457 it = myPrs.remove(it);
462 if (myFloatingEdge) {
463 QPoint aPoint = myFloatingEdge->endPoint();
464 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
465 aPoint.x(), aPoint.y());
468 setFloatPoint(aLast);
473 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort, int dx, int dy)
475 if (myPort && myPort == thePort) {
476 myPrs.first()->moveBy(dx, dy);
481 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort)
483 QPoint p = thePort->getConnectionPoint();
484 if (myPort && myPort == thePort) {
485 myPrs.first()->move(p.x(), p.y());
491 //===============================================================================
492 // SUPERVGUI_CanvasPointPrs: link point presentation
493 //===============================================================================
494 SUPERVGUI_CanvasPointPrs::SUPERVGUI_CanvasPointPrs(QCanvas* theCanvas,
495 SUPERVGUI_CanvasLink* theLink,
496 const int& theIndex):
497 QCanvasEllipse(theCanvas),
498 myLink(theLink), myIndex(theIndex),
499 myInEdge(0), myOutEdge(0), myMoving(false)
501 setSize(POINT_SIZE, POINT_SIZE);
505 int SUPERVGUI_CanvasPointPrs::rtti() const
507 return SUPERVGUI_Canvas::Rtti_LinkPoint;
510 void SUPERVGUI_CanvasPointPrs::setInEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
513 theEdge->setFromPoint((int)x(), (int)y());
516 void SUPERVGUI_CanvasPointPrs::setOutEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
519 theEdge->setToPoint((int)x(), (int)y());
522 void SUPERVGUI_CanvasPointPrs::moveBy(double dx, double dy)
524 QCanvasEllipse::moveBy(dx, dy);
525 if (myInEdge) myInEdge->setFromPoint((int)x(), (int)y());
526 if (myOutEdge) myOutEdge->setToPoint((int)x(), (int)y());
527 //resize canvas view if mouse is outside
528 int w = (int)(x()+dx) + width() + GRAPH_MARGIN;
529 int h = (int)(y()+dy) + height() + GRAPH_MARGIN;
530 if (canvas()->width() > w) w = canvas()->width();
531 if (canvas()->height() > h) h = canvas()->height();
532 if (canvas()->width() < w || canvas()->height() < h) canvas()->resize(w, h);
533 if (myIndex > 0 && isMoving()) {
534 myLink->getEngine()->ChangeCoord(myIndex, (int)x(), (int)y());
538 void SUPERVGUI_CanvasPointPrs::setColor(const QColor& theColor)
543 //===============================================================================
544 // SUPERVGUI_CanvasEdgePrs: link edge presentation
545 //===============================================================================
546 SUPERVGUI_CanvasEdgePrs::SUPERVGUI_CanvasEdgePrs(QCanvas* theCanvas,
547 SUPERVGUI_CanvasLink* theLink):
548 QCanvasLine(theCanvas),
554 int SUPERVGUI_CanvasEdgePrs::rtti() const
556 return SUPERVGUI_Canvas::Rtti_LinkEdge;
559 void SUPERVGUI_CanvasEdgePrs::setFromPoint(int x, int y)
561 setPoints(x, y, endPoint().x(), endPoint().y());
564 void SUPERVGUI_CanvasEdgePrs::setToPoint(int x, int y)
566 setPoints(startPoint().x(), startPoint().y(), x, y);
569 void SUPERVGUI_CanvasEdgePrs::setColor(const QColor& theColor)
571 setPen(QPen(theColor, LINE_WIDTH));