Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / gui / YACSGui_ContainerPage.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_ContainerPage
110   Description :  Page for container properties
111 */
112
113 YACSGui_ContainerPage::YACSGui_ContainerPage( QWidget* theParent, const char* theName, WFlags theFlags )
114   : ContainerPage( theParent, theName, theFlags ),
115     GuiObserver(),
116     mySContainer( 0 )
117 {
118   showAdvanced->setChecked(false);
119   onShowAdvanced();
120   connect(showAdvanced, SIGNAL(clicked()), this, SLOT(onShowAdvanced()));
121 }
122
123 YACSGui_ContainerPage::~YACSGui_ContainerPage()
124 {
125   if (getInputPanel()) getInputPanel()->removePage(this);
126
127   if ( mySContainer ) mySContainer->detach(this);
128 }
129
130 void YACSGui_ContainerPage::select( bool isSelected )
131 {
132   DEBTRACE(">> YACSGui_ContainerPage::select");
133 }
134
135 void YACSGui_ContainerPage::update( YACS::HMI::GuiEvent event, int type, YACS::HMI::Subject* son)
136 {
137   DEBTRACE(">> YACSGui_ContainerPage::update");
138   switch (event)
139   {
140   case REMOVE:
141     {
142       if ( !type && !son && mySContainer )
143       {
144         mySContainer->detach(this);
145         mySContainer = 0;
146       }
147     }
148     break;
149   default:
150     GuiObserver::update(event, type, son);
151   }
152 }
153
154 void YACSGui_ContainerPage::setSContainer(YACS::HMI::SubjectContainer* theSContainer )
155 {
156   if ( mySContainer != theSContainer )
157   {
158     if ( mySContainer ) mySContainer->detach(this); //detach from old container
159     mySContainer = theSContainer;
160     if ( mySContainer ) mySContainer->attach(this); // attach to new container
161
162     fillHostNames();
163     updateState();
164   }
165
166   if ( theSContainer )
167   {
168     // set "Container Name" fields to read only if the user is editing a service node
169     ServiceNode* aService = 0;
170     if ( YACSGui_EditionTreeView * aETV = 
171          dynamic_cast<YACSGui_EditionTreeView*>(getInputPanel()->getModule()->activeTreeView()) )
172       {
173         std::list<QListViewItem*> aList = aETV->getSelected();
174         if (!aList.empty())
175           if ( YACSGui_NodeViewItem* aNode = dynamic_cast<YACSGui_NodeViewItem*>(aList.front()) )
176             aService = dynamic_cast<ServiceNode*>(aNode->getNode());
177       }
178     
179     if ( aService )
180       {
181         myDefinitionName->setReadOnly(true);
182         myExecutionName->setReadOnly(true);
183       }
184     else
185       {
186         myDefinitionName->setReadOnly(false);
187         myExecutionName->setReadOnly(false);
188       }
189   }
190 }
191
192 YACS::ENGINE::Container* YACSGui_ContainerPage::getContainer() const
193 {
194   return ( mySContainer ? mySContainer->getContainer() : 0 );
195 }
196
197 YACS::ENGINE::SalomeContainer* YACSGui_ContainerPage::getSalomeContainer() const
198 {
199   return ( mySContainer ? dynamic_cast<SalomeContainer*>(mySContainer->getContainer()) : 0 );
200 }
201
202 QString YACSGui_ContainerPage::getDefinitionName() const
203 {
204   return ( mySContainer ? QString( mySContainer->getName() ) : QString("") );
205 }
206
207 bool YACSGui_ContainerPage::setDefinitionName( const QString& theName )
208 {
209   DEBTRACE("YACSGui_ContainerPage::setDefinitionName " << theName.latin1());
210   // --- TODO: create a command in hmi for container rename.
211   bool ret = false;
212   bool alreadyExists = false;
213   GuiContext* aContext = GuiContext::getCurrent();
214   if ( getContainer() )
215     {
216       map<Container*, SubjectContainer*>::const_iterator it;
217       for(it = aContext->_mapOfSubjectContainer.begin(); it !=aContext->_mapOfSubjectContainer.end(); ++it)
218         {
219           if ( QString::compare(theName, (*it).first->getName().c_str()) == 0)
220             {
221               alreadyExists =true;
222               break;
223             }
224         }
225       }
226   if (!alreadyExists)
227   {
228     DEBTRACE("set name " << theName.latin1());
229     string oldName = getContainer()->getName();
230     getContainer()->setName( theName.latin1() );
231     aContext->getProc()->containerMap.erase(oldName);
232     aContext->getProc()->containerMap[theName.latin1()] = getContainer();
233
234     mySContainer->update( RENAME, 0, mySContainer );
235     ret = true;
236   }
237   return ret;
238 }
239
240 QString YACSGui_ContainerPage::getExecutionName() const
241 {
242   QString name = "";
243   if (getSalomeContainer())
244     {
245       string nc = getSalomeContainer()->getProperty("container_name");
246       name = nc.c_str();
247     } 
248   return name;
249 }
250
251 void YACSGui_ContainerPage::setExecutionName( const QString& theName )
252 {
253   if ( getSalomeContainer() )
254     {
255       getSalomeContainer()->setProperty( "container_name", theName.latin1() );
256       mySContainer->update( RENAME, 0, mySContainer );
257     }
258 }
259
260 YACSGui_InputPanel* YACSGui_ContainerPage::getInputPanel() const
261 {
262   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
263   if( !anApp )
264     return 0;
265
266   YACSGui_Module* aModule = dynamic_cast<YACSGui_Module*>( anApp->activeModule() );
267   if( !aModule )
268     return 0;
269
270   return aModule->getInputPanel();
271 }
272
273 void YACSGui_ContainerPage::fillHostNames() const
274 {
275   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
276   SALOME_NamingService* namingService = anApp->namingService();
277
278   CORBA::Object_var obj = namingService->Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS);
279   if ( !CORBA::is_nil(obj) )
280     if ( Engines::ResourcesManager_var aResManager=Engines::ResourcesManager::_narrow(obj) )
281     {
282       Engines::CompoList aCompoList ;
283       Engines::MachineParameters params;
284       anApp->lcc()->preSet(params);
285
286       Engines::MachineList* aMachineList = aResManager->GetFittingResources( params, aCompoList );
287
288       myHostName->clear();
289       myHostName->insertItem( QString("localhost") );
290       for ( unsigned int i = 0; i < aMachineList->length(); i++ )
291       {
292         const char* aMachine = (*aMachineList)[i];
293         myHostName->insertItem( QString(aMachine) );
294       }
295     }
296 }
297
298 QString YACSGui_ContainerPage::getHostName() const
299 {
300   if ( getSalomeContainer() )
301   {
302     QString aHN(getSalomeContainer()->_params.hostname);
303     return aHN;
304   }
305   else 
306     return QString("");
307 }
308
309 void YACSGui_ContainerPage::setHostName( const QString& theHostName )
310 {
311   if ( getSalomeContainer() )
312     getSalomeContainer()->setProperty( "hostname", theHostName.latin1() );
313 }
314
315 int YACSGui_ContainerPage::getMemMb() const
316 {
317   return ( getSalomeContainer() ? getSalomeContainer()->_params.mem_mb : 0 );
318 }
319
320 void YACSGui_ContainerPage::setMemMb(const int theMem) 
321 {
322   if ( getSalomeContainer() )
323     getSalomeContainer()->setProperty( "mem_mb", QString("%1").arg(theMem).latin1() );
324 }
325
326 int YACSGui_ContainerPage::getCpuClock() const
327 {
328   return ( getSalomeContainer() ? getSalomeContainer()->_params.cpu_clock : 0 );
329 }
330
331 void YACSGui_ContainerPage::setCpuClock(const int theClock) 
332 {
333   if ( getSalomeContainer() )
334     getSalomeContainer()->setProperty( "cpu_clock", QString("%1").arg(theClock).latin1() );
335 }
336
337 int YACSGui_ContainerPage::getNbProcPerNode() const
338 {
339   return ( getSalomeContainer() ? getSalomeContainer()->_params.nb_proc_per_node : 0 );
340 }
341
342 void YACSGui_ContainerPage::setNbProcPerNode(const int theNbProc) 
343 {
344   if ( getSalomeContainer() )
345     getSalomeContainer()->setProperty( "nb_proc_per_node", QString("%1").arg(theNbProc).latin1() );
346 }
347
348 int YACSGui_ContainerPage::getNbNode() const
349 {
350   return ( getSalomeContainer() ? getSalomeContainer()->_params.nb_node : 0 );
351 }
352
353 void YACSGui_ContainerPage::setNbNode(const int theNbNode) 
354 {
355   if ( getSalomeContainer() )
356     getSalomeContainer()->setProperty( "nb_node", QString("%1").arg(theNbNode).latin1() );
357 }
358
359 bool YACSGui_ContainerPage::getMpiUsage() const
360 {
361   return ( getSalomeContainer() ? getSalomeContainer()->_params.isMPI : false );
362 }
363
364 void YACSGui_ContainerPage::setMpiUsage(const bool on)
365 {
366   if ( getSalomeContainer() )
367     getSalomeContainer()->setProperty( "isMPI", on ? "true" : "false" );
368 }
369
370 QString YACSGui_ContainerPage::getParallelLib() const
371 {
372   return ( getSalomeContainer() ? QString(getSalomeContainer()->_params.parallelLib) : QString("") );
373 }
374
375 void YACSGui_ContainerPage::setParallelLib( const QString& theLib)
376 {
377   if ( getSalomeContainer() )
378     getSalomeContainer()->setProperty( "parallelLib", theLib.latin1() );
379 }
380
381 int YACSGui_ContainerPage::getNbComponentNodes() const
382 {
383   return ( getSalomeContainer() ? getSalomeContainer()->_params.nb_component_nodes : 0 );
384 }
385
386 void YACSGui_ContainerPage::setNbComponentNodes(const int theNbComponentNodes)
387 {
388   if ( getSalomeContainer() )
389     getSalomeContainer()->setProperty( "nb_component_nodes", QString("%1").arg(theNbComponentNodes).latin1() );
390 }
391
392 QString YACSGui_ContainerPage::getWorkingDir() const
393 {
394   return ( getSalomeContainer() ? QString(getSalomeContainer()->_params.workingdir) : QString("") );
395 }
396
397 void YACSGui_ContainerPage::setWorkingDir( const QString& theWD)
398 {
399   if ( getSalomeContainer() )
400     getSalomeContainer()->setProperty( "workingdir", theWD.latin1() );
401 }
402
403 void YACSGui_ContainerPage::checkModifications( bool& theWarnToShow, bool& theToApply )
404 {
405   if ( !getContainer() || !theWarnToShow && !theToApply ) return;
406
407   // 1) check if the content of the page is really modified (in compare with the content of engine object)
408   bool isModified = false;
409   if ( myDefinitionName->text().compare(getDefinitionName()) != 0
410        ||
411        myExecutionName->text().compare(getExecutionName()) != 0
412        ||
413        myHostName->currentText().compare(getHostName()) != 0
414        ||
415        myMemMb->value() != getMemMb()
416        ||
417        myCpuClock->value() != getCpuClock()
418        ||
419        myNbProcPerNode->value() != getNbProcPerNode()
420        ||
421        myNbNode->value() != getNbNode()
422        ||
423        ( myMpiUsage->currentItem() ? false : true ) != getMpiUsage()
424        ||
425        myParallelLib->text().compare(getParallelLib()) != 0
426        ||
427        myNbComponentNodes->value() != getNbComponentNodes() 
428        ||
429        myWorkingDir->text().compare(getWorkingDir()) != 0
430      ) isModified = true;
431     
432   // 2) if yes, show a warning message: Apply or Cancel
433   if ( isModified )
434     if ( theWarnToShow )
435     {
436       theWarnToShow = false;
437       if ( SUIT_MessageBox::warn2(getInputPanel()->getModule()->getApp()->desktop(),
438                                   tr("WRN_WARNING"),
439                                   tr("APPLY_CANCEL_MODIFICATIONS"),
440                                   tr("BUT_YES"), tr("BUT_NO"), 0, 1, 0) == 0 )
441       {
442         onApply();
443         theToApply = true;
444         if ( getInputPanel() ) getInputPanel()->emitApply(YACSGui_InputPanel::ContainerId);
445       }
446       else
447         theToApply = false;
448     }
449     else if ( theToApply )
450     {
451       onApply();
452       if ( getInputPanel() ) getInputPanel()->emitApply(YACSGui_InputPanel::ContainerId);
453     }
454 }
455
456 void YACSGui_ContainerPage::onShowAdvanced()
457 {
458   if(showAdvanced->isChecked()) {
459     groupBoxAdv->show();
460   } else {
461     groupBoxAdv->hide();
462   }
463 }
464
465 void YACSGui_ContainerPage::updateState()
466 {
467   // Set container name
468
469   if ( myDefinitionName )
470     {
471       QString defName = getDefinitionName();
472       if (QString::compare(defName, "DefaultContainer") == 0)
473         myDefinitionName->setReadOnly(true);
474       else
475         myDefinitionName->setReadOnly(false);
476       myDefinitionName->setText(defName);
477       
478     }
479
480   if ( myExecutionName )
481     myExecutionName->setText(getExecutionName());
482
483   // Set host name
484   if ( myHostName )
485     myHostName->setCurrentText(getHostName());
486
487   // Set mem_mb
488   if ( myMemMb )
489     myMemMb->setValue(getMemMb());
490
491   // Set cpu_clock
492   if ( myCpuClock )
493     myCpuClock->setValue(getCpuClock());
494   
495   // Set nb_proc_per_node
496   if ( myNbProcPerNode )
497     myNbProcPerNode->setValue(getNbProcPerNode());
498
499   // Set nb_node
500   if ( myNbNode )
501     myNbNode->setValue(getNbNode());
502   
503   // Set MPI usage
504   if ( myMpiUsage )
505     myMpiUsage->setCurrentItem( getMpiUsage() ? 0 : 1 );
506
507   // Set parallel library
508   if ( myParallelLib )
509     myParallelLib->setText(getParallelLib());
510
511   // Set nb_component_nodes
512   if ( myNbComponentNodes )
513     myNbComponentNodes->setValue(getNbComponentNodes());
514
515   // Set working directory
516   if ( myWorkingDir )
517     myWorkingDir->setText(getWorkingDir());
518
519 }
520
521 void YACSGui_ContainerPage::onApply()
522 {
523   if ( myDefinitionName )
524     if (! setDefinitionName(myDefinitionName->text().latin1()))
525       if (getContainer()) myDefinitionName->setText(getContainer()->getName());
526
527   if ( myExecutionName )
528     setExecutionName(myExecutionName->text().latin1());
529
530   if ( myHostName )
531     setHostName(myHostName->currentText().latin1());
532
533   if ( myMemMb )
534     setMemMb(myMemMb->value());
535
536   if ( myCpuClock )
537     setCpuClock(myCpuClock->value());
538   
539   if ( myNbProcPerNode )
540     setNbProcPerNode(myNbProcPerNode->value());
541
542   if ( myNbNode )
543     setNbNode(myNbNode->value());
544   
545   if ( myMpiUsage )
546     setMpiUsage( myMpiUsage->currentItem() ? false : true );
547
548   if ( myParallelLib )
549     setParallelLib(myParallelLib->text().latin1());
550
551   if ( myNbComponentNodes )
552     setNbComponentNodes(myNbComponentNodes->value());
553
554   if ( myWorkingDir )
555     setWorkingDir(myWorkingDir->text().latin1());
556
557   //mySContainer->update( EDIT, 0, mySContainer );
558 }
559