Salome HOME
3a1676f005dc2fdaa9423cd54bd306edd095fea7
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_GraphNode.cxx
1 //  SUPERV SUPERVGUI : GUI for Supervisor component
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : SUPERVGUI_ComputeNode.cxx
8 //  Author : Vitaly SMETANNIKOV
9 //  Module : SUPERV
10
11 using namespace std;
12 #include "SUPERVGUI_GraphNode.h"
13 #include "SUPERVGUI_Graph.h"
14 #include "SUPERVGUI_Main.h"
15
16
17 SUPERVGUI_GraphNode::SUPERVGUI_GraphNode(QWidget* theParent, SUPERVGUI_Main* theMain, SUPERV_CNode theNode)
18   :SUPERVGUI_Node(theParent, theMain, theNode),
19    MouseX(MouseNo),
20    MouseY(MouseNo)
21 {
22   //disconnect(myTitle, 0, this, 0);
23   myTitle = new SUPERVGUI_Label(this, LABEL_WIDTH, LABEL_HEIGHT, name(), QLabel::AlignLeft);
24   myTitle->hide();
25   connect(myTitle, SIGNAL(MousePress(QMouseEvent*)), this, SLOT(mouseTitlePress(QMouseEvent*)));
26   connect(myTitle, SIGNAL(MouseMove (QMouseEvent*)), this, SLOT(mouseTitleMove(QMouseEvent*)));
27   connect(myTitle, SIGNAL(MouseRelease(QMouseEvent*)), this, SLOT(mouseTitleRelease(QMouseEvent*)));
28
29   myPortsBox = new QVBox(0);  
30   myPortsBox->setSpacing(3);
31   myValuesBox = new QWidget(myPortsBox);
32   myPortLayout = new QGridLayout(myValuesBox, 0, 2, 0, 1);
33
34   myGatesBox = new QFrame(myPortsBox);
35   myGatesBox->setFrameStyle( QFrame::Panel | QFrame::Raised );
36   myGatesBox->setLineWidth(2);
37   //  myGatesBox->setPaletteBackgroundColor(backgroundColor().dark(105));
38   myGatesBox->setPaletteBackgroundColor(green.light(170));
39   myGatesLayout = new QGridLayout(myGatesBox, 0, 2);
40   myGatesLayout->setMargin(3);
41   
42   myTimer = new QTimer(this);
43   connect(myTimer, SIGNAL(timeout()), this, SLOT(movingNode(/*QMouseEvent* e*/)));
44   myStopFlag = true;
45
46   myX = -1;
47   myY = -1;
48   myDifX = 0;
49   myDifY = 0;
50   myFirstDifX = 0;
51   myFirstDifY = 0;
52
53   myPIcount = 0;
54   myPOcount = 0;
55   SUPERV_Ports       ports = myNode->Ports();
56   int                n     = ports->length();
57
58   for (int i=0; i<n; i++) {
59     if (ports[i]->IsInput()) {
60       if (ports[i]->IsGate())
61         myGatesLayout->addWidget(new SUPERVGUI_PortIn(myGatesBox, myMain, ports[i]), 
62                                  0, 0);
63       else {
64         myPortLayout->addWidget(new SUPERVGUI_PortIn(myValuesBox, myMain, ports[i]), 
65                                 myPIcount, 0);
66         myPIcount++;
67       }
68     } else {
69       if (ports[i]->IsGate())
70         myGatesLayout->addWidget(new SUPERVGUI_PortOut(myGatesBox, myMain, ports[i]), 
71                                  0, 1, Qt::AlignRight);
72       else {
73         myPortLayout->addWidget(new SUPERVGUI_PortOut(myValuesBox, myMain, ports[i]), 
74                                 myPOcount, 1, Qt::AlignRight);
75         myPOcount++;
76       }
77     }
78   }
79 }
80
81
82
83 SUPERVGUI_GraphNode::~SUPERVGUI_GraphNode() {
84 }
85
86 void SUPERVGUI_GraphNode::mouseTitlePress(QMouseEvent* e) {
87   if (!myMain->getGraph()->isAnyLinkCreating()) {
88     if (e->button() == RightButton) {
89       MouseLeft       = 0;
90       showPopup(e);
91     } else {
92       MouseLeft       = 1;
93       SUPERVGUI_Graph* sv = myMain->getGraph();
94       MouseX          = sv->childX(this) - e->globalX();
95       MouseY          = sv->childY(this) - e->globalY();
96     }
97   }
98 }
99
100 void SUPERVGUI_GraphNode::mouseTitleMove(QMouseEvent* e) {
101     Trace("SUPERVGUI_Node::moveAgain")
102     SUPERVGUI_Graph* sv = myMain->getGraph();
103
104     if ((MouseX == MouseNo) && (MouseY == MouseNo)) {
105         MouseX    = sv->childX(this) - e->globalX();
106         MouseY    = sv->childY(this) - e->globalY();
107         MouseLeft = (e->state() == RightButton? 0: 1);
108     };
109
110     if (MouseLeft == 1) {
111
112       int x = e->globalX()+MouseX;
113       int y = e->globalY()+MouseY;
114       x = x<0? 0: x;
115       y = y<0? 0: y;
116
117         if (x > myMain->getGraph()->horizontalScrollBar()->value()
118             + myMain->getGraph()->viewport()->width() - width()/2
119             ||
120             y > myMain->getGraph()->verticalScrollBar()->value()
121             + myMain->getGraph()->viewport()->height() - height()/2 
122             ||
123             x < myMain->getGraph()->horizontalScrollBar()->value()
124             ||
125             y < myMain->getGraph()->verticalScrollBar()->value()){
126           if (!myTimer->isActive()) {
127             myX = x;
128             myY = y;
129             myDifX = x - myNode->X();
130             myDifY = y - myNode->Y();
131             myFirstDifX = myDifX;
132             myFirstDifY = myDifY;
133           }
134
135           StartTimer();
136           myStopFlag = false;
137
138           if (x - myNode->X() > 15 && abs(myDifX) < abs(myDifY)) {
139             if (x > myMain->getGraph()->horizontalScrollBar()->value()
140                 + myMain->getGraph()->viewport()->width() - width()/2)
141               myDifX = 5; // or another positive number
142             else {
143               //not out of the right boundary
144               sv->moveChild(this, x, myNode->Y()); //new X and old Y
145               myNode->Coords(x, myNode->Y());
146               myX = x;
147             }
148           }
149
150           if (x - myNode->X() < -15 && abs(myDifX) < abs(myDifY)) {
151             if(x < myMain->getGraph()->horizontalScrollBar()->value())
152               myDifX = -5; //or another negative number
153             else {
154               //not out of the left boundary
155               sv->moveChild(this, x, myNode->Y()); //new X and old Y
156               myNode->Coords(x, myNode->Y());
157               myX = x;
158             }
159           }
160
161           if (y - myNode->Y() > 15 && abs(myDifX) > abs(myDifY)) {
162             if (y > myMain->getGraph()->verticalScrollBar()->value() 
163                 + myMain->getGraph()->viewport()->height() - height()/2)
164               myDifY = 5; //or another positive number
165             else {
166               //not out of the lower boundary
167               sv->moveChild(this, myNode->X(), y); //old X and new Y
168               myNode->Coords(myNode->X(), y);
169               myY = y;
170             }
171           }
172
173           if (y - myNode->Y() < -15 && abs(myDifX) > abs(myDifY)) {
174             if (y < myMain->getGraph()->verticalScrollBar()->value())
175               myDifY = -5; //or another negative number
176             else {
177               //not out of the upper boundary
178               sv->moveChild(this, myNode->X(), y); //old X and new Y
179               myNode->Coords(myNode->X(), y);
180               myY = y;
181             }
182           }
183
184         } 
185         else { 
186           if ((myDifX*(x - myNode->X()) < 0 || myDifY*(y - myNode->Y()) < 0)) {
187             StopTimer();
188             myStopFlag = true;
189           }
190           //for mouse moving to boundaries from outside space (chack then node must be move)
191           int xp1, yp1, xp2, yp2;
192           xp1 = myMain->getGraph()->horizontalScrollBar()->value();
193           xp2 = myMain->getGraph()->horizontalScrollBar()->value() +
194             myMain->getGraph()->viewport()->width();
195           yp1 = myMain->getGraph()->verticalScrollBar()->value();
196           yp2 = myMain->getGraph()->verticalScrollBar()->value() +
197             myMain->getGraph()->viewport()->height();
198           if (x >= xp1
199               && x <= xp1+myMain->getGraph()->viewport()->visibleRect().width() 
200               && y >= yp1 
201               && y <= yp1+myMain->getGraph()->viewport()->visibleRect().height()) {
202             sv->moveChild(this, x, y);
203             myNode->Coords(x, y);
204           }
205           
206         }
207     }
208 }
209
210 void SUPERVGUI_GraphNode::mouseTitleRelease(QMouseEvent* e) {
211   StopTimer();
212   myStopFlag = true;
213 }
214
215 void SUPERVGUI_GraphNode::movingNode() {
216   SUPERVGUI_Graph* sv = myMain->getGraph();
217
218   myX = myX<0 ? 0: myX;
219   myY = myY<0 ? 0: myY;
220
221   if (myDifX > 0)
222     myX = myX + 5;
223   if (myDifX < 0)
224     myX = myX - 5;
225   if (myDifY > 0)
226     myY = myY + 5;
227   if (myDifY < 0)
228     myY = myY - 5;
229
230   myMain->getGraph()->ResizeGraph(this, myX, myY);
231   myMain->getGraph()->scrollBy( myX - myNode->X(), myY - myNode->Y() );
232   sv->moveChild(this, myX, myY);
233   myNode->Coords(myX, myY);
234 }
235
236 void SUPERVGUI_GraphNode::StartTimer() {
237     Trace("SUPERVGUI_Main::StartTimer")
238     if (!myTimer->isActive()) {
239       myTimer->start(170);
240     };
241 }
242
243 void SUPERVGUI_GraphNode::StopTimer() {
244     Trace("SUPERVGUI_Main::StopTimer")
245     if (myTimer->isActive()) {
246       myTimer->stop();
247     };
248 }
249
250 void SUPERVGUI_GraphNode::deleteLinks() {
251   QObjectList* aList = queryList("SUPERVGUI_Port");
252   SUPERVGUI_Port* aPort;
253   QObjectListIt aIt(*aList);
254   while ((aPort=(SUPERVGUI_Port*)aIt.current()) != 0) {
255     ++aIt;
256     aPort->deleteLinks();
257   }
258   delete aList;
259 }
260
261
262 void SUPERVGUI_GraphNode::sync() {
263   SUPERVGUI_Node::sync();
264
265   SUPERVGUI_Port* pi;
266   QObjectList* ihmList = queryList("SUPERVGUI_Port");
267   QObjectListIt i(*ihmList);
268   while ((pi=(SUPERVGUI_Port*)i.current()) != 0) {
269     ++i;
270     pi->sync();
271   }
272   delete ihmList;
273     
274   //check: is creation of link is complete
275   if (myMain->getGraph()->isAnyLinkCreating()) {
276     //not creation complete
277     myPopup->setItemEnabled(myDeleteItem, false);
278   }
279   else {
280     //creation complete
281     myPopup->setItemEnabled(myDeleteItem, true);
282   }
283 }
284
285
286 /**
287  * Creates presentation of links to In ports
288  * If toCheckExisting = false the links will be created without checking
289  * of their existing in Graph
290  * If toCheckExisting = true the existing of links will be checked before creation
291  */
292 void SUPERVGUI_GraphNode::updateLinksPrs(bool toCheckExisting) {
293   SUPERVGUI_Graph* aGraph= myMain->getGraph();
294   SUPERVGUI_PortIn* pi;
295   QObjectList* ihmList = queryList("SUPERVGUI_PortIn");
296   QObjectListIt i(*ihmList);
297   while ((pi=(SUPERVGUI_PortIn*)i.current()) != 0) {
298     ++i;
299     if (pi->getPort()->IsLinked()) {
300       SUPERV_Link aLink = pi->getPort()->Link();
301       if (toCheckExisting) {
302         if (aGraph->isLinkPrsExists(aLink))
303           continue;
304       }
305       aGraph->createLinkPrs(aLink);
306     }
307   }
308   delete ihmList;
309
310   //Find PortInESNode
311   SUPERVGUI_PortInESNode* piES;
312   QObjectList* ihmListES = queryList("SUPERVGUI_PortInESNode");
313   QObjectListIt iES(*ihmListES);
314   while ((piES=(SUPERVGUI_PortInESNode*)iES.current()) != 0) {
315     ++iES;
316     if (piES->getPort()->IsLinked()) {
317       SUPERV_Links aLinks = piES->getPort()->Links();
318       for (int j=0; j<aLinks->length(); j++) {
319         if (toCheckExisting) {
320           if (aGraph->isLinkPrsExists(aLinks[j]))
321             continue;
322         }
323         aGraph->createLinkPrs(aLinks[j]);
324       }
325     }
326   }
327   delete ihmListES;
328 }
329
330
331 void SUPERVGUI_GraphNode::setNodeName(QString theName) {
332   SUPERVGUI_Node::setNodeName(theName);
333   myTitle->setText(name());
334 }
335
336
337 void SUPERVGUI_GraphNode::deletePort(SUPERVGUI_Port* thePort) {
338   if (thePort->isA("SUPERVGUI_PortIn") || thePort->isA("SUPERVGUI_PortInESNode")) {
339     myPIcount--;
340   }
341   else {
342     myPOcount--;
343   }
344   thePort->deleteLinks();
345   
346   thePort->getPort()->destroy();
347   thePort->close(true);
348   updatePorts();
349   updateShape();
350 }
351
352
353 void SUPERVGUI_GraphNode::addInputPort() {
354   SUPERV_Port aPort = createInPort();
355   if (aPort == NULL) return;
356
357   if (getNodeType() == SUPERV::EndSwitchNode) {
358     SUPERVGUI_PortInESNode* aPortPrs = new SUPERVGUI_PortInESNode(myValuesBox, myMain, aPort);    
359     myPortLayout->addWidget(aPortPrs, myPIcount, 0);
360
361     if (myPortsBox->isVisible()) {
362       aPortPrs->show();
363     }
364   }
365   else {
366     SUPERVGUI_PortIn* aPortPrs = new SUPERVGUI_PortIn(myValuesBox, myMain, aPort);
367     myPortLayout->addWidget(aPortPrs, myPIcount, 0);
368
369     if (myPortsBox->isVisible()) {
370       aPortPrs->show();
371     }
372   }
373
374   myPIcount++;
375   updatePorts();
376   updateShape();
377 }
378
379
380 void SUPERVGUI_GraphNode::addOutputPort() {
381   SUPERV_Port aPort = createOutPort();
382   if (aPort == NULL) return;
383
384   SUPERVGUI_PortOut* aPortPrs = new SUPERVGUI_PortOut(myValuesBox, myMain, aPort);
385   myPortLayout->addWidget(aPortPrs, myPOcount, 1, Qt::AlignRight);
386   myPOcount++;
387   if (myPortsBox->isVisible()) {
388     aPortPrs->show();
389   }
390   updatePorts();
391   updateShape();
392 }
393
394
395 void SUPERVGUI_GraphNode::updatePorts() {
396   bool isAdded = false;
397   SUPERV_Ports aPorts = getEngine()->Ports();
398   int n = aPorts->length();
399   SUPERVGUI_Port* aPortPrs;
400   bool aIsVisible = myPortsBox->isVisible();
401   for (int i=0; i < n; i++) {
402     QString aName(aPorts[i]->Name());
403     aName += (aPorts[i]->IsInput())? "Input":"Output";
404     aPortPrs = (SUPERVGUI_Port*) child(aName, "SUPERVGUI_Port");
405     if (aPortPrs == NULL) {
406       if (aPorts[i]->IsInput()) {
407         SUPERVGUI_PortIn* aPortIn;
408         if (aPorts[i]->IsGate()) {
409           aPortIn = new SUPERVGUI_PortIn(myGatesBox, myMain, aPorts[i]);
410           myGatesLayout->addWidget(aPortIn, myPIcount, 0);
411         } else {
412           aPortIn = new SUPERVGUI_PortIn(myValuesBox, myMain, aPorts[i]);
413           myPortLayout->addWidget(aPortIn, myPIcount, 0);
414           myPIcount++;
415         }
416         if (aIsVisible) aPortIn->show();
417         isAdded = true;
418       } else {
419         SUPERVGUI_PortOut* aPortOut;
420         if (aPorts[i]->IsGate()) {
421           aPortOut = new SUPERVGUI_PortOut(myGatesBox, myMain, aPorts[i]);
422           myGatesLayout->addWidget(aPortOut, myPOcount, 1, Qt::AlignRight);
423         } else {
424           aPortOut = new SUPERVGUI_PortOut(myValuesBox, myMain, aPorts[i]);
425           myPortLayout->addWidget(aPortOut, myPOcount, 1, Qt::AlignRight);
426           myPOcount++;
427         }
428         if (aIsVisible) aPortOut->show();
429         isAdded = true;
430       }
431     }
432   }
433   
434   QObjectList* aShownPortsList = queryList("SUPERVGUI_Port");
435   QObjectListIt aLI(*aShownPortsList);
436   SUPERVGUI_Port* aVisPort;
437
438   while ((aVisPort=(SUPERVGUI_Port*)aLI.current()) != 0) {  
439     ++aLI;
440     QString aNameVisible(aVisPort->getPort()->Name());
441     
442     bool aIsExists = false;
443     for (int i=0; i < n; i++) {
444       QString aName(aPorts[i]->Name());
445       if (aName == aNameVisible)
446           aIsExists = true;
447     }
448   
449     if (!aIsExists) { //we have a visible object, which has no engine entity
450       aVisPort->close(true);
451     }
452   }
453 }
454
455
456 /**
457  * Returns coordinates of connection point in content coordinates
458  */
459 QPoint SUPERVGUI_GraphNode::getInConnectPnt() {
460   return QPoint(pos().x(), 
461                 pos().y() + (height()/2));
462 }
463 QPoint SUPERVGUI_GraphNode::getOutConnectPnt() {
464   return QPoint(pos().x() + width(),
465                 pos().y() + (height()/2));
466 }