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