Salome HOME
Updated copyright comment
[modules/hexablock.git] / src / HEXABLOCKGUI / HEXABLOCKGUI_DocumentSelectionModel.cxx
1 // Copyright (C) 2009-2024  CEA, EDF
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, or (at your option) any later version.
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 #include <set>
21 #include <map>
22
23
24 #include "utilities.h"
25
26 #include <QtxWorkstack.h>
27 #include <STD_TabDesktop.h>
28 #include <STD_MDIDesktop.h>
29 #include <STD_SDIDesktop.h>
30
31 #include <SalomeApp_Tools.h>
32
33 #include "SOCC_ViewModel.h"
34 #include <OCCViewer_ViewManager.h>
35 #include <OCCViewer_ViewModel.h>
36 #include <OCCViewer_ViewWindow.h>
37
38 #include <SUIT_OverrideCursor.h>
39 #include <SUIT_MessageBox.h>
40 #include <SUIT_Session.h>
41 #include <SUIT_Selector.h>
42 #include <SUIT_Desktop.h>
43 #include <SUIT_ViewManager.h>
44 #include <SVTK_View.h>
45
46 #include "HEXABLOCKGUI_VtkDocumentGraphicView.hxx"
47 #include "HEXABLOCKGUI_OccGraphicView.hxx"
48 #include "HEXABLOCKGUI_SalomeTools.hxx"
49 #include "HEXABLOCKGUI_DocumentSelectionModel.hxx"
50 #include "HEXABLOCKGUI_DocumentItem.hxx"
51 #include "HEXABLOCKGUI.hxx"
52
53
54 #include <SVTK_Selector.h>
55 #include <SVTK_ViewModel.h>
56
57
58 #include <SalomeApp_Study.h>
59 #include <SalomeApp_Application.h>
60 #include <SALOME_Actor.h>
61 #include <SALOME_ListIO.hxx>
62 #include <AIS_ListIteratorOfListOfInteractive.hxx>
63
64 #include <QMultiMap>
65
66 #include <OCCViewer_ViewModel.h>
67 #include <SVTK_ViewModel.h>
68 #include <SalomeApp_Study.h>
69 #include <SalomeApp_Application.h>
70 #include <LightApp_SelectionMgr.h>
71 #include <TopExp.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Iterator.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopTools_IndexedMapOfShape.hxx>
76 #include <TColStd_IndexedMapOfInteger.hxx>
77
78
79 //#define _DEVDEBUG_
80 using namespace std;
81 using namespace HEXABLOCK::GUI;
82
83
84 // //===========================================================================
85 //                              SelectionModel
86 // //===========================================================================
87
88 bool SelectionModel::infoMode = true;
89
90 SelectionModel::SelectionModel( QAbstractItemModel * model ):
91 QItemSelectionModel( model )
92 {
93
94 }
95
96 SelectionModel::~SelectionModel()
97 {
98   disconnect( HEXABLOCKGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( salomeSelectionChanged() ) );
99 }
100
101
102 QModelIndex SelectionModel::indexBy( int role, const QString& value )
103 {
104   QModelIndex eltIndex; // element (vertex, edge, quad) of model
105   const QAbstractItemModel* theModel = model();
106   if ( !theModel ) return eltIndex;
107   QModelIndexList theIndexes = theModel->match( theModel->index(0, 0),
108                                           role,
109                                           value,
110                                           1,
111                                           Qt::MatchRecursive | Qt::MatchContains );//Qt::MatchFixedString );
112   if ( theIndexes.count()>0 )
113     eltIndex = theIndexes[0] ;
114   return eltIndex;
115 }
116
117
118 QModelIndex SelectionModel::indexBy( int role, const QVariant& var )
119 {
120   QModelIndex eltIndex; // element (vertex, edge, quad) of model
121   const QAbstractItemModel* theModel = model();
122   if ( !theModel ) return eltIndex;
123   QModelIndexList theIndexes = theModel->match( theModel->index(0, 0),
124                                           role,
125                                           var,
126                                           1,
127                                           Qt::MatchRecursive /*| Qt::MatchContains*/ );//Qt::MatchFixedString );
128   if ( theIndexes.count()>0 )
129     eltIndex = theIndexes[0] ;
130   return eltIndex;
131 }
132
133 QModelIndex SelectionModel::indexOf( const QString& anEntry, int role )
134 {
135   QModelIndex eltIndex; // element (vertex, edge, quad) of model
136   const QAbstractItemModel* theModel = model();
137   if ( !theModel ) return eltIndex;
138
139   QModelIndexList theIndexes = theModel->match( theModel->index(0, 0),
140                                           role,
141                                           anEntry,
142                                           1,
143                                           Qt::MatchRecursive | Qt::MatchContains );//Qt::MatchFixedString );
144   if ( theIndexes.count()>0 )
145     eltIndex = theIndexes[0] ;
146   return eltIndex;
147 }
148
149
150 QModelIndexList SelectionModel::indexListOf( const QString& anEntry, int role )
151 {
152   QModelIndexList theIndexes; // element (vertex, edge, quad) of model
153   const QAbstractItemModel* theModel = model();
154   if ( !theModel ) return theIndexes;
155   theIndexes = theModel->match( theModel->index(0, 0),
156                                 role,
157                                 anEntry,
158                                 -1,
159                                 Qt::MatchRecursive | Qt::MatchContains );//Qt::MatchFixedString );
160   return theIndexes;
161 }
162
163 DocumentModel* SelectionModel::getDocModel() const
164 {
165     DocumentModel* docModel = NULL;
166     const QSortFilterProxyModel *pModel   = dynamic_cast<const QSortFilterProxyModel *>( model() );
167     if ( pModel != NULL)
168         docModel = dynamic_cast<DocumentModel*>( pModel->sourceModel() );
169
170     return docModel;
171 }
172
173 void SelectionModel::showEltInfo(QModelIndex& elt)
174 {
175     DocumentModel* docModel = getDocModel();
176     if (!elt.isValid() || docModel == NULL)
177         return;
178
179     HEXA_NS::Vertex* vertex  = docModel->getHexaPtr<HEXA_NS::Vertex*>(elt);
180     HEXA_NS::Edge*   edge    = docModel->getHexaPtr<HEXA_NS::Edge*>(elt);
181     HEXA_NS::Quad*   quad    = docModel->getHexaPtr<HEXA_NS::Quad*>(elt);
182     HEXA_NS::Hexa*   hexa    = docModel->getHexaPtr<HEXA_NS::Hexa*>(elt);
183     HEXA_NS::Vector* vector  = docModel->getHexaPtr<HEXA_NS::Vector*>(elt);
184     HEXA_NS::Group*  group   = docModel->getHexaPtr<HEXA_NS::Group*>(elt);
185     HEXA_NS::Law*    law     = docModel->getHexaPtr<HEXA_NS::Law*>(elt);
186     HEXA_NS::Propagation* propagation = docModel->getHexaPtr<HEXA_NS::Propagation*>(elt);
187
188     HEXABLOCKGUI*    hexagui = HEXABLOCKGUI::getInstance();
189     if (vertex != NULL)
190         hexagui->showVertexInfoDialog(vertex);
191     else if (edge != NULL)
192         hexagui->showEdgeInfoDialog(edge);
193     else if (quad != NULL)
194         hexagui->showQuadInfoDialog(quad);
195     else if (hexa != NULL)
196         hexagui->showHexaInfoDialog(hexa);
197     else if (vector != NULL)
198         hexagui->showVectorInfoDialog(vector);
199     else if (group != NULL)
200         hexagui->showGroupInfoDialog(group);
201     else if (law != NULL)
202         hexagui->showLawInfoDialog(law);
203     else if (propagation != NULL)
204         hexagui->showPropagationInfoDialog(propagation);
205 }
206
207 void SelectionModel::salomeSelectionChanged()
208 {
209     // clear highlights and selections in the trees
210     PatternDataSelectionModel* pdsm = HEXABLOCKGUI::currentDocGView->getPatternDataSelectionModel();
211 //    PatternBuilderSelectionModel* pbsm = HEXABLOCKGUI::currentDocGView->getPatternBuilderSelectionModel();
212     PatternGeomSelectionModel* pgsm = HEXABLOCKGUI::currentDocGView->getPatternGeomSelectionModel();
213     pdsm->clearSelection();
214 //    pbsm->clearSelection();
215     pgsm->clearSelection();
216     pdsm->unhighlightTreeItems();
217     pgsm->unhighlightTreeItems();
218
219     try {
220         SALOME_ListIO selectedObjects;
221         Handle(SALOME_InteractiveObject) anIObject;
222
223         switch (HEXABLOCKGUI::getActiveViewType())
224         {
225         case HEXABLOCKGUI::VTK:
226         {
227             HEXABLOCKGUI::currentDocGView->getSelected(selectedObjects);
228             if ( selectedObjects.IsEmpty() )
229                 return;
230             anIObject = selectedObjects.First();
231             vtkSelectionChanged( anIObject );
232             break;
233         }
234         case HEXABLOCKGUI::OCC:
235             HEXABLOCKGUI::currentOccGView->getSelected(selectedObjects);
236             if ( selectedObjects.IsEmpty() )
237                 return;
238             anIObject = selectedObjects.First();
239             geomSelectionChanged( anIObject );
240             break;
241         }
242     } catch ( ... ) {
243         MESSAGE("*  Unknown selection exception!");
244     }
245 }
246
247
248 QModelIndexList SelectionModel::getSelectionFromModel(const Handle(SALOME_InteractiveObject)& anIObject)
249 {
250    QModelIndexList selectedIndexes;
251
252    //verify if the IOBject is valid and from VTK selection
253    bool fromVTK  = ( strcmp("HEXABLOCK", anIObject->getComponentDataType()) == 0 );
254    if ( !fromVTK || !anIObject->hasEntry() || HEXABLOCKGUI::currentDocGView->getViewWindow() == NULL)
255       return selectedIndexes;
256
257    QString anIOEntry = anIObject->getEntry();
258    int anhexaElemsId;
259    QString aText = "";
260
261    //extract vtk selection from the model -----------
262    if ( GetNameOfSelectedElements( HEXABLOCKGUI::currentDocGView->getViewWindow(), anIObject, aText ) <= 0 )
263       return selectedIndexes;
264
265    Document_Actor* docActor = dynamic_cast<Document_Actor*>( findActorByEntry( HEXABLOCKGUI::currentDocGView->getViewWindow(),
266                                                                                        anIOEntry.toLatin1() ) );
267    if ( !docActor ) return selectedIndexes;
268    QStringList idList = aText.split(" ");
269    foreach( const QString& id, idList )
270    {
271       if (!id.isEmpty())
272          {
273             //find selection in the model
274             anhexaElemsId = docActor->hexaElemsId[ id.toInt() ];
275             anIOEntry = QString::number( anhexaElemsId );
276
277             selectedIndexes << indexOf( anIOEntry, HEXA_ENTRY_ROLE );
278          }
279    }
280    return selectedIndexes;
281 }
282
283 // //===========================================================================
284 //                              PatternDataSelectionModel
285 // //===========================================================================
286
287 PatternDataSelectionModel::PatternDataSelectionModel( QAbstractItemModel * model ):
288 SelectionModel( model )
289 {
290   connect( this, SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
291            this, SLOT( onCurrentChanged( const QModelIndex & , const QModelIndex & ) ), Qt::UniqueConnection );
292   connect( this, SIGNAL( selectionChanged( const QItemSelection & , const QItemSelection & ) ),
293            this, SLOT( onSelectionChanged( const QItemSelection & , const QItemSelection & ) ), Qt::UniqueConnection );
294
295 }
296
297 PatternDataSelectionModel::~PatternDataSelectionModel()
298 {
299   disconnect( this, SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
300           this, SLOT( onCurrentChanged( const QModelIndex & , const QModelIndex & ) ) );
301   disconnect( this, SIGNAL( selectionChanged( const QItemSelection & , const QItemSelection & ) ),
302           this, SLOT( onSelectionChanged( const QItemSelection & , const QItemSelection & ) ) );
303 }
304
305
306 void PatternDataSelectionModel::onCurrentChanged( const QModelIndex & current, const QModelIndex & previous )
307 {
308   //Setting the selection mode of the selected item from the treeview
309   HEXABLOCKGUI::currentDocGView->setSelectionMode( current );
310   HEXABLOCKGUI::currentOccGView->setSelectionMode( current );
311 }
312
313 void PatternDataSelectionModel::highlightTreeItems(QModelIndexList& indexes,
314                                                    Qt::GlobalColor bgColor,
315                                                    Qt::GlobalColor fgColor, bool only)
316 {
317     if (indexes.count() == 0)
318         return;
319
320     if (only)
321         unhighlightTreeItems();
322
323     // * highlight item
324     QAbstractItemModel* theModel = (QAbstractItemModel*) model();
325     foreach( const QModelIndex& anItemIndex, indexes )
326     {
327         if (anItemIndex.isValid())
328         {
329             theModel->setData(anItemIndex, QColor(fgColor), Qt::ForegroundRole);
330             theModel->setData(anItemIndex, QColor(bgColor), Qt::BackgroundRole);
331             currentHighlightedItems << anItemIndex;
332         }
333     }
334
335     // * scroll to the first highlighted item in the tree
336     HEXABLOCKGUI* module = HEXABLOCKGUI::getInstance();
337     if (module != NULL && indexes[0].isValid())
338         module->getPatternDataTreeView()->scrollTo(indexes[0]);
339 }
340
341 void PatternDataSelectionModel::unhighlightTreeItems(bool clearSelected)
342 {
343     if (clearSelected)
344         clearSelection();
345     if (currentHighlightedItems.count() == 0)
346         return;
347
348     QAbstractItemModel* theModel = (QAbstractItemModel*) model();
349     foreach( const QModelIndex& anItemIndex, currentHighlightedItems)
350     {
351         if (anItemIndex.isValid())
352         {
353             theModel->setData(anItemIndex, QColor(Qt::darkGreen), Qt::ForegroundRole);
354             theModel->setData(anItemIndex, QColor(Qt::white), Qt::BackgroundRole);
355         }
356     }
357     currentHighlightedItems.clear();
358 }
359
360 QModelIndexList PatternDataSelectionModel::getGeomAssociations(const QModelIndex& dataIndex)
361 {
362     QModelIndexList geomIndexList;
363     DocumentModel*               docModel = getDocModel();
364     PatternGeomSelectionModel*   pGSModel = HEXABLOCKGUI::currentDocGView->getPatternGeomSelectionModel();
365     if (docModel == NULL || pGSModel == NULL)
366         return geomIndexList;
367
368     const QSortFilterProxyModel *pModel   = dynamic_cast<const QSortFilterProxyModel *>( model() );
369     HEXA_NS::Vertex* vertex = docModel->getHexaPtr<HEXA_NS::Vertex*>(dataIndex);
370     HEXA_NS::Edge*   edge   = docModel->getHexaPtr<HEXA_NS::Edge*>(dataIndex);
371     HEXA_NS::Quad*   quad   = docModel->getHexaPtr<HEXA_NS::Quad*>(dataIndex);
372     QModelIndex index = pModel->mapToSource(dataIndex);
373
374     if (vertex != NULL)
375         geomIndexList << docModel->getVertexAssociation( index );
376     else if (edge != NULL)
377         geomIndexList = docModel->getEdgeAssociations( index );
378     else if ( quad != NULL)
379         geomIndexList = docModel->getQuadAssociations( index );
380
381     return geomIndexList;
382 }
383
384 void PatternDataSelectionModel::onSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected )
385 {
386     QModelIndexList indexes = selected.indexes();
387     int nbSelected = indexes.count();
388     if (nbSelected == 0)
389         return;
390
391     // ** unhighlight current highlighted items in the trees
392     PatternGeomSelectionModel* pgsm = HEXABLOCKGUI::currentDocGView->getPatternGeomSelectionModel();
393     if (pgsm == NULL)
394         return;
395     unhighlightTreeItems(false);
396
397     QModelIndexList associatedGeomIndexes = getGeomAssociations(indexes[0]); //Mono Selection
398     if (associatedGeomIndexes.count() == 0)
399         pgsm->unhighlightTreeItems();
400
401     // ** highlight association in geometry tree
402     pgsm->highlightTreeItems(associatedGeomIndexes);
403
404     // ** highlight association in the vtk view
405     HEXABLOCKGUI::currentDocGView->highlight(indexes);
406
407     // ** highlight association in the occ view
408     HEXABLOCKGUI::currentOccGView->highlight(indexes);
409
410     if (!infoMode || nbSelected > 1)
411         return;
412
413     // ** Show informations of the selected element
414     QModelIndex elt = indexes[0];
415     showEltInfo(elt);
416 }
417
418 void PatternDataSelectionModel::geomSelectionChanged( const Handle(SALOME_InteractiveObject)& anIObject )
419 {
420 //   if (HEXABLOCKGUI::assocInProgress) return;
421
422    PatternGeomSelectionModel*  pgsm = HEXABLOCKGUI::currentDocGView->getPatternGeomSelectionModel();
423    if (pgsm == NULL) return;
424
425    QModelIndex geomModelIndex = pgsm->getModelIndex(anIObject);
426    if (!geomModelIndex.isValid())
427        return;
428    pgsm->select( geomModelIndex, QItemSelectionModel::SelectCurrent );
429 }
430
431
432 void PatternDataSelectionModel::vtkSelectionChanged( const Handle(SALOME_InteractiveObject)& anIObject )
433 {
434     QModelIndexList selectedIndexes =  getSelectionFromModel(anIObject);
435     if (selectedIndexes.count() == 0)
436     {
437         clearSelection();
438         return;
439     }
440     QModelIndex anIOIndex = selectedIndexes[0]; //Monoselection
441
442     //Temporary Debug for hexa selection ------------------------------
443     if (HEXABLOCKGUI::currentDocGView->getSelectionMode() == HEXA_TREE)
444     {
445         DocumentModel* docModel = getDocModel();
446         if ( docModel != NULL && anIOIndex.isValid())
447         {
448             //get the selected quad
449             HEXA_NS::Quad* quad = docModel->getHexaPtr<HEXA_NS::Quad*>(anIOIndex);
450
451             if (quad != NULL)
452             {
453                 //get the hexa the quad belongs to
454                 HEXA_NS::Hexa* hexa = docModel->getQuadHexa(quad);
455                 if (hexa != NULL) //convert the hexa to a QModelIndex so we can select it in the model
456                     anIOIndex = indexBy( HEXA_DATA_ROLE, QVariant::fromValue(hexa));
457                 else
458                 {
459                     SUIT_MessageBox::critical( 0,
460                             tr("HexaBlock"),
461                             tr("The Hexahedron this quad belongs to has been deleted!"));
462                     return;
463                 }
464             }
465         }
466     }//end if HEXA_TREE-----------------------------------------------
467
468     //select the element in the model
469     select( anIOIndex, QItemSelectionModel::SelectCurrent );
470 }
471
472 // //===========================================================================
473 //                              PatternGeomSelectionModel
474 // //===========================================================================
475
476 PatternGeomSelectionModel::PatternGeomSelectionModel( QAbstractItemModel * model ):
477 SelectionModel( model )
478 {
479   connect( this, SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
480            this, SLOT( onCurrentChanged( const QModelIndex & , const QModelIndex & ) ) );
481   connect( this, SIGNAL( selectionChanged( const QItemSelection & , const QItemSelection & ) ),
482            this, SLOT( onSelectionChanged( const QItemSelection & , const QItemSelection & ) ), Qt::UniqueConnection );
483 }
484
485 PatternGeomSelectionModel::~PatternGeomSelectionModel()
486 {
487   disconnect( this, SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
488           this, SLOT( onCurrentChanged( const QModelIndex & , const QModelIndex & ) ) );
489   disconnect( this, SIGNAL( selectionChanged( const QItemSelection & , const QItemSelection & ) ),
490           this, SLOT( onSelectionChanged( const QItemSelection & , const QItemSelection & ) ) );
491 }
492
493 void PatternGeomSelectionModel::onCurrentChanged( const QModelIndex & current, const QModelIndex & previous )
494 {
495   //Setting the selection mode of the selected item from the treeview}
496   HEXABLOCKGUI::currentDocGView->setSelectionMode( current );
497   HEXABLOCKGUI::currentOccGView->setSelectionMode( current );
498 }
499
500 void PatternGeomSelectionModel::onSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected )
501 {
502     DocumentModel* docModel = NULL;
503     const QSortFilterProxyModel *pModel = dynamic_cast<const QSortFilterProxyModel *>( model() );
504     if ( pModel != NULL)
505         docModel = dynamic_cast<DocumentModel*>(pModel->sourceModel());
506
507     QModelIndexList indexes = selected.indexes();
508     if (indexes.count() == 0 || docModel == NULL)
509         return;
510
511     // ** unhighlight current highlighted items in the trees
512     PatternDataSelectionModel* pdsm = HEXABLOCKGUI::currentDocGView->getPatternDataSelectionModel();
513     if (pdsm == NULL)
514         return;
515     unhighlightTreeItems(false);
516
517     //find the corresponding element in the model
518     HEXA_NS::SubShape* eltSubShape = dynamic_cast<HEXA_NS::SubShape*>(docModel->getHexaPtr(indexes[0]));
519     if (eltSubShape == NULL) return;
520
521     HEXA_NS::NewShape* subShapeParent = eltSubShape->getParentShape();
522     if (subShapeParent == NULL) return;
523
524     QString parentShapeName = subShapeParent->getName();
525     QString subId = QString::number(eltSubShape->getIdent());
526     QString aGeomObjModelEntry = parentShapeName + "," + subId + ";";
527
528     QModelIndexList assocsIndexes = pdsm->indexListOf(aGeomObjModelEntry, HEXA_ASSOC_ENTRY_ROLE);
529     if (assocsIndexes.count() == 0)
530         pdsm->unhighlightTreeItems();
531
532     // ** highlight associations in the data tree
533     pdsm->highlightTreeItems(assocsIndexes);
534
535     // ** highlight associations in the vtk view
536     HEXABLOCKGUI::currentDocGView->highlight(assocsIndexes);
537
538     // ** highlight the selected element in the occ view
539     QMultiMap<QString, int>  entrySubIDs;
540     entrySubIDs.insert(parentShapeName, eltSubShape->getIdent());
541     HEXABLOCKGUI::currentOccGView->highlight(entrySubIDs);
542 }
543
544 QModelIndex PatternGeomSelectionModel::getModelIndex(const Handle(SALOME_InteractiveObject)& anIObject)
545 {
546     QModelIndex result;
547     DocumentModel               *docModel = NULL;
548     const QSortFilterProxyModel *pModel   = dynamic_cast<const QSortFilterProxyModel *>( model() );
549     if ( pModel != NULL)
550         docModel = dynamic_cast<DocumentModel*>( pModel->sourceModel());
551
552     if ( docModel == NULL || HEXABLOCKGUI::selectionMgr() == NULL ||
553             HEXABLOCKGUI::currentOccGView->getViewWindow() == NULL)
554         return result;
555
556     //extract associated elements in the model
557     TColStd_IndexedMapOfInteger anIndexes;
558     HEXABLOCKGUI::selectionMgr()->GetIndexes(anIObject, anIndexes);
559     if (anIndexes.Extent() == 0) return result;
560     QString aGeomObjStudyEntry = anIObject->getEntry();
561     QString aGeomObjModelEntry = docModel->getGeomObjName(aGeomObjStudyEntry) + "," + QString::number(anIndexes(1));
562
563     HEXA_NS::SubShape*    ssh =  docModel->getGeomPtr(aGeomObjModelEntry);
564     HEXA_NS::VertexShape* vSh =  dynamic_cast<HEXA_NS::VertexShape*>(ssh);
565     HEXA_NS::EdgeShape*   eSh =  dynamic_cast<HEXA_NS::EdgeShape*>(ssh);
566     HEXA_NS::FaceShape*   fSh =  dynamic_cast<HEXA_NS::FaceShape*>(ssh);
567
568     if (vSh != NULL)
569         result = indexBy( HEXA_DATA_ROLE, QVariant::fromValue(vSh));
570     else if (eSh != NULL)
571         result = indexBy( HEXA_DATA_ROLE, QVariant::fromValue(eSh));
572     else if (fSh != NULL)
573         result = indexBy( HEXA_DATA_ROLE, QVariant::fromValue(fSh));
574
575     return result;
576 }
577
578 void PatternGeomSelectionModel::highlightTreeItems(QModelIndexList& indexes,
579                                                    Qt::GlobalColor bgColor,
580                                                    Qt::GlobalColor fgColor, bool only)
581 {
582     if (indexes.count() == 0)
583         return;
584
585     if (only)
586         unhighlightTreeItems();
587
588     // * highlight items
589     QAbstractItemModel* theModel = (QAbstractItemModel*) model();
590     foreach( const QModelIndex& anItemIndex, indexes )
591     {
592         if (anItemIndex.isValid())
593         {
594             theModel->setData(anItemIndex, QColor(fgColor), Qt::ForegroundRole);
595             theModel->setData(anItemIndex, QColor(bgColor), Qt::BackgroundRole);
596             currentHighlightedItems << anItemIndex;
597         }
598     }
599
600     // * scroll to the first highlighted item in the tree
601     HEXABLOCKGUI* module = HEXABLOCKGUI::getInstance();
602     if (module != NULL && indexes[0].isValid())
603         module->getPatternGeomTreeView()->scrollTo(indexes[0]);
604 }
605
606 void PatternGeomSelectionModel::unhighlightTreeItems(bool clearSelected)
607 {
608     if (clearSelected)
609         clearSelection();
610     if (currentHighlightedItems.count() == 0)
611         return;
612     QAbstractItemModel* theModel = (QAbstractItemModel*) model();
613     foreach( const QModelIndex& anItemIndex, currentHighlightedItems)
614     {
615         if (anItemIndex.isValid())
616         {
617             theModel->setData(anItemIndex, QColor(Qt::darkGreen), Qt::ForegroundRole);
618             theModel->setData(anItemIndex, QColor(Qt::white), Qt::BackgroundRole);
619         }
620     }
621     currentHighlightedItems.clear();
622 }
623
624 // //===========================================================================
625 //                              GroupsSelectionModel
626 // //===========================================================================
627 GroupsSelectionModel::GroupsSelectionModel( QAbstractItemModel * model ):
628 SelectionModel( model )
629 {
630   connect( this, SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
631            this, SLOT( onCurrentChanged( const QModelIndex & , const QModelIndex & ) ), Qt::UniqueConnection );
632   connect( this, SIGNAL( selectionChanged( const QItemSelection & , const QItemSelection & ) ),
633            this, SLOT( onSelectionChanged( const QItemSelection & , const QItemSelection & ) ), Qt::UniqueConnection );
634 }
635
636 GroupsSelectionModel::~GroupsSelectionModel()
637 {
638   disconnect( this, SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
639           this, SLOT( onCurrentChanged( const QModelIndex & , const QModelIndex & ) ) );
640   disconnect( this, SIGNAL( selectionChanged( const QItemSelection & , const QItemSelection & ) ),
641           this, SLOT( onSelectionChanged( const QItemSelection & , const QItemSelection & ) ) );
642 }
643
644 void GroupsSelectionModel::onSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected )
645 {
646     QModelIndexList indexes = selected.indexes();
647     int nbSelected = indexes.count();
648     if (nbSelected == 0)
649         return;
650
651     // ** Highlight the group in the vtk view **/
652     try {
653         for( QModelIndexList::const_iterator i_index = indexes.begin(); i_index != indexes.end(); ++i_index ){
654             HEXABLOCKGUI::currentDocGView->highlightGroups( *i_index );
655         }
656     } catch ( ... ) {
657         MESSAGE("Unknown exception was cought !!!");
658     }
659
660     if (!infoMode || nbSelected > 1)
661         return;
662
663     // ** Show informations of the selected element **/
664     QModelIndex elt = indexes[0];
665     showEltInfo(elt);
666 }
667
668 // //===========================================================================
669 //                              MeshSelectionModel
670 // //===========================================================================
671 MeshSelectionModel::MeshSelectionModel( QAbstractItemModel * model ):
672         SelectionModel( model )
673 {
674     connect( this, SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
675             this, SLOT( onCurrentChanged( const QModelIndex & , const QModelIndex & ) ), Qt::UniqueConnection );
676     connect( this, SIGNAL( selectionChanged( const QItemSelection & , const QItemSelection & ) ),
677             this, SLOT( onSelectionChanged( const QItemSelection & , const QItemSelection & ) ), Qt::UniqueConnection );
678 }
679
680 MeshSelectionModel::~MeshSelectionModel()
681 {
682     disconnect( this, SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
683             this, SLOT( onCurrentChanged( const QModelIndex & , const QModelIndex & ) ) );
684     disconnect( this, SIGNAL( selectionChanged( const QItemSelection & , const QItemSelection & ) ),
685             this, SLOT( onSelectionChanged( const QItemSelection & , const QItemSelection & ) ) );
686 }
687
688
689 void MeshSelectionModel::onSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected )
690 {
691     QModelIndexList indexes = selected.indexes();
692     int nbSelected = indexes.count();
693     if (nbSelected == 0)
694         return;
695
696     try {
697         for( QModelIndexList::const_iterator i_index = indexes.begin(); i_index != indexes.end(); ++i_index ){
698             HEXABLOCKGUI::currentDocGView->highlightPropagation( *i_index );
699         }
700     } catch ( ... ) {
701         MESSAGE("Unknown exception was cought !!!");
702     }
703
704     if (!infoMode || nbSelected > 1)
705         return;
706
707     // ** Show informations of the selected element **/
708     QModelIndex elt = indexes[0];
709     showEltInfo(elt);
710 }
711