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() {
218 SUPERVGUI_CanvasPortIn* aPort = 0;
219 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
220 if (myLink && !SUPERV_isNull(myLink)) {
222 if (myInputPort->getEngine()->IsParam() || myInputPort->getEngine()->IsInLine()) {
223 aValue = QString(myInputPort->getEngine()->ToString());
224 aPort = (SUPERVGUI_CanvasPortIn*) myInputPort;
230 if (aPort && !aValue.isEmpty() && myMain->getDataflow()->GraphLevel() == 0) {
231 aPort->setValue(aValue);
236 void SUPERVGUI_CanvasLink::addPoint() {
237 if (mySelectedItem && mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
238 SUPERVGUI_CanvasEdgePrs* anEdge = (SUPERVGUI_CanvasEdgePrs*) mySelectedItem;
241 QCanvasItemList::Iterator it;
242 for (it = myPrs.begin(); it != myPrs.end(); ++it) {
243 if ((*it) == anEdge) break;
245 if (it != myPrs.begin()) {
247 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
248 anIndex = aPoint->getIndex()+1;
249 if (anIndex < 1) anIndex = 1;
251 if (myLink && !SUPERV_isNull(myLink))
252 myLink->AddCoord(anIndex, mySelectedPoint.x(), mySelectedPoint.y());
254 myMain->getCanvas()->update();
258 void SUPERVGUI_CanvasLink::removePoint() {
259 if (mySelectedItem && mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
260 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) mySelectedItem;
261 if (myLink && !SUPERV_isNull(myLink))
262 myLink->RemoveCoord(aPoint->getIndex());
264 myMain->getCanvas()->update();
269 //===============================================================================
270 // SUPERVGUI_CanvasStreamLink: new link to be created
271 //===============================================================================
272 SUPERVGUI_CanvasStreamLink::SUPERVGUI_CanvasStreamLink(QObject* theParent, SUPERVGUI_Main* theMain,
273 SUPERV::StreamLink_ptr theLink):
274 SUPERVGUI_CanvasLink(theParent, theMain, theLink)
276 if (theLink && !SUPERV_isNull(theLink)) {
277 myStreamLink = SUPERV::StreamLink::_duplicate(theLink);
282 void SUPERVGUI_CanvasStreamLink::remove() {
284 SUPERVGUI_CanvasPortIn* aPort = 0;
285 SUPERVGUI_Canvas* aCanvas = getMain()->getCanvas();
286 if (myStreamLink && !SUPERV_isNull(myStreamLink)) {
287 if (getInputPort()) {
288 if (getInputPort()->getEngine()->IsParam() || getInputPort()->getEngine()->IsInLine()) {
289 aPort = (SUPERVGUI_CanvasPortIn*) getInputPort();
290 aValue = QString(aPort->getEngine()->ToString());
293 myStreamLink->destroy();
296 if (aPort && !aValue.isEmpty()) {
297 aPort->setValue(aValue);
303 //===============================================================================
304 // SUPERVGUI_CanvasLinkBuilder: new link to be created
305 //===============================================================================
306 SUPERVGUI_CanvasLinkBuilder::SUPERVGUI_CanvasLinkBuilder(QObject* theParent, SUPERVGUI_Main* theMain,
307 SUPERVGUI_CanvasPort* thePort):
308 SUPERVGUI_CanvasLink(theParent, theMain),
313 myPort->addLink(this);
314 addPoint(myPort->getConnectionPoint());
316 myColor = SKETCH_COLOR;
319 SUPERVGUI_CanvasLinkBuilder::~SUPERVGUI_CanvasLinkBuilder()
321 if (myFloatingEdge) delete myFloatingEdge;
322 if (myPort) myPort->removeLink(this);
325 bool SUPERVGUI_CanvasLinkBuilder::canCreateEngine(SUPERVGUI_CanvasPort* thePort)
328 if (thePort && myPort) {
329 SUPERVGUI_CanvasPort* aInPort;
330 SUPERVGUI_CanvasPort* aOutPort;
332 // check if ports are couple of input and output
333 if (myPort->getEngine()->IsInput()) {
335 if (thePort->getEngine()->IsInput())
341 if (!thePort->getEngine()->IsInput())
346 // control if node is different
347 QString aInNode(aInPort->getEngine()->Node()->Name());
348 QString aOutNode(aOutPort->getEngine()->Node()->Name());
349 if (aInNode.compare(aOutNode) == 0)
352 // control if no port is "Default"
353 QString aInName(aInPort->getEngine()->Name());
354 QString aOutName(aOutPort->getEngine()->Name());
355 if (aInName.compare("Default") == 0 ||
356 aOutName.compare("Default") == 0)
359 // control types of ports
360 int aInKind = aInPort->getEngine()->Kind();
361 int aOutKind = aOutPort->getEngine()->Kind();
363 // connect stream port with stream port only
364 if ((aInKind == SUPERV::DataStreamParameter && aOutKind != SUPERV::DataStreamParameter) ||
365 (aOutKind == SUPERV::DataStreamParameter && aInKind != SUPERV::DataStreamParameter))
368 // connect gate port with gate or inline port
369 if (aInKind == SUPERV::GateParameter || aOutKind == SUPERV::GateParameter) {
370 if (aInKind != aOutKind &&
371 aInKind != SUPERV::InLineParameter &&
372 aOutKind != SUPERV::InLineParameter)
376 // control if port is already linked except for input port of end switch node
377 if (!(aInKind == SUPERV::EndSwitchParameter ||
378 aInPort->getEngine()->Node()->Kind() == SUPERV::EndSwitchNode)) {
379 if (aInPort->getEngine()->IsLinked())
387 void SUPERVGUI_CanvasLinkBuilder::setCoords(SUPERV::Link_ptr theLink)
390 QCanvasItemList::Iterator it;
392 if (myPort->getEngine()->IsInput()) {
393 it = myPrs.begin(); ++it; // ignore the first point
394 for (; it != myPrs.end(); ++it) {
395 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
396 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
401 it = myPrs.end(); --it;
402 for (; it != myPrs.begin(); --it) {
403 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
404 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
411 void SUPERVGUI_CanvasLinkBuilder::addNextPoint(const QPoint& thePoint, bool theOrtho)
413 if (myFloatingEdge) myFloatingEdge->hide();
415 if (!theOrtho || myPrs.empty()) {
419 SUPERVGUI_CanvasPointPrs* aPrev = (SUPERVGUI_CanvasPointPrs*) myPrs.last();
420 int x = (int)aPrev->x(); int y = (int)aPrev->y();
421 if (thePoint.x() != x && thePoint.y() != y) {
422 addPoint(QPoint(thePoint.x(), y), -2);
429 void SUPERVGUI_CanvasLinkBuilder::setFloatPoint(const QPoint& thePoint)
431 if (!myFloatingEdge) {
432 myFloatingEdge = new QCanvasLine(getMain()->getCanvas());
433 myFloatingEdge->setPen(QPen(myColor, LINE_WIDTH));
435 if (!myPrs.empty()) {
436 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
437 thePoint.x(), thePoint.y());
438 myFloatingEdge->show();
442 void SUPERVGUI_CanvasLinkBuilder::removeLastPoint()
444 if (myPrs.count() > 1) {
445 QPoint aLast((int)myPrs.last()->x(), (int)myPrs.last()->y());
446 QCanvasItemList::Iterator it = myPrs.end();
447 bool removed = false;
449 for (; it != myPrs.begin(); --it) {
450 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
451 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
452 if (aPoint->getIndex() == -1 && removed) break;
454 QCanvasItem* anItem = (*it);
455 it = myPrs.remove(it);
460 if (myFloatingEdge) {
461 QPoint aPoint = myFloatingEdge->endPoint();
462 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
463 aPoint.x(), aPoint.y());
466 setFloatPoint(aLast);
471 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort, int dx, int dy)
473 if (myPort && myPort == thePort) {
474 myPrs.first()->moveBy(dx, dy);
479 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort)
481 QPoint p = thePort->getConnectionPoint();
482 if (myPort && myPort == thePort) {
483 myPrs.first()->move(p.x(), p.y());
489 //===============================================================================
490 // SUPERVGUI_CanvasPointPrs: link point presentation
491 //===============================================================================
492 SUPERVGUI_CanvasPointPrs::SUPERVGUI_CanvasPointPrs(QCanvas* theCanvas,
493 SUPERVGUI_CanvasLink* theLink,
494 const int& theIndex):
495 QCanvasEllipse(theCanvas),
496 myLink(theLink), myIndex(theIndex),
497 myInEdge(0), myOutEdge(0), myMoving(false)
499 setSize(POINT_SIZE, POINT_SIZE);
503 int SUPERVGUI_CanvasPointPrs::rtti() const
505 return SUPERVGUI_Canvas::Rtti_LinkPoint;
508 void SUPERVGUI_CanvasPointPrs::setInEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
511 theEdge->setFromPoint((int)x(), (int)y());
514 void SUPERVGUI_CanvasPointPrs::setOutEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
517 theEdge->setToPoint((int)x(), (int)y());
520 void SUPERVGUI_CanvasPointPrs::moveBy(double dx, double dy)
522 QCanvasEllipse::moveBy(dx, dy);
523 if (myInEdge) myInEdge->setFromPoint((int)x(), (int)y());
524 if (myOutEdge) myOutEdge->setToPoint((int)x(), (int)y());
525 //resize canvas view if mouse is outside
526 int w = (int)(x()+dx) + width() + GRAPH_MARGIN;
527 int h = (int)(y()+dy) + height() + GRAPH_MARGIN;
528 if (canvas()->width() > w) w = canvas()->width();
529 if (canvas()->height() > h) h = canvas()->height();
530 if (canvas()->width() < w || canvas()->height() < h) canvas()->resize(w, h);
531 if (myIndex > 0 && isMoving()) {
532 myLink->getEngine()->ChangeCoord(myIndex, (int)x(), (int)y());
536 void SUPERVGUI_CanvasPointPrs::setColor(const QColor& theColor)
541 //===============================================================================
542 // SUPERVGUI_CanvasEdgePrs: link edge presentation
543 //===============================================================================
544 SUPERVGUI_CanvasEdgePrs::SUPERVGUI_CanvasEdgePrs(QCanvas* theCanvas,
545 SUPERVGUI_CanvasLink* theLink):
546 QCanvasLine(theCanvas),
552 int SUPERVGUI_CanvasEdgePrs::rtti() const
554 return SUPERVGUI_Canvas::Rtti_LinkEdge;
557 void SUPERVGUI_CanvasEdgePrs::setFromPoint(int x, int y)
559 setPoints(x, y, endPoint().x(), endPoint().y());
562 void SUPERVGUI_CanvasEdgePrs::setToPoint(int x, int y)
564 setPoints(startPoint().x(), startPoint().y(), x, y);
567 void SUPERVGUI_CanvasEdgePrs::setColor(const QColor& theColor)
569 setPen(QPen(theColor, LINE_WIDTH));