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