Salome HOME
b18abf38512b84e35e6e2d2597214e2a413c9849
[modules/visu.git] / src / VISUGUI / VisuGUI_TimeAnimation.cxx
1 // Copyright (C) 2007-2011  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.
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   : VisuGUI_TimeAnimation.cxx
24 //  Author : Vitaly SMETANNIKOV
25 //  Module : VISU
26 //
27 #include "VisuGUI_TimeAnimation.h"
28
29 #include "VisuGUI.h"
30 #include "VisuGUI_Tools.h"
31 #include "VisuGUI_ViewTools.h"
32 #include "VisuGUI_ScalarBarDlg.h"
33 #include "VisuGUI_DeformedShapeDlg.h"
34 #include "VisuGUI_CutPlanesDlg.h"
35 #include "VisuGUI_CutLinesDlg.h"
36 #include "VisuGUI_CutSegmentDlg.h"
37 #include "VisuGUI_Plot3DDlg.h"
38 #include "VisuGUI_VectorsDlg.h"
39 #include "VisuGUI_IsoSurfacesDlg.h"
40 #include "VisuGUI_StreamLinesDlg.h"
41 #include "VisuGUI_DeformedShapeAndScalarMapDlg.h"
42 #include "VisuGUI_GaussPointsDlg.h"
43
44 #include "VISU_TimeAnimation.h"
45
46 #include "VISU_ScalarMap_i.hh"
47 #include "VISU_IsoSurfaces_i.hh"
48 #include "VISU_DeformedShape_i.hh"
49 #include "VISU_CutPlanes_i.hh"
50 #include "VISU_Plot3D_i.hh"
51 #include "VISU_CutLines_i.hh"
52 #include "VISU_CutSegment_i.hh"
53 #include "VISU_Vectors_i.hh"
54 #include "VISU_StreamLines_i.hh"
55 #include "VISU_DeformedShapeAndScalarMap_i.hh"
56 #include "VISU_GaussPoints_i.hh"
57
58 #include "VISU_ViewManager_i.hh"
59
60 #include "VISU_ScalarBarActor.hxx"
61 #include "VISU_Actor.h"
62
63 #include <SalomeApp_DoubleSpinBox.h>
64 #include <SalomeApp_IntSpinBox.h>
65 #include "SalomeApp_Study.h"
66 #include "LightApp_Application.h"
67
68 #include "SVTK_ViewWindow.h"
69
70 #include "VTKViewer_Algorithm.h"
71
72 #include "SUIT_OverrideCursor.h"
73 #include "SUIT_MessageBox.h"
74 #include "SUIT_ResourceMgr.h"
75 #include "SUIT_Session.h"
76 #include "SUIT_Desktop.h"
77 #include "SUIT_FileDlg.h"
78
79 #include <vtkRenderer.h>
80 #include <vtkMapper.h>
81
82 #include <QGridLayout>
83 #include <QImage>
84 #include <QImageWriter>
85 #include <QLayout>
86 #include <QSlider>
87 #include <QThread>
88 #include <QListWidget>
89 #include <QLCDNumber>
90 #include <QToolButton>
91 #include <QKeyEvent>
92 #include <QComboBox>
93 #include <QLineEdit>
94 #include <QRadioButton>
95 #include <QGroupBox>
96 #include <QPushButton>
97 #include <QLabel>
98
99 #include <qwt_wheel.h>
100
101 #define  MAXVAL 1e10
102 #define  VALPRECISION 8
103
104 namespace {
105   void GeneratePresentations(int theFieldId, VISU_TimeAnimation* theAnimator)
106   {
107     if(theAnimator->getNbFields() == 0)
108       return;
109
110     int aRefFieldId = ( theAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) ? theFieldId : 0;
111     
112     VISU::ColoredPrs3d_i* aInitialPrs3d = 0;
113     if (theAnimator->getFieldData(aRefFieldId).myPrs.size() > 0)
114       aInitialPrs3d = dynamic_cast<VISU::ColoredPrs3d_i*>(theAnimator->getFieldData(aRefFieldId).myPrs[0]);
115
116     theAnimator->generatePresentations(theFieldId);
117
118     if (!aInitialPrs3d)
119       aInitialPrs3d = dynamic_cast<VISU::ColoredPrs3d_i*>(theAnimator->getFieldData(aRefFieldId).myPrs[0]);
120
121     if (aInitialPrs3d) {
122       FieldData& aFieldData = theAnimator->getFieldData(theFieldId);
123       for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
124         VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
125
126         // Special case for DeformedShape And ScalarMap presentation
127         // Restore time stamp number for all presentations
128         VISU::DeformedShapeAndScalarMap_i* aDeformedAndScalPrs = dynamic_cast<VISU::DeformedShapeAndScalarMap_i*>(aColoredPrs3d);
129         int aTimeStampNum = -1;
130         if(aDeformedAndScalPrs){
131           aTimeStampNum = aDeformedAndScalPrs->GetScalarTimeStampNumber();
132         }
133
134         aColoredPrs3d->SameAs(aInitialPrs3d);
135         
136         // rnv: fix for the 20870: EDF 1410 VISU: Anomaly in the Gauss point representation.
137         // special case for the "Gauss Points" presentation,
138         // update the LookupTable in the mapper, after assign properties of the presentation
139         // using SameAs(...) method.
140         if(aFieldData.myPrsType == VISU::TGAUSSPOINTS) {
141           aColoredPrs3d->UpdateMapperLookupTable();
142         }
143
144         if(aDeformedAndScalPrs){
145           aDeformedAndScalPrs->SetScalarField(aDeformedAndScalPrs->GetScalarEntity(),
146                                               aDeformedAndScalPrs->GetScalarFieldName(),
147                                               aTimeStampNum);
148         }
149
150         std::string aTitle = aColoredPrs3d->GetCTitle();
151         if ( aFrameId != 0 && theAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
152           aColoredPrs3d->SetTitle(aTitle.c_str());
153         }
154       }
155     }
156   }
157 }
158
159 ArrangeDlg::ArrangeDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
160   : QDialog(theParent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
161     myAnimator(theAnimator),
162     myViewWindow(theAnimator->getViewer())
163 {
164   setModal( true );
165   myCurrent = 0;
166   init();
167   QStringList aFieldNames;
168   // Find names of fields
169   for (int i = 0; i < myAnimator->getNbFields(); i++) {
170     _PTR(SObject) aSObject = myAnimator->getFieldData(i).myField;
171     VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
172     aFieldNames.append(aRestoringMap["myName"]);
173     Offset aOffs;
174     aOffs.myOffset[0] = myAnimator->getFieldData(i).myOffset[0];
175     aOffs.myOffset[1] = myAnimator->getFieldData(i).myOffset[1];
176     aOffs.myOffset[2] = myAnimator->getFieldData(i).myOffset[2];
177     myOffsets.append(aOffs);
178   }
179   myFieldLst->addItems(aFieldNames);
180   myFieldLst->setCurrentRow(0);
181 }
182
183 ArrangeDlg::ArrangeDlg(QWidget* theParent,
184                        const SalomeApp_Module* theModule,
185                        SVTK_ViewWindow* theViewWindow)
186   : QDialog(theParent,  Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
187     myAnimator(NULL),
188     myViewWindow(theViewWindow)
189 {
190   setModal( true );
191   myCurrent = 0;
192   init();
193   QStringList aPrsNames;
194   VTK::ActorCollectionCopy aCopy(myViewWindow->getRenderer()->GetActors());
195   vtkActorCollection *aCollection = aCopy.GetActors();
196   aCollection->InitTraversal();
197   while(vtkActor* anActor = aCollection->GetNextActor()){
198     if (VISU_Actor* anVISUActor = dynamic_cast<VISU_Actor*>(anActor)) {
199       if(anVISUActor->GetVisibility() != 0){
200         if (VISU::Prs3d_i* aPrs = anVISUActor->GetPrs3d()){
201           if(!myPrsMap.contains(aPrs)){
202             Handle(SALOME_InteractiveObject) anIO = aPrs->GetIO();
203             if(!anIO->hasEntry())
204               continue;
205             SalomeApp_Study* aStudy = VISU::GetAppStudy(theModule);
206             VISU::TObjectInfo anObjectInfo = VISU::GetObjectByEntry(aStudy, anIO->getEntry());
207             if(_PTR(SObject) aSObject = anObjectInfo.mySObject){
208               _PTR(GenericAttribute) anAttr;
209               if (aSObject->FindAttribute(anAttr, "AttributeName")) {
210                 _PTR(AttributeName) aName(anAttr);
211                 QString strIn(aName->Value().c_str());
212                 aPrsNames.append(strIn);
213                 myPrsMap[aPrs] = myOffsets.count();
214                 Offset aOffs;
215                 anVISUActor->GetPosition(aOffs.myOffset);
216                 myOffsets.append(aOffs);
217               }
218             }
219           }
220         }
221       }
222     } else { //if PointMap3d Actor
223       if (VISU_ActorBase* anActorBase = dynamic_cast<VISU_ActorBase*>(anActor))
224         if(anActorBase->GetVisibility() != 0)
225           if (VISU::PointMap3d_i* aPrs = dynamic_cast<VISU::PointMap3d_i*>(anActorBase->GetFactory())) {
226             if(!myPointMapPrsMap.contains(aPrs)){
227               Handle(SALOME_InteractiveObject) anIO = aPrs->GetIO();
228               if(!anIO->hasEntry())
229                 continue;
230               SalomeApp_Study* aStudy = VISU::GetAppStudy(theModule);
231               VISU::TObjectInfo anObjectInfo = VISU::GetObjectByEntry(aStudy, anIO->getEntry());
232               if(_PTR(SObject) aSObject = anObjectInfo.mySObject){
233                 _PTR(GenericAttribute) anAttr;
234                 if (aSObject->FindAttribute(anAttr, "AttributeName")) {
235                   _PTR(AttributeName) aName(anAttr);
236                   QString strIn(aName->Value().c_str());
237                   aPrsNames.append(strIn);
238                   myPointMapPrsMap[aPrs] = myOffsets.count();
239                   Offset aOffs;
240                   anActorBase->GetPosition(aOffs.myOffset);
241                   myOffsets.append(aOffs);
242                 }
243               }
244             }
245           }
246     }
247   }
248   myFieldLst->addItems(aPrsNames);
249   myFieldLst->setCurrentRow(0);
250 }
251
252 void ArrangeDlg::init()
253 {
254   setWindowTitle("Arrange Presentations");
255   setSizeGripEnabled( TRUE );
256
257   QVBoxLayout* aMainLayout = new QVBoxLayout(this);
258   aMainLayout->setMargin( 7 );
259   aMainLayout->setSpacing(5);
260
261   QButtonGroup* aBtnGrp = new QButtonGroup( this);
262   aBtnGrp->setExclusive(true);
263   //aMainLayout->addWidget(aBtnGrp);
264
265   QGroupBox* aBtnGB = new QGroupBox( this );
266   QHBoxLayout* aHBLay = new QHBoxLayout( aBtnGB );
267   aMainLayout->addWidget(aBtnGB);
268
269   QRadioButton* aAutoBtn = new QRadioButton("Auto", aBtnGB);
270   aHBLay->addWidget( aAutoBtn );
271   aBtnGrp->addButton(aAutoBtn, AutoMode);
272
273   QRadioButton* aManualBtn = new QRadioButton("Manual", aBtnGB);
274   aHBLay->addWidget( aManualBtn );
275   aBtnGrp->addButton(aManualBtn, ManualMode);
276
277   aAutoBtn->setChecked( true );
278
279   myStackWgt = new QStackedWidget(this);
280   aMainLayout->addWidget(myStackWgt);
281
282   //  AUTO Pane
283   QWidget* aAutoPane = new QWidget(myStackWgt);
284   QVBoxLayout* aAutoLay = new QVBoxLayout( aAutoPane );
285   aAutoLay->setSpacing(5);
286
287   // Axis Group
288   myAxisGrp = new QButtonGroup(aAutoPane);
289
290   QGroupBox* aAxisGB = new QGroupBox( "Axis", aAutoPane );
291   QHBoxLayout* aVBLay = new QHBoxLayout( aAxisGB );
292   aAutoLay->addWidget( aAxisGB );
293
294   QRadioButton* aXBtn = new QRadioButton("X",aAxisGB );
295   aVBLay->addWidget( aXBtn );
296   myAxisGrp->addButton(aXBtn, XAxis);
297
298   QRadioButton* aYBtn = new QRadioButton("Y",aAxisGB );
299   aVBLay->addWidget( aYBtn );
300   myAxisGrp->addButton(aYBtn, YAxis);
301
302   QRadioButton* aZBtn = new QRadioButton("Z",aAxisGB );
303   aVBLay->addWidget( aZBtn );
304   myAxisGrp->addButton(aZBtn, ZAxis);
305
306   aXBtn->setChecked( true );
307
308   //Distance Input
309   QWidget* aDistPane = new QWidget(aAutoPane);
310   QHBoxLayout* aHLay = new QHBoxLayout( aDistPane );
311   aHLay->setSpacing(5);
312   aHLay->addWidget( new QLabel("Relative Distance", aDistPane) );
313   myDistVal = new SalomeApp_DoubleSpinBox( aDistPane );
314   VISU::initSpinBox( myDistVal, -10., 10., 0.5, "length_precision" );  
315   myDistVal->setValue(1);
316   aHLay->addWidget( myDistVal );
317
318   aAutoLay->addWidget( aDistPane );
319
320   myStackWgt->insertWidget( AutoMode, aAutoPane);
321
322   // Manual Pane
323   QWidget* aManualPane = new QWidget(myStackWgt);
324   aHLay = new QHBoxLayout( aManualPane );
325   aHLay->setSpacing(10);
326
327   myFieldLst = new QListWidget(aManualPane);
328   aHLay->addWidget( myFieldLst );
329   connect( myFieldLst, SIGNAL( currentRowChanged(int) ),
330            this, SLOT( onFieldChange(int) ) );
331
332   QWidget* aCoordPane = new QWidget( aManualPane);
333   aHLay->addWidget( aCoordPane );
334   QGridLayout* aCoordLayout = new QGridLayout( aCoordPane );
335   aCoordLayout->setSpacing(5);
336
337   aCoordLayout->addWidget( new QLabel("X", aCoordPane), 0, 0 );
338   myCoord[0] = new SalomeApp_DoubleSpinBox(aCoordPane);
339   VISU::initSpinBox( myCoord[0], -MAXVAL, MAXVAL, 1., "length_precision" );
340   aCoordLayout->addWidget( myCoord[0], 0, 1 );
341
342   aCoordLayout->addWidget( new QLabel("Y", aCoordPane), 1, 0 );
343   myCoord[1] = new SalomeApp_DoubleSpinBox(aCoordPane);
344   VISU::initSpinBox( myCoord[1], -MAXVAL, MAXVAL, 1., "length_precision" );
345   aCoordLayout->addWidget( myCoord[1], 1, 1 );
346
347   aCoordLayout->addWidget( new QLabel("Z", aCoordPane), 2, 0 );
348   myCoord[2] = new SalomeApp_DoubleSpinBox(aCoordPane);
349   VISU::initSpinBox( myCoord[2], -MAXVAL, MAXVAL, 1., "length_precision" );
350   aCoordLayout->addWidget( myCoord[2], 2, 1 );
351
352   myStackWgt->insertWidget(ManualMode, aManualPane );
353
354   myStackWgt->setCurrentIndex(AutoMode);
355
356   connect(aBtnGrp, SIGNAL(buttonClicked(int)), myStackWgt, SLOT(setCurrentIndex(int)) );
357
358   SUIT_Study* aSUITStudy = myViewWindow->getViewManager()->study();
359   SalomeApp_Study* anAppStudy = dynamic_cast<SalomeApp_Study*>(aSUITStudy);
360   _PTR(Study) aCStudy = VISU::GetCStudy(anAppStudy);
361   if (!myAnimator && !aCStudy->GetProperties()->IsLocked()) {
362     mySaveChk = new QCheckBox ("Save to presentation", this);
363     mySaveChk->setChecked(false);
364     aMainLayout->addWidget(mySaveChk);
365   } else {
366     mySaveChk = 0;
367   }
368
369   // Common buttons ===========================================================
370   QGroupBox* GroupButtons = new QGroupBox( this );
371   //GroupButtons->setColumnLayout(0, Qt::Vertical );
372   //GroupButtons->layout()->setSpacing( 0 );
373   //GroupButtons->layout()->setMargin( 0 );
374   QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons );
375   GroupButtonsLayout->setAlignment( Qt::AlignTop );
376   GroupButtonsLayout->setSpacing( 6 );
377   GroupButtonsLayout->setMargin( 11 );
378
379   QPushButton* buttonOk = new QPushButton( tr( "&OK" ), GroupButtons );
380   buttonOk->setAutoDefault( TRUE );
381   buttonOk->setDefault( TRUE );
382   GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
383   GroupButtonsLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
384
385   QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ) , GroupButtons );
386   buttonCancel->setAutoDefault( TRUE );
387   GroupButtonsLayout->addWidget( buttonCancel, 0, 2 );
388
389   aMainLayout->addWidget( GroupButtons );
390
391   connect( buttonOk,     SIGNAL( clicked() ),      this, SLOT( accept() ) );
392   connect( buttonCancel, SIGNAL( clicked() ),      this, SLOT( reject() ) );
393 }
394
395 void ArrangeDlg::accept()
396 {
397   if (myAnimator != NULL) {
398     acceptAnimation();
399   } else {
400     acceptViewWindow();
401   }
402   QDialog::accept();
403 }
404
405 void ArrangeDlg::onFieldChange(int theCurrent)
406 {
407   if (myCurrent != theCurrent) {
408     Offset& aOffs = myOffsets[myCurrent];
409     aOffs.myOffset[0] = myCoord[0]->value();
410     aOffs.myOffset[1] = myCoord[1]->value();
411     aOffs.myOffset[2] = myCoord[2]->value();
412   }
413   myCurrent = theCurrent;
414   const Offset& aNewOffs = myOffsets[myCurrent];
415   myCoord[0]->setValue(aNewOffs.myOffset[0]);
416   myCoord[1]->setValue(aNewOffs.myOffset[1]);
417   myCoord[2]->setValue(aNewOffs.myOffset[2]);
418 }
419
420 void ArrangeDlg::acceptAnimation()
421 {
422   if (getMode() == ManualMode) {
423     // Save from GUI
424     Offset& aOffs = myOffsets[myCurrent];
425     aOffs.myOffset[0] = myCoord[0]->value();
426     aOffs.myOffset[1] = myCoord[1]->value();
427     aOffs.myOffset[2] = myCoord[2]->value();
428
429     for (int i = 0; i < myAnimator->getNbFields(); i++) {
430       Offset aOffs = myOffsets[i];
431       myAnimator->getFieldData(i).myOffset[0] = aOffs.myOffset[0];
432       myAnimator->getFieldData(i).myOffset[1] = aOffs.myOffset[1];
433       myAnimator->getFieldData(i).myOffset[2] = aOffs.myOffset[2];
434     }
435   } else {
436     QApplication::setOverrideCursor( Qt::WaitCursor );
437     FieldData& aData = myAnimator->getFieldData(myFieldLst->currentRow());
438     if (aData.myPrs.empty())
439       GeneratePresentations(myFieldLst->currentRow(),myAnimator);
440     vtkFloatingPointType aBounds[6];
441     aData.myPrs[0]->GetBounds(aBounds);
442     vtkFloatingPointType aDist = 0;
443     int aAxis = getAxis();
444     switch (aAxis) {
445     case XAxis:
446       aDist = fabs(aBounds[1] - aBounds[0]);
447       break;
448     case YAxis:
449       aDist = fabs(aBounds[3] - aBounds[2]);
450       break;
451     case ZAxis:
452       aDist = fabs(aBounds[5] - aBounds[4]);
453     }
454
455     vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
456     vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
457     vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
458     vtkFloatingPointType max = (dx > dy) ? dx : dy;
459     max = (dz > max) ? dz : max;
460     max /= 100.0;
461
462     if (aDist < max) {
463       // set base distance between centers of bounding boxes
464       // to minimal (but big enough) size of current bounding box
465       if (dx < max) dx = FLT_MAX;
466       if (dy < max) dy = FLT_MAX;
467       if (dz < max) dz = FLT_MAX;
468
469       aDist = (dx < dy) ? dx : dy;
470       aDist = (dz < aDist) ? dz : aDist;
471     }
472     aDist = aDist * getDistance();
473     for (int i = 0; i < myAnimator->getNbFields(); i++) {
474       myAnimator->getFieldData(i).myOffset[0] = 0;
475       myAnimator->getFieldData(i).myOffset[1] = 0;
476       myAnimator->getFieldData(i).myOffset[2] = 0;
477       myAnimator->getFieldData(i).myOffset[aAxis] = aDist * i;
478     }
479
480     QApplication::restoreOverrideCursor();
481   }
482 }
483
484 void ArrangeDlg::acceptViewWindow()
485 {
486   if (getMode() == ManualMode) {
487     // Save from GUI
488     Offset& aOffs = myOffsets[myCurrent];
489     aOffs.myOffset[0] = myCoord[0]->value();
490     aOffs.myOffset[1] = myCoord[1]->value();
491     aOffs.myOffset[2] = myCoord[2]->value();
492
493     QMap<VISU::Prs3d_i*, int>::Iterator it;
494     for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it) {
495       VISU::Prs3d_i* aPrs = it.key();
496       Offset& aOffs = myOffsets[it.value()];
497       if (VISU_Actor* anActor = VISU::FindActor(myViewWindow, aPrs))
498         anActor->SetPosition(aOffs.myOffset);
499       if (mySaveChk)
500         if (mySaveChk->isChecked())
501           aPrs->SetOffset(aOffs.myOffset[0],aOffs.myOffset[1],aOffs.myOffset[2]);
502     }
503     QMap<VISU::PointMap3d_i*, int>::Iterator itt;
504     for (itt = myPointMapPrsMap.begin(); itt != myPointMapPrsMap.end(); ++itt) {
505       VISU::PointMap3d_i* aPrs = itt.key();
506       Offset& aOffs = myOffsets[itt.value()];
507       if (VISU_ActorBase* anActor = VISU::FindActorBase(myViewWindow, aPrs))
508         anActor->SetPosition(aOffs.myOffset);
509       if (mySaveChk)
510         if (mySaveChk->isChecked())
511           aPrs->SetOffset(aOffs.myOffset[0],aOffs.myOffset[1],aOffs.myOffset[2]);
512     }
513   } else {
514     vtkFloatingPointType aDist = 0;
515     vtkFloatingPointType aShift = 0;
516     vtkFloatingPointType aPrevDist = 0;
517     vtkFloatingPointType aPrevShift = 0;
518     int i = 0;
519     QMap<VISU::Prs3d_i*, int>::Iterator it;
520     for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it, i++) {
521       VISU::Prs3d_i* aPrs = it.key();
522       if (VISU_Actor* aActor = VISU::FindActor(myViewWindow, aPrs)) {
523         int aAxis = getAxis();
524
525         vtkFloatingPointType aZeroOffset[3];
526         aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
527         aActor->SetPosition(aZeroOffset);
528         aActor->GetMapper()->Update();
529
530         vtkFloatingPointType aBounds[6];
531         aActor->GetBounds(aBounds);
532         switch (aAxis) {
533         case XAxis:
534           aDist = fabs(aBounds[1] - aBounds[0]);
535           break;
536         case YAxis:
537           aDist = fabs(aBounds[3] - aBounds[2]);
538           break;
539         case ZAxis:
540           aDist = fabs(aBounds[5] - aBounds[4]);
541         }
542         vtkFloatingPointType aOffset[3];
543         aOffset[0] = aOffset[1] = aOffset[2] = 0;
544         aOffset[aAxis] =
545           (aBounds[2*aAxis+1] < aBounds[2*aAxis]) ? -aBounds[2*aAxis+1] : -aBounds[2*aAxis];
546
547         if (i > 0) {
548           vtkFloatingPointType aCCDist = (aDist + aPrevDist) / 2.0;
549
550           vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
551           vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
552           vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
553           vtkFloatingPointType max = (dx > dy) ? dx : dy;
554           max = (dz > max) ? dz : max;
555           max /= 100.0;
556
557           if (aCCDist < max) {
558             // set base distance between centers of bounding boxes
559             // to minimal (but big enough) size of current bounding box
560             if (dx < max) dx = FLT_MAX;
561             if (dy < max) dy = FLT_MAX;
562             if (dz < max) dz = FLT_MAX;
563
564             aCCDist = (dx < dy) ? dx : dy;
565             aCCDist = (dz < aCCDist) ? dz : aCCDist;
566           }
567
568           //-------------------------------->
569           //             aShift
570           //                                 aDist / 2
571           //                                 <-->
572           //            .--------------.     .------.
573           //----------->|              |     |      |
574           // aPrevShift '--------------'     '------'
575           //            <------>
576           //            aPrevDist / 2
577           //
578           //                    <--------------->
579           //                    (aDist + aPrevDist) * getDistance() / 2
580
581           aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
582         }
583
584         aOffset[aAxis] += aShift;
585         aActor->SetPosition(aOffset);
586         if (mySaveChk)
587           if (mySaveChk->isChecked())
588             aPrs->SetOffset(aOffset[0],aOffset[1],aOffset[2]);
589
590         aPrevDist = aDist;
591         aPrevShift = aShift;
592       }
593     } // end of myPrsMap loop
594     // Loop in PointMap3D the same as previous loop
595     QMap<VISU::PointMap3d_i*, int>::Iterator itt;
596     for (itt = myPointMapPrsMap.begin(); itt != myPointMapPrsMap.end(); ++itt, i++) {
597       VISU::PointMap3d_i* aPrs = itt.key();
598       if (VISU_ActorBase* aActor = VISU::FindActorBase(myViewWindow, aPrs)) {
599         int aAxis = getAxis();
600
601         vtkFloatingPointType aZeroOffset[3];
602         aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
603         aActor->SetPosition(aZeroOffset);
604         aActor->GetMapper()->Update();
605
606         vtkFloatingPointType aBounds[6];
607         aActor->GetBounds(aBounds);
608         switch (aAxis) {
609         case XAxis:
610           aDist = fabs(aBounds[1] - aBounds[0]);
611           break;
612         case YAxis:
613           aDist = fabs(aBounds[3] - aBounds[2]);
614           break;
615         case ZAxis:
616           aDist = fabs(aBounds[5] - aBounds[4]);
617         }
618         vtkFloatingPointType aOffset[3];
619         aOffset[0] = aOffset[1] = aOffset[2] = 0;
620         aOffset[aAxis] =
621           (aBounds[2*aAxis+1] < aBounds[2*aAxis]) ? -aBounds[2*aAxis+1] : -aBounds[2*aAxis];
622
623         if (i > 0) {
624           vtkFloatingPointType aCCDist = (aDist + aPrevDist) / 2.0;
625
626           vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
627           vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
628           vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
629           vtkFloatingPointType max = (dx > dy) ? dx : dy;
630           max = (dz > max) ? dz : max;
631           max /= 100.0;
632
633           if (aCCDist < max) {
634             // set base distance between centers of bounding boxes
635             // to minimal (but big enough) size of current bounding box
636             if (dx < max) dx = FLT_MAX;
637             if (dy < max) dy = FLT_MAX;
638             if (dz < max) dz = FLT_MAX;
639
640             aCCDist = (dx < dy) ? dx : dy;
641             aCCDist = (dz < aCCDist) ? dz : aCCDist;
642           }
643           aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
644         }
645
646         aOffset[aAxis] += aShift;
647         aActor->SetPosition(aOffset);
648         if (mySaveChk)
649           if (mySaveChk->isChecked())
650             aPrs->SetOffset(aOffset[0],aOffset[1],aOffset[2]);
651
652         aPrevDist = aDist;
653         aPrevShift = aShift;
654       }
655     } // end of myPointMapPrsMap loop
656   }
657   myViewWindow->getRenderer()->ResetCameraClippingRange();
658   myViewWindow->Repaint();
659 }
660
661
662 //------------------------------------------------------------------------
663 //------------------------------------------------------------------------
664
665 class SetupDlg::LineEdit : public QLineEdit
666 {
667 public:
668   LineEdit( QWidget* p = 0 ) : QLineEdit( p ) {}
669   virtual ~LineEdit() {}
670
671 protected:
672   void    focusOutEvent( QFocusEvent* e )
673   {
674     QLineEdit::focusOutEvent( e );
675
676     if ( text().isEmpty() )
677       emit editingFinished();
678   }
679   void    keyPressEvent( QKeyEvent* e )
680   {
681     QLineEdit::keyPressEvent( e );
682
683     if ( text().isEmpty() && e->key() == Qt::Key_Return )
684       emit returnPressed();
685   }
686 };
687
688
689 //------------------------------------------------------------------------
690 //------------------------------------------------------------------------
691
692 SetupDlg::SetupDlg (QWidget* theParent,
693                     VisuGUI* theModule,
694                     VISU_TimeAnimation* theAnimator) :
695   QDialog(theParent,
696           Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
697   myAnimator(theAnimator),
698   myModule(theModule),
699   myIsRegenerate( false )
700 {
701   setModal( true );
702   setWindowTitle("Setup Animation");
703   setSizeGripEnabled( TRUE );
704
705   QVBoxLayout* aMainLayout = new QVBoxLayout(this);
706   aMainLayout->setMargin( 7 );
707   aMainLayout->setSpacing(5);
708
709   // Range of time stamps
710   myUseRangeBox = new QGroupBox("Use range of time stamps", this);
711   myUseRangeBox->setCheckable( true );
712   myUseRangeBox->setChecked(myAnimator->isRangeDefined());
713
714   QHBoxLayout* aRangeLayout = new QHBoxLayout( myUseRangeBox );
715   aRangeLayout->setMargin( 11 );
716   aRangeLayout->setSpacing( 6 );
717
718   double aMaxTime = myAnimator->getMaxTime();
719   double aMinTime = myAnimator->getMinTime();
720   double aStep = 1;
721   if( myAnimator->getNbFields() > 0 ) {
722     if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL )
723       aStep = (aMaxTime - aMinTime) / (myAnimator->getFieldData(0).myNbTimes - 1);
724     else { // successive animation mode
725       std::pair<int,long> aLastFieldFrame(myAnimator->getNbFields() - 1,
726                                           myAnimator->getFieldData(myAnimator->getNbFields() - 1).myNbTimes - 1);
727       aStep = (aMaxTime - aMinTime) / myAnimator->getAbsoluteFrameNumber(aLastFieldFrame);
728     }
729   }
730
731   QLabel* aMinLbl = new QLabel("From", myUseRangeBox);
732   aRangeLayout->addWidget(aMinLbl);
733   //myMinVal = new SalomeApp_DoubleSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
734   //VISU::initSpinBox( myMinVal, aMinTime, aMaxTime, aStep, "visual_data_precision" );
735   myMinVal = new LineEdit( myUseRangeBox );
736   myMinVal->setValidator( new QDoubleValidator( myMinVal ) );
737   if ( myUseRangeBox->isChecked() )
738     myMinVal->setText( QString::number( myAnimator->getMinRange() ) );
739   else
740     myMinVal->setText( QString::number( aMinTime ) );
741
742   //  connect(myMinVal, SIGNAL( valueChanged(double)),
743   //      this, SLOT( onMinValue(double) ));
744   connect( myMinVal, SIGNAL( returnPressed() ), this, SLOT( onMinValue() ) );
745   connect( myMinVal, SIGNAL( editingFinished() ), this, SLOT( onMinValue() ) );
746 //   connect( myMinVal, SIGNAL( textChanged(const QString&)),
747 //        this, SLOT( onMinValueEdit(const QString&) ));
748   aRangeLayout->addWidget(myMinVal);
749
750   QLabel* aMaxLbl = new QLabel("To", myUseRangeBox);
751   aRangeLayout->addWidget(aMaxLbl);
752   //myMaxVal = new SalomeApp_DoubleSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
753   //VISU::initSpinBox( myMaxVal, aMinTime, aMaxTime, aStep, "visual_data_precision" );
754   myMaxVal = new LineEdit( myUseRangeBox );
755   myMaxVal->setValidator( new QDoubleValidator( myMaxVal ) );
756   if ( myUseRangeBox->isChecked() )
757     myMaxVal->setText( QString::number( myAnimator->getMaxRange() ) );
758   else
759     myMaxVal->setText( QString::number( aMaxTime ) );
760
761   //  connect(myMaxVal, SIGNAL( valueChanged(double)),
762   //      this, SLOT( onMaxValue(double) ));
763   connect( myMaxVal, SIGNAL( returnPressed() ), this, SLOT( onMaxValue() ) );
764   connect( myMaxVal, SIGNAL( editingFinished() ), this, SLOT( onMaxValue() ) );
765 //   connect(myMaxVal, SIGNAL( textChanged(const QString&)),
766 //        this, SLOT( onMaxValueEdit(const QString&) ));
767   aRangeLayout->addWidget(myMaxVal);
768
769   connect(myUseRangeBox, SIGNAL( toggled(bool)),
770           this, SLOT( onRangeCheck(bool) ));
771
772   aMainLayout->addWidget(myUseRangeBox);
773
774   // Sequence of time stamps
775   myUseSequenceBox = new QGroupBox("Use sequence of time stamps", this);
776   myUseSequenceBox->setCheckable( true );
777   myUseSequenceBox->setChecked( myAnimator->isSequenceDefined() );
778
779   QGridLayout* aUseSequenceLayout = new QGridLayout( myUseSequenceBox );
780   aUseSequenceLayout->setAlignment( Qt::AlignTop );
781   aUseSequenceLayout->setSpacing( 6 );
782   aUseSequenceLayout->setMargin( 11 );
783
784   QLabel* anIndicesLbl = new QLabel("Indices", myUseSequenceBox);
785   myIndices = new QLineEdit( myUseSequenceBox );
786
787   myValues = new QListWidget( myUseSequenceBox );
788   myValues->setSelectionMode( QAbstractItemView::ExtendedSelection );
789
790   connect(myIndices, SIGNAL( textChanged(const QString&)),
791           this, SLOT( onIndicesChanged(const QString&) ));
792
793   connect(myValues, SIGNAL( itemSelectionChanged() ),
794           this, SLOT( onValuesChanged() ) );
795
796   connect(myUseSequenceBox, SIGNAL( toggled(bool)),
797           this, SLOT( onSequenceCheck(bool) ));
798
799   aUseSequenceLayout->addWidget( anIndicesLbl, 0, 0 );
800   aUseSequenceLayout->addWidget( myIndices, 0, 1 );
801   aUseSequenceLayout->addWidget( myValues, 1, 1, 1, 2 );
802
803   aMainLayout->addWidget(myUseSequenceBox);
804
805   // Fields and Properties
806   QWidget* aPropFrame = new QWidget(this);
807   QHBoxLayout* aHPropLayout = new QHBoxLayout( aPropFrame );
808   aHPropLayout->setSpacing(5);
809   aHPropLayout->setMargin(0);
810
811   QGroupBox* aNamesBox = new QGroupBox("Fields",aPropFrame);
812   aHPropLayout->addWidget( aNamesBox );
813   QVBoxLayout* aVBoxLayout = new QVBoxLayout( aNamesBox );
814
815   myFieldLst = new QListWidget(aNamesBox);
816   aVBoxLayout->addWidget( myFieldLst );
817   QStringList aFieldNames;
818   // Find names of fields
819   for (int i = 0; i < myAnimator->getNbFields(); i++) {
820     _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
821     VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSO);
822     QString aFieldName(aRestoringMap["myName"]);
823     if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL )
824       aFieldNames.append(aFieldName);
825     else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
826       _PTR(SObject) aSObject = aSO->GetFather()->GetFather()->GetFather();
827       VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
828       QString aFileName(aRestoringMap["myInitFileName"]);
829       aFileName = aFileName.right(aFileName.length() - (aFileName.lastIndexOf("/") + 1));
830       aFieldNames.append(aFileName + QString(" : ") + aFieldName);
831     }
832   }
833   myFieldLst->addItems(aFieldNames);
834
835   if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) {
836     myFieldLst->setCurrentRow(0);
837     connect( myFieldLst, SIGNAL( currentRowChanged(int) ),
838              this, SLOT( onFieldChange(int) ) );
839   }
840   else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE )
841     myFieldLst->setSelectionMode(QAbstractItemView::NoSelection);
842
843   QWidget* aSetupBox = new QWidget(aPropFrame);
844   aHPropLayout->addWidget( aSetupBox );
845   aVBoxLayout = new QVBoxLayout( aSetupBox );
846   aVBoxLayout->setSpacing(5);
847   aVBoxLayout->setMargin(0);
848
849   QGroupBox* aPropBox = new QGroupBox("Properties", aSetupBox);
850   aVBoxLayout->addWidget( aPropBox );
851   QVBoxLayout* aPropVBLay = new QVBoxLayout( aPropBox );
852
853   //QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
854   myTypeCombo = new QComboBox(aPropBox);
855   aPropVBLay->addWidget( myTypeCombo );
856   connect( myTypeCombo, SIGNAL( activated(int) ),
857            this, SLOT( onTypeChanged(int) ) );
858
859   //  QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
860   //connect( aBarBtn, SIGNAL( clicked() ),
861   //       this, SLOT( onScalarBarDlg() ) );
862
863   myPropBtn = new QPushButton("Properties...", aPropBox);
864   myPropBtn->setAutoDefault( false );
865   aPropVBLay->addWidget( myPropBtn );
866   //  myPropBtn->setEnabled(myAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
867   connect( myPropBtn, SIGNAL( clicked() ),
868            this, SLOT( onPreferencesDlg() ) );
869
870   if (myAnimator->getNbFields() > 1 ) {
871     if( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) {
872       myArrangeBtn = new QPushButton("Arrange...", aSetupBox);
873       aVBoxLayout->addWidget( myArrangeBtn );
874       connect( myArrangeBtn, SIGNAL( clicked() ), this, SLOT( onArrangeDlg() ) );
875     }
876   }
877   onFieldChange(0);
878   aMainLayout->addWidget(aPropFrame);
879
880   QWidget* aBtnBox = new QWidget(this);
881   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox);
882   aBtnLayout->setContentsMargins( 5, 5, 0, 5 );
883   //  aBtnLayout->addStretch();
884
885   QPushButton* closeBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
886   closeBtn->setAutoDefault( false );
887   aBtnLayout->addStretch();
888   aBtnLayout->addWidget( closeBtn );
889   connect( closeBtn, SIGNAL( clicked() ), this, SLOT( onClose() ) );
890
891   aMainLayout->addWidget( aBtnBox );
892 }
893
894 //------------------------------------------------------------------------
895 void SetupDlg::initialize()
896 {
897   myValues->clear();
898
899   _PTR(Study) aStudy = myAnimator->getStudy();
900
901   if( myAnimator->getNbFields() == 0 )
902     return;
903
904   FieldData& aData = myAnimator->getFieldData( 0 );
905   _PTR(SObject) aField = aData.myField;
906
907   if ( !aField )
908     return;
909
910   _PTR(ChildIterator) anIter = aStudy->NewChildIterator(aField);
911   anIter->Next(); // First is reference on support
912   for(int index = 1; anIter->More(); anIter->Next(), index++)
913   {
914     double aTime = VISU_TimeAnimation::getTimeValue(anIter->Value());
915     QString itemText = QString("[%1] - %2").arg( index ).arg( aTime );
916
917     myValues->addItem( itemText );
918   }
919
920   QString anIndices( myAnimator->getAnimationSequence() );
921   myIndices->setText( anIndices );
922 }
923
924 //------------------------------------------------------------------------
925 enum PrsComboItem {
926   TSCALARMAP_ITEM     = 0, // VISU::TSCALARMAP
927   TISOSURFACES_ITEM   = 1, // VISU::TISOSURFACES
928   TCUTPLANES_ITEM     = 2, // VISU::TCUTPLANES
929   TCUTLINES_ITEM      = 3, // VISU::TCUTLINES
930   TCUTSEGMENT_ITEM    = 4, // VISU::TCUTSEGMENT
931   TPLOT3D_ITEM        = 5, // VISU::TPLOT3D
932   TDEFORMEDSHAPE_ITEM = 6, // VISU::TDEFORMEDSHAPE
933   TVECTORS_ITEM       = 7, // VISU::TVECTORS
934   TSTREAMLINES_ITEM   = 8, // VISU::TSTREAMLINES
935   TGAUSSPOINTS_ITEM   = 9, // VISU::TGAUSSPOINTS
936   TDEFORMEDSHAPEANDSCALARMAP_ITEM = 10 // VISU::TDEFORMEDSHAPEANDSCALARMAP
937 };
938
939 //------------------------------------------------------------------------
940 void SetupDlg::onClose()
941 {
942   if ( !myUseRangeBox->isChecked() )
943     myAnimator->setAnimationRange( 0, 0 );
944   else
945   {
946     double min = myMinVal->text().toDouble();
947     double max = myMaxVal->text().toDouble();
948     myAnimator->setAnimationRange( qMin( min, max ), qMax( min, max ) );
949   }
950
951   if ( !myUseSequenceBox->isChecked() )
952     myAnimator->setAnimationSequence( 0 );
953
954   close();
955 }
956
957 //------------------------------------------------------------------------
958 void SetupDlg::onFieldChange (int theIndex)
959 {
960   myTypeCombo->clear();
961   myTypeId2ComboId.clear();
962   myComboId2TypeId.clear();
963
964   if( myAnimator->getNbFields() == 0 )
965     return;
966
967   // ATTENTION: append items in the same order like it is done in the PrsComboItem enumeration
968   myTypeCombo->addItem("Scalar Map");   // item 0
969   myTypeId2ComboId[TSCALARMAP_ITEM] = myComboId2TypeId.size();
970   myComboId2TypeId.push_back(TSCALARMAP_ITEM);;
971
972   myTypeCombo->addItem("Iso Surfaces"); // item 1
973   myTypeId2ComboId[TISOSURFACES_ITEM] = myComboId2TypeId.size();
974   myComboId2TypeId.push_back(TISOSURFACES_ITEM);;
975
976   myTypeCombo->addItem("Cut Planes");   // item 2
977   myTypeId2ComboId[TCUTPLANES_ITEM] = myComboId2TypeId.size();
978   myComboId2TypeId.push_back(TCUTPLANES_ITEM);;
979
980   myTypeCombo->addItem("Cut Lines");   // item 3
981   myTypeId2ComboId[TCUTLINES_ITEM] = myComboId2TypeId.size();
982   myComboId2TypeId.push_back(TCUTLINES_ITEM);;
983
984   myTypeCombo->addItem("Cut Segment");  // item 4
985   myTypeId2ComboId[TCUTSEGMENT_ITEM] = myComboId2TypeId.size();
986   myComboId2TypeId.push_back(TCUTSEGMENT_ITEM);;
987
988   myTypeCombo->addItem("Plot 3D");      // item 5
989   myTypeId2ComboId[TPLOT3D_ITEM] = myComboId2TypeId.size();
990   myComboId2TypeId.push_back(TPLOT3D_ITEM);;
991
992   bool anEnableItems = false;
993   bool anEnableGP = false;
994   VISU::VISUType aPrsType;
995   if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) { // parallel animation mode
996
997     FieldData& aData = myAnimator->getFieldData(theIndex);
998     _PTR(SObject) aSObject = aData.myField;
999     VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
1000     long aNumComp = aRestoringMap["myNumComponent"].toLong();
1001     anEnableItems = (aNumComp > 1);
1002
1003     long anEntityId = aRestoringMap["myEntityId"].toLong();
1004     anEnableGP = (anEntityId == VISU::CELL);
1005
1006     aPrsType = aData.myPrsType;
1007
1008   }
1009   else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) { // successive animation mode
1010
1011     for (int i = 0; i < myAnimator->getNbFields(); i++) {
1012       _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
1013       VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSO);
1014       long aNumComp = aRestoringMap["myNumComponent"].toLong();
1015       anEnableItems = (aNumComp > 1);
1016
1017       long anEntityId = aRestoringMap["myEntityId"].toLong();
1018       anEnableGP = (anEntityId == VISU::CELL);
1019
1020       if ( !anEnableItems && !anEnableGP ) break;
1021     }
1022
1023     aPrsType = myAnimator->getFieldData(0).myPrsType;
1024
1025   }
1026
1027   if (anEnableItems) {
1028     myTypeCombo->addItem("Deformed Shape"); // item 6
1029     myTypeId2ComboId[TDEFORMEDSHAPE_ITEM] = myComboId2TypeId.size();
1030     myComboId2TypeId.push_back(TDEFORMEDSHAPE_ITEM);;
1031
1032     myTypeCombo->addItem("Vectors");        // item 7
1033     myTypeId2ComboId[TVECTORS_ITEM] = myComboId2TypeId.size();
1034     myComboId2TypeId.push_back(TVECTORS_ITEM);;
1035
1036     myTypeCombo->addItem("Stream Lines");   // item 8
1037     myTypeId2ComboId[TSTREAMLINES_ITEM] = myComboId2TypeId.size();
1038     myComboId2TypeId.push_back(TSTREAMLINES_ITEM);;
1039
1040     myTypeCombo->addItem("Deformed shape and Scalar map");   // item 10
1041     myTypeId2ComboId[TDEFORMEDSHAPEANDSCALARMAP_ITEM] = myComboId2TypeId.size();
1042     myComboId2TypeId.push_back(TDEFORMEDSHAPEANDSCALARMAP_ITEM);;
1043   }
1044
1045   if(anEnableGP){
1046     myTypeCombo->addItem("Gauss Points");   // item 9
1047     myTypeId2ComboId[TGAUSSPOINTS_ITEM] = myComboId2TypeId.size();
1048     myComboId2TypeId.push_back(TGAUSSPOINTS_ITEM);;
1049   }
1050
1051   switch (aPrsType) {
1052   case VISU::TSCALARMAP: //Scalar Map
1053     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TSCALARMAP_ITEM]);
1054     break;
1055   case VISU::TISOSURFACES: //Iso Surfaces
1056     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TISOSURFACES_ITEM]);
1057     break;
1058   case VISU::TCUTPLANES: //Cut Planes
1059     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TCUTPLANES_ITEM]);
1060     break;
1061   case VISU::TCUTLINES: //Cut Lines
1062     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TCUTLINES_ITEM]);
1063     break;
1064   case VISU::TCUTSEGMENT: //Cut Segment
1065     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TCUTSEGMENT_ITEM]);
1066     break;
1067   case VISU::TPLOT3D: //Plot 3D
1068     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TPLOT3D_ITEM]);
1069     break;
1070   case VISU::TDEFORMEDSHAPE: //Deformed Shape
1071     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TDEFORMEDSHAPE_ITEM]);
1072     break;
1073   case VISU::TSCALARMAPONDEFORMEDSHAPE: //Scalar Map on Deformed Shape
1074   case VISU::TDEFORMEDSHAPEANDSCALARMAP:
1075     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TDEFORMEDSHAPEANDSCALARMAP_ITEM]);
1076     break;
1077   case VISU::TVECTORS: //Vectors
1078     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TVECTORS_ITEM]);
1079     break;
1080   case VISU::TSTREAMLINES: //Stream Lines
1081     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TSTREAMLINES_ITEM]);
1082     break;
1083   case VISU::TGAUSSPOINTS: //Gauss Points
1084     myTypeCombo->setCurrentIndex(myTypeId2ComboId[TGAUSSPOINTS_ITEM]);
1085     break;
1086   }
1087   //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
1088 }
1089
1090 //------------------------------------------------------------------------
1091 void SetupDlg::onTypeChanged (int theIndex)
1092 {
1093   int aType = myComboId2TypeId[theIndex];
1094
1095   for (int i = 0; i < myAnimator->getNbFields(); i++) {
1096     FieldData& aData = ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) ?
1097       myAnimator->getFieldData(myFieldLst->currentRow()) :
1098       myAnimator->getFieldData(i);
1099
1100     switch (aType) {
1101     case TSCALARMAP_ITEM: //Scalar Map
1102       aData.myPrsType = VISU::TSCALARMAP;
1103       break;
1104     case TISOSURFACES_ITEM: //Iso Surfaces
1105       aData.myPrsType = VISU::TISOSURFACES;
1106       break;
1107     case TCUTPLANES_ITEM: //Cut Planes
1108       aData.myPrsType = VISU::TCUTPLANES;
1109       break;
1110     case TCUTLINES_ITEM: //Cut Lines
1111       aData.myPrsType = VISU::TCUTLINES;
1112       break;
1113     case TCUTSEGMENT_ITEM: //Cut Segment
1114       aData.myPrsType = VISU::TCUTSEGMENT;
1115       break;
1116     case TPLOT3D_ITEM: //Plot 3D
1117       aData.myPrsType = VISU::TPLOT3D;
1118       break;
1119     case TDEFORMEDSHAPE_ITEM: //Deformed Shape
1120       aData.myPrsType = VISU::TDEFORMEDSHAPE;
1121       break;
1122     case TDEFORMEDSHAPEANDSCALARMAP_ITEM: //Scalar Map on Deformed Shape
1123       aData.myPrsType = VISU::TDEFORMEDSHAPEANDSCALARMAP;
1124       break;
1125     case TVECTORS_ITEM: //Vectors
1126       aData.myPrsType = VISU::TVECTORS;
1127       break;
1128     case TSTREAMLINES_ITEM: //Stream Lines
1129       aData.myPrsType = VISU::TSTREAMLINES;
1130       break;
1131     case TGAUSSPOINTS_ITEM: //Gauss Points
1132       aData.myPrsType = VISU::TGAUSSPOINTS;
1133       break;
1134     }
1135     myAnimator->clearData(aData);
1136
1137     if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) // parallel animation mode
1138       break;
1139   }
1140   //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
1141   //myAnimator->generatePresentations(myFieldLst->currentItem());
1142 }
1143
1144
1145 //------------------------------------------------------------------------
1146 namespace
1147 {
1148   template<class TPrs3d, class TDialog>
1149   void
1150   EditPrs(VisuGUI* theModule,
1151           FieldData& theData,
1152           VISU_TimeAnimation* theAnimator)
1153   {
1154     TDialog* aDlg = new TDialog(theModule);
1155     TPrs3d* aPrs3d = dynamic_cast<TPrs3d*>(theData.myPrs[0]);
1156     aDlg->initFromPrsObject(aPrs3d, true);
1157     if (aDlg->exec() && aDlg->storeToPrsObject(dynamic_cast<TPrs3d*>(aPrs3d))) {
1158
1159       for (long aFrameId = 1; aFrameId < theData.myNbFrames; aFrameId++){
1160         VISU::ColoredPrs3d_i* aColoredPrs3d = theData.myPrs[aFrameId];
1161         aColoredPrs3d->SameAs(aPrs3d);
1162         // rnv: fix for the 20870: EDF 1410 VISU: Anomaly in the Gauss point representation.
1163         // special case for the "Gauss Points" presentation,
1164         // update the LookupTable in the mapper, after assign properties of the presentation
1165         // using SameAs(...) method.
1166         if(theData.myPrsType == VISU::TGAUSSPOINTS) {
1167           aColoredPrs3d->UpdateMapperLookupTable();
1168         }
1169       }
1170
1171       if ( theAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1172         for (int aFieldId = 1; aFieldId < theAnimator->getNbFields(); aFieldId++) {
1173           FieldData& aFieldData = theAnimator->getFieldData(aFieldId);
1174           for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1175             VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
1176             std::string aTitle = aColoredPrs3d->GetCTitle();
1177             aColoredPrs3d->SameAs(aPrs3d);          
1178             // rnv: fix for the 20870: EDF 1410 VISU: Anomaly in the Gauss point representation.
1179             // special case for the "Gauss Points" presentation,
1180             // update the LookupTable in the mapper, after assign properties of the presentation
1181             // using SameAs(...) method.
1182             if(theData.myPrsType == VISU::TGAUSSPOINTS) {
1183               aColoredPrs3d->UpdateMapperLookupTable();
1184             }
1185
1186             aColoredPrs3d->SetTitle(aTitle.c_str());
1187           }
1188         }
1189       }
1190     }
1191     delete aDlg;
1192   }
1193 }
1194
1195
1196 void SetupDlg::onPreferencesDlg()
1197 {
1198   if(myAnimator->getNbFields() == 0){
1199     SUIT_MessageBox::warning(this,
1200                            tr("ERROR"),
1201                            VisuGUI_TimeAnimationDlg::tr("MSG_NO_ANIMATIONDATA"),
1202                            tr("&OK"));
1203     return;
1204   }
1205
1206   SUIT_OverrideCursor c;
1207
1208   VISU::Animation::AnimationMode aMode = myAnimator->getAnimationMode();
1209   int aRefFieldId = ( aMode == VISU::Animation::PARALLEL ) ? myFieldLst->currentRow() : 0;
1210   FieldData& aData = myAnimator->getFieldData(aRefFieldId);
1211   if (aData.myPrs.empty())
1212     myAnimator->generatePresentations(aRefFieldId);
1213
1214   if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1215     for (int i = 0; i < myAnimator->getNbFields(); i++) {
1216       if ( i != aRefFieldId && myAnimator->getFieldData(i).myPrs.empty() )
1217         myAnimator->generatePresentations(i);
1218     }
1219   }
1220
1221   if(!aData.myNbFrames || aData.myPrs.empty() || !aData.myPrs[0]){
1222     QApplication::restoreOverrideCursor();
1223     SUIT_MessageBox::warning(this,
1224                            tr("ERROR"),
1225                            VisuGUI_TimeAnimationDlg::tr("MSG_NO_ANIMATIONDATA"),
1226                            tr("&OK"));
1227     return;
1228   }
1229
1230   int aType = myComboId2TypeId[myTypeCombo->currentIndex()];
1231   switch (aType) {
1232   case TSCALARMAP_ITEM: //Scalar Map
1233     c.suspend();
1234     EditPrs<VISU::ScalarMap_i,VisuGUI_ScalarBarDlg>(myModule,aData,myAnimator);
1235     break;
1236   case TISOSURFACES_ITEM: //Iso Surfaces
1237     c.suspend();
1238     EditPrs<VISU::IsoSurfaces_i,VisuGUI_IsoSurfacesDlg>(myModule,aData,myAnimator);
1239     break;
1240   case TCUTPLANES_ITEM: //Cut Planes
1241     c.suspend();
1242     EditPrs<VISU::CutPlanes_i,VisuGUI_CutPlanesDlg>(myModule,aData,myAnimator);
1243     break;
1244   case TCUTLINES_ITEM: //Cut Lines
1245     c.suspend();
1246     EditPrs<VISU::CutLines_i,VisuGUI_CutLinesDlg>(myModule,aData,myAnimator);
1247     break;
1248   case TCUTSEGMENT_ITEM: //Cut Segment
1249     c.suspend();
1250     EditPrs<VISU::CutSegment_i,VisuGUI_CutSegmentDlg>(myModule,aData,myAnimator);
1251     break;
1252   case TPLOT3D_ITEM: //Plot 3D
1253     c.suspend();
1254     EditPrs<VISU::Plot3D_i,VisuGUI_Plot3DDlg>(myModule,aData,myAnimator);
1255     break;
1256   case TDEFORMEDSHAPE_ITEM: //Deformed Shape
1257     c.suspend();
1258     EditPrs<VISU::DeformedShape_i,VisuGUI_DeformedShapeDlg>(myModule,aData,myAnimator);
1259     break;
1260   case TDEFORMEDSHAPEANDSCALARMAP_ITEM: //Scalar Map on Deformed Shape
1261     c.suspend();
1262     {
1263       typedef VisuGUI_DeformedShapeAndScalarMapDlg DLG;
1264       typedef VISU::DeformedShapeAndScalarMap_i TYPE;
1265       DLG* aDlg = new DLG (myModule);
1266       TYPE* aPrs3d = dynamic_cast<TYPE*>(aData.myPrs[0]);
1267       aDlg->initFromPrsObject(aPrs3d, true);
1268       if (aDlg->exec() && aDlg->storeToPrsObject(aData.myPrs[0])) {
1269         for (long aFrameId = 1; aFrameId < aData.myNbFrames; aFrameId++){
1270           TYPE* aDeformedPrs3d = dynamic_cast<TYPE*>(aData.myPrs[aFrameId]);
1271           //Set correct time stamp number
1272           int aTimeStampNum = aDeformedPrs3d->GetScalarTimeStampNumber();
1273           aDeformedPrs3d->SameAs(aPrs3d);
1274           aDeformedPrs3d->SetScalarField(aDeformedPrs3d->GetScalarEntity(),
1275                                          aDeformedPrs3d->GetScalarFieldName(),
1276                                          aTimeStampNum);
1277
1278         }
1279
1280         if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1281           for (int aFieldId = 1; aFieldId < myAnimator->getNbFields(); aFieldId++) {
1282             FieldData& aFieldData = myAnimator->getFieldData(aFieldId);
1283             for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1284               TYPE* aDeformedPrs3d = dynamic_cast<TYPE*>(aFieldData.myPrs[aFrameId]);
1285               std::string aTitle = aDeformedPrs3d->GetCTitle();
1286               //Set correct time stamp number
1287               int aTimeStampNum = aDeformedPrs3d->GetScalarTimeStampNumber();
1288               aDeformedPrs3d->SameAs(aPrs3d);
1289               aDeformedPrs3d->SetTitle(aTitle.c_str());
1290               aDeformedPrs3d->SetScalarField(aDeformedPrs3d->GetScalarEntity(),
1291                                              aDeformedPrs3d->GetScalarFieldName(),
1292                                              aTimeStampNum);
1293
1294             }
1295           }
1296         }
1297       }
1298       delete aDlg;
1299     }
1300     break;
1301   case TVECTORS_ITEM: //Vectors
1302     c.suspend();
1303     EditPrs<VISU::Vectors_i,VisuGUI_VectorsDlg>(myModule,aData,myAnimator);
1304     break;
1305   case TSTREAMLINES_ITEM: //Stream Lines
1306     c.suspend();
1307     EditPrs<VISU::StreamLines_i,VisuGUI_StreamLinesDlg>(myModule,aData,myAnimator);
1308     break;
1309   case TGAUSSPOINTS_ITEM: //Gauss Points
1310     c.suspend();
1311     EditPrs<VISU::GaussPoints_i,VisuGUI_GaussPointsDlg>(myModule,aData,myAnimator);
1312     break;
1313   }
1314 }
1315
1316
1317 //------------------------------------------------------------------------
1318 void SetupDlg::onArrangeDlg()
1319 {
1320   ArrangeDlg aDlg(this, myAnimator);
1321   aDlg.exec();
1322 }
1323
1324 //------------------------------------------------------------------------
1325 void SetupDlg::onRangeCheck (bool theCheck)
1326 {
1327   if( theCheck )
1328   {
1329     myUseSequenceBox->blockSignals( true );
1330     myUseSequenceBox->setChecked( false );
1331     myUseSequenceBox->blockSignals( false );
1332   }
1333
1334   if (!theCheck)
1335     myAnimator->setAnimationRange(0, 0);
1336   else
1337     myAnimator->setAnimationRange(myMinVal->text().toDouble(), myMaxVal->text().toDouble());
1338
1339   setIsRegenerate( true );
1340 }
1341
1342 //------------------------------------------------------------------------
1343 void SetupDlg::onMinValue()
1344 {
1345   double aVal = myMinVal->text().toDouble();
1346   aVal = qMax( qMin( aVal, myAnimator->getMaxRange() ), myAnimator->getMinTime() );
1347   myAnimator->setAnimationRange( aVal, myAnimator->getMaxRange() );
1348   myMinVal->setText( QString::number( aVal ) );
1349   // myMinVal->setFocus();
1350
1351   setIsRegenerate( true );
1352 }
1353
1354 //------------------------------------------------------------------------
1355 void SetupDlg::onMaxValue()
1356 {
1357   double aVal = myMaxVal->text().toDouble();
1358   aVal = qMin( qMax( aVal, myAnimator->getMinRange() ), myAnimator->getMaxTime() );
1359   myAnimator->setAnimationRange( myAnimator->getMinRange(), aVal );
1360   myMaxVal->setText( QString::number( aVal ) );
1361   // myMaxVal->setFocus();
1362
1363   setIsRegenerate( true );
1364 }
1365
1366 //------------------------------------------------------------------------
1367 void SetupDlg::onMinValueEdit (const QString& theVal)
1368 {
1369   double aVal = theVal.toDouble();
1370   if ((aVal > myAnimator->getMaxRange()) || (aVal < myAnimator->getMinRange())){
1371     myMinVal->setText( QString::number(myAnimator->getMinTime()) );
1372     myMinVal->setFocus();
1373     return;
1374   }
1375 }
1376
1377 //------------------------------------------------------------------------
1378 void SetupDlg::onMaxValueEdit (const QString& theVal)
1379 {
1380   double aVal = theVal.toDouble();
1381   if ((aVal > myAnimator->getMaxRange()) || (aVal < myAnimator->getMinRange())) {
1382     myMaxVal->setText( QString::number(myAnimator->getMaxTime()) );
1383     myMaxVal->setFocus();
1384   }
1385 }
1386
1387 //------------------------------------------------------------------------
1388 void SetupDlg::onSequenceCheck( bool theCheck )
1389 {
1390   if( theCheck )
1391   {
1392     myUseRangeBox->blockSignals( true );
1393     myUseRangeBox->setChecked( false );
1394     myUseRangeBox->blockSignals( false );
1395   }
1396
1397   QString anIndices = myIndices->text();
1398   myAnimator->setAnimationSequence( anIndices.toLatin1().data() );
1399
1400   setIsRegenerate( true );
1401 }
1402
1403 //------------------------------------------------------------------------
1404 void SetupDlg::onIndicesChanged( const QString& theIndices )
1405 {
1406   bool aCorrect = true;
1407   int aLimit = myValues->count();
1408
1409   QList<long> anIndicesList;
1410   aCorrect = myAnimator->getIndicesFromSequence( theIndices, anIndicesList );
1411
1412   myValues->blockSignals( true );
1413   myValues->clearSelection();
1414
1415   QList<long>::iterator indIt = anIndicesList.begin();
1416   QList<long>::iterator indItEnd = anIndicesList.end();
1417   for( int i = 0; indIt != indItEnd; ++indIt, i++ )
1418   {
1419     long anIndex = *indIt;
1420     if( anIndex < 1 || anIndex > aLimit )
1421     {
1422       aCorrect = false;
1423       myValues->clearSelection();
1424       break;
1425     }
1426     myValues->item( anIndex-1 )->setSelected( true );
1427   }
1428
1429   myValues->blockSignals( false );
1430
1431   QPalette palette = myIndices->palette();
1432
1433   if( !aCorrect )
1434   {
1435     palette.setColor(myIndices->foregroundRole(), Qt::red);
1436     myIndices->setPalette(palette);
1437     return;
1438   }
1439
1440   palette.setColor(myIndices->foregroundRole(), Qt::black);
1441   myIndices->setPalette(palette);
1442
1443   myAnimator->setAnimationSequence( theIndices.toLatin1().data() );
1444
1445   setIsRegenerate( true );
1446 }
1447
1448 //------------------------------------------------------------------------
1449 void SetupDlg::onValuesChanged()
1450 {
1451   int aLimit = myValues->count();
1452
1453   QString anIndices;
1454
1455   for( int i = 0; i < aLimit; i++ )
1456   {
1457     if( !myValues->item( i )->isSelected() )
1458       continue;
1459
1460     QString aString = QString::number( i+1 );
1461
1462     bool aPrevSelected = i != 0 && myValues->item( i-1 )->isSelected();
1463     bool aNextSelected = i != aLimit - 1 && myValues->item( i+1 )->isSelected();
1464     if( aPrevSelected )
1465     {
1466       if( aNextSelected )
1467         aString = "";
1468       else
1469         aString += ",";
1470     }
1471     else
1472     {
1473       if( aNextSelected )
1474         aString += "-";
1475       else
1476         aString += ",";
1477     }
1478
1479     anIndices += aString;
1480   }
1481
1482   if( anIndices.right( 1 ) == "," )
1483     anIndices.truncate( anIndices.length() - 1 );
1484
1485   myIndices->blockSignals( true );
1486
1487   QPalette palette = myIndices->palette();
1488   palette.setColor(myIndices->foregroundRole(), Qt::black);
1489   myIndices->setPalette(palette);
1490
1491   myIndices->setText( anIndices );
1492   myIndices->blockSignals( false );
1493
1494   myAnimator->setAnimationSequence( anIndices.toLatin1().data() );
1495
1496   setIsRegenerate( true );
1497 }
1498
1499 //------------------------------------------------------------------------
1500 static const char * firstIco[] = {
1501 "18 10 2 1",
1502 "       g None",
1503 ".      g #000000",
1504 "         .     .  ",
1505 "  ..    ..    ..  ",
1506 "  ..   ...   ...  ",
1507 "  ..  ....  ....  ",
1508 "  .. ..... .....  ",
1509 "  .. ..... .....  ",
1510 "  ..  ....  ....  ",
1511 "  ..   ...   ...  ",
1512 "  ..    ..    ..  ",
1513 "         .     .  "};
1514
1515
1516 static const char * lastIco[] = {
1517 "18 10 2 1",
1518 "       g None",
1519 ".      g #000000",
1520 "  .     .         ",
1521 "  ..    ..    ..  ",
1522 "  ...   ...   ..  ",
1523 "  ....  ....  ..  ",
1524 "  ..... ..... ..  ",
1525 "  ..... ..... ..  ",
1526 "  ....  ....  ..  ",
1527 "  ...   ...   ..  ",
1528 "  ..    ..    ..  ",
1529 "  .     .         "};
1530
1531
1532 static const char * leftIco[] = {
1533 "11 10 2 1",
1534 "       g None",
1535 ".      g #000000",
1536 "    .     .",
1537 "   ..    ..",
1538 "  ...   ...",
1539 " ....  ....",
1540 "..... .....",
1541 "..... .....",
1542 " ....  ....",
1543 "  ...   ...",
1544 "   ..    ..",
1545 "    .     ."};
1546
1547 static const char * playIco[] = {
1548 "14 14 2 1",
1549 "       g None",
1550 ".      g #000000",
1551 "              ",
1552 "              ",
1553 "  ..          ",
1554 "  ....        ",
1555 "  ......      ",
1556 "  ........    ",
1557 "  ..........  ",
1558 "  ..........  ",
1559 "  ........    ",
1560 "  ......      ",
1561 "  ....        ",
1562 "  ..          ",
1563 "              ",
1564 "              "};
1565
1566 static QPixmap MYplayPixmap(playIco);
1567
1568
1569 static const char * rightIco[] = {
1570 "11 10 2 1",
1571 "       g None",
1572 ".      g #000000",
1573 ".     .    ",
1574 "..    ..   ",
1575 "...   ...  ",
1576 "....  .... ",
1577 "..... .....",
1578 "..... .....",
1579 "....  .... ",
1580 "...   ...  ",
1581 "..    ..   ",
1582 ".     .    "};
1583
1584
1585 static const char * pauseIco[] = {
1586 "14 14 2 1",
1587 "       g None",
1588 ".      g #000000",
1589 "              ",
1590 "              ",
1591 "   ..    ..   ",
1592 "   ..    ..   ",
1593 "   ..    ..   ",
1594 "   ..    ..   ",
1595 "   ..    ..   ",
1596 "   ..    ..   ",
1597 "   ..    ..   ",
1598 "   ..    ..   ",
1599 "   ..    ..   ",
1600 "   ..    ..   ",
1601 "              ",
1602 "              "};
1603
1604 static QPixmap MYpausePixmap(pauseIco);
1605
1606
1607 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (VisuGUI* theModule,
1608                                                     _PTR(Study) theStudy,
1609                                                     VISU::Animation::AnimationMode theMode) :
1610   QDialog(VISU::GetDesktop(theModule),
1611           Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
1612   myModule(theModule),
1613   mySetupDlg(NULL)
1614 {
1615   setAttribute( Qt::WA_DeleteOnClose, true );
1616   setModal( false );
1617   if ( theMode == VISU::Animation::PARALLEL )
1618     setWindowTitle(tr("PARALLEL_ANIMATION"));
1619   else
1620     setWindowTitle(tr("SUCCESSIVE_ANIMATION"));
1621   setSizeGripEnabled( TRUE );
1622
1623   myAnimator = new VISU_TimeAnimation (theStudy);
1624   myAnimator->setViewer(VISU::GetActiveViewWindow<SVTK_ViewWindow>(theModule));
1625   connect(myAnimator, SIGNAL(frameChanged(long, double)), this, SLOT(onExecution(long, double)));
1626   connect(myAnimator, SIGNAL(stopped()),                  this, SLOT(onStop()));
1627   myAnimator->setAnimationMode(theMode);
1628
1629   QVBoxLayout* aMainLayout = new QVBoxLayout(this);
1630   aMainLayout->setMargin( 7 );
1631   aMainLayout->setSpacing(5);
1632
1633   mySetupBtn = new QPushButton("Setup Animation...", this);
1634   connect( mySetupBtn, SIGNAL( clicked() ),
1635            this, SLOT( onSetupDlg() ) );
1636   aMainLayout->addWidget(mySetupBtn);
1637
1638   myGenBtn = new QPushButton("Generate frames", this);
1639   connect( myGenBtn, SIGNAL( clicked() ),
1640            this, SLOT( createFrames() ) );
1641   aMainLayout->addWidget(myGenBtn);
1642
1643   myPlayFrame = new QFrame(this);
1644   myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
1645   myPlayFrame->setLineWidth( 1 );
1646
1647
1648   // --- Play controls ---
1649   QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
1650   TopLayout->setSpacing( 6 );
1651   TopLayout->setMargin( 11 );
1652
1653   myTimeLbl = new QLabel("0", myPlayFrame);
1654   TopLayout->addWidget(myTimeLbl, 0, 0, 1, 3, Qt::AlignHCenter);
1655
1656   mySlider = new QSlider( myPlayFrame);
1657   mySlider->setOrientation(Qt::Horizontal);
1658   mySlider->setMinimum(0);
1659   mySlider->setMaximum(3);
1660   mySlider->setTickInterval(1);
1661   //mySlider->setTickmarks(QSlider::Below);
1662   mySlider->setTracking(false);
1663   connect( mySlider, SIGNAL( sliderMoved(int) ),
1664            this, SLOT( onWindowChanged(int) ) );
1665   TopLayout->addWidget(mySlider, 1, 0, 1, 3);
1666
1667   myPlayBtn = new QPushButton(myPlayFrame);
1668   myPlayBtn->setIcon(MYplayPixmap);
1669   myPlayBtn->setCheckable(true);
1670   connect( myPlayBtn, SIGNAL( clicked() ),
1671            this, SLOT( onPlayPressed() ) );
1672   TopLayout->addWidget(myPlayBtn, 2, 0, 1, 2);
1673
1674   QPushButton* aBackBtn = new QPushButton(myPlayFrame);
1675   aBackBtn->setIcon(QPixmap(leftIco));
1676   connect( aBackBtn, SIGNAL( clicked() ),
1677            this, SLOT( onBackPressed() ) );
1678   TopLayout->addWidget(aBackBtn, 3, 0);
1679
1680   QPushButton* aForvardBtn = new QPushButton(myPlayFrame);
1681   aForvardBtn->setIcon(QPixmap(rightIco));
1682   connect( aForvardBtn, SIGNAL( clicked() ),
1683            this, SLOT( onForvardPressed() ) );
1684   TopLayout->addWidget(aForvardBtn, 3, 1);
1685
1686   QPushButton* aFirstBtn = new QPushButton(myPlayFrame);
1687   aFirstBtn->setIcon(QPixmap(firstIco));
1688   connect( aFirstBtn, SIGNAL( clicked() ),
1689            this, SLOT( onFirstPressed() ) );
1690   TopLayout->addWidget(aFirstBtn, 4, 0);
1691
1692   QPushButton* aLastBtn = new QPushButton(myPlayFrame);
1693   aLastBtn->setIcon(QPixmap(lastIco));
1694   connect( aLastBtn, SIGNAL( clicked() ),
1695            this, SLOT( onLastPressed() ) );
1696   TopLayout->addWidget(aLastBtn, 4, 1);
1697
1698   QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
1699   TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
1700
1701   QLCDNumber* aSpeedNum  = new QLCDNumber( 2, myPlayFrame );
1702   aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
1703   aSpeedNum->display((int)myAnimator->getSpeed());
1704   TopLayout->addWidget(aSpeedNum, 4, 3);
1705
1706   QwtWheel* aWheel = new QwtWheel(myPlayFrame);
1707   aWheel->setOrientation(Qt::Vertical);
1708   aWheel->setRange(1, 99, 1);
1709   aWheel->setValue((int)myAnimator->getSpeed());
1710   connect( aWheel, SIGNAL(valueChanged(double)),
1711            aSpeedNum, SLOT(display(double)) );
1712   connect( aWheel, SIGNAL(valueChanged(double)),
1713            this, SLOT(onSpeedChange(double)) );
1714   TopLayout->addWidget(aWheel, 1, 3, 3, 1, Qt::AlignRight);
1715
1716   QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
1717   aCycleCheck->setChecked(myAnimator->isCycling());
1718   connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
1719   TopLayout->addWidget(aCycleCheck, 5, 0, 1, 4);
1720
1721   QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
1722   aPropCheck->setChecked(myAnimator->isProportional());
1723   connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
1724   TopLayout->addWidget(aPropCheck, 6, 0, 1, 4);
1725
1726   // Pictures saving on disk
1727   QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
1728   //aSaveBox->setColumnLayout(0, Qt::Horizontal );
1729   QGridLayout* aSaveLay = new QGridLayout(aSaveBox);
1730   aSaveLay->setSpacing( 5 );
1731   aSaveLay->setMargin( 5 );
1732
1733   mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
1734   connect(mySaveCheck, SIGNAL( toggled(bool)),
1735           this, SLOT( onCheckDump(bool) ));
1736   aSaveLay->addWidget(mySaveCheck, 0, 0, 1, 3);
1737
1738   QLabel* aFormatLbl = new QLabel("Saving format:", aSaveBox);
1739   aFormatLbl->setEnabled(false);
1740   connect(mySaveCheck, SIGNAL( toggled(bool)),
1741           aFormatLbl, SLOT( setEnabled(bool) ));
1742   aSaveLay->addWidget(aFormatLbl, 1, 0, 1, 2);
1743
1744   myPicsFormat = new QComboBox(aSaveBox);
1745   QList<QByteArray> aDumpFormats = QImageWriter::supportedImageFormats();
1746   for (unsigned int i = 0; i < aDumpFormats.count(); i++) {
1747     myPicsFormat->addItem(aDumpFormats.at(i));
1748   }
1749   if (aDumpFormats.indexOf("jpeg") >= 0)
1750     myPicsFormat->setCurrentIndex(aDumpFormats.indexOf("jpeg"));
1751   else
1752     myPicsFormat->setCurrentIndex(0);
1753
1754   myPicsFormat->setEnabled(false);
1755   aSaveLay->addWidget(myPicsFormat, 1, 2);
1756   connect(mySaveCheck, SIGNAL( toggled(bool)),
1757           myPicsFormat, SLOT( setEnabled(bool) ));
1758   connect(myPicsFormat, SIGNAL(  activated (int)),
1759           this, SLOT( onPicsFormatChanged()));
1760
1761   QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
1762   aPathLbl->setEnabled(false);
1763   connect(mySaveCheck, SIGNAL( toggled(bool)),
1764           aPathLbl, SLOT( setEnabled(bool) ));
1765   aSaveLay->addWidget(aPathLbl, 2, 0);
1766
1767   myPathEdit = new QLineEdit(aSaveBox);
1768   myPathEdit->setReadOnly(true);
1769   myPathEdit->setEnabled(false);
1770   connect(mySaveCheck, SIGNAL( toggled(bool)),
1771           myPathEdit, SLOT( setEnabled(bool) ));
1772   aSaveLay->addWidget(myPathEdit, 2, 1);
1773
1774   QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
1775   aBrowseBtn->setEnabled(false);
1776   connect(mySaveCheck, SIGNAL( toggled(bool)),
1777           aBrowseBtn, SLOT( setEnabled(bool) ));
1778   connect(aBrowseBtn, SIGNAL( clicked()),
1779           this, SLOT( onBrowse() ));
1780   mySaveCheck->setChecked(false);
1781   aSaveLay->addWidget(aBrowseBtn, 2, 2);
1782
1783   mySaveAVICheck = new QCheckBox("Save animation to AVI file", aSaveBox);
1784   connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1785           this, SLOT( onCheckDump(bool) ));
1786   aSaveLay->addWidget(mySaveAVICheck, 3, 0, 1, 3);
1787
1788   myPathAVILbl = new QLabel("Path:", aSaveBox);
1789   myPathAVILbl->setEnabled(false);
1790   //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1791   //        myPathAVILbl, SLOT( setEnabled(bool) ));
1792   aSaveLay->addWidget(myPathAVILbl, 4, 0);
1793
1794   myPathAVIEdit = new QLineEdit(aSaveBox);
1795   myPathAVIEdit->setReadOnly(true);
1796   myPathAVIEdit->setEnabled(false);
1797   //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1798   //        myPathAVIEdit, SLOT( setEnabled(bool) ));
1799   aSaveLay->addWidget(myPathAVIEdit, 4, 1);
1800
1801   myBrowseAVIBtn = new QPushButton("Browse...", aSaveBox);
1802   myBrowseAVIBtn->setEnabled(false);
1803   //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1804   //        myBrowseAVIBtn, SLOT( setEnabled(bool) ));
1805   connect(myBrowseAVIBtn, SIGNAL( clicked()),
1806           this, SLOT( onBrowseAVI() ));
1807   aSaveLay->addWidget(myBrowseAVIBtn, 4, 2);
1808
1809   myFrequencyLbl = new QLabel("Time stamp frequency:", aSaveBox);
1810   myFrequencyLbl->setEnabled(false);
1811   aSaveLay->addWidget(myFrequencyLbl, 5, 0, 1, 2);
1812
1813   myFrequencySpin = new SalomeApp_IntSpinBox(aSaveBox);
1814   VISU::initSpinBox(myFrequencySpin, 1, 100, 1);
1815   myFrequencySpin->setValue(myAnimator->getTimeStampFrequency());
1816   myFrequencySpin->setEnabled(false);
1817   aSaveLay->addWidget(myFrequencySpin, 5, 2);
1818
1819   mySaveAVICheck->setChecked(false);
1820   //mySaveAVICheck->setEnabled(myAnimator->checkAVIMaker());
1821
1822   int aDumpMode = myAnimator->getDumpMode();
1823   if(aDumpMode == VISU_TimeAnimation::DM_Picture)
1824     mySaveCheck->setChecked(true);
1825   else if(aDumpMode == VISU_TimeAnimation::DM_Video && myAnimator->checkAVIMaker())
1826     mySaveAVICheck->setChecked(true);
1827
1828   TopLayout->addWidget(aSaveBox, 7, 0, 1, 4);
1829
1830   QCheckBox* aCleanMemCheck = new QCheckBox("Clean memory at each frame",myPlayFrame);
1831   aCleanMemCheck->setChecked(myAnimator->isCleaningMemoryAtEachFrame());
1832   connect(aCleanMemCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCleaningMemoryAtEachFrameSlot(bool)));
1833   TopLayout->addWidget(aCleanMemCheck, 8, 0, 1, 4);
1834
1835   aMainLayout->addWidget(myPlayFrame);
1836
1837   // Animation publishing in study
1838   QWidget* aPublishBox = new QWidget(this);
1839   QHBoxLayout* aPubHBLay = new QHBoxLayout( aPublishBox );
1840   aPubHBLay->setMargin( 0 );
1841
1842   myPublishBtn = new QPushButton("Publish to study", aPublishBox);
1843   aPubHBLay->addWidget( myPublishBtn );
1844   connect(myPublishBtn, SIGNAL(clicked()), this, SLOT(publishToStudy()));
1845
1846   mySaveBtn = new QPushButton("Save Animation", aPublishBox);
1847   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1848   aPubHBLay->addWidget( mySaveBtn );
1849   connect(mySaveBtn, SIGNAL(clicked()), this, SLOT(saveToStudy()));
1850
1851   aMainLayout->addWidget(aPublishBox);
1852
1853
1854   QWidget* aBtnBox = new QWidget(this);
1855   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox);
1856   aBtnLayout->setContentsMargins( 5, 5, 0, 5 );
1857   aBtnLayout->addStretch();
1858
1859   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
1860   aBtnLayout->addWidget( aCloseBtn );
1861   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
1862
1863   QPushButton* aHelpBtn = new QPushButton(tr("BUT_HELP"), aBtnBox);
1864   aBtnLayout->addWidget( aHelpBtn );
1865   connect(aHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp()));
1866
1867   SUIT_Study* aStudy = VISU::GetAppStudy(myModule);
1868   connect(aStudy, SIGNAL(destroyed()), this, SLOT(close()));
1869
1870   connect(myAnimator->getViewer(), SIGNAL(destroyed()), this, SLOT(close()));
1871   connect(myAnimator->getViewer(), SIGNAL(closing(SUIT_ViewWindow*)), this, SLOT(close()));
1872
1873   aMainLayout->addWidget(aBtnBox);
1874
1875   myPlayFrame->setEnabled(false);
1876 }
1877
1878 //------------------------------------------------------------------------
1879 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg()
1880 {
1881   if (myAnimator != NULL) {
1882     delete myAnimator;
1883     myAnimator = NULL;
1884     if ( VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule) )
1885       VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule)->Repaint();
1886   }
1887 }
1888
1889 //------------------------------------------------------------------------
1890 void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
1891 {
1892   stopAnimation();
1893   myPropBtn->setEnabled(index != 0);
1894
1895   clearView();
1896   myPlayFrame->setEnabled(false);
1897 }
1898
1899 //------------------------------------------------------------------------
1900 bool VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
1901 {
1902   myPlayFrame->setEnabled(false);
1903   return myAnimator->addField(theSObject);
1904 }
1905
1906 //------------------------------------------------------------------------
1907 void VisuGUI_TimeAnimationDlg::createFrames()
1908 {
1909   stopAnimation();
1910   SUIT_OverrideCursor c;
1911
1912   bool isRegenerate = mySetupDlg->isRegenerate();
1913
1914   for (int i = 0; i < myAnimator->getNbFields(); i++) {
1915     FieldData& aFieldData = myAnimator->getFieldData(i);
1916     if( aFieldData.myPrs.empty() )
1917     {
1918       //myAnimator->generatePresentations(i);
1919       GeneratePresentations(i,myAnimator);
1920       continue;
1921     }
1922
1923     // ouv : IPAL18064
1924     // even if aFieldData is not empty, we must regenerate presentations,
1925     // when a range or a sequence of the animation has been changed
1926     if( isRegenerate )
1927     {
1928       GeneratePresentations(i,myAnimator);
1929       /*
1930       VISU::ColoredPrs3d_i* aPrs3d = dynamic_cast<VISU::ColoredPrs3d_i*>(aFieldData.myPrs[0]);
1931       if( !aPrs3d )
1932         continue;
1933
1934       myAnimator->generatePresentations(i);
1935
1936       aFieldData = myAnimator->getFieldData(i);
1937       for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1938         VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
1939         std::string aTitle = aColoredPrs3d->GetCTitle();
1940         aColoredPrs3d->SameAs(aPrs3d);
1941         if ( aFrameId != 0 && myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1942           aColoredPrs3d->SetTitle(aTitle.c_str());
1943         }
1944       }
1945       */
1946     }
1947   }
1948   if( isRegenerate )
1949     mySetupDlg->setIsRegenerate( false );
1950
1951   if (myAnimator->getNbFrames() == 0) {
1952     myPlayFrame->setEnabled(false);
1953     c.suspend();
1954     SUIT_MessageBox::warning(this,
1955                            tr("ERROR"),
1956                            tr("MSG_NO_ANIMATIONDATA"),
1957                            tr("&OK"));
1958     return;
1959   }
1960   mySlider->setMaximum(myAnimator->getNbFrames()-1);
1961   myPlayFrame->setEnabled(true);
1962   if (!myAnimator->generateFrames()) {
1963     c.suspend();
1964     //myPlayFrame->setEnabled(false);
1965     SUIT_MessageBox::warning(this,
1966                            tr("ERROR"),
1967                            myAnimator->getLastErrorMsg(),
1968                            tr("&OK"));
1969     return;
1970   }
1971   //myPlayFrame->setEnabled(true);
1972 }
1973
1974 //------------------------------------------------------------------------
1975 void VisuGUI_TimeAnimationDlg::onPlayPressed()
1976 {
1977   if (myPlayBtn->isChecked() && (!myAnimator->isRunning())) {
1978     myPlayBtn->setIcon(MYpausePixmap);
1979     if (mySaveCheck->isChecked()) {
1980       onPicsFormatChanged();
1981       onPathChanged();
1982
1983     } else if (mySaveAVICheck->isChecked()) {
1984       myAnimator->setDumpFormat("AVI");
1985       myAnimator->dumpTo(myPathAVIEdit->text().toLatin1().data());
1986       myAnimator->setTimeStampFrequency(myFrequencySpin->value());
1987     } else {
1988       myAnimator->dumpTo("");
1989     }
1990     mySetupBtn->setEnabled(false);
1991     myGenBtn->setEnabled(false);
1992     myAnimator->startAnimation();
1993   } else {
1994     myPlayBtn->setIcon(MYplayPixmap);
1995     myAnimator->stopAnimation();
1996     mySetupBtn->setEnabled(true);
1997     myGenBtn->setEnabled(true);
1998   }
1999 }
2000
2001 //------------------------------------------------------------------------
2002 void VisuGUI_TimeAnimationDlg::onBackPressed()
2003 {
2004   stopAnimation();
2005   myAnimator->prevFrame();
2006 }
2007
2008 //------------------------------------------------------------------------
2009 void VisuGUI_TimeAnimationDlg::onForvardPressed()
2010 {
2011   stopAnimation();
2012   myAnimator->nextFrame();
2013 }
2014
2015 //------------------------------------------------------------------------
2016 void VisuGUI_TimeAnimationDlg::onLastPressed()
2017 {
2018   stopAnimation();
2019   myAnimator->lastFrame();
2020 }
2021
2022 //------------------------------------------------------------------------
2023 void VisuGUI_TimeAnimationDlg::onFirstPressed()
2024 {
2025   stopAnimation();
2026   myAnimator->firstFrame();
2027 }
2028
2029 //------------------------------------------------------------------------
2030 void VisuGUI_TimeAnimationDlg::clearView()
2031 {
2032   myAnimator->clearView();
2033 }
2034
2035 //------------------------------------------------------------------------
2036 void VisuGUI_TimeAnimationDlg::showEvent(QShowEvent* theEvent)
2037 {
2038   mySetupDlg = new SetupDlg(this,myModule, myAnimator);
2039   mySetupDlg->initialize();
2040 }
2041
2042 //------------------------------------------------------------------------
2043 void VisuGUI_TimeAnimationDlg::closeEvent (QCloseEvent* theEvent)
2044 {
2045   if (myAnimator != NULL) {
2046     myAnimator->stopAnimation();
2047     myAnimator->wait(500);
2048     if (myAnimator->isRunning() && (! myAnimator->isFinished())) {
2049       theEvent->ignore();
2050       QCloseEvent* aNewCloseEvent = new QCloseEvent;
2051       QApplication::postEvent( this, aNewCloseEvent );
2052     } else {
2053       QDialog::closeEvent(theEvent);
2054     }
2055   } else {
2056     QDialog::closeEvent(theEvent);
2057   }
2058 }
2059
2060 //------------------------------------------------------------------------
2061 void VisuGUI_TimeAnimationDlg::onWindowChanged (int index)
2062 {
2063   if (myAnimator->isRunning()) return;
2064   myAnimator->gotoFrame(index);
2065 }
2066
2067 //------------------------------------------------------------------------
2068 void VisuGUI_TimeAnimationDlg::onSpeedChange (double theSpeed)
2069 {
2070   myAnimator->setSpeed((int)theSpeed);
2071 }
2072
2073 //------------------------------------------------------------------------
2074 void VisuGUI_TimeAnimationDlg::stopAnimation()
2075 {
2076   myAnimator->stopAnimation();
2077   myPlayBtn->setChecked(false);
2078   myPlayBtn->setIcon(MYplayPixmap);
2079   mySetupBtn->setEnabled(true);
2080   myGenBtn->setEnabled(true);
2081 }
2082
2083 //------------------------------------------------------------------------
2084 void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
2085 {
2086   myTimeLbl->setText(QString("%1").arg(theTime));
2087   mySlider->setValue(theNewFrame);
2088 }
2089
2090 //------------------------------------------------------------------------
2091 void VisuGUI_TimeAnimationDlg::onSetupDlg()
2092 {
2093   if (myAnimator->getNbFrames() > 0)
2094     myAnimator->firstFrame();
2095   mySetupDlg->exec();
2096   myPlayFrame->setEnabled(false);
2097 }
2098
2099 //------------------------------------------------------------------------
2100 void VisuGUI_TimeAnimationDlg::onBrowse()
2101 {
2102   //  QString aPath = SUIT_FileDlg::getExistingDirectory(this, "/", "Select path");
2103   QString aDir;
2104   if (myPathEdit->text().isEmpty())
2105     aDir = getenv("HOME");
2106   else
2107     aDir = myPathEdit->text();
2108   QString aPath = SUIT_FileDlg::getExistingDirectory(this, aDir, "Select path");
2109   if (!aPath.isEmpty())
2110     myPathEdit->setText(Qtx::addSlash(aPath));
2111   onPathChanged();
2112 }
2113
2114 //------------------------------------------------------------------------
2115 void VisuGUI_TimeAnimationDlg::onBrowseAVI()
2116 {
2117   QStringList aFilter;
2118   aFilter.append( "AVI Files (*.avi)" );
2119   aFilter.append( "All Files (*.*)" );
2120
2121   QString aDir;
2122   if (myPathAVIEdit->text().isEmpty())
2123     aDir = getenv("HOME");
2124   else {
2125     QFileInfo aFile(myPathAVIEdit->text());
2126     aDir = aFile.absoluteDir().absolutePath();
2127   }
2128   QString aPath = SUIT_FileDlg::getFileName(this, aDir, aFilter, "Select file", false);
2129   if (!aPath.isEmpty())
2130     myPathAVIEdit->setText(aPath);
2131 }
2132
2133 //------------------------------------------------------------------------
2134 void VisuGUI_TimeAnimationDlg::onCheckDump(bool)
2135 {
2136   const QObject* source = sender();
2137   if (source == mySaveCheck) {
2138     if (mySaveCheck->isChecked()) {
2139       onPicsFormatChanged();
2140       onPathChanged();
2141       if (mySaveAVICheck->isChecked())
2142         mySaveAVICheck->setChecked(false);
2143     } else {
2144       myAnimator->dumpTo("");
2145     }
2146     //mySaveAVICheck->setEnabled(!mySaveCheck->isChecked() && myAnimator->checkAVIMaker());
2147     mySaveAVICheck->setEnabled(!mySaveCheck->isChecked());
2148   }
2149   else if (source == mySaveAVICheck) {
2150     if (mySaveAVICheck->isChecked()) {
2151       if (!myAnimator->checkAVIMaker()) {
2152         // AVI maker is not available
2153         SUIT_MessageBox::warning(this, tr("ERROR"), tr("MSG_NO_AVI_MAKER"), tr("&OK"));
2154         mySaveAVICheck->setChecked(false);
2155       }
2156       else {
2157         if (mySaveCheck->isChecked()) {
2158           mySaveCheck->setChecked(false);
2159         }
2160         myPathAVILbl->setEnabled(true);
2161         myPathAVIEdit->setEnabled(true);
2162         myBrowseAVIBtn->setEnabled(true);
2163         myFrequencyLbl->setEnabled(true);
2164         myFrequencySpin->setEnabled(true);
2165       }
2166     }
2167     else {
2168       // it is necessary in case of not available AVI maker,
2169       // because otherwise they will stay enabled
2170       // (??? slots, connected on SIGNAL(toggled(bool)) of mySaveAVICheck,
2171       // works in wrong order ???)
2172       myPathAVILbl->setEnabled(false);
2173       myPathAVIEdit->setEnabled(false);
2174       myBrowseAVIBtn->setEnabled(false);
2175       myFrequencyLbl->setEnabled(false);
2176       myFrequencySpin->setEnabled(false);
2177     }
2178     mySaveCheck->setEnabled(!mySaveAVICheck->isChecked());
2179   }
2180 }
2181
2182 //------------------------------------------------------------------------
2183 void VisuGUI_TimeAnimationDlg::onStop()
2184 {
2185   myPlayBtn->setChecked(false);
2186   myPlayBtn->setIcon(MYplayPixmap);
2187   mySetupBtn->setEnabled(true);
2188   myGenBtn->setEnabled(true);
2189 }
2190
2191 //------------------------------------------------------------------------
2192 void VisuGUI_TimeAnimationDlg::onHelp()
2193 {
2194   QString aHelpFileName = "animating_page.html";
2195   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
2196   if (app)
2197     app->onHelpContextModule(myModule ? app->moduleName(myModule->moduleName()) : QString(""), aHelpFileName);
2198   else {
2199                 QString platform;
2200 #ifdef WIN32
2201                 platform = "winapplication";
2202 #else
2203                 platform = "application";
2204 #endif
2205     SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
2206                            QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
2207                            arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName),
2208                            QObject::tr("BUT_OK"));
2209   }
2210 }
2211
2212 //------------------------------------------------------------------------
2213 void VisuGUI_TimeAnimationDlg::saveToStudy()
2214 {
2215   myAnimator->saveAnimation();
2216   VISU::UpdateObjBrowser(myModule, true);
2217 }
2218
2219 //------------------------------------------------------------------------
2220 void VisuGUI_TimeAnimationDlg::publishToStudy()
2221 {
2222   myAnimator->publishInStudy();
2223   VISU::UpdateObjBrowser(myModule, true);
2224   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
2225 }
2226
2227 //------------------------------------------------------------------------
2228 void VisuGUI_TimeAnimationDlg::restoreFromStudy(_PTR(SObject) theAnimation)
2229 {
2230   myAnimator->restoreFromStudy(theAnimation);
2231   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
2232   if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE )
2233     setWindowTitle(tr("SUCCESSIVE_ANIMATION"));
2234 }
2235
2236 //------------------------------------------------------------------------
2237 void VisuGUI_TimeAnimationDlg::onPicsFormatChanged()
2238 {
2239   QList<QByteArray> aDumpFormats = QImageWriter::supportedImageFormats();
2240   if (aDumpFormats.count() < 1) {
2241     SUIT_MessageBox::warning(this, tr("ERROR"), tr("MSG_NO_SUPPORTED_IMAGE_FORMATS"), tr("&OK"));
2242     return;
2243   }
2244   if (myPicsFormat->currentIndex() < 0 || aDumpFormats.count() <= myPicsFormat->currentIndex()) {
2245     SUIT_MessageBox::warning(this, tr("ERROR"), tr("MSG_INVALID_IMAGE_FORMAT_INDEX"), tr("&OK"));
2246     return;
2247   }
2248   myAnimator->setDumpFormat(aDumpFormats.at(myPicsFormat->currentIndex()));
2249 }
2250
2251 //------------------------------------------------------------------------
2252 void VisuGUI_TimeAnimationDlg::onPathChanged()
2253 {
2254   myAnimator->dumpTo(myPathEdit->text().toLatin1().data());
2255 }
2256
2257 //------------------------------------------------------------------------
2258 void VisuGUI_TimeAnimationDlg::keyPressEvent( QKeyEvent* e )
2259 {
2260   QDialog::keyPressEvent( e );
2261   if ( e->isAccepted() )
2262     return;
2263
2264   if ( e->key() == Qt::Key_F1 )
2265     {
2266       e->accept();
2267       onHelp();
2268     }
2269 }