]> SALOME platform Git repositories - modules/superv.git/blob - src/SUPERVGUI/SUPERVGUI_ManagePortsDlg.cxx
Salome HOME
Merge from OCC_development_generic_2006
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_ManagePortsDlg.cxx
1 //  SUPERV SUPERVGUI : GUI for Supervisor component
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : SUPERVGUI_ManagePortsDlg.cxx
8 //  Author : Alexander SLADKOV
9 //  Module : SUPERV
10
11 #include "SUIT_Desktop.h"
12 #include "SUIT_Session.h"
13
14 #include "SUPERVGUI_ManagePortsDlg.h"
15 #include "SUPERVGUI_CanvasNode.h"
16 #include "SUPERVGUI_CanvasPort.h"
17 #include "SUPERVGUI_CanvasControlNode.h"
18 #include "SUPERVGUI_CanvasLink.h"
19
20 #include <qlayout.h>
21 #include <qlabel.h>
22 #include <qpushbutton.h>
23 #include <qhbox.h>
24 #include <qgroupbox.h>
25
26 static const char* gTypes[] = 
27   {"string", "boolean", "char", "short", "int", "long", "float", "double", "objref"};
28
29 static const char* const add_pix_data[] = { 
30 "20 20 4 1",
31 ". c None",
32 "b c #084818",
33 "a c #186929",
34 "# c #208541",
35 "....................",
36 "....................",
37 "....................",
38 "....................",
39 "........##a.........",
40 "........##b.........",
41 "........##b.........",
42 "........##b.........",
43 "........##b.........",
44 "...############a....",
45 "...############b....",
46 "...abbbb##bbbbbb....",
47 "........##b.........",
48 "........##b.........",
49 "........##b.........",
50 "........##b.........",
51 "........abb.........",
52 "....................",
53 "....................",
54 "...................."};
55
56 static const char* const del_pix_data[] = { 
57 "16 16 3 1",
58 ". c None",
59 "# c #800000",
60 "a c #ffffff",
61 "................",
62 "................",
63 ".##a........##a.",
64 ".####a.....##a..",
65 "..####a...##a...",
66 "....###a.#a.....",
67 ".....#####a.....",
68 "......###a......",
69 ".....#####a.....",
70 "....###a.##a....",
71 "...###a...##a...",
72 "..###a.....#a...",
73 "..###a......#a..",
74 "...#a........#a.",
75 "................",
76 "................"};
77
78 static const char* const up_pix_data[] = { 
79 "16 16 5 1",
80 ". c None",
81 "# c #000000",
82 "a c #838183",
83 "c c #c5c2c5",
84 "b c #ffffff",
85 "................",
86 "................",
87 "........#.......",
88 "......a#b#......",
89 ".....a#bbb#.....",
90 "....a#bccbb#....",
91 "...a#bccccbb#...",
92 "..a####ccb####..",
93 ".aaaaa#ccb#.....",
94 ".....a#ccb#.....",
95 ".....a#ccb#.....",
96 ".....a#ccb#.....",
97 ".....a#ccb#.....",
98 ".....a#ccb#.....",
99 ".....a#####.....",
100 "................"};
101
102 static const char* const down_pix_data[] = { 
103 "16 16 5 1",
104 ". c None",
105 "# c #000000",
106 "a c #838183",
107 "c c #c5c2c5",
108 "b c #ffffff",
109 "................",
110 ".....#####a.....",
111 ".....#bcc#a.....",
112 ".....#bcc#a.....",
113 ".....#bcc#a.....",
114 ".....#bcc#a.....",
115 ".....#bcc#a.....",
116 ".....#bcc#aaaaa.",
117 "..####bcc####a..",
118 "...#bbccccb#a...",
119 "....#bbccb#a....",
120 ".....#bbb#a.....",
121 "......#b#a......",
122 ".......#........",
123 "................",
124 "................"};
125
126
127 /**
128  * Constructor
129  */
130 SUPERVGUI_ManagePortsDlg::SUPERVGUI_ManagePortsDlg( SUPERVGUI_CanvasNode* theNode )
131   : QDialog( SUIT_Session::session()->activeApplication()->desktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
132 {
133   myNode = theNode;
134   myLastItem = 0;
135   init();
136 }
137
138 void SUPERVGUI_ManagePortsDlg::init()
139 {
140   setName( "SUPERVGUI_ManagePortsDlg" );
141
142   SUPERV_CNode aCNode = myNode->getEngine();
143   setCaption( tr( "TIT_MANAGE_PORTS" ) + aCNode->Name() );
144
145   QGridLayout* aBaseLayout = new QGridLayout( this );
146   aBaseLayout->setMargin( 11 ); 
147   aBaseLayout->setSpacing( 6 );
148
149   // -- name and type upper line widgets --
150   QLabel* aNameLbl = new QLabel( tr( "NAME_LBL") , this );
151   myNameEdt = new QLineEdit( this );
152   QLabel* aTypeLbl = new QLabel( tr( "TYPE_LBL" ), this );
153   myTypeCombo = new QComboBox( false, this ); // input field not editable
154
155   aBaseLayout->addWidget( aNameLbl, 0, 0 );
156   aBaseLayout->addWidget( myNameEdt, 0, 1 );
157   aBaseLayout->addWidget( aTypeLbl, 0, 2 );  
158   aBaseLayout->addWidget( myTypeCombo, 0, 3 );
159   aBaseLayout->setColStretch( 1, 1 );
160   aBaseLayout->setColStretch( 3, 1 );
161
162   // -- common Input/Output variables --
163   QPixmap adPix( (const char**) add_pix_data );
164   QPixmap rmPix( (const char**) del_pix_data );
165   QPixmap upPix( (const char**) up_pix_data );
166   QPixmap dnPix( (const char**) down_pix_data );
167
168   // -- Input ports group box --
169   QGroupBox* anInputGr = new QGroupBox( 1, Qt::Vertical, tr( "INPUT" ), this );
170   anInputGr->layout()->setSpacing( 6 ); 
171   anInputGr->layout()->setMargin( 11 );
172
173   myInList = new QListBox( anInputGr );
174   myInList->setSelectionMode( QListBox::Single );
175
176   QGroupBox* anInputBtnGr = new QGroupBox( 0, Qt::Vertical, anInputGr );
177   anInputBtnGr->setFrameStyle( QFrame::NoFrame );
178   anInputBtnGr->layout()->setSpacing( 0 ); 
179   anInputBtnGr->layout()->setMargin( 0 );  
180
181   QVBoxLayout* anInputBtnLay = new QVBoxLayout( anInputBtnGr->layout() );
182   anInputBtnLay->layout()->setSpacing( 6 ); 
183   anInputBtnLay->layout()->setMargin( 0 );
184   
185   QPushButton* anAddInputBtn = new QPushButton( anInputBtnGr );
186   anAddInputBtn->setPixmap( adPix );
187   QPushButton* aDeleteInputBtn = new QPushButton( anInputBtnGr );
188   aDeleteInputBtn->setPixmap( rmPix );
189   QPushButton* anUpInputBtn = new QPushButton( anInputBtnGr );
190   anUpInputBtn->setPixmap( upPix );
191   QPushButton* aDownInputBtn = new QPushButton( anInputBtnGr );
192   aDownInputBtn->setPixmap( dnPix );
193
194   connect( anAddInputBtn, SIGNAL( clicked() ), this, SLOT( addInput() ) );
195   connect( aDeleteInputBtn, SIGNAL( clicked() ), this, SLOT( removeInput() ) );
196   connect( anUpInputBtn, SIGNAL( clicked() ), this, SLOT( upInput() ) );
197   connect( aDownInputBtn, SIGNAL( clicked() ), this, SLOT( downInput() ) );
198
199   anInputBtnLay->addWidget( anAddInputBtn );
200   anInputBtnLay->addWidget( aDeleteInputBtn );
201   anInputBtnLay->addItem( new QSpacerItem( 1, 16, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding ) );
202   anInputBtnLay->addWidget( anUpInputBtn );
203   anInputBtnLay->addWidget( aDownInputBtn );
204   anInputBtnLay->addItem( new QSpacerItem( 1, 16, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding ) );
205
206   aBaseLayout->addMultiCellWidget( anInputGr, 1, 1, 0, 1 );
207
208   // -- Output ports group box --
209   QGroupBox* anOutputGr = new QGroupBox( 1, Qt::Vertical, tr( "OUTPUT" ), this );
210   anOutputGr->layout()->setSpacing( 6 ); 
211   anOutputGr->layout()->setMargin( 11 );
212
213   myOutList = new QListBox( anOutputGr );
214   myOutList->setSelectionMode( QListBox::Single );
215
216   QGroupBox* anOutputBtnGr = new QGroupBox( 0, Qt::Vertical, anOutputGr );
217   anOutputBtnGr->setFrameStyle( QFrame::NoFrame );
218   anOutputBtnGr->layout()->setSpacing( 0 ); 
219   anOutputBtnGr->layout()->setMargin( 0 );  
220
221   QVBoxLayout* anOutputBtnLay = new QVBoxLayout( anOutputBtnGr->layout() );
222   anOutputBtnLay->layout()->setSpacing( 6 ); 
223   anOutputBtnLay->layout()->setMargin( 0 );
224   
225   QPushButton* anAddOutputBtn = new QPushButton( anOutputBtnGr );
226   anAddOutputBtn->setPixmap( adPix );
227   QPushButton* aDeleteOutputBtn = new QPushButton( anOutputBtnGr );
228   aDeleteOutputBtn->setPixmap( rmPix );
229   QPushButton* anUpOutputBtn = new QPushButton( anOutputBtnGr );
230   anUpOutputBtn->setPixmap( upPix );
231   QPushButton* aDownOutputBtn = new QPushButton( anOutputBtnGr );
232   aDownOutputBtn->setPixmap( dnPix );
233
234   connect( anAddOutputBtn, SIGNAL( clicked() ), this, SLOT( addOutput() ) );
235   connect( aDeleteOutputBtn, SIGNAL( clicked() ), this, SLOT( removeOutput() ) );
236   connect( anUpOutputBtn, SIGNAL( clicked() ), this, SLOT( upOutput() ) );
237   connect( aDownOutputBtn, SIGNAL( clicked() ), this, SLOT( downOutput() ) );
238
239   anOutputBtnLay->addWidget( anAddOutputBtn );
240   anOutputBtnLay->addWidget( aDeleteOutputBtn );
241   anOutputBtnLay->addItem( new QSpacerItem( 1, 16, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding ) );
242   anOutputBtnLay->addWidget( anUpOutputBtn );
243   anOutputBtnLay->addWidget( aDownOutputBtn );
244   anOutputBtnLay->addItem( new QSpacerItem( 1, 16, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding ) );
245
246   aBaseLayout->addMultiCellWidget( anOutputGr, 1, 1, 2, 3 );
247
248   // -- Ok / Cancel buttons line at the bottom of dialog -- 
249   QGroupBox* aBtnBox = new QGroupBox( this );
250   aBtnBox->setColumnLayout( 0, Qt::Vertical );
251   aBtnBox->layout()->setSpacing( 0 ); 
252   aBtnBox->layout()->setMargin( 0 );
253   
254   QHBoxLayout* aBtnLayout = new QHBoxLayout( aBtnBox->layout() );
255   aBtnLayout->setAlignment( Qt::AlignTop );
256   aBtnLayout->setSpacing( 6 ); 
257   aBtnLayout->setMargin( 11 );
258
259   QPushButton* aOkBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
260   QPushButton* aCancelBtn = new QPushButton( tr( "BUT_CANCEL" ), aBtnBox );
261   connect( aOkBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
262   connect( aCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
263
264   aBtnLayout->addWidget( aOkBtn );
265   aBtnLayout->addStretch();
266   aBtnLayout->addWidget( aCancelBtn );
267   
268   aBaseLayout->addMultiCellWidget( aBtnBox, 2, 2, 0, 3 );
269   // -----------
270
271   connect( myInList,SIGNAL(currentChanged(QListBoxItem*)), this, SLOT(itemChanged(QListBoxItem*)));
272   connect( myOutList, SIGNAL(currentChanged(QListBoxItem*)), this, SLOT(itemChanged(QListBoxItem*)));
273   connect( myNameEdt, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
274   connect( myTypeCombo, SIGNAL(activated(const QString&)), this, SLOT(typeChanged(const QString&)));
275
276   myNode->getMain()->lockedGraph( true );
277
278   // asv : 11.01.05 : if a node is a loop node, then only INPUT ports can be added/removed
279   if ( myNode->getNodeType() == SUPERV::LoopNode ) {
280     myOutList->setEnabled( false );
281     anAddOutputBtn->setEnabled( false );
282     aDeleteOutputBtn->setEnabled( false );
283     anUpOutputBtn->setEnabled( false );
284     aDownOutputBtn->setEnabled( false );
285   }
286     
287 }
288
289 /**
290  * Destructor
291  */
292 SUPERVGUI_ManagePortsDlg::~SUPERVGUI_ManagePortsDlg() {
293 }
294
295 // mkr : PAL8060
296 void SUPERVGUI_ManagePortsDlg::createLinkEngine( SUPERV::Port_ptr thePort, 
297                                                  QValueList< QPair< QString,QString > >& theOwnList, 
298                                                  QValueList< QPair< QString,QString > >& theCorrespList ) {
299   // pair <NodeName, PortName> for the given port
300   QPair<QString, QString> anOwnPair(QString(thePort->Node()->Name()), QString(thePort->Name()));
301   int aNum = theOwnList.contains(anOwnPair);
302   while ( aNum > 0 ) {
303     int anId = theOwnList.findIndex(anOwnPair); // get index in theOwnList
304     QPair<QString, QString> aCorrespPair = theCorrespList[anId]; // corresponding pair in theCorrespList
305     
306     theOwnList.remove(theOwnList.at(anId));
307     theCorrespList.remove(theCorrespList.at(anId));
308     
309     SUPERV_Port aCorrespPort = myNode->getMain()->getDataflow()->Node(aCorrespPair.first)->Port(aCorrespPair.second);
310     SUPERV_Link aLinkEngine;
311     if ( thePort->IsInput() )
312       aLinkEngine = myNode->getMain()->getDataflow()->Link(aCorrespPort, thePort);
313     else
314       aLinkEngine = myNode->getMain()->getDataflow()->Link(thePort, aCorrespPort);
315     SUPERVGUI_CanvasLink* aLink = new SUPERVGUI_CanvasLink(myNode->getMain()->getCanvas(), myNode->getMain(), aLinkEngine);
316     aLink->show();
317     
318     aNum--;
319   }  
320 }
321
322 /** 
323  * Set the ports as entered by user (order, name/type, etc.) and close the dialog
324  */
325 void SUPERVGUI_ManagePortsDlg::accept() {
326   myNode->getMain()->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag 
327   // 1. set the ports to Engine's CNode
328   SUPERV_INode aINode = myNode->getInlineNode();
329   if ( !SUPERV_isNull( aINode ) ) {
330     int i; 
331     const bool isLoop = ( myNode->getNodeType() == SUPERV::LoopNode );
332
333     // 1.1 delete all ports (delete CanvasPorts, they delete SUPERV_Ports) 
334     QObjectList* oldPorts = myNode->queryList("SUPERVGUI_CanvasPort");
335     QObjectListIt it( *oldPorts ); // iterate over the old ports
336     QObject *obj;
337
338     // asv : 11.01.05 : fix for a bug: for Loop node, removal of an Input Port
339     // automatically removes the corresponding Output Port.  So for Loops the
340     // oldPorts list should be filtered to include only Input Ports.
341     // But I'll filter Gate-s as well..
342     bool isAnyLinked = false; // check if any port from old ports is linked
343     // map PortName <-> (PortType, PortInputValue) for non linked input ports, which have input
344     QMap< QString, QPair< QString,QString > > InNameInput;
345     QObjectList portsToRemove;
346     while ( (obj = it.current()) != 0 ) {
347       ++it;
348       SUPERV::Port_var aPort = ((SUPERVGUI_CanvasPort*)obj)->getEngine();
349       if ( !aPort->IsGate() && ( !isLoop || aPort->IsInput() ) ) {
350         portsToRemove.append( obj );
351       }
352       // check if port has a link (output porst of Loop node are also checked)
353       if ( !aPort->IsGate() && aPort->IsLinked() && !isAnyLinked)
354         isAnyLinked = true;
355       // check if input port has an input value
356       if ( !aPort->IsGate() && aPort->IsInput() && aPort->HasInput() )
357         InNameInput.insert( QString(aPort->Name()), 
358                             QPair<QString, QString>(QString(aPort->Type()),QString(aPort->ToString())) );
359     }
360     delete oldPorts; // delete the list, not the objects
361
362     // mkr : PAL8060 -->
363     QString aNodeName = myNode->getEngine()->Name();
364     QValueList< QPair< QString,QString > > InPortsL, OutPortsL;
365     if ( isAnyLinked ) {
366       // if myNode has linked port(s), create two lists of In/Out ports (InPortsL, OutPortsL) to identify all links for myNode
367       QObjectList* list = myNode->getMain()->getCanvas()->queryList("SUPERVGUI_CanvasLink");
368       QObjectListIt listit( *list );
369       QObject *listobj;
370       while ( (listobj = listit.current()) != 0 ) {
371         ++listit;
372         SUPERV::Link_var aLink = ((SUPERVGUI_CanvasLink*)listobj)->getEngine();
373         if ( aNodeName.compare(aLink->InPort()->Node()->Name()) == 0
374              ||
375              aNodeName.compare(aLink->OutPort()->Node()->Name()) == 0 ) {
376           QPair<QString, QString> InPair(QString(aLink->InPort()->Node()->Name()), QString(aLink->InPort()->Name()));
377           QPair<QString, QString> OutPair(QString(aLink->OutPort()->Node()->Name()), QString(aLink->OutPort()->Name()));
378           InPortsL.append(InPair);
379           OutPortsL.append(OutPair);
380         }
381
382         if ( isLoop ) {
383           // put into In/Out lists all links for corresponding EndLoop node
384           QString aCoupledNodeName = ((SUPERVGUI_CanvasStartNode*)myNode)->getCoupled()->getEngine()->Name();
385           if ( aCoupledNodeName.compare(aLink->InPort()->Node()->Name()) == 0
386                ||
387                aCoupledNodeName.compare(aLink->OutPort()->Node()->Name()) == 0 ) {
388             QPair<QString, QString> InPair(QString(aLink->InPort()->Node()->Name()), QString(aLink->InPort()->Name()));
389             QPair<QString, QString> OutPair(QString(aLink->OutPort()->Node()->Name()), QString(aLink->OutPort()->Name()));
390             InPortsL.append(InPair);
391             OutPortsL.append(OutPair);
392           } 
393         }
394       }
395     }
396     // mkr : PAL8060 <--
397     
398     // portsToRemove list contains:
399     // for Loop node: all INPUT ports except Gates
400     // for other Inline: all INPUT and OUTPUT ports except Gates
401     it = QObjectListIt( portsToRemove );
402     while ( (obj = it.current()) != 0 ) {
403       ++it;
404       ((SUPERVGUI_CanvasPort*)obj)->remove();
405     }
406
407     // 1.2 create new ports in INode and CanvasPort in myNode
408     PortListItem* item;
409     SUPERV_Port aPort;
410     for ( i = 0; i < myInList->count(); i++ ) {
411       item = (PortListItem*)myInList->item( i );
412       aPort = aINode->InPort( item->PortName.latin1(), item->PortType.latin1() );
413       if ( InNameInput.contains( item->PortName ) 
414            && 
415            item->PortType.compare(InNameInput[item->PortName].first) == 0 ) {
416         // i.e. aPort is input and had a value (not linked!)
417         // if ports' name and type didn't change and ports had an input value => set this value again
418         SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
419         if ( aSupMod )
420           aPort->Input( aSupMod->getEngine()->StringValue( InNameInput[item->PortName].second ) );
421         myNode->createPort( aPort.in() );
422       }
423       else {
424         myNode->createPort( aPort.in() );
425         // mkr : PAL8060
426         if ( !InPortsL.isEmpty() && !OutPortsL.isEmpty() )
427           // create links for those input ports, which had links earlier
428           createLinkEngine( aPort, InPortsL, OutPortsL );
429       }
430     }
431     
432     if ( isLoop ) {
433       // asv : 11.01.05 : for Loop nodes do the same as in SUPERVGUI_CanvasStartNode::addInputPort()
434       SUPERVGUI_CanvasStartNode* aStartLoopNode = (SUPERVGUI_CanvasStartNode*)myNode;
435       aStartLoopNode->merge();
436       aStartLoopNode->getCoupled()->merge();
437      
438       // mkr : PAL8060 -->
439       if ( !InPortsL.isEmpty() && !OutPortsL.isEmpty() ) {
440
441         // 1) create old links for output ports of Loop node
442         QObjectList* aPortsOut = aStartLoopNode->queryList("SUPERVGUI_CanvasPortOut");
443         QObjectListIt aPorstOutit( *aPortsOut );
444         QObject *listobj;
445         while ( (listobj = aPorstOutit.current()) != 0 ) {
446           ++aPorstOutit;
447         
448           SUPERV::Port_var aPortOut = ((SUPERVGUI_CanvasPort*)listobj)->getEngine();
449           createLinkEngine( aPortOut, OutPortsL, InPortsL );
450         }
451
452         // 2) create old links for input ports of EndLoop node
453         QObjectList* aPortsIn = aStartLoopNode->getCoupled()->queryList("SUPERVGUI_CanvasPortIn");
454         QObjectListIt aPorstInit( *aPortsIn );
455         while ( (listobj = aPorstInit.current()) != 0 ) {
456           ++aPorstInit;
457         
458           SUPERV::Port_var aPortIn = ((SUPERVGUI_CanvasPort*)listobj)->getEngine();
459           createLinkEngine( aPortIn, InPortsL, OutPortsL );
460         }
461
462         // 3) create old links for output ports of EndLoop node
463         aPortsOut = aStartLoopNode->getCoupled()->queryList("SUPERVGUI_CanvasPortOut");
464         aPorstOutit = QObjectListIt( *aPortsOut );
465         while ( (listobj = aPorstOutit.current()) != 0 ) {
466           ++aPorstOutit;
467         
468           SUPERV::Port_var aPortOut = ((SUPERVGUI_CanvasPort*)listobj)->getEngine();
469           createLinkEngine( aPortOut, OutPortsL, InPortsL );
470         }
471       }
472       // mkr : PAL8060 <--
473     }
474
475     // creating Out-ports, except LoopNode-s
476     for ( i = 0; i < myOutList->count() && !isLoop; i++ ) {
477       item = (PortListItem*)myOutList->item( i );
478       aPort = aINode->OutPort( item->PortName.latin1(), item->PortType.latin1() );
479       myNode->createPort( aPort.in() );
480
481       // mkr : PAL8060
482       if ( !InPortsL.isEmpty() && !OutPortsL.isEmpty() )
483         // create links for those output ports, which had links earlier
484         createLinkEngine( aPort, OutPortsL, InPortsL );
485     }  
486
487     // 2. update the node's presentation
488     myNode->getMain()->getCanvas()->update();
489   }
490   
491   // 3. close the dialog
492   myNode->getMain()->lockedGraph( false );
493   QDialog::accept();
494   close();
495 }
496
497 /** 
498  * Simply close the dialog
499  */
500 void SUPERVGUI_ManagePortsDlg::reject() {
501   myNode->getMain()->lockedGraph( false );
502   QDialog::reject();
503   close();
504 }
505
506 /**
507  * Update current values on show event
508  */
509 void SUPERVGUI_ManagePortsDlg::showEvent( QShowEvent* theEvent ) {
510   init( myNode );
511   QDialog::showEvent( theEvent );
512 }
513
514 /**
515  * Initialize In/Out tables with values from the given node
516  */
517 void SUPERVGUI_ManagePortsDlg::init( const SUPERVGUI_CanvasNode* theNode ) {
518   if ( !theNode ) {
519     MESSAGE("ERROR: SUPERVGUI_ManagePortsDlg: the CanvasNode is nil!");
520     return;
521   }
522
523   SUPERV_INode aINode = myNode->getInlineNode();
524   if ( SUPERV_isNull( aINode ) ) {
525     MESSAGE("ERROR: SUPERVGUI_ManagePortsDlg: the node of wrong type is found (not InLine node)!");
526     return;
527   }
528   
529   // 1. fill myTypeCombo with all available types
530   myTypeCombo->insertStrList( gTypes );
531   
532   // 2. fill Input and Output listboxes with Ports' names/types
533   QStringList aTypes;
534   SUPERV_Ports aPorts = aINode->Ports();
535   for ( int i=0; i < aPorts->length(); i++ ) {
536     if ( aPorts[i]->IsGate() )
537       continue;
538     if ( aPorts[i]->IsInput()
539          &&
540          !myInList->findItem( QString( "%1 (%2)" ).arg( aPorts[i]->Name() ).arg( aPorts[i]->Type() ) ) ) // mkr : PAL11332
541       new PortListItem( myInList, aPorts[i]->Name(), aPorts[i]->Type() );
542     if ( !aPorts[i]->IsInput()
543          &&
544          !myOutList->findItem( QString( "%1 (%2)" ).arg( aPorts[i]->Name() ).arg( aPorts[i]->Type() ) ) ) // mkr : PAL11332 
545       new PortListItem( myOutList, aPorts[i]->Name(), aPorts[i]->Type() );
546   }
547 }
548
549 void SUPERVGUI_ManagePortsDlg::addPort( QListBox* theLB ) {
550   if ( !theLB )
551     return;
552   QString name = myNameEdt->text();
553   if ( !name.isNull() && name.length() ) {
554     bool found = false; // check if already exists -- and don't allow if yes
555     for ( int i = 0; i < theLB->count(); i++ ) {
556       if ( ((PortListItem*)theLB->item(i))->PortName == name ) {
557         found = true;
558         break;
559       }
560     }
561     if ( found )
562       QMessageBox::warning( this, tr("ERROR"), tr("MSG_PORT_EXIST") ); // mkr : IPAL10386
563     else
564       new PortListItem( theLB, name, myTypeCombo->currentText() );
565   }
566 }
567
568 /**
569  * called on 'X' button press - remove selected port item
570  */
571 void SUPERVGUI_ManagePortsDlg::removePort( QListBox* theLB ) {
572   if ( !theLB )
573     return;
574
575   const int i = theLB->currentItem();
576   if ( i >=0 )
577     delete theLB->item( i );    
578 }
579
580 /**
581  * called on up/down key press - move the selected list box item from position 'from' to position 'to'
582  */
583 void SUPERVGUI_ManagePortsDlg::moveItem( QListBox* theLB, const int from, const int to ) {
584   if ( !theLB )
585     return;
586
587   // disconnect itemChanged - it leads to crash if there was only 1 item left
588   disconnect( theLB, SIGNAL(currentChanged(QListBoxItem*)), this, SLOT(itemChanged(QListBoxItem*)));
589
590   if ( from >= 0 && from < theLB->count() && to >=0 && to < theLB->count() ) {
591     QListBoxItem* item = theLB->item( from );
592     theLB->takeItem( item );
593     theLB->insertItem( item, to );
594     theLB->setCurrentItem( item );
595     theLB->setSelected( item, true );
596   }
597
598   // connect back..
599   connect( theLB, SIGNAL(currentChanged(QListBoxItem*)), this, SLOT(itemChanged(QListBoxItem*)));
600 }
601
602 /**
603  * move the selected item UP
604  */
605 void SUPERVGUI_ManagePortsDlg::moveUp( QListBox* theLB ) {
606   if ( !theLB )
607     return;
608   const int i = theLB->currentItem();
609   moveItem( theLB, i, i-1 );
610 }
611
612 /**
613  * move the selected item DOWN
614  */
615 void SUPERVGUI_ManagePortsDlg::moveDown( QListBox* theLB ) {
616   if ( !theLB )
617     return;
618   const int i = theLB->currentItem();
619   moveItem( theLB, i, i+1 );
620 }
621
622
623 /**
624  * returns true if there is a current and selected item in the given listbox and it
625  * equals to the given item.
626  */
627 bool isEditingItem( const QListBoxItem* item, const QListBox* theLB ) {
628   return item && item == theLB->item( theLB->currentItem() ) && theLB->isSelected( item );
629 }
630
631 /**
632  * called when name is changed.  Tries to change name of the item, which was
633  * the last selected by user item in myInList or myOutList (myLastItem)
634  */
635 void SUPERVGUI_ManagePortsDlg::nameChanged( const QString& name ) {
636   if ( isEditingItem( myLastItem, myInList ) || isEditingItem( myLastItem, myOutList ) ) {
637     ((PortListItem*)myLastItem)->PortName = name;
638     //myLastItem->listBox()->repaint( true );
639     // it would be much better to change the item and repaint it -- but -- repaint() 
640     // is done only after a while, which is not good..  so -- "cheating" around
641     const int i = myLastItem->listBox()->index( myLastItem );
642     moveItem( myLastItem->listBox(), i, i );
643   }
644 }
645
646 /**
647  * called when type item in myTypeCombo is changed.  Tries to change type
648  * of the last selected by user item in myInList or myOutList (myLastItem)
649  */
650 void SUPERVGUI_ManagePortsDlg::typeChanged( const QString& type ) {
651   if ( isEditingItem( myLastItem, myInList ) || isEditingItem( myLastItem, myOutList ) ) {
652     ((PortListItem*)myLastItem)->PortType = type;
653     //myLastItem->listBox()->repaint( true );
654     // it would be much better to change the item and repaint it -- but -- repaint() 
655     // is done only after a while, which is not good..  so -- "cheating" around
656     const int i = myLastItem->listBox()->index( myLastItem );
657     moveItem( myLastItem->listBox(), i, i );
658   }
659 }
660
661 /**
662  * called when new item became "currentItem" in any myInList or myOutList listboxes.
663  */
664 void SUPERVGUI_ManagePortsDlg::itemChanged( QListBoxItem * item ) {
665   if ( !item ) // after remove, etc..
666     return;
667
668   // disable nameChanged, typeChanged callbacks
669   disconnect( myNameEdt, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
670   disconnect( myTypeCombo, SIGNAL(activated(const QString&)), this, SLOT(typeChanged(const QString&)));
671   
672   myLastItem = item;
673   myNameEdt->setText( ((PortListItem*)item)->PortName );
674   for ( int i = 0; i < myTypeCombo->count(); i++ )
675     if ( myTypeCombo->text( i ) == ((PortListItem*)item)->PortType ) {
676       myTypeCombo->setCurrentItem( i );
677       break;
678     }
679
680   // connect back nameChanged, typeChanged
681   connect( myNameEdt, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
682   connect( myTypeCombo, SIGNAL(activated(const QString&)), this, SLOT(typeChanged(const QString&)));
683 }
684
685
686
687
688 /*!
689  * Port parameters dialog definition (taken from SUPERVGUI_Node.cxx without change)
690  */
691 SUPERVGUI_PortParamsDlg::SUPERVGUI_PortParamsDlg(const QStringList& thePortsNames)
692   : QDialog(SUIT_Session::session()->activeApplication()->desktop(), 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu  ),
693     myPortsNames( thePortsNames )
694 {
695   setSizeGripEnabled( true );
696   setCaption("Port parameters");
697
698   QGridLayout* aBaseLayout = new QGridLayout( this );
699   aBaseLayout->setMargin( 11 ); aBaseLayout->setSpacing( 6 );
700
701   QLabel* aNameLbl = new QLabel("Port Name", this );
702   aBaseLayout->addWidget(aNameLbl, 0, 0);
703
704   myNameTxt = new QLineEdit( this );
705   aNameLbl->setBuddy( myNameTxt );
706   aBaseLayout->addWidget(myNameTxt, 0, 1);
707   
708   QLabel* aTypeLbl = new QLabel("Value Type", this );
709   aBaseLayout->addWidget(aTypeLbl, 1, 0);
710  
711   myTypeTxt = new QComboBox( this );
712   aTypeLbl->setBuddy( myTypeTxt );
713   myTypeTxt->insertStrList( gTypes );
714   aBaseLayout->addWidget(myTypeTxt, 1, 1);
715  
716   QGroupBox* aBtnBox = new QGroupBox( this );
717   aBtnBox->setColumnLayout( 0, Qt::Vertical );
718   aBtnBox->layout()->setSpacing( 0 ); aBtnBox->layout()->setMargin( 0 );
719   QHBoxLayout* aBtnLayout = new QHBoxLayout( aBtnBox->layout() );
720   aBtnLayout->setAlignment( Qt::AlignTop );
721   aBtnLayout->setSpacing( 6 ); aBtnLayout->setMargin( 11 );
722
723   aBaseLayout->addMultiCellWidget( aBtnBox, 2, 2, 0, 1 );
724
725   QPushButton* aOKBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
726   connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( clickOnOk() ) );
727   aBtnLayout->addWidget( aOKBtn );
728
729   aBtnLayout->addStretch();
730
731   QPushButton* aCancelBtn = new QPushButton( tr("BUT_CANCEL"), aBtnBox );
732   connect( aCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
733   aBtnLayout->addWidget( aCancelBtn );
734 }
735
736 void SUPERVGUI_PortParamsDlg::clickOnOk()
737 {
738   if (getName().isEmpty() || getType().isEmpty())
739     QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr( "ERROR" ), tr( "MSG_CANT_CREATE_PORT" ) );
740   else if (myPortsNames.contains(getName()))
741     QMessageBox::warning( this, tr("ERROR"), tr("MSG_PORT_EXIST") ); // mkr : IPAL10386
742   else  
743     accept();
744 }