Salome HOME
5d9c498d3513f3fac2fde17fa4063d040f2f9565
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_CanvasControlNode.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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File   : SUPERVGUI_CanvasControlNode.cxx
23 //  Author : Natalia KOPNOVA
24 //  Module : SUPERV
25
26 #include "SUPERVGUI_CanvasControlNode.h"
27 #include "SUPERVGUI_CanvasControlNodePrs.h"
28 #include "SUPERVGUI_CanvasCellNodePrs.h"
29 #include "SUPERVGUI_Clipboard.h"
30 #include "SUPERVGUI_Main.h"
31 #include "SUPERVGUI.h"
32 #include "SUPERVGUI_Canvas.h"
33
34 #include "SUIT_FileDlg.h"
35 #include "SUIT_Session.h"
36
37 #include <qlabel.h>
38 #include <qlayout.h>
39
40 //=====================================================================
41 // Compute node
42 //=====================================================================
43 SUPERVGUI_CanvasComputeNode::SUPERVGUI_CanvasComputeNode( SUIT_ResourceMgr* mgr, QObject* theParent, SUPERVGUI_Main* theMain, SUPERV_CNode theNode):
44   SUPERVGUI_CanvasNode( mgr, theParent, theMain, theNode)
45 {
46   Trace("SUPERVGUI_CanvasComputeNode::SUPERVGUI_CanvasComputeNode");
47 }
48
49 QPopupMenu* SUPERVGUI_CanvasComputeNode::getPopupMenu(QWidget* theParent) 
50 {
51   QPopupMenu* popup = SUPERVGUI_CanvasNode::getPopupMenu(theParent);
52
53   QPopupMenu* aShowPopup = new QPopupMenu(theParent);
54   int anItem;
55   anItem = aShowPopup->insertItem(tr("POP_SHOWTITLES"), this, SLOT(switchLabel()));
56   aShowPopup->setItemChecked(anItem, getPrs()->isLabelVisible());
57   anItem = aShowPopup->insertItem(tr("POP_SHOWPORTS"), this, SLOT(switchPorts()));
58   aShowPopup->setItemChecked(anItem, getPrs()->isPortVisible());
59
60   popup->insertSeparator();
61   popup->insertItem(tr("POP_SHOW"), aShowPopup);
62
63   return popup;
64 }
65
66
67 //=====================================================================
68 // Start control node
69 //=====================================================================
70 SUPERVGUI_CanvasStartNode::SUPERVGUI_CanvasStartNode(SUIT_ResourceMgr* mgr, QObject* theParent, SUPERVGUI_Main* theMain, SUPERV_CNode theNode):
71   SUPERVGUI_CanvasNode( mgr, theParent, theMain, theNode), 
72   myCoupled(0)
73 {
74   Trace("SUPERVGUI_CanvasStartNode::SUPERVGUI_CanvasStartNode");
75 }
76
77 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasStartNode::createPrs() const
78 {
79   return new SUPERVGUI_CanvasStartNodePrs( resMgr(), getMain()->getCanvas(), 
80                                            (SUPERVGUI_CanvasStartNode*)this);
81 }
82
83 bool SUPERVGUI_CanvasStartNode::setNodeName(QString aName)
84 {
85   bool result = SUPERVGUI_CanvasNode::setNodeName(aName);
86   if (result && myCoupled) {
87     myCoupled->setNodeName(QString(tr("ENDNODE_PREFIX"))+aName);
88   }
89   return result;
90 }
91
92 QPopupMenu* SUPERVGUI_CanvasStartNode::getPopupMenu(QWidget* theParent) 
93 {
94   QPopupMenu* popup = SUPERVGUI_CanvasNode::getPopupMenu(theParent);
95
96   popup->insertSeparator();
97   int anItem = popup->insertItem(tr("POP_HIDEPORTS"), this, SLOT(switchPorts()));
98   popup->setItemChecked(anItem, !getPrs()->isPortVisible());
99
100   return popup;
101 }
102
103 void SUPERVGUI_CanvasStartNode::remove()
104 {
105   SUPERVGUI_Canvas* aCanvas = getMain()->getCanvas();
106
107   setDestroyed();
108   SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
109   if (myCoupled) {
110
111     //set myCopyPort from Main object to empty if engine of this port is deleted
112     //check if any port of this deleted node has been copied
113     if ( aCB->isCopyPort() )
114       if ( QString(getEngine()->Name()) == QString(aCB->getCopyPort()->Node()->Name())    ||
115            QString(myCoupled->getEngine()->Name()) == QString(aCB->getCopyPort()->Node()->Name()) )
116         aCB->setCopyPort( 0 );
117     
118     myCoupled->setDestroyed();
119   }
120
121   //set myCopyNode from Main object to empty if engine of this node is deleted
122   //check if myCopyNode and this node engine is equal
123   if ( aCB->isCopyNode() )
124     if ( QString(getEngine()->Name()) == QString(aCB->getCopyNode()->Name()) ) 
125       aCB->setCopyNode( 0 );
126
127   // mkr: since the deletion of the node allow only in CANVAS view,
128   // it is necessary to remove the CanvasArray's children, which
129   // have the same CNode engine as deleting node
130   getMain()->removeArrayChild(getEngine());
131   getMain()->removeArrayChild(myCoupled->getEngine());
132
133   getEngine()->destroy();
134
135   if (myCoupled) 
136     delete myCoupled;
137
138   delete this;
139
140   aCanvas->update();
141 }
142
143 void SUPERVGUI_CanvasStartNode::onDestroyed(QObject* theObject)
144 {
145   if (!isIgnore) {
146     SUPERVGUI_CanvasNode::onDestroyed(theObject);
147     if (getEngine()->IsLoop()) merge();
148     if (myCoupled) myCoupled->merge();
149   }
150 }
151
152 // mkr : IPAL9815 : commented the following code
153 /*void SUPERVGUI_CanvasStartNode::addInputPort()
154 {
155   SUPERVGUI_CanvasNode::addInputPort();
156   if (getEngine()->IsLoop()) merge();
157   if (myCoupled) myCoupled->merge();
158 }
159
160 void SUPERVGUI_CanvasStartNode::addOutputPort()
161 {
162   SUPERVGUI_CanvasNode::addOutputPort();
163   if (myCoupled) myCoupled->merge();
164 }*/
165  
166 void SUPERVGUI_CanvasStartNode::pastePort()
167 {
168   SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
169   SUPERVGUI_CanvasNode::pastePort();
170   if ( aCB->getCopyPort()->IsInput() && getEngine()->IsLoop() ) 
171     merge();
172   if ( myCoupled )
173     myCoupled->merge();
174 }
175
176 //=====================================================================
177 // End control node
178 //=====================================================================
179 SUPERVGUI_CanvasEndNode::SUPERVGUI_CanvasEndNode(SUIT_ResourceMgr* mgr, QObject* theParent, SUPERVGUI_Main* theMain,
180                                                  SUPERV_CNode theNode, SUPERVGUI_CanvasStartNode* theStart):
181   SUPERVGUI_CanvasNode(mgr, theParent, theMain, theNode), 
182   myCoupled(theStart)
183 {
184   Trace("SUPERVGUI_CanvasEndNode::SUPERVGUI_CanvasEndNode");
185   myCoupled->setCoupled(this);
186 }
187
188 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasEndNode::createPrs() const
189 {
190   return new SUPERVGUI_CanvasEndNodePrs( resMgr(), getMain()->getCanvas(), 
191                                          (SUPERVGUI_CanvasEndNode*)this);
192 }
193
194 QPopupMenu* SUPERVGUI_CanvasEndNode::getPopupMenu(QWidget* theParent) 
195 {
196   QPopupMenu* popup = SUPERVGUI_CanvasNode::getPopupMenu(theParent);
197
198   popup->insertSeparator();
199   int anItem = popup->insertItem(tr("POP_HIDEPORTS"), this, SLOT(switchPorts()));
200   popup->setItemChecked(anItem, !getPrs()->isPortVisible());
201
202   return popup;
203 }
204
205 // mkr : IPAL9815 : commented the following code
206 /*void SUPERVGUI_CanvasEndNode::addInputPort()
207 {
208   SUPERVGUI_CanvasNode::addInputPort();
209   if (getEngine()->IsEndSwitch()) merge();
210 }*/
211
212
213 //=====================================================================
214 // Goto control node
215 //=====================================================================
216 SUPERVGUI_CanvasGotoNode::SUPERVGUI_CanvasGotoNode(SUIT_ResourceMgr* mgr, QObject* theParent, SUPERVGUI_Main* theMain, SUPERV_CNode theNode):
217   SUPERVGUI_CanvasNode(mgr, theParent, theMain, theNode)
218 {
219   Trace("SUPERVGUI_CanvasGotoNode::SUPERVGUI_CanvasGotoNode");
220 }
221
222 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasGotoNode::createPrs() const
223 {
224   return new SUPERVGUI_CanvasGotoNodePrs( resMgr(), getMain()->getCanvas(), 
225                                           (SUPERVGUI_CanvasGotoNode*)this);
226 }
227
228 QPopupMenu* SUPERVGUI_CanvasGotoNode::getPopupMenu(QWidget* theParent) 
229 {
230   QPopupMenu* popup = SUPERVGUI_CanvasNode::getPopupMenu(theParent);
231
232   popup->insertSeparator();
233   popup->insertItem("Link to Node...", this, SLOT(linkToNode()));
234
235   popup->insertSeparator();
236   int anItem = popup->insertItem(tr("POP_HIDEPORTS"), this, SLOT(switchPorts()));
237   popup->setItemChecked(anItem, !getPrs()->isPortVisible());
238
239   return popup;
240 }
241
242 void SUPERVGUI_CanvasGotoNode::linkToNode() {
243   SUPERVGUI_SelectInlineDlg* aDlg = new SUPERVGUI_SelectInlineDlg(getMain());
244   if (aDlg->exec()) {
245     QString aNodeName = aDlg->getName();
246     if (!aNodeName.isEmpty()) { //implement additional check from GUI side for bug PAL7007
247       getGotoNode()->SetCoupled(aNodeName.latin1());
248       getMain()->getCanvas()->sync();
249     }
250   }
251   delete aDlg;
252 }
253
254 //=====================================================================
255 // Macro node
256 //=====================================================================
257 SUPERVGUI_CanvasMacroNode::SUPERVGUI_CanvasMacroNode(SUIT_ResourceMgr* mgr, QObject* theParent, SUPERVGUI_Main* theMain, SUPERV_CNode theNode):
258   SUPERVGUI_CanvasComputeNode(mgr, theParent, theMain, theNode)
259 {
260   Trace("SUPERVGUI_CanvasMacroNode::SUPERVGUI_CanvasMacroNode");
261 }
262
263 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasMacroNode::createPrs() const
264 {
265   return new SUPERVGUI_CanvasMacroNodePrs( resMgr(), getMain()->getCanvas(), 
266                                            (SUPERVGUI_CanvasMacroNode*)this);
267 }
268
269 QPopupMenu* SUPERVGUI_CanvasMacroNode::getPopupMenu(QWidget* theParent) 
270 {
271   QPopupMenu* popup = SUPERVGUI_CanvasComputeNode::getPopupMenu(theParent);
272
273   popup->insertSeparator(0);
274   popup->insertItem(tr("MSG_EXPORT"), this, SLOT(exportDataflow()), 0, -1, 0);
275   popup->insertItem("Open SubGraph", this, SLOT(openSubGraph()), 0, -1, 0);
276
277   return popup;
278 }
279
280 void SUPERVGUI_CanvasMacroNode::openSubGraph()
281 {
282   getMain()->openSubGraph(getEngine());
283 }
284
285 void SUPERVGUI_CanvasMacroNode::exportDataflow()
286 {
287   SUPERV_Graph aGraph;
288   if (getEngine()->IsMacro()) {
289     SUPERV_Graph aMacro = getMacroNode();
290     if (aMacro->IsStreamMacro())
291       aGraph = aMacro->StreamObjRef();
292     else
293       aGraph = aMacro->FlowObjRef();
294   }
295   if (SUPERV_isNull(aGraph)) {
296     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_EXPORT"));
297     return;
298   }
299   else {
300     QString aFileName = SUIT_FileDlg::getFileName(SUIT_Session::session()->activeApplication()->desktop(),
301                                                   "",
302                                                   "*.xml",
303                                                   tr("TTL_EXPORT_DATAFLOW"),
304                                                   false);
305     if ( !aFileName.isEmpty() ) {
306       // asv : bug [VSR Bugs and Improvements in Supervisor] 1.8 : when exporting a file, 
307       // a backup copy of an existing file must be created (in case Export fails..)
308       QString aBackupFile = SUPERVGUI::createBackupFile( aFileName );
309
310       if (!aGraph->Export(aFileName.latin1())) {
311         QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_BAD_WRITING").arg(aBackupFile));
312       }
313       // remove a backup file if export was successfull
314       else if ( !aBackupFile.isNull() && !aBackupFile.isEmpty() ) {
315         QFile::remove( aBackupFile );
316       }
317     }
318   }
319 }
320
321 // mkr : IPAL11549 : before remove Macro Node we have to destroy
322 //                   all its opened sub-graphs
323 void SUPERVGUI_CanvasMacroNode::remove()
324 {
325   SUPERV_Graph aGraph;
326   if (getEngine()->IsMacro()) {
327     SUPERV_Graph aMacro = getMacroNode();
328     if (aMacro->IsStreamMacro())
329       aGraph = aMacro->StreamObjRef();
330     else
331       aGraph = aMacro->FlowObjRef();
332   }
333   if (SUPERV_isNull(aGraph)) {
334     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NOSUBGRAPH_TO_REMOVE"));
335     return;
336   }
337   else {
338     getMain()->destroySubGraph(aGraph->Name());
339   }
340
341   SUPERVGUI_CanvasNode::remove();
342 }
343
344 //=====================================================================
345 // Cell node: node for table view
346 //=====================================================================
347 SUPERVGUI_CanvasCellNode::SUPERVGUI_CanvasCellNode(SUIT_ResourceMgr* mgr, QObject* theParent, 
348                                                    SUPERVGUI_Main* theMain, 
349                                                    SUPERV_CNode theNode):
350   SUPERVGUI_CanvasNode(mgr, theParent, theMain, theNode, true)
351 {
352   Trace("SUPERVGUI_CanvasCellNode::SUPERVGUI_CanvasCellNode");
353   
354   myIsControl = false;
355   myIsStart = false;
356
357   //check for control nodes
358   if (getEngine()->IsLoop() || getEngine()->IsSwitch()) {
359     myIsControl = true;  
360     myIsStart = true;
361   }
362   if (getEngine()->IsEndLoop() || getEngine()->IsEndSwitch())
363     myIsControl = true;
364 }
365
366 SUPERVGUI_CanvasCellNode::~SUPERVGUI_CanvasCellNode()
367 {
368 }
369 /*
370 QPopupMenu* SUPERVGUI_CanvasCellNode::getPopupMenu(QWidget* theParent)
371 {
372   QPopupMenu* popup = SUPERVGUI_CanvasNode::getPopupMenu(theParent);
373   popup->setItemEnabled(myDeleteItem, false);
374   return popup;
375 }
376 */
377 void SUPERVGUI_CanvasCellNode::setPairCell(SUPERVGUI_CanvasCellNode* thePairCell) {
378   if (myIsControl) { //only for ControlNode
379     myPairCell = thePairCell;
380   }
381   else 
382     myPairCell = 0;
383 }
384
385 SUPERVGUI_CanvasCellNode* SUPERVGUI_CanvasCellNode::getPairCell() {
386   return myPairCell;
387 }
388
389 void SUPERVGUI_CanvasCellNode::sync() {
390   const bool isExecuting = getMain()->getDataflow()->IsExecuting();
391   //if getEngine() is a MacroNode then set it state to state of its subgraph
392   if ( getEngine()->IsMacro() && isExecuting ) {
393     // get SubGraph from MacroNode
394     SUPERV_Graph aMacro = SUPERV::Graph::_narrow(getEngine());
395     if (!SUPERV_isNull(aMacro)) {
396       SUPERV_Graph aGraph;
397       if (aMacro->IsStreamMacro())
398         aGraph = aMacro->StreamObjRef();
399       else
400         aGraph = aMacro->FlowObjRef();
401       if (!SUPERV_isNull(aGraph)) {
402         if (aGraph->State() != SUPERV::UndefinedState && aGraph->State() != SUPERV::NoState)
403           getPrs()->setState(aGraph->State());
404         else 
405           getPrs()->setState(getEngine()->State());
406       }
407     }
408   }
409   else {
410     getPrs()->setState(getEngine()->State());
411   }
412 }
413 /*
414 bool SUPERVGUI_CanvasCellNode::setNodeName(QString aName) 
415 {
416   bool result = SUPERVGUI_CanvasNode::setNodeName(aName);
417   if (result && myPairCell) {
418     result = myPairCell->setNodeName(QString(tr("ENDNODE_PREFIX"))+aName);
419   }
420   return result;
421 }
422 */
423 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasCellNode::createPrs() const
424 {
425   SUPERVGUI_CanvasNodePrs* aPrs = 
426     new SUPERVGUI_CanvasCellNodePrs( resMgr(), getMain()->getCanvasArray(), 
427                                      (SUPERVGUI_CanvasCellNode*)this);
428   return aPrs;
429 }
430
431 SUPERVGUI_CanvasCellEndNode::SUPERVGUI_CanvasCellEndNode( SUIT_ResourceMgr* mgr, QObject* theParent, 
432                                                           SUPERVGUI_Main* theMain, 
433                                                           SUPERV_CNode theNode, 
434                                                           SUPERVGUI_CanvasCellNode* theStart):
435   SUPERVGUI_CanvasCellNode(mgr, theParent, theMain, theNode)
436 {
437   //set start cell for end cell as pair 
438   myPairCell = theStart; 
439   //set end cell for start cell as pair
440   myPairCell->setPairCell(dynamic_cast<SUPERVGUI_CanvasCellNode*>(this));
441 }
442 /*
443 bool SUPERVGUI_CanvasCellEndNode::setNodeName(QString theName)
444 {
445   return SUPERVGUI_CanvasNode::setNodeName(theName);
446 }
447 */
448 //-----------------------------------------------------------
449 //*************** Select Inline node dialog******************
450 // Taken from SUPERVGUI_ControlNode.cxx without change
451 //-----------------------------------------------------------
452
453 SUPERVGUI_SelectInlineDlg::SUPERVGUI_SelectInlineDlg(SUPERVGUI_Main* theMain)  
454   :QDialog(theMain, 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
455 {
456   setSizeGripEnabled( true );
457   setCaption(tr("TIT_FUNC_PYTHON"));
458   QGridLayout* aMainLayout = new QGridLayout(this, 2, 2, 7, 4);
459
460   QLabel* aLabel = new QLabel("Connect to", this );
461   aMainLayout->addWidget(aLabel, 0, 0);
462
463   myCombo = new QComboBox(this);
464   myCombo->clear(); //for the additional check from GUI side for bug PAL7007
465   SUPERV_Nodes aNodesList = theMain->getDataflow()->Nodes();  
466   int i;
467   for (i = 0; i < aNodesList->INodes.length(); i++) {
468     myCombo->insertItem(QString(aNodesList->INodes[i]->Name()));
469   }
470   for (i = 0; i < aNodesList->LNodes.length(); i++) {
471     myCombo->insertItem(QString(aNodesList->LNodes[i]->Name()));
472   }
473   for (i = 0; i < aNodesList->SNodes.length(); i++) {
474     myCombo->insertItem(QString(aNodesList->SNodes[i]->Name()));
475   }
476   aMainLayout->addWidget(myCombo, 0, 1);
477
478   QGroupBox* aBtnBox = new QGroupBox( this );
479   aBtnBox->setColumnLayout( 0, Qt::Vertical );
480   aBtnBox->layout()->setSpacing( 0 ); aBtnBox->layout()->setMargin( 0 );
481   QHBoxLayout* aBtnLayout = new QHBoxLayout( aBtnBox->layout() );
482   aBtnLayout->setAlignment( Qt::AlignTop );
483   aBtnLayout->setSpacing( 6 ); aBtnLayout->setMargin( 11 );
484   
485   QPushButton* aOKBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
486   connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
487   aBtnLayout->addWidget( aOKBtn );
488
489   aBtnLayout->addStretch();
490
491   QPushButton* aCancelBtn = new QPushButton( tr("BUT_CANCEL"), aBtnBox );
492   connect( aCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
493   aBtnLayout->addWidget( aCancelBtn );
494
495   aMainLayout->addMultiCellWidget(aBtnBox, 1, 1, 0, 1);
496 }