Salome HOME
Implementation of the "21384: [CEA 508] Plot2d Allow user to rescale curve" isuue.
[modules/visu.git] / src / VISU_I / VISU_Tools.cxx
1 // Copyright (C) 2007-2011  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.
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 //  File   : VISU_Tools.cxx
21 //  Author : Oleg UVAROV
22 //  Module : VISU
23 //
24 #include "VISU_Tools.h"
25
26 #include "VISU_Gen_i.hh"
27 #include "VISU_Table_i.hh"
28 #include "VISU_ViewManager_i.hh"
29
30 #include <VISU_ActorBase.h>
31
32 #include <LightApp_Displayer.h>
33
34 #include <SalomeApp_Study.h>
35 #include <SalomeApp_Application.h>
36 #include <SalomeApp_Module.h>
37
38 #include <SPlot2d_ViewModel.h>
39 #include <Plot2d_ViewFrame.h>
40 #include <Plot2d_ViewManager.h>
41
42 #include <SUIT_ResourceMgr.h>
43 #include <SUIT_Session.h>
44
45 //=============================================================================
46 namespace VISU
47 {
48   //------------------------------------------------------------
49   // Internal function used by several public functions below
50   void
51   UpdateCurve(VISU::Curve_i* theCurve,
52               Plot2d_ViewFrame* thePlot,
53               SPlot2d_Curve* plotCurve,
54               int theDisplaying)
55   {
56     if ( theDisplaying == VISU::eErase ) {
57       if ( plotCurve && thePlot )
58         thePlot->eraseCurve( plotCurve, false );
59     }
60     else if ( theDisplaying == VISU::eDisplay || theDisplaying == VISU::eDisplayOnly ) {
61       if ( plotCurve ) {
62         plotCurve->setHorTitle( theCurve->GetHorTitle().c_str() );
63         //plotCurve->setVerTitle( ( theCurve->GetVerTitle().c_str() ) );
64         plotCurve->setVerTitle( theCurve->GetName().c_str() );
65         plotCurve->setHorUnits( theCurve->GetHorUnits().c_str() );
66         plotCurve->setVerUnits( theCurve->GetVerUnits().c_str() );
67         plotCurve->setScale( theCurve->GetScale() );
68         double* xList = 0;
69         double* yList = 0;
70         QStringList zList;
71         int     nbPoints = theCurve->GetData( xList, yList, zList );
72         if ( nbPoints > 0 && xList && yList ) {
73           plotCurve->setData( xList, yList, nbPoints, zList );
74         }
75         if ( !theCurve->IsAuto() ) {
76           plotCurve->setLine( (Plot2d::LineType)theCurve->GetLine(), theCurve->GetLineWidth() );
77           plotCurve->setMarker( (Plot2d::MarkerType)theCurve->GetMarker() );
78           SALOMEDS::Color color = theCurve->GetColor();
79           plotCurve->setColor( QColor( (int)(color.R*255.), (int)(color.G*255.), (int)(color.B*255.) ) );
80         }
81         plotCurve->setAutoAssign( theCurve->IsAuto() );
82         if( thePlot )
83           thePlot->displayCurve( plotCurve, false );
84       }
85       else {
86         Plot2d_Curve* crv = theCurve->CreatePresentation();
87         if ( crv ) {
88           if( thePlot )
89             thePlot->displayCurve( crv, false );
90           theCurve->SetLine( (VISU::Curve::LineType)crv->getLine(), crv->getLineWidth() );
91           theCurve->SetMarker( (VISU::Curve::MarkerType)crv->getMarker());
92           SALOMEDS::Color newColor;
93           newColor.R = crv->getColor().red()/255.;
94           newColor.G = crv->getColor().green()/255.;
95           newColor.B = crv->getColor().blue()/255.;
96           theCurve->SetColor( newColor );
97           crv->setAutoAssign( theCurve->IsAuto() );
98         }
99       }
100     }
101   }
102
103   //------------------------------------------------------------
104   void
105   PlotTable(SalomeApp_Study* theStudy,
106             Plot2d_ViewFrame* thePlot,
107             VISU::Table_i* table,
108             int theDisplaying)
109   {
110     if ( !thePlot )
111       return;
112
113     if ( theDisplaying == VISU::eDisplayOnly )
114       thePlot->EraseAll();
115     QList<Plot2d_Curve*> clist;
116     thePlot->getCurves( clist );
117     _PTR(Study) aStudy = theStudy->studyDS();
118     _PTR(SObject) TableSO = aStudy->FindObjectID( table->GetEntry() );
119     if ( TableSO ) {
120       _PTR(ChildIterator) Iter = aStudy->NewChildIterator( TableSO );
121       for ( ; Iter->More(); Iter->Next() ) {
122         CORBA::Object_var childObject = VISU::ClientSObjectToObject( Iter->Value() );
123         if( !CORBA::is_nil( childObject ) ) {
124           CORBA::Object_ptr aCurve = VISU::Curve::_narrow( childObject );
125           if( !CORBA::is_nil( aCurve ) ) {
126             VISU::Curve_i* theCurve = dynamic_cast<VISU::Curve_i*>(VISU::GetServant(aCurve).in());
127             SPlot2d_Curve* plotCurve = 0;
128             SPlot2d_Curve* tmpCurve;
129             for ( int i = 0; i < clist.count(); i++ ) {
130               tmpCurve = dynamic_cast<SPlot2d_Curve*>( clist.at( i ) );
131               if (tmpCurve && tmpCurve->hasIO() &&
132                   theCurve->GetEntry() == tmpCurve->getIO()->getEntry()) {
133                 plotCurve = tmpCurve;
134                 break;
135               }
136             }
137
138             UpdateCurve( theCurve, thePlot, plotCurve, theDisplaying );
139             CurveVisibilityChanged(theCurve, theDisplaying, true, false, true);
140
141             if ( theDisplaying == VISU::eErase && plotCurve ) {
142               clist.removeAll(plotCurve );
143             }
144           }
145         }
146       }
147       thePlot->Repaint();
148       SetVisibilityState(table->GetEntry(),GetStateByDisplaying(theDisplaying));
149     }
150     
151   }
152
153   //------------------------------------------------------------
154   void
155   PlotCurve(Plot2d_ViewFrame* thePlot,
156             VISU::Curve_i* theCurve,
157             int theDisplaying)
158   {
159     if ( !thePlot )
160       return;
161
162 //  if ( theDisplaying == VISU::eDisplayOnly )
163 //    thePlot->EraseAll();
164     QList<Plot2d_Curve*> clist;
165     thePlot->getCurves( clist );
166     SPlot2d_Curve* plotCurve = 0;
167     SPlot2d_Curve* tmpCurve;
168     if(theDisplaying == VISU::eErase) {
169       // 23.06.2008 skl for IPAL17672
170       for (int i = 0; i < clist.count(); i++) {
171         tmpCurve = dynamic_cast<SPlot2d_Curve*>(clist.at(i));
172         if (tmpCurve && tmpCurve->hasIO() &&
173             theCurve->GetEntry() == tmpCurve->getIO()->getEntry()) {
174           plotCurve = tmpCurve;
175           thePlot->eraseCurve(clist.at(i));
176           break;
177         }
178       }
179       UpdateCurve(theCurve, thePlot, plotCurve, theDisplaying);
180     }
181     else {
182       for (int i = 0; i < clist.count(); i++) {
183         tmpCurve = dynamic_cast<SPlot2d_Curve*>(clist.at(i));
184         if (tmpCurve && tmpCurve->hasIO() &&
185             theCurve->GetEntry() == tmpCurve->getIO()->getEntry()) {
186           plotCurve = tmpCurve;
187         }
188         else if (theDisplaying == VISU::eDisplayOnly) {
189           thePlot->eraseCurve(clist.at(i));
190         }
191       }
192       UpdateCurve(theCurve, thePlot, plotCurve, theDisplaying);
193     }
194
195     thePlot->Repaint();
196
197     SetVisibilityState(theCurve->GetEntry(),GetStateByDisplaying(theDisplaying));
198     CurveVisibilityChanged(theCurve,theDisplaying,false, true, true);
199   }
200
201   //------------------------------------------------------------
202   void
203   PlotRemoveCurve(SalomeApp_Application* theApp,
204                   VISU::Curve_i* pCrv)
205   {
206     QString anEntry = pCrv->GetEntry().c_str();
207     ViewManagerList pvm_list;
208     theApp->viewManagers( SPlot2d_Viewer::Type(), pvm_list );
209     ViewManagerList::Iterator pvm_it = pvm_list.begin();
210     for( ; pvm_it != pvm_list.end(); pvm_it++ ){
211       Plot2d_ViewManager* pvm = dynamic_cast<Plot2d_ViewManager*>( *pvm_it );
212       if( pvm ){
213         SPlot2d_Viewer* aSPlot2d = dynamic_cast<SPlot2d_Viewer*>( pvm->getViewModel() );
214         if( aSPlot2d ){
215           Plot2d_ViewFrame* thePlot = aSPlot2d->getActiveViewFrame();
216           if(thePlot){
217             QList<Plot2d_Curve*> clist;
218             thePlot->getCurves( clist );
219             for (int i = 0; i < clist.count(); i++) {
220               if(SPlot2d_Curve* plotCurve = dynamic_cast<SPlot2d_Curve*>(clist[i]))
221                 if(plotCurve->hasIO() && (plotCurve->getIO()->getEntry() == anEntry))
222                   thePlot->eraseCurve(clist[i]);
223             }
224           }
225         }
226       }
227     }
228   }
229   
230   //------------------------------------------------------------
231   // Internal function used by the function below
232   SPlot2d_Curve* GetCurveByIO( const Handle(SALOME_InteractiveObject)& theIObject,
233                                Plot2d_ViewFrame* thePlot )
234   {
235     if ( !theIObject.IsNull() && thePlot ) {
236       CurveDict aCurves = thePlot->getCurves();
237       CurveDict::Iterator it = aCurves.begin();
238       for( ; it != aCurves.end(); ++it ) {
239         SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>( it.value() );
240         if(aCurve) {
241           if ( aCurve->hasIO() && aCurve->getIO()->isSame( theIObject ) )
242             return aCurve;
243         }
244       }
245     }
246     return NULL;
247   }
248
249   //------------------------------------------------------------
250   void
251   PlotContainer(Plot2d_ViewFrame* thePlot,
252                 VISU::Container_i* container,
253                 int theDisplaying)
254   {
255     if ( !thePlot || !container)
256       return;
257
258     if ( theDisplaying == VISU::eDisplayOnly )
259       thePlot->EraseAll();
260     QList<Plot2d_Curve*> clist;
261     thePlot->getCurves( clist );
262     if ( container->GetNbCurves() > 0 ) {
263       int nbCurves = container->GetNbCurves();
264       SetVisibilityState(container->GetEntry(), GetStateByDisplaying(theDisplaying));
265       for ( int k = 1; k <= nbCurves; k++ ) {
266         VISU::Curve_i* theCurve = container->GetCurve( k );
267         if ( theCurve && theCurve->IsValid() ) {
268           SPlot2d_Curve* plotCurve = GetCurveByIO(new SALOME_InteractiveObject(theCurve->GetEntry().c_str(), "", ""), thePlot);
269
270           UpdateCurve( theCurve, thePlot, plotCurve, theDisplaying );
271
272           if ( plotCurve && theDisplaying == VISU::eErase ) {
273             clist.removeAll( plotCurve );
274           }
275           CurveVisibilityChanged(theCurve, theDisplaying, true, true, true);
276         }
277       }
278     }
279     
280     thePlot->Repaint();
281     if(GetResourceMgr()->booleanValue("VISU","automatic_fit_all",false)){
282       thePlot->fitAll();
283     }
284     
285     qApp->processEvents();
286   }
287
288   //------------------------------------------------------------
289   void
290   CreatePlot(VISU_Gen_i* theVisuGen,
291              Plot2d_ViewFrame* thePlot,
292              _PTR(SObject) theTableSO)
293   {
294     _PTR(GenericAttribute) anAttr;
295     if ( theTableSO &&
296          ( theTableSO->FindAttribute( anAttr, "AttributeTableOfInteger" ) ||
297            theTableSO->FindAttribute( anAttr, "AttributeTableOfReal" ) ) ) {
298       CORBA::Object_var aTable = VISU::ClientSObjectToObject(theTableSO);
299       CORBA::Object_var aContainer = theVisuGen->CreateContainer();
300
301       if ( !CORBA::is_nil( aTable ) && !CORBA::is_nil( aContainer ) ) {
302         VISU::Table_i*     pTable     = dynamic_cast<VISU::Table_i*>(VISU::GetServant(aTable).in());
303         VISU::Container_i* pContainer = dynamic_cast<VISU::Container_i*>(VISU::GetServant(aContainer).in());
304
305         if ( pContainer && pTable ) {
306           for ( int i = 2; i <= pTable->GetNbRows(); i++ ) {
307             CORBA::Object_var aNewCurve = theVisuGen->CreateCurve( pTable->_this(), 1, i );
308             if( !CORBA::is_nil( aNewCurve ) ) {
309               VISU::Curve_i* pCrv = dynamic_cast<VISU::Curve_i*>( VISU::GetServant(aNewCurve).in() );
310               if ( pCrv ) {
311                 pContainer->AddCurve( pCrv->_this() );
312               }
313             }
314           }
315           PlotContainer( thePlot, pContainer, VISU::eDisplay );
316
317           QString anEntry = pContainer->GetEntry().c_str();
318           _PTR(Study) aStudy = theTableSO->GetStudy();
319           _PTR(SObject) aContainerSO = aStudy->FindObjectID(anEntry.toLatin1().data());
320           _PTR(SObject) aParentSO = aContainerSO->GetFather();
321         }
322       }
323     }
324   }
325
326   //------------------------------------------------------------
327   void SetVisibilityState(std::string entry, Qtx::VisibilityState state) {
328     if(entry.empty())
329       return;
330
331     if( SUIT_Session* aSession = SUIT_Session::session() )
332       if( SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSession->activeApplication()) )
333         if( SalomeApp_Study* aStudy =  dynamic_cast<SalomeApp_Study*>(anApp->activeStudy()) )
334           aStudy->setVisibilityState(entry.c_str(), state);
335
336   }
337
338   //------------------------------------------------------------
339   void SetVisibilityState(SALOME_Actor *theActor, Qtx::VisibilityState state) {
340     if(!theActor || !theActor->hasIO() || !theActor->getIO()->hasEntry())
341       return;
342     SetVisibilityState(theActor->getIO()->getEntry(), state);
343   }
344
345   void CurveVisibilityChanged(VISU::Curve_i* theCurve, 
346                               int theDisplaying,
347                               bool updateCurve,
348                               bool updateTable,
349                               bool updateContainers) {
350     
351     SUIT_Session* aSession = SUIT_Session::session();
352     if (!aSession) return;
353     
354     SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSession->activeApplication());
355     if ( !anApp ) return;
356
357     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
358     if ( !aStudy ) return;
359
360     SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>( anApp->module( anApp->moduleTitle( "VISU" ) ) );
361     if ( !aModule ) return;
362
363     LightApp_Displayer* aDisplayer = aModule->displayer();
364
365     SUIT_ViewManager* aManager = anApp->activeViewManager();
366
367     Qtx::VisibilityState state = ( aManager && aManager->getType() == SPlot2d_Viewer::Type() ) ?
368       GetStateByDisplaying(theDisplaying) : Qtx::UnpresentableState;
369     
370     if ( updateCurve )
371       SetVisibilityState( theCurve->GetEntry(), state );
372     
373     if ( updateTable ) {
374       Table_i* aTable = theCurve->getTable();
375       if ( aTable && !(aStudy->visibilityState( aTable->GetEntry().c_str() ) == state) ) {
376         _PTR(SObject) TableSO = aStudy->studyDS()->FindObjectID( aTable->GetEntry() );
377         if ( TableSO ) {
378           bool isTableVisible = false;
379           if ( aDisplayer && state != Qtx::UnpresentableState ) {
380             _PTR(ChildIterator) Iter = aStudy->studyDS()->NewChildIterator( TableSO );
381             for ( ; Iter->More() && !isTableVisible ; Iter->Next() ) {
382               CORBA::Object_var childObject = VISU::ClientSObjectToObject( Iter->Value() );
383               if ( CORBA::is_nil( childObject ) ) continue;
384               VISU::Curve_i* aCurve = dynamic_cast<VISU::Curve_i*>( VISU::GetServant( childObject.in() ).in() );
385               isTableVisible = aCurve && aDisplayer->IsDisplayed( aCurve->GetEntry().c_str() );
386             }
387           } // if ( aDisplayer ... )
388           if ( state != Qtx::UnpresentableState )
389             SetVisibilityState( aTable->GetEntry(), ( isTableVisible ? Qtx::ShownState : Qtx::HiddenState ) );
390           else 
391             SetVisibilityState( aTable->GetEntry(), state );
392         } // if ( TableSO )
393       } // if ( aTable )
394     } // if ( updateTable )
395
396     if ( updateContainers ) {
397       ContainerSet aContainers = theCurve->getContainers();
398       ContainerSet::ConstIterator it = aContainers.begin();
399       for ( ; it != aContainers.end(); it++ ) {
400         //Check that state of container is not set already
401         if(aStudy->visibilityState(*it) == state) continue;
402         _PTR(SObject) aSObject = aStudy->studyDS()->FindObjectID( (*it).toLatin1().data() );
403         if ( !aSObject ) continue;
404         bool isContainerDisplayed = false;
405         if ( aDisplayer && state != Qtx::UnpresentableState ) {
406           CORBA::Object_var anObj = VISU::ClientSObjectToObject( aSObject );
407           if ( CORBA::is_nil( anObj ) ) continue;
408           VISU::Container_i* aContainer = dynamic_cast<VISU::Container_i*>( VISU::GetServant( anObj.in() ).in() );
409           if ( !aContainer ) continue;
410           int nbCurves = aContainer->GetNbCurves();
411           for ( int k = 1; k <= nbCurves && !isContainerDisplayed; k++ ) {
412             VISU::Curve_i* aCurve = aContainer->GetCurve( k );
413             isContainerDisplayed = aCurve && aDisplayer->IsDisplayed( aCurve->GetEntry().c_str() );
414           }
415         } // if ( aDisplayer ... )
416         if ( state != Qtx::UnpresentableState )
417           SetVisibilityState( (*it).toLatin1().constData(), ( isContainerDisplayed ? Qtx::ShownState : Qtx::HiddenState ) );
418         else {
419           SetVisibilityState( (*it).toLatin1().constData(), state );
420         }
421       } // for ( ; it != aContainers.end(); it++ )
422     } //updateContainers    
423   }
424   
425   Qtx::VisibilityState GetStateByDisplaying(int theDisplaying)
426   {
427     Qtx::VisibilityState state = Qtx::UnpresentableState;
428     if(theDisplaying == eDisplayAll || 
429        theDisplaying == eDisplay    || 
430        theDisplaying == eDisplayOnly ) {
431       state = Qtx::ShownState;
432       
433     } else if (theDisplaying == eErase || theDisplaying == eEraseAll) {
434       state = Qtx::HiddenState;
435     }
436     return state;
437   }
438
439   void updateContainerVisibility(VISU::Container_i* theContainer)
440   {
441     if ( !theContainer ) return;
442     
443     SUIT_Session* aSession = SUIT_Session::session();
444     if (!aSession) return;
445     
446     SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSession->activeApplication());
447     if ( !anApp ) return;
448
449     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
450     if ( !aStudy ) return;
451
452     SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>( anApp->module( anApp->moduleTitle( "VISU" ) ) );
453     if ( !aModule ) return;
454
455     SUIT_ViewManager* aManager = anApp->activeViewManager();
456     int nbCurves = theContainer->GetNbCurves();
457     
458     Qtx::VisibilityState state = ( aManager && aManager->getType() == SPlot2d_Viewer::Type() && nbCurves > 0 ) ?
459       Qtx::HiddenState : Qtx::UnpresentableState;
460     
461     LightApp_Displayer* aDisplayer = aModule->displayer();
462
463     if ( nbCurves > 0 && aDisplayer ) {
464       for ( int k = 1; k <= nbCurves; k++ ) {
465         VISU::Curve_i* aCurve = theContainer->GetCurve( k );
466         if ( aCurve && aDisplayer->IsDisplayed( aCurve->GetEntry().c_str() ) ) {
467           state = Qtx::ShownState;
468           break;
469         }             
470       }
471     }
472     aStudy->setVisibilityState( theContainer->GetEntry().c_str(), state );
473   }
474 }