1 // SUPERV SUPERVGUI : GUI for Supervisor component
3 // Copyright (C) 2003 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 // File : SUPERVGUI_GanvasNodePrs.cxx
23 // Author : Natalia KOPNOVA
26 #include "SUPERVGUI_CanvasLink.h"
27 #include "SUPERVGUI_Canvas.h"
28 #include "SUPERVGUI_CanvasPort.h"
29 #include "SUPERVGUI_Main.h"
34 #include <sys/timeb.h>
37 #define DRAW_COLOR Qt::black
38 #define SELECT_COLOR Qt::magenta
39 #define SKETCH_COLOR Qt::darkGreen
40 #define STREAM_COLOR Qt::darkRed // QColor(0, 64, 128) // Qt::blue
45 SUPERVGUI_CanvasLink::SUPERVGUI_CanvasLink(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV::Link_ptr theLink):
54 if (theLink && !SUPERV_isNull(theLink)) {
55 myLink = SUPERV::Link::_duplicate(theLink);
57 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
58 setName(aCanvas->getLinkName(theLink));
60 myInputPort = aCanvas->getPort(myLink->InPort());
61 if (myInputPort) myInputPort->addLink(this);
63 myOutputPort = aCanvas->getPort(myLink->OutPort());
64 if (myOutputPort) myOutputPort->addLink(this);
66 if (myInputPort->isStream())
67 myColor = STREAM_COLOR;
73 connect(this, SIGNAL(objectCreatedDeleted()), myMain, SLOT(onObjectCreatedDeleted()));
76 SUPERVGUI_CanvasLink::~SUPERVGUI_CanvasLink()
78 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
82 if (myInputPort) myInputPort->removeLink(this);
83 if (myOutputPort) myOutputPort->removeLink(this);
86 void SUPERVGUI_CanvasLink::createPrs()
88 if (myLink && !SUPERV_isNull(myLink)) {
90 addPoint(myInputPort->getConnectionPoint());
92 if (!myMain->getCanvas()->isControlView()) {
94 for (CORBA::Long i = 0; i < myLink->CoordsSize(); i++) {
95 myLink->Coords(i+1, x, y);
96 addPoint(QPoint(x, y), i+1);
100 addPoint(myOutputPort->getConnectionPoint());
103 setColor(myHilighted ? SELECT_COLOR : myColor);
106 void SUPERVGUI_CanvasLink::addPoint(const QPoint& thePoint, const int& theIndex)
108 SUPERVGUI_CanvasPointPrs* aPoint;
110 aPoint = new SUPERVGUI_CanvasPointPrs(myMain->getCanvas(), this, theIndex);
111 aPoint->setColor(myColor);
112 aPoint->move(thePoint.x(), thePoint.y());
115 SUPERVGUI_CanvasPointPrs* aPrev = (SUPERVGUI_CanvasPointPrs*) myPrs.last();
117 SUPERVGUI_CanvasEdgePrs* anEdge = new SUPERVGUI_CanvasEdgePrs(myMain->getCanvas(), this);
118 anEdge->setColor(myColor);
119 myPrs.append(anEdge);
121 aPoint = new SUPERVGUI_CanvasPointPrs(myMain->getCanvas(), this, theIndex);
122 aPoint->setColor(myColor);
123 aPoint->move(thePoint.x(), thePoint.y());
125 aPrev->setOutEdge(anEdge);
126 aPoint->setInEdge(anEdge);
128 myPrs.append(aPoint);
131 void SUPERVGUI_CanvasLink::setSelectedObject(QCanvasItem* theItem, const QPoint& thePoint)
133 mySelectedItem = theItem;
134 mySelectedPoint = thePoint;
137 QPopupMenu* SUPERVGUI_CanvasLink::getPopupMenu(QWidget* theParent)
139 QPopupMenu* popup = new QPopupMenu(theParent);
141 anItem = popup->insertItem(tr("MSG_DELLINK"), this, SLOT(remove()));
143 (myInputPort->getEngine()->Kind() != SUPERV::EndSwitchParameter ||
144 myInputPort->getEngine()->Node()->Kind() != SUPERV::EndSwitchNode))
145 if (myInputPort->getEngine()->Kind() == SUPERV::LoopParameter ||
146 myOutputPort && myOutputPort->getEngine()->Kind() == SUPERV::LoopParameter)
147 popup->setItemEnabled(anItem, false);
149 popup->insertSeparator();
150 if (mySelectedItem) {
151 anItem = popup->insertItem(tr("MSG_ADD_POINT"), this, SLOT(addPoint()));
152 if (mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint)
153 popup->setItemEnabled(anItem, false);
155 anItem = popup->insertItem(tr("MSG_DEL_POINT"), this, SLOT(removePoint()));
156 if (mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge)
157 popup->setItemEnabled(anItem, false);
162 void SUPERVGUI_CanvasLink::show()
164 if (myPrs.isEmpty()) createPrs();
166 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
171 void SUPERVGUI_CanvasLink::merge()
173 // remove old presentation
174 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
183 void SUPERVGUI_CanvasLink::setHilighted(bool state)
186 setColor(myHilighted ? SELECT_COLOR : myColor);
187 if (!myPrs.isEmpty()) {
188 bool disp = myPrs.first()->isVisible();
190 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
191 (*it)->hide(); (*it)->show();
193 myMain->getCanvas()->update();
198 void SUPERVGUI_CanvasLink::moveByPort(SUPERVGUI_CanvasPort* thePort, int dx, int dy)
200 if (myInputPort && myInputPort == thePort) {
201 myPrs.first()->moveBy(dx, dy);
204 if (myOutputPort && myOutputPort == thePort) {
205 myPrs.last()->moveBy(dx, dy);
210 void SUPERVGUI_CanvasLink::moveByPort(SUPERVGUI_CanvasPort* thePort)
212 QPoint p = thePort->getConnectionPoint();
213 if (myInputPort && myInputPort == thePort) {
214 myPrs.first()->move(p.x(), p.y());
217 if (myOutputPort && myOutputPort == thePort) {
218 myPrs.last()->move(p.x(), p.y());
223 void SUPERVGUI_CanvasLink::setColor(const QColor& theColor)
225 for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) {
226 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
227 ((SUPERVGUI_CanvasPointPrs*)(*it))->setColor(theColor);
229 else if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
230 ((SUPERVGUI_CanvasEdgePrs*)(*it))->setColor(theColor);
235 void SUPERVGUI_CanvasLink::remove() {
236 // IPAL9369 : check the dataflow readiness to modify
237 if ( !myMain->ReadyToModify() ) // null dataflow or executing, ..
240 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
243 SUPERVGUI_CanvasPortIn* aPort = 0;
244 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
245 if (myLink && !SUPERV_isNull(myLink)) {
247 if (myInputPort->getEngine()->IsParam() || myInputPort->getEngine()->IsInLine()) {
248 aValue = QString(myInputPort->getEngine()->ToString());
249 aPort = (SUPERVGUI_CanvasPortIn*) myInputPort;
254 emit objectCreatedDeleted(); // mkr : PAL8237
258 if (aPort && !aValue.isEmpty() && myMain->getDataflow()->GraphLevel() == 0) {
259 aPort->setValue(aValue);
264 void SUPERVGUI_CanvasLink::addPoint() {
265 if (mySelectedItem && mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
266 SUPERVGUI_CanvasEdgePrs* anEdge = (SUPERVGUI_CanvasEdgePrs*) mySelectedItem;
269 QCanvasItemList::Iterator it;
270 for (it = myPrs.begin(); it != myPrs.end(); ++it) {
271 if ((*it) == anEdge) break;
273 if (it != myPrs.begin()) {
275 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
276 anIndex = aPoint->getIndex()+1;
277 if (anIndex < 1) anIndex = 1;
279 if (myLink && !SUPERV_isNull(myLink)) {
280 myLink->AddCoord(anIndex, mySelectedPoint.x(), mySelectedPoint.y());
281 emit objectCreatedDeleted(); // mkr : PAL8237
284 myMain->getCanvas()->update();
288 void SUPERVGUI_CanvasLink::removePoint() {
289 if (mySelectedItem && mySelectedItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
290 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) mySelectedItem;
291 if (myLink && !SUPERV_isNull(myLink)) {
292 myLink->RemoveCoord(aPoint->getIndex());
293 emit objectCreatedDeleted(); // mkr : PAL8237
296 myMain->getCanvas()->update();
300 QString SUPERVGUI_CanvasLink::getToolTipText() const {
302 if (myInputPort && myOutputPort)
303 aTTT = myOutputPort->getEngine()->Node()->Name() + QString(" : ") +
304 myOutputPort->getEngine()->Name() + QString(" => ") +
305 myInputPort->getEngine()->Node()->Name() + QString(" : ") +
306 myInputPort->getEngine()->Name();
311 //===============================================================================
312 // SUPERVGUI_CanvasStreamLink: new link to be created
313 //===============================================================================
314 SUPERVGUI_CanvasStreamLink::SUPERVGUI_CanvasStreamLink(QObject* theParent, SUPERVGUI_Main* theMain,
315 SUPERV::StreamLink_ptr theLink):
316 SUPERVGUI_CanvasLink(theParent, theMain, theLink)
318 if (theLink && !SUPERV_isNull(theLink)) {
319 myStreamLink = SUPERV::StreamLink::_duplicate(theLink);
324 void SUPERVGUI_CanvasStreamLink::remove() {
326 SUPERVGUI_CanvasPortIn* aPort = 0;
327 SUPERVGUI_Canvas* aCanvas = getMain()->getCanvas();
328 if (myStreamLink && !SUPERV_isNull(myStreamLink)) {
329 if (getInputPort()) {
330 if (getInputPort()->getEngine()->IsParam() || getInputPort()->getEngine()->IsInLine()) {
331 aPort = (SUPERVGUI_CanvasPortIn*) getInputPort();
332 aValue = QString(aPort->getEngine()->ToString());
335 myStreamLink->destroy();
338 if (aPort && !aValue.isEmpty()) {
339 aPort->setValue(aValue);
345 //===============================================================================
346 // SUPERVGUI_CanvasLinkBuilder: new link to be created
347 //===============================================================================
348 SUPERVGUI_CanvasLinkBuilder::SUPERVGUI_CanvasLinkBuilder(QObject* theParent, SUPERVGUI_Main* theMain,
349 SUPERVGUI_CanvasPort* thePort):
350 SUPERVGUI_CanvasLink(theParent, theMain),
355 myPort->addLink(this);
356 addPoint(myPort->getConnectionPoint());
358 myColor = SKETCH_COLOR;
361 SUPERVGUI_CanvasLinkBuilder::~SUPERVGUI_CanvasLinkBuilder()
363 if (myFloatingEdge) delete myFloatingEdge;
364 if (myPort) myPort->removeLink(this);
367 bool SUPERVGUI_CanvasLinkBuilder::canCreateEngine(SUPERVGUI_CanvasPort* thePort)
369 if (thePort && myPort) {
370 SUPERVGUI_CanvasPort* aInPort;
371 SUPERVGUI_CanvasPort* aOutPort;
373 // check if ports are couple of input and output
374 if (myPort->getEngine()->IsInput()) {
376 if (thePort->getEngine()->IsInput())
382 if (!thePort->getEngine()->IsInput())
387 // control if nodes are different, not the same node
388 QString aInNode(aInPort->getEngine()->Node()->Name());
389 QString aOutNode(aOutPort->getEngine()->Node()->Name());
390 if (aInNode.compare(aOutNode) == 0) // linking outport and inport of the same node
393 // control types of ports
394 int aInKind = aInPort->getEngine()->Kind();
395 int aOutKind = aOutPort->getEngine()->Kind();
397 // connect stream port with stream port only
398 if ((aInKind == SUPERV::DataStreamParameter && aOutKind != SUPERV::DataStreamParameter) ||
399 (aOutKind == SUPERV::DataStreamParameter && aInKind != SUPERV::DataStreamParameter))
402 // asv : 15.12.04 : NOT allow to connect Gate-to-InLine --> it does not make sence!
403 // Out Gate port can be connected only to In Gate port
404 // mkr : NPAL14823 : Out Gate port can be connected to Inline port too
405 if ( aOutKind == SUPERV::GateParameter && aInKind != SUPERV::GateParameter && aInKind != SUPERV::InLineParameter )
408 // In Gate can be connected to (receive links from) Gate port and InLine ports (important for Switch nodes)
409 if ( aInKind == SUPERV::GateParameter && aOutKind != SUPERV::GateParameter && aOutKind != SUPERV::InLineParameter )
412 // asv : 15.12.04 : PAL7374, p.2.2 "Bugs and Improvements": multiple links into Gate port
413 // for InGate it's OK to accept more than 1 link
414 // THESE NEEDS REVISION, ALSO DON'T ALLOW MANY LINKS TO "DEFAULT" PORT OF EndSwitch
415 //if ( aInPort->getEngine()->IsLinked() && aInKind != SUPERV::GateParameter )
417 // control if port is already linked except for input inline ports of end switch node (check for EndSwitchParameter)
418 // and "Default" port of Switch node (check for aNode->isEndSwitch()). "Default" port is linked by default, but we
419 // let it to be "re-linked" to another port.
420 const bool isEndSwitch = ( aInKind == SUPERV::EndSwitchParameter || aInPort->getEngine()->Node()->IsEndSwitch() );
421 if ( !isEndSwitch && aInPort->getEngine()->IsLinked() )
429 void SUPERVGUI_CanvasLinkBuilder::setCoords(SUPERV::Link_ptr theLink)
432 QCanvasItemList::Iterator it;
434 if (myPort->getEngine()->IsInput()) {
435 it = myPrs.begin(); ++it; // ignore the first point
436 for (; it != myPrs.end(); ++it) {
437 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
438 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
443 it = myPrs.end(); --it;
444 for (; it != myPrs.begin(); --it) {
445 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
446 theLink->AddCoord(anIndex++, (int)(*it)->x(), (int)(*it)->y());
453 void SUPERVGUI_CanvasLinkBuilder::addNextPoint(const QPoint& thePoint, bool theOrtho)
455 if (myFloatingEdge) myFloatingEdge->hide();
457 if (!theOrtho || myPrs.empty()) {
461 SUPERVGUI_CanvasPointPrs* aPrev = (SUPERVGUI_CanvasPointPrs*) myPrs.last();
462 int x = (int)aPrev->x(); int y = (int)aPrev->y();
463 if (thePoint.x() != x && thePoint.y() != y) {
464 addPoint(QPoint(thePoint.x(), y), -2);
471 void SUPERVGUI_CanvasLinkBuilder::setFloatPoint(const QPoint& thePoint)
473 if (!myFloatingEdge) {
474 myFloatingEdge = new QCanvasLine(getMain()->getCanvas());
475 myFloatingEdge->setPen(QPen(myColor, LINE_WIDTH));
477 if (!myPrs.empty()) {
478 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
479 thePoint.x(), thePoint.y());
480 myFloatingEdge->show();
484 void SUPERVGUI_CanvasLinkBuilder::removeLastPoint()
486 if (myPrs.count() > 1) {
487 QPoint aLast((int)myPrs.last()->x(), (int)myPrs.last()->y());
488 QCanvasItemList::Iterator it = myPrs.end();
489 bool removed = false;
491 for (; it != myPrs.begin(); --it) {
492 if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
493 SUPERVGUI_CanvasPointPrs* aPoint = (SUPERVGUI_CanvasPointPrs*) (*it);
494 if (aPoint->getIndex() == -1 && removed) break;
496 QCanvasItem* anItem = (*it);
497 it = myPrs.remove(it);
502 if (myFloatingEdge) {
503 QPoint aPoint = myFloatingEdge->endPoint();
504 myFloatingEdge->setPoints((int)myPrs.last()->x(), (int)myPrs.last()->y(),
505 aPoint.x(), aPoint.y());
508 setFloatPoint(aLast);
513 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort, int dx, int dy)
515 if (myPort && myPort == thePort) {
516 myPrs.first()->moveBy(dx, dy);
521 void SUPERVGUI_CanvasLinkBuilder::moveByPort(SUPERVGUI_CanvasPort* thePort)
523 QPoint p = thePort->getConnectionPoint();
524 if (myPort && myPort == thePort) {
525 myPrs.first()->move(p.x(), p.y());
531 //===============================================================================
532 // SUPERVGUI_CanvasPointPrs: link point presentation
533 //===============================================================================
534 SUPERVGUI_CanvasPointPrs::SUPERVGUI_CanvasPointPrs(QCanvas* theCanvas,
535 SUPERVGUI_CanvasLink* theLink,
536 const int& theIndex):
537 QCanvasEllipse(theCanvas),
538 myLink(theLink), myIndex(theIndex),
539 myInEdge(0), myOutEdge(0), myMoving(false)
541 setSize(POINT_SIZE, POINT_SIZE);
545 int SUPERVGUI_CanvasPointPrs::rtti() const
547 return SUPERVGUI_Canvas::Rtti_LinkPoint;
550 void SUPERVGUI_CanvasPointPrs::setInEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
553 theEdge->setFromPoint(this);
556 void SUPERVGUI_CanvasPointPrs::setOutEdge(SUPERVGUI_CanvasEdgePrs* theEdge)
559 theEdge->setToPoint(this);
562 void SUPERVGUI_CanvasPointPrs::moveBy(double dx, double dy)
564 QCanvasEllipse::moveBy(dx, dy);
565 if (myInEdge) myInEdge->setFromPoint(this);
566 if (myOutEdge) myOutEdge->setToPoint(this);
567 //resize canvas view if mouse is outside
568 int w = (int)(x()+dx) + width() + GRAPH_MARGIN;
569 int h = (int)(y()+dy) + height() + GRAPH_MARGIN;
570 if (canvas()->width() > w) w = canvas()->width();
571 if (canvas()->height() > h) h = canvas()->height();
572 if (canvas()->width() < w || canvas()->height() < h) canvas()->resize(w, h);
573 if (myIndex > 0 && isMoving()) {
574 myLink->getEngine()->ChangeCoord(myIndex, (int)x(), (int)y());
578 void SUPERVGUI_CanvasPointPrs::setColor(const QColor& theColor)
583 //===============================================================================
584 // SUPERVGUI_CanvasEdgePrs: link edge presentation
585 //===============================================================================
586 SUPERVGUI_CanvasEdgePrs::SUPERVGUI_CanvasEdgePrs(QCanvas* theCanvas,
587 SUPERVGUI_CanvasLink* theLink):
588 QCanvasLine(theCanvas),
594 int SUPERVGUI_CanvasEdgePrs::rtti() const
596 return SUPERVGUI_Canvas::Rtti_LinkEdge;
599 void SUPERVGUI_CanvasEdgePrs::setFromPoint(SUPERVGUI_CanvasPointPrs* thePoint)
601 myStartPoint = thePoint;
602 setPoints((int)(thePoint->x()), (int)(thePoint->y()), endPoint().x(), endPoint().y());
605 void SUPERVGUI_CanvasEdgePrs::setToPoint(SUPERVGUI_CanvasPointPrs* thePoint)
607 myEndPoint = thePoint;
608 setPoints(startPoint().x(), startPoint().y(), (int)(thePoint->x()), (int)(thePoint->y()));
611 void SUPERVGUI_CanvasEdgePrs::setColor(const QColor& theColor)
613 setPen(QPen(theColor, LINE_WIDTH));
616 void SUPERVGUI_CanvasEdgePrs::moveBy(double dx, double dy)
618 //mkr: for moving segment of link
619 if (myStartPoint && myEndPoint) {
620 myStartPoint->setMoving(true);
621 myStartPoint->moveBy(dx, dy);
623 myEndPoint->setMoving(true);
624 myEndPoint->moveBy(dx,dy);