Salome HOME
IPAL9283,9286,9295,9296,9297; some icons restored
[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_VectorsDlg.h"
18 #include "VisuGUI_IsoSurfacesDlg.h"
19 #include "VisuGUI_StreamLinesDlg.h"
20
21 #include "VISU_TimeAnimation.h"
22
23 #include "VISU_ScalarMap_i.hh"
24 #include "VISU_IsoSurfaces_i.hh"
25 #include "VISU_DeformedShape_i.hh"
26 #include "VISU_CutPlanes_i.hh"
27 #include "VISU_CutLines_i.hh"
28 #include "VISU_Vectors_i.hh"
29 #include "VISU_StreamLines_i.hh"
30
31 #include "VISU_ScalarBarActor.hxx"
32
33 #include "SalomeApp_Application.h"
34
35 #include "SUIT_OverrideCursor.h"
36 #include "SUIT_MessageBox.h"
37 #include "SUIT_Desktop.h"
38 #include "SUIT_FileDlg.h"
39
40 #include <qlayout.h>
41 #include <qhbox.h>
42 #include <qhgroupbox.h>
43 #include <qwt_wheel.h>
44 #include <qlcdnumber.h>
45 #include <qlistbox.h>
46 #include <qvgroupbox.h>
47 #include <qthread.h>
48
49 //static double MAXVALUE = 1.0E+300;
50
51
52 SetupDlg::SetupDlg (QWidget* theParent, VISU_TimeAnimation* theAnimator)
53      : QDialog(theParent, "SetupDlg", true, WStyle_Customize |
54                WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
55 {
56   setCaption("Setup Animation");
57   setSizeGripEnabled( TRUE );
58   myAnimator = theAnimator;
59
60   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
61   aMainLayout->setSpacing(5);
62
63
64   QFrame* aRangeGrp = new QFrame(this);
65   QGridLayout* aRangeLayout = new QGridLayout( aRangeGrp );
66   aRangeLayout->setSpacing( 6 );
67   aRangeLayout->setMargin( 11 );
68   aRangeGrp->setFrameStyle(QFrame::Box | QFrame::Raised);
69
70   myUseRangeChk = new QCheckBox("Use range of time stamps", aRangeGrp);
71   aRangeLayout->addMultiCellWidget(myUseRangeChk, 0, 0, 0, 3);
72   myUseRangeChk->setChecked(myAnimator->isRangeDefined());
73
74   QLabel* aMinLbl = new QLabel("From", aRangeGrp);
75   aMinLbl->setEnabled(myUseRangeChk->isChecked());
76   aRangeLayout->addWidget(aMinLbl, 1, 0);
77   double aStep = (myAnimator->getMaxTime() - myAnimator->getMinTime())/(theAnimator->getFieldData(0).myNbTimes - 1);
78   myMinVal = new QtxDblSpinBox( myAnimator->getMinTime(), myAnimator->getMaxTime(), aStep, aRangeGrp );
79   myMinVal->setEnabled(myUseRangeChk->isChecked());
80   if (myUseRangeChk->isChecked())
81     myMinVal->setValue( myAnimator->getMinRange() );
82   else
83     myMinVal->setValue( myAnimator->getMinTime() );
84
85   connect(myMinVal, SIGNAL( valueChanged(double)),
86           this, SLOT( onMinValue(double) ));
87   aRangeLayout->addWidget(myMinVal, 1, 1);
88
89   QLabel* aMaxLbl = new QLabel("To", aRangeGrp);
90   aMaxLbl->setEnabled(myUseRangeChk->isChecked());
91   aRangeLayout->addWidget(aMaxLbl, 1, 2);
92   myMaxVal = new QtxDblSpinBox( myAnimator->getMinTime(), myAnimator->getMaxTime(), aStep, aRangeGrp );
93   myMaxVal->setEnabled(myUseRangeChk->isChecked());
94   if (myUseRangeChk->isChecked())
95     myMaxVal->setValue( myAnimator->getMaxRange() );
96   else
97     myMaxVal->setValue( myAnimator->getMaxTime() );
98
99   connect(myMaxVal, SIGNAL( valueChanged(double)),
100           this, SLOT( onMaxValue(double) ));
101   aRangeLayout->addWidget(myMaxVal, 1, 3);
102
103   connect(myUseRangeChk, SIGNAL( toggled(bool)),
104           aMinLbl, SLOT( setEnabled(bool) ));
105   connect(myUseRangeChk, SIGNAL( toggled(bool)),
106           aMaxLbl, SLOT( setEnabled(bool) ));
107   connect(myUseRangeChk, SIGNAL( toggled(bool)),
108           this, SLOT( onRangeCheck(bool) ));
109
110   aMainLayout->addWidget(aRangeGrp);
111
112
113   QHBox* aPropFrame = new QHBox(this);
114   aPropFrame->setSpacing(5);
115
116   QVGroupBox* aNamesBox = new QVGroupBox("Fields",aPropFrame);
117   myFieldLst = new QListBox(aNamesBox);
118   QStringList aFieldNames;
119   // Find names of fields
120   for (int i = 0; i < theAnimator->getNbFields(); i++) {
121     _PTR(SObject) aSO = theAnimator->getFieldData(i).myField;
122     aFieldNames.append(VISU::getValue(aSO, "myName"));
123   }
124   myFieldLst->insertStringList(aFieldNames);
125   myFieldLst->setSelected(0, true);
126   connect( myFieldLst, SIGNAL( highlighted(int) ),
127            this, SLOT( onFieldChange(int) ) );
128
129
130   QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
131   myTypeCombo = new QComboBox(aPropBox);
132   connect( myTypeCombo, SIGNAL( activated(int) ),
133            this, SLOT( onTypeChanged(int) ) );
134
135   //  QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
136   //connect( aBarBtn, SIGNAL( clicked() ),
137   //       this, SLOT( onScalarBarDlg() ) );
138
139   myPropBtn = new QPushButton("Properties...", aPropBox);
140   //  myPropBtn->setEnabled(theAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
141   connect( myPropBtn, SIGNAL( clicked() ),
142            this, SLOT( onPreferencesDlg() ) );
143
144   onFieldChange(0);
145   aMainLayout->addWidget(aPropFrame);
146
147   QHBox* aBtnBox = new QHBox(this);
148   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
149   aBtnLayout->addStretch();
150
151   QPushButton* aCloseBtn = new QPushButton(tr("BUT_OK"), aBtnBox);
152   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
153
154   aMainLayout->addWidget(aBtnBox);
155 }
156
157 //************************************************************************
158 void SetupDlg::onFieldChange (int theIndex)
159 {
160   FieldData& aData = myAnimator->getFieldData(theIndex);
161   myTypeCombo->clear();
162   myTypeCombo->insertItem("Scalar Map");
163   myTypeCombo->insertItem("Iso Surfaces");
164   myTypeCombo->insertItem("Cut Planes");
165
166   _PTR(SObject) aSObject = aData.myField;
167   long aNumComp = VISU::getValue(aSObject, "myNumComponent").toLong();
168   if (aNumComp > 1) {
169     myTypeCombo->insertItem("Deformed Shape");
170     myTypeCombo->insertItem("Vectors");
171     myTypeCombo->insertItem("Stream Lines");
172   }
173   switch (aData.myPrsType) {
174   case VISU::TSCALARMAP: //Scalar Map
175     myTypeCombo->setCurrentItem(0);
176     break;
177   case VISU::TISOSURFACE: //Iso Surfaces
178     myTypeCombo->setCurrentItem(1);
179     break;
180   case VISU::TCUTPLANES: //Cut Planes
181     myTypeCombo->setCurrentItem(2);
182     break;
183   case VISU::TDEFORMEDSHAPE: //Deformed Shape
184     myTypeCombo->setCurrentItem(3);
185     break;
186   case VISU::TVECTORS: //Vectors
187     myTypeCombo->setCurrentItem(4);
188     break;
189   case VISU::TSTREAMLINES: //Stream Lines
190     myTypeCombo->setCurrentItem(5);
191     aData.myPrsType = VISU::TSTREAMLINES;
192     break;
193   }
194   //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
195 }
196
197 //************************************************************************
198 void SetupDlg::onTypeChanged (int theIndex)
199 {
200   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
201   switch (theIndex) {
202   case 0: //Scalar Map
203     aData.myPrsType = VISU::TSCALARMAP;
204     break;
205   case 1: //Iso Surfaces
206     aData.myPrsType = VISU::TISOSURFACE;
207     break;
208   case 2: //Cut Planes
209     aData.myPrsType = VISU::TCUTPLANES;
210     break;
211   case 3: //Deformed Shape
212     aData.myPrsType = VISU::TDEFORMEDSHAPE;
213     break;
214   case 4: //Vectors
215     aData.myPrsType = VISU::TVECTORS;
216     break;
217   case 5: //Stream Lines
218     aData.myPrsType = VISU::TSTREAMLINES;
219     break;
220   }
221   myAnimator->clearData(aData);
222   //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
223   //myAnimator->generatePresentations(myFieldLst->currentItem());
224 }
225
226 //************************************************************************
227 /*void SetupDlg::onScalarBarDlg() {
228   QApplication::setOverrideCursor( Qt::waitCursor );
229   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
230   if (aData.myPrs == 0)
231     myAnimator->generatePresentations(myFieldLst->currentItem());
232   QApplication::restoreOverrideCursor();
233
234   VisuGUI_ScalarBarDlg* aScalarBarDlg = new VisuGUI_ScalarBarDlg();
235   aScalarBarDlg->initFromPrsObject(aData.myPrs[0]);
236   if (aScalarBarDlg->exec()) {
237     for (int i = 0; i < aData.myNbFrames; i++)
238       aScalarBarDlg->storeToPrsObject(aData.myPrs[i]);
239   }
240 }
241 */
242
243 //************************************************************************
244 void SetupDlg::onPreferencesDlg()
245 {
246   MESSAGE("SetupDlg::onPreferencesDlg() is not implemented");
247 /*  SUIT_OverrideCursor c;
248   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
249   if (aData.myPrs.empty())
250     myAnimator->generatePresentations(myFieldLst->currentItem());
251
252 // BUG VISU5725 : Compatibility gcc 2.95
253 // #define EDITPRS(TYPE, DLG) \
254 //     { \
255 //       DLG* aDlg = new DLG(); \
256 //       aDlg->initFromPrsObject(dynamic_cast<TYPE*>(aData.myPrs.at(0))); \
257 //       if (aDlg->exec()) { \
258 //      for (int i = 0; i < aData.myNbFrames; i++) \
259 //        aDlg->storeToPrsObject(dynamic_cast<TYPE*>(aData.myPrs.at(i))); \
260 //       } \
261 //       delete aDlg; \
262 //     }
263
264
265 #define EDITPRS(TYPE, DLG) {DLG* aDlg = new DLG(); aDlg->initFromPrsObject(dynamic_cast<TYPE*>(aData.myPrs[0])); if (aDlg->exec()) { for (int i = 0; i < aData.myNbFrames; i++) aDlg->storeToPrsObject(dynamic_cast<TYPE*>(aData.myPrs[i])); } delete aDlg;}
266
267   switch (myTypeCombo->currentItem()) {
268   case 0: //Scalar Map
269     EDITPRS(VISU::ScalarMap_i, VisuGUI_ScalarBarDlg);
270     break;
271   case 1: //Iso Surfaces
272     EDITPRS(VISU::IsoSurfaces_i, VisuGUI_IsoSurfacesDlg);
273     break;
274   case 2: //Cut Planes
275     //    EDITPRS(VISU::CutPlanes_i, VisuGUI_CutPlanesDlg);
276     {
277       VisuGUI_CutPlanesDlg* aDlg = new VisuGUI_CutPlanesDlg(false, true);
278       //_CS_PhB :operator [] .at      aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(0)));
279       aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[0]));
280
281       if (aDlg->exec()) {
282         for (int i = 0; i < aData.myNbFrames; i++)
283       //_CS_PhB:operator [] .at   aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(i)));
284           aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[i]));
285       }
286       delete aDlg;
287     }
288     break;
289   case 3: //Deformed Shape
290     EDITPRS(VISU::DeformedShape_i, VisuGUI_DeformedShapeDlg);
291     break;
292   case 4: //Vectors
293     EDITPRS(VISU::Vectors_i, VisuGUI_VectorsDlg);
294     break;
295   case 5: //Stream Lines
296     EDITPRS(VISU::StreamLines_i, VisuGUI_StreamLinesDlg);
297     break;
298   }
299 #undef EDITPRS
300 */
301 }
302
303 //************************************************************************
304 void SetupDlg::onRangeCheck (bool theCheck)
305 {
306   for (int i = 0; i < myAnimator->getNbFields(); i++)
307     myAnimator->clearData(myAnimator->getFieldData(i));
308
309   myMinVal->setEnabled(theCheck);
310   myMaxVal->setEnabled(theCheck);
311
312   if (!theCheck)
313     myAnimator->setAnimationRange(0, 0);
314   else {
315     //    if (myMinVal->value() < myMaxVal->value())
316     myAnimator->setAnimationRange(myMinVal->value(), myMaxVal->value());
317 //     else if (myMinVal->value() > myMaxVal->value())
318 //       myAnimator->setAnimationRange(myMaxVal->value(), myMinVal->value());
319 //     else // equal case
320 //       myAnimator->setAnimationRange(0, 0);
321   }
322 }
323
324 //************************************************************************
325 void SetupDlg::onMinValue (double theVal)
326 {
327   if (theVal > myAnimator->getMaxRange()) {
328     myMinVal->setValue( myAnimator->getMinTime() );
329     myMinVal->setFocus();
330     return;
331   }
332   for (int i = 0; i < myAnimator->getNbFields(); i++)
333     myAnimator->clearData(myAnimator->getFieldData(i));
334   myAnimator->setAnimationRange(theVal, myAnimator->getMaxRange());
335 }
336
337 //************************************************************************
338 void SetupDlg::onMaxValue (double theVal)
339 {
340   if (theVal < myAnimator->getMinRange()) {
341     myMaxVal->setValue( myAnimator->getMaxTime() );
342     myMaxVal->setFocus();
343     return;
344   }
345   for (int i = 0; i < myAnimator->getNbFields(); i++)
346     myAnimator->clearData(myAnimator->getFieldData(i));
347   myAnimator->setAnimationRange(myAnimator->getMinRange(), theVal);
348 }
349
350 static const char * firstIco[] = {
351 "18 10 2 1",
352 "       g None",
353 ".      g #000000",
354 "         .     .  ",
355 "  ..    ..    ..  ",
356 "  ..   ...   ...  ",
357 "  ..  ....  ....  ",
358 "  .. ..... .....  ",
359 "  .. ..... .....  ",
360 "  ..  ....  ....  ",
361 "  ..   ...   ...  ",
362 "  ..    ..    ..  ",
363 "         .     .  "};
364
365
366 static const char * lastIco[] = {
367 "18 10 2 1",
368 "       g None",
369 ".      g #000000",
370 "  .     .         ",
371 "  ..    ..    ..  ",
372 "  ...   ...   ..  ",
373 "  ....  ....  ..  ",
374 "  ..... ..... ..  ",
375 "  ..... ..... ..  ",
376 "  ....  ....  ..  ",
377 "  ...   ...   ..  ",
378 "  ..    ..    ..  ",
379 "  .     .         "};
380
381
382 static const char * leftIco[] = {
383 "11 10 2 1",
384 "       g None",
385 ".      g #000000",
386 "    .     .",
387 "   ..    ..",
388 "  ...   ...",
389 " ....  ....",
390 "..... .....",
391 "..... .....",
392 " ....  ....",
393 "  ...   ...",
394 "   ..    ..",
395 "    .     ."};
396
397 static const char * playIco[] = {
398 "14 14 2 1",
399 "       g None",
400 ".      g #000000",
401 "              ",
402 "              ",
403 "  ..          ",
404 "  ....        ",
405 "  ......      ",
406 "  ........    ",
407 "  ..........  ",
408 "  ..........  ",
409 "  ........    ",
410 "  ......      ",
411 "  ....        ",
412 "  ..          ",
413 "              ",
414 "              "};
415
416 static QPixmap MYplayPixmap(playIco);
417
418
419 static const char * rightIco[] = {
420 "11 10 2 1",
421 "       g None",
422 ".      g #000000",
423 ".     .    ",
424 "..    ..   ",
425 "...   ...  ",
426 "....  .... ",
427 "..... .....",
428 "..... .....",
429 "....  .... ",
430 "...   ...  ",
431 "..    ..   ",
432 ".     .    "};
433
434
435 static const char * pauseIco[] = {
436 "14 14 2 1",
437 "       g None",
438 ".      g #000000",
439 "              ",
440 "              ",
441 "   ..    ..   ",
442 "   ..    ..   ",
443 "   ..    ..   ",
444 "   ..    ..   ",
445 "   ..    ..   ",
446 "   ..    ..   ",
447 "   ..    ..   ",
448 "   ..    ..   ",
449 "   ..    ..   ",
450 "   ..    ..   ",
451 "              ",
452 "              "};
453
454 static QPixmap MYpausePixmap(pauseIco);
455
456
457 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (QWidget* parent, _PTR(Study) theStudy)
458      : QDialog(parent, "VisuGUI_TimeAnimationDlg", false, WStyle_Customize |
459                WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose)
460 {
461   setCaption("Animation");
462   setSizeGripEnabled( TRUE );
463   myStudy = theStudy;
464   isClosing = false;
465
466   //myAnimator = new VISU_TimeAnimation (VISU::GetDSStudy(theStudy));
467   myAnimator = new VISU_TimeAnimation (theStudy);
468   myAnimator->setSpeed(1);
469   myAnimator->setViewer(VISU::GetViewWindow());
470   connect(myAnimator, SIGNAL(frameChanged(long, double)), this, SLOT(onExecution(long, double)));
471   connect(myAnimator, SIGNAL(stopped()),                  this, SLOT(onStop()));
472
473   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
474   aMainLayout->setSpacing(5);
475
476   mySetupBtn = new QPushButton("Setup Animation...", this);
477   connect( mySetupBtn, SIGNAL( clicked() ),
478            this, SLOT( onSetupDlg() ) );
479   aMainLayout->addWidget(mySetupBtn);
480
481   myGenBtn = new QPushButton("Generate frames", this);
482   connect( myGenBtn, SIGNAL( clicked() ),
483            this, SLOT( createFrames() ) );
484   aMainLayout->addWidget(myGenBtn);
485
486   myPlayFrame = new QFrame(this);
487   myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
488   myPlayFrame->setLineWidth( 1 );
489
490
491   // --- Play controls ---
492   QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
493   TopLayout->setSpacing( 6 );
494   TopLayout->setMargin( 11 );
495
496   myTimeLbl = new QLabel("0", myPlayFrame);
497   TopLayout->addMultiCellWidget(myTimeLbl, 0, 0, 0, 2, Qt::AlignHCenter);
498
499   mySlider = new QSlider(Qt::Horizontal, myPlayFrame);
500   mySlider->setMinValue(0);
501   mySlider->setMaxValue(3);
502   mySlider->setTickInterval(1);
503   //mySlider->setTickmarks(QSlider::Below);
504   mySlider->setTracking(false);
505   connect( mySlider, SIGNAL( valueChanged(int) ),
506            this, SLOT( onWindowChanged(int) ) );
507   TopLayout->addMultiCellWidget(mySlider, 1, 1, 0, 2);
508
509   myPlayBtn = new QToolButton(myPlayFrame);
510   myPlayBtn->setIconSet(MYplayPixmap);
511   myPlayBtn->setToggleButton(true);
512   connect( myPlayBtn, SIGNAL( clicked() ),
513            this, SLOT( onPlayPressed() ) );
514   TopLayout->addMultiCellWidget(myPlayBtn, 2, 2, 0, 1);
515
516   QToolButton* aBackBtn = new QToolButton(myPlayFrame);
517   aBackBtn->setIconSet(QPixmap(leftIco));
518   connect( aBackBtn, SIGNAL( clicked() ),
519            this, SLOT( onBackPressed() ) );
520   TopLayout->addWidget(aBackBtn, 3, 0);
521
522   QToolButton* aForvardBtn = new QToolButton(myPlayFrame);
523   aForvardBtn->setIconSet(QPixmap(rightIco));
524   connect( aForvardBtn, SIGNAL( clicked() ),
525            this, SLOT( onForvardPressed() ) );
526   TopLayout->addWidget(aForvardBtn, 3, 1);
527
528   QToolButton* aFirstBtn = new QToolButton(myPlayFrame);
529   aFirstBtn->setIconSet(QPixmap(firstIco));
530   connect( aFirstBtn, SIGNAL( clicked() ),
531            this, SLOT( onFirstPressed() ) );
532   TopLayout->addWidget(aFirstBtn, 4, 0);
533
534   QToolButton* aLastBtn = new QToolButton(myPlayFrame);
535   aLastBtn->setIconSet(QPixmap(lastIco));
536   connect( aLastBtn, SIGNAL( clicked() ),
537            this, SLOT( onLastPressed() ) );
538   TopLayout->addWidget(aLastBtn, 4, 1);
539
540   QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
541   TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
542
543   QLCDNumber* aSpeedNum  = new QLCDNumber( 2, myPlayFrame );
544   aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
545   aSpeedNum->display(1);
546   TopLayout->addWidget(aSpeedNum, 4, 3);
547
548   QwtWheel* aWheel = new QwtWheel(myPlayFrame);
549   aWheel->setOrientation(Qt::Vertical);
550   aWheel->setRange(1, 99, 1);
551   connect( aWheel, SIGNAL(valueChanged(double)),
552            aSpeedNum, SLOT(display(double)) );
553   connect( aWheel, SIGNAL(valueChanged(double)),
554            this, SLOT(onSpeedChange(double)) );
555   TopLayout->addMultiCellWidget(aWheel, 1, 3, 3, 3, Qt::AlignRight);
556
557   QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
558   aCycleCheck->setChecked(myAnimator->isCycling());
559   connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
560   TopLayout->addMultiCellWidget(aCycleCheck, 5, 5, 0, 3);
561
562   QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
563   aPropCheck->setChecked(myAnimator->isProportional());
564   connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
565   TopLayout->addMultiCellWidget(aPropCheck, 6, 6, 0, 3);
566
567   QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
568   aSaveBox->setColumnLayout(0, Qt::Horizontal );
569   QGridLayout* aSaveLay = new QGridLayout(aSaveBox->layout());
570   aSaveLay->setSpacing( 5 );
571   aSaveLay->setMargin( 5 );
572
573   mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
574   aSaveLay->addMultiCellWidget(mySaveCheck, 0, 0, 0, 2);
575   connect(mySaveCheck, SIGNAL( toggled(bool)),
576           aWheel, SLOT( setDisabled(bool) ));
577
578   QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
579   aPathLbl->setEnabled(false);
580   connect(mySaveCheck, SIGNAL( toggled(bool)),
581           aPathLbl, SLOT( setEnabled(bool) ));
582   aSaveLay->addWidget(aPathLbl, 1, 0);
583
584   myPathEdit = new QLineEdit(aSaveBox);
585   myPathEdit->setEnabled(false);
586   connect(mySaveCheck, SIGNAL( toggled(bool)),
587           myPathEdit, SLOT( setEnabled(bool) ));
588   aSaveLay->addWidget(myPathEdit, 1, 1);
589
590   QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
591   aBrowseBtn->setEnabled(false);
592   connect(mySaveCheck, SIGNAL( toggled(bool)),
593           aBrowseBtn, SLOT( setEnabled(bool) ));
594   connect(aBrowseBtn, SIGNAL( clicked()),
595           this, SLOT( onBrowse() ));
596   mySaveCheck->setChecked(false);
597   aSaveLay->addWidget(aBrowseBtn, 1, 2);
598
599   TopLayout->addMultiCellWidget(aSaveBox, 7, 7, 0, 3);
600
601   aMainLayout->addWidget(myPlayFrame);
602
603   QHBox* aBtnBox = new QHBox(this);
604   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
605   aBtnLayout->addStretch();
606
607   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
608   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
609
610   aMainLayout->addWidget(aBtnBox);
611
612   myPlayFrame->setEnabled(false);
613 }
614
615 //************************************************************************
616 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg()
617 {
618   delete myAnimator;
619 }
620
621 //************************************************************************
622 void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
623 {
624   stopAnimation();
625   myPropBtn->setEnabled(index != 0);
626
627   clearView();
628   myPlayFrame->setEnabled(false);
629 }
630
631 //************************************************************************
632 void VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
633 {
634   myPlayFrame->setEnabled(false);
635   myAnimator->addField(VISU::GetSObject(theSObject));
636 }
637
638 //************************************************************************
639 void VisuGUI_TimeAnimationDlg::createFrames()
640 {
641   stopAnimation();
642   SUIT_OverrideCursor c;
643
644   for (int i = 0; i < myAnimator->getNbFields(); i++) {
645     if (myAnimator->getFieldData(i).myPrs.empty())
646       myAnimator->generatePresentations(i);
647   }
648   if (myAnimator->getNbFrames() == 0) {
649     myPlayFrame->setEnabled(false);
650     c.suspend();
651     SUIT_MessageBox::warn1(this,
652                            tr("ERROR"),
653                            tr("MSG_NO_ANIMATIONDATA"),
654                            tr("&OK"));
655     return;
656   }
657   mySlider->setMaxValue(myAnimator->getNbFrames()-1);
658   myPlayFrame->setEnabled(true);
659   if (!myAnimator->generateFrames()) {
660     c.suspend();
661     //myPlayFrame->setEnabled(false);
662     SUIT_MessageBox::warn1(this,
663                            tr("ERROR"),
664                            myAnimator->getLastErrorMsg(),
665                            tr("&OK"));
666     return;
667   }
668   //myPlayFrame->setEnabled(true);
669 }
670
671 //************************************************************************
672 void VisuGUI_TimeAnimationDlg::onPlayPressed()
673 {
674   if (myPlayBtn->isOn() && (!myAnimator->running())) {
675     myPlayBtn->setIconSet(MYpausePixmap);
676     if (mySaveCheck->isChecked())
677       myAnimator->dumpTo(myPathEdit->text());
678     else
679       myAnimator->dumpTo("");
680     mySetupBtn->setEnabled(false);
681     myGenBtn->setEnabled(false);
682     myAnimator->startAnimation();
683   } else {
684     myPlayBtn->setIconSet(MYplayPixmap);
685     myAnimator->stopAnimation();
686     mySetupBtn->setEnabled(true);
687     myGenBtn->setEnabled(true);
688   }
689 }
690
691 //************************************************************************
692 void VisuGUI_TimeAnimationDlg::onBackPressed()
693 {
694   //stopAnimation();
695   myAnimator->prevFrame();
696 }
697
698 //************************************************************************
699 void VisuGUI_TimeAnimationDlg::onForvardPressed()
700 {
701   myAnimator->nextFrame();
702 }
703
704 //************************************************************************
705 void VisuGUI_TimeAnimationDlg::onLastPressed()
706 {
707   myAnimator->lastFrame();
708 }
709
710 //************************************************************************
711 void VisuGUI_TimeAnimationDlg::onFirstPressed()
712 {
713   myAnimator->firstFrame();
714 }
715
716 //************************************************************************
717 void VisuGUI_TimeAnimationDlg::clearView()
718 {
719   myAnimator->clearView();
720 }
721
722 //************************************************************************
723 void VisuGUI_TimeAnimationDlg::closeEvent (QCloseEvent* theEvent)
724 {
725   myAnimator->stopAnimation();
726   if (myAnimator->running() && (! myAnimator->finished())) {
727     isClosing = true;
728     myEvent = theEvent;
729   } else {
730     QDialog::closeEvent(theEvent);
731   }
732 }
733
734 //************************************************************************
735 void VisuGUI_TimeAnimationDlg::onWindowChanged (int index)
736 {
737   if (myAnimator->isRunning()) return;
738   myAnimator->gotoFrame(index);
739 }
740
741 //************************************************************************
742 void VisuGUI_TimeAnimationDlg::onSpeedChange (double theSpeed)
743 {
744   myAnimator->setSpeed((int)theSpeed);
745 }
746
747 //************************************************************************
748 void VisuGUI_TimeAnimationDlg::stopAnimation()
749 {
750   myAnimator->stopAnimation();
751   myPlayBtn->setOn(false);
752   myPlayBtn->setIconSet(MYplayPixmap);
753   mySetupBtn->setEnabled(true);
754   myGenBtn->setEnabled(true);
755 }
756
757 //************************************************************************
758 void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
759 {
760   myTimeLbl->setText(QString("%1").arg(theTime));
761   mySlider->setValue(theNewFrame);
762 }
763
764 //************************************************************************
765 void VisuGUI_TimeAnimationDlg::onSetupDlg()
766 {
767   if (myAnimator->getNbFrames() > 0) myAnimator->firstFrame();
768   SetupDlg* aDlg = new SetupDlg(this, myAnimator);
769   aDlg->exec();
770   myPlayFrame->setEnabled(false);
771   delete aDlg;
772 }
773
774 //************************************************************************
775 void VisuGUI_TimeAnimationDlg::onBrowse()
776 {
777   QString aPath = SUIT_FileDlg::getExistingDirectory(this, "/","Select path");
778   if (!aPath.isEmpty())
779     myPathEdit->setText(aPath);
780 }
781
782 //************************************************************************
783 void VisuGUI_TimeAnimationDlg::onStop()
784 {
785   if (isClosing) {
786     QDialog::closeEvent(myEvent);
787   } else {
788     myPlayBtn->setOn(false);
789     myPlayBtn->setIconSet(MYplayPixmap);
790     mySetupBtn->setEnabled(true);
791     myGenBtn->setEnabled(true);
792   }
793 }