Salome HOME
0598764e379343b0ef5915d9b230453c50914dfd
[modules/visu.git] / src / VISUGUI / VisuGUI_TimeAnimation.cxx
1 //  VISU VISUGUI : GUI of VISU component
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : VisuGUI_TimeAnimation.cxx
8 //  Author : Vitaly SMETANNIKOV
9 //  Module : VISU
10
11 #include "VisuGUI_TimeAnimation.h"
12
13 #include "VisuGUI.h"
14 #include "VisuGUI_Tools.h"
15 #include "VisuGUI_DeformedShapeDlg.h"
16 #include "VisuGUI_CutPlanesDlg.h"
17 #include "VisuGUI_Plot3DDlg.h"
18 #include "VisuGUI_VectorsDlg.h"
19 #include "VisuGUI_IsoSurfacesDlg.h"
20 #include "VisuGUI_StreamLinesDlg.h"
21
22 #include "VISU_TimeAnimation.h"
23
24 #include "VISU_ScalarMap_i.hh"
25 #include "VISU_IsoSurfaces_i.hh"
26 #include "VISU_DeformedShape_i.hh"
27 #include "VISU_CutPlanes_i.hh"
28 #include "VISU_Plot3D_i.hh"
29 #include "VISU_CutLines_i.hh"
30 #include "VISU_Vectors_i.hh"
31 #include "VISU_StreamLines_i.hh"
32
33 #include "VISU_ViewManager_i.hh"
34
35 #include "VISU_ScalarBarActor.hxx"
36 #include "VISU_Actor.h"
37
38 #include "SalomeApp_Study.h"
39 #include "SalomeApp_Application.h"
40
41 #include "SVTK_ViewWindow.h"
42
43 #include "SUIT_OverrideCursor.h"
44 #include "SUIT_MessageBox.h"
45 #include "SUIT_Desktop.h"
46 #include "SUIT_FileDlg.h"
47
48 #include <vtkRenderer.h>
49
50 #include <qhbox.h>
51 #include <qgrid.h>
52 #include <qlayout.h>
53 #include <qslider.h>
54 #include <qthread.h>
55 #include <qlistbox.h>
56 #include <qwt_wheel.h>
57 #include <qhgroupbox.h>
58 #include <qlcdnumber.h>
59 #include <qvgroupbox.h>
60
61 #define  MAXVAL 1e10
62
63 ArrangeDlg::ArrangeDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
64   : QDialog(theParent, "ArrangeDlg", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
65     myAnimator(theAnimator), myViewWindow(theAnimator->getViewer())
66 {
67   myCurrent = 0;
68   init();
69   QStringList aFieldNames;
70   // Find names of fields
71   for (int i = 0; i < theAnimator->getNbFields(); i++) {
72     aFieldNames.append(VISU::getValue(theAnimator->getFieldData(i).myField, "myName"));
73     Offset aOffs;
74     aOffs.myOffset[0] = myAnimator->getFieldData(i).myOffset[0];
75     aOffs.myOffset[1] = myAnimator->getFieldData(i).myOffset[1];
76     aOffs.myOffset[2] = myAnimator->getFieldData(i).myOffset[2];
77     myOffsets.append(aOffs);
78   }
79   myFieldLst->insertStringList(aFieldNames);
80   myFieldLst->setSelected(0, true);
81 }
82
83 ArrangeDlg::ArrangeDlg(QWidget* theParent, SVTK_ViewWindow* theViewWindow)
84   : QDialog(theParent, "ArrangeDlg", true, WStyle_Customize |
85             WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
86     myAnimator(0), myViewWindow(theViewWindow)
87 {
88   myCurrent = 0;
89   init();
90   QStringList aPrsNames;
91   vtkActor* anActor;
92   vtkActorCollection *anActColl = myViewWindow->getRenderer()->GetActors();
93   for (anActColl->InitTraversal(); (anActor = anActColl->GetNextActor()) != NULL;) {
94     VISU_Actor* anVISUActor = dynamic_cast<VISU_Actor*>(anActor);
95     if (anVISUActor)
96       if (anVISUActor->GetVisibility() != 0) {
97         VISU::Prs3d_i* aPrs = anVISUActor->GetParent()->GetPrs3d();
98         if (aPrs) {
99           if (!myPrsMap.contains(aPrs)) {
100             SALOMEDS::SObject_var aSObject = aPrs->GetSObject();
101             if(!aSObject->_is_nil()){
102               SALOMEDS::GenericAttribute_var anAttr;
103               if (aSObject->FindAttribute(anAttr, "AttributeName")) {
104                 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
105                 string aNam = aName->Value();
106                 QString strIn(aNam.c_str());
107                 aPrsNames.append(strIn);
108                 myPrsMap[aPrs] = myOffsets.count();
109                 Offset aOffs;
110                 anVISUActor->GetPosition(aOffs.myOffset);
111                 myOffsets.append(aOffs);
112               }
113             }
114           }
115         }
116       }
117   }
118   myFieldLst->insertStringList(aPrsNames);
119   myFieldLst->setSelected(0, true);
120 }
121
122 void ArrangeDlg::init()
123 {
124   setCaption("Arrange Presentations");
125   setSizeGripEnabled( TRUE );
126
127   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
128   aMainLayout->setSpacing(5);
129
130   QButtonGroup* aBtnGrp = new QButtonGroup(2, Qt::Horizontal, this);
131   aBtnGrp->setExclusive(true);
132   aMainLayout->addWidget(aBtnGrp);
133
134   QRadioButton* aAutoBtn = new QRadioButton("Auto", aBtnGrp);
135   aBtnGrp->insert(aAutoBtn, AutoMode);
136
137   QRadioButton* aManualBtn = new QRadioButton("Manual", aBtnGrp);
138   aBtnGrp->insert(aManualBtn, ManualMode);
139   aBtnGrp->setButton(AutoMode);
140
141   myStackWgt = new QWidgetStack(this);
142   aMainLayout->addWidget(myStackWgt);
143
144   //  AUTO Pane
145   QVBox* aAutoPane = new QVBox(myStackWgt);
146   aAutoPane->setSpacing(5);
147   // Axis Group
148   myAxisGrp = new QButtonGroup(3, Qt::Horizontal,"Axis", aAutoPane);
149
150   QRadioButton* aXBtn = new QRadioButton("X",myAxisGrp );
151   myAxisGrp->insert(aXBtn, XAxis);
152
153   QRadioButton* aYBtn = new QRadioButton("Y",myAxisGrp );
154   myAxisGrp->insert(aYBtn, YAxis);
155
156   QRadioButton* aZBtn = new QRadioButton("Z",myAxisGrp );
157   myAxisGrp->insert(aZBtn, ZAxis);
158
159   myAxisGrp->setButton(XAxis);
160
161   //Distance Input
162   QHBox* aDistPane = new QHBox(aAutoPane);
163   aDistPane->setSpacing(5);
164   new QLabel("Relative Distance", aDistPane);
165   myDistVal = new QtxDblSpinBox (-10,10, 0.5, aDistPane);
166   myDistVal->setValue(1);
167
168   myStackWgt->addWidget(aAutoPane, AutoMode);
169
170   // Manual Pane
171   QHBox* aManualPane = new QHBox(myStackWgt);
172   aManualPane->setSpacing(10);
173
174   myFieldLst = new QListBox(aManualPane);
175   connect( myFieldLst, SIGNAL( highlighted(int) ),
176            this, SLOT( onFieldChange(int) ) );
177
178   QGrid* aCoordPane = new QGrid(2, aManualPane);
179   aCoordPane->setSpacing(5);
180
181   new QLabel("X", aCoordPane);
182   myCoord[0] = new QtxDblSpinBox(aCoordPane);
183   myCoord[0]->setRange(-MAXVAL, MAXVAL);
184
185   new QLabel("Y", aCoordPane);
186   myCoord[1] = new QtxDblSpinBox(aCoordPane);
187   myCoord[1]->setRange(-MAXVAL, MAXVAL);
188
189   new QLabel("Z", aCoordPane);
190   myCoord[2] = new QtxDblSpinBox(aCoordPane);
191   myCoord[2]->setRange(-MAXVAL, MAXVAL);
192
193   myStackWgt->addWidget(aManualPane, ManualMode);
194
195   myStackWgt->raiseWidget(AutoMode);
196
197   connect(aBtnGrp, SIGNAL(clicked(int)), myStackWgt, SLOT(raiseWidget(int)) );
198
199   SUIT_Study* aSUITStudy = myViewWindow->getViewManager()->study();
200   SalomeApp_Study* anAppStudy = dynamic_cast<SalomeApp_Study*>(aSUITStudy);
201   _PTR(Study) aCStudy = VISU::GetCStudy(anAppStudy);
202   if (!myAnimator && !aCStudy->GetProperties()->IsLocked()) {
203     mySaveChk = new QCheckBox ("Save to presentation", this);
204     mySaveChk->setChecked(false);
205     aMainLayout->addWidget(mySaveChk);
206   } else {
207     mySaveChk = 0;
208   }
209
210   // Common buttons ===========================================================
211   QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
212   GroupButtons->setColumnLayout(0, Qt::Vertical );
213   GroupButtons->layout()->setSpacing( 0 );
214   GroupButtons->layout()->setMargin( 0 );
215   QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
216   GroupButtonsLayout->setAlignment( Qt::AlignTop );
217   GroupButtonsLayout->setSpacing( 6 );
218   GroupButtonsLayout->setMargin( 11 );
219
220   QPushButton* buttonOk = new QPushButton( tr( "&OK" ), GroupButtons, "buttonOk" );
221   buttonOk->setAutoDefault( TRUE );
222   buttonOk->setDefault( TRUE );
223   GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
224   GroupButtonsLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
225
226   QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ) , GroupButtons, "buttonCancel" );
227   buttonCancel->setAutoDefault( TRUE );
228   GroupButtonsLayout->addWidget( buttonCancel, 0, 2 );
229
230   aMainLayout->addWidget( GroupButtons );
231
232   connect( buttonOk,     SIGNAL( clicked() ),      this, SLOT( accept() ) );
233   connect( buttonCancel, SIGNAL( clicked() ),      this, SLOT( reject() ) );
234 }
235
236 void ArrangeDlg::accept()
237 {
238   if (myAnimator) {
239     acceptAnimation();
240   } else {
241     acceptViewWindow();
242   }
243   QDialog::accept();
244 }
245
246 void ArrangeDlg::onFieldChange(int theCurrent)
247 {
248   if (myCurrent != theCurrent) {
249     Offset& aOffs = myOffsets[myCurrent];
250     aOffs.myOffset[0] = myCoord[0]->value();
251     aOffs.myOffset[1] = myCoord[1]->value();
252     aOffs.myOffset[2] = myCoord[2]->value();
253   }
254   myCurrent = theCurrent;
255   const Offset& aNewOffs = myOffsets[myCurrent];
256   myCoord[0]->setValue(aNewOffs.myOffset[0]);
257   myCoord[1]->setValue(aNewOffs.myOffset[1]);
258   myCoord[2]->setValue(aNewOffs.myOffset[2]);
259 }
260
261 void ArrangeDlg::acceptAnimation()
262 {
263   if (getMode() == ManualMode) {
264     // Save from GUI
265     Offset& aOffs = myOffsets[myCurrent];
266     aOffs.myOffset[0] = myCoord[0]->value();
267     aOffs.myOffset[1] = myCoord[1]->value();
268     aOffs.myOffset[2] = myCoord[2]->value();
269
270     for (int i = 0; i < myAnimator->getNbFields(); i++) {
271       Offset aOffs = myOffsets[i];
272       myAnimator->getFieldData(i).myOffset[0] = aOffs.myOffset[0];
273       myAnimator->getFieldData(i).myOffset[1] = aOffs.myOffset[1];
274       myAnimator->getFieldData(i).myOffset[2] = aOffs.myOffset[2];
275     }
276   } else {
277     QApplication::setOverrideCursor( Qt::waitCursor );
278     FieldData& aData = myAnimator->getFieldData(0);
279     if (aData.myPrs.empty())
280       myAnimator->generatePresentations(0);
281     VISU_Actor* aActor = aData.myPrs[0]->CreateActor();
282     float aBounds[6];
283     aActor->GetBounds(aBounds);
284     aActor->Delete();
285     float aDist = 0;
286     int aAxis = getAxis();
287     switch (aAxis) {
288     case XAxis:
289       aDist = fabs(aBounds[1] - aBounds[0]);
290       break;
291     case YAxis:
292       aDist = fabs(aBounds[3] - aBounds[2]);
293       break;
294     case ZAxis:
295       aDist = fabs(aBounds[5] - aBounds[4]);
296     }
297
298     float dx = fabs(aBounds[1] - aBounds[0]);
299     float dy = fabs(aBounds[3] - aBounds[2]);
300     float dz = fabs(aBounds[5] - aBounds[4]);
301     float max = (dx > dy) ? dx : dy;
302     max = (dz > max) ? dz : max;
303     max /= 100.0;
304
305     if (aDist < max) {
306       // set base distance between centers of bounding boxes
307       // to minimal (but big enough) size of current bounding box
308       if (dx < max) dx = FLT_MAX;
309       if (dy < max) dy = FLT_MAX;
310       if (dz < max) dz = FLT_MAX;
311
312       aDist = (dx < dy) ? dx : dy;
313       aDist = (dz < aDist) ? dz : aDist;
314     }
315     aDist = aDist * getDistance();
316     for (int i = 0; i < myAnimator->getNbFields(); i++) {
317       myAnimator->getFieldData(i).myOffset[0] = 0;
318       myAnimator->getFieldData(i).myOffset[1] = 0;
319       myAnimator->getFieldData(i).myOffset[2] = 0;
320       myAnimator->getFieldData(i).myOffset[aAxis] = aDist * i;
321     }
322
323     QApplication::restoreOverrideCursor();
324   }
325 }
326
327 void ArrangeDlg::acceptViewWindow()
328 {
329   if (getMode() == ManualMode) {
330     // Save from GUI
331     Offset& aOffs = myOffsets[myCurrent];
332     aOffs.myOffset[0] = myCoord[0]->value();
333     aOffs.myOffset[1] = myCoord[1]->value();
334     aOffs.myOffset[2] = myCoord[2]->value();
335
336     QMap<VISU::Prs3d_i*, int>::Iterator it;
337     for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it) {
338       VISU::Prs3d_i* aPrs = it.key();
339       Offset& aOffs = myOffsets[it.data()];
340       if (VISU_Actor* anActor = VISU::GetActor(aPrs, myViewWindow))
341         anActor->SetPosition(aOffs.myOffset);
342       if (mySaveChk)
343         if (mySaveChk->isChecked())
344           aPrs->SetOffset(aOffs.myOffset);
345     }
346   } else {
347     float aDist = 0;
348     float aShift = 0;
349     float aPrevDist = 0;
350     float aPrevShift = 0;
351     int i;
352     QMap<VISU::Prs3d_i*, int>::Iterator it;
353     for (it = myPrsMap.begin(), i = 0; it != myPrsMap.end(); ++it, i++) {
354       VISU::Prs3d_i* aPrs = it.key();
355       if (VISU_Actor* aActor = VISU::GetActor(aPrs, myViewWindow)) {
356         int aAxis = getAxis();
357
358         float aZeroOffset[3];
359         aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
360         aActor->SetPosition(aZeroOffset);
361         aActor->GetMapper()->Update();
362
363         float aBounds[6];
364         aActor->GetBounds(aBounds);
365         switch (aAxis) {
366         case XAxis:
367           aDist = fabs(aBounds[1] - aBounds[0]);
368           break;
369         case YAxis:
370           aDist = fabs(aBounds[3] - aBounds[2]);
371           break;
372         case ZAxis:
373           aDist = fabs(aBounds[5] - aBounds[4]);
374         }
375         float aOffset[3];
376         aOffset[0] = (aBounds[1] < aBounds[0]) ? -aBounds[1] : -aBounds[0];
377         aOffset[1] = (aBounds[3] < aBounds[2]) ? -aBounds[3] : -aBounds[2];
378         aOffset[2] = (aBounds[5] < aBounds[4]) ? -aBounds[5] : -aBounds[4];
379
380         if (i > 0) {
381           float aCCDist = (aDist + aPrevDist) / 2.0;
382
383           float dx = fabs(aBounds[1] - aBounds[0]);
384           float dy = fabs(aBounds[3] - aBounds[2]);
385           float dz = fabs(aBounds[5] - aBounds[4]);
386           float max = (dx > dy) ? dx : dy;
387           max = (dz > max) ? dz : max;
388           max /= 100.0;
389
390           if (aCCDist < max) {
391             // set base distance between centers of bounding boxes
392             // to minimal (but big enough) size of current bounding box
393             if (dx < max) dx = FLT_MAX;
394             if (dy < max) dy = FLT_MAX;
395             if (dz < max) dz = FLT_MAX;
396
397             aCCDist = (dx < dy) ? dx : dy;
398             aCCDist = (dz < aCCDist) ? dz : aCCDist;
399           }
400
401           //-------------------------------->
402           //             aShift
403           //                                 aDist / 2
404           //                                 <-->
405           //            .--------------.     .------.
406           //----------->|              |     |      |
407           // aPrevShift '--------------'     '------'
408           //            <------>
409           //            aPrevDist / 2
410           //
411           //                    <--------------->
412           //                    (aDist + aPrevDist) * getDistance() / 2
413
414           aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
415         }
416
417         aOffset[aAxis] += aShift;
418         aActor->SetPosition(aOffset);
419         if (mySaveChk)
420           if (mySaveChk->isChecked())
421             aPrs->SetOffset(aOffset);
422
423         aPrevDist = aDist;
424         aPrevShift = aShift;
425       }
426     }
427   }
428   myViewWindow->getRenderer()->ResetCameraClippingRange();
429   myViewWindow->Repaint();
430 }
431
432
433 //*****************************************************************************************************
434 //*****************************************************************************************************
435 //*****************************************************************************************************
436 SetupDlg::SetupDlg (VisuGUI* theModule, VISU_TimeAnimation* theAnimator)
437      : QDialog(VISU::GetDesktop(theModule), "SetupDlg", true, WStyle_Customize |
438                WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
439        myModule(theModule)
440 {
441   setCaption("Setup Animation");
442   setSizeGripEnabled( TRUE );
443   myAnimator = theAnimator;
444
445   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
446   aMainLayout->setSpacing(5);
447
448
449   QFrame* aRangeGrp = new QFrame(this);
450   QGridLayout* aRangeLayout = new QGridLayout( aRangeGrp );
451   aRangeLayout->setSpacing( 6 );
452   aRangeLayout->setMargin( 11 );
453   aRangeGrp->setFrameStyle(QFrame::Box | QFrame::Raised);
454
455   myUseRangeChk = new QCheckBox("Use range of time stamps", aRangeGrp);
456   aRangeLayout->addMultiCellWidget(myUseRangeChk, 0, 0, 0, 3);
457   myUseRangeChk->setChecked(myAnimator->isRangeDefined());
458
459   QLabel* aMinLbl = new QLabel("From", aRangeGrp);
460   aMinLbl->setEnabled(myUseRangeChk->isChecked());
461   aRangeLayout->addWidget(aMinLbl, 1, 0);
462   double aStep = (myAnimator->getMaxTime() - myAnimator->getMinTime())/(theAnimator->getFieldData(0).myNbTimes - 1);
463   myMinVal = new QtxDblSpinBox( myAnimator->getMinTime(), myAnimator->getMaxTime(), aStep, aRangeGrp );
464   myMinVal->setEnabled(myUseRangeChk->isChecked());
465   if (myUseRangeChk->isChecked())
466     myMinVal->setValue( myAnimator->getMinRange() );
467   else
468     myMinVal->setValue( myAnimator->getMinTime() );
469
470   connect(myMinVal, SIGNAL( valueChanged(double)),
471           this, SLOT( onMinValue(double) ));
472   aRangeLayout->addWidget(myMinVal, 1, 1);
473
474   QLabel* aMaxLbl = new QLabel("To", aRangeGrp);
475   aMaxLbl->setEnabled(myUseRangeChk->isChecked());
476   aRangeLayout->addWidget(aMaxLbl, 1, 2);
477   myMaxVal = new QtxDblSpinBox( myAnimator->getMinTime(), myAnimator->getMaxTime(), aStep, aRangeGrp );
478   myMaxVal->setEnabled(myUseRangeChk->isChecked());
479   if (myUseRangeChk->isChecked())
480     myMaxVal->setValue( myAnimator->getMaxRange() );
481   else
482     myMaxVal->setValue( myAnimator->getMaxTime() );
483
484   connect(myMaxVal, SIGNAL( valueChanged(double)),
485           this, SLOT( onMaxValue(double) ));
486   aRangeLayout->addWidget(myMaxVal, 1, 3);
487
488   connect(myUseRangeChk, SIGNAL( toggled(bool)),
489           aMinLbl, SLOT( setEnabled(bool) ));
490   connect(myUseRangeChk, SIGNAL( toggled(bool)),
491           aMaxLbl, SLOT( setEnabled(bool) ));
492   connect(myUseRangeChk, SIGNAL( toggled(bool)),
493           this, SLOT( onRangeCheck(bool) ));
494
495   aMainLayout->addWidget(aRangeGrp);
496
497
498   QHBox* aPropFrame = new QHBox(this);
499   aPropFrame->setSpacing(5);
500
501   QVGroupBox* aNamesBox = new QVGroupBox("Fields",aPropFrame);
502   myFieldLst = new QListBox(aNamesBox);
503   QStringList aFieldNames;
504   // Find names of fields
505   for (int i = 0; i < theAnimator->getNbFields(); i++) {
506     _PTR(SObject) aSO = theAnimator->getFieldData(i).myField;
507     aFieldNames.append(VISU::getValue(aSO, "myName"));
508   }
509   myFieldLst->insertStringList(aFieldNames);
510   myFieldLst->setSelected(0, true);
511   connect( myFieldLst, SIGNAL( highlighted(int) ),
512            this, SLOT( onFieldChange(int) ) );
513
514
515   QVBox* aSetupBox = new QVBox(aPropFrame);
516   aSetupBox->setSpacing(5);
517
518   QVGroupBox* aPropBox = new QVGroupBox("Properties", aSetupBox);
519   //QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
520   myTypeCombo = new QComboBox(aPropBox);
521   connect( myTypeCombo, SIGNAL( activated(int) ),
522            this, SLOT( onTypeChanged(int) ) );
523
524   //  QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
525   //connect( aBarBtn, SIGNAL( clicked() ),
526   //       this, SLOT( onScalarBarDlg() ) );
527
528   myPropBtn = new QPushButton("Properties...", aPropBox);
529   //  myPropBtn->setEnabled(theAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
530   connect( myPropBtn, SIGNAL( clicked() ),
531            this, SLOT( onPreferencesDlg() ) );
532
533   if (myAnimator->getNbFields() > 1) {
534     myArrangeBtn = new QPushButton("Arrange...", aSetupBox);
535     connect( myArrangeBtn, SIGNAL( clicked() ), this, SLOT( onArrangeDlg() ) );
536   }
537   onFieldChange(0);
538   aMainLayout->addWidget(aPropFrame);
539
540   QHBox* aBtnBox = new QHBox(this);
541   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
542   aBtnLayout->addStretch();
543
544   QPushButton* aCloseBtn = new QPushButton(tr("BUT_OK"), aBtnBox);
545   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
546
547   aMainLayout->addWidget(aBtnBox);
548 }
549
550 //************************************************************************
551 enum PrsComboItem {
552   TSCALARMAP_ITEM     = 0, // VISU::TSCALARMAP
553   TISOSURFACE_ITEM    = 1, // VISU::TISOSURFACE
554   TCUTPLANES_ITEM     = 2, // VISU::TCUTPLANES
555   TPLOT3D_ITEM        = 3, // VISU::TPLOT3D
556   TDEFORMEDSHAPE_ITEM = 4, // VISU::TDEFORMEDSHAPE
557   TVECTORS_ITEM       = 5, // VISU::TVECTORS
558   TSTREAMLINES_ITEM   = 6  // VISU::TSTREAMLINES
559 };
560
561 //************************************************************************
562 void SetupDlg::onFieldChange (int theIndex)
563 {
564   FieldData& aData = myAnimator->getFieldData(theIndex);
565   myTypeCombo->clear();
566   // ATTENTION: append items in the same order like it is done in the PrsComboItem enumeration
567   myTypeCombo->insertItem("Scalar Map");   // item 0
568   myTypeCombo->insertItem("Iso Surfaces"); // item 1
569   myTypeCombo->insertItem("Cut Planes");   // item 2
570   myTypeCombo->insertItem("Plot 3D");      // item 3
571
572   _PTR(SObject) aSObject = aData.myField;
573   long aNumComp = VISU::getValue(aSObject, "myNumComponent").toLong();
574   if (aNumComp > 1) {
575     myTypeCombo->insertItem("Deformed Shape"); // item 4
576     myTypeCombo->insertItem("Vectors");        // item 5
577     myTypeCombo->insertItem("Stream Lines");   // item 6
578   }
579   switch (aData.myPrsType) {
580   case VISU::TSCALARMAP: //Scalar Map
581     myTypeCombo->setCurrentItem(TSCALARMAP_ITEM);
582     break;
583   case VISU::TISOSURFACE: //Iso Surfaces
584     myTypeCombo->setCurrentItem(TISOSURFACE_ITEM);
585     break;
586   case VISU::TCUTPLANES: //Cut Planes
587     myTypeCombo->setCurrentItem(TCUTPLANES_ITEM);
588     break;
589   case VISU::TPLOT3D: //Plot 3D
590     myTypeCombo->setCurrentItem(TPLOT3D_ITEM);
591     break;
592   case VISU::TDEFORMEDSHAPE: //Deformed Shape
593     myTypeCombo->setCurrentItem(TDEFORMEDSHAPE_ITEM);
594     break;
595   case VISU::TVECTORS: //Vectors
596     myTypeCombo->setCurrentItem(TVECTORS_ITEM);
597     break;
598   case VISU::TSTREAMLINES: //Stream Lines
599     myTypeCombo->setCurrentItem(TSTREAMLINES_ITEM);
600     aData.myPrsType = VISU::TSTREAMLINES;
601     break;
602   }
603   //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
604 }
605
606 //************************************************************************
607 void SetupDlg::onTypeChanged (int theIndex)
608 {
609   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
610   switch (theIndex) {
611   case TSCALARMAP_ITEM: //Scalar Map
612     aData.myPrsType = VISU::TSCALARMAP;
613     break;
614   case TISOSURFACE_ITEM: //Iso Surfaces
615     aData.myPrsType = VISU::TISOSURFACE;
616     break;
617   case TCUTPLANES_ITEM: //Cut Planes
618     aData.myPrsType = VISU::TCUTPLANES;
619     break;
620   case TPLOT3D_ITEM: //Plot 3D
621     aData.myPrsType = VISU::TPLOT3D;
622     break;
623   case TDEFORMEDSHAPE_ITEM: //Deformed Shape
624     aData.myPrsType = VISU::TDEFORMEDSHAPE;
625     break;
626   case TVECTORS_ITEM: //Vectors
627     aData.myPrsType = VISU::TVECTORS;
628     break;
629   case TSTREAMLINES_ITEM: //Stream Lines
630     aData.myPrsType = VISU::TSTREAMLINES;
631     break;
632   }
633   myAnimator->clearData(aData);
634   //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
635   //myAnimator->generatePresentations(myFieldLst->currentItem());
636 }
637
638 //************************************************************************
639 /*void SetupDlg::onScalarBarDlg() {
640   QApplication::setOverrideCursor( Qt::waitCursor );
641   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
642   if (aData.myPrs == 0)
643     myAnimator->generatePresentations(myFieldLst->currentItem());
644   QApplication::restoreOverrideCursor();
645
646   VisuGUI_ScalarBarDlg* aScalarBarDlg = new VisuGUI_ScalarBarDlg();
647   aScalarBarDlg->initFromPrsObject(aData.myPrs[0]);
648   if (aScalarBarDlg->exec()) {
649     for (int i = 0; i < aData.myNbFrames; i++)
650       aScalarBarDlg->storeToPrsObject(aData.myPrs[i]);
651   }
652 }
653 */
654
655 //************************************************************************
656 void SetupDlg::onPreferencesDlg()
657 {
658   SUIT_OverrideCursor c;
659   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
660   if (aData.myPrs.empty())
661     myAnimator->generatePresentations(myFieldLst->currentItem());
662
663 // BUG VISU5725 : Compatibility gcc 2.95
664 // #define EDITPRS(TYPE, DLG) \
665 //     { \
666 //       DLG* aDlg = new DLG(); \
667 //       aDlg->initFromPrsObject(dynamic_cast<TYPE*>(aData.myPrs.at(0))); \
668 //       if (aDlg->exec()) { \
669 //      for (int i = 0; i < aData.myNbFrames; i++) \
670 //        aDlg->storeToPrsObject(dynamic_cast<TYPE*>(aData.myPrs.at(i))); \
671 //       } \
672 //       delete aDlg; \
673 //     }
674
675
676 #define EDITPRS(TYPE, DLG) {\
677         DLG* aDlg = new DLG (myModule);\
678         aDlg->initFromPrsObject(dynamic_cast<TYPE*>(aData.myPrs[0]));\
679         if (aDlg->exec())\
680         { \
681          for (int i = 0; i < aData.myNbFrames; i++)\
682           aDlg->storeToPrsObject(dynamic_cast<TYPE*>(aData.myPrs[i]));\
683         } \
684         delete aDlg;}
685
686   switch (myTypeCombo->currentItem()) {
687   case TSCALARMAP_ITEM: //Scalar Map
688     c.suspend();
689     EDITPRS(VISU::ScalarMap_i, VisuGUI_ScalarBarDlg);
690     break;
691   case TISOSURFACE_ITEM: //Iso Surfaces
692     c.suspend();
693     EDITPRS(VISU::IsoSurfaces_i, VisuGUI_IsoSurfacesDlg);
694     break;
695   case TCUTPLANES_ITEM: //Cut Planes
696     c.suspend();
697     EDITPRS(VISU::CutPlanes_i, VisuGUI_CutPlanesDlg);
698     /*{
699       VisuGUI_CutPlanesDlg* aDlg = new VisuGUI_CutPlanesDlg (myModule);
700       //_CS_PhB :operator [] .at      aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(0)));
701       aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[0]));
702
703       if (aDlg->exec()) {
704         for (int i = 0; i < aData.myNbFrames; i++)
705       //_CS_PhB:operator [] .at   aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(i)));
706           aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[i]));
707       }
708       delete aDlg;
709     }*/
710     break;
711   case TPLOT3D_ITEM: //Plot 3D
712     c.suspend();
713     EDITPRS(VISU::Plot3D_i, VisuGUI_Plot3DDlg);
714     break;
715   case TDEFORMEDSHAPE_ITEM: //Deformed Shape
716     c.suspend();
717     EDITPRS(VISU::DeformedShape_i, VisuGUI_DeformedShapeDlg);
718     break;
719   case TVECTORS_ITEM: //Vectors
720     c.suspend();
721     EDITPRS(VISU::Vectors_i, VisuGUI_VectorsDlg);
722     break;
723   case TSTREAMLINES_ITEM: //Stream Lines
724     c.suspend();
725     EDITPRS(VISU::StreamLines_i, VisuGUI_StreamLinesDlg);
726     break;
727   }
728 #undef EDITPRS
729 }
730
731
732 //************************************************************************
733 void SetupDlg::onArrangeDlg()
734 {
735   ArrangeDlg aDlg(this, myAnimator);
736   aDlg.exec();
737 }
738
739 //************************************************************************
740 void SetupDlg::onRangeCheck (bool theCheck)
741 {
742   for (int i = 0; i < myAnimator->getNbFields(); i++)
743     myAnimator->clearData(myAnimator->getFieldData(i));
744
745   myMinVal->setEnabled(theCheck);
746   myMaxVal->setEnabled(theCheck);
747
748   if (!theCheck)
749     myAnimator->setAnimationRange(0, 0);
750   else {
751     //    if (myMinVal->value() < myMaxVal->value())
752     myAnimator->setAnimationRange(myMinVal->value(), myMaxVal->value());
753 //     else if (myMinVal->value() > myMaxVal->value())
754 //       myAnimator->setAnimationRange(myMaxVal->value(), myMinVal->value());
755 //     else // equal case
756 //       myAnimator->setAnimationRange(0, 0);
757   }
758 }
759
760 //************************************************************************
761 void SetupDlg::onMinValue (double theVal)
762 {
763   if (theVal > myAnimator->getMaxRange()) {
764     myMinVal->setValue( myAnimator->getMinTime() );
765     myMinVal->setFocus();
766     return;
767   }
768   for (int i = 0; i < myAnimator->getNbFields(); i++)
769     myAnimator->clearData(myAnimator->getFieldData(i));
770   myAnimator->setAnimationRange(theVal, myAnimator->getMaxRange());
771 }
772
773 //************************************************************************
774 void SetupDlg::onMaxValue (double theVal)
775 {
776   if (theVal < myAnimator->getMinRange()) {
777     myMaxVal->setValue( myAnimator->getMaxTime() );
778     myMaxVal->setFocus();
779     return;
780   }
781   for (int i = 0; i < myAnimator->getNbFields(); i++)
782     myAnimator->clearData(myAnimator->getFieldData(i));
783   myAnimator->setAnimationRange(myAnimator->getMinRange(), theVal);
784 }
785
786 static const char * firstIco[] = {
787 "18 10 2 1",
788 "       g None",
789 ".      g #000000",
790 "         .     .  ",
791 "  ..    ..    ..  ",
792 "  ..   ...   ...  ",
793 "  ..  ....  ....  ",
794 "  .. ..... .....  ",
795 "  .. ..... .....  ",
796 "  ..  ....  ....  ",
797 "  ..   ...   ...  ",
798 "  ..    ..    ..  ",
799 "         .     .  "};
800
801
802 static const char * lastIco[] = {
803 "18 10 2 1",
804 "       g None",
805 ".      g #000000",
806 "  .     .         ",
807 "  ..    ..    ..  ",
808 "  ...   ...   ..  ",
809 "  ....  ....  ..  ",
810 "  ..... ..... ..  ",
811 "  ..... ..... ..  ",
812 "  ....  ....  ..  ",
813 "  ...   ...   ..  ",
814 "  ..    ..    ..  ",
815 "  .     .         "};
816
817
818 static const char * leftIco[] = {
819 "11 10 2 1",
820 "       g None",
821 ".      g #000000",
822 "    .     .",
823 "   ..    ..",
824 "  ...   ...",
825 " ....  ....",
826 "..... .....",
827 "..... .....",
828 " ....  ....",
829 "  ...   ...",
830 "   ..    ..",
831 "    .     ."};
832
833 static const char * playIco[] = {
834 "14 14 2 1",
835 "       g None",
836 ".      g #000000",
837 "              ",
838 "              ",
839 "  ..          ",
840 "  ....        ",
841 "  ......      ",
842 "  ........    ",
843 "  ..........  ",
844 "  ..........  ",
845 "  ........    ",
846 "  ......      ",
847 "  ....        ",
848 "  ..          ",
849 "              ",
850 "              "};
851
852 static QPixmap MYplayPixmap(playIco);
853
854
855 static const char * rightIco[] = {
856 "11 10 2 1",
857 "       g None",
858 ".      g #000000",
859 ".     .    ",
860 "..    ..   ",
861 "...   ...  ",
862 "....  .... ",
863 "..... .....",
864 "..... .....",
865 "....  .... ",
866 "...   ...  ",
867 "..    ..   ",
868 ".     .    "};
869
870
871 static const char * pauseIco[] = {
872 "14 14 2 1",
873 "       g None",
874 ".      g #000000",
875 "              ",
876 "              ",
877 "   ..    ..   ",
878 "   ..    ..   ",
879 "   ..    ..   ",
880 "   ..    ..   ",
881 "   ..    ..   ",
882 "   ..    ..   ",
883 "   ..    ..   ",
884 "   ..    ..   ",
885 "   ..    ..   ",
886 "   ..    ..   ",
887 "              ",
888 "              "};
889
890 static QPixmap MYpausePixmap(pauseIco);
891
892
893 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (VisuGUI* theModule, _PTR(Study) theStudy)
894      : QDialog(VISU::GetDesktop(theModule), "VisuGUI_TimeAnimationDlg", false, WStyle_Customize |
895                WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
896        myModule(theModule),
897        myStudy(theStudy)
898 {
899   setCaption("Animation");
900   setSizeGripEnabled( TRUE );
901   isClosing = false;
902
903   myAnimator = new VISU_TimeAnimation (theStudy);
904   myAnimator->setSpeed(1);
905   myAnimator->setViewer(VISU::GetViewWindow());
906   connect(myAnimator, SIGNAL(frameChanged(long, double)), this, SLOT(onExecution(long, double)));
907   connect(myAnimator, SIGNAL(stopped()),                  this, SLOT(onStop()));
908
909   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
910   aMainLayout->setSpacing(5);
911
912   mySetupBtn = new QPushButton("Setup Animation...", this);
913   connect( mySetupBtn, SIGNAL( clicked() ),
914            this, SLOT( onSetupDlg() ) );
915   aMainLayout->addWidget(mySetupBtn);
916
917   myGenBtn = new QPushButton("Generate frames", this);
918   connect( myGenBtn, SIGNAL( clicked() ),
919            this, SLOT( createFrames() ) );
920   aMainLayout->addWidget(myGenBtn);
921
922   myPlayFrame = new QFrame(this);
923   myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
924   myPlayFrame->setLineWidth( 1 );
925
926
927   // --- Play controls ---
928   QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
929   TopLayout->setSpacing( 6 );
930   TopLayout->setMargin( 11 );
931
932   myTimeLbl = new QLabel("0", myPlayFrame);
933   TopLayout->addMultiCellWidget(myTimeLbl, 0, 0, 0, 2, Qt::AlignHCenter);
934
935   mySlider = new QSlider(Qt::Horizontal, myPlayFrame);
936   mySlider->setMinValue(0);
937   mySlider->setMaxValue(3);
938   mySlider->setTickInterval(1);
939   //mySlider->setTickmarks(QSlider::Below);
940   mySlider->setTracking(false);
941   connect( mySlider, SIGNAL( valueChanged(int) ),
942            this, SLOT( onWindowChanged(int) ) );
943   TopLayout->addMultiCellWidget(mySlider, 1, 1, 0, 2);
944
945   myPlayBtn = new QToolButton(myPlayFrame);
946   myPlayBtn->setIconSet(MYplayPixmap);
947   myPlayBtn->setToggleButton(true);
948   connect( myPlayBtn, SIGNAL( clicked() ),
949            this, SLOT( onPlayPressed() ) );
950   TopLayout->addMultiCellWidget(myPlayBtn, 2, 2, 0, 1);
951
952   QToolButton* aBackBtn = new QToolButton(myPlayFrame);
953   aBackBtn->setIconSet(QPixmap(leftIco));
954   connect( aBackBtn, SIGNAL( clicked() ),
955            this, SLOT( onBackPressed() ) );
956   TopLayout->addWidget(aBackBtn, 3, 0);
957
958   QToolButton* aForvardBtn = new QToolButton(myPlayFrame);
959   aForvardBtn->setIconSet(QPixmap(rightIco));
960   connect( aForvardBtn, SIGNAL( clicked() ),
961            this, SLOT( onForvardPressed() ) );
962   TopLayout->addWidget(aForvardBtn, 3, 1);
963
964   QToolButton* aFirstBtn = new QToolButton(myPlayFrame);
965   aFirstBtn->setIconSet(QPixmap(firstIco));
966   connect( aFirstBtn, SIGNAL( clicked() ),
967            this, SLOT( onFirstPressed() ) );
968   TopLayout->addWidget(aFirstBtn, 4, 0);
969
970   QToolButton* aLastBtn = new QToolButton(myPlayFrame);
971   aLastBtn->setIconSet(QPixmap(lastIco));
972   connect( aLastBtn, SIGNAL( clicked() ),
973            this, SLOT( onLastPressed() ) );
974   TopLayout->addWidget(aLastBtn, 4, 1);
975
976   QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
977   TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
978
979   QLCDNumber* aSpeedNum  = new QLCDNumber( 2, myPlayFrame );
980   aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
981   aSpeedNum->display(1);
982   TopLayout->addWidget(aSpeedNum, 4, 3);
983
984   QwtWheel* aWheel = new QwtWheel(myPlayFrame);
985   aWheel->setOrientation(Qt::Vertical);
986   aWheel->setRange(1, 99, 1);
987   connect( aWheel, SIGNAL(valueChanged(double)),
988            aSpeedNum, SLOT(display(double)) );
989   connect( aWheel, SIGNAL(valueChanged(double)),
990            this, SLOT(onSpeedChange(double)) );
991   TopLayout->addMultiCellWidget(aWheel, 1, 3, 3, 3, Qt::AlignRight);
992
993   QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
994   aCycleCheck->setChecked(myAnimator->isCycling());
995   connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
996   TopLayout->addMultiCellWidget(aCycleCheck, 5, 5, 0, 3);
997
998   QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
999   aPropCheck->setChecked(myAnimator->isProportional());
1000   connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
1001   TopLayout->addMultiCellWidget(aPropCheck, 6, 6, 0, 3);
1002
1003   QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
1004   aSaveBox->setColumnLayout(0, Qt::Horizontal );
1005   QGridLayout* aSaveLay = new QGridLayout(aSaveBox->layout());
1006   aSaveLay->setSpacing( 5 );
1007   aSaveLay->setMargin( 5 );
1008
1009   mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
1010   aSaveLay->addMultiCellWidget(mySaveCheck, 0, 0, 0, 2);
1011   connect(mySaveCheck, SIGNAL( toggled(bool)),
1012           aWheel, SLOT( setDisabled(bool) ));
1013
1014   QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
1015   aPathLbl->setEnabled(false);
1016   connect(mySaveCheck, SIGNAL( toggled(bool)),
1017           aPathLbl, SLOT( setEnabled(bool) ));
1018   aSaveLay->addWidget(aPathLbl, 1, 0);
1019
1020   myPathEdit = new QLineEdit(aSaveBox);
1021   myPathEdit->setEnabled(false);
1022   connect(mySaveCheck, SIGNAL( toggled(bool)),
1023           myPathEdit, SLOT( setEnabled(bool) ));
1024   aSaveLay->addWidget(myPathEdit, 1, 1);
1025
1026   QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
1027   aBrowseBtn->setEnabled(false);
1028   connect(mySaveCheck, SIGNAL( toggled(bool)),
1029           aBrowseBtn, SLOT( setEnabled(bool) ));
1030   connect(aBrowseBtn, SIGNAL( clicked()),
1031           this, SLOT( onBrowse() ));
1032   mySaveCheck->setChecked(false);
1033   aSaveLay->addWidget(aBrowseBtn, 1, 2);
1034
1035   TopLayout->addMultiCellWidget(aSaveBox, 7, 7, 0, 3);
1036
1037   aMainLayout->addWidget(myPlayFrame);
1038
1039   QHBox* aPublishBox = new QHBox(this);
1040   aPublishBox->setSpacing(5);
1041
1042   myPublishBtn = new QPushButton("Publish to study", aPublishBox);
1043   connect(myPublishBtn, SIGNAL(clicked()), this, SLOT(publishToStudy()));
1044
1045   mySaveBtn = new QPushButton("Save Animation", aPublishBox);
1046   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1047   connect(mySaveBtn, SIGNAL(clicked()), this, SLOT(saveToStudy()));
1048
1049   aMainLayout->addWidget(aPublishBox);
1050
1051
1052   QHBox* aBtnBox = new QHBox(this);
1053   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
1054   aBtnLayout->addStretch();
1055
1056   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
1057   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
1058
1059   SUIT_Study* aStudy = VISU::GetAppStudy(myModule);
1060   connect(aStudy, SIGNAL(destroyed()), this, SLOT(close()));
1061
1062   aMainLayout->addWidget(aBtnBox);
1063
1064   myPlayFrame->setEnabled(false);
1065 }
1066
1067 //************************************************************************
1068 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg()
1069 {
1070   delete myAnimator;
1071 }
1072
1073 //************************************************************************
1074 void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
1075 {
1076   stopAnimation();
1077   myPropBtn->setEnabled(index != 0);
1078
1079   clearView();
1080   myPlayFrame->setEnabled(false);
1081 }
1082
1083 //************************************************************************
1084 void VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
1085 {
1086   myPlayFrame->setEnabled(false);
1087   myAnimator->addField(theSObject);
1088 }
1089
1090 //************************************************************************
1091 void VisuGUI_TimeAnimationDlg::createFrames()
1092 {
1093   stopAnimation();
1094   SUIT_OverrideCursor c;
1095
1096   for (int i = 0; i < myAnimator->getNbFields(); i++) {
1097     if (myAnimator->getFieldData(i).myPrs.empty())
1098       myAnimator->generatePresentations(i);
1099   }
1100   if (myAnimator->getNbFrames() == 0) {
1101     myPlayFrame->setEnabled(false);
1102     c.suspend();
1103     SUIT_MessageBox::warn1(this,
1104                            tr("ERROR"),
1105                            tr("MSG_NO_ANIMATIONDATA"),
1106                            tr("&OK"));
1107     return;
1108   }
1109   mySlider->setMaxValue(myAnimator->getNbFrames()-1);
1110   myPlayFrame->setEnabled(true);
1111   if (!myAnimator->generateFrames()) {
1112     c.suspend();
1113     //myPlayFrame->setEnabled(false);
1114     SUIT_MessageBox::warn1(this,
1115                            tr("ERROR"),
1116                            myAnimator->getLastErrorMsg(),
1117                            tr("&OK"));
1118     return;
1119   }
1120   //myPlayFrame->setEnabled(true);
1121 }
1122
1123 //************************************************************************
1124 void VisuGUI_TimeAnimationDlg::onPlayPressed()
1125 {
1126   if (myPlayBtn->isOn() && (!myAnimator->running())) {
1127     myPlayBtn->setIconSet(MYpausePixmap);
1128     if (mySaveCheck->isChecked())
1129       myAnimator->dumpTo(myPathEdit->text());
1130     else
1131       myAnimator->dumpTo("");
1132     mySetupBtn->setEnabled(false);
1133     myGenBtn->setEnabled(false);
1134     myAnimator->startAnimation();
1135   } else {
1136     myPlayBtn->setIconSet(MYplayPixmap);
1137     myAnimator->stopAnimation();
1138     mySetupBtn->setEnabled(true);
1139     myGenBtn->setEnabled(true);
1140   }
1141 }
1142
1143 //************************************************************************
1144 void VisuGUI_TimeAnimationDlg::onBackPressed()
1145 {
1146   //stopAnimation();
1147   myAnimator->prevFrame();
1148 }
1149
1150 //************************************************************************
1151 void VisuGUI_TimeAnimationDlg::onForvardPressed()
1152 {
1153   myAnimator->nextFrame();
1154 }
1155
1156 //************************************************************************
1157 void VisuGUI_TimeAnimationDlg::onLastPressed()
1158 {
1159   myAnimator->lastFrame();
1160 }
1161
1162 //************************************************************************
1163 void VisuGUI_TimeAnimationDlg::onFirstPressed()
1164 {
1165   myAnimator->firstFrame();
1166 }
1167
1168 //************************************************************************
1169 void VisuGUI_TimeAnimationDlg::clearView()
1170 {
1171   myAnimator->clearView();
1172 }
1173
1174 //************************************************************************
1175 void VisuGUI_TimeAnimationDlg::closeEvent (QCloseEvent* theEvent)
1176 {
1177   myAnimator->stopAnimation();
1178   myAnimator->wait(500);
1179   if (myAnimator->running() && (! myAnimator->finished())) {
1180     isClosing = true;
1181     myEvent = theEvent;
1182   } else {
1183     QDialog::closeEvent(theEvent);
1184   }
1185 }
1186
1187 //************************************************************************
1188 void VisuGUI_TimeAnimationDlg::onWindowChanged (int index)
1189 {
1190   if (myAnimator->isRunning()) return;
1191   myAnimator->gotoFrame(index);
1192 }
1193
1194 //************************************************************************
1195 void VisuGUI_TimeAnimationDlg::onSpeedChange (double theSpeed)
1196 {
1197   myAnimator->setSpeed((int)theSpeed);
1198 }
1199
1200 //************************************************************************
1201 void VisuGUI_TimeAnimationDlg::stopAnimation()
1202 {
1203   myAnimator->stopAnimation();
1204   myPlayBtn->setOn(false);
1205   myPlayBtn->setIconSet(MYplayPixmap);
1206   mySetupBtn->setEnabled(true);
1207   myGenBtn->setEnabled(true);
1208 }
1209
1210 //************************************************************************
1211 void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
1212 {
1213   myTimeLbl->setText(QString("%1").arg(theTime));
1214   mySlider->setValue(theNewFrame);
1215 }
1216
1217 //************************************************************************
1218 void VisuGUI_TimeAnimationDlg::onSetupDlg()
1219 {
1220   if (myAnimator->getNbFrames() > 0) myAnimator->firstFrame();
1221   SetupDlg* aDlg = new SetupDlg (myModule, myAnimator);
1222   aDlg->exec();
1223   myPlayFrame->setEnabled(false);
1224   delete aDlg;
1225 }
1226
1227 //************************************************************************
1228 void VisuGUI_TimeAnimationDlg::onBrowse()
1229 {
1230   QString aPath = SUIT_FileDlg::getExistingDirectory(this, "/","Select path");
1231   if (!aPath.isEmpty())
1232     myPathEdit->setText(aPath);
1233 }
1234
1235 //************************************************************************
1236 void VisuGUI_TimeAnimationDlg::onStop()
1237 {
1238   if (isClosing) {
1239     QDialog::closeEvent(myEvent);
1240   } else {
1241     myPlayBtn->setOn(false);
1242     myPlayBtn->setIconSet(MYplayPixmap);
1243     mySetupBtn->setEnabled(true);
1244     myGenBtn->setEnabled(true);
1245   }
1246 }
1247
1248 //************************************************************************
1249 void VisuGUI_TimeAnimationDlg::saveToStudy()
1250 {
1251   myAnimator->saveAnimation();
1252   VISU::UpdateObjBrowser(myModule, true);
1253 }
1254
1255 //************************************************************************
1256 void VisuGUI_TimeAnimationDlg::publishToStudy()
1257 {
1258   myAnimator->publishInStudy();
1259   VISU::UpdateObjBrowser(myModule, true);
1260   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1261 }
1262
1263 //************************************************************************
1264 void VisuGUI_TimeAnimationDlg::restoreFromStudy(_PTR(SObject) theAnimation)
1265 {
1266   myAnimator->restoreFromStudy(theAnimation);
1267   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1268 }