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