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