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