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