Salome HOME
401a613c36a1b1df1a195b44c8fb0f9a22a8e4ef
[modules/gui.git] / src / SPlot2d / SPlot2d_ViewModel.cxx
1 // Copyright (C) 2007-2014  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 //ASL: Temporary commented in order to avoir dependency on SALOMEDS
51
52 //#include "SALOMEDSClient.hxx"
53 //#include "SALOMEDS_StudyManager.hxx"
54
55 // in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study.
56 // SalomeApp_Study::studyDS() does it as well, but -- here it is retrieved from
57 // SALOMEDS::StudyManager - no linkage with SalomeApp.  
58
59 /*static _PTR(Study) getStudyDS()
60 {
61   SALOMEDSClient_Study* aStudy = NULL;
62   _PTR(StudyManager) aMgr( new SALOMEDS_StudyManager() );
63
64   // get id of SUIT_Study, if it's a SalomeApp_Study, it will return
65   //    id of its underlying SALOMEDS::Study
66   SUIT_Application* app = SUIT_Session::session()->activeApplication();
67   if ( !app )  return _PTR(Study)(aStudy);
68   SUIT_Study* stud = app->activeStudy();
69   if ( !stud ) return _PTR(Study)(aStudy);
70   const int id = stud->id(); // virtual method, must return SALOMEDS_Study id
71   // get SALOMEDS_Study with this id from StudyMgr
72   return aMgr->GetStudyByID( id );
73 } */               
74
75 /*!
76   Constructor
77 */
78 SPlot2d_Viewer::SPlot2d_Viewer(  bool theAutoDel )
79 : Plot2d_Viewer( theAutoDel ),
80   myDeselectAnalytical(true)
81 {
82 }
83
84 /*!
85   Destructor
86 */
87 SPlot2d_Viewer::~SPlot2d_Viewer()
88 {
89 }
90
91 /*!
92   Renames curve if it is found
93 */
94 void SPlot2d_Viewer::rename( const Handle(SALOME_InteractiveObject)& IObject,
95                              const QString& newName, Plot2d_ViewFrame* fr ) 
96 {
97   Plot2d_ViewFrame* aViewFrame = fr ? fr : getActiveViewFrame();
98   if( !aViewFrame )
99     return;
100
101   CurveDict aCurves = aViewFrame->getCurves();
102   CurveDict::Iterator it = aCurves.begin();
103   for( ; it != aCurves.end(); ++it )
104   {
105     SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>( it.value() );
106     if( aCurve && aCurve->hasIO() && aCurve->getIO()->isSame( IObject ) )
107     {
108       aCurve->setVerTitle( newName );
109       it.key()->setTitle( newName );
110     }
111
112     if( aCurve && aCurve->hasTableIO() && aCurve->getTableIO()->isSame( IObject ) )
113       aCurve->getTableIO()->setName( newName.toLatin1() );
114   }
115   aViewFrame->updateTitles();
116 }
117
118 /*!
119   Renames all copies of object in all view windows
120   \param IObj - object to be renamed
121   \param name - new name
122 */
123 void SPlot2d_Viewer::renameAll( const Handle(SALOME_InteractiveObject)& IObj, const QString& name )
124 {
125   SUIT_ViewManager* vm = getViewManager();
126   if ( vm )
127   {
128     const QVector<SUIT_ViewWindow*>& wnds = vm->getViews();
129
130     for ( uint i = 0; i < wnds.size(); i++ )
131     {
132       Plot2d_ViewWindow* pwnd = dynamic_cast<Plot2d_ViewWindow*>( wnds.at( i ) );
133       rename( IObj, name, pwnd->getViewFrame() );
134     }
135   }
136 }
137
138 /*!
139   Returns true if interactive object is presented in the viewer
140 */
141 bool SPlot2d_Viewer::isInViewer( const Handle(SALOME_InteractiveObject)& IObject ) 
142 {
143   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
144   if(aViewFrame == NULL) return 0;
145
146   if( getCurveByIO( IObject ) != NULL )
147     return 1;
148   else{
149     if(!IObject.IsNull()){
150       CurveDict aCurves = aViewFrame->getCurves();
151       CurveDict::Iterator it = aCurves.begin();
152       for( ; it != aCurves.end(); ++it ) {
153         SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>( it.value() );
154         if(aCurve && aCurve->hasIO() && aCurve->getTableIO()->isSame(IObject))
155           return 1;
156       }
157     }
158   }
159   return 0;
160 }
161
162
163 /*!
164   Actually this method just re-displays curves which refers to the <IObject>
165 */
166 void SPlot2d_Viewer::Display( const Handle(SALOME_InteractiveObject)& IObject, bool update )
167 {
168   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
169   if(aViewFrame == NULL) return;
170
171   SPlot2d_Curve* curve = getCurveByIO( IObject );
172   if ( curve )
173     aViewFrame->updateCurve( curve, update );
174 }
175
176 /*!
177   Actually this method just erases all curves which don't refer to <IOBject> 
178   and re-displays curve which is of <IObject>
179 */
180 void SPlot2d_Viewer::DisplayOnly( const Handle(SALOME_InteractiveObject)& IObject )
181 {
182   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
183   if(aViewFrame == NULL) return;
184
185   Plot2d_Curve* curve = getCurveByIO( IObject );
186   CurveDict aCurves = aViewFrame->getCurves();
187   CurveDict::Iterator it = aCurves.begin();
188   for( ; it != aCurves.end(); ++it ) {
189     if(it.value() != curve)
190       aViewFrame->eraseCurve( curve );
191     else
192       aViewFrame->updateCurve( curve, false );
193   }
194
195   aViewFrame->Repaint();
196 }
197
198 /*!
199   Removes from the viewer the curves which refer to <IObject>
200 */
201 void SPlot2d_Viewer::Erase( const Handle(SALOME_InteractiveObject)& IObject, bool update )
202 {
203   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
204   if(aViewFrame == NULL) return;
205
206   SPlot2d_Curve* curve = getCurveByIO( IObject );
207   if ( curve )
208     aViewFrame->eraseCurve( curve, update );
209
210   // it can be table or container object selected
211   //ASL: Temporary commented in order to avoid dependency on SALOMEDS
212 /*  _PTR(Study) aStudy = getStudyDS();
213   _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry());
214   if ( aSO ) {
215     _PTR(ChildIterator) aIter = aStudy->NewChildIterator( aSO );
216     for ( ; aIter->More(); aIter->Next() ) {
217       _PTR(SObject) aChildSO = aIter->Value();
218       _PTR(SObject) refSO;
219       if ( aChildSO->ReferencedObject( refSO ) && refSO )
220         aChildSO = refSO;
221       curve = getCurveByIO( new SALOME_InteractiveObject( aChildSO->GetID().c_str(), "") );
222       if ( curve )
223         aViewFrame->eraseCurve( curve, update );
224     }
225   }
226 */
227
228 }
229
230 /*!
231    Removes all curves from the view
232 */
233 void SPlot2d_Viewer::EraseAll(const bool /*forced*/) 
234 {
235   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
236   if(aViewFrame) aViewFrame->EraseAll();
237 }
238
239 /*!
240   Redraws Viewer contents
241 */
242 void SPlot2d_Viewer::Repaint()
243 {
244   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
245   if(aViewFrame) aViewFrame->Repaint();
246 }
247
248 /*!
249   Display presentation
250 */
251 void SPlot2d_Viewer::Display( const SALOME_Prs2d* prs )
252 {
253   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
254   Plot2d_Prs* aPrs = dynamic_cast<Plot2d_Prs*>(const_cast<SALOME_Prs2d*>(prs));
255   if(aViewFrame && aPrs) aViewFrame->Display(aPrs);
256 }
257
258 /*!
259   Erase presentation
260 */
261 void SPlot2d_Viewer::Erase( const SALOME_Prs2d* prs, const bool )
262 {
263   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
264   Plot2d_Prs* aPrs = dynamic_cast<Plot2d_Prs*>(const_cast<SALOME_Prs2d*>(prs));
265   if(aViewFrame && aPrs) aViewFrame->Erase(aPrs);
266 }
267   
268 /*!
269   Create presentation by entry
270 */
271 SALOME_Prs* SPlot2d_Viewer::CreatePrs( const char* entry )
272 {
273   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
274   SPlot2d_Prs *prs = new SPlot2d_Prs();
275   if(aViewFrame)
276   {
277     CurveDict aCurves = aViewFrame->getCurves();
278     CurveDict::Iterator it = aCurves.begin();
279     for( ; it != aCurves.end(); ++it ) {
280       SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>(it.value());
281       OwnerSet owners = aCurve->getOwners();
282       if(aCurve) {
283         if ( 
284             (aCurve->hasIO() && !strcmp( aCurve->getIO()->getEntry(), entry )) ||
285             (aCurve->hasTableIO() && !strcmp( aCurve->getTableIO()->getEntry(), entry )) ||
286             owners.contains(entry)
287             ) {
288           prs->AddObject(aCurve);
289         }
290       }      
291     }
292   }
293   return prs;
294 }
295
296 /*!
297   Returns true if interactive object is presented in the viewer and displayed
298 */
299 bool SPlot2d_Viewer::isVisible( const Handle(SALOME_InteractiveObject)& IObject ) 
300 {
301   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
302   if(aViewFrame == NULL) return false;
303
304   SPlot2d_Curve* curve = getCurveByIO( IObject );
305   return aViewFrame->isVisible( curve );
306 }
307
308 /*!
309   \Collect objects visible in viewer
310   \param theList - visible objects collection
311 */
312 void SPlot2d_Viewer::GetVisible( SALOME_ListIO& theList )
313 {
314   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
315   if(aViewFrame == NULL) return;
316   CurveDict aCurves = aViewFrame->getCurves();
317   CurveDict::Iterator it = aCurves.begin();
318   for( ; it != aCurves.end(); ++it ) {
319     SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>(it.value()); 
320     if ( aCurve && aCurve->hasIO() && aViewFrame->isVisible( aCurve ) )
321       theList.Append( aCurve->getIO() );
322   }
323 }
324
325 /*!
326   Return interactive obeject if is presented in the viewer
327 */
328 Handle(SALOME_InteractiveObject) SPlot2d_Viewer::FindIObject( const char* Entry )
329 {
330   Handle(SALOME_InteractiveObject) anIO;
331   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
332   if(aViewFrame == NULL) return anIO;
333
334   CurveDict aCurves = aViewFrame->getCurves();
335   CurveDict::Iterator it = aCurves.begin();
336   for( ; it != aCurves.end(); ++it ) {
337     SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>(it.value()); 
338     if ( aCurve && aCurve->hasIO() && !strcmp( aCurve->getIO()->getEntry(), Entry ) ) {
339       anIO = aCurve->getIO();
340       break;
341     }
342   }
343   return anIO;
344 }
345
346 /*!
347   Returns an active Plot2d ViewFrame or NULL
348 */
349 Plot2d_ViewFrame* SPlot2d_Viewer::getActiveViewFrame()
350 {
351   SUIT_ViewManager* aViewMgr = getViewManager();
352   if(aViewMgr) {
353     Plot2d_ViewWindow* aViewWnd = dynamic_cast<Plot2d_ViewWindow*>(aViewMgr->getActiveView());
354     if(aViewWnd)
355       return aViewWnd->getViewFrame();
356   }
357
358   return NULL;
359 }
360
361 /*!
362   \return curve by object and viewframe
363   \param theIObject - object
364   \param fr - viewframe
365 */
366 SPlot2d_Curve* SPlot2d_Viewer::getCurveByIO( const Handle(SALOME_InteractiveObject)& theIObject,
367                                              Plot2d_ViewFrame* fr )
368 {
369   if ( !theIObject.IsNull() ) {
370     Plot2d_ViewFrame* aViewFrame = fr ? fr : getActiveViewFrame();
371     if(aViewFrame) {
372       CurveDict aCurves = aViewFrame->getCurves();
373       CurveDict::Iterator it = aCurves.begin();
374       for( ; it != aCurves.end(); ++it ) {
375         SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>( it.value() );
376         if(aCurve) {
377           if ( aCurve->hasIO() && aCurve->getIO()->isSame( theIObject ) )
378             return aCurve;
379         }
380       }
381     }
382   }
383   return NULL;
384 }
385
386 /*!
387   create SPlot2d_ViewWindow
388 */
389 SUIT_ViewWindow* SPlot2d_Viewer::createView( SUIT_Desktop* theDesktop )
390 {
391   SPlot2d_ViewWindow* aPlot2dView = new SPlot2d_ViewWindow(theDesktop, this);
392   aPlot2dView->initLayout();
393   if (getPrs())
394     aPlot2dView->getViewFrame()->Display(getPrs());
395   return aPlot2dView;
396 }
397
398 /*!
399   SLOT: called when action "Legend Clicked" is activated.
400   override "onLegendClicked" method from Plot2d_ViewModel.
401 */
402 void SPlot2d_Viewer::onClicked( const QVariant& itemInfo, int index )
403 {
404   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
405   if(aViewFrame == NULL) return;
406
407   QwtPlotItem* plotItem = aViewFrame->getPlot()->infoToItem( itemInfo );
408
409   bool isAnalytical = false;
410   AnalyticalCurveList curves = aViewFrame->getAnalyticalCurves();
411    foreach ( Plot2d_AnalyticalCurve* curve, curves ) {
412            if(plotItem == curve->plotItem()) {
413                   isAnalytical = true;
414                   curve->setSelected(true);
415            } else {
416                   curve->setSelected(false);
417            }
418    }
419   if(isAnalytical) {
420         myDeselectAnalytical = false;
421         emit clearSelected();
422         aViewFrame->updateAnalyticalCurves();
423         myDeselectAnalytical = true;
424         return;
425   }
426
427   Plot2d_Object* anObject = aViewFrame->getPlotObject(plotItem);
428   
429   if(anObject) {
430     
431     // Highlight object in Object Browser
432     QString anEntry;
433     if(SPlot2d_Curve* aSCurve = dynamic_cast<SPlot2d_Curve*>(anObject)) {
434       if(aSCurve->hasIO())
435         anEntry = aSCurve->getIO()->getEntry();
436     } else if( SPlot2d_Histogram* aSHisto = dynamic_cast<SPlot2d_Histogram*>(anObject)) {
437       if(aSHisto->hasIO())
438         anEntry = aSHisto->getIO()->getEntry();
439     }
440     
441     if(!anEntry.isEmpty())
442       emit legendSelected( anEntry );
443   }     
444 }
445
446 /*!
447   
448 */
449 void SPlot2d_Viewer::setObjectsSelected( SALOME_ListIO& theList ) {
450   Plot2d_ViewFrame* aViewFrame = getActiveViewFrame();
451   if(aViewFrame) {
452
453     objectList allObjects;
454     aViewFrame->getObjects( allObjects );
455     
456     bool isSelected = false;
457     SPlot2d_Histogram* h = 0;
458     SPlot2d_Curve* c =0;
459     
460     foreach ( Plot2d_Object* o, allObjects ) {
461       isSelected = false;
462       
463       Handle(SALOME_InteractiveObject) io;
464       if( (h = dynamic_cast<SPlot2d_Histogram*>(o)) && h->hasIO() ) {
465         io = h->getIO();
466       } else if((c = dynamic_cast<SPlot2d_Curve*>(o)) && c->hasIO()) {
467         io = c->getIO();
468       } else {
469         continue;
470       }
471
472       SALOME_ListIteratorOfListIO anIter( theList ); 
473       
474       for( ; anIter.More(); anIter.Next() ) {
475         if ( anIter.Value()->hasEntry() ) {
476           if( io->isSame(anIter.Value()) ) {
477             isSelected = o->isSelected();
478             if( !isSelected ) {
479               o->setSelected(true);
480               aViewFrame->updateObject(o);
481               theList.Remove(anIter);
482               isSelected = true;
483               break;
484             } else 
485               break;
486           }
487         }
488       }
489       if( !isSelected && o->isSelected() != false ) {   
490         o->setSelected(false);
491         aViewFrame->updateObject(o);
492       }
493     }
494         if( myDeselectAnalytical ) {
495                 aViewFrame->deselectAnalyticalCurves();
496                 aViewFrame->updateAnalyticalCurves(); 
497         }
498     aViewFrame->Repaint();
499   }
500 }