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