Salome HOME
e2c3cc38d58240d33892f3d981c0be19c7006e6d
[modules/geom.git] / src / GEOMGUI / GEOMGUI_AnnotationMgr.cxx
1 // Copyright (C) 2007-2021  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, 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 "GEOMGUI_AnnotationMgr.h"
21
22 #include <GEOMGUI_AnnotationAttrs.h>
23 #include <GEOM_Annotation.hxx>
24 #include <GEOM_Client.hxx>
25 #include <GEOM_Constants.h>
26 #include <GEOM_Displayer.h>
27 #include <GEOMGUI_TextTreeWdg.h>
28
29 #include <GeometryGUI.h>
30
31 #include <SalomeApp_Application.h>
32 #include <SalomeApp_Study.h>
33 #include <SALOME_Prs.h>
34
35 #include <SUIT_ResourceMgr.h>
36 #include <SUIT_Session.h>
37 #include <SUIT_Desktop.h>
38 #include <SUIT_ViewWindow.h>
39 #include <SUIT_ViewManager.h>
40
41 #include <SOCC_Prs.h>
42 #include <SOCC_ViewWindow.h>
43
44 #include <Quantity_Color.hxx>
45 #include <TCollection_AsciiString.hxx>
46
47 #include <TopExp.hxx>
48 #include <TopoDS_Shape.hxx>
49 #include <TopTools_IndexedMapOfShape.hxx>
50 #include <gp_Ax3.hxx>
51 #include <AIS_ListIteratorOfListOfInteractive.hxx>
52
53 #include <QFont>
54 #include <QColor>
55
56
57 GEOMGUI_AnnotationMgr::GEOMGUI_AnnotationMgr( SalomeApp_Application* theApplication )
58 : myApplication( theApplication )
59 {
60 }
61
62 QString GEOMGUI_AnnotationMgr::GetEntrySeparator()
63 {
64         return "_annotation:";
65 }
66
67 //================================================================
68 // Function : CreatePresentation
69 // Purpose  :
70 //================================================================
71 SALOME_Prs* GEOMGUI_AnnotationMgr::CreatePresentation( const GEOMGUI_AnnotationAttrs::Properties& theProperty,
72                                                        GEOM::GEOM_Object_ptr theObject,
73                                                        SOCC_Viewer* theView,
74                                                        const QString& theEntry )
75 {
76   SOCC_Viewer* aView = viewOrActiveView( theView );
77   if ( !aView ) {
78     return NULL;
79   }
80
81   Handle ( GEOM_Annotation ) aPresentation = new GEOM_Annotation();
82   if ( !theEntry.isEmpty() ) {
83     // owner should be set to provide selection mechanizm
84     Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
85     anIO->setEntry( theEntry.toUtf8().constData() );
86     aPresentation->SetOwner( anIO );
87   }
88
89   aPresentation->SetIsScreenFixed( theProperty.IsScreenFixed );
90
91   TopoDS_Shape aShape = GEOM_Client::get_client().GetShape( GeometryGUI::GetGeomGen(), theObject );
92   if ( !aShape.IsNull() ) {
93
94     gp_Ax3 aShapeLCS = gp_Ax3().Transformed( aShape.Location().Transformation() );
95
96     GEOMGUI_AnnotationAttrs::SetupPresentation( aPresentation, theProperty, aShapeLCS );
97
98     if ( theProperty.ShapeType == TopAbs_SHAPE ) {
99
100       aPresentation->SetHilightShape( aShape );
101     }
102     else if ( theProperty.ShapeIndex > 0 ) {
103
104       TopTools_IndexedMapOfShape aSubShapeMap;
105       TopExp::MapShapes( aShape, static_cast<TopAbs_ShapeEnum>( theProperty.ShapeType ), aSubShapeMap );
106       if ( theProperty.ShapeIndex <= aSubShapeMap.Extent() ) {
107
108         aPresentation->SetHilightShape( aSubShapeMap( theProperty.ShapeIndex ) );
109       }
110     }
111   }
112
113   setDisplayProperties( aPresentation, aView, getEntry( theObject ).c_str() );
114
115   // add Prs to preview
116   //SUIT_ViewWindow* vw = getApplication()->desktop()->activeWindow();
117   SOCC_Prs* aPrs =
118       dynamic_cast<SOCC_Prs*>( ( aView )->CreatePrs( 0 ) );
119
120   if ( aPrs )
121     aPrs->AddObject( aPresentation );
122
123   return aPrs;
124 }
125
126 bool GEOMGUI_AnnotationMgr::IsDisplayed( const QString& theEntry, const int theIndex, SOCC_Viewer* theView ) const
127 {
128   SOCC_Viewer* aView = viewOrActiveView( theView );
129   if ( !aView || !myVisualized.contains( aView ) )
130     return false;
131
132   EntryToAnnotations anEntryToAnnotation = myVisualized[aView];
133   if ( !anEntryToAnnotation.contains( theEntry ) )
134     return false;
135
136   AnnotationToPrs anAnnotationToPrs = anEntryToAnnotation[theEntry];
137   if ( !anAnnotationToPrs.contains( theIndex ) )
138     return false;
139
140   return true;
141 }
142
143 //=======================================================================
144 // function : GEOMGUI_AnnotationMgr::Display
145 // purpose  : Displays annotation shape presentation in view. It creates an annotation presentation
146 // and stores it in an internal container
147 //=======================================================================
148 void GEOMGUI_AnnotationMgr::Display( const QString& theEntry, const int theIndex, SOCC_Viewer* theView,
149                                      const bool isStoreViewState, const bool isUpdateViewer )
150 {
151   SOCC_Viewer* aView = viewOrActiveView( theView );
152   if ( !aView )
153     return;
154
155   if ( IsDisplayed( theEntry, theIndex, aView ) )
156     return;
157
158   GEOMGUI_AnnotationAttrs::Properties aProperty;
159   GEOM::GEOM_Object_ptr anObject;
160   getObject( theEntry, theIndex, anObject, aProperty );
161
162   // display presentation in the viewer
163   QString anEntry = QString("%1%2%3").arg(theEntry).arg(GetEntrySeparator()).arg(theIndex);
164   SALOME_Prs* aPrs = CreatePresentation( aProperty, anObject, aView, anEntry );
165   ((SALOME_View*)aView)->Display( getDisplayer(), aPrs );
166   if ( isUpdateViewer )
167     getDisplayer()->UpdateViewer();
168
169   EntryToAnnotations anEntryToMap;
170   if ( myVisualized.contains( aView ) )
171     anEntryToMap = myVisualized[aView];
172
173   // store displayed parameters to an internal container
174   AnnotationToPrs anAnnotationToPrsMap;
175   if ( anEntryToMap.contains( theEntry ) )
176     anAnnotationToPrsMap = anEntryToMap[theEntry];
177   anAnnotationToPrsMap[theIndex] = aPrs;
178   anEntryToMap[theEntry] = anAnnotationToPrsMap;
179   myVisualized[aView] = anEntryToMap;
180
181   if ( isStoreViewState ) {
182     // change persistent for the entry: set visible state in true for indices which presentations are shown
183     storeVisibleState( theEntry, theView );
184     storeFixedPosition( theEntry, theView );
185   }
186 }
187
188 void GEOMGUI_AnnotationMgr::Redisplay( const QString& theEntry, const int theIndex,
189                                        const GEOMGUI_AnnotationAttrs::Properties& theProperty )
190 {
191   SUIT_Session* ses = SUIT_Session::session();
192   SUIT_Application* app = ses->activeApplication();
193   if ( app )
194   {
195     SUIT_Desktop* desk = app->desktop();
196     QList<SUIT_ViewWindow*> wnds = desk->windows();
197     SUIT_ViewWindow* wnd;
198     QListIterator<SUIT_ViewWindow*> it( wnds );
199     while ( it.hasNext() && (wnd = it.next()) )
200     {
201       SUIT_ViewManager* vman = wnd->getViewManager();
202       if ( vman )
203       {
204         SUIT_ViewModel* vmodel = vman->getViewModel();
205         if ( vmodel )
206         {
207           SOCC_Viewer* aView = dynamic_cast<SOCC_Viewer*>(vmodel);
208           if ( aView )
209             Redisplay( theEntry, theIndex, theProperty, aView );
210         }
211       }
212     }
213   }
214 }
215
216 void GEOMGUI_AnnotationMgr::Redisplay( const QString& theEntry, const int theIndex,
217                                        const GEOMGUI_AnnotationAttrs::Properties& theProperty,
218                                        SOCC_Viewer* theView )
219 {
220   SOCC_Viewer* aView = viewOrActiveView( theView );
221   if ( !aView )
222     return;
223
224   if ( !myVisualized.contains( aView ) )
225     return;
226
227   EntryToAnnotations anEntryToAnnotation = myVisualized[aView];
228   if ( !anEntryToAnnotation.contains( theEntry ) )
229     return;
230
231   AnnotationToPrs anAnnotationToPrs = anEntryToAnnotation[theEntry];
232   if ( !anAnnotationToPrs.contains( theIndex ) )
233     return;
234
235   GEOMGUI_AnnotationAttrs::Properties aProperty;
236   GEOM::GEOM_Object_ptr anObject;
237   getObject( theEntry, theIndex, anObject, aProperty );
238   TopoDS_Shape aShape = GEOM_Client::get_client().GetShape( GeometryGUI::GetGeomGen(), anObject );
239   gp_Ax3 aShapeLCS = gp_Ax3().Transformed( aShape.Location().Transformation() );
240
241   // erase presentation from the viewer
242   SALOME_Prs* aPrs = anAnnotationToPrs[theIndex];
243   SOCC_Prs* anOCCPrs = dynamic_cast<SOCC_Prs*>( aPrs );
244   if ( anOCCPrs ) {
245     AIS_ListOfInteractive anIOs;
246     anOCCPrs->GetObjects( anIOs );
247     AIS_ListIteratorOfListOfInteractive anIter( anIOs );
248
249     for ( ; anIter.More(); anIter.Next() ) {
250       Handle(AIS_InteractiveObject) aPrs = anIter.Value();
251       Handle(GEOM_Annotation) aPresentation = Handle(GEOM_Annotation)::DownCast( aPrs );
252
253       GEOMGUI_AnnotationAttrs::SetupPresentation( aPresentation, theProperty, aShapeLCS );
254       aView->getAISContext()->Redisplay( aPresentation, Standard_True );
255     }
256   }
257 }
258
259 void GEOMGUI_AnnotationMgr::Erase( const QString& theEntry, const int theIndex, SOCC_Viewer* theView,
260                                    const bool isUpdateViewer )
261 {
262   SOCC_Viewer* aView = viewOrActiveView( theView );
263   if ( !aView )
264     return;
265
266   if ( !myVisualized.contains( aView ) )
267     return;
268
269   EntryToAnnotations anEntryToAnnotation = myVisualized[aView];
270   if ( !anEntryToAnnotation.contains( theEntry ) )
271     return;
272
273   AnnotationToPrs anAnnotationToPrs = anEntryToAnnotation[theEntry];
274   if ( !anAnnotationToPrs.contains( theIndex ) )
275     return;
276
277   // erase presentation from the viewer
278   SALOME_Prs* aPrs = anAnnotationToPrs[theIndex];
279   ((SALOME_View*)aView)->Erase( getDisplayer(), aPrs );
280   if ( isUpdateViewer )
281     getDisplayer()->UpdateViewer();
282
283   // remove displayed parameters from an internal container
284   anAnnotationToPrs.remove( theIndex );
285   anEntryToAnnotation[theEntry] = anAnnotationToPrs;
286   if (anAnnotationToPrs.isEmpty()) {
287     anEntryToAnnotation.remove( theEntry );
288   }
289   else {
290     anEntryToAnnotation[theEntry] = anAnnotationToPrs;
291   }
292   myVisualized[aView] = anEntryToAnnotation;
293
294   // change persistent for the entry: set visible state in true for indices which presentations are shown
295   storeVisibleState( theEntry, theView );
296 }
297
298 void GEOMGUI_AnnotationMgr::DisplayVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView,
299                                                        const bool isUpdateViewer )
300 {
301   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
302   _PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( theEntry.toStdString() );
303   const Handle(GEOMGUI_AnnotationAttrs) aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
304   if ( !aShapeAnnotations.IsNull() ) {
305     const int aCount = aShapeAnnotations->GetNbAnnotation();
306     std::vector<bool> isVisible( aCount );
307     for ( int anIndex = 0; anIndex < aCount; ++anIndex )
308     {
309       isVisible[anIndex] = aShapeAnnotations->GetIsVisible( anIndex );
310     }
311     for ( int anIndex = 0; anIndex < aCount; ++anIndex )
312     {
313       if ( isVisible[anIndex] )
314         Display( theEntry, anIndex, theView, true, isUpdateViewer );
315     }
316   }
317 }
318
319 void GEOMGUI_AnnotationMgr::EraseVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView,
320                                                      const bool isUpdateViewer )
321 {
322   SOCC_Viewer* aView = viewOrActiveView( theView );
323   if ( !myVisualized.contains( aView ) )
324     return;
325
326   EntryToAnnotations anEntryToAnnotation = myVisualized[aView];
327   if ( !anEntryToAnnotation.contains( theEntry ) )
328     return;
329   AnnotationToPrs anAnnotationToPrs = anEntryToAnnotation[theEntry];
330
331   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
332   _PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( theEntry.toStdString() );
333   const Handle(GEOMGUI_AnnotationAttrs) aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
334
335   const int aCount = aShapeAnnotations->GetNbAnnotation();
336   for ( int anIndex = 0; anIndex < aCount; ++anIndex )
337   {
338     if ( !anAnnotationToPrs.contains( anIndex ) )
339       continue;
340
341     // erase presentation from the viewer
342     SALOME_Prs* aPrs = anAnnotationToPrs[anIndex];
343     ((SALOME_View*)aView)->Erase( getDisplayer(), aPrs );
344   }
345   if ( isUpdateViewer )
346     getDisplayer()->UpdateViewer();
347   anEntryToAnnotation.remove( theEntry );
348   myVisualized[aView] = anEntryToAnnotation;
349 }
350
351 //=======================================================================
352 // function : GEOMGUI_AnnotationMgr::EraseRemovedAnnotation
353 // purpose  : Method to update internal maps after removing an
354 //  annotation from the object.
355 //=======================================================================
356 void GEOMGUI_AnnotationMgr::EraseRemovedAnnotation( const QString& theEntry, const int theIndex )
357 {
358   QMap<SOCC_Viewer*, EntryToAnnotations>::iterator aEntryMapIt = myVisualized.begin();
359   for ( ; aEntryMapIt != myVisualized.end(); ++aEntryMapIt ) {
360     SOCC_Viewer* aView = aEntryMapIt.key();
361     EntryToAnnotations& anEntryToAnnotation = aEntryMapIt.value();
362     if ( !anEntryToAnnotation.contains( theEntry ) )
363       continue;
364
365     AnnotationToPrs aUpdatedToPrs;
366     AnnotationToPrs& anAnnotationToPrs = anEntryToAnnotation[theEntry];
367     AnnotationToPrs::iterator anAnnotationIt = anAnnotationToPrs.begin();
368     for ( ; anAnnotationIt != anAnnotationToPrs.end(); ++anAnnotationIt ) {
369
370       const int aIndex = anAnnotationIt.key();
371       SALOME_Prs* aPrs = anAnnotationIt.value();
372       if ( aIndex > theIndex ) {
373         aUpdatedToPrs[aIndex - 1] = aPrs;
374       }
375       else if ( aIndex != theIndex ) {
376         aUpdatedToPrs[aIndex] = aPrs;
377       }
378       else {
379         ((SALOME_View*)aView)->Erase( getDisplayer(), aPrs );
380       }
381     }
382
383     anAnnotationToPrs = aUpdatedToPrs;
384   }
385   getDisplayer()->UpdateViewer();
386 }
387
388 //=======================================================================
389 // function : GEOMGUI_AnnotationMgr::UpdateVisibleAnnotations
390 // purpose  : 
391 //=======================================================================
392 void GEOMGUI_AnnotationMgr::UpdateVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView )
393 {
394   SOCC_Viewer* aView = viewOrActiveView( theView );
395   if ( !myVisualized.contains( aView ) )
396     return;
397
398   EntryToAnnotations& anEntryToAnnotation = myVisualized[aView];
399   if ( !anEntryToAnnotation.contains( theEntry ) )
400     return;
401
402   AnnotationToPrs& anAnnotationToPrs = anEntryToAnnotation[theEntry];
403   AnnotationToPrs::iterator anIt = anAnnotationToPrs.begin();
404   for (; anIt != anAnnotationToPrs.end(); ++anIt ) {
405     SOCC_Prs* aPrs =
406       dynamic_cast<SOCC_Prs*> (anIt.value());
407
408     GEOMGUI_AnnotationAttrs::Properties aProperty;
409     GEOM::GEOM_Object_ptr anObject;
410     getObject( theEntry, anIt.key(), anObject, aProperty );
411     TopoDS_Shape aShape = GEOM_Client::get_client().GetShape( GeometryGUI::GetGeomGen(), anObject );
412     gp_Ax3 aShapeLCS = gp_Ax3().Transformed( aShape.Location().Transformation() );
413
414     AIS_ListOfInteractive aIObjects;
415     aPrs->GetObjects( aIObjects );
416     AIS_ListOfInteractive::Iterator aIOIt( aIObjects );
417     for ( ; aIOIt.More(); aIOIt.Next() ) {
418
419       Handle(GEOM_Annotation) aPresentation =
420         Handle(GEOM_Annotation)::DownCast( aIOIt.Value() );
421
422       if ( aPresentation.IsNull() )
423         continue;
424
425       if ( !aShape.IsNull() ) {
426
427         GEOMGUI_AnnotationAttrs::SetupPresentation( aPresentation, aProperty, aShapeLCS );
428         if ( aProperty.ShapeType == TopAbs_SHAPE ) {
429           aPresentation->SetHilightShape( aShape );
430         }
431         else if ( aProperty.ShapeIndex > 0 ) {
432           TopTools_IndexedMapOfShape aSubShapeMap;
433           TopExp::MapShapes( aShape, static_cast<TopAbs_ShapeEnum>( aProperty.ShapeType ), aSubShapeMap );
434           if ( aProperty.ShapeIndex <= aSubShapeMap.Extent() ) {
435             aPresentation->SetHilightShape( aSubShapeMap( aProperty.ShapeIndex ) );
436           }
437         }
438       }
439
440       setDisplayProperties( aPresentation, aView, theEntry );
441
442       aView->getAISContext()->Redisplay( aPresentation, Standard_True );
443     }
444   }
445   getDisplayer()->UpdateViewer();
446 }
447
448 void GEOMGUI_AnnotationMgr::DisplayAllAnnotations( SOCC_Viewer* theView )
449 {
450   SOCC_Viewer* aView = viewOrActiveView( theView );
451   if ( !myVisualized.contains( aView ) )
452     return;
453
454   GeometryGUI* aModule = dynamic_cast<GeometryGUI*>( getApplication()->activeModule() );
455   GEOMGUI_TextTreeWdg* aTextWidget = aModule->GetTextTreeWdg();
456   QList<QString> anEntries = aTextWidget->getAllEntries( GEOMGUI_TextTreeWdg::AnnotationShape );
457
458   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
459   for ( int i = 0, aCount = anEntries.size(); i < aCount; i++ ) {
460      QString anEntry = anEntries[i];
461
462     _PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( anEntry.toStdString() );
463     if ( !aSObj )
464       continue;
465
466     const Handle(GEOMGUI_AnnotationAttrs) aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
467     if ( aShapeAnnotations.IsNull() )
468       continue;
469
470     int anAnnotationsCount = aShapeAnnotations->GetNbAnnotation();
471     for ( int anIndex = 0; anIndex < anAnnotationsCount; ++anIndex )
472     {
473       Display( anEntry, anIndex, aView, false, false );
474     }
475     getDisplayer()->UpdateViewer();
476     storeVisibleState( anEntry, aView );
477     storeFixedPosition( anEntry, aView );
478   }
479 }
480
481 void GEOMGUI_AnnotationMgr::EraseAllAnnotations( SOCC_Viewer* theView )
482 {
483   SOCC_Viewer* aView = viewOrActiveView( theView );
484   if ( !myVisualized.contains( aView ) )
485     return;
486
487   GeometryGUI* aModule = dynamic_cast<GeometryGUI*>( getApplication()->activeModule() );
488   GEOMGUI_TextTreeWdg* aTextWidget = aModule->GetTextTreeWdg();
489   QList<QString> anEntries = aTextWidget->getAllEntries( GEOMGUI_TextTreeWdg::AnnotationShape );
490
491   for ( int i = 0, aCount = anEntries.size(); i < aCount; i++ ) {
492     QString anEntry = anEntries[i];
493     EraseVisibleAnnotations( anEntry, aView, false );
494     storeVisibleState( anEntry, aView );
495   }
496   getDisplayer()->UpdateViewer();
497 }
498
499 void GEOMGUI_AnnotationMgr::SetPreviewStyle( const QString& theEntry, const int theIndex, const bool theIsPreview )
500 {
501   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
502   const QColor aFontColor = aResMgr->colorValue( "Geometry", "shape_annotation_font_color", QColor( 255, 255, 255 ) );
503   const QColor aLineColor = aResMgr->colorValue( "Geometry", "shape_annotation_line_color", QColor( 255, 255, 255 ) );
504
505   const Quantity_Color aOcctFontColor( aFontColor.redF(), aFontColor.greenF(), aFontColor.blueF(), Quantity_TOC_RGB );
506   const Quantity_Color aOcctLineColor( aLineColor.redF(), aLineColor.greenF(), aLineColor.blueF(), Quantity_TOC_RGB );
507
508   QMap<SOCC_Viewer*, EntryToAnnotations>::Iterator aViewIt = myVisualized.begin();
509   for (; aViewIt != myVisualized.end(); ++aViewIt ) {
510
511     Handle(GEOM_Annotation) aPresentation = getAISPresentation ( theEntry, theIndex, aViewIt.key() );
512     if ( aPresentation.IsNull() ) {
513       continue;
514     }
515
516     if ( theIsPreview ) {
517       aPresentation->SetTextColor( Quantity_NOC_VIOLET );
518       aPresentation->SetLineColor( Quantity_NOC_VIOLET );
519       aPresentation->SetDepthCulling( Standard_False );
520     }
521     else {
522       aPresentation->SetTextColor( aOcctFontColor );
523       aPresentation->SetLineColor( aOcctLineColor );
524       aPresentation->SetDepthCulling( Standard_True );
525     }
526   }
527   getDisplayer()->UpdateViewer();
528 }
529
530 Handle(SALOME_InteractiveObject) GEOMGUI_AnnotationMgr::FindInteractiveObject( const QString& theEntry,
531                                                                                const int theIndex,
532                                                                                SOCC_Viewer* theView ) const
533 {
534   Handle(SALOME_InteractiveObject) anIO;
535
536   SOCC_Viewer* aView = viewOrActiveView( theView );
537   if ( !myVisualized.contains( aView ) )
538     return anIO;
539
540   EntryToAnnotations anEntryToAnnotation = myVisualized[aView];
541   if ( !anEntryToAnnotation.contains( theEntry ) )
542     return anIO;
543
544   AnnotationToPrs anAnnotationToPrs = anEntryToAnnotation[theEntry];
545   if ( !anAnnotationToPrs.contains(theIndex) )
546     return anIO;
547
548   SALOME_Prs* aPrs = anAnnotationToPrs[theIndex];
549   SOCC_Prs* anOCCPrs = dynamic_cast<SOCC_Prs*>( aPrs );
550   if ( !anOCCPrs )
551     return anIO;
552
553   AIS_ListOfInteractive anIOs;
554   anOCCPrs->GetObjects( anIOs );
555   AIS_ListIteratorOfListOfInteractive anIter( anIOs );
556   for ( ; anIter.More() && anIO.IsNull(); anIter.Next() ) {
557     Handle(AIS_InteractiveObject) aPrs = anIter.Value();
558     if ( aPrs->GetOwner() )
559       anIO = Handle(SALOME_InteractiveObject)::DownCast( aPrs->GetOwner() );
560   }
561   return anIO;
562 }
563
564 int GEOMGUI_AnnotationMgr::FindAnnotationIndex( Handle(SALOME_InteractiveObject) theIO,
565                                                 SOCC_Viewer* theView )
566 {
567   int anIndex = -1;
568
569   SOCC_Viewer* aView = viewOrActiveView( theView );
570   if ( !myVisualized.contains( aView ) )
571     return anIndex;
572
573   QString anEntry = theIO->getEntry();
574
575   EntryToAnnotations anEntryToAnnotation = myVisualized[aView];
576   if ( !anEntryToAnnotation.contains( anEntry ) )
577     return anIndex;
578
579   AnnotationToPrs anAnnotationToPrs = anEntryToAnnotation[anEntry];
580   //typedef QMap<int, SALOME_Prs*> AnnotationToPrs;
581   AnnotationToPrs::const_iterator anIt = anAnnotationToPrs.begin(),
582                                   aLast = anAnnotationToPrs.end();
583   for (; anIt != aLast && anIndex < 0; anIt++) {
584     SALOME_Prs* aPrs = anIt.value();
585     SOCC_Prs* anOCCPrs = dynamic_cast<SOCC_Prs*>( aPrs );
586     if ( !anOCCPrs )
587       continue;
588
589     AIS_ListOfInteractive anIOs;
590     anOCCPrs->GetObjects( anIOs );
591     AIS_ListIteratorOfListOfInteractive anIter( anIOs );
592     for ( ; anIter.More() && anIndex < 0; anIter.Next() ) {
593       Handle(AIS_InteractiveObject) aPrs = anIter.Value();
594       if ( aPrs->GetOwner() ) {
595         Handle(SALOME_InteractiveObject) aPrsOwner = Handle(SALOME_InteractiveObject)::DownCast(aPrs->GetOwner());
596         if ( aPrsOwner == theIO )
597           anIndex = anIt.key();
598       }
599     }
600   }
601
602   return anIndex;
603 }
604
605 //=======================================================================
606 // function : GEOMGUI_AnnotationMgr::RemoveView
607 // purpose  : 
608 //=======================================================================
609 void GEOMGUI_AnnotationMgr::RemoveView( SOCC_Viewer* theView )
610 {
611   if ( !theView && myVisualized.contains( theView ) )
612     myVisualized.remove( theView );
613 }
614
615 QString GEOMGUI_AnnotationMgr::getDisplayedIndicesInfo( const QString& theEntry, SOCC_Viewer* theView ) const
616 {
617   QString aDisplayedIndices;
618
619   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
620   _PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( theEntry.toStdString() );
621   if ( !aSObj )
622   {
623     return aDisplayedIndices;
624   }
625   const Handle(GEOMGUI_AnnotationAttrs) aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
626   if ( !aShapeAnnotations.IsNull() )
627   {
628     const int aCount = aShapeAnnotations->GetNbAnnotation();
629     QStringList anIndices;
630     for ( int anIndex = 0; anIndex < aCount; ++anIndex )
631     {
632       if (IsDisplayed( theEntry, anIndex, theView ) )
633         anIndices.append( QString::number(anIndex) );
634     }
635     aDisplayedIndices = anIndices.join(";");
636   }
637   return aDisplayedIndices;
638 }
639
640 void GEOMGUI_AnnotationMgr::setDisplayedIndicesInfo( const QString& theEntry, SOCC_Viewer* theView,
641                                                      const QString theIndicesInfo )
642 {
643   if ( theIndicesInfo.isEmpty() )
644     return;
645
646   QStringList anIndices = theIndicesInfo.split( ";" );
647   for ( int i = 0, aCount = anIndices.size(); i < aCount; i++ ) {
648     Display( theEntry, anIndices[i].toInt(), theView );
649   }
650 }
651
652 GEOM_Displayer* GEOMGUI_AnnotationMgr::getDisplayer() const
653 {
654   LightApp_Module* aModule = dynamic_cast<LightApp_Module*>( getApplication()->activeModule() );
655   return dynamic_cast<GEOM_Displayer*>( aModule->displayer() );
656 }
657
658 SOCC_Viewer* GEOMGUI_AnnotationMgr::viewOrActiveView( SOCC_Viewer* theView ) const
659 {
660   SOCC_Viewer* aView = theView;
661   if ( !aView ) {
662     SalomeApp_Application* anApp = getApplication();
663     SUIT_ViewWindow* anActiveWindow = anApp->desktop()->activeWindow();
664     if ( anActiveWindow ) {
665       aView = dynamic_cast<SOCC_Viewer*>( anActiveWindow->getViewManager()->getViewModel() );
666     }
667   }
668   return aView;
669 }
670
671 QString GEOMGUI_AnnotationMgr::makeAnnotationEntry( const QString& theEntry, const int theIndex )
672 {
673   return QString("%1%2%3").arg(theEntry).arg(GetEntrySeparator()).arg(theIndex);
674 }
675
676 bool GEOMGUI_AnnotationMgr::getIndexFromEntry( const QString& theEntry, QString& theObjEntry, int& theIndex )
677 {
678   QStringList aSplit = theEntry.split( GetEntrySeparator() );
679   if ( aSplit.size() < 2 )
680     return false;
681
682   bool isOk = true;
683   theObjEntry = aSplit.at( 0 );
684   theIndex = aSplit.at( 1 ).toInt( &isOk );
685   return isOk;
686 }
687
688 void GEOMGUI_AnnotationMgr::getObject( const QString& theEntry, const int theIndex,
689                                        GEOM::GEOM_Object_ptr& theObject,
690                                        GEOMGUI_AnnotationAttrs::Properties& theProperty )
691 {
692   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
693   _PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( theEntry.toStdString() );
694   const Handle(GEOMGUI_AnnotationAttrs) aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
695   if ( !aShapeAnnotations.IsNull() ) {
696     aShapeAnnotations->GetProperties( theIndex, theProperty );
697
698     theObject = GEOM::GEOM_Object::_narrow( GeometryGUI::ClientSObjectToObject(aSObj) );
699   }
700 }
701
702 void GEOMGUI_AnnotationMgr::storeFixedPosition( const QString& theEntry, SOCC_Viewer* theView )
703 {
704   SOCC_Viewer* aView = viewOrActiveView( theView );
705   if ( !aView || !myVisualized.contains( aView ) )
706     return;
707
708   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
709   _PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( theEntry.toStdString() );
710   const Handle(GEOMGUI_AnnotationAttrs) aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
711   if ( aShapeAnnotations.IsNull() )
712     return;
713
714
715   EntryToAnnotations anEntryToAnnotation = myVisualized[aView];
716   AnnotationToPrs anAnnotationToPrs;
717   if ( anEntryToAnnotation.contains( theEntry ) )
718     anAnnotationToPrs = anEntryToAnnotation[theEntry];
719
720   AnnotationToPrs::iterator anIt = anAnnotationToPrs.begin();
721   for (; anIt != anAnnotationToPrs.end(); ++anIt ) {
722     int anIndex = anIt.key();
723     bool isFixedAnnotation = aShapeAnnotations->GetIsScreenFixed( anIndex );
724     if ( !isFixedAnnotation )
725       continue;
726
727     SOCC_Prs* aPrs = dynamic_cast<SOCC_Prs*> (anIt.value());
728     Handle(GEOM_Annotation) anAnnotationPresentation;
729
730     AIS_ListOfInteractive aIObjects;
731     aPrs->GetObjects( aIObjects );
732     AIS_ListOfInteractive::Iterator aIOIt( aIObjects );
733     for ( ; aIOIt.More(); aIOIt.Next() ) {
734       anAnnotationPresentation = Handle(GEOM_Annotation)::DownCast( aIOIt.Value() );
735       if ( !anAnnotationPresentation.IsNull() )
736         break;
737     }
738     if ( !anAnnotationPresentation.IsNull() )
739       aShapeAnnotations->SetPosition( anIndex, anAnnotationPresentation->GetPosition() );
740   }
741 }
742
743 void GEOMGUI_AnnotationMgr::storeVisibleState( const QString& theEntry, SOCC_Viewer* theView )
744 {
745   SOCC_Viewer* aView = viewOrActiveView( theView );
746   if ( !aView || !myVisualized.contains( aView ) )
747     return;
748
749   EntryToAnnotations anEntryToAnnotation = myVisualized[aView];
750   AnnotationToPrs anAnnotationToPrs;
751   if ( anEntryToAnnotation.contains( theEntry ) )
752     anAnnotationToPrs = anEntryToAnnotation[theEntry];
753
754
755   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
756   _PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( theEntry.toStdString() );
757   const Handle(GEOMGUI_AnnotationAttrs) aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
758   if ( !aShapeAnnotations.IsNull() ) {
759     const int aCount = aShapeAnnotations->GetNbAnnotation();
760     for ( int anIndex = 0; anIndex < aCount; ++anIndex ) {
761       bool aVisible = anAnnotationToPrs.contains( anIndex );
762       aShapeAnnotations->SetIsVisible( anIndex, aVisible );
763     }
764   }
765 }
766
767 //=======================================================================
768 // function : GEOMGUI_AnnotationMgr::getEntry
769 // purpose  : 
770 //=======================================================================
771 std::string GEOMGUI_AnnotationMgr::getEntry( const GEOM::GEOM_Object_ptr theObject )
772 {
773   SUIT_Session* session = SUIT_Session::session();
774   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
775   if ( app )
776   {
777     CORBA::String_var IOR = app->orb()->object_to_string( theObject );
778     if ( strcmp(IOR.in(), "") != 0 )
779     {
780       SalomeApp_Study* study = ( SalomeApp_Study* )app->activeStudy();
781       _PTR(SObject) SO ( study->studyDS()->FindObjectIOR( std::string(IOR) ) );
782       if ( SO )
783         return SO->GetID();
784     }
785   }
786   return std::string();
787 }
788
789 //=======================================================================
790 // function : GEOMGUI_AnnotationMgr::getName
791 // purpose  : 
792 //=======================================================================
793 std::string GEOMGUI_AnnotationMgr::getName( const GEOM::GEOM_Object_ptr theObject )
794 {
795   SUIT_Session* session = SUIT_Session::session();
796   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( session->activeApplication() );
797   if ( app )
798   {
799     CORBA::String_var IOR = app->orb()->object_to_string( theObject );
800     if ( strcmp(IOR.in(), "") != 0 )
801     {
802       SalomeApp_Study* study = ( SalomeApp_Study* )app->activeStudy();
803       _PTR(SObject) aSObj ( study->studyDS()->FindObjectIOR( std::string(IOR) ) );
804
805       _PTR(GenericAttribute) anAttr;
806
807       if ( aSObj && aSObj->FindAttribute( anAttr, "AttributeName") )
808       {
809         _PTR(AttributeName) aNameAttr( anAttr );
810         return aNameAttr->Value();
811       }
812     }
813   }
814   return std::string();
815 }
816
817 //=======================================================================
818 // function : GEOMGUI_AnnotationMgr::setDisplayProperties
819 // purpose  : 
820 //=======================================================================
821 void GEOMGUI_AnnotationMgr::setDisplayProperties( const Handle(GEOM_Annotation)& thePrs,
822                                                   SOCC_Viewer* theView,
823                                                   const QString& theEntry )
824 {
825   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
826   const QFont  aFont      = aResMgr->fontValue( "Geometry", "shape_annotation_font", QFont( "Y14.5M-2009", 24 ) );
827   const QColor aFontColor = aResMgr->colorValue( "Geometry", "shape_annotation_font_color", QColor( 0, 0, 127 ) );
828   const QColor aLineColor = aResMgr->colorValue( "Geometry", "shape_annotation_line_color", QColor( 0, 0, 127 ) );
829   const double aLineWidth = aResMgr->doubleValue( "Geometry", "shape_annotation_line_width", 1.0 );
830   const int aLineStyle    = aResMgr->integerValue( "Geometry", "shape_annotation_line_style", 0 );
831   const bool isAutoHide   = aResMgr->booleanValue( "Geometry", "shape_annotation_autohide", false );
832
833   const Quantity_Color aOcctFontColor( aFontColor.redF(), aFontColor.greenF(), aFontColor.blueF(), Quantity_TOC_RGB );
834   const Quantity_Color aOcctLineColor( aLineColor.redF(), aLineColor.greenF(), aLineColor.blueF(), Quantity_TOC_RGB );
835   const Standard_Real aFontHeight = aFont.pixelSize() != -1 ? aFont.pixelSize() : aFont.pointSize();
836
837   thePrs->SetFont( TCollection_AsciiString( aFont.family().toLatin1().data() ) );
838   thePrs->SetTextHeight( aFontHeight );
839   thePrs->SetTextColor( Quantity_Color( aFontColor.redF(), aFontColor.greenF(), aFontColor.blueF(), Quantity_TOC_RGB ) );
840   thePrs->SetLineColor( Quantity_Color( aLineColor.redF(), aLineColor.greenF(), aLineColor.blueF(), Quantity_TOC_RGB ) );
841   thePrs->SetLineWidth( aLineWidth );
842   thePrs->SetLineStyle( static_cast<Aspect_TypeOfLine>( aLineStyle ) );
843   thePrs->SetAutoHide( isAutoHide ? Standard_True : Standard_False );
844   thePrs->SetDepthCulling( Standard_True );
845
846   SOCC_Viewer* aView = viewOrActiveView( theView );
847   if ( aView && !theEntry.isEmpty() ) {
848
849     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
850     int aMgrId = dynamic_cast< SUIT_ViewModel* >( aView )->getViewManager()->getGlobalId();
851     QVariant aVal = aStudy->getObjectProperty( aMgrId, theEntry, GEOM::propertyName( GEOM::TopLevel ), QVariant() );
852     bool isBringToFront = aVal.isValid() ? aVal.toBool() : false;
853     if( isBringToFront ) {
854       thePrs->SetZLayer( Graphic3d_ZLayerId_Topmost );
855     }
856     else {
857       thePrs->SetDefaultZLayer();
858     }
859   }
860   else {
861     thePrs->SetDefaultZLayer();
862   }
863 }
864
865 //=======================================================================
866 // function : GEOMGUI_AnnotationMgr::getAISPresentation
867 // purpose  : 
868 //=======================================================================
869 Handle(GEOM_Annotation) GEOMGUI_AnnotationMgr::getAISPresentation ( const QString& theEntry,
870                                                                     const int theIndex,
871                                                                     SOCC_Viewer* theView )
872 {
873   if ( !myVisualized.contains( theView ) ) {
874     return Handle(GEOM_Annotation)();
875   }
876
877   EntryToAnnotations& aEntryToAnnotation = myVisualized[theView];
878   if ( !aEntryToAnnotation.contains( theEntry ) ) {
879     return Handle(GEOM_Annotation)();
880   }
881
882   AnnotationToPrs& aAnnotationToPrs = aEntryToAnnotation[theEntry];
883   if ( !aAnnotationToPrs.contains( theIndex ) ) {
884     return Handle(GEOM_Annotation)();
885   }
886
887   SALOME_Prs* aPrs = aAnnotationToPrs[theIndex];
888
889   // set or unset preview style for the presentation
890   AIS_ListOfInteractive aIObjects;
891   ((SOCC_Prs*)aPrs)->GetObjects( aIObjects );
892   AIS_ListOfInteractive::Iterator aIOIt( aIObjects );
893   for ( ; aIOIt.More(); aIOIt.Next() ) {
894     return Handle(GEOM_Annotation)::DownCast( aIOIt.Value() );
895   }
896
897   return Handle(GEOM_Annotation)();
898 }