Salome HOME
Merge from V5_1_main 14/05/2010
[modules/visu.git] / src / VISUGUI / VisuGUI_SelectionPanel.cxx
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //  VISU VISUGUI : GUI of VISU component
21 //  File   : VisuGUI_SelectionPanel.h
22 //  Author : Laurent CORNABE & Hubert ROLLAND
23 //  Module : VISU
24 //  $Header$
25 //
26 #include "VisuGUI_SelectionPanel.h"
27
28 #include "VisuGUI.h"
29 #include "VisuGUI_Tools.h"
30 #include "VisuGUI_ViewTools.h"
31 #include "VisuGUI_SelectionPrefDlg.h"
32 #include "VisuGUI_GaussPointsSelectionPane.h"
33 #include "VisuGUI_FindPane.h"
34
35 #include "VISU_Event.h"
36 #include "VISU_ConvertorUtils.hxx"
37
38 #include "VISU_Actor.h"
39 #include "VISU_PrsObject_i.hh"
40 #include "VISU_Prs3d_i.hh"
41 #include "VISU_PipeLine.hxx"
42 #include "VISU_GaussPointsPL.hxx"
43 #include "VISU_GaussPtsSettings.h"
44 #include "VISU_PickingSettings.h"
45
46 #include "SalomeApp_Study.h"
47 #include "SalomeApp_Application.h"
48 #include "LightApp_Application.h"
49 #include "LightApp_SelectionMgr.h"
50 #include "LightApp_VTKSelector.h"
51
52 #include "SUIT_Desktop.h"
53 #include "SUIT_MessageBox.h"
54 #include "SUIT_ViewWindow.h"
55 #include "SUIT_Session.h"
56 #include "SUIT_ResourceMgr.h"
57
58 #include "SALOME_ListIO.hxx"
59 #include "SALOME_ListIteratorOfListIO.hxx"
60
61 #include "SVTK_ViewWindow.h"
62 #include "SVTK_Selector.h"
63 #include "SVTK_RenderWindowInteractor.h"
64
65 #include "VTKViewer_Algorithm.h"
66
67 #include "utilities.h"
68
69 // OCCT Includes
70 #include <TColStd_IndexedMapOfInteger.hxx>
71 #include <TColStd_MapOfInteger.hxx>
72
73 // QT Includes
74 #include <QLabel>
75 #include <QListWidget>
76 #include <QLayout>
77 #include <QButtonGroup>
78 #include <QRadioButton>
79 #include <QValidator>
80 #include <QPushButton>
81 #include <QToolButton>
82 #include <QGroupBox>
83 #include <QLineEdit>
84 #include <QValidator>
85 #include <QTableWidget>
86 #include <QVBoxLayout>
87 #include <QHBoxLayout>
88 #include <QKeyEvent>
89 #include <QHeaderView>
90 #include <QTabWidget>
91 #include <QScrollArea>
92 #include <QStackedWidget>
93
94 // VTK Includes
95 #include <vtkDataSetMapper.h>
96 #include <vtkDataSet.h>
97 #include <vtkPointData.h>
98 #include <vtkCellData.h>
99 #include <vtkCell.h>
100
101 // STL Includes
102 #include <map>
103
104 class CustomIntValidator: public QIntValidator
105 {
106 public:
107   CustomIntValidator( QObject * theParent ):
108     QIntValidator( 0, VTK_LARGE_ID, theParent )
109   {}
110
111   virtual 
112   State
113   validate( QString& theInput, int& thePos ) const
114   {
115     if( theInput.isEmpty() )
116       return QValidator::Acceptable;
117
118     return QIntValidator::validate( theInput, thePos );
119   }
120 };
121
122 VisuGUI_SelectionPanel::VisuGUI_SelectionPanel( VisuGUI* theModule, QWidget* theParent ) :
123   VisuGUI_Panel( tr( "WINDOW_TITLE" ), theModule, theParent, CloseBtn | HelpBtn ),
124   myPreferencesDlg( 0 )
125 {
126   setWindowTitle( tr( "WINDOW_TITLE" ) );
127   setObjectName( tr( "WINDOW_TITLE" ) );
128
129   QVBoxLayout* TopLayout = new QVBoxLayout ( mainFrame() );
130
131   QWidget* aNamePane = new QWidget (mainFrame());
132   QGridLayout* aNameLay = new QGridLayout (aNamePane);
133
134   QLabel* aMeshLbl = new QLabel (tr("MESH_NAME_LBL"), aNamePane);
135   myMeshName = new QLabel (aNamePane);
136   myMeshName->setText(tr("WRN_NO_AVAILABLE_DATA"));
137
138   QLabel* aFieldLbl = new QLabel (tr("FIELD_NAME_LBL"), aNamePane);
139   myFieldName = new QLabel (aNamePane);
140
141   aNameLay->addWidget(aMeshLbl, 0, 0);
142   aNameLay->addWidget(myMeshName, 0, 1);
143   aNameLay->addWidget(aFieldLbl, 1, 0);
144   aNameLay->addWidget(myFieldName, 1, 1);
145
146   TopLayout->addWidget(aNamePane);
147
148   myTabWidget = new QTabWidget( mainFrame() );
149
150   QTableWidget* aTable;
151
152   // Fill column data
153   myColumnData.insert( CellStdCell,  QList<int>() << Cell << Scalar << Vector );
154   myColumnData.insert( CellStdPoint, QList<int>() << Point << X << Y << Z << I << J << K << Scalar << Vector );
155   myColumnData.insert( PointStd,     QList<int>() << Point << X << Y << Z << I << J << K << Scalar << Vector );
156   myColumnData.insert( CellElno,     QList<int>() << Cell << Point << X << Y << Z << I << J << K << Scalar << Vector );
157   myColumnData.insert( PointElno,    QList<int>() << Point << X << Y << Z << I << J << K << Cell << Scalar << Vector );
158
159   QMap<int, QString> aColumnHeaders;
160   aColumnHeaders.insert( Cell, tr( "CELL_ID_HDR" ) );
161   aColumnHeaders.insert( Point, tr( "POINT_ID_HDR" ) );
162   aColumnHeaders.insert( X, "X" );
163   aColumnHeaders.insert( Y, "Y" );
164   aColumnHeaders.insert( Z, "Z" );
165   aColumnHeaders.insert( I, "I" );
166   aColumnHeaders.insert( J, "J" );
167   aColumnHeaders.insert( K, "K" );
168   aColumnHeaders.insert( Scalar, tr( "DATA_SCALAR_HDR" ) );
169   aColumnHeaders.insert( Vector, tr( "DATA_VECTOR_HDR" ) );
170
171   // Create Points pane
172   myPointsPane = new QWidget (mainFrame());
173   QVBoxLayout* aVBoxLayout = new QVBoxLayout(myPointsPane);
174
175   QGroupBox* aDataGrp = new QGroupBox ( tr("POINT_DATA_TITLE"), myPointsPane);
176   QGridLayout* aGridLay = new QGridLayout (aDataGrp);
177
178   aGridLay->addWidget( new QLabel (tr("DATA_ID_LBL"), aDataGrp), 0, 0 );
179   
180   myIDValLbl = new QLineEdit ("", aDataGrp);
181   aGridLay->addWidget( myIDValLbl, 0, 1 );
182   CustomIntValidator* aIntValidator = new CustomIntValidator (myIDValLbl);
183   aIntValidator->setBottom(0);
184   myIDValLbl->setValidator(aIntValidator);
185   connect(myIDValLbl, SIGNAL(returnPressed()), this, SLOT(onPointIdEdit()));
186
187   QToolButton* anIDBtn = new QToolButton( aDataGrp );
188   anIDBtn->setIcon( VISU::GetResourceMgr()->loadPixmap("VISU", tr( "ICON_OK" ) ) );
189   aGridLay->addWidget( anIDBtn, 0, 2 );
190   connect(anIDBtn, SIGNAL(clicked()), this, SLOT(onPointIdEdit()));
191
192   aVBoxLayout->addWidget( aDataGrp );
193
194   myPointStackedWg = new QStackedWidget( myPointsPane );
195
196   aTable = new QTableWidget( myPointStackedWg );
197   myPointStackedWg->insertWidget( StdMesh, aTable );
198   myTables.insert( PointStd, aTable );
199
200   aTable = new QTableWidget( myPointStackedWg );
201   myPointStackedWg->insertWidget( ElnoMesh, aTable );
202   myTables.insert( PointElno, aTable );
203
204   aVBoxLayout->addWidget(myPointStackedWg, 1, 0);
205
206   // Create Cells pane
207   myCellsPane = new QWidget (mainFrame());
208   QGridLayout* aCellLayout = new QGridLayout (myCellsPane);
209   aCellLayout->setRowStretch(0, 0);
210   aCellLayout->setRowStretch(1, 1);
211
212   QGroupBox* aCellGrp = new QGroupBox( tr("CELL_DATA_TITLE"), myCellsPane);
213   aGridLay = new QGridLayout (aCellGrp);
214
215   aGridLay->addWidget( new QLabel (tr("DATA_ID_LBL"), aCellGrp), 0, 0);
216   myCellIDValLbl = new QLineEdit ("", aCellGrp);
217   myCellIDValLbl->setValidator(aIntValidator);
218   aGridLay->addWidget( myCellIDValLbl, 0, 1);
219   connect(myCellIDValLbl, SIGNAL(returnPressed()), this, SLOT(onCellIdEdit()));
220
221   QToolButton* aCellIDBtn = new QToolButton( aDataGrp );
222   aCellIDBtn->setIcon( VISU::GetResourceMgr()->loadPixmap("VISU", tr( "ICON_OK" ) ) );
223   aGridLay->addWidget( aCellIDBtn, 0, 2 );
224   connect(aCellIDBtn, SIGNAL(clicked()), this, SLOT(onCellIdEdit()));
225
226   aCellLayout->addWidget(aCellGrp, 0, 0);
227
228   myCellStackedWg = new QStackedWidget( myCellsPane );
229
230   QTabWidget* aStdTabWidget = new QTabWidget( myCellStackedWg );
231   myCellStackedWg->insertWidget( StdMesh, aStdTabWidget );
232
233   aTable = new QTableWidget( aStdTabWidget );
234   aStdTabWidget->addTab( aTable, tr("CELL_INFO") );
235   myTables.insert( CellStdCell, aTable );
236
237   aTable = new QTableWidget( aStdTabWidget );
238   aStdTabWidget->addTab( aTable, tr("POINT_INFO") );
239   myTables.insert( CellStdPoint, aTable );
240
241   aTable = new QTableWidget( myCellStackedWg );
242   myCellStackedWg->insertWidget( ElnoMesh, aTable );
243   myTables.insert( CellElno, aTable );
244
245   aCellLayout->addWidget(myCellStackedWg, 1, 0);
246
247   // Common operations for all tables
248   QMap<int, QTableWidget*>::iterator it = myTables.begin(), itEnd = myTables.end();
249   for( ; it != itEnd; ++it )
250   {
251     aTable = it.value();
252     if( !aTable )
253       continue;
254
255     int aTableId = it.key();
256     if( !myColumnData.contains( aTableId ) )
257       continue;
258
259     QStringList aHorizontalHeaderLabels;
260     QList<int> aColumns = myColumnData[ aTableId ];
261     QListIterator<int> aColumnIter( aColumns );
262     while( aColumnIter.hasNext() )
263     {
264       int aColumnId = aColumnIter.next();
265       if( aColumnId >= 0 && aColumnId < aColumnHeaders.size() )
266         aHorizontalHeaderLabels << aColumnHeaders[ aColumnId ];
267     }
268     aTable->setColumnCount( aHorizontalHeaderLabels.size() );
269     aTable->setHorizontalHeaderLabels( aHorizontalHeaderLabels );
270
271     aTable->setEditTriggers( QAbstractItemView::NoEditTriggers );
272     aTable->setSelectionMode( QAbstractItemView::SingleSelection );
273     aTable->resizeColumnsToContents();
274
275     connect( aTable, SIGNAL( doubleClicked( const QModelIndex& ) ),
276              this, SLOT( onDoubleClicked( const QModelIndex& ) ) );
277   }
278
279   // Actor Pane
280   myActorsPane = new QWidget (mainFrame());
281   aVBoxLayout = new QVBoxLayout(myActorsPane);  
282
283   QGroupBox* aPosGrp = new QGroupBox (tr("ACTOR_DATA_POSITION_TITLE"), myActorsPane);
284   aGridLay = new QGridLayout (aPosGrp);
285   aGridLay->addWidget( new QLabel ("X:", aPosGrp), 0, 0);
286   myXPosLbl = new QLabel ("0", aPosGrp);
287   aGridLay->addWidget( myXPosLbl, 0, 1);
288   aGridLay->addWidget( new QLabel ("Y:", aPosGrp), 1, 0);
289   myYPosLbl = new QLabel ("0", aPosGrp);
290   aGridLay->addWidget( myYPosLbl, 1, 1);
291   aGridLay->addWidget( new QLabel ("Z:", aPosGrp), 2, 0);
292   myZPosLbl = new QLabel ("0", aPosGrp);
293   aGridLay->addWidget( myZPosLbl, 2, 1);
294
295   aVBoxLayout->addWidget( aPosGrp );
296
297   QGroupBox* aSizeGrp = new QGroupBox ( tr("ACTOR_DATA_SIZE_TITLE"), myActorsPane);
298   aGridLay = new QGridLayout (aSizeGrp);
299   aGridLay->addWidget( new QLabel ("dX:", aSizeGrp ), 0, 0);
300   myDXLbl = new QLabel ("0", aSizeGrp);
301   aGridLay->addWidget( myDXLbl, 0, 1);
302   aGridLay->addWidget( new QLabel ("dY:", aSizeGrp ), 1, 0);
303   myDYLbl = new QLabel ("0", aSizeGrp);
304   aGridLay->addWidget( myDYLbl, 1, 1);
305   aGridLay->addWidget( new QLabel ("dZ:", aSizeGrp ), 2, 0);
306   myDZLbl = new QLabel ("0", aSizeGrp);
307   aGridLay->addWidget( myDZLbl, 2, 1);
308
309   aVBoxLayout->addWidget( aSizeGrp );
310   aVBoxLayout->addStretch();
311
312   // Gauss Points Pane
313   myGaussPointsPane = new VisuGUI_GaussPointsSelectionPane( myModule, mainFrame() );
314
315   // Add panes to tab widget
316   myTabWidget->addTab(myActorsPane, tr("MODE_ACTOR"));
317   myTabWidget->addTab(myCellsPane,  tr("MODE_CELL"));
318   myTabWidget->addTab(myPointsPane, tr("MODE_POINT"));
319   myTabWidget->addTab(myGaussPointsPane, tr("MODE_GAUSS_POINT"));
320
321   connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( onSelectionModeChanged( int ) ) );
322
323   TopLayout->addWidget( myTabWidget );
324
325   // Find Pane
326   myFindPane = new VisuGUI_FindPane( mainFrame() );
327
328   connect( myFindPane, SIGNAL( idChanged( int, int ) ), this, SLOT( onIdChanged( int, int ) ) );
329
330   TopLayout->addWidget( myFindPane );
331
332   // Preferences button
333   QPushButton* aPrefBtn = new QPushButton( tr( "SELECTION_PREFERENCES" ),  mainFrame() );
334   connect( aPrefBtn, SIGNAL( clicked() ), this, SLOT( onPreferences() ) );
335
336   TopLayout->addWidget( aPrefBtn );
337
338   connect( myModule->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
339            this,                               SLOT( onSelectionEvent() ) );
340
341   connect( this, SIGNAL( selectionModeChanged( int ) ), myModule, SLOT( OnSwitchSelectionMode( int ) ) );
342
343   myFl = false;
344
345   // Activate Points pane
346   myTabWidget->setCurrentWidget(myActorsPane);
347   if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule))
348     aViewWindow->SetSelectionMode(ActorSelection);
349   onSelectionEvent();
350 }
351
352 VisuGUI_SelectionPanel::~VisuGUI_SelectionPanel()
353 {
354   if( myPreferencesDlg )
355   {
356     delete myPreferencesDlg;
357     myPreferencesDlg = 0;
358   }
359 }
360
361 int VisuGUI_SelectionPanel::column( int theTableId, int theColumnId )
362 {
363   if( !myColumnData.contains( theTableId ) )
364     return -1;
365
366   const QList<int>& aColumnList = myColumnData[ theTableId ];
367   return aColumnList.indexOf( theColumnId );
368 }
369
370 QVariant VisuGUI_SelectionPanel::data( int theTableId, int theRow, int theColumnId )
371 {
372   if( !myTables.contains( theTableId ) )
373     return QVariant();
374
375   if( QTableWidget* aTable = myTables[ theTableId ] )
376     if( QAbstractItemModel* aModel = aTable->model() )
377       return aModel->data( aModel->index( theRow, column( theTableId, theColumnId ) ) );
378
379   return QVariant();
380 }
381
382 void VisuGUI_SelectionPanel::setData( int theTableId, int theRow, int theColumnId, const QVariant& theValue )
383 {
384   if( !myTables.contains( theTableId ) )
385     return;
386
387   if( QTableWidget* aTable = myTables[ theTableId ] )
388     if( QAbstractItemModel* aModel = aTable->model() )
389       aModel->setData( aModel->index( theRow, column( theTableId, theColumnId ) ), theValue );
390 }
391
392 void VisuGUI_SelectionPanel::setRowSpan( int theTableId, int theRow, int theColumnId, int theRowSpan )
393 {
394   if( !myTables.contains( theTableId ) )
395     return;
396
397   if( QTableWidget* aTable = myTables[ theTableId ] )
398     aTable->setSpan( theRow, column( theTableId, theColumnId ), theRowSpan, 1 );
399 }
400
401 VisuGUI_SelectionPrefDlg* VisuGUI_SelectionPanel::preferencesDlg()
402 {
403   if( !myPreferencesDlg )
404     myPreferencesDlg = new VisuGUI_SelectionPrefDlg();
405   myPreferencesDlg->update();
406   return myPreferencesDlg;
407 }
408
409 void VisuGUI_SelectionPanel::setSelectionMode( int theId )
410 {
411   myTabWidget->setCurrentIndex( theId );
412 }
413
414 void VisuGUI_SelectionPanel::onSelectionModeChanged( int theId )
415 {
416   SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule);
417   if (!aViewWindow) return;
418
419   switch (theId) {
420   case 0: // Actor
421     aViewWindow->SetSelectionMode(ActorSelection);
422     onSelectionEvent();
423     break;
424   case 1: // Cells
425     aViewWindow->SetSelectionMode(CellSelection);
426     onCellIdEdit();
427     break;
428   case 2: // Points
429     aViewWindow->SetSelectionMode(NodeSelection);
430     onPointIdEdit();
431     break;
432   case 3: // Gauss Points
433     aViewWindow->SetSelectionMode(GaussPointSelection);
434     myGaussPointsPane->update();
435     onSelectionEvent();
436     break;
437   }
438
439   myFindPane->setSelectionMode( aViewWindow->SelectionMode() );
440
441   emit selectionModeChanged( theId );
442 }
443
444 void VisuGUI_SelectionPanel::showEvent( QShowEvent* theEvent )
445 {
446   VisuGUI_Panel::showEvent(theEvent);
447 }
448
449 void VisuGUI_SelectionPanel::closeEvent( QCloseEvent* theEvent )
450 {
451   //onClose();
452   VisuGUI_Panel::closeEvent(theEvent);
453 }
454
455 template<class TData> QString getScalar(TData* theData, int theId){
456   if (vtkDataArray *aScalar = theData->GetScalars()){
457     vtkFloatingPointType aVal = aScalar->GetTuple1(theId);
458     return QString::number(aVal);
459   } else {
460     return QString("No data");
461   }
462 }
463
464 template<class TData> QString getVector(TData* theData, int theId){
465   if (vtkDataArray *aVector = theData->GetVectors()) {
466     vtkFloatingPointType *aVal = aVector->GetTuple3(theId);
467     return QString("%1; %2; %3").arg(aVal[0]).arg(aVal[1]).arg(aVal[2]);
468   } else {
469     return QString("No data");
470   }
471 }
472
473 template<class TData> TValueData getValueData( TPointID thePointVTKID, VISU_Actor* theActor, TData* theData )
474 {
475   TValueData aValueData;
476
477   aValueData.Scalar = getScalar( theData, thePointVTKID );
478   aValueData.Vector = getVector( theData, thePointVTKID );
479
480   return aValueData;
481 }
482
483 TPointData getPointData( TPointID thePointVTKID, VISU_Actor* theActor, const VISU::PIDMapper& theMapper,
484                          bool theIsValueData )
485 {
486   TPointData aPointData;
487
488   vtkDataSet* aDataSet = theActor->GetMapper()->GetInput();
489
490   vtkFloatingPointType* aCoord = aDataSet->GetPoint( thePointVTKID );
491   aPointData.X = aCoord[0];
492   aPointData.Y = aCoord[1];
493   aPointData.Z = aCoord[2];
494
495   TPointID aPointObjID = theActor->GetNodeObjId( thePointVTKID );
496   VISU::TStructuredId aVec = theMapper->GetIndexesOfNode( aPointObjID );
497   aPointData.I = aVec[0];
498   aPointData.J = aVec[1];
499   aPointData.K = aVec[2];
500
501   if( theIsValueData )
502     aPointData.ValueData = getValueData( thePointVTKID, theActor, aDataSet->GetPointData() );
503
504   return aPointData;
505 }
506
507 void VisuGUI_SelectionPanel::onSelectionEvent() {
508   SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule);
509   if (!aViewWindow)
510     return;
511
512   switch (aViewWindow->SelectionMode()) {
513   case ActorSelection:
514   case CellSelection:
515   case NodeSelection:
516   case GaussPointSelection:
517     break;
518   default:
519     hide();
520     return;
521   }
522
523   if (myFl)
524     return;
525   myFl = true;
526
527   int aType = myTabWidget->currentIndex();
528
529   SVTK_RenderWindowInteractor* anInteractor = aViewWindow->GetInteractor();
530   myGaussPointsPane->setInteractor(anInteractor);
531
532   SVTK_Selector* aSelector = aViewWindow->GetSelector();
533
534   _PTR(SObject) aSObject;
535   VISU::Prs3d_i* aPrs3d = NULL;
536   Handle(SALOME_InteractiveObject) anIO;
537
538   VISU::TSelectionInfo aSelectionInfo = VISU::GetSelectedObjects(myModule);
539   if(aSelectionInfo.size() == 1){
540     // Get selected SObject
541     VISU::TSelectionItem aSelectionItem = aSelectionInfo.front();
542     VISU::TObjectInfo anObjectInfo = aSelectionItem.myObjectInfo;
543     aPrs3d = GetPrs3dFromBase(anObjectInfo.myBase);
544     if(aPrs3d){
545       anIO = aSelectionItem.myIO;
546       aSObject = anObjectInfo.mySObject;
547     }
548   }
549   
550   clearFields();
551
552   if (aPrs3d) {
553     QString aMeshName("NULL"), aFieldName("NULL");
554     if (aSObject) {
555       VISU::Storable::TRestoringMap aMap = VISU::Storable::GetStorableMap(aSObject);
556       if (!aMap.empty()) {
557         aMeshName  = VISU::Storable::FindValue(aMap, "myMeshName");
558         aFieldName = VISU::Storable::FindValue(aMap, "myFieldName");
559       }
560     }
561
562     myMeshName ->setText((aMeshName  == "NULL") ? QString("No name") : aMeshName);
563     myFieldName->setText((aFieldName == "NULL") ? QString("No name") : aFieldName);
564
565     VISU_Actor* anVISUActor =
566       VISU::FindActor(VISU::GetAppStudy(myModule), aViewWindow, aSObject->GetID().c_str());
567     myFindPane->setActor( anVISUActor );
568     if (anVISUActor) {
569       vtkFloatingPointType aCoord[6];
570       anVISUActor->GetBounds(aCoord);
571       myXPosLbl->setText(QString::number( aCoord[0] ));
572       myYPosLbl->setText(QString::number( aCoord[2] ));
573       myZPosLbl->setText(QString::number( aCoord[4] ));
574
575       myDXLbl->setText(QString::number( fabs(aCoord[1]-aCoord[0]) ));
576       myDYLbl->setText(QString::number( fabs(aCoord[3]-aCoord[2]) ));
577       myDZLbl->setText(QString::number( fabs(aCoord[5]-aCoord[4]) ));
578
579       TColStd_IndexedMapOfInteger aMapIndex;
580       aSelector->GetIndex(anIO, aMapIndex);
581       bool aSingleSelection = aMapIndex.Extent() == 1;
582
583       vtkDataSet* aDataSet = anVISUActor->GetMapper()->GetInput();
584       bool isElno = VISU::IsElnoData( aDataSet );
585
586       const VISU::PIDMapper& aMapper = aPrs3d->GetPipeLine()->GetIDMapper();
587       bool isStructured = aMapper->IsStructured();
588
589       TCellToPointDataMap aCellToPointDataMap;
590       TPointToCellDataMap aPointToCellDataMap;
591       TPointDataMap aGlobalPointDataMap;
592
593       for (int ind = 1; ind <= aMapIndex.Extent(); ind++) {
594         int anID = aMapIndex(ind);
595
596         switch( aType )
597         {
598           case 1:
599           {
600             if( aSingleSelection )
601               myCellIDValLbl->setText( QString::number( anID ) );
602
603             vtkCell* aCell = anVISUActor->GetElemCell( anID );
604             int aCellVTKID = anVISUActor->GetElemVTKID( anID );
605             if( !aCell || aCellVTKID < 0 )
606               break;
607
608             int aNbOfPoints = aCell->GetNumberOfPoints();
609             if( aNbOfPoints < 1 )
610               break;
611
612             TPointDataMap aPointDataMap;
613
614             vtkIdList* aPointList = aCell->GetPointIds();
615             for( int i = 0; i < aNbOfPoints; i++ )
616             {
617               int aPointVTKID = aPointList->GetId(i);
618
619               TPointID aPointID = anVISUActor->GetNodeObjId( aPointVTKID );
620               TPointData aPointData = getPointData( aPointVTKID, anVISUActor, aMapper, true );
621               aPointDataMap[ aPointID ] = aPointData;
622               aGlobalPointDataMap[ aPointID ] = aPointData;
623             }
624
625             TCellToPointData aCellToPointData;
626             aCellToPointData.CellData = getValueData( aCellVTKID, anVISUActor, aDataSet->GetCellData() );
627             aCellToPointData.PointDataMap = aPointDataMap;
628             aCellToPointDataMap[ anID ] = aCellToPointData;
629             break;
630           }
631           case 2:
632           {
633             if( aSingleSelection )
634               myIDValLbl->setText( QString::number( anID ) );
635
636             int aPointVTKID = anVISUActor->GetNodeVTKID( anID );
637             if( aPointVTKID < 0 )
638               break;
639
640             TCellDataMap aCellDataMap;
641
642             VISU::TElnoPoints anElnoPoints = VISU::GetElnoPoints( aDataSet, anID );
643             VISU::TElnoPoints::iterator anElnoIter = anElnoPoints.begin();
644             for( ; anElnoIter != anElnoPoints.end(); anElnoIter++ )
645             {
646               VISU::TElnoPointID anElnoPointID = *anElnoIter;
647               VISU::TVTKPointID aVTKPointID = anElnoPointID.first;
648               VISU::TVTKCellID aVTKCellID = anElnoPointID.second;
649
650               TCellID aCellID = anVISUActor->GetElemObjId( aVTKCellID );
651               TValueData aValueData = getValueData( aVTKPointID, anVISUActor, aDataSet->GetPointData() );
652               aCellDataMap[ aCellID ] = aValueData;
653             }
654
655             TPointToCellData aPointToCellData;
656             aPointToCellData.PointData = getPointData( aPointVTKID, anVISUActor, aMapper, !isElno );
657             aPointToCellData.CellDataMap = aCellDataMap;
658             aPointToCellDataMap[ anID ] = aPointToCellData;
659             break;
660           }
661         }
662       }
663
664       // Fill tables
665       QList<int> aTableIds;
666       switch( aType )
667       {
668         case 1:
669           if( isElno )
670             aTableIds.append( CellElno );
671           else
672           {
673             aTableIds.append( CellStdCell );
674             aTableIds.append( CellStdPoint );
675           }
676           break;
677         case 2:
678           aTableIds.append( isElno ? PointElno : PointStd );
679           break;
680       }
681
682       QListIterator<int> aTableIter( aTableIds );
683       while( aTableIter.hasNext() )
684       {
685         int aTableId = aTableIter.next();
686         if( !myTables.contains( aTableId ) )
687           continue;
688
689         QTableWidget* aTable = myTables[ aTableId ];
690         if( !aTable )
691           continue;
692
693         int aRow = -1;
694         switch( aTableId )
695         {
696           case CellStdPoint:
697           {
698             int aRowCount = aGlobalPointDataMap.size();
699             aTable->setRowCount( aRowCount );
700
701             TPointDataMap::const_iterator aPointIter = aGlobalPointDataMap.begin();
702             for( ; aPointIter != aGlobalPointDataMap.end(); aPointIter++ )
703             {
704               aRow++;
705               TPointID aPointID = aPointIter.key();
706               const TPointData& aPointData = aPointIter.value();
707               const TValueData& aValueData = aPointData.ValueData;
708
709               setData( aTableId, aRow, Point, aPointID );
710               setData( aTableId, aRow, X, aPointData.X );
711               setData( aTableId, aRow, Y, aPointData.Y );
712               setData( aTableId, aRow, Z, aPointData.Z );
713               setData( aTableId, aRow, I, aPointData.I );
714               setData( aTableId, aRow, J, aPointData.J );
715               setData( aTableId, aRow, K, aPointData.K );
716               setData( aTableId, aRow, Scalar, aValueData.Scalar );
717               setData( aTableId, aRow, Vector, aValueData.Vector );
718             }
719             break;
720           }
721           case CellStdCell:
722           case CellElno:
723           {
724             int aRowCount = 0;
725             TCellToPointDataMap::const_iterator aCellToPointIter = aCellToPointDataMap.begin();
726             for( ; aCellToPointIter != aCellToPointDataMap.end(); aCellToPointIter++ )
727             {
728               if( aTableId == CellStdCell )
729                 aRowCount++;
730               else if( aTableId == CellElno )
731               {
732                 const TCellToPointData& aCellToPointData = aCellToPointIter.value();
733                 const TPointDataMap& aPointDataMap = aCellToPointData.PointDataMap;
734                 int aNbPoints = aPointDataMap.size();
735
736                 aRowCount += aNbPoints;
737               }
738             }
739             aTable->setRowCount( aRowCount );
740
741             aCellToPointIter = aCellToPointDataMap.begin();
742             for( ; aCellToPointIter != aCellToPointDataMap.end(); aCellToPointIter++ )
743             {
744               aRow++;
745
746               TCellID aCellID = aCellToPointIter.key();
747               const TCellToPointData& aCellToPointData = aCellToPointIter.value();
748               const TValueData& aCellData = aCellToPointData.CellData;
749
750               setData( aTableId, aRow, Cell, aCellID );
751               if( aTableId == CellStdCell )
752               {
753                 setData( aTableId, aRow, Scalar, aCellData.Scalar );
754                 setData( aTableId, aRow, Vector, aCellData.Vector );
755               }
756               else if( aTableId == CellElno )
757               {
758                 const TPointDataMap& aPointDataMap = aCellToPointData.PointDataMap;
759                 int aNbPoints = aPointDataMap.size();
760                 if( aNbPoints > 1 )
761                   setRowSpan( aTableId, aRow, Cell, aNbPoints );
762
763                 TPointDataMap::const_iterator aPointIter = aPointDataMap.begin();
764                 for( aRow--; aPointIter != aPointDataMap.end(); aPointIter++ )
765                 {
766                   aRow++;
767                   TPointID aPointID = aPointIter.key();
768                   const TPointData& aPointData = aPointIter.value();
769                   const TValueData& aValueData = aPointData.ValueData;
770
771                   setData( aTableId, aRow, Point, aPointID );
772                   setData( aTableId, aRow, X, aPointData.X );
773                   setData( aTableId, aRow, Y, aPointData.Y );
774                   setData( aTableId, aRow, Z, aPointData.Z );
775                   setData( aTableId, aRow, I, aPointData.I );
776                   setData( aTableId, aRow, J, aPointData.J );
777                   setData( aTableId, aRow, K, aPointData.K );
778                   setData( aTableId, aRow, Scalar, aValueData.Scalar );
779                   setData( aTableId, aRow, Vector, aValueData.Vector );
780                 }
781               }
782             }
783             break;
784           }
785           case PointStd:
786           case PointElno:
787           {
788             int aRowCount = 0;
789             TPointToCellDataMap::const_iterator aPointToCellIter = aPointToCellDataMap.begin();
790             for( ; aPointToCellIter != aPointToCellDataMap.end(); aPointToCellIter++ )
791             {
792               const TPointToCellData& aPointToCellData = aPointToCellIter.value();
793               const TCellDataMap& aCellDataMap = aPointToCellData.CellDataMap;
794               int aNbCells = aCellDataMap.size();
795               if( aNbCells > 1 )
796                 aRowCount += aNbCells;
797               else
798                 aRowCount++;          
799             }
800             aTable->setRowCount( aRowCount );
801
802             aPointToCellIter = aPointToCellDataMap.begin();
803             for( ; aPointToCellIter != aPointToCellDataMap.end(); aPointToCellIter++ )
804             {
805               aRow++;
806
807               TPointID aPointID = aPointToCellIter.key();
808               const TPointToCellData& aPointToCellData = aPointToCellIter.value();
809               const TPointData& aPointData = aPointToCellData.PointData;
810
811               setData( aTableId, aRow, Point, aPointID );
812               setData( aTableId, aRow, X, aPointData.X );
813               setData( aTableId, aRow, Y, aPointData.Y );
814               setData( aTableId, aRow, Z, aPointData.Z );
815               setData( aTableId, aRow, I, aPointData.I );
816               setData( aTableId, aRow, J, aPointData.J );
817               setData( aTableId, aRow, K, aPointData.K );
818
819               if( aTableId == PointElno )
820               {
821                 const TCellDataMap& aCellDataMap = aPointToCellData.CellDataMap;
822                 int aNbCells = aCellDataMap.size();
823                 if( aNbCells > 1 )
824                   for( int aColumnId = Point; aColumnId <= K; aColumnId++ )
825                     setRowSpan( aTableId, aRow, aColumnId, aNbCells );
826
827                 TCellDataMap::const_iterator aCellIter = aCellDataMap.begin();
828                 for( aRow--; aCellIter != aCellDataMap.end(); aCellIter++ )
829                 {
830                   aRow++;
831                   TCellID aCellID = aCellIter.key();
832                   const TValueData& aCellData = aCellIter.value();
833
834                   setData( aTableId, aRow, Cell, aCellID );
835                   setData( aTableId, aRow, Scalar, aCellData.Scalar );
836                   setData( aTableId, aRow, Vector, aCellData.Vector );
837                 }
838               }
839               else
840               {
841                 const TValueData& aValueData = aPointData.ValueData;
842                 setData( aTableId, aRow, Scalar, aValueData.Scalar );
843                 setData( aTableId, aRow, Vector, aValueData.Vector );
844               }
845             }
846             break;
847           }
848         }
849
850         for( int aCol = column( aTableId, I ), aLastCol = column( aTableId, K ); aCol <= aLastCol; aCol++ )
851           if( aCol != -1 )
852             aTable->setColumnHidden( aCol, !isStructured );
853         aTable->resizeColumnsToContents();
854       }
855
856       int stackId = isElno ? ElnoMesh : StdMesh;
857       QStackedWidget* aStackedWg = aType == 1 ? myCellStackedWg : aType == 2 ? myPointStackedWg : 0;
858       if( aStackedWg )
859         aStackedWg->setCurrentIndex( stackId );
860     }
861   }
862   myFl = false;
863 }
864
865 void VisuGUI_SelectionPanel::clearFields() {
866   int aType = myTabWidget->currentIndex();
867   switch (aType) {
868   case 0:
869     myXPosLbl->setText("");
870     myYPosLbl->setText("");
871     myZPosLbl->setText("");
872     myDXLbl->setText("");
873     myDYLbl->setText("");
874     myDZLbl->setText("");
875     break;
876   case 1:
877     myCellIDValLbl->setText( "" );
878     break;
879   case 2:
880     myIDValLbl->setText( "" );
881     break;
882   }
883
884   QMap<int, QTableWidget*>::iterator it = myTables.begin(), itEnd = myTables.end();
885   for( ; it != itEnd; ++it )
886     if( QTableWidget* aTable = *it )
887     {
888       aTable->clearSpans();
889       aTable->setRowCount(0);
890       aTable->resizeColumnsToContents();
891     }
892 }
893
894 typedef  vtkIdType (VISU_PipeLine::* TGetVTKIdMethod)(vtkIdType theID);
895
896 bool onIdEdit (const QString& theText,
897                TGetVTKIdMethod theMethod,
898                bool theIsCell,
899                const SalomeApp_Module* theModule,
900                QLabel* theMeshName,
901                QString theValue,
902                QLabel* theFieldName)
903 {
904   SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(theModule);
905   if (!aViewWindow) 
906     return false;
907   SVTK_Selector* aSelector = aViewWindow->GetSelector();
908
909   _PTR(SObject) aSObject;
910   VISU::Prs3d_i* aPrs3d = NULL;
911   Handle(SALOME_InteractiveObject) anIO;
912
913   VISU::TSelectionInfo aSelectionInfo = VISU::GetSelectedObjects(theModule);
914   if(aSelectionInfo.size() == 1){
915     // Get selected SObject
916     VISU::TSelectionItem aSelectionItem = aSelectionInfo.front();
917     VISU::TObjectInfo anObjectInfo = aSelectionItem.myObjectInfo;
918     aPrs3d = GetPrs3dFromBase(anObjectInfo.myBase);
919     if(aPrs3d){
920       anIO = aSelectionItem.myIO;
921       aSObject = anObjectInfo.mySObject;
922     }
923   }
924   if (aPrs3d) {
925     bool ok = false;
926     int anObjId = theText.toInt( &ok );
927     if( !ok )
928       anObjId = -1;
929
930     VISU_PipeLine* aPipeLine = aPrs3d->GetPipeLine();
931
932     if( dynamic_cast<VISU_GaussPointsPL*>( aPipeLine ) )
933       return false;
934
935     if( anObjId < 0 )
936       aSelector->ClearIndex();
937     else
938     {
939       int aVTKId = (aPipeLine->*theMethod)(anObjId);
940       if(aVTKId < 0)
941         return false;
942
943       TColStd_MapOfInteger newIndices;
944       newIndices.Add(anObjId);
945       aSelector->AddOrRemoveIndex(anIO, newIndices, false);
946     }
947
948     aViewWindow->highlight(anIO, true, true);
949
950     SVTK_RenderWindowInteractor* anInteractor = aViewWindow->GetInteractor();
951     VTK::ActorCollectionCopy aCopy(anInteractor->getRenderer()->GetActors());
952     VISU_Actor* anActor = SVTK::Find<VISU_Actor>(aCopy.GetActors(),
953                                                  SVTK::TIsSameIObject<VISU_Actor>( anIO ));
954     anActor->Highlight( anIO );
955
956     return true;
957
958   } else {
959     theMeshName->setText(theValue);
960     theFieldName->setText("");
961   }
962   return false;
963 }
964
965 void VisuGUI_SelectionPanel::onPointIdEdit ()
966 {
967   if (myFl) return;
968   TGetVTKIdMethod aMethod = &VISU_PipeLine::GetNodeVTKID;
969   bool anIsSelected = onIdEdit(myIDValLbl->text(),
970                                aMethod,
971                                false,
972                                myModule,
973                                myMeshName,
974                                tr("WRN_NO_AVAILABLE_DATA"),
975                                myFieldName);
976   if (anIsSelected)
977     // as selection manager doesn't send signal currentSelectionChanged()
978     onSelectionEvent();
979   else
980     clearFields();
981 }
982
983 void VisuGUI_SelectionPanel::onCellIdEdit ()
984 {
985   if (myFl) return;
986   TGetVTKIdMethod aMethod = &VISU_PipeLine::GetElemVTKID;
987   bool anIsSelected = onIdEdit(myCellIDValLbl->text(),
988                                aMethod,
989                                true,
990                                myModule,
991                                myMeshName,
992                                tr("WRN_NO_AVAILABLE_DATA"),
993                                myFieldName);
994   if (anIsSelected)
995     // as selection manager doesn't send signal currentSelectionChanged()
996     onSelectionEvent();
997   else
998     clearFields();
999 }
1000
1001 void VisuGUI_SelectionPanel::onDoubleClicked( const QModelIndex& theIndex )
1002 {
1003   QTableWidget* aTable = dynamic_cast<QTableWidget*>( sender() );
1004   if( !aTable )
1005     return;
1006
1007   int aTableId = myTables.key( aTable, -1 );
1008   if( aTableId == -1 )
1009     return;
1010
1011   int aRow = theIndex.row(), aCol = theIndex.column();
1012   const QList<int>& aColumnList = myColumnData[ aTableId ];
1013
1014   if( aCol >= aColumnList.size() )
1015     return;
1016
1017   int aColumnId = aColumnList[ aCol ];
1018
1019   bool anIsCellSelection = true;
1020   switch( aColumnId )
1021   {
1022     case Cell:
1023       anIsCellSelection = true;
1024       break;
1025     case Point:
1026     case X:
1027     case Y:
1028     case Z:
1029     case I:
1030     case J:
1031     case K:
1032       anIsCellSelection = false;
1033       break;
1034     case Scalar:
1035     case Vector:
1036       anIsCellSelection = aTableId == CellStdCell || aTableId == PointElno;
1037       break;
1038     default:
1039       return;
1040   }
1041
1042   int anIdColumnId = anIsCellSelection ? Cell : Point;
1043   QVariant anId = data( aTableId, aRow, anIdColumnId );
1044
1045   bool ok = false;
1046   anId.toInt( &ok );
1047   if( !ok )
1048     return;
1049
1050   if( anIsCellSelection )
1051   {
1052     setSelectionMode( 1 );
1053     myCellIDValLbl->setText( anId.toString() );
1054     onCellIdEdit();
1055   }
1056   else
1057   {
1058     setSelectionMode( 2 );
1059     myIDValLbl->setText( anId.toString() );
1060     onPointIdEdit();
1061   }
1062 }
1063
1064 void VisuGUI_SelectionPanel::onIdChanged( int theFirstId, int theSecondId )
1065 {
1066   int aType = myTabWidget->currentIndex();
1067   if( aType == 1 )
1068   {
1069     myCellIDValLbl->setText( theFirstId < 0 ? "" : QString::number( theFirstId ) );
1070     onCellIdEdit();
1071   }
1072   else if( aType == 2 )
1073   {
1074     myIDValLbl->setText( theFirstId < 0 ? "" : QString::number( theFirstId ) );
1075     onPointIdEdit();
1076   }
1077   else if( aType == 3 )
1078     myGaussPointsPane->setIds( theFirstId, theSecondId );
1079 }
1080
1081 void VisuGUI_SelectionPanel::onPreferences()
1082 {
1083   preferencesDlg()->exec();
1084 }
1085
1086 void VisuGUI_SelectionPanel::onApply()
1087 {
1088   VisuGUI_Panel::onApply();
1089 }
1090
1091 void VisuGUI_SelectionPanel::onClose()
1092 {
1093   //hide();
1094   VisuGUI_Panel::onClose();
1095 }
1096
1097 void VisuGUI_SelectionPanel::onHelp()
1098 {
1099   QString aHelpFileName = "selection_info_page.html";
1100   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
1101   if (app)
1102     app->onHelpContextModule(myModule ? app->moduleName(myModule->moduleName()) : QString(""), aHelpFileName);
1103   else {
1104     QString platform;
1105 #ifdef WIN32
1106     platform = "winapplication";
1107 #else
1108     platform = "application";
1109 #endif
1110     SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
1111                              QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
1112                              arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName) );
1113   }
1114
1115   VisuGUI_Panel::onHelp();
1116 }
1117
1118 void VisuGUI_SelectionPanel::keyPressEvent( QKeyEvent* e )
1119 {
1120   VisuGUI_Panel::keyPressEvent( e );
1121   if ( e->isAccepted() )
1122     return;
1123
1124   if ( e->key() == Qt::Key_F1 )
1125     {
1126       e->accept();
1127       onHelp();
1128     }
1129 }
1130
1131 void VisuGUI_SelectionPanel::onModuleActivated()
1132 {
1133   disconnect( myModule->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
1134               this,                               SLOT( onSelectionEvent() ) );
1135   connect( myModule->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
1136            this,                               SLOT( onSelectionEvent() ) );
1137   VisuGUI_Panel::onModuleActivated();
1138 }
1139
1140 void VisuGUI_SelectionPanel::onModuleDeactivated()
1141 {
1142   disconnect( myModule->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
1143               this,                               SLOT( onSelectionEvent() ) );
1144   VisuGUI_Panel::onModuleDeactivated();
1145 }