Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / gui / YACSGui_ForLoopNodePage.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 _DEVDEBUG_
97 #include "YacsTrace.hxx"
98
99 #define SPACING 5
100 #define MARGIN 5
101
102 using namespace YACS;
103 using namespace YACS::ENGINE;
104 using namespace YACS::HMI;
105 using namespace std;
106
107
108 /*
109   Class : YACSGui_ForLoopNodePage
110   Description :  Page for FOR node properties
111 */
112
113 YACSGui_ForLoopNodePage::YACSGui_ForLoopNodePage( QWidget* theParent, const char* theName, WFlags theFlags )
114   : ForLoopNodePage( theParent, theName, theFlags ),
115     YACSGui_NodePage()
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_ForLoopNodePage::~YACSGui_ForLoopNodePage()
125 {
126   if (getInputPanel()) getInputPanel()->removePage(this);
127 }
128
129 void YACSGui_ForLoopNodePage::setSNode( YACS::HMI::SubjectNode* theSNode )
130 {
131   if ( !theSNode ) return;
132
133   if ( dynamic_cast<ForLoop*>( theSNode->getNode() ) )
134     YACSGui_NodePage::setSNode( theSNode );
135 }
136
137 void YACSGui_ForLoopNodePage::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_ForLoopNodePage::notifyNodeStatus( int theStatus )
158 {
159   if ( myNodeState )
160   {
161     myNodeState->setPaletteForegroundColor(getColor(theStatus));
162     myNodeState->setText(getText(theStatus));
163   }
164 }
165
166 void YACSGui_ForLoopNodePage::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_ForLoopNodePage::notifyInPortValues( std::map<std::string,std::string> theInPortName2Value )
186 {
187   DEBTRACE("==> ForLoopNodePage : Size of theInPortName2Value : " << theInPortName2Value.size());
188   
189   ForLoop* aForLoopNode = dynamic_cast<ForLoop*>( getNode() );
190   if ( !aForLoopNode ) return;
191
192   if ( theInPortName2Value.size() == 1 )
193   {
194     // nsteps port
195     QString aName(aForLoopNode->edGetNbOfTimesInputPort()->getName());
196     map<string,string>::iterator it = theInPortName2Value.begin();
197     QString aGivenName( (*it).first );
198     if ( !aGivenName.compare(aName) && myNbTimesInputPortValue )
199     {
200       QString aValue( (*it).second );
201       if ( !aValue.compare(QString("< ? >")) )
202         myNbTimesInputPortValue->setValue( myNbTimesInputPortValue->minValue() );
203       else
204         myNbTimesInputPortValue->setValue( aValue.toInt() );
205     }
206   }
207 }
208
209 void YACSGui_ForLoopNodePage::notifyOutPortValues( std::map<std::string,std::string> theOutPortName2Value )
210 {
211   DEBTRACE("==> ForLoopNodePage : " << theOutPortName2Value.size());
212 }
213
214 void YACSGui_ForLoopNodePage::notifyNodeCreateBody( YACS::HMI::Subject* theSubject )
215 {
216   DEBTRACE("YACSGui_ForLoopNodePage::notifyNodeCreateBody");
217   if( myLoopBodyNodeName )
218   {
219     QString aBodyName = theSubject->getName();
220     myLoopBodyNodeName->setText( aBodyName );
221   }
222 }
223
224 void YACSGui_ForLoopNodePage::checkModifications()
225 {
226   if ( !getNode() ) return;
227
228   // 1) check if the content of the page is really modified (in compare with the content of engine object)
229   bool isModified = false;
230
231   if ( myNodeName->text().compare(getNodeName()) != 0 ) isModified = true;
232   else if ( YACS::ENGINE::ForLoop* aForLoopNode = dynamic_cast<ForLoop*>( getNode() ) )
233     if( YACS::ENGINE::InputPort* aPort = aForLoopNode->edGetNbOfTimesInputPort() )
234     {
235       bool ok;
236       int aValue = getPortValue( aPort ).toInt( &ok );
237       if( ok && myNbTimesInputPortValue->value() != aValue ) isModified = true;
238     }
239   
240   //if ( !isModified )
241   //  TODO: compare view mode: expanded or collapsed (not yet in use)    
242   
243   // 2) if yes, show a warning message: Apply or Cancel
244   if ( isModified )
245     if ( SUIT_MessageBox::warn2(getInputPanel()->getModule()->getApp()->desktop(),
246                                 tr("WRN_WARNING"),
247                                 tr("APPLY_CANCEL_MODIFICATIONS"),
248                                 tr("BUT_YES"), tr("BUT_NO"), 0, 1, 0) == 0 )
249     {
250       onApply();
251       if ( getInputPanel() ) getInputPanel()->emitApply(YACSGui_InputPanel::InlineNodeId);
252     }
253 }
254
255 void YACSGui_ForLoopNodePage::onApply()
256 {
257   DEBTRACE("YACSGui_ForLoopNodePage::onApply");
258   // Rename a node
259   if ( myNodeName ) setNodeName( myNodeName->text() );
260   
261   // Reset number of times input port value
262   if ( YACS::ENGINE::ForLoop* aForLoopNode = dynamic_cast<ForLoop*>( getNode() ) )
263   {
264     if( YACS::ENGINE::InputPort* aPort = aForLoopNode->edGetNbOfTimesInputPort() )
265     {
266       int aValue = myNbTimesInputPortValue->value();
267       aPort->edInit( aValue );
268       mySNode->update( EDIT, INPUTPORT, GuiContext::getCurrent()->_mapOfSubjectDataPort[aPort] );
269     }
270   }
271
272   // Reset the view mode
273   // ...
274
275   updateBlocSize();
276 }
277
278 void YACSGui_ForLoopNodePage::updateState()
279 {
280   DEBTRACE("YACSGui_ForLoopNodePage::updateState");
281   // Set node name
282   if ( myNodeName ) myNodeName->setText( getNodeName() );
283
284   // Set node full name (read only)
285   if ( myNodeFullName )
286     myNodeFullName->setText( getNode()->getRootNode()->getChildName(getNode()) );
287
288   // Set number of times input port value and loop body node name
289   if ( YACS::ENGINE::ForLoop* aForLoopNode = dynamic_cast<ForLoop*>( getNode() ) )
290   {
291     if( YACS::ENGINE::InputPort* aPort = aForLoopNode->edGetNbOfTimesInputPort() )
292     {
293       bool ok;
294       int aValue = getPortValue( aPort ).toInt( &ok );
295       if( ok && aValue > 1 )
296         myNbTimesInputPortValue->setValue( aValue );
297     }
298
299     if( myLoopBodyNodeName )
300     {
301       std::list<Node*> aNodes = aForLoopNode->edGetDirectDescendants();
302       if ( !aNodes.empty() )
303       {
304         QString aBodyName;
305         
306         std::list<Node*>::iterator aNodesIt = aNodes.begin();
307         Node* aNode = *aNodesIt;
308         if( aNode )
309           aBodyName = aNode->getName();
310         
311         myLoopBodyNodeName->setText( aBodyName );
312       }
313     }
314   }
315
316   // Set view mode of the given FOR node
317   // the following method can be used if its needed:
318   // YACSGui_Graph* aGraph = getInputPanel()->getModule()->getGraph( myProc );
319   // ...
320 }
321
322 void YACSGui_ForLoopNodePage::onNodeNameChanged( const QString& theName )
323 {
324   if ( myNodeFullName )
325   {
326     QString anOldName = myNodeFullName->text();
327     int aRDotId = anOldName.findRev('.');
328     myNodeFullName->setText( anOldName.replace( aRDotId+1, anOldName.length()-(aRDotId+1), theName ) );
329   }
330 }
331