Salome HOME
PAL9828 - regression of Plot2d legend
[modules/visu.git] / src / VISUGUI / VisuGUI_Selection.cxx
1 //  VISU VISUGUI : GUI of VISU component
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 //  File   : VisuGUI_Selection.cxx
25 //  Author : Laurent CORNABE & Hubert ROLLAND
26 //  Module : VISU
27 //  $Header$
28
29 #include "VisuGUI_Selection.h"
30
31 #include "VisuGUI.h"
32 #include "VisuGUI_Tools.h"
33
34 #include "VISU_Actor.h"
35 #include "VISU_PrsObject_i.hh"
36 #include "VISU_Prs3d_i.hh"
37 #include "VISU_PipeLine.hxx"
38
39 #include "SalomeApp_Study.h"
40 #include "SalomeApp_Application.h"
41 #include "LightApp_SelectionMgr.h"
42 #include "LightApp_VTKSelector.h"
43
44 #include "SUIT_MessageBox.h"
45 #include "SUIT_ViewWindow.h"
46 #include "SUIT_Session.h"
47
48 #include "SALOME_ListIO.hxx"
49 #include "SALOME_ListIteratorOfListIO.hxx"
50
51 #include "SVTK_ViewWindow.h"
52 #include "SVTK_ViewModel.h"
53 #include "SVTK_Selector.h"
54
55 #include "utilities.h"
56
57 // OCCT Includes
58 #include <TColStd_IndexedMapOfInteger.hxx>
59 #include <TColStd_MapOfInteger.hxx>
60
61 // QT Includes
62 #include <qstring.h>
63 #include <qlabel.h>
64 #include <qspinbox.h>
65 #include <qlistbox.h>
66 #include <qlayout.h>
67 #include <qhbuttongroup.h>
68 #include <qradiobutton.h>
69 #include <qvalidator.h>
70 #include <qpushbutton.h>
71 #include <qwidgetstack.h>
72 #include <qvbox.h>
73 #include <qgroupbox.h>
74 #include <qlineedit.h>
75 #include <qvalidator.h>
76 #include <qtable.h>
77
78 // VTK Includes
79 #include <vtkDataSetMapper.h>
80 #include <vtkDataSet.h>
81 #include <vtkPointData.h>
82 #include <vtkCellData.h>
83 #include <vtkCell.h>
84
85 // STL Includes
86 #include <map>
87
88 using namespace std;
89
90 static VisuGUI_SelectionDlg* mySelectionDlg = NULL;
91
92 VisuGUI_SelectionDlg::VisuGUI_SelectionDlg (QWidget* parent)
93      : QDialog(parent, 0, false, WStyle_Customize | WStyle_NormalBorder |
94                WStyle_Title | WStyle_SysMenu | WDestructiveClose),
95        mySelectionMgr(NULL)
96 {
97   if (mySelectionDlg)
98     mySelectionDlg->close(true);
99
100   setCaption( "Data on elements" );
101   setSizeGripEnabled(TRUE);
102
103   QGridLayout* TopLayout = new QGridLayout (this);
104   TopLayout->setSpacing(6);
105   TopLayout->setMargin(11);
106   TopLayout->setRowStretch(0, 0);
107   TopLayout->setRowStretch(1, 0);
108   TopLayout->setRowStretch(2, 1);
109   TopLayout->setRowStretch(3, 0);
110
111   QHButtonGroup* aTypeBox = new QHButtonGroup ("Selection", this);
112
113   QRadioButton* aPointBtn =
114   new QRadioButton ("Point", aTypeBox);
115   new QRadioButton ("Cell" , aTypeBox);
116   new QRadioButton ("Actor", aTypeBox);
117   aPointBtn->setChecked(true);
118
119   connect(aTypeBox, SIGNAL(clicked(int)), this, SLOT(onSelectionChange(int)));
120
121   TopLayout->addWidget(aTypeBox, 0, 0);
122
123   QWidget* aNamePane = new QWidget (this);
124   QGridLayout* aNameLay = new QGridLayout (aNamePane);
125
126   QLabel* aMeshLbl = new QLabel ("Mesh name: ", aNamePane);
127   myMeshName = new QLabel (aNamePane);
128
129   QLabel* aFieldLbl = new QLabel ("Field name: ", aNamePane);
130   myFieldName = new QLabel (aNamePane);
131
132   aNameLay->addWidget(aMeshLbl, 0, 0);
133   aNameLay->addWidget(myMeshName, 0, 1);
134   aNameLay->addWidget(aFieldLbl, 1, 0);
135   aNameLay->addWidget(myFieldName, 1, 1);
136
137   TopLayout->addWidget(aNamePane, 1, 0);
138
139   myWidgetStack = new QWidgetStack (this);
140
141   // Create Points pane
142   myPointsPane = new QVBox (myWidgetStack);
143   myPointsPane->layout()->setSpacing(6);
144
145   QGroupBox* aDataGrp = new QGroupBox (2, Qt::Horizontal, "Data of Point", myPointsPane);
146   aDataGrp->layout()->setSpacing(6);
147
148   new QLabel ("ID:", aDataGrp);
149   myIDValLbl = new QLineEdit ("", aDataGrp);
150   QIntValidator* aIntValidator = new QIntValidator (myIDValLbl);
151   aIntValidator->setBottom(0);
152   myIDValLbl->setValidator(aIntValidator);
153   connect(myIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onPointIdEdit(const QString&)));
154
155   new QLabel ("Scalar Value:", aDataGrp);
156   myScalarValLbl = new QLabel ("", aDataGrp);
157   new QLabel ("Vector Value:", aDataGrp);
158   myVectorValLbl = new QLabel ("", aDataGrp);
159   myVectorValLbl->setMinimumWidth(150);
160
161   QGroupBox* aCoordGrp = new QGroupBox (2, Qt::Horizontal, "Coordinates", myPointsPane);
162   aCoordGrp->layout()->setSpacing(6);
163   new QLabel ("X:", aCoordGrp);
164   myXValLbl = new QLabel ("", aCoordGrp);
165   new QLabel ("Y:", aCoordGrp);
166   myYValLbl = new QLabel ("", aCoordGrp);
167   new QLabel ("Z:",aCoordGrp );
168   myZValLbl = new QLabel ("", aCoordGrp);
169
170
171   myWidgetStack->addWidget(myPointsPane, 0);
172
173   // Create Cells pane
174   myCellsPane = new QWidget (myWidgetStack);
175   QGridLayout* aCellLayout = new QGridLayout (myCellsPane);
176   aCellLayout->setSpacing(6);
177   aCellLayout->setRowStretch(0, 0);
178   aCellLayout->setRowStretch(1, 1);
179
180   QGroupBox* aCellGrp = new QGroupBox(2, Qt::Horizontal, "Data of Cell", myCellsPane);
181
182   new QLabel ("ID:", aCellGrp);
183   myCellIDValLbl = new QLineEdit ("", aCellGrp);
184   myCellIDValLbl->setValidator(aIntValidator);
185   connect(myCellIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onCellIdEdit(const QString&)));
186
187   new QLabel ("Scalar Value:", aCellGrp);
188   myCellScalarValLbl = new QLabel ("", aCellGrp);
189   new QLabel ("Vector Value:", aCellGrp);
190   myCellVectorValLbl = new QLabel ("", aCellGrp);
191
192   aCellLayout->addWidget(aCellGrp, 0, 0);
193
194   myListPoints = new QTable (myCellsPane);
195   myListPoints->setReadOnly(true);
196   myListPoints->setNumCols(6);
197   myListPoints->setNumRows(0);
198   myListPoints->setColumnWidth(0, 40);
199   myListPoints->setColumnWidth(1, 40);
200   myListPoints->setColumnWidth(2, 40);
201   myListPoints->setColumnWidth(3, 40);
202   myListPoints->setSelectionMode(QTable::NoSelection);
203   QHeader* aHeader = myListPoints->horizontalHeader();
204   aHeader->setLabel( 0, "ID" );
205   aHeader->setLabel( 1, "X" );
206   aHeader->setLabel( 2, "Y" );
207   aHeader->setLabel( 3, "Z" );
208   aHeader->setLabel( 4, "Scalar" );
209   aHeader->setLabel( 5, "Vector" );
210
211   aCellLayout->addWidget(myListPoints, 1, 0);
212
213   myWidgetStack->addWidget(myCellsPane, 1);
214
215   // Actor Pane
216   myActorsPane = new QVBox (myWidgetStack);
217   myActorsPane->layout()->setSpacing(6);
218
219   QGroupBox* aPosGrp = new QGroupBox (2, Qt::Horizontal, "Position", myActorsPane);
220   aPosGrp->layout()->setSpacing(6);
221   new QLabel ("X:", aPosGrp);
222   myXPosLbl = new QLabel ("0", aPosGrp);
223   new QLabel ("Y:", aPosGrp);
224   myYPosLbl = new QLabel ("0", aPosGrp);
225   new QLabel ("Z:", aPosGrp);
226   myZPosLbl = new QLabel ("0", aPosGrp);
227
228   QGroupBox* aSizeGrp = new QGroupBox (2, Qt::Horizontal, "Size", myActorsPane);
229   aSizeGrp->layout()->setSpacing(6);
230   new QLabel ("dX:", aSizeGrp);
231   myDXLbl = new QLabel ("0", aSizeGrp);
232   new QLabel ("dY:", aSizeGrp);
233   myDYLbl = new QLabel ("0", aSizeGrp);
234   new QLabel ("dZ:",aSizeGrp );
235   myDZLbl = new QLabel ("0", aSizeGrp);
236
237   myWidgetStack->addWidget(myActorsPane, 2);
238
239
240   TopLayout->addWidget(myWidgetStack, 2, 0);
241
242   // Create buttons group
243   QHBox* aBtnBox = new QHBox (this);
244   QHBoxLayout* aBtnLayout = (QHBoxLayout*)aBtnBox->layout();
245   aBtnLayout->addStretch();
246
247   QPushButton* aCloseBtn = new QPushButton (tr("BUT_CLOSE"), aBtnBox);
248   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
249
250   TopLayout->addWidget(aBtnBox, 3, 0);
251
252   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
253     (SUIT_Session::session()->activeApplication());
254   mySelectionMgr = anApp->selectionMgr();
255   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionEvent()));
256
257   //connect(visuGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(close()));
258
259   myFl = false;
260
261   // Activate Points pane
262   SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
263   myWidgetStack->raiseWidget(myPointsPane);
264   if (aSVTKVW)
265     aSVTKVW->SetSelectionMode(NodeSelection);
266   onSelectionEvent();
267
268   mySelectionDlg = this;
269 }
270
271 VisuGUI_SelectionDlg::~VisuGUI_SelectionDlg()
272 {
273 }
274
275 void VisuGUI_SelectionDlg::onSelectionChange (int theId)
276 {
277   SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
278   if (!aSVTKVW) return;
279
280   switch (theId) {
281   case 0: // Points
282     myWidgetStack->raiseWidget(myPointsPane);
283     aSVTKVW->SetSelectionMode(NodeSelection);
284     onPointIdEdit(myIDValLbl->text());
285     break;
286   case 1: // Cells
287     myWidgetStack->raiseWidget(myCellsPane);
288     aSVTKVW->SetSelectionMode(CellSelection);
289     onCellIdEdit(myCellIDValLbl->text());
290     break;
291   case 2: // Actor
292     myWidgetStack->raiseWidget(myActorsPane);
293     aSVTKVW->SetSelectionMode(ActorSelection);
294     onSelectionEvent();
295   }
296 }
297
298
299 void VisuGUI_SelectionDlg::closeEvent (QCloseEvent* theEvent)
300 {
301   SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
302
303   mySelectionDlg = NULL;
304   if (aSVTKVW)
305     aSVTKVW->SetSelectionMode(ActorSelection);
306   disconnect(mySelectionMgr,0,0,0);
307   QDialog::closeEvent(theEvent);
308 }
309
310 template<class TData> QString getValue(TData* theData, int theId){
311   if (vtkDataArray *aScalar = theData->GetScalars()){
312     float aVal = aScalar->GetTuple1(theId);
313     return QString::number(aVal);
314   } else {
315     return QString("No data");
316   }
317 }
318
319 template<class TData> QString getVector(TData* theData, int theId){
320   if (vtkDataArray *aVector = theData->GetVectors()) {
321     float *aVal = aVector->GetTuple3(theId);
322     return QString("%1; %2; %3").arg(aVal[0]).arg(aVal[1]).arg(aVal[2]);
323   } else {
324     return QString("No data");
325   }
326 }
327
328 #define ABS(a) (a>=0)?a:-a
329
330 void VisuGUI_SelectionDlg::onSelectionEvent() {
331   SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
332   if (!aSVTKVW) return;
333
334   if (myFl) return;
335   myFl = true;
336
337   int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
338
339   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
340     (SUIT_Session::session()->activeApplication());
341
342   SVTK_Selector* aSelector = aSVTKVW->GetSelector();
343
344   VISU::Prs3d_i* aPrs3d = NULL;
345   _PTR(SObject) aSObject;
346   Handle(SALOME_InteractiveObject) anIO;
347
348   SALOME_ListIO aListIO;
349   mySelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
350
351   if (aListIO.Extent() == 1) {
352     anIO = aListIO.First();
353
354     if (anIO->hasEntry()) {
355       SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
356       _PTR(Study) aStudy = theStudy->studyDS();
357       aSObject = aStudy->FindObjectID(anIO->getEntry());
358
359       if (aSObject) {
360         CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
361
362         if (!CORBA::is_nil(anObject)) {
363           PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
364
365           if (aServant.in()) {
366             aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
367           }
368         }
369       }
370     }
371   }
372
373   if (aPrs3d) {
374     VISU::Storable::TRestoringMap aMap;
375     if (aSObject) {
376       _PTR(GenericAttribute) anAttr;
377       if (aSObject->FindAttribute(anAttr, "AttributeComment")) {
378         _PTR(AttributeComment) aComment (anAttr);
379         std::string aString = aComment->Value();
380         QString strIn( aString.c_str() );
381         VISU::Storable::StrToMap(strIn, aMap);
382       }
383     }
384
385     QString aMeshName("NULL"), aFieldName("NULL");
386     if (!aMap.empty()) {
387       aMeshName  = VISU::Storable::FindValue(aMap, "myMeshName");
388       aFieldName = VISU::Storable::FindValue(aMap, "myFieldName");
389     }
390
391     myMeshName ->setText((aMeshName  == "NULL") ? QString("No name") : aMeshName);
392     myFieldName->setText((aFieldName == "NULL") ? QString("No name") : aFieldName);
393
394     VISU_Actor* anVISUActor =
395       VISU::FindActor(aSVTKVW, aSObject->GetID().c_str());
396     if (anVISUActor) {
397       float aCoord[6];
398       anVISUActor->GetBounds(aCoord);
399       myXPosLbl->setText(QString::number( aCoord[0] ));
400       myYPosLbl->setText(QString::number( aCoord[2] ));
401       myZPosLbl->setText(QString::number( aCoord[4] ));
402
403       myDXLbl->setText(QString::number( ABS(aCoord[1]-aCoord[0]) ));
404       myDYLbl->setText(QString::number( ABS(aCoord[3]-aCoord[2]) ));
405       myDZLbl->setText(QString::number( ABS(aCoord[5]-aCoord[4]) ));
406
407       TColStd_IndexedMapOfInteger aMapIndex;
408       typedef map<int,float*> PointsMap;
409       PointsMap aPointsMap;
410
411       aSelector->GetIndex(anIO, aMapIndex);
412
413       vtkDataSet* aDataSet = anVISUActor->GetInput();
414       vtkPointData* aPntData = aDataSet->GetPointData();
415
416       for (int ind = 1; ind <= aMapIndex.Extent(); ind++) {
417         int aID = aMapIndex(ind);
418
419         switch (aType) {
420         case 0:
421           {
422             float aCoord[3];
423             aDataSet->GetPoint(aID, aCoord);
424             myXValLbl->setText( QString::number( aCoord[0] ) );
425             myYValLbl->setText( QString::number( aCoord[1] ) );
426             myZValLbl->setText( QString::number( aCoord[2] ) );
427             myIDValLbl->setText( QString::number(aID) );
428             myScalarValLbl->setText(getValue(aPntData, aID));
429             myVectorValLbl->setText(getVector(aPntData, aID));
430           }
431           break;
432         case 1:
433           {
434             vtkCellData* aData = aDataSet->GetCellData();
435             vtkCell* aCell = aDataSet->GetCell(aID);
436             if (aCell != NULL) {
437               int aNbOfPoints = aCell->GetNumberOfPoints();
438               if (aNbOfPoints <=1 ) { // Cell is point
439                 clearFields();
440               } else {
441                 myCellIDValLbl->setText( QString::number(aID) );
442                 myCellScalarValLbl->setText(getValue(aData, aID));
443                 myCellVectorValLbl->setText(getVector(aData, aID));
444
445                 float* aCoord;
446                 vtkIdList *aPointList = aCell->GetPointIds();
447
448                 for (int i = 0; i < aNbOfPoints; i++) {
449                   int idCurrent = aPointList->GetId(i);
450                   aCoord = aDataSet->GetPoint(idCurrent);
451                   aPointsMap.insert(PointsMap::value_type(idCurrent,aCoord));
452                 }
453               }
454             }
455           }
456           break;
457         }
458       }
459
460       myListPoints->setNumRows(aPointsMap.size());
461       PointsMap::const_iterator It = aPointsMap.begin();
462       for (int i = 0; It != aPointsMap.end() && i < myListPoints->numRows(); It++, i++) {
463         myListPoints->verticalHeader()->setLabel(i, QString::number( i ));
464         int id = It->first;
465         myListPoints->setText(i, 0, QString::number( id ));
466         float* aCoord = It->second;
467         myListPoints->setText(i, 1, QString::number( aCoord[0] ));
468         myListPoints->setText(i, 2, QString::number( aCoord[1] ));
469         myListPoints->setText(i, 3, QString::number( aCoord[2] ));
470         myListPoints->setText(i, 4, getValue(aPntData, id));
471         myListPoints->setText(i, 5, getVector(aPntData, id));
472       }
473     }
474   } else {
475     clearFields();
476   }
477   myFl = false;
478 }
479 #undef ABS
480
481
482 void VisuGUI_SelectionDlg::clearFields() {
483   int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
484   switch (aType) {
485   case 0:
486     myXValLbl->setText( "" );
487     myYValLbl->setText( "" );
488     myZValLbl->setText( "" );
489     myIDValLbl->setText( "" );
490     myScalarValLbl->setText("");
491     myVectorValLbl->setText("");
492     break;
493   case 1:
494     myCellIDValLbl->setText( "" );
495     myCellScalarValLbl->setText("");
496     myCellVectorValLbl->setText("");
497     myListPoints->setNumRows(0);
498     break;
499   case 2:
500     myXPosLbl->setText("");
501     myYPosLbl->setText("");
502     myZPosLbl->setText("");
503     myDXLbl->setText("");
504     myDYLbl->setText("");
505     myDZLbl->setText("");
506   }
507 }
508
509 typedef  vtkIdType (vtkDataSet::* TDataSetMethod)();
510
511 bool onIdEdit (const QString& theText,
512                TDataSetMethod theMethod,
513                bool theIsCell,
514                LightApp_SelectionMgr* theSelectionMgr,
515                QLabel* theMeshName,
516                QString theValue,
517                QLabel* theFieldName)
518 {
519   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
520     (SUIT_Session::session()->activeApplication());
521   SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
522   if (!aSVTKVW) return false;
523   SVTK_Selector* aSelector = aSVTKVW->GetSelector();
524
525   VISU::Prs3d_i* aPrs3d = NULL;
526   Handle(SALOME_InteractiveObject) anIO;
527
528   SALOME_ListIO aListIO;
529   theSelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
530
531   if (aListIO.Extent() == 1) {
532     anIO = aListIO.First();
533
534     if (anIO->hasEntry()) {
535       SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
536       _PTR(Study) aStudy = theStudy->studyDS();
537       _PTR(SObject) aSObject = aStudy->FindObjectID(anIO->getEntry());
538
539       if (aSObject) {
540         CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
541
542         if (!CORBA::is_nil(anObject)) {
543           PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
544
545           if (aServant.in()) {
546             aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
547           }
548         }
549       }
550     }
551   }
552
553   if (aPrs3d) {
554     int anId = theText.toInt();
555     vtkDataSet* aDataSet = aPrs3d->GetPL()->GetMapper()->GetInput();
556     int aMaxId = (aDataSet->*theMethod)();
557     if (anId < 0) anId = 0;
558     if (anId >= aMaxId) anId = aMaxId - 1;
559
560     TColStd_MapOfInteger newIndices;
561     newIndices.Add(anId);
562     aSelector->AddOrRemoveIndex(anIO, newIndices, false);
563     aSVTKVW->highlight(anIO, true, true);
564
565     return true;
566
567   } else {
568     theMeshName->setText(theValue);
569     theFieldName->setText("");
570   }
571   return false;
572 }
573
574 void VisuGUI_SelectionDlg::onPointIdEdit (const QString& theText)
575 {
576   if (myFl) return;
577   TDataSetMethod aMethod = &vtkDataSet::GetNumberOfPoints;
578   bool anIsSelected = onIdEdit(theText,aMethod,false,mySelectionMgr,
579                                myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
580                                myFieldName);
581   if (anIsSelected)
582     // as selection manager doesn't send signal currentSelectionChanged()
583     onSelectionEvent();
584   else
585     clearFields();
586 }
587
588 void VisuGUI_SelectionDlg::onCellIdEdit (const QString& theText)
589 {
590   if (myFl) return;
591   TDataSetMethod aMethod = &vtkDataSet::GetNumberOfCells;
592   bool anIsSelected = onIdEdit(theText,aMethod,true,mySelectionMgr,
593                                myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
594                                myFieldName);
595   if (anIsSelected)
596     // as selection manager doesn't send signal currentSelectionChanged()
597     onSelectionEvent();
598   else
599     clearFields();
600 }