Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / gui / YACSGui_InputPanel.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 <DataNode.hxx>
62 #include <PresetNode.hxx>
63 #include <OutNode.hxx>
64 #include <StudyNodes.hxx>
65 #include <InlineNode.hxx>
66 #include <ServiceNode.hxx>
67 #include <ServiceInlineNode.hxx>
68 #include <CORBANode.hxx>
69 #include <SalomePythonNode.hxx>
70 #include <CppNode.hxx>
71 #include <XMLNode.hxx>
72 #include <Exception.hxx>
73 #include <Catalog.hxx>
74 #include <ComponentDefinition.hxx>
75 #include <CORBAComponent.hxx>
76 #include <CppComponent.hxx>
77 #include <SalomeComponent.hxx>
78 #include <SalomePythonComponent.hxx>
79 #include <RuntimeSALOME.hxx>
80
81 #include <qwindowsstyle.h>
82 #include <qpushbutton.h>
83 #include <qlayout.h>
84 #include <qhbox.h>
85 #include <qlabel.h>
86 #include <qlineedit.h>
87 #include <qbuttongroup.h>
88 #include <qradiobutton.h>
89 #include <qcombobox.h>
90 #include <qtextedit.h>
91 #include <qtoolbutton.h>
92 #include <qspinbox.h>
93 #include <qprogressbar.h>
94 #include <qobjectlist.h>
95 #include <qfiledialog.h>
96 #include <qcheckbox.h>
97
98 #include <sstream>
99
100 //#define _DEVDEBUG_
101 #include "YacsTrace.hxx"
102
103 #define SPACING 5
104 #define MARGIN 5
105
106 using namespace YACS;
107 using namespace YACS::ENGINE;
108 using namespace YACS::HMI;
109 using namespace std;
110
111
112 QColor getColor( int theStatus )
113 {
114   QColor aColor;
115   switch (theStatus)
116     {
117     case UNDEFINED:    aColor = Qt::lightGray;     break;
118     case INVALID:      aColor = Qt::red;           break;
119     case READY:        aColor = Qt::green;         break;
120     case TOLOAD:       aColor = Qt::darkYellow;    break;
121     case LOADED:       aColor = Qt::darkMagenta;   break;
122     case TOACTIVATE:   aColor = Qt::darkCyan;      break;
123     case ACTIVATED:    aColor = Qt::darkBlue;      break;
124     case DESACTIVATED: aColor = Qt::gray;          break;
125     case DONE:         aColor = Qt::darkGreen;     break;
126     case SUSPENDED:    aColor = Qt::gray;          break;
127     case LOADFAILED:   aColor.setHsv(320,255,255); break;
128     case EXECFAILED:   aColor.setHsv( 20,255,255); break;
129     case PAUSE:        aColor.setHsv(180,255,255); break;
130     case INTERNALERR:  aColor.setHsv(340,255,255); break;
131     case DISABLED:     aColor.setHsv( 40,255,255); break;
132     case FAILED:       aColor.setHsv( 20,255,255); break;
133     case ERROR:        aColor.setHsv(  0,255,255); break;
134     default:           aColor = Qt::lightGray;
135     }
136   return aColor;
137 }
138
139 std::string portValueType( YACS::ENGINE::TypeCode* theTC )
140 {
141   std::string aType = "";
142   switch ( theTC->kind() )
143     {
144     case Double: aType = "double";     break;
145     case Int:    aType = "int";        break;
146     case String: aType = "string";     break;
147     case Bool:   aType = "bool";       break;
148     case Objref: aType = "objref";     break;
149     case Sequence: aType = "sequence"; break;
150     case Array:    aType = "array";    break;
151     case Struct:   aType = "struct";   break;
152     default:                           break;
153     }
154   return aType;
155 }
156
157 QString getText( int theStatus )
158 {
159   QString aText;
160   switch (theStatus)
161     {
162     case UNDEFINED:    aText = "UNDEFINED";    break;
163     case INVALID:      aText = "INVALID";      break;
164     case READY:        aText = "READY";        break;
165     case TOLOAD:       aText = "TOLOAD";       break;
166     case LOADED:       aText = "LOADED";       break;
167     case TOACTIVATE:   aText = "TOACTIVATE";   break;
168     case ACTIVATED:    aText = "ACTIVATED";    break;
169     case DESACTIVATED: aText = "DESACTIVATED"; break;
170     case DONE:         aText = "DONE";         break;
171     case SUSPENDED:    aText = "SUSPENDED";    break;
172     case LOADFAILED:   aText = "LOADFAILED";   break;
173     case EXECFAILED:   aText = "EXECFAILED";   break;
174     case PAUSE:        aText = "PAUSE";        break;
175     case INTERNALERR:  aText = "INTERNALERR";  break;
176     case DISABLED:     aText = "DISABLED";     break;
177     case FAILED:       aText = "FAILED";       break;
178     case ERROR:        aText = "ERROR";        break;
179     default: break;
180     }
181   return aText;
182 }
183
184 /*
185   Class : YACSGui_InputPanel::BtnStyle
186   Description : Style for buttons with text aligned to the left border
187 */
188
189 class YACSGui_InputPanel::BtnStyle : public QWindowsStyle
190 {
191 public:
192
193   virtual void drawControl( ControlElement element,
194                             QPainter *p,
195                             const QWidget *widget,
196                             const QRect &r,
197                             const QColorGroup &cg,
198                             SFlags how = Style_Default,
199                             const QStyleOption& = QStyleOption::Default ) const;
200 };
201
202 void YACSGui_InputPanel::BtnStyle::drawControl( ControlElement element,
203                                                                     QPainter *p,
204                                                                     const QWidget *widget,
205                                                                     const QRect &r,
206                                                                     const QColorGroup &cg,
207                                                                     SFlags flags,
208                                                                     const QStyleOption& opt ) const
209 {
210   if ( element != CE_PushButtonLabel )
211     QWindowsStyle::drawControl( element, p, widget, r, cg, flags, opt );
212   else
213   {
214 #ifndef QT_NO_PUSHBUTTON
215     const QPushButton *button = (const QPushButton *) widget;
216     QRect ir = r;
217     
218     if ( button->isDown() || button->isOn() ) 
219     {
220       flags |= Style_Sunken;
221       ir.moveBy(pixelMetric(PM_ButtonShiftHorizontal, widget),
222         pixelMetric(PM_ButtonShiftVertical, widget));
223     }
224
225     int tf=AlignVCenter | ShowPrefix;
226     if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0))
227       tf |= NoAccel;
228     
229     tf |= AlignLeft;
230     ir.setLeft( 10 );
231     drawItem(p, ir, tf, cg,
232       flags & Style_Enabled, button->pixmap(), button->text(),
233       button->text().length(), &(cg.buttonText()) );
234
235     // draw arrow
236     PrimitiveElement aPE = button->isOn() ? PE_ArrowUp : PE_ArrowDown;
237     int h = r.height();
238     QRect aRect( r.right() - h, r.top(), h, h );
239     SFlags aFlags = Style_Default | Style_Enabled; 
240     drawPrimitive( aPE, p, aRect, cg, aFlags, QStyleOption( QColor( 0, 0, 255 ) ) );
241     
242     if (flags & Style_HasFocus)
243       drawPrimitive( PE_FocusRect, p, subRect( SR_PushButtonFocusRect, widget ), cg, flags );
244 #endif
245   }
246 }
247
248
249 /*
250   Class       : YACSGui_InputPanel
251   Description : Dockable window containing push buttons and corresponding widgets
252 */
253
254 //=======================================================================
255 // name    : YACSGui_InputPanel
256 // Purpose : Constructor
257 //=======================================================================
258 YACSGui_InputPanel::YACSGui_InputPanel( YACSGui_Module* theModule )
259   :  QDockWindow( QDockWindow::InDock, theModule && theModule->getApp() ? theModule->application()->desktop() : 0 ),
260      myModule(theModule),
261      myApplyBtn(0),
262      myCancelBtn(0)
263 {
264   QScrollView* scrollView = new QScrollView( this );
265
266   // Create main frame and main layout
267   QFrame* aMainFrame  = new QFrame( scrollView->viewport() );
268   scrollView->addChild( aMainFrame );
269   scrollView->setResizePolicy( QScrollView::AutoOneFit );
270
271   myMainLayout = new QVBoxLayout( aMainFrame, MARGIN, SPACING);
272
273   // create an empty property pages
274   createPage( YACSGui_InputPanel::ContainerId );
275   createPage( YACSGui_InputPanel::ComponentId );
276   createPage( YACSGui_InputPanel::SchemaId );
277   createPage( YACSGui_InputPanel::InDataNodeId );
278   createPage( YACSGui_InputPanel::OutDataNodeId );
279   createPage( YACSGui_InputPanel::InStudyNodeId );
280   createPage( YACSGui_InputPanel::OutStudyNodeId );
281   createPage( YACSGui_InputPanel::InlineNodeId );
282   createPage( YACSGui_InputPanel::ServiceNodeId );
283   createPage( YACSGui_InputPanel::ForLoopNodeId );
284   createPage( YACSGui_InputPanel::ForEachLoopNodeId );
285   createPage( YACSGui_InputPanel::WhileLoopNodeId );
286   createPage( YACSGui_InputPanel::SwitchNodeId );
287   createPage( YACSGui_InputPanel::BlockNodeId );
288   createPage( YACSGui_InputPanel::LinkId );
289   createPage( YACSGui_InputPanel::DataTypeId );
290
291   //  myMainLayout->addStretch( 1 );
292
293   // Add "Apply" and "Close" buttons
294   QGroupBox* aGrpBtns = new QGroupBox( aMainFrame, "GroupButtons" );
295   aGrpBtns->setColumnLayout(0, Qt::Vertical );
296   aGrpBtns->layout()->setSpacing( 0 ); aGrpBtns->layout()->setMargin( 0 );
297   aGrpBtns->setFrameStyle( QFrame::NoFrame );
298   //aGrpBtns->setFrameStyle( QFrame::StyledPanel );
299   QHBoxLayout* aGrpBtnsLayout = new QHBoxLayout( aGrpBtns->layout() );
300   aGrpBtnsLayout->setAlignment( Qt::AlignTop );
301   aGrpBtnsLayout->setSpacing( 0 ); aGrpBtnsLayout->setMargin( 0 );
302
303   myApplyBtn = new QPushButton( tr( "APPLY_BTN" ), aGrpBtns );
304   connect( myApplyBtn, SIGNAL( clicked() ), this, SLOT( onApply() ) );
305
306   myCancelBtn = new QPushButton( tr( "CLOSE_BTN" ), aGrpBtns );
307   connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( onClose() ) );
308
309   aGrpBtnsLayout->addWidget( myApplyBtn );
310   aGrpBtnsLayout->addItem  ( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
311   aGrpBtnsLayout->addWidget( myCancelBtn );
312   
313   myMainLayout->addWidget( aGrpBtns );
314   myMainLayout->addSpacing( SPACING );
315
316   updateState();
317
318   setWidget( scrollView );
319   scrollView->show();
320 }
321
322 //=======================================================================
323 // name    : ~YACSGui_InputPanel
324 // Purpose : Destructor
325 //=======================================================================
326 YACSGui_InputPanel::~YACSGui_InputPanel()
327 {
328   myMainBtns.clear();
329   myPages.clear();
330 }
331
332 //================================================================
333 // Function : setBtnText
334 // Purpose  : 
335 //================================================================
336 void YACSGui_InputPanel::setBtnText( const QString& theText, const int thePageId )
337 {
338   if ( myMainBtns.contains( thePageId ) )
339     myMainBtns[ thePageId ]->setText( theText );
340 }
341
342 //=======================================================================
343 // name    : getPage
344 // Purpose : 
345 //=======================================================================
346 QWidget* YACSGui_InputPanel::getPage( const int thePageId,
347                                       const bool theWithCreate )
348 {
349   if ( myPages.contains( thePageId ) )
350     return myPages[ thePageId ];
351   else if ( theWithCreate )
352   {
353     createPage( thePageId );
354     return myPages.contains( thePageId ) ? myPages[ thePageId ] : 0;
355   }
356
357   QWidget* aWid = 0;
358   return aWid;
359 }
360
361 //=============================================================================
362 // Function : getPageId
363 // Purpose  : 
364 //=============================================================================
365 int YACSGui_InputPanel::getPageId( QWidget* thePage ) const
366 {
367   int anId = -1;
368   if ( thePage != 0 )
369   {
370     QMap< int, QWidget* >::const_iterator anIter;
371     for ( anIter = myPages.begin(); anIter != myPages.end(); ++anIter )
372     {
373       QWidget* aPage = anIter.data();
374       if ( aPage == thePage )
375       {
376         anId = anIter.key();
377         break;
378       }
379     }
380   }
381
382   return anId;
383 }
384
385 //=============================================================================
386 // Function : insertPage
387 // Purpose  : Insert page in input panel. If this is already present in input panel 
388 //            then it is not inserted. if theBeforePageId == -1 then page is added 
389 //            at the end. Method returns identifier of inserted page or -1 if page 
390 //            is not inserted.
391 //=============================================================================
392 int YACSGui_InputPanel::insertPage( QWidget*, 
393                                     const int thePageId,
394                                     const int theBeforePageId,
395                                     const int theStretch ) const
396 {
397  
398 }
399
400 //=======================================================================
401 // name    : removePage
402 // Purpose : 
403 //=======================================================================
404 void YACSGui_InputPanel::removePage( QWidget* thePage )
405 {
406   if ( !thePage ) return;
407
408   int anId = getPageId(thePage);
409
410   if ( myMainBtns.find(anId) != myMainBtns.end() )
411   {
412     QPushButton* aBtn = myMainBtns[anId];
413     myMainBtns.erase(anId);
414     delete aBtn;
415   }
416     
417   if ( myPages.find(anId) != myPages.end() )
418     myPages.erase(anId);
419 }
420
421 //=======================================================================
422 // name    : sizeHint
423 // Purpose : 
424 //=======================================================================
425 QSize YACSGui_InputPanel::sizeHint() const
426 {
427   int w = QFontMetrics( font() ).width( QString("0"), 1 ) * 30;
428   return QSize( w, QDockWindow::sizeHint().height() );
429   //return QDockWindow::sizeHint();
430 }
431
432 //=======================================================================
433 // name    : isOn
434 // Purpose : 
435 //=======================================================================
436 bool YACSGui_InputPanel::isOn( const int i ) const
437 {
438   bool res = false;
439   if ( myMainBtns.contains( i ) )
440     res = myMainBtns[i]->isOn();
441   return res;
442 }
443
444 //=======================================================================
445 // name    : setOn
446 // Purpose : 
447 //=======================================================================
448 void YACSGui_InputPanel::setOn( const bool on, const int i )
449 {
450   if ( myMainBtns.contains( i ) )
451     myMainBtns[i]->setOn( on );
452 }
453
454 //=======================================================================
455 // name    : isVisible
456 // Purpose : 
457 //=======================================================================
458 bool YACSGui_InputPanel::isVisible( const int i ) const
459 {
460   DEBTRACE("YACSGui_InputPanel::isVisible " << i);
461   bool res = false;
462   if ( myMainBtns.contains( i ) )
463     res = myMainBtns[i]->isVisibleTo( myMainBtns[i]->parentWidget() );
464   return res;
465 }
466
467 //=======================================================================
468 // name    : setVisible
469 // Purpose : 
470 //=======================================================================
471 void YACSGui_InputPanel::setVisible( const bool on, const int i )
472 {
473   if ( myMainBtns.contains( i ) )
474     myMainBtns[i]->setShown( on );
475   if ( myPages.contains( i ) )
476     myPages[i]->setShown( on && myMainBtns[i]->isOn() );
477 }
478
479 //=======================================================================
480 // name    : setExclusiveVisible
481 // Purpose : 
482 //=======================================================================
483 void YACSGui_InputPanel::setExclusiveVisible( const bool on, const std::list<int> ids )
484 {
485   QMap< int, QWidget* >::const_iterator anIter;
486   for ( anIter = myPages.begin(); anIter != myPages.end(); ++anIter )
487   {
488     int anId = anIter.key();
489     
490     bool aVisibility = on;
491     if ( std::find(ids.begin(), ids.end(), anId) == ids.end() )
492       aVisibility = !on;
493     
494     if ( myMainBtns.contains( anId ) ) myMainBtns[anId]->setShown( aVisibility );
495     myPages[anId]->setShown( aVisibility && myMainBtns[anId]->isOn() );
496   }
497 }
498
499 //=======================================================================
500 // name    : getVisiblePagesIds
501 // Purpose : 
502 //=======================================================================
503 std::list<int> YACSGui_InputPanel::getVisiblePagesIds()
504 {
505   list<int> aRetList;
506
507   for ( QMap< int, QWidget* >::const_iterator anIter = myPages.begin(); anIter != myPages.end(); ++anIter )
508   {
509     int anId = anIter.key();
510     if ( isVisible(anId) ) aRetList.push_back(anId);
511   }
512
513   return aRetList;
514 }
515
516 //=======================================================================
517 // name    : setMode
518 // Purpose : 
519 //=======================================================================
520 void YACSGui_InputPanel::setMode( const YACSGui_InputPanel::PageMode theMode, const int thePageId )
521 {
522   switch( thePageId )
523   {
524   case SchemaId:
525     {
526       if ( YACSGui_SchemaPage* page = dynamic_cast<YACSGui_SchemaPage*>(myPages[thePageId]) )
527         page->setMode( theMode );
528     }
529     break;
530   case InDataNodeId:
531   case OutDataNodeId:
532   case InStudyNodeId:
533   case OutStudyNodeId:
534   case InlineNodeId:
535   case ServiceNodeId:
536   case ForLoopNodeId:
537   case ForEachLoopNodeId:
538   case WhileLoopNodeId:
539   case SwitchNodeId:
540   case BlockNodeId:
541     {
542       if ( YACSGui_NodePage* page = dynamic_cast<YACSGui_NodePage*>(myPages[thePageId]) )
543         page->setMode( theMode );
544     }
545     break;
546   case DataTypeId:
547     {
548       if ( YACSGui_DataTypePage* page = dynamic_cast<YACSGui_DataTypePage*>(myPages[thePageId]) )
549         page->setMode( theMode );
550     }
551     break;
552   default:
553     break;
554   }
555 }
556
557 //================================================================
558 // Function : getPrefferedSize
559 // Purpose  : 
560 //================================================================
561 QSize YACSGui_InputPanel::getPrefferedSize()
562 {
563   setUpdatesEnabled( false );
564
565   QMap< int, QWidget* >::const_iterator anIter;
566   for ( anIter = myPages.begin(); anIter != myPages.end(); ++anIter )
567     if ( isVisible(anIter.key()) )
568       anIter.data()->updateGeometry();
569
570   QSize aSize = this->sizeHint() * 1.44;
571   setUpdatesEnabled( true );
572   repaint();
573   return aSize;
574 }
575
576 //================================================================
577 // Function : emitApply
578 // Purpose  : 
579 //================================================================
580 void YACSGui_InputPanel::emitApply( const int theId )
581 {
582   emit Apply( theId );
583 }
584
585 //=======================================================================
586 // name    : onMainBtn
587 // Purpose : SLOT. Called when main button ( i.e. button used for show/hide
588 //           windows of input panel clicked )
589 //=======================================================================
590 void YACSGui_InputPanel::onMainBtn( bool )
591 {
592   updateState();
593 }
594
595 //=======================================================================
596 // name    : onApplyEnabled
597 // Purpose : SLOT. Called when "Apply" button should be disabled or enabled.
598 //=======================================================================
599 void YACSGui_InputPanel::onApplyEnabled( bool enable )
600 {
601   myApplyBtn->setEnabled(enable);
602 }
603
604 //=======================================================================
605 // name    : onApply
606 // Purpose : SLOT. Called when "Apply" button clicked. Emit signal with 
607 //           Corresponding id.
608 //=======================================================================
609 void YACSGui_InputPanel::onApply()
610 {
611   DEBTRACE("YACSGui_InputPanel::onApply");
612   QMap< int, QWidget* >::const_iterator anIter;
613   for ( anIter = myPages.begin(); anIter != myPages.end(); ++anIter )
614   {
615     int anId = anIter.key();
616     if ( isVisible(anId) ) 
617     {
618       switch(anId) {
619       case ContainerId: {
620         YACSGui_ContainerPage* page = dynamic_cast<YACSGui_ContainerPage*>(myPages[anId]);
621         if(page)
622           page->onApply();
623         break;
624       }
625       case ComponentId: {
626         YACSGui_ComponentPage* page = dynamic_cast<YACSGui_ComponentPage*>(myPages[anId]);
627         if(page)
628           page->onApply();
629         break;
630       }
631       case SchemaId: {
632         YACSGui_SchemaPage* page = dynamic_cast<YACSGui_SchemaPage*>(myPages[anId]);
633         if(page)
634           page->onApply();
635         break;
636       }
637       case InDataNodeId:
638       case OutDataNodeId: 
639       case InStudyNodeId:
640       case OutStudyNodeId: {
641   DEBTRACE("YACSGui_InputPanel::onApply");
642         YACSGui_DataNodePage* page = dynamic_cast<YACSGui_DataNodePage*>(myPages[anId]);
643         if(page)
644           page->onApply();
645         break;
646       }
647       case InlineNodeId: {
648   DEBTRACE("YACSGui_InputPanel::onApply");
649         YACSGui_InlineNodePage* page = dynamic_cast<YACSGui_InlineNodePage*>(myPages[anId]);
650         if(page)
651           page->onApply();
652         break;
653       }
654       case ServiceNodeId: {
655         YACSGui_ServiceNodePage* page = dynamic_cast<YACSGui_ServiceNodePage*>(myPages[anId]);
656         if(page)
657           page->onApply();
658         break;
659       }
660       case ForLoopNodeId: {
661         YACSGui_ForLoopNodePage* page = dynamic_cast<YACSGui_ForLoopNodePage*>(myPages[anId]);
662         if(page)
663           page->onApply();
664         break;
665       }
666       case ForEachLoopNodeId: {
667         YACSGui_ForEachLoopNodePage* page = dynamic_cast<YACSGui_ForEachLoopNodePage*>(myPages[anId]);
668         if(page)
669           page->onApply();
670         break;
671       }
672       case WhileLoopNodeId: {
673         YACSGui_WhileLoopNodePage* page = dynamic_cast<YACSGui_WhileLoopNodePage*>(myPages[anId]);
674         if(page)
675           page->onApply();
676         break;
677       }
678       case SwitchNodeId: {
679         YACSGui_SwitchNodePage* page = dynamic_cast<YACSGui_SwitchNodePage*>(myPages[anId]);
680         if(page)
681           page->onApply();
682         break;
683       }
684       case BlockNodeId: {
685         YACSGui_BlockNodePage* page = dynamic_cast<YACSGui_BlockNodePage*>(myPages[anId]);
686         if(page)
687           page->onApply();
688         break;
689       }
690       // ...
691       case LinkId: {
692         YACSGui_LinkPage* page = dynamic_cast<YACSGui_LinkPage*>(myPages[anId]);
693         if(page)
694           page->onApply();
695         break;
696       }
697       case DataTypeId: {
698         YACSGui_DataTypePage* page = dynamic_cast<YACSGui_DataTypePage*>(myPages[anId]);
699         if(page)
700           page->onApply();
701         break;
702       }
703       default:
704         break;
705       }
706       emit Apply( anId );
707     }
708   }
709
710   // export the modified schema (i.e. an active schema!) into
711   // the temporary XML file, which will be used for create execution objects
712   myModule->temporaryExport();
713 }
714
715 //=======================================================================
716 // name    : onClose
717 // Purpose : SLOT. Called when "Close" button clicked.
718 //=======================================================================
719 void YACSGui_InputPanel::onClose()
720 {
721   hide();
722   if(getModule()->getGuiMode() == YACSGui_Module::NewMode) {
723     getModule()->setGuiMode(YACSGui_Module::EditMode);
724     if(getModule()->activeTreeView())
725       getModule()->activeTreeView()->syncPageTypeWithSelection();
726   }
727   onApplyEnabled(true);
728 }
729
730 //=======================================================================
731 // name    : onNotifyNodeStatus
732 // Purpose : 
733 //=======================================================================
734 void YACSGui_InputPanel::onNotifyNodeStatus( int theNodeId, int theStatus )
735 {
736   DEBTRACE("YACSGui_InputPanel::onNotifyNodeStatus: " << theNodeId << " " << theStatus);
737   if ( Node::idMap.count(theNodeId) == 0 ) return;
738   Node* aNode= Node::idMap[theNodeId];
739   
740   QMap< int, QWidget* >::const_iterator anIter;
741   for ( anIter = myPages.begin(); anIter != myPages.end(); ++anIter )
742   {
743     int anId = anIter.key();
744     if ( isVisible(anId) )
745     {
746       switch(anId) {
747       case InDataNodeId:
748       case OutDataNodeId:
749       case InStudyNodeId:
750       case OutStudyNodeId: {
751         YACSGui_DataNodePage* page = dynamic_cast<YACSGui_DataNodePage*>(myPages[anId]);
752         if(page && page->getNode() == aNode)
753           page->notifyNodeStatus(theStatus);
754         break;
755       }
756       case InlineNodeId: {
757         YACSGui_InlineNodePage* page = dynamic_cast<YACSGui_InlineNodePage*>(myPages[anId]);
758         if(page && page->getNode() == aNode)
759           page->notifyNodeStatus(theStatus);
760         break;
761       }
762       case ServiceNodeId: {
763         YACSGui_ServiceNodePage* page = dynamic_cast<YACSGui_ServiceNodePage*>(myPages[anId]);
764         if(page && page->getNode() == aNode)
765           page->notifyNodeStatus(theStatus);
766         break;
767       }
768       case ForLoopNodeId: {
769         YACSGui_ForLoopNodePage* page = dynamic_cast<YACSGui_ForLoopNodePage*>(myPages[anId]);
770         if(page && page->getNode() == aNode)
771           page->notifyNodeStatus(theStatus);
772         break;
773       }
774       case ForEachLoopNodeId: {
775         YACSGui_ForEachLoopNodePage* page = dynamic_cast<YACSGui_ForEachLoopNodePage*>(myPages[anId]);
776         if(page && page->getNode() == aNode)
777           page->notifyNodeStatus(theStatus);
778         break;
779       }
780       case WhileLoopNodeId: {
781         YACSGui_WhileLoopNodePage* page = dynamic_cast<YACSGui_WhileLoopNodePage*>(myPages[anId]);
782         if(page && page->getNode() == aNode)
783           page->notifyNodeStatus(theStatus);
784         break;
785       }
786       case SwitchNodeId: {
787         YACSGui_SwitchNodePage* page = dynamic_cast<YACSGui_SwitchNodePage*>(myPages[anId]);
788         if(page && page->getNode() == aNode)
789           page->notifyNodeStatus(theStatus);
790         break;
791       }
792       case BlockNodeId: {
793         YACSGui_BlockNodePage* page = dynamic_cast<YACSGui_BlockNodePage*>(myPages[anId]);
794         if(page && page->getNode() == aNode)
795           page->notifyNodeStatus(theStatus);
796         break;
797       }
798       default:
799         break;
800       }
801     }
802   }
803 }
804
805 //=======================================================================
806 // name    : onNotifyInPortValues
807 // Purpose : 
808 //=======================================================================
809 void YACSGui_InputPanel::onNotifyInPortValues( int theNodeId,
810                                                std::map<std::string,std::string> theInPortName2Value )
811 {
812   DEBTRACE("onNotifyInPortValues: " << theNodeId);
813   if ( Node::idMap.count(theNodeId) == 0 ) return;
814   Node* aNode= Node::idMap[theNodeId];
815   
816   QMap< int, QWidget* >::const_iterator anIter;
817   for ( anIter = myPages.begin(); anIter != myPages.end(); ++anIter )
818   {
819     int anId = anIter.key();
820     if ( isVisible(anId) )
821     {
822       switch(anId) {
823       case InDataNodeId:
824       case OutDataNodeId:
825       case InStudyNodeId:
826       case OutStudyNodeId: {
827         YACSGui_DataNodePage* page = dynamic_cast<YACSGui_DataNodePage*>(myPages[anId]);
828         if(page && page->getNode() == aNode)
829           page->notifyInPortValues(theInPortName2Value);
830         break;
831       }
832       case InlineNodeId: {
833         YACSGui_InlineNodePage* page = dynamic_cast<YACSGui_InlineNodePage*>(myPages[anId]);
834         if(page && page->getNode() == aNode)
835           page->notifyInPortValues(theInPortName2Value);
836         break;
837       }
838       case ServiceNodeId: {
839         YACSGui_ServiceNodePage* page = dynamic_cast<YACSGui_ServiceNodePage*>(myPages[anId]);
840         if(page && page->getNode() == aNode)
841           page->notifyInPortValues(theInPortName2Value);
842         break;
843       }
844       case ForLoopNodeId: {
845         YACSGui_ForLoopNodePage* page = dynamic_cast<YACSGui_ForLoopNodePage*>(myPages[anId]);
846         if(page && page->getNode() == aNode)
847           page->notifyInPortValues(theInPortName2Value);
848         break;
849       }
850       case ForEachLoopNodeId: {
851         YACSGui_ForEachLoopNodePage* page = dynamic_cast<YACSGui_ForEachLoopNodePage*>(myPages[anId]);
852         if(page && page->getNode() == aNode)
853           page->notifyInPortValues(theInPortName2Value);
854         break;
855       }
856       case WhileLoopNodeId: {
857         YACSGui_WhileLoopNodePage* page = dynamic_cast<YACSGui_WhileLoopNodePage*>(myPages[anId]);
858         if(page && page->getNode() == aNode)
859           page->notifyInPortValues(theInPortName2Value);
860         break;
861       }
862       case SwitchNodeId: {
863         YACSGui_SwitchNodePage* page = dynamic_cast<YACSGui_SwitchNodePage*>(myPages[anId]);
864         if(page && page->getNode() == aNode)
865           page->notifyInPortValues(theInPortName2Value);
866         break;
867       }
868       case BlockNodeId: {
869         YACSGui_BlockNodePage* page = dynamic_cast<YACSGui_BlockNodePage*>(myPages[anId]);
870         if(page && page->getNode() == aNode)
871           page->notifyInPortValues(theInPortName2Value);
872         break;
873       }
874       default:
875         break;
876       }
877     }
878   }
879 }
880
881 //=======================================================================
882 // name    : onNotifyOutPortValues
883 // Purpose : 
884 //=======================================================================
885 void YACSGui_InputPanel::onNotifyOutPortValues( int theNodeId,
886                                                 std::map<std::string,std::string> theOutPortName2Value )
887 {
888   DEBTRACE("YACSGui_InputPanel::onNotifyOutPortValues" << theNodeId);
889   if ( Node::idMap.count(theNodeId) == 0 ) return;
890   Node* aNode= Node::idMap[theNodeId];
891   
892   QMap< int, QWidget* >::const_iterator anIter;
893   for ( anIter = myPages.begin(); anIter != myPages.end(); ++anIter )
894   {
895     int anId = anIter.key();
896     if ( isVisible(anId) )
897     {
898       switch(anId) {
899       case InDataNodeId:
900       case OutDataNodeId:
901       case InStudyNodeId:
902       case OutStudyNodeId: {
903         YACSGui_DataNodePage* page = dynamic_cast<YACSGui_DataNodePage*>(myPages[anId]);
904         DEBTRACE("Notify");
905         if(page && page->getNode() == aNode)
906           page->notifyOutPortValues(theOutPortName2Value);
907         break;
908       }
909       case InlineNodeId: {
910         YACSGui_InlineNodePage* page = dynamic_cast<YACSGui_InlineNodePage*>(myPages[anId]);
911         DEBTRACE("Notify");
912         if(page && page->getNode() == aNode)
913           page->notifyOutPortValues(theOutPortName2Value);
914         break;
915       }
916       case ServiceNodeId: {
917         YACSGui_ServiceNodePage* page = dynamic_cast<YACSGui_ServiceNodePage*>(myPages[anId]);
918         DEBTRACE("Notify");
919         if(page && page->getNode() == aNode)
920           page->notifyOutPortValues(theOutPortName2Value);
921         break;
922       }
923       case ForLoopNodeId: {
924         YACSGui_ForLoopNodePage* page = dynamic_cast<YACSGui_ForLoopNodePage*>(myPages[anId]);
925         if(page && page->getNode() == aNode)
926           page->notifyOutPortValues(theOutPortName2Value);
927         break;
928       }
929       case ForEachLoopNodeId: {
930         YACSGui_ForEachLoopNodePage* page = dynamic_cast<YACSGui_ForEachLoopNodePage*>(myPages[anId]);
931         if(page && page->getNode() == aNode)
932           page->notifyOutPortValues(theOutPortName2Value);
933         break;
934       }
935       case WhileLoopNodeId: {
936         YACSGui_WhileLoopNodePage* page = dynamic_cast<YACSGui_WhileLoopNodePage*>(myPages[anId]);
937         if(page && page->getNode() == aNode)
938           page->notifyOutPortValues(theOutPortName2Value);
939         break;
940       }
941       case SwitchNodeId: {
942         YACSGui_SwitchNodePage* page = dynamic_cast<YACSGui_SwitchNodePage*>(myPages[anId]);
943         if(page && page->getNode() == aNode)
944           page->notifyOutPortValues(theOutPortName2Value);
945         break;
946       }
947       case BlockNodeId: {
948         YACSGui_BlockNodePage* page = dynamic_cast<YACSGui_BlockNodePage*>(myPages[anId]);
949         DEBTRACE("Notify");
950         if(page && page->getNode() == aNode)
951           page->notifyOutPortValues(theOutPortName2Value);
952         break;
953       }
954       default:
955         break;
956       }
957     }
958   }
959 }
960
961 //=======================================================================
962 // name    : updateState
963 // Purpose : 
964 //=======================================================================
965 void YACSGui_InputPanel::updateState()
966 {
967   DEBTRACE("YACSGui_InputPanel::updateState()");
968   QMap< int, QWidget* >::const_iterator anIter;
969   for ( anIter = myPages.begin(); anIter != myPages.end(); ++anIter )
970   {
971     int anId = anIter.key();
972     QPushButton* b = myMainBtns.contains( anId ) ? myMainBtns[ anId ] : 0;
973     QWidget* page  = myPages.contains( anId ) ? myPages[ anId ] : 0;
974     if ( b && page )
975       page->setShown( b->isVisibleTo( b->parentWidget() ) && b->isOn() );
976   }
977 }
978
979 //=======================================================================
980 // name    : createPage
981 // Purpose : 
982 //=======================================================================
983 void YACSGui_InputPanel::createPage( const int thePageId )
984 {
985   DEBTRACE("YACSGui_InputPanel::createPage");
986   // Create buttons and frames inside the main frame
987   if ( !myMainLayout ) return;
988   QFrame* aMainFrame = dynamic_cast<QFrame*>( myMainLayout->parent() );
989   if ( !aMainFrame ) return;
990
991   // Create a drop down button
992   QPushButton* button = new QPushButton( aMainFrame );
993     
994   QWidget* page = 0;
995   switch ( thePageId )
996   {
997   case ContainerId:
998     page = new YACSGui_ContainerPage( aMainFrame );
999     break;
1000   case ComponentId:
1001     page = new YACSGui_ComponentPage( aMainFrame );
1002     break;
1003   case SchemaId:
1004     page = new YACSGui_SchemaPage( aMainFrame );
1005     break;
1006   case InDataNodeId:
1007   case OutDataNodeId:
1008   case InStudyNodeId:
1009   case OutStudyNodeId:
1010     page = new YACSGui_DataNodePage(thePageId, aMainFrame );
1011     break;
1012   case InlineNodeId:
1013     page = new YACSGui_InlineNodePage( aMainFrame );
1014     break;
1015   case ServiceNodeId:
1016     page = new YACSGui_ServiceNodePage( aMainFrame );
1017     break;
1018   case ForLoopNodeId:
1019     page = new YACSGui_ForLoopNodePage( aMainFrame );
1020     break;
1021   case ForEachLoopNodeId:
1022     page = new YACSGui_ForEachLoopNodePage( aMainFrame );
1023     break;
1024   case WhileLoopNodeId:
1025     page = new YACSGui_WhileLoopNodePage( aMainFrame );
1026     break;
1027   case SwitchNodeId:
1028     page = new YACSGui_SwitchNodePage( aMainFrame );
1029     break;
1030   case BlockNodeId:
1031     page = new YACSGui_BlockNodePage( aMainFrame );
1032     break;
1033   case LinkId:
1034     break;
1035   case DataTypeId:
1036     page = new YACSGui_DataTypePage( aMainFrame );
1037     break;
1038   default:
1039     break;
1040   }
1041
1042   // Use only if the drop down button is created for each property page
1043   if ( !page )
1044   {
1045     delete button;
1046     return;
1047   }
1048
1049   if ( myApplyBtn && myCancelBtn )
1050   {
1051     int anIndex;
1052     if ( thePageId == ContainerId ) anIndex = 0;
1053     if ( thePageId == ComponentId ) anIndex = 2;
1054     else anIndex = myMainLayout->findWidget(myApplyBtn->parentWidget()) - 1;
1055     
1056     myMainLayout->insertWidget( anIndex, page );
1057     myMainLayout->insertWidget( anIndex, button );
1058   }
1059   else
1060   {
1061     myMainLayout->insertWidget( -1, button );
1062     myMainLayout->insertWidget( -1, page );
1063   }
1064   
1065   myMainBtns.insert( thePageId, button );
1066   myPages.insert( thePageId, page );
1067     
1068   // Set custom style for drawing buttons with text aligned to the left border
1069   static BtnStyle aStyle;
1070   button->setStyle( &aStyle );
1071
1072   QFont aFont = button->font();
1073   aFont.setBold( true );
1074   button->setFont( aFont );
1075   button->setPaletteForegroundColor( QColor( 0, 0, 0 ) );
1076   button->setToggleButton( true );
1077   button->setOn(true);
1078   
1079   // Set titles for property pages as the text on the drop down button
1080   switch ( thePageId )
1081   {
1082   case ContainerId:
1083     myMainBtns[ContainerId]->setText(tr( "Container Properties" ));
1084     break;
1085   case ComponentId:
1086     myMainBtns[ComponentId]->setText(tr( "Component Properties" ));
1087     break;
1088   case SchemaId:
1089     myMainBtns[SchemaId]->setText( tr( "Schema Properties" ) );
1090     break;
1091   case InDataNodeId:
1092   case OutDataNodeId:
1093   case InStudyNodeId:
1094   case OutStudyNodeId:
1095   case InlineNodeId:
1096   case ServiceNodeId:
1097   case ForLoopNodeId:
1098   case ForEachLoopNodeId:
1099   case WhileLoopNodeId:
1100   case SwitchNodeId:
1101   case BlockNodeId:
1102     myMainBtns[thePageId]->setText( tr( "Node Properties" ) );
1103     break;
1104   case LinkId:
1105     break;
1106   case DataTypeId:
1107     myMainBtns[thePageId]->setText( tr( "Data Type Properties" ) );
1108     break;
1109   default:
1110     break;
1111   }
1112   
1113   // Connect signals and slots
1114   if ( myMainBtns.contains( thePageId ) )
1115     connect( myMainBtns[ thePageId ], SIGNAL( toggled( bool ) ), SLOT( onMainBtn( bool ) ) );
1116 }
1117