Salome HOME
ca31bf138f747e6d37c9bfbfe119d2baad2c8430
[modules/gui.git] / src / SPlot2d / SPlot2d_ViewModel.cxx
1 // Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : SPlot2d_Viewer.cxx
24 //  Author : Sergey RUIN
25 //  Module : SUIT
26 //
27 #include "SPlot2d_ViewModel.h"
28
29 #include "SPlot2d_ViewWindow.h"
30
31 #include "SPlot2d_Prs.h"
32 #include "SPlot2d_Histogram.h"
33 #include "SUIT_Session.h"
34 #include "SUIT_Application.h"
35 #include "SUIT_ViewManager.h"
36
37 #include "SALOME_ListIO.hxx"
38
39 #include <QApplication>
40 #include <QToolBar>
41 #include <QToolButton>
42 #include <QCursor>
43 #include <QColorDialog>
44
45 //#include <qwt_math>
46 #include <qwt_plot_canvas.h>
47 #include <qwt_plot_curve.h>
48 #include <stdlib.h>
49
50 /*!
51   Constructor
52 */
53 SPlot2d_Viewer::SPlot2d_Viewer(  bool theAutoDel )
54 : Plot2d_Viewer( theAutoDel ),
55   myDeselectAnalytical(true)
56 {
57 }
58
59 /*!
60   Destructor
61 */
62 SPlot2d_Viewer::~SPlot2d_Viewer()
63 {
64 }
65
66 /*!
67   Renames curve if it is found
68 */
69 void SPlot2d_Viewer::rename( const Handle(SALOME_InteractiveObject)& IObject,
70                              const QString& newName, Plot2d_ViewFrame* fr ) 
71 {
72   Plot2d_ViewFrame* aViewFrame = fr ? fr : getActiveViewFrame();
73   if( !aViewFrame )
74     return;
75
76   CurveDict aCurves = aViewFrame->getCurves();
77   CurveDict::Iterator it = aCurves.begin();
78   for( ; it != aCurves.end(); ++it )
79   {
80     SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>( it.value() );
81     if( aCurve && aCurve->hasIO() && aCurve->getIO()->isSame( IObject ) )
82     {
83       aCurve->setVerTitle( newName );
84       it.key()->setTitle( newName );
85     }
86
87     if( aCurve && aCurve->hasTableIO() && aCurve->getTableIO()->isSame( IObject ) )
88       aCurve->getTableIO()->setName( newName.toUtf8() );
89   }
90   aViewFrame->updateTitles();
91 }
92
93 /*!
94   Renames all copies of object in all view windows
95   \param IObj - object to be renamed
96   \param name - new name
97 */
98 void SPlot2d_Viewer::renameAll( const Handle(SALOME_InteractiveObject)& IObj, const QString& name )
99 {
100   SUIT_ViewManager* vm = getViewManager();
101   if ( vm )
102   {
103     const QVector<SUIT_ViewWindow*>& wnds = vm->getViews();
104
105     for ( int i = 0; i < wnds.size(); i++ )
106     {
107       Plot2d_ViewWindow* pwnd = dynamic_cast<Plot2d_ViewWindow*>( wnds.at( i ) );
108       rename( IObj, name, pwnd->getViewFrame() );
109     }
110   }
111 }
112
113 /*!
114   Returns true if interactive object is presented in the viewer
115 */
116 bool SPlot2d_Viewer::isInViewer( const Handle(SALOME_InteractiveObject)& IObject ) 
117 {
118   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
119   if(aViewFrame == NULL) return 0;
120
121   if( getCurveByIO( IObject ) != NULL )
122     return 1;
123   else{
124     if(!IObject.IsNull()){
125       CurveDict aCurves = aViewFrame->getCurves();
126       CurveDict::Iterator it = aCurves.begin();
127       for( ; it != aCurves.end(); ++it ) {
128         SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>( it.value() );
129         if(aCurve && aCurve->hasIO() && aCurve->getTableIO()->isSame(IObject))
130           return 1;
131       }
132     }
133   }
134   return 0;
135 }
136
137
138 /*!
139   Actually this method just re-displays curves which refers to the <IObject>
140 */
141 void SPlot2d_Viewer::Display( const Handle(SALOME_InteractiveObject)& IObject, bool update )
142 {
143   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
144   if(aViewFrame == NULL) return;
145
146   SPlot2d_Curve* curve = getCurveByIO( IObject );
147   if ( curve )
148     aViewFrame->updateCurve( curve, update );
149 }
150
151 /*!
152   Actually this method just erases all curves which don't refer to <IOBject> 
153   and re-displays curve which is of <IObject>
154 */
155 void SPlot2d_Viewer::DisplayOnly( const Handle(SALOME_InteractiveObject)& IObject )
156 {
157   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
158   if(aViewFrame == NULL) return;
159
160   Plot2d_Curve* curve = getCurveByIO( IObject );
161   CurveDict aCurves = aViewFrame->getCurves();
162   CurveDict::Iterator it = aCurves.begin();
163   for( ; it != aCurves.end(); ++it ) {
164     if(it.value() != curve)
165       aViewFrame->eraseCurve( curve );
166     else
167       aViewFrame->updateCurve( curve, false );
168   }
169
170   aViewFrame->Repaint();
171 }
172
173 /*!
174   Removes from the viewer the curves which refer to <IObject>
175 */
176 void SPlot2d_Viewer::Erase( const Handle(SALOME_InteractiveObject)& IObject, bool update )
177 {
178   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
179   if(aViewFrame == NULL) return;
180
181   SPlot2d_Curve* curve = getCurveByIO( IObject );
182   if ( curve )
183     aViewFrame->eraseCurve( curve, update );
184
185   // it can be table or container object selected
186   //ASL: Temporary commented in order to avoid dependency on SALOMEDS
187 /*  _PTR(Study) aStudy = getStudyDS();
188   _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry());
189   if ( aSO ) {
190     _PTR(ChildIterator) aIter = aStudy->NewChildIterator( aSO );
191     for ( ; aIter->More(); aIter->Next() ) {
192       _PTR(SObject) aChildSO = aIter->Value();
193       _PTR(SObject) refSO;
194       if ( aChildSO->ReferencedObject( refSO ) && refSO )
195         aChildSO = refSO;
196       curve = getCurveByIO( new SALOME_InteractiveObject( aChildSO->GetID().c_str(), "") );
197       if ( curve )
198         aViewFrame->eraseCurve( curve, update );
199     }
200   }
201 */
202
203 }
204
205 /*!
206    Removes all curves from the view
207 */
208 void SPlot2d_Viewer::EraseAll(SALOME_Displayer* d, const bool forced) 
209 {
210   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
211   if(aViewFrame) aViewFrame->EraseAll();
212   SALOME_View::EraseAll(d, forced);
213 }
214
215 /*!
216   Redraws Viewer contents
217 */
218 void SPlot2d_Viewer::Repaint()
219 {
220   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
221   if(aViewFrame) aViewFrame->Repaint();
222 }
223
224 /*!
225   Display presentation
226 */
227 void SPlot2d_Viewer::Display( const SALOME_Prs2d* prs )
228 {
229   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
230   Plot2d_Prs* aPrs = dynamic_cast<Plot2d_Prs*>(const_cast<SALOME_Prs2d*>(prs));
231   if(aViewFrame && aPrs) aViewFrame->Display(aPrs);
232 }
233
234 /*!
235   Erase presentation
236 */
237 void SPlot2d_Viewer::Erase( const SALOME_Prs2d* prs, const bool )
238 {
239   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
240   Plot2d_Prs* aPrs = dynamic_cast<Plot2d_Prs*>(const_cast<SALOME_Prs2d*>(prs));
241   if(aViewFrame && aPrs) aViewFrame->Erase(aPrs);
242 }
243   
244 /*!
245   Create presentation by entry
246 */
247 SALOME_Prs* SPlot2d_Viewer::CreatePrs( const char* entry )
248 {
249   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
250   SPlot2d_Prs *prs = new SPlot2d_Prs( entry );
251   if(aViewFrame)
252   {
253     CurveDict aCurves = aViewFrame->getCurves();
254     CurveDict::Iterator it = aCurves.begin();
255     for( ; it != aCurves.end(); ++it ) {
256       SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>(it.value());
257       OwnerSet owners = aCurve->getOwners();
258       if(aCurve) {
259         if ( 
260             (aCurve->hasIO() && !strcmp( aCurve->getIO()->getEntry(), entry )) ||
261             (aCurve->hasTableIO() && !strcmp( aCurve->getTableIO()->getEntry(), entry )) ||
262             owners.contains(entry)
263             ) {
264           prs->AddObject(aCurve);
265         }
266       }      
267     }
268   }
269   return prs;
270 }
271
272 /*!
273   Returns true if interactive object is presented in the viewer and displayed
274 */
275 bool SPlot2d_Viewer::isVisible( const Handle(SALOME_InteractiveObject)& IObject ) 
276 {
277   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
278   if(aViewFrame == NULL) return false;
279
280   SPlot2d_Curve* curve = getCurveByIO( IObject );
281   return aViewFrame->isVisible( curve );
282 }
283
284 /*!
285   \Collect objects visible in viewer
286   \param theList - visible objects collection
287 */
288 void SPlot2d_Viewer::GetVisible( SALOME_ListIO& theList )
289 {
290   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
291   if(aViewFrame == NULL) return;
292   CurveDict aCurves = aViewFrame->getCurves();
293   CurveDict::Iterator it = aCurves.begin();
294   for( ; it != aCurves.end(); ++it ) {
295     SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>(it.value()); 
296     if ( aCurve && aCurve->hasIO() && aViewFrame->isVisible( aCurve ) )
297       theList.Append( aCurve->getIO() );
298   }
299 }
300
301 /*!
302   Return interactive obeject if is presented in the viewer
303 */
304 Handle(SALOME_InteractiveObject) SPlot2d_Viewer::FindIObject( const char* Entry )
305 {
306   Handle(SALOME_InteractiveObject) anIO;
307   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
308   if(aViewFrame == NULL) return anIO;
309
310   CurveDict aCurves = aViewFrame->getCurves();
311   CurveDict::Iterator it = aCurves.begin();
312   for( ; it != aCurves.end(); ++it ) {
313     SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>(it.value()); 
314     if ( aCurve && aCurve->hasIO() && !strcmp( aCurve->getIO()->getEntry(), Entry ) ) {
315       anIO = aCurve->getIO();
316       break;
317     }
318   }
319   return anIO;
320 }
321
322 /*!
323   Returns an active Plot2d ViewFrame or NULL
324 */
325 Plot2d_ViewFrame* SPlot2d_Viewer::getActiveViewFrame()
326 {
327   SUIT_ViewManager* aViewMgr = getViewManager();
328   if(aViewMgr) {
329     Plot2d_ViewWindow* aViewWnd = dynamic_cast<Plot2d_ViewWindow*>(aViewMgr->getActiveView());
330     if(aViewWnd)
331       return aViewWnd->getViewFrame();
332   }
333
334   return NULL;
335 }
336
337 /*!
338   \return curve by object and viewframe
339   \param theIObject - object
340   \param fr - viewframe
341 */
342 SPlot2d_Curve* SPlot2d_Viewer::getCurveByIO( const Handle(SALOME_InteractiveObject)& theIObject,
343                                              Plot2d_ViewFrame* fr )
344 {
345   if ( !theIObject.IsNull() ) {
346     Plot2d_ViewFrame* aViewFrame = fr ? fr : getActiveViewFrame();
347     if(aViewFrame) {
348       CurveDict aCurves = aViewFrame->getCurves();
349       CurveDict::Iterator it = aCurves.begin();
350       for( ; it != aCurves.end(); ++it ) {
351         SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>( it.value() );
352         if(aCurve) {
353           if ( aCurve->hasIO() && aCurve->getIO()->isSame( theIObject ) )
354             return aCurve;
355         }
356       }
357     }
358   }
359   return NULL;
360 }
361
362 /*!
363   create SPlot2d_ViewWindow
364 */
365 SUIT_ViewWindow* SPlot2d_Viewer::createView( SUIT_Desktop* theDesktop )
366 {
367   SPlot2d_ViewWindow* aPlot2dView = new SPlot2d_ViewWindow(theDesktop, this);
368   aPlot2dView->initLayout();
369   if (getPrs())
370     aPlot2dView->getViewFrame()->Display(getPrs());
371   return aPlot2dView;
372 }
373
374 /*!
375   SLOT: called when action "Legend Clicked" is activated.
376   override "onLegendClicked" method from Plot2d_ViewModel.
377 */
378 void SPlot2d_Viewer::onClicked( const QVariant& itemInfo, int /*index*/ )
379 {
380   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
381   if(aViewFrame == NULL) return;
382
383   QwtPlotItem* plotItem = aViewFrame->getPlot()->infoToItem( itemInfo );
384
385   bool isCurveSelected = false;
386   CurveDict aCurves = aViewFrame->getCurves();
387   for( CurveDict::Iterator it = aCurves.begin(); it != aCurves.end(); ++it )
388   {
389     if(plotItem == it.key()) {
390       isCurveSelected = true;
391       it.value()->setSelected(true);
392     } else {
393       it.value()->setSelected(false);
394     }
395   }
396
397   AnalyticalCurveList curves = aViewFrame->getAnalyticalCurves();
398    foreach ( Plot2d_AnalyticalCurve* curve, curves ) {
399            if(plotItem == curve->plotItem()) {
400           isCurveSelected = true;
401                   curve->setSelected(true);
402            } else {
403                   curve->setSelected(false);
404            }
405    }
406   if(isCurveSelected) {
407     for( CurveDict::Iterator it = aCurves.begin(); it != aCurves.end(); ++it )
408       aViewFrame->updateCurve( it.value() );
409
410         myDeselectAnalytical = false;
411         emit clearSelected();
412         aViewFrame->updateAnalyticalCurves();
413         myDeselectAnalytical = true;
414         return;
415   }
416
417   Plot2d_Object* anObject = aViewFrame->getPlotObject(plotItem);
418   if(anObject) {
419     
420     // Highlight object in Object Browser
421     QString anEntry;
422     if(SPlot2d_Curve* aSCurve = dynamic_cast<SPlot2d_Curve*>(anObject)) {
423       if(aSCurve->hasIO())
424         anEntry = aSCurve->getIO()->getEntry();
425     } else if( SPlot2d_Histogram* aSHisto = dynamic_cast<SPlot2d_Histogram*>(anObject)) {
426       if(aSHisto->hasIO())
427         anEntry = aSHisto->getIO()->getEntry();
428     }
429     
430     if(!anEntry.isEmpty())
431       emit legendSelected( anEntry );
432   }     
433 }
434
435 /*!
436   
437 */
438 void SPlot2d_Viewer::setObjectsSelected( SALOME_ListIO& theList ) {
439   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
440   if(aViewFrame) {
441
442     objectList allObjects;
443     aViewFrame->getObjects( allObjects );
444     
445     bool isSelected = false;
446     SPlot2d_Histogram* h = 0;
447     SPlot2d_Curve* c =0;
448     
449     foreach ( Plot2d_Object* o, allObjects ) {
450       isSelected = false;
451       
452       Handle(SALOME_InteractiveObject) io;
453       if( (h = dynamic_cast<SPlot2d_Histogram*>(o)) && h->hasIO() ) {
454         io = h->getIO();
455       } else if((c = dynamic_cast<SPlot2d_Curve*>(o)) && c->hasIO()) {
456         io = c->getIO();
457       } else {
458         continue;
459       }
460
461       SALOME_ListIteratorOfListIO anIter( theList ); 
462       
463       for( ; anIter.More(); anIter.Next() ) {
464         if ( anIter.Value()->hasEntry() ) {
465           if( io->isSame(anIter.Value()) ) {
466             isSelected = o->isSelected();
467             if( !isSelected ) {
468               o->setSelected(true);
469               aViewFrame->updateObject(o);
470               theList.Remove(anIter);
471               isSelected = true;
472               break;
473             } else 
474               break;
475           }
476         }
477       }
478       if( !isSelected && o->isSelected() != false ) {   
479         o->setSelected(false);
480         aViewFrame->updateObject(o);
481       }
482     }
483         if( myDeselectAnalytical ) {
484                 aViewFrame->deselectAnalyticalCurves();
485                 aViewFrame->updateAnalyticalCurves(); 
486         }
487     aViewFrame->Repaint();
488   }
489 }