Salome HOME
MPV: Merge V1_2d
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_Port.cxx
1 //  SUPERV SUPERVGUI : GUI for Supervisor component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SUPERVGUI_Port.cxx
25 //  Author : Francis KLOSS
26 //  Module : SUPERV
27
28 using namespace std;
29 #include "SUPERVGUI_Port.h"
30 #include "SUPERVGUI_Def.h"
31 #include "SUPERVGUI_Main.h"
32 #include "SUPERVGUI_Link.h"
33 #include "SUPERVGUI.h"
34 #include "SUPERVGUI_BrowseNodeDlg.h"
35 #include "QAD_LeftFrame.h"
36 #include "QAD_ObjectBrowser.h"
37 #include <qpoint.h>
38 #include "SUPERVGUI_GraphNode.h"
39
40
41 // Port en general
42 // ---------------
43
44 SUPERVGUI_Port::SUPERVGUI_Port(QWidget* parent, SUPERVGUI_Main* m, SUPERV_Port p):
45     SUPERVGUI_Label(parent, PORT_WIDTH, PORT_HEIGHT, "", QLabel::AlignLeft | QLabel::AlignVCenter),
46     main(m),
47     port(p)
48 {
49   Trace("SUPERVGUI_Port::SUPERVGUI_Port");
50   myName = port->Name();
51   QString aName(port->Name());
52   aName += (port->IsInput())? "Input":"Output";
53   setName(aName);
54
55   if (myName.compare(OUTVOID) == 0)
56     setAlignment(QLabel::AlignRight | QLabel::AlignVCenter);
57
58   if (port->IsParam() || port->IsInLine())
59     setText(myName + "=" +  port->ToString());
60   else
61     setText(myName);
62     
63   setLineWidth(1);
64   setMidLineWidth(2);
65   setFrameShape(QLabel::Box);
66   setFrameShadow(QLabel::Plain);
67
68   popup = new QPopupMenu(this);
69   if (main->isEditable()) {
70     mySketchItem = popup->insertItem(tr("MSG_SKETCH_LINK"), this, SLOT(sketchLink()));
71     popup->insertSeparator();
72   }
73   //for Loop Node: enable "Delete" popup item only for the input port 
74   if ( ( port->IsInLine() 
75          && 
76          ( port->Node()->Kind()!=SUPERV::EndLoopNode )
77          &&
78          !( port->Node()->Kind()==SUPERV::LoopNode && !port->IsInput() )
79        )
80        ||
81        ( port->IsEndSwitch() && port->IsInput())) {
82     myDelItem = popup->insertItem(tr("ITM_DEL_PORT"), this, SLOT(deletePort()));    
83   }
84   connect(this, SIGNAL(MousePress(QMouseEvent*)), this, SLOT(showPopup(QMouseEvent*)));  
85   connect(this, SIGNAL(MouseRelease(QMouseEvent*)), this, SLOT(endSketch()));
86 }
87
88 SUPERVGUI_Port::~SUPERVGUI_Port() {
89     Trace("SUPERVGUI_Port::~SUPERVGUI_Port")
90 }
91
92 SUPERV_Port SUPERVGUI_Port::getPort() {
93     Trace("SUPERVGUI_Port::getPort")
94     return(port);
95 }
96
97 void SUPERVGUI_Port::showPopup(QMouseEvent* e) {
98   Trace("SUPERVGUI_Port::showPopup");
99   if (e->button() != RightButton) return;
100   if (main->getDataflow()->IsExecuting()) 
101     popup->setItemEnabled(mySketchItem, false);
102   else  
103     if (!port->IsInput() //output port
104         || 
105         port->IsInput() && (!port->IsLinked() //not linked input port
106                             ||
107                             port->Kind() == SUPERV::EndSwitchParameter)) { //input port of EndSwitch node
108       popup->setItemEnabled(mySketchItem, true);
109     }
110       
111   main->showPopup(popup, e);
112 }
113
114
115 QPoint SUPERVGUI_Port::getConnectPnt() {
116   return QPoint(0,0);
117 }
118
119
120 void SUPERVGUI_Port::sync() {
121   if (port->IsParam() || port->IsInLine())
122     setText(myName + "=" +  port->ToString());
123   else
124     setText(myName);
125
126 }
127
128
129 void SUPERVGUI_Port::sketchLink() {
130   main->getGraph()->sketchBegin(this);
131   if (port->IsInput()) 
132     setLineWidth(1);
133 }
134
135 void SUPERVGUI_Port::endSketch() {
136   main->getGraph()->sketchEnd(this);
137   if (port->IsInput() && port->IsLinked()) 
138     setLineWidth(1);
139 }
140
141
142 void SUPERVGUI_Port::deletePort() {
143   SUPERVGUI_GraphNode*  aNode = (SUPERVGUI_GraphNode* )main->getGraph()->child(port->Node()->Name(), "SUPERVGUI_GraphNode");
144   if (aNode) {
145     aNode->deletePort(this);
146   }
147 }
148
149
150
151
152 //***********************************************************
153 // Port d'entree
154 // -------------
155
156 SUPERVGUI_PortIn::SUPERVGUI_PortIn(QWidget* parent, SUPERVGUI_Main* m, SUPERV_Port p)
157   : SUPERVGUI_Port(parent, m, p), myDlg( 0 )
158 {
159   Trace("SUPERVGUI_PortIn::SUPERVGUI_PortIn");
160   myLinkPrs = 0;
161   //    link->move(0, height()/2-POINT_SIZE_HALF);
162
163   bool editing = port->IsInput() && ( !port->IsLinked() ); //main->isEditable();
164 //  bool linked  = port->IsLinked();
165 //  bool b = (!linked) && editing;
166   if ((!port->IsGate())  && editing ) {
167     psc = popup->insertItem(tr("MSG_SETVALUE"),      this, SLOT(setInput()));
168   }
169   browser = popup->insertItem(tr("MSG_BROWSE"),         this, SLOT(browse()));
170 }
171
172 SUPERVGUI_PortIn::~SUPERVGUI_PortIn() {
173   Trace("SUPERVGUI_PortIn::~SUPERVGUI_PortIn");
174 }
175
176
177 bool SUPERVGUI_PortIn::eventFilter( QObject* o, QEvent* e )
178 {
179   if ( o == myDlg && e->type() == QEvent::Close )
180     myDlg = 0;
181   return SUPERVGUI_Port::eventFilter( o, e );
182 }
183
184
185 void SUPERVGUI_PortIn::deleteLinks() {
186   if (myLinkPrs) {
187     disconnect(myLinkPrs, 0, this, 0);
188     main->getGraph()->deleteLink(myLinkPrs);
189     myLinkPrs = 0;
190   }
191 }
192
193
194 void SUPERVGUI_PortIn::sync() {
195   SUPERVGUI_Port::sync();
196   if (port->IsLinked()) {
197     popup->setItemEnabled(browser, port->State() == SUPERV_Ready);
198   } else {
199     if (port->HasInput()) {
200       popup->setItemEnabled(browser, true);
201       setLineWidth(2);
202     } else {
203       popup->setItemEnabled(browser, false);
204       setLineWidth(1);
205     }
206   }
207 }
208
209 void SUPERVGUI_PortIn::setValue(const char* d) {
210     Trace("SUPERVGUI_PortIn::setValue")
211     if (port->Input(Supervision.getEngine()->StringValue(d))) {
212         sync();
213     } else {
214         QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_SETVAL"));
215     };
216 }
217
218 void SUPERVGUI_PortIn::setInput() {
219     Trace("SUPERVGUI_PortIn::setInput");
220     if ( !myDlg ) {
221       myDlg = new SUPERVGUI_GetValueDlg(this);
222       myDlg->installEventFilter( this );
223     }
224     if ( !myDlg->isVisible() )
225       myDlg->show();
226     else {
227       myDlg->raise();
228       myDlg->setActiveWindow();
229       myDlg->setFocus();
230     }
231 }
232
233 void SUPERVGUI_PortIn::browse() {
234     Trace("SUPERVGUI_PortIn::browse")
235     QString mess(tr("MSG_IPORT_VAL"));
236     mess += port->ToString();
237     QMessageBox::information(QAD_Application::getDesktop(), tr("MSG_INFO"), mess);
238 }
239
240
241
242 /**
243  * Returns coordinates of connection point in content coordinates
244  */
245 QPoint SUPERVGUI_PortIn::getConnectPnt() {
246   // Parent widget is internal node frame
247   // parent of parent is node it self
248   QWidget* aNode = parentWidget()->parentWidget()->parentWidget();
249   QPoint aPnt(aNode->pos()); // position of the node
250
251   if (parentWidget()->isVisible()) {
252     aPnt += parentWidget()->parentWidget()->pos();
253     aPnt += parentWidget()->pos();
254     return QPoint(aPnt.x() + pos().x(), 
255                   aPnt.y() + (pos().y() + height()/2));
256   }
257   return QPoint(aPnt.x(), 
258                 aPnt.y() + (aNode->height()/2));
259 }
260
261 void SUPERVGUI_PortIn::setLinkPrs(SUPERVGUI_Link* theLink) {
262   myLinkPrs = theLink;
263   connect(myLinkPrs, SIGNAL(linkDeleted(SUPERVGUI_Link*)),
264           this, SLOT(onDeleteLink(SUPERVGUI_Link*)));
265   popup->setItemEnabled(mySketchItem, false);
266 }
267
268 void SUPERVGUI_PortIn::onDeleteLink(SUPERVGUI_Link*) {
269   disconnect(myLinkPrs, 0, this, 0);
270   myLinkPrs = 0;
271   popup->setItemEnabled(psc, true);
272   if (port->HasInput())
273     setLineWidth(2);
274   if (main->isEditable()) {
275     popup->setItemEnabled(mySketchItem, true);
276   } else {
277     popup->setItemEnabled(mySketchItem, false);
278   }
279 }
280
281
282
283 //***********************************************************
284 // Port de sortie
285 // --------------
286
287 SUPERVGUI_PortOut::SUPERVGUI_PortOut(QWidget* parent, SUPERVGUI_Main* m, SUPERV_Port p):
288     SUPERVGUI_Port(parent, m, p),
289     study(false)
290 {
291     Trace("SUPERVGUI_PortOut::SUPERVGUI_PortOut")
292       //    link->move(width()-POINT_SIZE, height()/2-POINT_SIZE_HALF);
293     myLinksList.setAutoDelete(false);
294     
295     if (!port->IsGate()) {
296       pls = popup->insertItem(tr("MSG_PUT_INSTUDY"), this, SLOT(toStudy()));
297     }
298     browser = popup->insertItem(tr("MSG_BROWSE"), this, SLOT(browse()));
299
300     if (!main->getDataflow()->IsReadOnly()) {
301       popup->setItemEnabled(mySketchItem, true);
302     } else {
303       popup->setItemEnabled(mySketchItem, false);
304     }
305 }
306
307 SUPERVGUI_PortOut::~SUPERVGUI_PortOut() {
308   Trace("SUPERVGUI_PortOut::~SUPERVGUI_PortOut");
309 }
310
311 void SUPERVGUI_PortOut::sync() {
312     Trace("SUPERVGUI_PortOut::sync")
313     SUPERVGUI_Port::sync();
314
315     bool ok = (port->State() == SUPERV_Ready);
316     popup->setItemEnabled(browser, ok);
317     if (study && ok) {
318       study = main->putDataStudy(port, STUDY_PORT_OUT);
319     }
320
321     if (study) {
322         setLineWidth(2);
323         popup->changeItem(pls, tr("MSG_NOT_INSTUDY"));
324     } else {
325         setLineWidth(1);
326         popup->changeItem(pls, tr("MSG_PUT_INSTUDY"));
327     }
328
329 }
330
331 void SUPERVGUI_PortOut::updateStudy() {
332   Trace("SUPERVGUI_PortOut::updateStudy")
333   SUPERVGUI_Node*  aNode = (SUPERVGUI_Node* )main->getGraph()->child(port->Node()->Name(), "SUPERVGUI_Node");
334   if (aNode)
335     ((SUPERVGUI_PortOut*)aNode->child(port->Name(), "SUPERVGUI_PortOut"))->study = study;
336   else
337     {
338       aNode = (SUPERVGUI_Node* )main->getArray()->child(port->Node()->Name(), "SUPERVGUI_Node");
339       if (aNode)
340         ((SUPERVGUI_PortOut*)aNode->child(port->Name(), "SUPERVGUI_PortOut"))->study = study;
341     }
342 }
343
344 void SUPERVGUI_PortOut::toStudy() {
345     Trace("SUPERVGUI_PortOut::toStudy")
346
347     if (main->getStudy()->getStudyDocument()->GetProperties()->IsLocked()) {
348       QMessageBox::warning(QAD_Application::getDesktop(), tr("WRN_WARNING"), tr("WRN_STUDY_LOCKED"));
349       return;
350     }
351
352     if (!main->isFromStudy()) {
353       if (main->addStudy()) main->setAsFromStudy(true);
354     }
355     study = !study;
356     sync();
357 }
358
359 void SUPERVGUI_PortOut::browse() {
360     Trace("SUPERVGUI_PortOut::browse")
361     QString mess(tr("MSG_OPORT_VAL"));
362     mess += port->ToString();
363     QMessageBox::information(QAD_Application::getDesktop(), tr("MSG_INFO"), mess);
364 }
365
366
367 /**
368  * Returns coordinates of connection point in scroll view content coordinates
369  */
370 QPoint SUPERVGUI_PortOut::getConnectPnt() {
371   // Parent widget is internal node frame
372   // parent of parent is node it self
373   QWidget* aNode = parentWidget()->parentWidget()->parentWidget();
374   QPoint aPnt(aNode->pos()); // position of the node
375   if (parentWidget()->isVisible()) {
376     aPnt += parentWidget()->parentWidget()->pos();
377     aPnt += parentWidget()->pos();
378     return QPoint(aPnt.x() + pos().x() + width(), 
379                   aPnt.y() + (pos().y() + height()/2));
380   }
381   return QPoint(aPnt.x() + aNode-> width(),
382                 aPnt.y() + (aNode->height()/2));
383 }
384
385
386 void SUPERVGUI_PortOut::addLinkPrs(SUPERVGUI_Link* theLink) {
387   myLinksList.append(theLink);
388   connect(theLink, SIGNAL(linkDeleted(SUPERVGUI_Link*)),
389           this, SLOT(onDeleteLink(SUPERVGUI_Link*)));
390 }
391
392
393 void SUPERVGUI_PortOut::onDeleteLink(SUPERVGUI_Link* theLink) {
394   disconnect(theLink, 0, this, 0);
395   myLinksList.remove(theLink);
396 }
397
398
399 void SUPERVGUI_PortOut::deleteLinks() {
400   if (myLinksList.count() > 0) {
401     SUPERVGUI_Link* aLink;
402     while (aLink = myLinksList.last()) {
403       disconnect(aLink, 0, this, 0); 
404       myLinksList.remove(aLink);
405       main->getGraph()->deleteLink(aLink);
406     }
407   }
408 }
409
410
411
412 // ----------------------------
413 // Input Port of EndSwitch Node
414 // ----------------------------
415 SUPERVGUI_PortInESNode::SUPERVGUI_PortInESNode(QWidget* parent, SUPERVGUI_Main* m, SUPERV_Port p)
416   : SUPERVGUI_Port(parent, m, p), myDlg( 0 )
417 {
418   Trace("SUPERVGUI_PortInESNode::SUPERVGUI_PortInESNode");
419   myLinksList.setAutoDelete(false);
420
421   bool editing = port->IsInput() && ( !port->IsLinked() ); //main->isEditable();
422   if ((!port->IsGate())  && editing ) {
423     psc = popup->insertItem(tr("MSG_SETVALUE"),this, SLOT(setInput()));
424   }
425   browser = popup->insertItem(tr("MSG_BROWSE"),this, SLOT(browse()));
426 }
427
428 SUPERVGUI_PortInESNode::~SUPERVGUI_PortInESNode() {
429   Trace("SUPERVGUI_PortInESNode::~SUPERVGUI_PortInESNode");
430 }
431
432 bool SUPERVGUI_PortInESNode::eventFilter( QObject* o, QEvent* e ) {
433   if ( o == myDlg && e->type() == QEvent::Close )
434     myDlg = 0;
435   return SUPERVGUI_Port::eventFilter( o, e );
436 }
437
438 void SUPERVGUI_PortInESNode::sync() {
439   SUPERVGUI_Port::sync();
440   if (port->IsLinked()) {
441     popup->setItemEnabled(browser, port->State() == SUPERV_Ready);
442   } else {
443     if (port->HasInput()) {
444       popup->setItemEnabled(browser, true);
445       setLineWidth(2);
446     } else {
447       popup->setItemEnabled(browser, false);
448       setLineWidth(1);
449     }
450   }
451 }
452
453 void SUPERVGUI_PortInESNode::setValue(const char* d) {
454     Trace("SUPERVGUI_PortIn::setValue")
455     if (port->Input(Supervision.getEngine()->StringValue(d))) {
456         sync();
457     } else {
458         QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_SETVAL"));
459     };
460 }
461
462 /**
463  * Returns coordinates of connection point in content coordinates
464  */
465 QPoint SUPERVGUI_PortInESNode::getConnectPnt() {
466   QWidget* aNode = parentWidget()->parentWidget()->parentWidget();
467   QPoint aPnt(aNode->pos());
468
469   if (parentWidget()->isVisible()) {
470     aPnt += parentWidget()->parentWidget()->pos();
471     aPnt += parentWidget()->pos();
472     return QPoint(aPnt.x() + pos().x(), 
473                   aPnt.y() + (pos().y() + height()/2));
474   }
475   return QPoint(aPnt.x(), 
476                 aPnt.y() + (aNode->height()/2));
477 }
478
479 void SUPERVGUI_PortInESNode::setLinkPrs(SUPERVGUI_Link* theLink) {
480   myLinksList.append(theLink);
481   connect(theLink, SIGNAL(linkDeleted(SUPERVGUI_Link*)),
482           this, SLOT(onDeleteLink(SUPERVGUI_Link*)));
483 }
484
485 void SUPERVGUI_PortInESNode::deleteLinks() {
486   if (myLinksList.count() > 0) {
487     SUPERVGUI_Link* aLink;
488     while (aLink = myLinksList.last()) {
489       disconnect(aLink, 0, this, 0); 
490       myLinksList.remove(aLink);
491       main->getGraph()->deleteLink(aLink);
492     }
493   }
494 }
495
496 void SUPERVGUI_PortInESNode::setInput() {
497     Trace("SUPERVGUI_PortInESNode::setInput");
498     if ( !myDlg ) {
499       myDlg = new SUPERVGUI_GetValueDlg(this);
500       myDlg->installEventFilter( this );
501     }
502     if ( !myDlg->isVisible() )
503       myDlg->show();
504     else {
505       myDlg->raise();
506       myDlg->setActiveWindow();
507       myDlg->setFocus();
508     }
509 }
510
511 void SUPERVGUI_PortInESNode::browse() {
512     Trace("SUPERVGUI_PortInESNode::browse")
513     QString mess(tr("MSG_IPORT_VAL"));
514     mess += port->ToString();
515     QMessageBox::information(QAD_Application::getDesktop(), tr("MSG_INFO"), mess);
516 }
517
518
519 void SUPERVGUI_PortInESNode::onDeleteLink(SUPERVGUI_Link* theLink) {
520   disconnect(theLink, 0, this, 0);
521   myLinksList.remove(theLink);
522   
523   if (myLinksList.count() == 0) {
524     popup->setItemEnabled(psc, true);
525   } else {
526     popup->setItemEnabled(psc, false);
527   }
528   
529   if (port->HasInput())
530     setLineWidth(2);    
531   
532   if (main->isEditable()) {
533     popup->setItemEnabled(mySketchItem, true);
534   } else {
535     popup->setItemEnabled(mySketchItem, false);
536   }
537 }
538