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