Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / gui / YACSGui_ForEachLoopNodePage.cxx
1 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 // 
4 //  This library is free software; you can redistribute it and/or 
5 //  modify it under the terms of the GNU Lesser General Public 
6 //  License as published by the Free Software Foundation; either 
7 //  version 2.1 of the License. 
8 // 
9 //  This library is distributed in the hope that it will be useful, 
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 //  Lesser General Public License for more details. 
13 // 
14 //  You should have received a copy of the GNU Lesser General Public 
15 //  License along with this library; if not, write to the Free Software 
16 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
17 // 
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20
21 #include <Python.h>
22 #include <PythonNode.hxx>
23
24 #include <SALOME_ResourcesManager.hxx>
25 #include <SALOME_LifeCycleCORBA.hxx>
26
27 #include <YACSGui_InputPanel.h>
28 #include <YACSGui_Module.h>
29 #include <YACSGui_PlusMinusGrp.h>
30 #include <YACSGui_Table.h>
31 #include <YACSGui_Graph.h>
32 #include <YACSGui_Executor.h>
33 #include <YACSGui_TreeView.h>
34 #include <YACSGui_TreeViewItem.h>
35 #include <YACSGui_LogViewer.h>
36
37 #include <YACSPrs_ElementaryNode.h>
38
39 #include <QxGraph_Canvas.h>
40
41 #include <LightApp_Application.h>
42 #include <CAM_Application.h>
43 #include <SUIT_Session.h>
44 #include <SUIT_Application.h>
45 #include <SUIT_MessageBox.h>
46 #include <LogWindow.h>
47
48 #include <InPort.hxx>
49 #include <OutPort.hxx>
50 #include <InputPort.hxx>
51 #include <OutputPort.hxx>
52 #include <CalStreamPort.hxx>
53 #include <ConditionInputPort.hxx>
54 #include <ForLoop.hxx>
55 #include <ForEachLoop.hxx>
56 #include <WhileLoop.hxx>
57 #include <Switch.hxx>
58 #include <CORBAPorts.hxx>
59 #include <PythonPorts.hxx>
60 #include <XMLPorts.hxx>
61 #include <InlineNode.hxx>
62 #include <ServiceNode.hxx>
63 #include <ServiceInlineNode.hxx>
64 #include <CORBANode.hxx>
65 #include <SalomePythonNode.hxx>
66 #include <CppNode.hxx>
67 #include <XMLNode.hxx>
68 #include <Exception.hxx>
69 #include <Catalog.hxx>
70 #include <ComponentDefinition.hxx>
71 #include <CORBAComponent.hxx>
72 #include <CppComponent.hxx>
73 #include <SalomeComponent.hxx>
74 #include <SalomePythonComponent.hxx>
75 #include <RuntimeSALOME.hxx>
76
77 #include <qwindowsstyle.h>
78 #include <qpushbutton.h>
79 #include <qlayout.h>
80 #include <qhbox.h>
81 #include <qlabel.h>
82 #include <qlineedit.h>
83 #include <qbuttongroup.h>
84 #include <qradiobutton.h>
85 #include <qcombobox.h>
86 #include <qtextedit.h>
87 #include <qtoolbutton.h>
88 #include <qspinbox.h>
89 #include <qprogressbar.h>
90 #include <qobjectlist.h>
91 #include <qfiledialog.h>
92 #include <qcheckbox.h>
93
94 #include <sstream>
95
96 #define SPACING 5
97 #define MARGIN 5
98
99 using namespace YACS;
100 using namespace YACS::ENGINE;
101 using namespace YACS::HMI;
102 using namespace std;
103
104
105 /*
106   Class : YACSGui_ForEachLoopNodePage
107   Description :  Page for FOREACH node properties
108 */
109
110 YACSGui_ForEachLoopNodePage::YACSGui_ForEachLoopNodePage( QWidget* theParent, const char* theName, WFlags theFlags )
111   : ForEachLoopNodePage( theParent, theName, theFlags ),
112     YACSGui_NodePage()
113 {
114   connect( myDataPortToDispatchValue, SIGNAL( textChanged( const QString& ) ),
115            this, SLOT( onSeqOfSamplesChanged( const QString& ) ) );
116
117   // TODO: implement presentation of the FOR node in collapsed mode
118   // temporary solution :
119   myCollapsedRadioButton->setEnabled(false );
120
121   connect( myNodeName, SIGNAL(textChanged( const QString& )), this, SLOT(onNodeNameChanged( const QString& )) );
122 }
123
124 YACSGui_ForEachLoopNodePage::~YACSGui_ForEachLoopNodePage()
125 {
126   if (getInputPanel()) getInputPanel()->removePage(this);
127 }
128
129 void YACSGui_ForEachLoopNodePage::setSNode( YACS::HMI::SubjectNode* theSNode )
130 {
131   if ( !theSNode ) return;
132
133   if ( dynamic_cast<ForEachLoop*>( theSNode->getNode() ) )
134     YACSGui_NodePage::setSNode( theSNode );
135 }
136
137 void YACSGui_ForEachLoopNodePage::setMode( const YACSGui_InputPanel::PageMode theMode )
138 {
139   YACSGui_NodePage::setMode(theMode);
140
141   if ( myMode == YACSGui_InputPanel::EditMode )
142   {
143     myNodeName->setReadOnly(false);
144     ViewModeButtonGroup->show();
145
146     ExecutionGroupBox->hide();
147   } 
148   else if ( myMode == YACSGui_InputPanel::RunMode )
149   {
150     myNodeName->setReadOnly(true);
151     ViewModeButtonGroup->hide();
152
153     ExecutionGroupBox->show();
154   }
155 }
156
157 void YACSGui_ForEachLoopNodePage::notifyNodeStatus( int theStatus )
158 {
159   if ( myNodeState )
160   {
161     myNodeState->setPaletteForegroundColor(getColor(theStatus));
162     myNodeState->setText(getText(theStatus));
163   }
164 }
165
166 void YACSGui_ForEachLoopNodePage::notifyNodeProgress()
167 {
168   if ( myProgressBar )
169   {
170     Proc* aProc = dynamic_cast<Proc*>(getNode()->getRootNode());
171     if ( !aProc ) return;
172
173     YACSGui_Graph* aGraph = getInputPanel()->getModule()->getGraph( aProc );
174     if ( !aGraph ) return;
175
176     if ( YACSPrs_ElementaryNode* anItem = aGraph->getItem(getNode()) )
177     {
178       int aProgress = (int)( ( (anItem->getStoredPercentage() < 0) ? anItem->getPercentage() :
179                                                                      anItem->getStoredPercentage() ) );
180       myProgressBar->setProgress(aProgress);
181     }
182   }
183 }
184
185 void YACSGui_ForEachLoopNodePage::notifyInPortValues( std::map<std::string,std::string> theInPortName2Value )
186 {
187   //printf("==> ForEachLoopNodePage : Size of theInPortName2Value : %d\n",theInPortName2Value.size());
188
189   ForEachLoop* aForEachLoopNode = dynamic_cast<ForEachLoop*>( getNode() );
190   if ( !aForEachLoopNode ) return;
191
192   if ( theInPortName2Value.size() == 2 )
193   {
194     QString aName1 = QString(aForEachLoopNode->edGetNbOfBranchesPort()->getName());
195     QString aName2 = QString(aForEachLoopNode->edGetSeqOfSamplesPort()->getName());
196     QString aGivenName, aValue;
197     
198     map<string,string>::iterator it = theInPortName2Value.begin();
199     for ( ; it!=theInPortName2Value.end(); it++ )
200     {
201       aGivenName = QString( (*it).first );
202       aValue = QString( (*it).second );
203       
204       if ( !aGivenName.compare(aName1) && myNbBranchesInputPortValue )
205       { // nbBranches port
206         if ( !aValue.compare(QString("< ? >")) )
207           myNbBranchesInputPortValue->setValue( myNbBranchesInputPortValue->minValue() );
208         else
209           myNbBranchesInputPortValue->setValue( aValue.toInt() );
210       }
211
212       if ( !aGivenName.compare(aName2) && myDataPortToDispatchValue )
213       { // SmplsCollection port
214         myDataPortToDispatchValue->setText( aValue );
215       }
216     }
217   }
218 }
219
220 void YACSGui_ForEachLoopNodePage::notifyOutPortValues( std::map<std::string,std::string> theOutPortName2Value )
221 {
222   //printf("==> ForEachLoopNodePage : Size of theOutPortName2Value : %d\n",theOutPortName2Value.size());
223   // SmplPrt port (no gui control for it in the property page!)
224   //...
225 }
226
227 void YACSGui_ForEachLoopNodePage::notifyNodeCreateBody( YACS::HMI::Subject* theSubject )
228 {
229   if( myLoopBodyNodeName )
230   {
231     QString aBodyName = theSubject->getName();
232     myLoopBodyNodeName->setText( aBodyName );
233   }
234 }
235
236 void YACSGui_ForEachLoopNodePage::checkModifications()
237 {
238   if ( !getNode() ) return;
239
240   // 1) check if the content of the page is really modified (in compare with the content of engine object)
241   bool isModified = false;
242
243   if ( myNodeName->text().compare(getNodeName()) != 0 ) isModified = true;
244   else if ( YACS::ENGINE::ForEachLoop* aForEachLoopNode = dynamic_cast<ForEachLoop*>( getNode() ) )
245   {
246     if( YACS::ENGINE::InputPort* aBranchesPort = aForEachLoopNode->edGetNbOfBranchesPort() )
247     {
248       bool ok;
249       int aValue = getPortValue( aBranchesPort ).toInt( &ok );
250       if( ok && myNbBranchesInputPortValue->value() != aValue ) isModified = true;
251     }
252     if( YACS::ENGINE::InputPort* aSamplesPort = aForEachLoopNode->edGetSeqOfSamplesPort() )
253       if ( myDataPortToDispatchValue->text().compare(getPortValue(aSamplesPort)) ) isModified = true;
254   }
255   
256   //if ( !isModified )
257   //  TODO: compare view mode: expanded or collapsed (not yet in use)    
258   
259   // 2) if yes, show a warning message: Apply or Cancel
260   if ( isModified )
261     if ( SUIT_MessageBox::warn2(getInputPanel()->getModule()->getApp()->desktop(),
262                                 tr("WRN_WARNING"),
263                                 tr("APPLY_CANCEL_MODIFICATIONS"),
264                                 tr("BUT_YES"), tr("BUT_NO"), 0, 1, 0) == 0 )
265     {
266       onApply();
267       if ( getInputPanel() ) getInputPanel()->emitApply(YACSGui_InputPanel::InlineNodeId);
268     }
269 }
270
271 void YACSGui_ForEachLoopNodePage::onApply()
272 {
273   // Rename a node
274   if ( myNodeName ) setNodeName( myNodeName->text() );
275   
276   // Reset number of brances input port value and data port to dispatch value
277   if ( YACS::ENGINE::ForEachLoop* aForEachLoopNode = dynamic_cast<ForEachLoop*>( getNode() ) )
278   {
279     if( YACS::ENGINE::InputPort* aBranchesPort = aForEachLoopNode->edGetNbOfBranchesPort() )
280     {
281       int aValue = myNbBranchesInputPortValue->value();
282       aBranchesPort->edInit( aValue );
283       mySNode->update( EDIT, INPUTPORT, GuiContext::getCurrent()->_mapOfSubjectDataPort[aBranchesPort] );
284     }
285
286     if( YACS::ENGINE::InputPort* aSamplesPort = aForEachLoopNode->edGetSeqOfSamplesPort() )
287     {
288       QString aValue = myDataPortToDispatchValue->text();
289       aSamplesPort->edInit( aValue.latin1() );
290       mySNode->update( EDIT, INPUTPORT, GuiContext::getCurrent()->_mapOfSubjectDataPort[aSamplesPort] );
291     }
292   }
293
294   // Reset the view mode
295   // ...
296
297   updateBlocSize();
298 }
299
300 void YACSGui_ForEachLoopNodePage::updateState()
301 {
302   // Set node name
303   if ( myNodeName ) myNodeName->setText( getNodeName() );
304
305   // Set node full name (read only)
306   if ( myNodeFullName )
307     myNodeFullName->setText( getNode()->getRootNode()->getChildName(getNode()) );
308
309   // Set number of brances input port value, data port to dispatch value and loop body node name
310   if ( YACS::ENGINE::ForEachLoop* aForEachLoopNode = dynamic_cast<ForEachLoop*>( getNode() ) )
311   {
312     if( YACS::ENGINE::InputPort* aBranchesPort = aForEachLoopNode->edGetNbOfBranchesPort() )
313     {
314       bool ok;
315       int aValue = getPortValue( aBranchesPort ).toInt( &ok );
316       if( ok && aValue > 1 )
317         myNbBranchesInputPortValue->setValue( aValue );
318     }
319
320     if( YACS::ENGINE::InputPort* aSamplesPort = aForEachLoopNode->edGetSeqOfSamplesPort() )
321     {
322       QString aValue = getPortValue( aSamplesPort );
323       myDataPortToDispatchValue->setText( aValue );
324     }
325
326     if( myLoopBodyNodeName )
327     {
328       std::list<Node*> aNodes = aForEachLoopNode->edGetDirectDescendants();
329       if ( !aNodes.empty() )
330       {
331         QString aBodyName;
332         
333         std::list<Node*>::iterator aNodesIt = aNodes.begin();
334         Node* aNode = *aNodesIt;
335         if( aNode )
336           aBodyName = aNode->getName();
337
338         myLoopBodyNodeName->setText( aBodyName );
339       }
340     }
341   }
342   
343   // Set view mode of the given FOREACH node
344   // the following method can be used if its needed:
345   // YACSGui_Graph* aGraph = getInputPanel()->getModule()->getGraph( myProc );
346   // ...
347 }
348
349 void YACSGui_ForEachLoopNodePage::onNodeNameChanged( const QString& theName )
350 {
351   if ( myNodeFullName )
352   {
353     QString anOldName = myNodeFullName->text();
354     int aRDotId = anOldName.findRev('.');
355     myNodeFullName->setText( anOldName.replace( aRDotId+1, anOldName.length()-(aRDotId+1), theName ) );
356   }
357 }
358
359 void YACSGui_ForEachLoopNodePage::onSeqOfSamplesChanged( const QString& theText )
360 {
361   /*
362   QString aText = theText;
363   if( aText.left( 1 ) != "[" )
364     aText.prepend( "[" );
365     
366   if( aText.right( 1 ) != "]" )
367     aText.append( "]" );
368
369   if( aText != theText )
370     myDataPortToDispatchValue->setText( aText );
371   */
372 }
373