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