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