Salome HOME
ILMAB project. A dialog box for creating/editing the Field on Geometry implemented
[modules/geom.git] / src / EntityGUI / EntityGUI_FieldDlg.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 //  File   : EntityGUI_FieldDlg.cxx
23
24 #include "EntityGUI_FieldDlg.h"
25
26 #include <DlgRef.h>
27 #include <GEOMBase.h>
28 #include <GEOMBase_Skeleton.h>
29 #include <GEOM_Displayer.h>
30 #include <GeometryGUI.h>
31
32 #include <SalomeApp_Application.h>
33 #include <SalomeApp_Study.h>
34 #include <SalomeApp_Tools.h>
35 #include <SalomeApp_IntSpinBox.h>
36 #include <SalomeApp_DoubleSpinBox.h>
37
38 #include <LightApp_SelectionMgr.h>
39
40 #include <OCCViewer_ViewModel.h>
41 #include <OCCViewer_ViewManager.h>
42 #include <SVTK_ViewModel.h>
43 #include <SALOME_Prs.h>
44 #include <SALOME_ListIteratorOfListIO.hxx>
45
46 #include <SUIT_Desktop.h>
47 #include <SUIT_MessageBox.h>
48 #include <SUIT_OverrideCursor.h>
49 #include <SUIT_ResourceMgr.h>
50 #include <SUIT_Session.h>
51 #include <SUIT_ViewWindow.h>
52 #include <SUIT_ViewManager.h>
53
54 #include <QComboBox>
55 #include <QGridLayout>
56 #include <QGroupBox>
57 #include <QHeaderView>
58 #include <QLabel>
59 #include <QLineEdit>
60 #include <QPushButton>
61 #include <QTableWidget>
62 #include <QVBoxLayout>
63
64 #include <AIS_ListOfInteractive.hxx>
65 #include <AIS_ListIteratorOfListOfInteractive.hxx>
66
67 #include <TopExp.hxx>
68 #include <TopExp_Explorer.hxx>
69 #include <TopTools_IndexedMapOfShape.hxx>
70 #include <TColStd_IndexedMapOfInteger.hxx>
71 #include <TColStd_MapOfInteger.hxx>
72 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
73
74 #include <limits>
75
76 #include <SALOMEDS_wrap.hxx>
77 #include <GEOMImpl_Types.hxx>
78
79
80 const int theIntLimit = std::numeric_limits<int>::max() - 10;
81
82 /*
83   Class       : EntityGUI_FieldDlg::CheckItem
84   Description : Bool item.
85 */
86 class EntityGUI_FieldDlg::CheckItem : public QTableWidgetItem
87 {
88 public:
89   static int     Type();
90
91   CheckItem( bool = false );
92   ~CheckItem();
93
94   void  setValue( bool );
95   bool  value() const;
96 };
97
98 int EntityGUI_FieldDlg::CheckItem::Type()
99 {
100   return QTableWidgetItem::UserType + 2;
101 }
102
103 EntityGUI_FieldDlg::CheckItem::CheckItem( bool value )
104  : QTableWidgetItem( Type() )
105 {
106   Qt::ItemFlags f = flags();
107   f = f | Qt::ItemIsUserCheckable;
108   f = f & ~Qt::ItemIsTristate;
109   f = f & ~Qt::ItemIsEditable;
110   setFlags( f );
111   setValue(value);
112 }
113
114 EntityGUI_FieldDlg::CheckItem::~CheckItem()
115 {
116 }
117
118 void EntityGUI_FieldDlg::CheckItem::setValue( bool value )
119 {
120   setCheckState( value ? Qt::Checked : Qt::Unchecked );
121 }
122
123 bool EntityGUI_FieldDlg::CheckItem::value() const
124 {
125   return checkState() == Qt::Checked;
126 }
127
128 /*
129   Class       : EntityGUI_FieldDlg::IntSpinItem
130   Description : Integer spin table item.
131 */
132
133 class EntityGUI_FieldDlg::IntSpinItem : public QTableWidgetItem
134 {
135 public:
136   static int     Type();
137
138   IntSpinItem( const int theValue );
139
140   int            value() const;
141   void           setValue( const int theValue );
142
143   void           clear();
144 };
145
146 int EntityGUI_FieldDlg::IntSpinItem::Type()
147 {
148   return QTableWidgetItem::UserType + 3;
149 }
150
151 EntityGUI_FieldDlg::IntSpinItem::IntSpinItem( const int theValue )
152  : QTableWidgetItem( Type() )
153 {
154   setValue( theValue );
155 }
156
157 int EntityGUI_FieldDlg::IntSpinItem::value() const
158 {
159   bool ok = false;
160   int value = data( Qt::UserRole ).toInt( &ok );
161   return ok ? value : 0; 
162 }
163
164 void EntityGUI_FieldDlg::IntSpinItem::setValue( const int theValue )
165 {
166   setData( Qt::UserRole, theValue );
167   setText( QString::number( theValue ) ); 
168 }
169
170 void EntityGUI_FieldDlg::IntSpinItem::clear()
171 {
172   setText( "" );
173 }
174
175 /*
176   Class       : EntityGUI_FieldDlg::DoubleSpinItem
177   Description : Double spin table item.
178 */
179
180 class EntityGUI_FieldDlg::DoubleSpinItem : public QTableWidgetItem
181 {
182 public:
183   static int     Type();
184
185   DoubleSpinItem( const double theValue, const int thePrecision=6 );
186
187   double         value() const;
188   void           setValue( const double theValue );
189
190   int            precision() const;
191   void           setPrecision( const int thePrecision );
192
193   void           clear();
194 };
195
196 int EntityGUI_FieldDlg::DoubleSpinItem::Type()
197 {
198   return QTableWidgetItem::UserType + 4;
199 }
200
201 EntityGUI_FieldDlg::DoubleSpinItem::DoubleSpinItem( const double theValue,
202                                                     const int    thePrecision)
203  : QTableWidgetItem( Type() )
204 {
205   setValue( theValue );
206   setPrecision( thePrecision );
207 }
208
209 double EntityGUI_FieldDlg::DoubleSpinItem::value() const
210 {
211   bool ok = false;
212   double value = data( Qt::UserRole ).toDouble( &ok );
213   return ok ? value : 0; 
214 }
215
216 void EntityGUI_FieldDlg::DoubleSpinItem::setValue( const double theValue )
217 {
218   setData( Qt::UserRole, theValue );
219   setText( QString::number( theValue ) ); 
220 }
221
222 int EntityGUI_FieldDlg::DoubleSpinItem::precision() const
223 {
224   bool ok = false;
225   int precision = data( Qt::UserRole + 1 ).toInt( &ok );
226   return ok ? precision : 0; 
227 }
228
229 void EntityGUI_FieldDlg::DoubleSpinItem::setPrecision( const int thePrecision )
230 {
231   setData( Qt::UserRole + 1, thePrecision );
232 }
233
234 void EntityGUI_FieldDlg::DoubleSpinItem::clear()
235 {
236   setText( "" );
237 }
238
239 /*
240   Class       : EntityGUI_FieldDlg::ComboDelegate
241   Description : Table used by this widget
242 */
243
244 class EntityGUI_FieldDlg::Delegate : public QItemDelegate
245 {
246 public:
247   Delegate( QObject* = 0 );
248   ~Delegate();
249   
250   QWidget*      createEditor( QWidget*, const QStyleOptionViewItem&,
251                               const QModelIndex& ) const;
252   
253   void          setEditorData( QWidget*, const QModelIndex& ) const;
254   void          setModelData( QWidget*, QAbstractItemModel*, const QModelIndex& ) const;
255   
256   void          updateEditorGeometry( QWidget*, const QStyleOptionViewItem&, 
257                                       const QModelIndex& ) const;
258 private:
259   StepTable* myTable;
260 };
261
262 /*
263   Class       : EntityGUI_FieldDlg::StepTable
264   Description : Table widget
265 */
266
267 class EntityGUI_FieldDlg::StepTable : public QTableWidget
268 {
269   //Q_OBJECT
270
271   int                      myDataType;
272   int                      myStepID;
273   int                      myStamp;
274   GEOM::GEOM_FieldStep_var myStep;
275   bool                     myIsChanged;
276
277   QTableWidgetItem * newDefaultItem();
278 public:
279   StepTable( int stepID, int dataType, int nbRows, int nbColumns,
280              QString shapeName, QStringList headers,
281              GEOM::GEOM_FieldStep_ptr stepVar, QWidget* = 0 );
282   virtual ~StepTable();
283
284   QSize                    minimumSizeHint() const;
285
286   void                     setEditable( bool, int, int );
287   bool                     isEditable( int, int ) const;
288
289   void                     setReadOnly( bool );
290   bool                     isReadOnly() const;
291
292   void                     insertRows( int, int = 1 );
293   QString                  text( int, int );
294
295   QList<int>               selectedRows();
296   void                     selectRows(const QList<int>& rows);
297
298   void                     setDim( int nbRows, QString shapeName, bool setDefault=true );
299   void                     setNbComps( int nbComps );
300   void                     setDataType( int dataType );
301   void                     setStamp( int stamp ) { myStamp = stamp; }
302   int                      getStamp() { return myStamp; }
303   int                      getStepID() { return myStepID; }
304   QStringList              getHeaders();
305   void                     setHeaders(const QStringList& headers);
306   GEOM::GEOM_FieldStep_var getStep() { return myStep; }
307   void                     setValues(GEOM::GEOM_FieldStep_var& step);
308
309   void                     setIsChanged() { myIsChanged = true; }
310 };
311
312 EntityGUI_FieldDlg::Delegate::Delegate( QObject* parent )
313   : QItemDelegate( parent ), 
314     myTable( dynamic_cast<EntityGUI_FieldDlg::StepTable*>( parent ) )
315 {
316 }
317   
318 EntityGUI_FieldDlg::Delegate::~Delegate()
319 {
320 }
321
322 QWidget* EntityGUI_FieldDlg::Delegate::createEditor( QWidget* parent,
323                                                      const QStyleOptionViewItem& option,
324                                                      const QModelIndex& index ) const
325 {
326   QVariant aData = index.data( Qt::UserRole );
327   QVariant::Type aDataType = aData.type();
328   if( aDataType == QVariant::Int ) {
329     bool ok = false;
330     int aValue = aData.toInt( &ok );
331     if ( ok ) {
332       SalomeApp_IntSpinBox* intSpin = new SalomeApp_IntSpinBox( -theIntLimit, theIntLimit, 1, parent, false, true );
333       intSpin->setFrame( false );
334       intSpin->setValue( aValue );
335       return intSpin;
336     }
337   }
338   else if( aDataType == QVariant::Double ) {
339     bool ok = false;
340     double aValue = aData.toDouble( &ok );
341     if ( ok ) {
342       int aPrecision = index.data( Qt::UserRole + 1 ).toInt( &ok );
343       if ( !ok )
344         aPrecision = 0;
345
346       SalomeApp_DoubleSpinBox* dblSpin = new SalomeApp_DoubleSpinBox( -1.e20, 1.e20, 1, aPrecision, 20, parent, false, true );
347       dblSpin->setFrame( false );
348       dblSpin->setValue( aValue );
349       return dblSpin;
350     }
351   }
352   return QItemDelegate::createEditor( parent, option, index );
353 }
354
355 void EntityGUI_FieldDlg::Delegate::setEditorData( QWidget* editor, 
356                                                   const QModelIndex& index ) const
357 {
358   QVariant data = index.model()->data( index, Qt::DisplayRole );
359   QString value = data.toString();
360   bool bOk = false;
361   if ( SalomeApp_DoubleSpinBox* dblSpin = dynamic_cast<SalomeApp_DoubleSpinBox*>( editor ) ) {
362     if( data.type() == QVariant::Double ) {
363       double valueDouble = data.toDouble( &bOk );
364       if( bOk )
365         dblSpin->setValue( valueDouble );
366     }
367   }
368   if ( !bOk ) QItemDelegate::setEditorData( editor, index );
369 }
370
371 void EntityGUI_FieldDlg::Delegate::setModelData( QWidget* editor,
372                                                  QAbstractItemModel* model,
373                                                  const QModelIndex& index) const
374 {
375   QString oldData = myTable->text( index.row(), index.column() );
376
377   if( SalomeApp_IntSpinBox* intSpin = dynamic_cast<SalomeApp_IntSpinBox*>( editor ) )
378     model->setData( index, intSpin->value(), Qt::DisplayRole );
379   else if( SalomeApp_DoubleSpinBox* dblSpin = dynamic_cast<SalomeApp_DoubleSpinBox*>( editor ) )
380     model->setData( index, dblSpin->value(), Qt::DisplayRole );
381   else
382     QItemDelegate::setModelData( editor, model, index );
383
384   QString newData = myTable->text( index.row(), index.column() );
385   if ( newData != oldData )
386     myTable->setIsChanged();
387 }
388
389 void EntityGUI_FieldDlg::Delegate::updateEditorGeometry( QWidget* editor,
390                                                          const QStyleOptionViewItem& option, 
391                                                          const QModelIndex& index ) const
392 {
393   editor->setGeometry( option.rect );
394 }
395
396 //=======================================================================
397 // name    : EntityGUI_FieldDlg::StepTable::Table
398 // Purpose : Constructor
399 //=======================================================================
400 EntityGUI_FieldDlg::StepTable::StepTable (int stepID, int dataType,
401                                           int nbRows, int nbComps,
402                                           QString shapeName, QStringList headers,
403                                           GEOM::GEOM_FieldStep_ptr stepVar,
404                                           QWidget* parent)
405   : QTableWidget(0, nbComps+1, parent),
406     myDataType( dataType ),
407     myStepID( stepID ),
408     myStamp( 0 ),
409     myStep( GEOM::GEOM_FieldStep::_duplicate( stepVar )),
410     myIsChanged( false )
411 {
412   setDim( nbRows, shapeName, stepVar->_is_nil() );
413
414   setHorizontalHeaderLabels( headers );
415   verticalHeader()->hide();
416
417   // set custom item delegate
418   setItemDelegate( new Delegate(this) );
419   // set edit triggers by default
420   setReadOnly( false );
421
422   if ( stepVar->_is_nil() )
423     return;
424
425   myStamp = stepVar->GetStamp();
426
427   const int nbColumns = nbComps + 1;
428
429   switch ( dataType )
430   {
431   case 0:
432   {
433     GEOM::GEOM_BoolFieldStep_var bs = GEOM::GEOM_BoolFieldStep::_narrow( stepVar );
434     if ( !bs->_is_nil() )
435     {
436       GEOM::short_array_var vals = bs->GetValues();
437       if ( vals->length() == nbRows * nbComps )
438         for ( int iV = 0, iR = 0; iR < nbRows; ++iR )
439           for ( int iC = 1; iC < nbColumns; ++iC )
440             setItem( iR, iC, new CheckItem( vals[ iV++ ]));
441     }
442     break;
443   }
444   case 1:
445   {
446     GEOM::GEOM_IntFieldStep_var is = GEOM::GEOM_IntFieldStep::_narrow( stepVar );
447     if ( !is->_is_nil() )
448     {
449       GEOM::ListOfLong_var vals = is->GetValues();
450       if ( vals->length() == nbRows * nbComps )
451         for ( int iV = 0, iR = 0; iR < nbRows; ++iR )
452           for ( int iC = 1; iC < nbColumns; ++iC )
453             setItem( iR, iC, new IntSpinItem( vals[ iV++ ]));
454     }
455     break;
456   }
457   case 2:
458   {
459     GEOM::GEOM_DoubleFieldStep_var ds = GEOM::GEOM_DoubleFieldStep::_narrow( stepVar );
460     if ( !ds->_is_nil() )
461     {
462       GEOM::ListOfDouble_var vals = ds->GetValues();
463       if ( vals->length() == nbRows * nbComps )
464         for ( int iV = 0, iR = 0; iR < nbRows; ++iR )
465           for ( int iC = 1; iC < nbColumns; ++iC )
466             setItem( iR, iC, new DoubleSpinItem( vals[ iV++ ]));
467     }
468     break;
469   }
470   default:
471     GEOM::GEOM_StringFieldStep_var ss = GEOM::GEOM_StringFieldStep::_narrow( stepVar );
472     if ( !ss->_is_nil() )
473     {
474       GEOM::string_array_var vals = ss->GetValues();
475       if ( vals->length() == nbRows * nbComps )
476         for ( int iV = 0, iR = 0; iR < nbRows; ++iR )
477           for ( int iC = 1; iC < nbColumns; ++iC )
478             setItem( iR, iC, new QTableWidgetItem( vals[ iV++ ].in() ));
479     }
480     break;
481   }
482 }
483
484 //=======================================================================
485 // name    : EntityGUI_FieldDlg::StepTable::~StepTable
486 // Purpose : Destructor
487 //=======================================================================
488 EntityGUI_FieldDlg::StepTable::~StepTable()
489 {
490 }
491
492 //=======================================================================
493 // name    : EntityGUI_FieldDlg::StepTable::minimumSizeHint
494 // Purpose : Get minimum size for the table
495 //=======================================================================
496 QSize EntityGUI_FieldDlg::StepTable::minimumSizeHint() const
497 {
498   QSize s = QTableWidget::minimumSizeHint();
499   QHeaderView* hv = horizontalHeader();
500   if ( hv )
501     s.setWidth( qMax( s.width(), hv->length() ) );
502   return s;
503 }
504
505 //=======================================================================
506 // name    : EntityGUI_FieldDlg::StepTable::setEditable
507 // Purpose : Set editable of specified cell
508 //=======================================================================
509 void EntityGUI_FieldDlg::StepTable::setEditable (bool isEditable,
510                                                  int row, int col)
511 {
512   QTableWidgetItem* anItem = item( row, col );
513   if ( anItem ) {
514     bool isSignalsBlocked = signalsBlocked();
515     blockSignals( true );
516
517     Qt::ItemFlags f = anItem->flags();
518     if ( !isEditable ) f = f & ~Qt::ItemIsEditable;
519     else f = f | Qt::ItemIsEditable;
520     anItem->setFlags( f );
521     
522     blockSignals( isSignalsBlocked );
523   }
524 }
525
526 //=======================================================================
527 // name    : EntityGUI_FieldDlg::StepTable::isEditable
528 // Purpose : Verify wheter cell is editable
529 //=======================================================================
530 bool EntityGUI_FieldDlg::StepTable::isEditable (int row, int col) const
531 {
532   QTableWidgetItem* anItem = item( row, col );
533   return anItem == 0 || anItem->flags() & Qt::ItemIsEditable;
534 }
535
536 void EntityGUI_FieldDlg::StepTable::setReadOnly( bool on )
537 {
538   setEditTriggers( on ? 
539                    QAbstractItemView::NoEditTriggers  :
540                    QAbstractItemView::AllEditTriggers );
541 }
542
543 bool EntityGUI_FieldDlg::StepTable::isReadOnly() const
544 {
545   return editTriggers() == QAbstractItemView::NoEditTriggers;
546 }
547
548 //=======================================================================
549 // name    : EntityGUI_FieldDlg::StepTable::insertRows
550 // Purpose : Insert rows (virtual redefined)
551 //=======================================================================
552 void EntityGUI_FieldDlg::StepTable::insertRows (int row, int count)
553 {
554   while ( count-- ) insertRow( row );
555 }
556
557 //=======================================================================
558 // name    : EntityGUI_FieldDlg::StepTable::text
559 // Purpose : Get text from cell (virtual redefined)
560 //=======================================================================
561 QString EntityGUI_FieldDlg::StepTable::text (int row, int col)
562 {
563   closePersistentEditor( currentItem() );
564   QTableWidgetItem* anItem = item( row, col );
565   return anItem ? anItem->text() : QString();
566 }
567
568 QList<int> EntityGUI_FieldDlg::StepTable::selectedRows()
569 {
570   QList<QTableWidgetItem*> selItems = selectedItems();
571   QTableWidgetItem* anItem;
572   QList<int> rows;
573
574   foreach( anItem, selItems ) {
575     int r = row( anItem );
576     if ( !rows.contains( r ) ) rows.append( r );
577   }
578
579   qSort( rows );
580   return rows;
581 }
582
583 //=======================================================================
584 //function : selectRows
585 //purpose  : 
586 //=======================================================================
587
588 void EntityGUI_FieldDlg::StepTable::selectRows(const QList<int>& rows)
589 {
590   closePersistentEditor( currentItem() );
591
592   QList<QTableWidgetSelectionRange> ranges = selectedRanges();
593   for ( int i = 0; i < ranges.count(); ++i )
594     setRangeSelected( ranges[i], false );
595
596   QList<int>::const_iterator row = rows.begin();
597   for ( ; row != rows.end(); ++row )
598     // QTableWidgetSelectionRange ( int top, int left, int bottom, int right )
599     setRangeSelected ( QTableWidgetSelectionRange(*row,0,*row,0), true );
600 }
601
602 //=======================================================================
603 //function : setDim
604 //purpose  : change nb rows in the table
605 //=======================================================================
606
607 void EntityGUI_FieldDlg::StepTable::setDim( int nbRows, QString shapeName, bool setDefault )
608 {
609   closePersistentEditor( currentItem() );
610   int curNbRows = rowCount();
611   if ( nbRows < curNbRows )
612   {
613     while ( nbRows < curNbRows )
614       removeRow( --curNbRows );
615   }
616   else if ( nbRows > curNbRows )
617   {
618     int nbColumns = columnCount();
619     for ( ; nbRows > curNbRows; ++curNbRows )
620     {
621       insertRow( curNbRows );
622       if ( setDefault )
623         for ( int iC = 1; iC < nbColumns; ++iC )
624           setItem( curNbRows, iC, newDefaultItem() );
625     }
626   }
627
628   int indexWidth = 1, maxNbR = 10;
629   while ( nbRows >= maxNbR )
630     ++indexWidth, maxNbR *= 10;
631   shapeName = shapeName.toLower() + "_%1";
632   for ( int iR = 0; iR < nbRows; ++iR )
633   {
634     setItem( iR, 0, new QTableWidgetItem( shapeName.arg( iR+1, indexWidth, 10, QChar('0') )));
635     setEditable( false, iR, 0 );
636   }
637 }
638
639 //=======================================================================
640 //function : setNbComps
641 //purpose  : 
642 //=======================================================================
643
644 void EntityGUI_FieldDlg::StepTable::setNbComps( int nbComps )
645 {
646   closePersistentEditor( currentItem() );
647   nbComps++; // add sub-shape column
648   int curNbCols = columnCount();
649   if ( nbComps < curNbCols )
650   {
651     while ( nbComps < curNbCols )
652       removeColumn( --curNbCols );
653   }
654   else if ( nbComps > curNbCols )
655   {
656     int nbRows = rowCount();
657     for ( ; nbComps > curNbCols; ++curNbCols )
658     {
659       insertColumn( curNbCols );
660       setHorizontalHeaderItem( curNbCols,
661                                new QTableWidgetItem(QString("Comp %1").arg( curNbCols )));
662       for ( int iR = 0; iR < nbRows; ++iR )
663         setItem( iR, curNbCols, newDefaultItem() );
664     }
665   }
666 }
667
668 //=======================================================================
669 //function : setDataType
670 //purpose  : change type of data
671 //=======================================================================
672
673 void EntityGUI_FieldDlg::StepTable::setDataType( int dataType )
674 {
675   myDataType = dataType;
676
677   int nbRows = rowCount();
678   int nbColumns = columnCount();
679
680   for ( int iR = 0; iR < nbRows; ++iR )
681     for ( int iC = 1; iC < nbColumns; ++iC )
682       setItem( iR, iC, newDefaultItem() );
683 }
684
685 //=======================================================================
686 //function : newDefaultItem
687 //purpose  : creates a table item with a default value
688 //=======================================================================
689
690 QTableWidgetItem * EntityGUI_FieldDlg::StepTable::newDefaultItem()
691 {
692   switch( myDataType ) {
693   case 0: return new CheckItem(false);
694   case 1: return new IntSpinItem(0);
695   case 2: return new DoubleSpinItem(0);
696   default:;
697   }
698   return new QTableWidgetItem(""); // string
699 }
700
701 //=======================================================================
702 //function : getHeaders
703 //purpose  : 
704 //=======================================================================
705
706 QStringList EntityGUI_FieldDlg::StepTable::getHeaders()
707 {
708   QStringList headers;
709   int nbColumns = columnCount();
710   for ( int iC = 0; iC < nbColumns; ++iC )
711     headers << horizontalHeaderItem( iC )->text();
712   return headers;
713 }
714
715 //=======================================================================
716 //function : setHeaders
717 //purpose  : 
718 //=======================================================================
719
720 void EntityGUI_FieldDlg::StepTable::setHeaders(const QStringList& headers)
721 {
722   setHorizontalHeaderLabels( headers );
723 }
724
725 //=======================================================================
726 //function : setValues
727 //purpose  : store values from this table to a field step
728 //=======================================================================
729
730 void EntityGUI_FieldDlg::StepTable::setValues(GEOM::GEOM_FieldStep_var& step)
731 {
732   closePersistentEditor( currentItem() );
733
734   if ( step->GetStamp() != myStamp )
735     step->SetStamp( myStamp );
736
737   if ( step->_is_equivalent( myStep ) && !myIsChanged )
738     return;
739
740   const int nbColumns = columnCount();
741   const int nbComps = nbColumns - 1;
742   const int nbRows = rowCount();
743
744   switch ( myDataType ) {
745   case 0:
746   {
747     GEOM::GEOM_BoolFieldStep_var bs = GEOM::GEOM_BoolFieldStep::_narrow( step );
748     if ( !bs->_is_nil() )
749     {
750       GEOM::short_array_var vals = new GEOM::short_array();
751       vals->length( nbRows * nbComps );
752       for ( int iV = 0, iR = 0; iR < nbRows; ++iR )
753         for ( int iC = 1; iC < nbColumns; ++iC )
754           vals[ iV++ ] = ((CheckItem*)item( iR, iC ))->value();
755       bs->SetValues( vals );
756     }
757     break;
758   }
759   case 1:
760   {
761     GEOM::GEOM_IntFieldStep_var is = GEOM::GEOM_IntFieldStep::_narrow( step );
762     if ( !is->_is_nil() )
763     {
764       GEOM::ListOfLong_var vals = new GEOM::ListOfLong();
765       vals->length( nbRows * nbComps );
766       for ( int iV = 0, iR = 0; iR < nbRows; ++iR )
767         for ( int iC = 1; iC < nbColumns; ++iC )
768           vals[ iV++ ] = text( iR, iC ).toInt();
769       is->SetValues( vals );
770     }
771     break;
772   }
773   case 2:
774   {
775     GEOM::GEOM_DoubleFieldStep_var ds = GEOM::GEOM_DoubleFieldStep::_narrow( step );
776     if ( !ds->_is_nil() )
777     {
778       GEOM::ListOfDouble_var vals = new GEOM::ListOfDouble();
779       vals->length( nbRows * nbComps );
780       for ( int iV = 0, iR = 0; iR < nbRows; ++iR )
781         for ( int iC = 1; iC < nbColumns; ++iC )
782           vals[ iV++ ] = text( iR, iC ).toDouble();
783       ds->SetValues( vals );
784     }
785     break;
786   }
787   default:
788
789     GEOM::GEOM_StringFieldStep_var ss = GEOM::GEOM_StringFieldStep::_narrow( step );
790     if ( !ss->_is_nil() )
791     {
792       GEOM::string_array_var vals = new GEOM::string_array();
793       vals->length( nbRows * nbComps );
794       for ( int iV = 0, iR = 0; iR < nbRows; ++iR )
795         for ( int iC = 1; iC < nbColumns; ++iC )
796           vals[ iV++ ] = item( iR, iC )->text().toLatin1().constData();
797       ss->SetValues( vals );
798     }
799   }
800
801   myIsChanged = false;
802
803   return;
804 }
805
806 //=======================================================================
807 //function : EntityGUI_FieldDlg
808 //purpose  : 
809 //=======================================================================
810
811 EntityGUI_FieldDlg::EntityGUI_FieldDlg (GeometryGUI* theGeometryGUI,
812                                         GEOM::GEOM_Field_ptr theField, int stepID,
813                                         QWidget* parent,
814                                         bool modal, Qt::WindowFlags fl)
815   : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
816     myIsCreation( CORBA::is_nil( theField )),
817     myField( GEOM::GEOM_Field::_duplicate( theField )),
818     myCurStepID( stepID ),
819     myCurStepTable( NULL ),
820     myIsHiddenMain( false )
821 {
822   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
823   QPixmap iconSelect (resMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
824
825   setWindowTitle(myIsCreation ? tr("CREATE_FIELD_TITLE") : tr("EDIT_FIELD_TITLE"));
826
827   // Shape type button group
828   mainFrame()->GroupConstructors->hide();
829
830   // Field name
831   mainFrame()->GroupBoxName->setTitle(tr("FIELD_NAME"));
832
833   // Field properties
834
835   QGroupBox* propGroup = new QGroupBox(tr("PROPERTIES"), centralWidget());
836   QGridLayout* propLayout = new QGridLayout(propGroup);
837   propLayout->setMargin(9);
838   propLayout->setSpacing(6);
839
840   // shape
841   QLabel* shapeLabel = new QLabel(tr("SHAPE"), propGroup);
842   myShapeSelBtn = new QPushButton(propGroup);
843   myShapeSelBtn->setIcon(iconSelect);
844   myShapeSelBtn->setEnabled( myIsCreation );
845   myShapeName = new QLineEdit(propGroup);
846   myShapeName->setReadOnly(true);
847   myShapeName->setEnabled( myIsCreation );
848
849   // data type
850   QLabel* typeLabel = new QLabel( tr("DATA_TYPE"), propGroup );
851   myTypeCombo = new QComboBox( propGroup );
852   myTypeCombo->insertItem( GEOM::FDT_Bool,   tr("BOOL"));
853   myTypeCombo->insertItem( GEOM::FDT_Int,    tr("INT"));
854   myTypeCombo->insertItem( GEOM::FDT_Double, tr("DOUBLE"));
855   myTypeCombo->insertItem( GEOM::FDT_String, tr("STRING"));
856   myTypeCombo->setCurrentIndex( GEOM::FDT_Double ); // double
857
858   // dimension
859   QLabel* dimLabel = new QLabel( tr("SHAPE_TYPE"), propGroup );
860   myDimCombo = new QComboBox( propGroup );
861
862   // nb components
863   QLabel* nbCompsLabel = new QLabel( tr("NB_COMPS"), propGroup );
864   myNbCompsSpin = new SalomeApp_IntSpinBox( 1, 1000, 1, propGroup, true, true );
865   myNbCompsSpin->setValue( 1 );
866   propLayout->addWidget(shapeLabel,         0, 0);
867   propLayout->addWidget(myShapeSelBtn,      0, 1);
868   propLayout->addWidget(myShapeName,        0, 2);
869   propLayout->addWidget(typeLabel,          1, 0, 1, 2);
870   propLayout->addWidget(myTypeCombo,        1, 2);
871   propLayout->addWidget(dimLabel,           2, 0, 1, 2);
872   propLayout->addWidget(myDimCombo,         2, 2);
873   propLayout->addWidget(nbCompsLabel,       3, 0, 1, 2);
874   propLayout->addWidget(myNbCompsSpin,      3, 2);
875   // propLayout->addWidget(shapeLabel,         0, 0);
876   // propLayout->addWidget(myShapeName,        0, 1);
877   // propLayout->addWidget(typeLabel,          1, 0);
878   // propLayout->addWidget(myTypeCombo,        1, 1);
879   // propLayout->addWidget(dimLabel,           2, 0);
880   // propLayout->addWidget(myDimCombo,         2, 1);
881   // propLayout->addWidget(nbCompsLabel,       3, 0);
882   // propLayout->addWidget(myNbCompsSpin,      3, 1);
883
884   propLayout->setColumnStretch(2, 5);
885
886   // Field values
887
888   QGroupBox* valsGroup = new QGroupBox(tr("VALUES"), centralWidget());
889   QGridLayout* valsLayout = new QGridLayout(valsGroup);
890   valsLayout->setMargin(9);
891   valsLayout->setSpacing(6);
892
893   // value table
894   mySwitchTableWdg = new QWidget(valsGroup);
895   QVBoxLayout* switchTableGrpLayout = new QVBoxLayout(mySwitchTableWdg);
896   switchTableGrpLayout->setMargin(0);
897   switchTableGrpLayout->setSpacing(0);
898
899   // step browse controls
900   myPrevStepBtn = new QPushButton( tr("PREV_STEP"), valsGroup );
901   QLabel* curStepLbl = new QLabel(tr("STEP"), valsGroup );
902   myStepsCombo = new QComboBox(valsGroup);
903   myNextStepBtn = new QPushButton( tr("NEXT_STEP"), valsGroup );
904
905   // step add/rm controls
906   QPushButton* addStepBtn = new QPushButton( tr("ADD_STEP"), valsGroup );
907   QLabel* stampLbl = new QLabel(tr("STAMP"), valsGroup );
908   myStampSpin = new SalomeApp_IntSpinBox( -theIntLimit, theIntLimit, 1, valsGroup, true, true);
909   myRmStepBtn = new QPushButton( tr("REMOVE_STEP"), valsGroup );
910
911   valsLayout->addWidget(mySwitchTableWdg,   0, 0, 1, 4);
912   valsLayout->addWidget(myPrevStepBtn,      1, 0);
913   valsLayout->addWidget(curStepLbl,         1, 1);
914   valsLayout->addWidget(myStepsCombo,       1, 2);
915   valsLayout->addWidget(myNextStepBtn,      1, 3);
916   valsLayout->addWidget(addStepBtn,         2, 0);
917   valsLayout->addWidget(stampLbl,           2, 1);
918   valsLayout->addWidget(myStampSpin,        2, 2);
919   valsLayout->addWidget(myRmStepBtn,        2, 3);
920
921   valsLayout->setColumnStretch(2, 5);
922   valsLayout->setRowStretch   (0, 5);
923
924   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
925   layout->setMargin(0); layout->setSpacing(6);
926   layout->addWidget(propGroup);
927   layout->addWidget(valsGroup);
928
929   setHelpFileName("geom_field_page.html");
930
931   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
932   connect(aSelMgr,       SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
933
934   connect(myPrevStepBtn, SIGNAL(clicked()),                 this, SLOT( onPrevStep() ));
935   connect(myNextStepBtn, SIGNAL(clicked()),                 this, SLOT( onNextStep() ));
936   connect(addStepBtn,    SIGNAL(clicked()),                 this, SLOT( onAddStep() ));
937   connect(myRmStepBtn,   SIGNAL(clicked()),                 this, SLOT( onRmStep() ));
938   connect(myStampSpin,   SIGNAL(valueChanged(int)),         this, SLOT( onStampChange() ));
939   connect(myStepsCombo,  SIGNAL(currentIndexChanged(int)),  this, SLOT( showCurStep() ));
940   connect(myStepsCombo,  SIGNAL(activated(int)),            this, SLOT( showCurStep() ));
941
942   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
943   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
944
945   Init();
946   //updateState();
947 }
948
949 //=======================================================================
950 //function : ~EntityGUI_FieldDlg
951 //purpose  : 
952 //=======================================================================
953
954 EntityGUI_FieldDlg::~EntityGUI_FieldDlg()
955 {
956   GEOM_Displayer* aDisplayer = getDisplayer();
957   if (myIsHiddenMain) {
958     aDisplayer->Display(myShape);
959     myIsHiddenMain = false;
960   }
961   // if ( !myField->_is_nil())
962   //   aDisplayer->Display(myField);
963 }
964
965 //=================================================================================
966 // function : Init()
967 // purpose  :
968 //=================================================================================
969 void EntityGUI_FieldDlg::Init()
970 {
971   myDmMode = -1;
972   myStepsCombo->clear();
973
974   if ( myIsCreation || myField->_is_nil() )
975   {
976     myIsCreation = true;
977     myStepTables.clear();
978     if ( myCurStepTable )
979       myCurStepTable->hide();
980     myCurStepTable = NULL;
981     myCurStepID = 0;
982
983     initName(tr("FIELD_PREFIX"));
984     myStampSpin->setValue(0);
985
986     SelectionIntoArgument();
987
988     onAddStep();
989
990     connect(myShapeSelBtn, SIGNAL(clicked()),                 this, SLOT(SetEditCurrentArgument()));
991     connect(myTypeCombo,   SIGNAL(currentIndexChanged(int)),  this, SLOT( onTypeChange()));
992     connect(myDimCombo,    SIGNAL(currentIndexChanged(int)),  this, SLOT( onDimChange()));
993     connect(myNbCompsSpin, SIGNAL(valueChanged(int)),         this, SLOT( onNbCompsChange()));
994
995   }
996   else // edition
997   {
998     myIsCreation = false;
999
1000     CORBA::String_var fName = myField->GetName();
1001     myMainFrame->ResultName->setText( fName.in() );
1002
1003     myShape = myField->GetShape();
1004     CORBA::String_var sName;
1005     if ( !myShape->_is_nil() )
1006       sName = myShape->GetName();
1007     myShapeName->setText( sName.in() ? sName.in() : "");
1008
1009     myTypeCombo->setCurrentIndex( myField->GetDataType() );
1010
1011     updateDims( myField->GetDimension() );
1012     updateShapeIDs();
1013
1014     GEOM::string_array_var compNames = myField->GetComponents();
1015     myNbCompsSpin->setValue( compNames->length() );
1016
1017     myShapeSelBtn->setEnabled( false );
1018     myShapeName->setEnabled( false );
1019     myTypeCombo->setEnabled( false );
1020     myDimCombo->setEnabled( false );
1021     myNbCompsSpin->setEnabled( false );
1022
1023     // get and sort step IDs
1024     GEOM::ListOfLong_var stepIDs = myField->GetSteps();
1025     QList< int > stepsList;
1026     for ( size_t i = 0; i < stepIDs->length(); ++i )
1027       stepsList.push_back( stepIDs[i] );
1028     qSort( stepsList.begin(), stepsList.end() );
1029
1030     myStepsCombo->blockSignals( true );
1031     for ( size_t i = 0; i < stepIDs->length(); ++i )
1032     {
1033       myStepsCombo->insertItem( i, QString::number( stepsList[i] ));
1034       if ( myCurStepID == stepsList[i] )
1035         myStepsCombo->setCurrentIndex( i );
1036     }
1037     // if ( myStepsCombo->count() == 0 )
1038     //   myStepsCombo->insertItem( 0, QString::number( myCurStepID ));
1039     myStepsCombo->blockSignals( false );
1040
1041     showCurStep();
1042     activateSelection();
1043   }
1044 }
1045
1046 //=================================================================================
1047 // function : enterEvent()
1048 // purpose  :
1049 //=================================================================================
1050 void EntityGUI_FieldDlg::enterEvent(QEvent* e)
1051 {
1052   if (!buttonCancel()->isEnabled())
1053     ActivateThisDialog();
1054 }
1055
1056 //=================================================================================
1057 // function : ClickOnOk()
1058 // purpose  :
1059 //=================================================================================
1060 void EntityGUI_FieldDlg::ClickOnOk()
1061 {
1062   setIsApplyAndClose(true);
1063   if (ClickOnApply())
1064     ClickOnCancel();
1065   setIsApplyAndClose(false);
1066 }
1067
1068 //=================================================================================
1069 // function : ClickOnApply()
1070 // purpose  :
1071 //=================================================================================
1072 bool EntityGUI_FieldDlg::ClickOnApply()
1073 {
1074   if(!isApplyAndClose()) {
1075     setIsDisableBrowsing( true );
1076     setIsDisplayResult( false );
1077   }
1078
1079   QString msg;
1080   if ( !isValid( msg ) ) {
1081     showError( msg );
1082     return false;
1083   }
1084   SUIT_OverrideCursor wc;
1085   SUIT_Session::session()->activeApplication()->putInfo( "" );
1086
1087   try {
1088     if ( openCommand() )
1089       if (!execute (/*isApplyAndClose()*/))
1090       {
1091         abortCommand();
1092         showError();
1093         return false;
1094       }
1095   }
1096   catch( const SALOME::SALOME_Exception& e ) {
1097     SalomeApp_Tools::QtCatchCorbaException( e );
1098     abortCommand();
1099     return false;
1100   }
1101   commitCommand();
1102
1103   if(!isApplyAndClose()) {
1104     setIsDisableBrowsing( false );
1105     setIsDisplayResult( true );
1106   }
1107
1108   if ( myIsCreation )
1109   {
1110     myField = GEOM::GEOM_Field::_nil();
1111     if ( !isApplyAndClose() )
1112       Init();
1113   }
1114   return true;
1115 }
1116
1117 //=================================================================================
1118 // function : ActivateThisDialog()
1119 // purpose  :
1120 //=================================================================================
1121 void EntityGUI_FieldDlg::ActivateThisDialog()
1122 {
1123   GEOMBase_Skeleton::ActivateThisDialog();
1124
1125   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
1126           this, SLOT(SelectionIntoArgument()));
1127
1128   activateSelection();
1129 }
1130
1131 //=================================================================================
1132 // function : SetEditCurrentArgument()
1133 // purpose  :
1134 //=================================================================================
1135 void EntityGUI_FieldDlg::SetEditCurrentArgument()
1136 {
1137   myEditCurrentArgument = myShapeName;
1138   SelectionIntoArgument();
1139 }
1140
1141 //=================================================================================
1142 // function : SelectionIntoArgument()
1143 // purpose  : Called when selection has changed
1144 //=================================================================================
1145 void EntityGUI_FieldDlg::SelectionIntoArgument()
1146 {
1147   if (myEditCurrentArgument == myShapeName ||  // Selection of a shape is active
1148       myShape->_is_nil())
1149   {
1150     myShapeName->setText("");
1151     myShape = GEOM::GEOM_Object::_nil();
1152
1153     LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
1154     SALOME_ListIO aSelList;
1155     aSelMgr->selectedObjects(aSelList);
1156     int nbSel = aSelList.Extent();
1157
1158     if (nbSel == 1) {
1159       GEOM::GEOM_Object_var anObj =
1160         GEOMBase::ConvertIOinGEOMObject(aSelList.First());
1161
1162       if ( GEOMBase::IsShape(anObj) && anObj->IsMainShape() ) {
1163         if (myIsHiddenMain) {
1164           GEOM_Displayer* aDisplayer = getDisplayer();
1165           aDisplayer->Display(myShape);
1166           myIsHiddenMain = false;
1167         }
1168         myShapeName->setText(GEOMBase::GetName(anObj));
1169
1170         if ( !anObj->_is_nil() && !anObj->IsSame( myShape ))
1171         {
1172           myShape = anObj;
1173           myShapeMap.Clear();
1174           myEditCurrentArgument = 0;
1175
1176           // re-fill myDimCombo
1177           const int curDim = getDim();
1178           updateDims( curDim );
1179
1180           // update table
1181           onDimChange();
1182         }
1183       }
1184     }
1185     else {
1186       if (myIsHiddenMain) {
1187         GEOM_Displayer* aDisplayer = getDisplayer();
1188         aDisplayer->Display(myShape);
1189         myIsHiddenMain = false;
1190       }
1191     }
1192   }
1193   else // select rows of a table according to shape selection
1194   {
1195     if ( !myCurStepTable )
1196       return;
1197
1198     bool isSignalsBlocked = myCurStepTable->signalsBlocked();
1199     myCurStepTable->blockSignals(true);
1200
1201     QList< int > rowsToSelect;
1202     TColStd_IndexedMapOfInteger aMapIndex;
1203     if ( getSelectedSubshapes(aMapIndex ))
1204       for (int ii = 1, nn = aMapIndex.Extent(); ii <= nn; ii++) {
1205         const int shapeID = aMapIndex( ii );
1206         for (int row = 0, n = myShapeIDs.size(); row < n; row++)
1207           if ( myShapeIDs[row] == shapeID ) {
1208             rowsToSelect.push_back( row );
1209             break;
1210           }
1211       }
1212     myCurStepTable->selectRows( rowsToSelect );
1213
1214     myCurStepTable->blockSignals(isSignalsBlocked);
1215   }
1216 }
1217
1218 //=================================================================================
1219 // function : onDimChange()
1220 // purpose  : update dialog at change of dimension
1221 //=================================================================================
1222 void EntityGUI_FieldDlg::onDimChange()
1223 {
1224   // get order of sub-shapes - myShapeIDs
1225   updateShapeIDs();
1226
1227   // update size of tables
1228   const int nbRows = myShapeIDs.size();
1229   QString subName = ( getDim() == -1 ) ? tr("WHOLE_SHAPE_VHEADER") : myDimCombo->currentText();
1230   QMap< int, StepTable* >::iterator tblIt = myStepTables.begin();
1231   for ( ; tblIt != myStepTables.end(); ++tblIt )
1232     if ( tblIt.value() )
1233       tblIt.value()->setDim( nbRows, subName );
1234
1235   activateSelection();
1236 }
1237
1238 //=======================================================================
1239 //function : onNbCompsChange
1240 //purpose  : 
1241 //=======================================================================
1242
1243 void EntityGUI_FieldDlg::onNbCompsChange()
1244 {
1245   QMap< int, StepTable* >::iterator tblIt = myStepTables.begin();
1246   for ( ; tblIt != myStepTables.end(); ++tblIt )
1247     if ( tblIt.value() )
1248       tblIt.value()->setNbComps( getNbComps() );
1249 }
1250
1251 //=======================================================================
1252 //function : onTypeChange
1253 //purpose  : 
1254 //=======================================================================
1255
1256 void EntityGUI_FieldDlg::onTypeChange()
1257 {
1258   QMap< int, StepTable* >::iterator tblIt = myStepTables.begin();
1259   for ( ; tblIt != myStepTables.end(); ++tblIt )
1260     if ( tblIt.value() )
1261       tblIt.value()->setDataType( myTypeCombo->currentIndex() );
1262 }
1263
1264 //=================================================================================
1265 // function : onPrevStep()
1266 // purpose  :
1267 //=================================================================================
1268 void EntityGUI_FieldDlg::onPrevStep()
1269 {
1270   int i = myStepsCombo->currentIndex();
1271   if ( i > 0 )
1272   {
1273     myStepsCombo->setCurrentIndex( i-1 );
1274     showCurStep();
1275   }
1276 }
1277
1278 //=================================================================================
1279 // function : onNextStep()
1280 // purpose  :
1281 //=================================================================================
1282 void EntityGUI_FieldDlg::onNextStep()
1283 {
1284   int i = myStepsCombo->currentIndex();
1285   if ( i+1 < myStepsCombo->count() )
1286   {
1287     myStepsCombo->setCurrentIndex( i+1 );
1288     showCurStep();
1289   }
1290 }
1291
1292 //=======================================================================
1293 //function : onAddStep
1294 //purpose  : 
1295 //=======================================================================
1296 void EntityGUI_FieldDlg::onAddStep()
1297 {
1298   if ( myStepsCombo->count() > 0 )
1299     myCurStepID = myStepsCombo->itemText( myStepsCombo->count()-1 ).toInt() + 1;
1300
1301   myStepsCombo->insertItem( myStepsCombo->count(), QString::number( myCurStepID ));
1302   myStepsCombo->setCurrentIndex( myStepsCombo->count() - 1 );
1303   myRemovedSteps.remove( getCurStepID() );
1304   //showCurStep();
1305 }
1306
1307 //=======================================================================
1308 //function : onRmStep
1309 //purpose  : 
1310 //=======================================================================
1311
1312 void EntityGUI_FieldDlg::onRmStep()
1313 {
1314   if ( myStepsCombo->count() > 1 )
1315   {
1316     myStepTables.remove( getCurStepID() );
1317     myRemovedSteps.insert( getCurStepID() );
1318     if ( myCurStepTable )
1319       myCurStepTable->hide();
1320     myCurStepTable = NULL;
1321     myStepsCombo->removeItem( myStepsCombo->currentIndex() );
1322     //showCurStep();
1323   }
1324 }
1325
1326 //=======================================================================
1327 //function : onStampChange
1328 //purpose  : 
1329 //=======================================================================
1330
1331 void EntityGUI_FieldDlg::onStampChange()
1332 {
1333   if ( myCurStepTable )
1334     myCurStepTable->setStamp( myStampSpin->value() );
1335 }
1336
1337 //=======================================================================
1338 //function : showCurStep
1339 //purpose  : 
1340 //=======================================================================
1341
1342 void EntityGUI_FieldDlg::showCurStep()
1343 {
1344   myCurStepID = getCurStepID();
1345
1346   QStringList headers;
1347   if ( myCurStepTable )
1348   {
1349     if ( myCurStepTable->getStepID() == myCurStepID )
1350     {
1351       myCurStepTable->show();
1352       return;
1353     }
1354     else
1355     {
1356       myCurStepTable->hide();
1357       headers = myCurStepTable->getHeaders();
1358       myCurStepTable->getStamp();
1359     }
1360   }
1361
1362   if ( myStepTables.count ( myCurStepID ))
1363   {
1364     myCurStepTable = myStepTables[ myCurStepID ];
1365     myCurStepTable->setHeaders( headers );
1366   }
1367   else
1368   {
1369     // if ( myStepsCombo->count() == 0 )
1370     //   return; // edit a field with no steps
1371
1372     // get step values
1373     GEOM::GEOM_FieldStep_var stepVar;
1374     if ( !myField->_is_nil() )
1375       stepVar = myField->GetStep( myCurStepID );
1376
1377     int nbComps = getNbComps();
1378     if ( headers.count() == 0 )
1379     {
1380       headers << tr("SUB_SHAPE_HEADER");
1381       if ( !myIsCreation && !myField->_is_nil() )
1382       {
1383         GEOM::string_array_var compNames = myField->GetComponents();
1384         for ( int iC = 0; iC < compNames->length(); ++iC )
1385           headers << compNames[ iC ].in();
1386       }
1387       else
1388       {
1389         for ( int iC = 0; iC < nbComps; ++iC )
1390           headers << QString("Comp %1").arg( iC + 1 );
1391       }
1392     }
1393     QString subName = ( getDim() == -1 ) ? tr("WHOLE_SHAPE_VHEADER") : myDimCombo->currentText();
1394     myCurStepTable = new StepTable( myCurStepID, getDataType(), myShapeIDs.size(),
1395                                     nbComps, subName, headers, stepVar, mySwitchTableWdg );
1396     myStepTables[ myCurStepID ] = myCurStepTable;
1397     mySwitchTableWdg->layout()->addWidget( myCurStepTable );
1398   }
1399   myCurStepTable->show();
1400   myStampSpin->setValue( myCurStepTable->getStamp() );
1401
1402   connect(myCurStepTable, SIGNAL(itemSelectionChanged()), this, SLOT( highlightSubShapes() ));
1403
1404   myPrevStepBtn->setEnabled( myStepsCombo->currentIndex() > 0 );
1405   myNextStepBtn->setEnabled( myStepsCombo->currentIndex()+1 < myStepsCombo->count() );
1406   myRmStepBtn->setEnabled( myStepsCombo->count() > 1 );
1407 }
1408
1409 //=================================================================================
1410 // function : getSelectedSubshapes
1411 // purpose  :
1412 //=================================================================================
1413 int EntityGUI_FieldDlg::getSelectedSubshapes (TColStd_IndexedMapOfInteger& theMapIndex)
1414 {
1415   theMapIndex.Clear();
1416
1417   SalomeApp_Application* app = myGeomGUI->getApp();
1418   if (!app || myShape->_is_nil())
1419     return 0;
1420
1421   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
1422   SALOME_ListIO aSelList;
1423   aSelMgr->selectedObjects(aSelList);
1424
1425   // try to find out and process the global selection
1426   // (of not published objects and of published sub-shapes)
1427   {
1428     SALOME_ListIteratorOfListIO anIter (aSelList);
1429     for (int i = 0; anIter.More(); anIter.Next(), i++)
1430     {
1431       Handle(SALOME_InteractiveObject) anIObj = anIter.Value();
1432       QString anEntry = anIObj->getEntry();
1433       QString str = "_";
1434       int index = anEntry.lastIndexOf(str);
1435       if (index > 0) // selection among special preview
1436       {
1437         anEntry.remove(0, index+1);
1438         int anIndex = anEntry.toInt();
1439         if (anIndex)
1440           theMapIndex.Add(anIndex);
1441       }
1442       else // selection among published shapes
1443       {
1444         SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
1445         if (!appStudy) return 0;
1446         _PTR(Study) aStudy = appStudy->studyDS();
1447
1448         _PTR(SObject) aSObj (aStudy->FindObjectID(anEntry.toLatin1().constData()));
1449         GEOM::GEOM_Object_var aGeomObj =
1450           GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(aSObj));
1451         TopoDS_Shape aShape;
1452         if (GEOMBase::GetShape(aGeomObj, aShape)) {
1453           if (aGeomObj->GetType() == GEOM_GROUP || aShape.ShapeType() == getShapeType())
1454           {
1455             TopExp_Explorer anExp (aShape, getShapeType());
1456             for (; anExp.More(); anExp.Next()) {
1457               TopoDS_Shape aSubShape = anExp.Current();
1458               int anIndex = myShapeMap.FindIndex(aSubShape);
1459               if (anIndex == 0) {
1460                 SUIT_MessageBox::warning(app->desktop(), QObject::tr("WRN_WARNING"),
1461                                          tr("WRN_NOT_SUBSHAPE"));
1462               }
1463               theMapIndex.Add(anIndex);
1464             }
1465           }
1466         }
1467       }
1468     } // for aSelList
1469   }
1470
1471   return theMapIndex.Extent();
1472 }
1473
1474 //=================================================================================
1475 // function : getShapeType()
1476 // purpose  :
1477 //=================================================================================
1478 TopAbs_ShapeEnum EntityGUI_FieldDlg::getShapeType(int* dim) const
1479 {
1480   
1481   switch ( dim ? *dim : getDim() )
1482   {
1483   case 0:  return TopAbs_VERTEX;
1484   case 1:  return TopAbs_EDGE;
1485   case 2:  return TopAbs_FACE;
1486   case 3:  return TopAbs_SOLID;
1487   default: return TopAbs_SHAPE;
1488   }
1489 }
1490
1491 //=======================================================================
1492 //function : getDim
1493 //purpose  : 
1494 //=======================================================================
1495
1496 int EntityGUI_FieldDlg::getDim() const
1497 {
1498   int i = myDimCombo->currentIndex();
1499   return ( i < 0 ) ? -1 : myDimCombo->itemData( i ).toInt();
1500 }
1501
1502 //=======================================================================
1503 //function : getDataType
1504 //purpose  : 
1505 //=======================================================================
1506
1507 int EntityGUI_FieldDlg::getDataType() const
1508 {
1509   return myTypeCombo->currentIndex();
1510 }
1511
1512 //=======================================================================
1513 //function : getCurStepID
1514 //purpose  : 
1515 //=======================================================================
1516
1517 int EntityGUI_FieldDlg::getCurStepID() const
1518 {
1519   if ( myStepsCombo->count() > 0 )
1520     return myStepsCombo->currentText().toInt();
1521   return myCurStepID;
1522 }
1523
1524 //=======================================================================
1525 //function : getNbComps
1526 //purpose  : 
1527 //=======================================================================
1528
1529 int EntityGUI_FieldDlg::getNbComps() const
1530 {
1531   return myNbCompsSpin->value();
1532 }
1533
1534 //=================================================================================
1535 // function : updateShapeIDs()
1536 // purpose  : update myShapeIDs
1537 //=================================================================================
1538 void EntityGUI_FieldDlg::updateShapeIDs()
1539 {
1540   myShapeIDs.clear();
1541   //myShapeMap.Clear();
1542   if ( !myShape->_is_nil() )
1543   {
1544     TopoDS_Shape aShape =
1545       GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myShape);
1546     if ( myShapeMap.IsEmpty() )
1547       TopExp::MapShapes(aShape, myShapeMap);
1548     TopAbs_ShapeEnum shapeType = getShapeType();
1549     if ( shapeType == TopAbs_SHAPE )
1550     {
1551       myShapeIDs.push_back( 1 );
1552     }
1553     else
1554     {
1555       TopTools_IndexedMapOfShape dimSubShapesMap;
1556       TopExp::MapShapes(aShape, shapeType, dimSubShapesMap);
1557       myShapeIDs.resize( dimSubShapesMap.Extent() );
1558       for ( int i = 1; i <= dimSubShapesMap.Extent(); ++i )
1559         myShapeIDs[i-1] = myShapeMap.FindIndex( dimSubShapesMap(i) );
1560     }
1561   }
1562 }
1563
1564 //=======================================================================
1565 //function : updateDims
1566 //purpose  : update myDimCombo
1567 //=======================================================================
1568
1569 void EntityGUI_FieldDlg::updateDims(int curDim)
1570 {
1571   myDimCombo->blockSignals( true );
1572   myDimCombo->clear();
1573   TopoDS_Shape aShape =
1574     GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myShape);
1575
1576   if ( !aShape.IsNull() )
1577   {
1578     const char* subNames[4] = { "VERTEX","EDGE","FACE","SOLID" };
1579     TopExp_Explorer exp;
1580     for ( int dim = 0; dim < 4; ++dim )
1581     {
1582       exp.Init( aShape, getShapeType(&dim));
1583       if ( exp.More() && !aShape.IsSame( exp.Current() ))
1584       {
1585         myDimCombo->insertItem( dim, tr( subNames[dim] ), dim );
1586         if ( dim == curDim )  // restore current dim
1587           myDimCombo->setCurrentIndex( myDimCombo->count()-1 );
1588       }
1589     }
1590     myDimCombo->insertItem( 4, tr("WHOLE"), -1 );
1591     if ( getDim() != curDim )
1592       myDimCombo->setCurrentIndex( myDimCombo->count()-1 );
1593   }
1594   myDimCombo->blockSignals( false );
1595 }
1596
1597 //=================================================================================
1598 // function : activateSelection
1599 // purpose  : Activate local selection
1600 //=================================================================================
1601 void EntityGUI_FieldDlg::activateSelection()
1602 {
1603   bool isApply = ((QPushButton*)sender() == buttonApply());
1604   if(!isApplyAndClose())
1605     erasePreview(false);
1606
1607   // local selection
1608   if (!myShape->_is_nil() &&
1609       !myEditCurrentArgument &&
1610       myShapeIDs.size() > 1 ) // shape type is already choosen by user
1611   {
1612     GEOM_Displayer*   aDisplayer = getDisplayer();
1613     CORBA::String_var aMainEntry = myShape->GetStudyEntry();
1614
1615     //display mode for main shape
1616     if ( myDmMode == -1 ) {
1617       SALOME_View* view = GEOM_Displayer::GetActiveView();
1618       if (view) {
1619         Handle(SALOME_InteractiveObject) io =
1620           new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
1621         if ( view->isVisible( io ) ) {
1622           Handle(GEOM_AISShape) aSh = GEOMBase::ConvertIOinGEOMAISShape( io, true );
1623           if(!aSh.IsNull()) {
1624             myDmMode = aSh->isTopLevel() ? aSh->prevDisplayMode() : aSh->DisplayMode();
1625           }
1626           // Hide main shape, if explode on VERTEX
1627           if(getShapeType() != TopAbs_VERTEX) {
1628             aDisplayer->Erase(myShape, false, false);
1629             myIsHiddenMain = true;
1630           }
1631         }
1632         else
1633           myDmMode = SUIT_Session::session()->resourceMgr()->integerValue( "Geometry", "display_mode" );
1634       }
1635     }
1636     aDisplayer->SetDisplayMode(myDmMode);
1637
1638     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
1639     if (getShapeType() == TopAbs_VERTEX) {
1640       if (myIsHiddenMain)
1641         aDisplayer->Display(myShape);
1642     }
1643     //aDisplayer->Erase(myField, false, false); ------- NOR YET implemented
1644
1645     QColor aColor = SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", "editField_color" );
1646     Quantity_NameOfColor aCol = SalomeApp_Tools::color( aColor ).Name();
1647
1648     if(!isApplyAndClose()) {
1649       SUIT_ViewWindow* aViewWindow = 0;
1650       SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
1651       if (activeStudy)
1652         aViewWindow = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1653       if (aViewWindow == 0) return;
1654
1655       SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
1656       if (aViewManager->getType() != OCCViewer_Viewer::Type() &&
1657           aViewManager->getType() != SVTK_Viewer::Type())
1658         return;
1659
1660       SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
1661       SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
1662       if (aView == 0) return;
1663
1664       TopoDS_Shape aMainShape = myShapeMap(1);
1665       for ( int i = 0; i < myShapeIDs.size(); ++i )
1666       {
1667         int index = myShapeIDs[ i ];
1668         TopoDS_Shape aSubShape = myShapeMap( index );
1669         QString anEntry = QString( "TEMP_" ) + aMainEntry.in() + QString("_%1").arg(index);
1670         Handle(SALOME_InteractiveObject) io =
1671           new SALOME_InteractiveObject(anEntry.toAscii(), "GEOM", "TEMP_IO");
1672         aDisplayer->SetColor( aCol );
1673         SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView);
1674         if (aPrs) {
1675           displayPreview(aPrs, true, false); // append, do not update
1676           // TODO: map or delete Prs
1677         }
1678       }
1679       aDisplayer->UnsetDisplayMode();
1680       aDisplayer->UnsetColor();
1681       aDisplayer->UpdateViewer();
1682     }
1683   }
1684
1685   globalSelection(GEOM_ALLSHAPES);
1686
1687   SelectionIntoArgument();
1688 }
1689
1690 //=================================================================================
1691 // function : highlightSubShapes
1692 // purpose  : select objects corresponding to selected table rows
1693 //=================================================================================
1694 void EntityGUI_FieldDlg::highlightSubShapes()
1695 {
1696   if (CORBA::is_nil(myShape) || !myCurStepTable )
1697     return;
1698
1699   TColStd_MapOfInteger anIds;
1700   QList<int> rows = myCurStepTable->selectedRows();
1701   int ii = 0, nn = rows.count();
1702   for (; ii < nn; ii++)
1703   {
1704     int shapeNum = rows[ ii ];
1705     if ( shapeNum < myShapeIDs.size() )
1706       anIds.Add( myShapeIDs[ shapeNum ]);
1707   }
1708
1709   SalomeApp_Application* app = myGeomGUI->getApp();
1710   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
1711   aSelMgr->clearSelected();
1712   if ( anIds.IsEmpty() )
1713     return;
1714
1715   SUIT_ViewWindow* aViewWindow = 0;
1716   SUIT_Study* activeStudy = app->activeStudy();
1717   if (activeStudy)
1718     aViewWindow = app->desktop()->activeWindow();
1719   if (aViewWindow == 0) return;
1720
1721   SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
1722   if (aViewManager->getType() != OCCViewer_Viewer::Type() &&
1723       aViewManager->getType() != SVTK_Viewer::Type())
1724     return;
1725
1726   SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
1727   SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
1728   if (aView == 0) return;
1729
1730   // TODO??: use here GEOMBase_Helper::myPreview instead of ic->DisplayedObjects()
1731
1732   OCCViewer_Viewer* v3d = ((OCCViewer_ViewManager*)aViewManager)->getOCCViewer();
1733   Handle(AIS_InteractiveContext) ic = v3d->getAISContext();
1734   AIS_ListOfInteractive List;
1735   //ic->DisplayedObjects(List);
1736   ic->ObjectsInside(List); // Mantis issue 0021367
1737
1738   SALOME_ListIO aSelList;
1739
1740   // To highlight the selected sub-shape in Object Browser, if it's already published under the main shape
1741   GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations(getStudyId());
1742   QMap<int, QString> childsMap;
1743   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
1744   if (appStudy) {
1745     _PTR(Study) aStudy = appStudy->studyDS();
1746     CORBA::String_var aMainEntry = myShape->GetStudyEntry();
1747     _PTR(SObject) aSObj = aStudy->FindObjectID( aMainEntry.in() );
1748     _PTR(ChildIterator) anIt = aStudy->NewChildIterator(aSObj);
1749     for (anIt->InitEx(true); anIt->More(); anIt->Next()) {
1750       GEOM::GEOM_Object_var aChild =
1751         GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(anIt->Value()));
1752       if (!CORBA::is_nil(aChild)) {
1753         int index = aLocOp->GetSubShapeIndex(myShape, aChild);
1754         if ( anIds.Contains( index )) {
1755           CORBA::String_var aChildEntry = aChild->GetStudyEntry();
1756           //childsMap.insert(index, aChildEntry.in());
1757             Handle(SALOME_InteractiveObject) tmpIO =
1758               new SALOME_InteractiveObject( aChildEntry.in(), "GEOM", "TEMP_IO");
1759             aSelList.Append(tmpIO);
1760         }
1761       }
1762     }
1763   }
1764
1765   AIS_ListIteratorOfListOfInteractive ite (List);
1766   for (; ite.More(); ite.Next()) {
1767     if (ite.Value()->IsInstance(STANDARD_TYPE(GEOM_AISShape))) {
1768       Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(ite.Value());
1769       if (aSh->hasIO()) {
1770         Handle(SALOME_InteractiveObject) anIO = aSh->getIO();
1771         QString anEntry = anIO->getEntry();
1772         int index = anEntry.lastIndexOf("_");
1773         anEntry.remove(0, index+1);
1774         int anIndex = anEntry.toInt();
1775         if (anIds.Contains(anIndex)) {
1776           aSelList.Append(anIO);
1777           // if (childsMap.contains (anIndex)) {
1778           //   Handle(SALOME_InteractiveObject) tmpIO = new SALOME_InteractiveObject(childsMap.value(anIndex).toLatin1().constData(), "GEOM", "TEMP_IO");
1779           //   aSelList.Append(tmpIO);
1780           // }
1781         }
1782       }
1783     }
1784   }
1785   aSelMgr->setSelectedObjects(aSelList);
1786 }
1787
1788 //=================================================================================
1789 // function : createOperation
1790 // purpose  :
1791 //=================================================================================
1792 GEOM::GEOM_IOperations_ptr EntityGUI_FieldDlg::createOperation()
1793 {
1794   return getGeomEngine()->GetIFieldOperations(getStudyId());
1795 }
1796
1797 #define RETURN_WITH_MSG(a, b) \
1798   if ((a)) { \
1799     theMessage += (b); \
1800     return false; \
1801   }
1802
1803 //=================================================================================
1804 // function : isValid()
1805 // purpose  : Verify validity of input data
1806 //=================================================================================
1807 bool EntityGUI_FieldDlg::isValid(QString& theMessage)
1808 {
1809   SalomeApp_Study* study = getStudy();
1810   RETURN_WITH_MSG  (!study, tr("GEOM_NO_STUDY"))
1811   RETURN_WITH_MSG  (study->studyDS()->GetProperties()->IsLocked(), tr("GEOM_STUDY_LOCKED"))
1812
1813   if ( myIsCreation ) {
1814     RETURN_WITH_MSG(CORBA::is_nil(myShape), tr("NO_SHAPE"))
1815   }
1816   else {
1817     RETURN_WITH_MSG(CORBA::is_nil(myShape), tr("NO_FIELD"))
1818   }
1819
1820   QString aName = getNewObjectName().trimmed();
1821   RETURN_WITH_MSG  (aName.isEmpty(), tr("EMPTY_NAME"))
1822
1823   RETURN_WITH_MSG  ( !myCurStepTable, tr("NO_VALUES"))
1824   return true;
1825 }
1826
1827 //=================================================================================
1828 // function : execute
1829 // purpose  :
1830 //=================================================================================
1831 bool EntityGUI_FieldDlg::execute()
1832 {
1833   SALOMEDS::Study_var aStudyDS = GeometryGUI::ClientStudyToStudy( getStudy()->studyDS() );
1834   SALOMEDS::StudyBuilder_var aBuilder = aStudyDS->NewBuilder();
1835
1836   QString aName = getNewObjectName().trimmed();
1837   QStringList anEntryList;
1838
1839   if ( myField->_is_nil() ) // create field
1840   {
1841     QStringList columnNames = myCurStepTable->getHeaders();
1842     int nbComps = columnNames.count() - 1;
1843     GEOM::string_array_var compNames = new GEOM::string_array();
1844     compNames->length( nbComps );
1845     for ( int iC = 0; iC < nbComps; ++iC )
1846       compNames[ iC ] = columnNames[ iC+1 ].toLatin1().constData();
1847
1848     GEOM::GEOM_IFieldOperations_var anOper = GEOM::GEOM_IFieldOperations::_narrow(getOperation());
1849     myField = anOper->CreateField( myShape,
1850                                    aName.toLatin1().constData(),
1851                                    GEOM::field_data_type( getDataType() ),
1852                                    CORBA::Short( getDim() ),
1853                                    compNames );
1854     if ( myField->_is_nil() )
1855       return false;
1856     
1857     SALOMEDS::SObject_wrap aSO =
1858       getGeomEngine()->AddInStudy( aStudyDS, myField, aName.toLatin1().constData(), myShape );
1859     if ( !aSO->_is_nil() ) {
1860       myField->UnRegister();
1861       CORBA::String_var entry = aSO->GetID();
1862       anEntryList << entry.in();
1863     }
1864   }
1865   else // update field name
1866   {
1867     myField->SetName( aName.toLatin1().constData() );
1868
1869     CORBA::String_var entry = myField->GetStudyEntry();
1870     if ( entry.in() ) {
1871       SALOMEDS::SObject_wrap SO = aStudyDS->FindObjectID( entry.in() );
1872       if ( !SO->_is_nil() ) {
1873         aBuilder->SetName(SO, aName.toLatin1().constData());
1874       }
1875     }
1876   }
1877
1878   // create / update steps
1879   QMap< int, StepTable* >::iterator i_tbl = myStepTables.begin();
1880   for ( ; i_tbl != myStepTables.end(); ++i_tbl )
1881   {
1882     StepTable* tbl = i_tbl.value();
1883     GEOM::GEOM_FieldStep_var step = tbl->getStep();
1884     if ( step->_is_nil() )
1885     {
1886       step = myField->GetStep( tbl->getStepID() );
1887       if ( step->_is_nil() )
1888       {
1889         step = myField->AddStep( tbl->getStepID(), tbl->getStamp() );
1890
1891         QString stepName = (tr("STEP")+" %1 %2").arg( tbl->getStepID() ).arg( tbl->getStamp() );
1892         SALOMEDS::SObject_wrap aSO =
1893           getGeomEngine()->AddInStudy( aStudyDS, step, stepName.toLatin1().constData(), myField );
1894         if ( /*!myIsCreation &&*/ !aSO->_is_nil() ) {
1895           step->UnRegister();
1896           CORBA::String_var entry = aSO->GetID();
1897           anEntryList << entry.in();
1898         }
1899       }
1900     }
1901     tbl->setValues( step );
1902   }
1903
1904   // remove steps
1905   if ( !myIsCreation )
1906   {
1907     QSet< int >::iterator stepID = myRemovedSteps.begin();
1908     for ( ; stepID != myRemovedSteps.end(); ++stepID )
1909     {
1910       GEOM::GEOM_FieldStep_var step = myField->GetStep( *stepID );
1911       if ( !step->_is_nil() )
1912       {
1913         CORBA::String_var entry = step->GetStudyEntry();
1914         myField->RemoveStep( *stepID );
1915
1916         if ( entry.in() ) {
1917           SALOMEDS::SObject_wrap SO = aStudyDS->FindObjectID( entry.in() );
1918           if ( !SO->_is_nil() )
1919             aBuilder->RemoveObjectWithChildren( SO );
1920         }
1921       }
1922     }
1923   }
1924   myRemovedSteps.clear();
1925
1926   updateObjBrowser();
1927
1928   if( SUIT_Application* anApp = SUIT_Session::session()->activeApplication() ) {
1929     LightApp_Application* aLightApp = dynamic_cast<LightApp_Application*>( anApp );
1930     if( aLightApp && !isDisableBrowsing() && anEntryList.count() )
1931     {
1932       aLightApp->browseObjects( anEntryList, isApplyAndClose(), isOptimizedBrowsing() );
1933       anApp->putInfo( QObject::tr("GEOM_PRP_DONE") );
1934     }
1935   }
1936
1937   return true;
1938 }