Salome HOME
5b0779f1dc50b0d9a35454232844b1dd0af32419
[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       aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(0)));
272       if (aDlg->exec()) {
273         for (int i = 0; i < aData.myNbFrames; i++)
274           aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(i)));
275       }
276       delete aDlg;
277     }
278     break;
279   case 3: //Deformed Shape
280     EDITPRS(VISU::DeformedShape_i, VisuGUI_MagnitudeDlg);
281     break;
282   case 4: //Vectors
283     EDITPRS(VISU::Vectors_i, VisuGUI_VectorsDlg);
284     break;
285   case 5: //Stream Lines
286     EDITPRS(VISU::StreamLines_i, VisuGUI_StreamLinesDlg);
287     break;
288   }
289 #undef EDITPRS
290 }
291
292 //************************************************************************
293 void SetupDlg::onRangeCheck(bool theCheck) {
294   for (int i = 0; i < myAnimator->getNbFields(); i++) 
295     myAnimator->clearData(myAnimator->getFieldData(i));
296
297   myMinVal->setEnabled(theCheck);
298   myMaxVal->setEnabled(theCheck);
299
300   if (!theCheck)
301     myAnimator->setAnimationRange(0, 0);
302   else {
303     //    if (myMinVal->value() < myMaxVal->value())
304     myAnimator->setAnimationRange(myMinVal->value(), myMaxVal->value());    
305 //     else if (myMinVal->value() > myMaxVal->value())
306 //       myAnimator->setAnimationRange(myMaxVal->value(), myMinVal->value());
307 //     else // equal case
308 //       myAnimator->setAnimationRange(0, 0);
309   }
310 }
311
312 //************************************************************************
313 void SetupDlg::onMinValue(double theVal) {
314   if (theVal > myAnimator->getMaxRange()) {
315     myMinVal->setValue( myAnimator->getMinTime() );
316     myMinVal->setFocus();
317     return;
318   }
319   for (int i = 0; i < myAnimator->getNbFields(); i++) 
320     myAnimator->clearData(myAnimator->getFieldData(i));
321   myAnimator->setAnimationRange(theVal, myAnimator->getMaxRange());
322 }
323
324 //************************************************************************
325 void SetupDlg::onMaxValue(double theVal) {
326   if (theVal < myAnimator->getMinRange()) {
327     myMaxVal->setValue( myAnimator->getMaxTime() );
328     myMaxVal->setFocus();
329     return;
330   }
331   for (int i = 0; i < myAnimator->getNbFields(); i++) 
332     myAnimator->clearData(myAnimator->getFieldData(i));
333   myAnimator->setAnimationRange(myAnimator->getMinRange(), theVal);
334 }
335
336
337 static const char * firstIco[] = {
338 "18 10 2 1",
339 "       g None",
340 ".      g #000000",
341 "         .     .  ",
342 "  ..    ..    ..  ",
343 "  ..   ...   ...  ",
344 "  ..  ....  ....  ",
345 "  .. ..... .....  ",
346 "  .. ..... .....  ",
347 "  ..  ....  ....  ",
348 "  ..   ...   ...  ",
349 "  ..    ..    ..  ",
350 "         .     .  "};
351
352
353 static const char * lastIco[] = {
354 "18 10 2 1",
355 "       g None",
356 ".      g #000000",
357 "  .     .         ",
358 "  ..    ..    ..  ",
359 "  ...   ...   ..  ",
360 "  ....  ....  ..  ",
361 "  ..... ..... ..  ",
362 "  ..... ..... ..  ",
363 "  ....  ....  ..  ",
364 "  ...   ...   ..  ",
365 "  ..    ..    ..  ",
366 "  .     .         "};
367
368
369 static const char * leftIco[] = {
370 "11 10 2 1",
371 "       g None",
372 ".      g #000000",
373 "    .     .",
374 "   ..    ..",
375 "  ...   ...",
376 " ....  ....",
377 "..... .....",
378 "..... .....",
379 " ....  ....",
380 "  ...   ...",
381 "   ..    ..",
382 "    .     ."};
383
384 static const char * playIco[] = {
385 "14 14 2 1",
386 "       g None",
387 ".      g #000000",
388 "              ",
389 "              ",
390 "  ..          ",
391 "  ....        ",
392 "  ......      ",
393 "  ........    ",
394 "  ..........  ",
395 "  ..........  ",
396 "  ........    ",
397 "  ......      ",
398 "  ....        ",
399 "  ..          ",
400 "              ",
401 "              "};
402
403 static QPixmap MYplayPixmap(playIco);
404
405
406
407 static const char * rightIco[] = {
408 "11 10 2 1",
409 "       g None",
410 ".      g #000000",
411 ".     .    ",
412 "..    ..   ",
413 "...   ...  ",
414 "....  .... ",
415 "..... .....",
416 "..... .....",
417 "....  .... ",
418 "...   ...  ",
419 "..    ..   ",
420 ".     .    "};
421
422
423 static const char * pauseIco[] = {
424 "14 14 2 1",
425 "       g None",
426 ".      g #000000",
427 "              ",
428 "              ",
429 "   ..    ..   ",
430 "   ..    ..   ",
431 "   ..    ..   ",
432 "   ..    ..   ",
433 "   ..    ..   ",
434 "   ..    ..   ",
435 "   ..    ..   ",
436 "   ..    ..   ",
437 "   ..    ..   ",
438 "   ..    ..   ",
439 "              ",
440 "              "};
441
442 static QPixmap MYpausePixmap(pauseIco);
443
444
445 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg(SALOMEDS::Study_var theStudy) 
446   : QDialog( QAD_Application::getDesktop(), "VisuGUI_TimeAnimationDlg", false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose)
447 {
448   setCaption("Animation");
449   setSizeGripEnabled( TRUE );
450   myStudy = theStudy;
451   isClosing = false;
452
453   myAnimator = new VISU_TimeAnimation(theStudy);
454   myAnimator->setSpeed(1);
455   myAnimator->setViewer(VisuGUI::GetVtkViewFrame());
456   connect( myAnimator, SIGNAL( frameChanged(long, double) ), 
457            this, SLOT( onExecution(long, double) ) );
458   connect( myAnimator, SIGNAL( stopped() ), 
459            this, SLOT( onStop() ) );
460
461   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
462   aMainLayout->setSpacing(5);
463
464   mySetupBtn = new QPushButton("Setup Animation...", this);
465   connect( mySetupBtn, SIGNAL( clicked() ), 
466            this, SLOT( onSetupDlg() ) );
467   aMainLayout->addWidget(mySetupBtn);  
468   
469   myGenBtn = new QPushButton("Generate frames", this);
470   connect( myGenBtn, SIGNAL( clicked() ), 
471            this, SLOT( createFrames() ) );
472   aMainLayout->addWidget(myGenBtn);
473
474   myPlayFrame = new QFrame(this);
475   myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
476   myPlayFrame->setLineWidth( 1 );
477  
478
479   // --- Play controls ---
480   QGridLayout* TopLayout = new QGridLayout( myPlayFrame ); 
481   TopLayout->setSpacing( 6 );
482   TopLayout->setMargin( 11 );
483
484   myTimeLbl = new QLabel("0", myPlayFrame);
485   TopLayout->addMultiCellWidget(myTimeLbl, 0, 0, 0, 2, Qt::AlignHCenter);
486
487   mySlider = new QSlider(Qt::Horizontal, myPlayFrame);
488   mySlider->setMinValue(0);
489   mySlider->setMaxValue(3);
490   mySlider->setTickInterval(1);
491   //mySlider->setTickmarks(QSlider::Below);
492   mySlider->setTracking(false);
493   connect( mySlider, SIGNAL( valueChanged(int) ), 
494            this, SLOT( onFrameChanged(int) ) );
495   TopLayout->addMultiCellWidget(mySlider, 1, 1, 0, 2);
496
497   myPlayBtn = new QToolButton(myPlayFrame);
498   myPlayBtn->setIconSet(MYplayPixmap);
499   myPlayBtn->setToggleButton(true);
500   connect( myPlayBtn, SIGNAL( clicked() ), 
501            this, SLOT( onPlayPressed() ) );
502   TopLayout->addMultiCellWidget(myPlayBtn, 2, 2, 0, 1);
503
504   QToolButton* aBackBtn = new QToolButton(myPlayFrame);
505   aBackBtn->setIconSet(QPixmap(leftIco));
506   connect( aBackBtn, SIGNAL( clicked() ), 
507            this, SLOT( onBackPressed() ) );
508   TopLayout->addWidget(aBackBtn, 3, 0);
509
510   QToolButton* aForvardBtn = new QToolButton(myPlayFrame);
511   aForvardBtn->setIconSet(QPixmap(rightIco));
512   connect( aForvardBtn, SIGNAL( clicked() ), 
513            this, SLOT( onForvardPressed() ) );
514   TopLayout->addWidget(aForvardBtn, 3, 1);
515
516   QToolButton* aFirstBtn = new QToolButton(myPlayFrame);
517   aFirstBtn->setIconSet(QPixmap(firstIco));
518   connect( aFirstBtn, SIGNAL( clicked() ), 
519            this, SLOT( onFirstPressed() ) );
520   TopLayout->addWidget(aFirstBtn, 4, 0);
521   
522   QToolButton* aLastBtn = new QToolButton(myPlayFrame);
523   aLastBtn->setIconSet(QPixmap(lastIco));
524   connect( aLastBtn, SIGNAL( clicked() ), 
525            this, SLOT( onLastPressed() ) );
526   TopLayout->addWidget(aLastBtn, 4, 1);
527   
528   QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
529   TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
530
531   QLCDNumber* aSpeedNum  = new QLCDNumber( 2, myPlayFrame );
532   aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
533   aSpeedNum->display(1);
534   TopLayout->addWidget(aSpeedNum, 4, 3);
535
536   QwtWheel* aWheel = new QwtWheel(myPlayFrame);
537   aWheel->setOrientation(Qt::Vertical);
538   aWheel->setRange(1, 99, 1);
539   connect( aWheel, SIGNAL(valueChanged(double)), 
540            aSpeedNum, SLOT(display(double)) );
541   connect( aWheel, SIGNAL(valueChanged(double)), 
542            this, SLOT(onSpeedChange(double)) );
543   TopLayout->addMultiCellWidget(aWheel, 1, 3, 3, 3, Qt::AlignRight);
544
545   QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
546   aCycleCheck->setChecked(myAnimator->isCycling());
547   connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
548   TopLayout->addMultiCellWidget(aCycleCheck, 5, 5, 0, 3);
549
550   QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
551   aPropCheck->setChecked(myAnimator->isProportional());
552   connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
553   TopLayout->addMultiCellWidget(aPropCheck, 6, 6, 0, 3);
554
555   QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
556   aSaveBox->setColumnLayout(0, Qt::Horizontal );
557   QGridLayout* aSaveLay = new QGridLayout(aSaveBox->layout());
558   aSaveLay->setSpacing( 5 );
559   aSaveLay->setMargin( 5 );
560
561   mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
562   aSaveLay->addMultiCellWidget(mySaveCheck, 0, 0, 0, 2);
563   connect(mySaveCheck, SIGNAL( toggled(bool)),
564           aWheel, SLOT( setDisabled(bool) ));
565
566   QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
567   aPathLbl->setEnabled(false);
568   connect(mySaveCheck, SIGNAL( toggled(bool)),
569           aPathLbl, SLOT( setEnabled(bool) ));
570   aSaveLay->addWidget(aPathLbl, 1, 0);
571   
572   myPathEdit = new QLineEdit(aSaveBox);
573   myPathEdit->setEnabled(false);
574   connect(mySaveCheck, SIGNAL( toggled(bool)),
575           myPathEdit, SLOT( setEnabled(bool) ));
576   aSaveLay->addWidget(myPathEdit, 1, 1);
577
578   QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
579   aBrowseBtn->setEnabled(false);
580   connect(mySaveCheck, SIGNAL( toggled(bool)),
581           aBrowseBtn, SLOT( setEnabled(bool) ));
582   connect(aBrowseBtn, SIGNAL( clicked()),
583           this, SLOT( onBrowse() ));
584   mySaveCheck->setChecked(false);
585   aSaveLay->addWidget(aBrowseBtn, 1, 2);
586
587   TopLayout->addMultiCellWidget(aSaveBox, 7, 7, 0, 3);
588
589   aMainLayout->addWidget(myPlayFrame);
590
591   QHBox* aBtnBox = new QHBox(this);
592   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout()); 
593   aBtnLayout->addStretch();
594
595   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
596   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
597   
598   aMainLayout->addWidget(aBtnBox);
599
600   myPlayFrame->setEnabled(false);
601 }
602
603
604 //************************************************************************
605 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg() {
606   delete myAnimator;
607 }
608
609
610 //************************************************************************
611 void VisuGUI_TimeAnimationDlg::onTypeChange(int index) {
612   stopAnimation();
613   myPropBtn->setEnabled(index != 0);
614   
615   clearView();
616   myPlayFrame->setEnabled(false);
617 }
618
619
620 //************************************************************************
621 void  VisuGUI_TimeAnimationDlg::addField(SALOMEDS::SObject_var theSObject) {
622   myPlayFrame->setEnabled(false);
623   myAnimator->addField(theSObject);
624 }
625
626
627
628 //************************************************************************
629 void VisuGUI_TimeAnimationDlg::createFrames() {
630   stopAnimation();
631   QApplication::setOverrideCursor( Qt::waitCursor );
632
633   for (int i = 0; i < myAnimator->getNbFields(); i++) {
634     if (myAnimator->getFieldData(i).myPrs.empty()) 
635       myAnimator->generatePresentations(i);
636   }
637   if (myAnimator->getNbFrames() == 0) {
638     myPlayFrame->setEnabled(false);
639     QApplication::restoreOverrideCursor();
640     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_NO_ANIMATIONDATA")); 
641     return;    
642   }    
643   mySlider->setMaxValue(myAnimator->getNbFrames()-1);
644   myPlayFrame->setEnabled(true);
645   if (!myAnimator->generateFrames()) {
646     QApplication::restoreOverrideCursor();
647     //myPlayFrame->setEnabled(false);
648     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), myAnimator->getLastErrorMsg()); 
649     return;
650   }
651   //myPlayFrame->setEnabled(true);
652   QApplication::restoreOverrideCursor();
653 }
654  
655   
656
657 //************************************************************************
658 void VisuGUI_TimeAnimationDlg::onPlayPressed() {
659   if (myPlayBtn->isOn() && (!myAnimator->running())) {
660     myPlayBtn->setIconSet(MYpausePixmap);
661     if (mySaveCheck->isChecked())
662       myAnimator->dumpTo(myPathEdit->text());
663     else
664       myAnimator->dumpTo("");
665     mySetupBtn->setEnabled(false);
666     myGenBtn->setEnabled(false);
667     myAnimator->startAnimation();
668   } else {
669     myPlayBtn->setIconSet(MYplayPixmap);
670     myAnimator->stopAnimation();
671     mySetupBtn->setEnabled(true);
672     myGenBtn->setEnabled(true);
673   }
674 }
675
676 //************************************************************************
677 void VisuGUI_TimeAnimationDlg::onBackPressed() {
678   //stopAnimation();
679   myAnimator->prevFrame();
680 }
681
682
683 //************************************************************************
684 void VisuGUI_TimeAnimationDlg::onForvardPressed() {
685   myAnimator->nextFrame();
686 }
687
688
689 //************************************************************************
690 void VisuGUI_TimeAnimationDlg::onLastPressed() {
691   myAnimator->lastFrame();
692 }
693
694
695 //************************************************************************
696 void VisuGUI_TimeAnimationDlg::onFirstPressed() {
697   myAnimator->firstFrame();
698 }
699
700
701
702 //************************************************************************
703 void VisuGUI_TimeAnimationDlg::clearView() {
704   myAnimator->clearView();
705 }
706
707
708 //************************************************************************
709 void VisuGUI_TimeAnimationDlg::closeEvent(QCloseEvent* theEvent) {
710   myAnimator->stopAnimation();
711   if (myAnimator->running() && (! myAnimator->finished())) {
712     isClosing = true;
713     myEvent = theEvent;
714   } else {
715     QDialog::closeEvent(theEvent);
716   }
717 }
718
719
720 //************************************************************************
721 void VisuGUI_TimeAnimationDlg::onFrameChanged(int index) {
722   if (myAnimator->isRunning()) return;
723   myAnimator->gotoFrame(index);
724 }
725
726
727 //************************************************************************
728 void VisuGUI_TimeAnimationDlg::onSpeedChange(double theSpeed) {
729   myAnimator->setSpeed((int)theSpeed);
730 }
731     
732
733 //************************************************************************
734 void VisuGUI_TimeAnimationDlg::stopAnimation() {
735   myAnimator->stopAnimation();
736   myPlayBtn->setOn(false);
737   myPlayBtn->setIconSet(MYplayPixmap);
738   mySetupBtn->setEnabled(true);
739   myGenBtn->setEnabled(true);
740 }
741
742 //************************************************************************
743 void VisuGUI_TimeAnimationDlg::onExecution(long theNewFrame, double theTime) {
744   myTimeLbl->setText(QString("%1").arg(theTime));
745   mySlider->setValue(theNewFrame);
746 }
747
748
749 //************************************************************************
750 void VisuGUI_TimeAnimationDlg::onSetupDlg() {
751   if (myAnimator->getNbFrames() > 0) myAnimator->firstFrame();
752   SetupDlg* aDlg = new SetupDlg(this, myAnimator);
753   aDlg->exec();
754   myPlayFrame->setEnabled(false);
755   delete aDlg;
756 }
757
758 //************************************************************************
759 void VisuGUI_TimeAnimationDlg::onBrowse() {
760   QString aPath = QAD_FileDlg::getExistingDirectory(this, "/","Select path");
761   if (!aPath.isEmpty())
762     myPathEdit->setText(aPath);
763 }
764
765
766 //************************************************************************
767 void VisuGUI_TimeAnimationDlg::onStop() {
768   if (isClosing) {
769     QDialog::closeEvent(myEvent);
770   } else {
771     myPlayBtn->setOn(false);
772     myPlayBtn->setIconSet(MYplayPixmap);
773     mySetupBtn->setEnabled(true);
774     myGenBtn->setEnabled(true);
775   }
776 }