1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SUPERV SUPERVGUI : GUI for Supervisor component
23 // File : SUPERVGUI_GanvasNodePrs.cxx
24 // Author : Natalia KOPNOVA
27 #include "SUPERVGUI_CanvasLink.h"
28 #include "SUPERVGUI_Canvas.h"
29 #include "SUPERVGUI_CanvasPort.h"
30 #include "SUPERVGUI_Main.h"
35 #include <sys/timeb.h>
38 #define DRAW_COLOR Qt::black
39 #define SELECT_COLOR Qt::magenta
40 #define SKETCH_COLOR Qt::darkGreen
41 #define STREAM_COLOR Qt::darkRed // QColor(0, 64, 128) // Qt::blue
46 SUPERVGUI_CanvasLink::SUPERVGUI_CanvasLink(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV::Link_ptr theLink):
55 if (theLink && !SUPERV_isNull(theLink)) {
56 myLink = SUPERV::Link::_duplicate(theLink);
58 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
59 setName(aCanvas->getLinkName(theLink));
61 myInputPort = aCanvas->getPort(myLink->InPort());
62 if (myInputPort) myInputPort->addLink(this);
64 myOutputPort = aCanvas->getPort(myLink->OutPort());
65 if (myOutputPort) myOutputPort->addLink(this);
67 if (myInputPort->isStream())
68 myColor = STREAM_COLOR;
74 connect(this, SIGNAL(objectCreatedDeleted()), myMain, SLOT(onObjectCreatedDeleted()));
77 SUPERVGUI_CanvasLink::~SUPERVGUI_CanvasLink()
79 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
83 if (myInputPort) myInputPort->removeLink(this);
84 if (myOutputPort) myOutputPort->removeLink(this);
87 void SUPERVGUI_CanvasLink::createPrs()
89 if (myLink && !SUPERV_isNull(myLink)) {
91 addPoint(myInputPort->getConnectionPoint());
93 if (!myMain->getCanvas()->isControlView()) {
95 for (CORBA::Long i = 0; i < myLink->CoordsSize(); i++) {
96 myLink->Coords(i+1, x, y);
97 addPoint(QPoint(x, y), i+1);
101 addPoint(myOutputPort->getConnectionPoint());
104 setColor(myHilighted ? SELECT_COLOR : myColor);
107 void SUPERVGUI_CanvasLink::addPoint(const QPoint& thePoint, const int& theIndex)
109 SUPERVGUI_CanvasPointPrs* aPoint;
111 aPoint = new SUPERVGUI_CanvasPointPrs(myMain->getCanvas(), this, theIndex);
112 aPoint->setColor(myColor);
113 aPoint->move(thePoint.x(), thePoint.y());
116 SUPERVGUI_CanvasPointPrs* aPrev = (SUPERVGUI_CanvasPointPrs*) myPrs.last();
118 SUPERVGUI_CanvasEdgePrs* anEdge = new SUPERVGUI_CanvasEdgePrs(myMain->getCanvas(), this);
119 anEdge->setColor(myColor);
120 myPrs.append(anEdge);
122 aPoint = new SUPERVGUI_CanvasPointPrs(myMain->getCanvas(), this, theIndex);
123 aPoint->setColor(myColor);
124 aPoint->move(thePoint.x(), thePoint.y());
126 aPrev->setOutEdge(anEdge);
127 aPoint->setInEdge(anEdge);
129 myPrs.append(aPoint);
132 void SUPERVGUI_CanvasLink::setSelectedObject(QCanvasItem* theItem, const QPoint& thePoint)
134 mySelectedItem = theItem;
135 mySelectedPoint = thePoint;
138 QPopupMenu* SUPERVGUI_CanvasLink::getPopupMenu(QWidget* theParent)
140 QPopupMenu* popup = new QPopupMenu(theParent);
142 anItem = popup->insertItem(tr("MSG_DELLINK"), this, SLOT(remove()));
144 (myInputPort->getEngine()->Kind() != SUPERV::EndSwitchParameter ||
145 myInputPort->getEngine()->Node()->Kind() != SUPERV::EndSwitchNode))
146 if (myInputPort->getEngine()->Kind() == SUPERV::LoopParameter ||
147 myOutputPort && myOutputPort->getEngine()->Kind() == SUPERV::LoopParameter)
148 popup->setItemEnabled(anItem, false);
150 popup->insertSeparator();
151 if (mySelectedItem) {
152 anItem = popup->insertItem(tr("MSG_ADD_POINT"), this, SLOT(addPoint()));
153 if (mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint)
154 popup->setItemEnabled(anItem, false);
156 anItem = popup->insertItem(tr("MSG_DEL_POINT"), this, SLOT(removePoint()));
157 if (mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge)
158 popup->setItemEnabled(anItem, false);
163 void SUPERVGUI_CanvasLink::show()
165 if (myPrs.isEmpty()) createPrs();
167 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
172 void SUPERVGUI_CanvasLink::merge()
174 // remove old presentation
175 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
184 void SUPERVGUI_CanvasLink::setHilighted(bool state)
187 setColor(myHilighted ? SELECT_COLOR : myColor);
188 if (!myPrs.isEmpty()) {
189 bool disp = myPrs.first()->isVisible();
191 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
192 (*it)->hide(); (*it)->show();
194 myMain->getCanvas()->update();
199 void SUPERVGUI_CanvasLink::moveByPort(SUPERVGUI_CanvasPort* thePort, int dx, int dy)
201 if (myInputPort && myInputPort == thePort) {
202 myPrs.first()->moveBy(dx, dy);
205 if (myOutputPort && myOutputPort == thePort) {
206 myPrs.last()->moveBy(dx, dy);
211 void SUPERVGUI_CanvasLink::moveByPort(SUPERVGUI_CanvasPort* thePort)
213 QPoint p = thePort->getConnectionPoint();
214 if (myInputPort && myInputPort == thePort) {
215 myPrs.first()->move(p.x(), p.y());
218 if (myOutputPort && myOutputPort == thePort) {
219 myPrs.last()->move(p.x(), p.y());
224 void SUPERVGUI_CanvasLink::setColor(const QColor& theColor)
226 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
227 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
228 ((SUPERVGUI_CanvasPointPrs*)(*it))->setColor(theColor);
230 else if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
231 ((SUPERVGUI_CanvasEdgePrs*)(*it))->setColor(theColor);
236 void SUPERVGUI_CanvasLink::remove() {
237 // IPAL9369 : check the dataflow readiness to modify
238 if ( !myMain->ReadyToModify() ) // null dataflow or executing, ..
241 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
244 SUPERVGUI_CanvasPortIn* aPort = 0;
245 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
246 if (myLink && !SUPERV_isNull(myLink)) {
248 if (myInputPort->getEngine()->IsParam() || myInputPort->getEngine()->IsInLine()) {
249 aValue = QString(myInputPort->getEngine()->ToString());
250 aPort = (SUPERVGUI_CanvasPortIn*) myInputPort;
255 emit objectCreatedDeleted(); // mkr : PAL8237
259 if (aPort && !aValue.isEmpty() && myMain->getDataflow()->GraphLevel() == 0) {
260 aPort->setValue(aValue);
265 void SUPERVGUI_CanvasLink::addPoint() {
266 if (mySelectedItem && mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
267 SUPERVGUI_CanvasEdgePrs* anEdge = (SUPERVGUI_CanvasEdgePrs*) mySelectedItem;
270 QCanvasItemList::Iterator it;
271 for (it = myPrs.begin(); it != myPrs.end(); ++it) {
272 if ((*it) == anEdge) break;
274 if (it != myPrs.begin()) {
276 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
277 anIndex = aPoint->getIndex()+1;
278 if (anIndex < 1) anIndex = 1;
280 if (myLink && !SUPERV_isNull(myLink)) {
281 myLink->AddCoord(anIndex, mySelectedPoint.x(), mySelectedPoint.y());
282 emit objectCreatedDeleted(); // mkr : PAL8237
285 myMain->getCanvas()->update();
289 void SUPERVGUI_CanvasLink::removePoint() {
290 if (mySelectedItem && mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
291 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) mySelectedItem;
292 if (myLink && !SUPERV_isNull(myLink)) {
293 myLink->RemoveCoord(aPoint->getIndex());
294 emit objectCreatedDeleted(); // mkr : PAL8237
297 myMain->getCanvas()->update();
301 QString SUPERVGUI_CanvasLink::getToolTipText() const {
303 if (myInputPort && myOutputPort)
304 aTTT = myOutputPort->getEngine()->Node()->Name() + QString(" : ") +
305 myOutputPort->getEngine()->Name() + QString(" => ") +
306 myInputPort->getEngine()->Node()->Name() + QString(" : ") +
307 myInputPort->getEngine()->Name();
312 //===============================================================================
313 // SUPERVGUI_CanvasStreamLink: new link to be created
314 //===============================================================================
315 SUPERVGUI_CanvasStreamLink::SUPERVGUI_CanvasStreamLink(QObject* theParent, SUPERVGUI_Main* theMain,
316 SUPERV::StreamLink_ptr theLink):
317 SUPERVGUI_CanvasLink(theParent, theMain, theLink)
319 if (theLink && !SUPERV_isNull(theLink)) {
320 myStreamLink = SUPERV::StreamLink::_duplicate(theLink);
325 void SUPERVGUI_CanvasStreamLink::remove() {
327 SUPERVGUI_CanvasPortIn* aPort = 0;
328 SUPERVGUI_Canvas* aCanvas = getMain()->getCanvas();
329 if (myStreamLink && !SUPERV_isNull(myStreamLink)) {
330 if (getInputPort()) {
331 if (getInputPort()->getEngine()->IsParam() || getInputPort()->getEngine()->IsInLine()) {
332 aPort = (SUPERVGUI_CanvasPortIn*) getInputPort();
333 aValue = QString(aPort->getEngine()->ToString());
336 myStreamLink->destroy();
339 if (aPort && !aValue.isEmpty()) {
340 aPort->setValue(aValue);
346 //===============================================================================
347 // SUPERVGUI_CanvasLinkBuilder: new link to be created
348 //===============================================================================
349 SUPERVGUI_CanvasLinkBuilder::SUPERVGUI_CanvasLinkBuilder(QObject* theParent, SUPERVGUI_Main* theMain,
350 SUPERVGUI_CanvasPort* thePort):
351 SUPERVGUI_CanvasLink(theParent, theMain),
356 myPort->addLink(this);
357 addPoint(myPort->getConnectionPoint());
359 myColor = SKETCH_COLOR;
362 SUPERVGUI_CanvasLinkBuilder::~SUPERVGUI_CanvasLinkBuilder()
364 if (myFloatingEdge) delete myFloatingEdge;
365 if (myPort) myPort->removeLink(this);
368 bool SUPERVGUI_CanvasLinkBuilder::canCreateEngine(SUPERVGUI_CanvasPort* thePort)
370 if (thePort && myPort) {
371 SUPERVGUI_CanvasPort* aInPort;
372 SUPERVGUI_CanvasPort* aOutPort;
374 // check if ports are couple of input and output
375 if (myPort->getEngine()->IsInput()) {
377 if (thePort->getEngine()->IsInput())
383 if (!thePort->getEngine()->IsInput())
388 // control if nodes are different, not the same node
389 QString aInNode(aInPort->getEngine()->Node()->Name());
390 QString aOutNode(aOutPort->getEngine()->Node()->Name());
391 if (aInNode.compare(aOutNode) == 0) // linking outport and inport of the same node
394 // control types of ports
395 int aInKind = aInPort->getEngine()->Kind();
396 int aOutKind = aOutPort->getEngine()->Kind();
398 // connect stream port with stream port only
399 if ((aInKind == SUPERV::DataStreamParameter && aOutKind != SUPERV::DataStreamParameter) ||
400 (aOutKind == SUPERV::DataStreamParameter && aInKind != SUPERV::DataStreamParameter))
403 // asv : 15.12.04 : NOT allow to connect Gate-to-InLine --> it does not make sence!
404 // Out Gate port can be connected only to In Gate port
405 // mkr : NPAL14823 : Out Gate port can be connected to Inline port too
406 if ( aOutKind == SUPERV::GateParameter && aInKind != SUPERV::GateParameter && aInKind != SUPERV::InLineParameter )
409 // In Gate can be connected to (receive links from) Gate port and InLine ports (important for Switch nodes)
410 if ( aInKind == SUPERV::GateParameter && aOutKind != SUPERV::GateParameter && aOutKind != SUPERV::InLineParameter )
413 // asv : 15.12.04 : PAL7374, p.2.2 "Bugs and Improvements": multiple links into Gate port
414 // for InGate it's OK to accept more than 1 link
415 // THESE NEEDS REVISION, ALSO DON'T ALLOW MANY LINKS TO "DEFAULT" PORT OF EndSwitch
416 //if ( aInPort->getEngine()->IsLinked() && aInKind != SUPERV::GateParameter )
418 // control if port is already linked except for input inline ports of end switch node (check for EndSwitchParameter)
419 // and "Default" port of Switch node (check for aNode->isEndSwitch()). "Default" port is linked by default, but we
420 // let it to be "re-linked" to another port.
421 const bool isEndSwitch = ( aInKind == SUPERV::EndSwitchParameter || aInPort->getEngine()->Node()->IsEndSwitch() );
422 if ( !isEndSwitch && aInPort->getEngine()->IsLinked() )
430 void SUPERVGUI_CanvasLinkBuilder::setCoords(SUPERV::Link_ptr theLink)
433 QCanvasItemList::Iterator it;
435 if (myPort->getEngine()->IsInput()) {
436 it = myPrs.begin(); ++it; // ignore the first point
437 for (; it != myPrs.end(); ++it) {
438 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
439 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
444 it = myPrs.end(); --it;
445 for (; it != myPrs.begin(); --it) {
446 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
447 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
454 void SUPERVGUI_CanvasLinkBuilder::addNextPoint(const QPoint& thePoint, bool theOrtho)
456 if (myFloatingEdge) myFloatingEdge->hide();
458 if (!theOrtho || myPrs.empty()) {
462 SUPERVGUI_CanvasPointPrs* aPrev = (SUPERVGUI_CanvasPointPrs*) myPrs.last();
463 int x = (int)aPrev->x(); int y = (int)aPrev->y();
464 if (thePoint.x() != x && thePoint.y() != y) {
465 addPoint(QPoint(thePoint.x(), y), -2);
472 void SUPERVGUI_CanvasLinkBuilder::setFloatPoint(const QPoint& thePoint)
474 if (!myFloatingEdge) {
475 myFloatingEdge = new QCanvasLine(getMain()->getCanvas());
476 myFloatingEdge->setPen(QPen(myColor, LINE_WIDTH));
478 if (!myPrs.empty()) {
479 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
480 thePoint.x(), thePoint.y());
481 myFloatingEdge->show();
485 void SUPERVGUI_CanvasLinkBuilder::removeLastPoint()
487 if (myPrs.count() > 1) {
488 QPoint aLast((int)myPrs.last()->x(), (int)myPrs.last()->y());
489 QCanvasItemList::Iterator it = myPrs.end();
490 bool removed = false;
492 for (; it != myPrs.begin(); --it) {
493 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
494 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
495 if (aPoint->getIndex() == -1 && removed) break;
497 QCanvasItem* anItem = (*it);
498 it = myPrs.remove(it);
503 if (myFloatingEdge) {
504 QPoint aPoint = myFloatingEdge->endPoint();
505 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
506 aPoint.x(), aPoint.y());
509 setFloatPoint(aLast);
514 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort, int dx, int dy)
516 if (myPort && myPort == thePort) {
517 myPrs.first()->moveBy(dx, dy);
522 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort)
524 QPoint p = thePort->getConnectionPoint();
525 if (myPort && myPort == thePort) {
526 myPrs.first()->move(p.x(), p.y());
532 //===============================================================================
533 // SUPERVGUI_CanvasPointPrs: link point presentation
534 //===============================================================================
535 SUPERVGUI_CanvasPointPrs::SUPERVGUI_CanvasPointPrs(QCanvas* theCanvas,
536 SUPERVGUI_CanvasLink* theLink,
537 const int& theIndex):
538 QCanvasEllipse(theCanvas),
539 myLink(theLink), myIndex(theIndex),
540 myInEdge(0), myOutEdge(0), myMoving(false)
542 setSize(POINT_SIZE, POINT_SIZE);
546 int SUPERVGUI_CanvasPointPrs::rtti() const
548 return SUPERVGUI_Canvas::Rtti_LinkPoint;
551 void SUPERVGUI_CanvasPointPrs::setInEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
554 theEdge->setFromPoint(this);
557 void SUPERVGUI_CanvasPointPrs::setOutEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
560 theEdge->setToPoint(this);
563 void SUPERVGUI_CanvasPointPrs::moveBy(double dx, double dy)
565 QCanvasEllipse::moveBy(dx, dy);
566 if (myInEdge) myInEdge->setFromPoint(this);
567 if (myOutEdge) myOutEdge->setToPoint(this);
568 //resize canvas view if mouse is outside
569 int w = (int)(x()+dx) + width() + GRAPH_MARGIN;
570 int h = (int)(y()+dy) + height() + GRAPH_MARGIN;
571 if (canvas()->width() > w) w = canvas()->width();
572 if (canvas()->height() > h) h = canvas()->height();
573 if (canvas()->width() < w || canvas()->height() < h) canvas()->resize(w, h);
574 if (myIndex > 0 && isMoving()) {
575 myLink->getEngine()->ChangeCoord(myIndex, (int)x(), (int)y());
579 void SUPERVGUI_CanvasPointPrs::setColor(const QColor& theColor)
584 //===============================================================================
585 // SUPERVGUI_CanvasEdgePrs: link edge presentation
586 //===============================================================================
587 SUPERVGUI_CanvasEdgePrs::SUPERVGUI_CanvasEdgePrs(QCanvas* theCanvas,
588 SUPERVGUI_CanvasLink* theLink):
589 QCanvasLine(theCanvas),
595 int SUPERVGUI_CanvasEdgePrs::rtti() const
597 return SUPERVGUI_Canvas::Rtti_LinkEdge;
600 void SUPERVGUI_CanvasEdgePrs::setFromPoint(SUPERVGUI_CanvasPointPrs* thePoint)
602 myStartPoint = thePoint;
603 setPoints((int)(thePoint->x()), (int)(thePoint->y()), endPoint().x(), endPoint().y());
606 void SUPERVGUI_CanvasEdgePrs::setToPoint(SUPERVGUI_CanvasPointPrs* thePoint)
608 myEndPoint = thePoint;
609 setPoints(startPoint().x(), startPoint().y(), (int)(thePoint->x()), (int)(thePoint->y()));
612 void SUPERVGUI_CanvasEdgePrs::setColor(const QColor& theColor)
614 setPen(QPen(theColor, LINE_WIDTH));
617 void SUPERVGUI_CanvasEdgePrs::moveBy(double dx, double dy)
619 //mkr: for moving segment of link
620 if (myStartPoint && myEndPoint) {
621 myStartPoint->setMoving(true);
622 myStartPoint->moveBy(dx, dy);
624 myEndPoint->setMoving(true);
625 myEndPoint->moveBy(dx,dy);