]> SALOME platform Git repositories - modules/superv.git/blob - src/SUPERVGUI/SUPERVGUI_ManagePortsDlg.cxx
Salome HOME
e887e1fd06272302e479cdbd71b2a9f069acd844
[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 using namespace std;
12
13 #include "SUPERVGUI_ManagePortsDlg.h"
14 #include "SUPERVGUI_CanvasNode.h"
15 #include "SUPERVGUI_CanvasPort.h"
16 #include "SUPERVGUI.h"
17
18 #include <qlayout.h>
19 #include <qlabel.h>
20 #include <qpushbutton.h>
21 #include <qhbox.h>
22 #include <qgroupbox.h>
23
24 static const char* gTypes[] = 
25   {"string", "boolean", "char", "short", "int", "long", "float", "double", "objref"};
26
27 static const char* const add_pix_data[] = { 
28 "20 20 4 1",
29 ". c None",
30 "b c #084818",
31 "a c #186929",
32 "# c #208541",
33 "....................",
34 "....................",
35 "....................",
36 "....................",
37 "........##a.........",
38 "........##b.........",
39 "........##b.........",
40 "........##b.........",
41 "........##b.........",
42 "...############a....",
43 "...############b....",
44 "...abbbb##bbbbbb....",
45 "........##b.........",
46 "........##b.........",
47 "........##b.........",
48 "........##b.........",
49 "........abb.........",
50 "....................",
51 "....................",
52 "...................."};
53
54 static const char* const del_pix_data[] = { 
55 "16 16 3 1",
56 ". c None",
57 "# c #800000",
58 "a c #ffffff",
59 "................",
60 "................",
61 ".##a........##a.",
62 ".####a.....##a..",
63 "..####a...##a...",
64 "....###a.#a.....",
65 ".....#####a.....",
66 "......###a......",
67 ".....#####a.....",
68 "....###a.##a....",
69 "...###a...##a...",
70 "..###a.....#a...",
71 "..###a......#a..",
72 "...#a........#a.",
73 "................",
74 "................"};
75
76 static const char* const up_pix_data[] = { 
77 "16 16 5 1",
78 ". c None",
79 "# c #000000",
80 "a c #838183",
81 "c c #c5c2c5",
82 "b c #ffffff",
83 "................",
84 "................",
85 "........#.......",
86 "......a#b#......",
87 ".....a#bbb#.....",
88 "....a#bccbb#....",
89 "...a#bccccbb#...",
90 "..a####ccb####..",
91 ".aaaaa#ccb#.....",
92 ".....a#ccb#.....",
93 ".....a#ccb#.....",
94 ".....a#ccb#.....",
95 ".....a#ccb#.....",
96 ".....a#ccb#.....",
97 ".....a#####.....",
98 "................"};
99
100 static const char* const down_pix_data[] = { 
101 "16 16 5 1",
102 ". c None",
103 "# c #000000",
104 "a c #838183",
105 "c c #c5c2c5",
106 "b c #ffffff",
107 "................",
108 ".....#####a.....",
109 ".....#bcc#a.....",
110 ".....#bcc#a.....",
111 ".....#bcc#a.....",
112 ".....#bcc#a.....",
113 ".....#bcc#a.....",
114 ".....#bcc#aaaaa.",
115 "..####bcc####a..",
116 "...#bbccccb#a...",
117 "....#bbccb#a....",
118 ".....#bbb#a.....",
119 "......#b#a......",
120 ".......#........",
121 "................",
122 "................"};
123
124
125 /**
126  * Constructor
127  */
128 SUPERVGUI_ManagePortsDlg::SUPERVGUI_ManagePortsDlg( SUPERVGUI_CanvasNode* theNode )
129   : QDialog( QAD_Application::getDesktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
130 {
131   myNode = theNode;
132   myLastItem = 0;
133   myFromItemChanged = false;
134   init();
135 }
136
137 void SUPERVGUI_ManagePortsDlg::init()
138 {
139   setName( "SUPERVGUI_ManagePortsDlg" );
140
141   SUPERV_CNode aCNode = myNode->getEngine();
142   setCaption( tr( "TIT_MANAGE_PORTS" ) + aCNode->Name() );
143
144   QGridLayout* aBaseLayout = new QGridLayout( this );
145   aBaseLayout->setMargin( 11 ); 
146   aBaseLayout->setSpacing( 6 );
147
148   // -- name and type upper line widgets --
149   QLabel* aNameLbl = new QLabel( tr( "NAME_LBL") , this );
150   myNameEdt = new QLineEdit( this );
151   QLabel* aTypeLbl = new QLabel( tr( "TYPE_LBL" ), this );
152   myTypeCombo = new QComboBox( false, this ); // input field not editable
153
154   aBaseLayout->addWidget( aNameLbl, 0, 0 );
155   aBaseLayout->addWidget( myNameEdt, 0, 1 );
156   aBaseLayout->addWidget( aTypeLbl, 0, 2 );  
157   aBaseLayout->addWidget( myTypeCombo, 0, 3 );
158   aBaseLayout->setColStretch( 1, 1 );
159   aBaseLayout->setColStretch( 3, 1 );
160
161   // -- common Input/Output variables --
162   QPixmap adPix( (const char**) add_pix_data );
163   QPixmap rmPix( (const char**) del_pix_data );
164   QPixmap upPix( (const char**) up_pix_data );
165   QPixmap dnPix( (const char**) down_pix_data );
166
167   // -- Input ports group box --
168   QGroupBox* anInputGr = new QGroupBox( 1, Qt::Vertical, tr( "INPUT" ), this );
169   anInputGr->layout()->setSpacing( 6 ); 
170   anInputGr->layout()->setMargin( 11 );
171
172   myInList = new QListBox( anInputGr );
173   myInList->setSelectionMode( QListBox::Single );
174
175   QGroupBox* anInputBtnGr = new QGroupBox( 0, Qt::Vertical, anInputGr );
176   anInputBtnGr->setFrameStyle( QFrame::NoFrame );
177   anInputBtnGr->layout()->setSpacing( 0 ); 
178   anInputBtnGr->layout()->setMargin( 0 );  
179
180   QVBoxLayout* anInputBtnLay = new QVBoxLayout( anInputBtnGr->layout() );
181   anInputBtnLay->layout()->setSpacing( 6 ); 
182   anInputBtnLay->layout()->setMargin( 0 );
183   
184   QPushButton* anAddInputBtn = new QPushButton( anInputBtnGr );
185   anAddInputBtn->setPixmap( adPix );
186   QPushButton* aDeleteInputBtn = new QPushButton( anInputBtnGr );
187   aDeleteInputBtn->setPixmap( rmPix );
188   QPushButton* anUpInputBtn = new QPushButton( anInputBtnGr );
189   anUpInputBtn->setPixmap( upPix );
190   QPushButton* aDownInputBtn = new QPushButton( anInputBtnGr );
191   aDownInputBtn->setPixmap( dnPix );
192
193   connect( anAddInputBtn, SIGNAL( clicked() ), this, SLOT( addInput() ) );
194   connect( aDeleteInputBtn, SIGNAL( clicked() ), this, SLOT( removeInput() ) );
195   connect( anUpInputBtn, SIGNAL( clicked() ), this, SLOT( upInput() ) );
196   connect( aDownInputBtn, SIGNAL( clicked() ), this, SLOT( downInput() ) );
197
198   anInputBtnLay->addWidget( anAddInputBtn );
199   anInputBtnLay->addWidget( aDeleteInputBtn );
200   anInputBtnLay->addItem( new QSpacerItem( 1, 16, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding ) );
201   anInputBtnLay->addWidget( anUpInputBtn );
202   anInputBtnLay->addWidget( aDownInputBtn );
203   anInputBtnLay->addItem( new QSpacerItem( 1, 16, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding ) );
204
205   aBaseLayout->addMultiCellWidget( anInputGr, 1, 1, 0, 1 );
206
207   // -- Output ports group box --
208   QGroupBox* anOutputGr = new QGroupBox( 1, Qt::Vertical, tr( "OUTPUT" ), this );
209   anOutputGr->layout()->setSpacing( 6 ); 
210   anOutputGr->layout()->setMargin( 11 );
211
212   myOutList = new QListBox( anOutputGr );
213   myOutList->setSelectionMode( QListBox::Single );
214
215   QGroupBox* anOutputBtnGr = new QGroupBox( 0, Qt::Vertical, anOutputGr );
216   anOutputBtnGr->setFrameStyle( QFrame::NoFrame );
217   anOutputBtnGr->layout()->setSpacing( 0 ); 
218   anOutputBtnGr->layout()->setMargin( 0 );  
219
220   QVBoxLayout* anOutputBtnLay = new QVBoxLayout( anOutputBtnGr->layout() );
221   anOutputBtnLay->layout()->setSpacing( 6 ); 
222   anOutputBtnLay->layout()->setMargin( 0 );
223   
224   QPushButton* anAddOutputBtn = new QPushButton( anOutputBtnGr );
225   anAddOutputBtn->setPixmap( adPix );
226   QPushButton* aDeleteOutputBtn = new QPushButton( anOutputBtnGr );
227   aDeleteOutputBtn->setPixmap( rmPix );
228   QPushButton* anUpOutputBtn = new QPushButton( anOutputBtnGr );
229   anUpOutputBtn->setPixmap( upPix );
230   QPushButton* aDownOutputBtn = new QPushButton( anOutputBtnGr );
231   aDownOutputBtn->setPixmap( dnPix );
232
233   connect( anAddOutputBtn, SIGNAL( clicked() ), this, SLOT( addOutput() ) );
234   connect( aDeleteOutputBtn, SIGNAL( clicked() ), this, SLOT( removeOutput() ) );
235   connect( anUpOutputBtn, SIGNAL( clicked() ), this, SLOT( upOutput() ) );
236   connect( aDownOutputBtn, SIGNAL( clicked() ), this, SLOT( downOutput() ) );
237
238   anOutputBtnLay->addWidget( anAddOutputBtn );
239   anOutputBtnLay->addWidget( aDeleteOutputBtn );
240   anOutputBtnLay->addItem( new QSpacerItem( 1, 16, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding ) );
241   anOutputBtnLay->addWidget( anUpOutputBtn );
242   anOutputBtnLay->addWidget( aDownOutputBtn );
243   anOutputBtnLay->addItem( new QSpacerItem( 1, 16, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding ) );
244
245   aBaseLayout->addMultiCellWidget( anOutputGr, 1, 1, 2, 3 );
246
247   // -- Ok / Cancel buttons line at the bottom of dialog -- 
248   QGroupBox* aBtnBox = new QGroupBox( this );
249   aBtnBox->setColumnLayout( 0, Qt::Vertical );
250   aBtnBox->layout()->setSpacing( 0 ); 
251   aBtnBox->layout()->setMargin( 0 );
252   
253   QHBoxLayout* aBtnLayout = new QHBoxLayout( aBtnBox->layout() );
254   aBtnLayout->setAlignment( Qt::AlignTop );
255   aBtnLayout->setSpacing( 6 ); 
256   aBtnLayout->setMargin( 11 );
257
258   QPushButton* aOkBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
259   QPushButton* aCancelBtn = new QPushButton( tr( "BUT_CANCEL" ), aBtnBox );
260   connect( aOkBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
261   connect( aCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
262
263   aBtnLayout->addWidget( aOkBtn );
264   aBtnLayout->addStretch();
265   aBtnLayout->addWidget( aCancelBtn );
266   
267   aBaseLayout->addMultiCellWidget( aBtnBox, 2, 2, 0, 3 );
268   // -----------
269
270   connect( myInList,SIGNAL(currentChanged(QListBoxItem*)), this, SLOT(itemChanged(QListBoxItem*)));
271   connect( myOutList, SIGNAL(currentChanged(QListBoxItem*)), this, SLOT(itemChanged(QListBoxItem*)));
272   connect( myNameEdt, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
273   connect( myTypeCombo, SIGNAL(activated(const QString&)), this, SLOT(typeChanged(const QString&)));
274
275   myNode->getMain()->lockedGraph( true );
276 }
277
278 /**
279  * Destructor
280  */
281 SUPERVGUI_ManagePortsDlg::~SUPERVGUI_ManagePortsDlg() {
282 }
283
284 /** 
285  * Set the ports as entered by user (order, name/type, etc.) and close the dialog
286  */
287 void SUPERVGUI_ManagePortsDlg::accept() {
288   // 1. set the ports to Engine's CNode
289   SUPERV_INode aINode = myNode->getInlineNode();
290   if ( !SUPERV_isNull( aINode ) ) {
291     int i; 
292
293     // 1.1 delete all ports (delete CanvasPorts, they delete SUPERV_Ports) 
294     QObjectList* oldPorts = myNode->queryList("SUPERVGUI_CanvasPort");
295     QObjectListIt it( *oldPorts ); // iterate over the old ports
296     QObject *obj;
297
298     while ( (obj = it.current()) != 0 ) {
299       ++it;
300       if ( !((SUPERVGUI_CanvasPort*)obj)->getEngine()->IsGate() ) // never do anything with Gate ports
301         ((SUPERVGUI_CanvasPort*)obj)->remove();
302     }
303     delete oldPorts; // delete the list, not the objects
304
305     // 1.2 create new ports in INode and CanvasPort in myNode
306     PortListItem* item;
307     SUPERV_Port aPort;
308     for ( i = 0; i < myInList->count(); i++ ) {
309       item = (PortListItem*)myInList->item( i );
310       aPort = aINode->InPort( item->PortName.latin1(), item->PortType.latin1() );
311       myNode->createPort( aPort.in() );
312     }
313     for ( i = 0; i < myOutList->count(); i++ ) {
314       item = (PortListItem*)myOutList->item( i );
315       aPort = aINode->OutPort( item->PortName.latin1(), item->PortType.latin1() );
316       myNode->createPort( aPort.in() );
317     }  
318
319     // 2. update the node's presentation
320     myNode->getMain()->getCanvas()->update();
321   }
322   
323   // 3. close the dialog
324   myNode->getMain()->lockedGraph( false );
325   QDialog::accept();
326   close();
327 }
328
329 /** 
330  * Simply close the dialog
331  */
332 void SUPERVGUI_ManagePortsDlg::reject() {
333   myNode->getMain()->lockedGraph( false );
334   QDialog::reject();
335   close();
336 }
337
338 /**
339  * Update current values on show event
340  */
341 void SUPERVGUI_ManagePortsDlg::showEvent( QShowEvent* theEvent ) {
342   init( myNode );
343   QDialog::showEvent( theEvent );
344 }
345
346 /**
347  * Initialize In/Out tables with values from the given node
348  */
349 void SUPERVGUI_ManagePortsDlg::init( const SUPERVGUI_CanvasNode* theNode ) {
350   if ( !theNode ) {
351     MESSAGE("ERROR: SUPERVGUI_ManagePortsDlg: the CanvasNode is nil!");
352     return;
353   }
354
355   SUPERV_INode aINode = myNode->getInlineNode();
356   if ( SUPERV_isNull( aINode ) ) {
357     MESSAGE("ERROR: SUPERVGUI_ManagePortsDlg: the node of wrong type is found (not InLine node)!");
358     return;
359   }
360   
361   // 1. fill myTypeCombo with all available types
362   myTypeCombo->insertStrList( gTypes );
363
364   // 2. fill Input and Output listboxes with Ports' names/types
365   QStringList aTypes;
366   SUPERV_Ports aPorts = aINode->Ports();
367   for ( int i=0; i < aPorts->length(); i++ ) {
368     if ( aPorts[i]->IsGate() )
369       continue;
370     if ( aPorts[i]->IsInput() )
371       new PortListItem( myInList, aPorts[i]->Name(), aPorts[i]->Type() );
372     else 
373       new PortListItem( myOutList, aPorts[i]->Name(), aPorts[i]->Type() );
374   }
375 }
376
377 void SUPERVGUI_ManagePortsDlg::addPort( QListBox* theLB ) {
378   if ( !theLB )
379     return;
380   QString name = myNameEdt->text();
381   if ( !name.isNull() && name.length() ) {
382     bool found = false; // check if already exists -- and don't allow if yes
383     for ( int i = 0; i < theLB->count(); i++ ) {
384       if ( ((PortListItem*)theLB->item(i))->PortName == name ) {
385         found = true;
386         break;
387       }
388     }
389     if ( found )
390       QMessageBox::warning( QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_PORT_EXIST") );
391     else
392       new PortListItem( theLB, name, myTypeCombo->currentText() );
393   }
394 }
395
396 void SUPERVGUI_ManagePortsDlg::removePort( QListBox* theLB ) {
397   if ( !theLB )
398     return;
399
400   const int i = theLB->currentItem();
401   if ( i >=0 )
402     delete theLB->item( i );    
403 }
404
405 void moveItem( QListBox* theLB, const int from, const int to ) {
406   if ( !theLB )
407     return;
408   if ( from >= 0 && from < theLB->count() && to >=0 && to < theLB->count() ) {
409     QListBoxItem* item = theLB->item( from );
410     theLB->takeItem( item );
411     theLB->insertItem( item, to );
412     theLB->setCurrentItem( item );
413     theLB->setSelected( item, true );
414   }
415 }
416
417 void SUPERVGUI_ManagePortsDlg::moveUp( QListBox* theLB ) {
418   if ( !theLB )
419     return;
420   const int i = theLB->currentItem();
421   moveItem( theLB, i, i-1 );
422 }
423
424 void SUPERVGUI_ManagePortsDlg::moveDown( QListBox* theLB ) {
425   if ( !theLB )
426     return;
427   const int i = theLB->currentItem();
428   moveItem( theLB, i, i+1 );
429 }
430
431
432 /**
433  * returns true if there is a current and selected item in the given listbox and it
434  * equals to the given item.
435  */
436 bool isEditingItem( const QListBoxItem* item, const QListBox* theLB ) {
437   return item && item == theLB->item( theLB->currentItem() ) && theLB->isSelected( item );
438 }
439
440 /**
441  * called when name is changed.  Tries to change name of the item, which was
442  * the last selected by user item in myInList or myOutList (myLastItem)
443  */
444 void SUPERVGUI_ManagePortsDlg::nameChanged( const QString& name ) {
445   if ( myFromItemChanged ) return;
446   if ( isEditingItem( myLastItem, myInList ) || isEditingItem( myLastItem, myOutList ) ) {
447     ((PortListItem*)myLastItem)->PortName = name;
448     //myLastItem->listBox()->repaint( true );
449     // it would be much better to change the item and repaint it -- but -- repaint() 
450     // is done only after a while, which is not good..  so -- "cheating" around
451     const int i = myLastItem->listBox()->index( myLastItem );
452     moveItem( myLastItem->listBox(), i, i );
453   }
454 }
455
456 /**
457  * called when type item in myTypeCombo is changed.  Tries to change type
458  * of the last selected by user item in myInList or myOutList (myLastItem)
459  */
460 void SUPERVGUI_ManagePortsDlg::typeChanged( const QString& type ) {
461   if ( myFromItemChanged ) return;
462   if ( isEditingItem( myLastItem, myInList ) || isEditingItem( myLastItem, myOutList ) ) {
463     ((PortListItem*)myLastItem)->PortType = type;
464     //myLastItem->listBox()->repaint( true );
465     // it would be much better to change the item and repaint it -- but -- repaint() 
466     // is done only after a while, which is not good..  so -- "cheating" around
467     const int i = myLastItem->listBox()->index( myLastItem );
468     moveItem( myLastItem->listBox(), i, i );
469   }
470 }
471
472 /**
473  * called when new item became "currentItem" in any myInList or myOutList listboxes.
474  */
475 void SUPERVGUI_ManagePortsDlg::itemChanged( QListBoxItem * item ) {
476   myFromItemChanged = true; // to disable nameChanged, typeChanged callbacks
477   myLastItem = item;
478   myNameEdt->setText( ((PortListItem*)item)->PortName );
479   for ( int i = 0; i < myTypeCombo->count(); i++ )
480     if ( myTypeCombo->text( i ) == ((PortListItem*)item)->PortType ) {
481       myTypeCombo->setCurrentItem( i );
482       break;
483     }
484   myFromItemChanged = false; // to enable nameChanged, typeChanged callbacks
485 }
486
487
488
489
490 /*!
491  * Port parameters dialog definition (taken from SUPERVGUI_Node.cxx without change)
492  */
493
494 SUPERVGUI_PortParamsDlg::SUPERVGUI_PortParamsDlg(const QStringList& thePortsNames)
495   : QDialog(QAD_Application::getDesktop(), 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu  ),
496     myPortsNames( thePortsNames )
497 {
498   setSizeGripEnabled( true );
499   setCaption("Port parameters");
500
501   QGridLayout* aBaseLayout = new QGridLayout( this );
502   aBaseLayout->setMargin( 11 ); aBaseLayout->setSpacing( 6 );
503
504   QLabel* aNameLbl = new QLabel("Port Name", this );
505   aBaseLayout->addWidget(aNameLbl, 0, 0);
506
507   myNameTxt = new QLineEdit( this );
508   aNameLbl->setBuddy( myNameTxt );
509   aBaseLayout->addWidget(myNameTxt, 0, 1);
510   
511   QLabel* aTypeLbl = new QLabel("Value Type", this );
512   aBaseLayout->addWidget(aTypeLbl, 1, 0);
513  
514   myTypeTxt = new QComboBox( this );
515   aTypeLbl->setBuddy( myTypeTxt );
516   myTypeTxt->insertStrList( gTypes );
517   aBaseLayout->addWidget(myTypeTxt, 1, 1);
518  
519   QGroupBox* aBtnBox = new QGroupBox( this );
520   aBtnBox->setColumnLayout( 0, Qt::Vertical );
521   aBtnBox->layout()->setSpacing( 0 ); aBtnBox->layout()->setMargin( 0 );
522   QHBoxLayout* aBtnLayout = new QHBoxLayout( aBtnBox->layout() );
523   aBtnLayout->setAlignment( Qt::AlignTop );
524   aBtnLayout->setSpacing( 6 ); aBtnLayout->setMargin( 11 );
525
526   aBaseLayout->addMultiCellWidget( aBtnBox, 2, 2, 0, 1 );
527
528   QPushButton* aOKBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
529   connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( clickOnOk() ) );
530   aBtnLayout->addWidget( aOKBtn );
531
532   aBtnLayout->addStretch();
533
534   QPushButton* aCancelBtn = new QPushButton( tr("BUT_CANCEL"), aBtnBox );
535   connect( aCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
536   aBtnLayout->addWidget( aCancelBtn );
537 }
538
539 void SUPERVGUI_PortParamsDlg::clickOnOk()
540 {
541   if (getName().isEmpty() || getType().isEmpty())
542     QMessageBox::warning( QAD_Application::getDesktop(), tr( "ERROR" ), tr( "MSG_CANT_CREATE_PORT" ) );
543   else if (myPortsNames.contains(getName()))
544     QMessageBox::warning( QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_PORT_EXIST") );
545   else  
546     accept();
547 }