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