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