Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/visu.git] / src / VISUGUI / VisuGUI_TimeAnimation.cxx
1 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 // 
4 //  This library is free software; you can redistribute it and/or 
5 //  modify it under the terms of the GNU Lesser General Public 
6 //  License as published by the Free Software Foundation; either 
7 //  version 2.1 of the License. 
8 // 
9 //  This library is distributed in the hope that it will be useful, 
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 //  Lesser General Public License for more details. 
13 // 
14 //  You should have received a copy of the GNU Lesser General Public 
15 //  License along with this library; if not, write to the Free Software 
16 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
17 // 
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //  File   : VisuGUI_TimeAnimation.cxx
21 //  Author : Vitaly SMETANNIKOV
22 //  Module : VISU
23
24 #include "VisuGUI_TimeAnimation.h"
25
26 #include "VisuGUI.h"
27 #include "VisuGUI_Tools.h"
28 #include "VisuGUI_ViewTools.h"
29 #include "VisuGUI_ScalarBarDlg.h"
30 #include "VisuGUI_DeformedShapeDlg.h"
31 #include "VisuGUI_CutPlanesDlg.h"
32 #include "VisuGUI_CutLinesDlg.h"
33 #include "VisuGUI_Plot3DDlg.h"
34 #include "VisuGUI_VectorsDlg.h"
35 #include "VisuGUI_IsoSurfacesDlg.h"
36 #include "VisuGUI_StreamLinesDlg.h"
37 #include "VisuGUI_ScalarMapOnDeformedShapeDlg.h"
38 #include "VisuGUI_GaussPointsDlg.h"
39
40 #include "VISU_TimeAnimation.h"
41
42 #include "VISU_ScalarMap_i.hh"
43 #include "VISU_IsoSurfaces_i.hh"
44 #include "VISU_DeformedShape_i.hh"
45 #include "VISU_CutPlanes_i.hh"
46 #include "VISU_Plot3D_i.hh"
47 #include "VISU_CutLines_i.hh"
48 #include "VISU_Vectors_i.hh"
49 #include "VISU_StreamLines_i.hh"
50 #include "VISU_ScalarMapOnDeformedShape_i.hh"
51 #include "VISU_GaussPoints_i.hh"
52
53 #include "VISU_ViewManager_i.hh"
54
55 #include "VISU_ScalarBarActor.hxx"
56 #include "VISU_Actor.h"
57
58 #include "SalomeApp_Study.h"
59 #include "LightApp_Application.h"
60
61 #include "SVTK_ViewWindow.h"
62
63 #include "SUIT_OverrideCursor.h"
64 #include "SUIT_MessageBox.h"
65 #include "SUIT_ResourceMgr.h"
66 #include "SUIT_Session.h"
67 #include "SUIT_Desktop.h"
68 #include "SUIT_FileDlg.h"
69
70 #include <vtkRenderer.h>
71 #include <vtkMapper.h>
72
73 #include <qhbox.h>
74 #include <qgrid.h>
75 #include <qimage.h>
76 #include <qlayout.h>
77 #include <qslider.h>
78 #include <qthread.h>
79 #include <qlistbox.h>
80 #include <qlineedit.h>
81 #include <qwt_wheel.h>
82 #include <qlcdnumber.h>
83 #include <qhgroupbox.h>
84 #include <qvgroupbox.h>
85 #include <qtoolbutton.h>
86
87 #define  MAXVAL 1e10
88
89 ArrangeDlg::ArrangeDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
90   : QDialog(theParent, "ArrangeDlg", true,
91             WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
92     myAnimator(theAnimator),
93     myViewWindow(theAnimator->getViewer())
94 {
95   myCurrent = 0;
96   init();
97   QStringList aFieldNames;
98   // Find names of fields
99   for (int i = 0; i < myAnimator->getNbFields(); i++) {
100     _PTR(SObject) aSObject = myAnimator->getFieldData(i).myField;
101     VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
102     aFieldNames.append(aRestoringMap["myName"]);
103     Offset aOffs;
104     aOffs.myOffset[0] = myAnimator->getFieldData(i).myOffset[0];
105     aOffs.myOffset[1] = myAnimator->getFieldData(i).myOffset[1];
106     aOffs.myOffset[2] = myAnimator->getFieldData(i).myOffset[2];
107     myOffsets.append(aOffs);
108   }
109   myFieldLst->insertStringList(aFieldNames);
110   myFieldLst->setSelected(0, true);
111 }
112
113 ArrangeDlg::ArrangeDlg(QWidget* theParent, 
114                        const SalomeApp_Module* theModule,
115                        SVTK_ViewWindow* theViewWindow)
116   : QDialog(theParent, "ArrangeDlg", true, WStyle_Customize |
117             WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
118     myAnimator(NULL), 
119     myViewWindow(theViewWindow)
120 {
121   myCurrent = 0;
122   init();
123   QStringList aPrsNames;
124   vtkActorCollection *aCollection = myViewWindow->getRenderer()->GetActors();
125   aCollection->InitTraversal();
126   while(vtkActor* anActor = aCollection->GetNextActor()){
127     if (VISU_Actor* anVISUActor = dynamic_cast<VISU_Actor*>(anActor))
128       if(anVISUActor->GetVisibility() != 0){
129         if (VISU::Prs3d_i* aPrs = anVISUActor->GetPrs3d()){
130           if(!myPrsMap.contains(aPrs)){
131             Handle(SALOME_InteractiveObject) anIO = aPrs->GetIO();
132             if(!anIO->hasEntry())
133               continue;
134             SalomeApp_Study* aStudy = VISU::GetAppStudy(theModule);
135             VISU::TObjectInfo anObjectInfo = VISU::GetObjectByEntry(aStudy, anIO->getEntry());
136             if(_PTR(SObject) aSObject = anObjectInfo.mySObject){
137               _PTR(GenericAttribute) anAttr;
138               if (aSObject->FindAttribute(anAttr, "AttributeName")) {
139                 _PTR(AttributeName) aName(anAttr);
140                 QString strIn(aName->Value().c_str());
141                 aPrsNames.append(strIn);
142                 myPrsMap[aPrs] = myOffsets.count();
143                 Offset aOffs;
144                 anVISUActor->GetPosition(aOffs.myOffset);
145                 myOffsets.append(aOffs);
146               }
147             }
148           }
149         }
150       }
151   }
152   myFieldLst->insertStringList(aPrsNames);
153   myFieldLst->setSelected(0, true);
154 }
155
156 void ArrangeDlg::init()
157 {
158   setCaption("Arrange Presentations");
159   setSizeGripEnabled( TRUE );
160
161   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
162   aMainLayout->setSpacing(5);
163
164   QButtonGroup* aBtnGrp = new QButtonGroup(2, Qt::Horizontal, this);
165   aBtnGrp->setExclusive(true);
166   aMainLayout->addWidget(aBtnGrp);
167
168   QRadioButton* aAutoBtn = new QRadioButton("Auto", aBtnGrp);
169   aBtnGrp->insert(aAutoBtn, AutoMode);
170
171   QRadioButton* aManualBtn = new QRadioButton("Manual", aBtnGrp);
172   aBtnGrp->insert(aManualBtn, ManualMode);
173   aBtnGrp->setButton(AutoMode);
174
175   myStackWgt = new QWidgetStack(this);
176   aMainLayout->addWidget(myStackWgt);
177
178   //  AUTO Pane
179   QVBox* aAutoPane = new QVBox(myStackWgt);
180   aAutoPane->setSpacing(5);
181   // Axis Group
182   myAxisGrp = new QButtonGroup(3, Qt::Horizontal,"Axis", aAutoPane);
183
184   QRadioButton* aXBtn = new QRadioButton("X",myAxisGrp );
185   myAxisGrp->insert(aXBtn, XAxis);
186
187   QRadioButton* aYBtn = new QRadioButton("Y",myAxisGrp );
188   myAxisGrp->insert(aYBtn, YAxis);
189
190   QRadioButton* aZBtn = new QRadioButton("Z",myAxisGrp );
191   myAxisGrp->insert(aZBtn, ZAxis);
192
193   myAxisGrp->setButton(XAxis);
194
195   //Distance Input
196   QHBox* aDistPane = new QHBox(aAutoPane);
197   aDistPane->setSpacing(5);
198   new QLabel("Relative Distance", aDistPane);
199   myDistVal = new QtxDblSpinBox (-10,10, 0.5, aDistPane);
200   myDistVal->setValue(1);
201
202   myStackWgt->addWidget(aAutoPane, AutoMode);
203
204   // Manual Pane
205   QHBox* aManualPane = new QHBox(myStackWgt);
206   aManualPane->setSpacing(10);
207
208   myFieldLst = new QListBox(aManualPane);
209   connect( myFieldLst, SIGNAL( highlighted(int) ),
210            this, SLOT( onFieldChange(int) ) );
211
212   QGrid* aCoordPane = new QGrid(2, aManualPane);
213   aCoordPane->setSpacing(5);
214
215   new QLabel("X", aCoordPane);
216   myCoord[0] = new QtxDblSpinBox(aCoordPane);
217   myCoord[0]->setRange(-MAXVAL, MAXVAL);
218
219   new QLabel("Y", aCoordPane);
220   myCoord[1] = new QtxDblSpinBox(aCoordPane);
221   myCoord[1]->setRange(-MAXVAL, MAXVAL);
222
223   new QLabel("Z", aCoordPane);
224   myCoord[2] = new QtxDblSpinBox(aCoordPane);
225   myCoord[2]->setRange(-MAXVAL, MAXVAL);
226
227   myStackWgt->addWidget(aManualPane, ManualMode);
228
229   myStackWgt->raiseWidget(AutoMode);
230
231   connect(aBtnGrp, SIGNAL(clicked(int)), myStackWgt, SLOT(raiseWidget(int)) );
232
233   SUIT_Study* aSUITStudy = myViewWindow->getViewManager()->study();
234   SalomeApp_Study* anAppStudy = dynamic_cast<SalomeApp_Study*>(aSUITStudy);
235   _PTR(Study) aCStudy = VISU::GetCStudy(anAppStudy);
236   if (!myAnimator && !aCStudy->GetProperties()->IsLocked()) {
237     mySaveChk = new QCheckBox ("Save to presentation", this);
238     mySaveChk->setChecked(false);
239     aMainLayout->addWidget(mySaveChk);
240   } else {
241     mySaveChk = 0;
242   }
243
244   // Common buttons ===========================================================
245   QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
246   GroupButtons->setColumnLayout(0, Qt::Vertical );
247   GroupButtons->layout()->setSpacing( 0 );
248   GroupButtons->layout()->setMargin( 0 );
249   QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
250   GroupButtonsLayout->setAlignment( Qt::AlignTop );
251   GroupButtonsLayout->setSpacing( 6 );
252   GroupButtonsLayout->setMargin( 11 );
253
254   QPushButton* buttonOk = new QPushButton( tr( "&OK" ), GroupButtons, "buttonOk" );
255   buttonOk->setAutoDefault( TRUE );
256   buttonOk->setDefault( TRUE );
257   GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
258   GroupButtonsLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
259
260   QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ) , GroupButtons, "buttonCancel" );
261   buttonCancel->setAutoDefault( TRUE );
262   GroupButtonsLayout->addWidget( buttonCancel, 0, 2 );
263
264   aMainLayout->addWidget( GroupButtons );
265
266   connect( buttonOk,     SIGNAL( clicked() ),      this, SLOT( accept() ) );
267   connect( buttonCancel, SIGNAL( clicked() ),      this, SLOT( reject() ) );
268 }
269
270 void ArrangeDlg::accept()
271 {
272   if (myAnimator != NULL) {
273     acceptAnimation();
274   } else {
275     acceptViewWindow();
276   }
277   QDialog::accept();
278 }
279
280 void ArrangeDlg::onFieldChange(int theCurrent)
281 {
282   if (myCurrent != theCurrent) {
283     Offset& aOffs = myOffsets[myCurrent];
284     aOffs.myOffset[0] = myCoord[0]->value();
285     aOffs.myOffset[1] = myCoord[1]->value();
286     aOffs.myOffset[2] = myCoord[2]->value();
287   }
288   myCurrent = theCurrent;
289   const Offset& aNewOffs = myOffsets[myCurrent];
290   myCoord[0]->setValue(aNewOffs.myOffset[0]);
291   myCoord[1]->setValue(aNewOffs.myOffset[1]);
292   myCoord[2]->setValue(aNewOffs.myOffset[2]);
293 }
294
295 void ArrangeDlg::acceptAnimation()
296 {
297   if (getMode() == ManualMode) {
298     // Save from GUI
299     Offset& aOffs = myOffsets[myCurrent];
300     aOffs.myOffset[0] = myCoord[0]->value();
301     aOffs.myOffset[1] = myCoord[1]->value();
302     aOffs.myOffset[2] = myCoord[2]->value();
303
304     for (int i = 0; i < myAnimator->getNbFields(); i++) {
305       Offset aOffs = myOffsets[i];
306       myAnimator->getFieldData(i).myOffset[0] = aOffs.myOffset[0];
307       myAnimator->getFieldData(i).myOffset[1] = aOffs.myOffset[1];
308       myAnimator->getFieldData(i).myOffset[2] = aOffs.myOffset[2];
309     }
310   } else {
311     QApplication::setOverrideCursor( Qt::waitCursor );
312     FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
313     if (aData.myPrs.empty())
314       myAnimator->generatePresentations(myFieldLst->currentItem());
315     vtkFloatingPointType aBounds[6];
316     aData.myPrs[0]->GetBounds(aBounds);
317     vtkFloatingPointType aDist = 0;
318     int aAxis = getAxis();
319     switch (aAxis) {
320     case XAxis:
321       aDist = fabs(aBounds[1] - aBounds[0]);
322       break;
323     case YAxis:
324       aDist = fabs(aBounds[3] - aBounds[2]);
325       break;
326     case ZAxis:
327       aDist = fabs(aBounds[5] - aBounds[4]);
328     }
329
330     vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
331     vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
332     vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
333     vtkFloatingPointType max = (dx > dy) ? dx : dy;
334     max = (dz > max) ? dz : max;
335     max /= 100.0;
336
337     if (aDist < max) {
338       // set base distance between centers of bounding boxes
339       // to minimal (but big enough) size of current bounding box
340       if (dx < max) dx = FLT_MAX;
341       if (dy < max) dy = FLT_MAX;
342       if (dz < max) dz = FLT_MAX;
343
344       aDist = (dx < dy) ? dx : dy;
345       aDist = (dz < aDist) ? dz : aDist;
346     }
347     aDist = aDist * getDistance();
348     for (int i = 0; i < myAnimator->getNbFields(); i++) {
349       myAnimator->getFieldData(i).myOffset[0] = 0;
350       myAnimator->getFieldData(i).myOffset[1] = 0;
351       myAnimator->getFieldData(i).myOffset[2] = 0;
352       myAnimator->getFieldData(i).myOffset[aAxis] = aDist * i;
353     }
354
355     QApplication::restoreOverrideCursor();
356   }
357 }
358
359 void ArrangeDlg::acceptViewWindow()
360 {
361   if (getMode() == ManualMode) {
362     // Save from GUI
363     Offset& aOffs = myOffsets[myCurrent];
364     aOffs.myOffset[0] = myCoord[0]->value();
365     aOffs.myOffset[1] = myCoord[1]->value();
366     aOffs.myOffset[2] = myCoord[2]->value();
367
368     QMap<VISU::Prs3d_i*, int>::Iterator it;
369     for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it) {
370       VISU::Prs3d_i* aPrs = it.key();
371       Offset& aOffs = myOffsets[it.data()];
372       if (VISU_Actor* anActor = VISU::FindActor(myViewWindow, aPrs))
373         anActor->SetPosition(aOffs.myOffset);
374       if (mySaveChk)
375         if (mySaveChk->isChecked())
376           aPrs->SetOffset(aOffs.myOffset[0],aOffs.myOffset[1],aOffs.myOffset[2]);
377     }
378   } else {
379     vtkFloatingPointType aDist = 0;
380     vtkFloatingPointType aShift = 0;
381     vtkFloatingPointType aPrevDist = 0;
382     vtkFloatingPointType aPrevShift = 0;
383     int i;
384     QMap<VISU::Prs3d_i*, int>::Iterator it;
385     for (it = myPrsMap.begin(), i = 0; it != myPrsMap.end(); ++it, i++) {
386       VISU::Prs3d_i* aPrs = it.key();
387       if (VISU_Actor* aActor = VISU::FindActor(myViewWindow, aPrs)) {
388         int aAxis = getAxis();
389
390         vtkFloatingPointType aZeroOffset[3];
391         aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
392         aActor->SetPosition(aZeroOffset);
393         aActor->GetMapper()->Update();
394
395         vtkFloatingPointType aBounds[6];
396         aActor->GetBounds(aBounds);
397         switch (aAxis) {
398         case XAxis:
399           aDist = fabs(aBounds[1] - aBounds[0]);
400           break;
401         case YAxis:
402           aDist = fabs(aBounds[3] - aBounds[2]);
403           break;
404         case ZAxis:
405           aDist = fabs(aBounds[5] - aBounds[4]);
406         }
407         vtkFloatingPointType aOffset[3];
408         aOffset[0] = aOffset[1] = aOffset[2] = 0;
409         aOffset[aAxis] =
410           (aBounds[2*aAxis+1] < aBounds[2*aAxis]) ? -aBounds[2*aAxis+1] : -aBounds[2*aAxis];
411
412         if (i > 0) {
413           vtkFloatingPointType aCCDist = (aDist + aPrevDist) / 2.0;
414
415           vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
416           vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
417           vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
418           vtkFloatingPointType max = (dx > dy) ? dx : dy;
419           max = (dz > max) ? dz : max;
420           max /= 100.0;
421
422           if (aCCDist < max) {
423             // set base distance between centers of bounding boxes
424             // to minimal (but big enough) size of current bounding box
425             if (dx < max) dx = FLT_MAX;
426             if (dy < max) dy = FLT_MAX;
427             if (dz < max) dz = FLT_MAX;
428
429             aCCDist = (dx < dy) ? dx : dy;
430             aCCDist = (dz < aCCDist) ? dz : aCCDist;
431           }
432
433           //-------------------------------->
434           //             aShift
435           //                                 aDist / 2
436           //                                 <-->
437           //            .--------------.     .------.
438           //----------->|              |     |      |
439           // aPrevShift '--------------'     '------'
440           //            <------>
441           //            aPrevDist / 2
442           //
443           //                    <--------------->
444           //                    (aDist + aPrevDist) * getDistance() / 2
445
446           aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
447         }
448
449         aOffset[aAxis] += aShift;
450         aActor->SetPosition(aOffset);
451         if (mySaveChk)
452           if (mySaveChk->isChecked())
453             aPrs->SetOffset(aOffset[0],aOffset[1],aOffset[2]);
454
455         aPrevDist = aDist;
456         aPrevShift = aShift;
457       }
458     }
459   }
460   myViewWindow->getRenderer()->ResetCameraClippingRange();
461   myViewWindow->Repaint();
462 }
463
464
465 //------------------------------------------------------------------------
466 //------------------------------------------------------------------------
467 //------------------------------------------------------------------------
468 SetupDlg::SetupDlg (QWidget* theParent,
469                     VisuGUI* theModule, 
470                     VISU_TimeAnimation* theAnimator) :
471   QDialog(theParent, 
472           "SetupDlg", 
473           true, 
474           WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
475   myAnimator(theAnimator),
476   myModule(theModule),
477   myIsRegenerate( false )
478 {
479   setCaption("Setup Animation");
480   setSizeGripEnabled( TRUE );
481
482   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
483   aMainLayout->setSpacing(5);
484
485   // Range of time stamps
486   myUseRangeBox = new QHGroupBox("Use range of time stamps", this);
487   myUseRangeBox->setCheckable( true );
488   myUseRangeBox->setChecked(myAnimator->isRangeDefined());
489
490   double aMaxTime = myAnimator->getMaxTime();
491   double aMinTime = myAnimator->getMinTime();
492   double aStep;
493   if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) 
494     aStep = (aMaxTime - aMinTime) / (myAnimator->getFieldData(0).myNbTimes - 1);
495   else { // successive animation mode
496     std::pair<int,long> aLastFieldFrame(myAnimator->getNbFields() - 1,
497                                         myAnimator->getFieldData(myAnimator->getNbFields() - 1).myNbTimes - 1);
498     aStep = (aMaxTime - aMinTime) / myAnimator->getAbsoluteFrameNumber(aLastFieldFrame);
499   }
500
501   QLabel* aMinLbl = new QLabel("From", myUseRangeBox);
502   myMinVal = new QtxDblSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
503   if (myUseRangeBox->isChecked())
504     myMinVal->setValue( myAnimator->getMinRange() );
505   else
506     myMinVal->setValue( aMinTime );
507
508   connect(myMinVal, SIGNAL( valueChanged(double)),
509           this, SLOT( onMinValue(double) ));
510
511   QLabel* aMaxLbl = new QLabel("To", myUseRangeBox);
512   myMaxVal = new QtxDblSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
513   if (myUseRangeBox->isChecked())
514     myMaxVal->setValue( myAnimator->getMaxRange() );
515   else
516     myMaxVal->setValue( aMaxTime );
517
518   connect(myMaxVal, SIGNAL( valueChanged(double)),
519           this, SLOT( onMaxValue(double) ));
520
521   connect(myUseRangeBox, SIGNAL( toggled(bool)),
522           this, SLOT( onRangeCheck(bool) ));
523
524   aMainLayout->addWidget(myUseRangeBox);
525
526
527   // Sequence of time stamps
528   myUseSequenceBox = new QGroupBox("Use sequence of time stamps", this);
529   myUseSequenceBox->setCheckable( true );
530   myUseSequenceBox->setChecked( myAnimator->isSequenceDefined() );
531
532   myUseSequenceBox->setColumnLayout(0, Qt::Vertical);
533   myUseSequenceBox->layout()->setSpacing( 0 );
534   myUseSequenceBox->layout()->setMargin( 0 );
535   QGridLayout* aUseSequenceLayout = new QGridLayout( myUseSequenceBox->layout() );
536   aUseSequenceLayout->setAlignment( Qt::AlignTop );
537   aUseSequenceLayout->setSpacing( 6 );
538   aUseSequenceLayout->setMargin( 11 );
539
540   QLabel* anIndicesLbl = new QLabel("Indices", myUseSequenceBox);
541   myIndices = new QLineEdit( myUseSequenceBox );
542
543   myValues = new QListBox( myUseSequenceBox );
544   myValues->setSelectionMode( QListBox::Extended );
545
546   connect(myIndices, SIGNAL( textChanged(const QString&)),
547           this, SLOT( onIndicesChanged(const QString&) ));
548
549   connect(myValues, SIGNAL( selectionChanged() ),
550           this, SLOT( onValuesChanged() ) );
551
552   connect(myUseSequenceBox, SIGNAL( toggled(bool)),
553           this, SLOT( onSequenceCheck(bool) ));
554
555   aUseSequenceLayout->addWidget( anIndicesLbl, 0, 0 );
556   aUseSequenceLayout->addWidget( myIndices, 0, 1 );
557   aUseSequenceLayout->addMultiCellWidget( myValues, 1, 1, 0, 1 );
558
559   aMainLayout->addWidget(myUseSequenceBox);
560
561
562   // Fields and Properties
563   QHBox* aPropFrame = new QHBox(this);
564   aPropFrame->setSpacing(5);
565
566   QVGroupBox* aNamesBox = new QVGroupBox("Fields",aPropFrame);
567   myFieldLst = new QListBox(aNamesBox);
568   QStringList aFieldNames;
569   // Find names of fields
570   for (int i = 0; i < myAnimator->getNbFields(); i++) {
571     _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
572     VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSO);
573     QString aFieldName(aRestoringMap["myName"]);
574     if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL )
575       aFieldNames.append(aFieldName);
576     else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
577       _PTR(SObject) aSObject = aSO->GetFather()->GetFather()->GetFather();
578       VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
579       QString aFileName(aRestoringMap["myInitFileName"]);
580       aFileName = aFileName.right(aFileName.length() - (aFileName.findRev("/") + 1));
581       aFieldNames.append(aFileName + QString(" : ") + aFieldName);
582     }
583   }
584   myFieldLst->insertStringList(aFieldNames);
585   
586   if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) {
587     myFieldLst->setSelected(0, true);
588     connect( myFieldLst, SIGNAL( highlighted(int) ),
589              this, SLOT( onFieldChange(int) ) );
590   }
591   else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE )
592     myFieldLst->setSelectionMode(QListBox::NoSelection);
593   
594     QVBox* aSetupBox = new QVBox(aPropFrame);
595   aSetupBox->setSpacing(5);
596
597   QVGroupBox* aPropBox = new QVGroupBox("Properties", aSetupBox);
598   //QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
599   myTypeCombo = new QComboBox(aPropBox);
600   connect( myTypeCombo, SIGNAL( activated(int) ),
601            this, SLOT( onTypeChanged(int) ) );
602
603   //  QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
604   //connect( aBarBtn, SIGNAL( clicked() ),
605   //       this, SLOT( onScalarBarDlg() ) );
606
607   myPropBtn = new QPushButton("Properties...", aPropBox);
608   //  myPropBtn->setEnabled(myAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
609   connect( myPropBtn, SIGNAL( clicked() ),
610            this, SLOT( onPreferencesDlg() ) );
611
612   if (myAnimator->getNbFields() > 1 ) {
613     if( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) {
614       myArrangeBtn = new QPushButton("Arrange...", aSetupBox);
615       connect( myArrangeBtn, SIGNAL( clicked() ), this, SLOT( onArrangeDlg() ) );
616     }
617   }
618   onFieldChange(0);
619   aMainLayout->addWidget(aPropFrame);
620
621   QHBox* aBtnBox = new QHBox(this);
622   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
623   aBtnLayout->addStretch();
624
625   QPushButton* aCloseBtn = new QPushButton(tr("BUT_OK"), aBtnBox);
626   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(onClose()));
627
628   aMainLayout->addWidget(aBtnBox);
629 }
630
631 //------------------------------------------------------------------------
632 void SetupDlg::initialize()
633 {
634   myValues->clear();
635
636   _PTR(Study) aStudy = myAnimator->getStudy();
637
638   FieldData& aData = myAnimator->getFieldData( 0 );
639   _PTR(SObject) aField = aData.myField;
640
641   _PTR(ChildIterator) anIter = aStudy->NewChildIterator(aField);
642   anIter->Next(); // First is reference on support
643   for(int index = 1; anIter->More(); anIter->Next(), index++)
644   {
645     QString aPrefix( "[" );
646     aPrefix += QString::number( index );
647     aPrefix += "] - ";
648
649     double aTime = VISU_TimeAnimation::getTimeValue(anIter->Value());
650     myValues->insertItem( aPrefix + QString::number( aTime ) );
651   }
652
653   QString anIndices( myAnimator->getAnimationSequence() );
654   myIndices->setText( anIndices );
655 }
656
657 //------------------------------------------------------------------------
658 enum PrsComboItem {
659   TSCALARMAP_ITEM     = 0, // VISU::TSCALARMAP
660   TISOSURFACES_ITEM   = 1, // VISU::TISOSURFACES
661   TCUTPLANES_ITEM     = 2, // VISU::TCUTPLANES
662   TCUTLINES_ITEM      = 3, // VISU::TCUTLINES
663   TPLOT3D_ITEM        = 4, // VISU::TPLOT3D
664   TDEFORMEDSHAPE_ITEM = 5, // VISU::TDEFORMEDSHAPE
665   TVECTORS_ITEM       = 6, // VISU::TVECTORS
666   TSTREAMLINES_ITEM   = 7, // VISU::TSTREAMLINES
667   TGAUSSPOINTS_ITEM   = 8, // VISU::TGAUSSPOINTS
668   TSCALARMAPONDEFORMEDSHAPE_ITEM = 9 // VISU::TSCALARMAPONDEFORMEDSHAPE
669 };
670
671 //------------------------------------------------------------------------
672 void SetupDlg::onClose()
673 {
674   if( !myUseRangeBox->isChecked() )
675     myAnimator->setAnimationRange( 0, 0 );
676   
677   if( !myUseSequenceBox->isChecked() )
678     myAnimator->setAnimationSequence( 0 );
679   
680   close();
681 }
682
683 //------------------------------------------------------------------------
684 void SetupDlg::onFieldChange (int theIndex)
685 {
686   myTypeCombo->clear();
687   myTypeId2ComboId.clear();
688   myComboId2TypeId.clear();
689
690   // ATTENTION: append items in the same order like it is done in the PrsComboItem enumeration
691   myTypeCombo->insertItem("Scalar Map");   // item 0
692   myTypeId2ComboId[TSCALARMAP_ITEM] = myComboId2TypeId.size();
693   myComboId2TypeId.push_back(TSCALARMAP_ITEM);;
694
695   myTypeCombo->insertItem("Iso Surfaces"); // item 1
696   myTypeId2ComboId[TISOSURFACES_ITEM] = myComboId2TypeId.size();
697   myComboId2TypeId.push_back(TISOSURFACES_ITEM);;
698
699   myTypeCombo->insertItem("Cut Planes");   // item 2
700   myTypeId2ComboId[TCUTPLANES_ITEM] = myComboId2TypeId.size();
701   myComboId2TypeId.push_back(TCUTPLANES_ITEM);;
702
703   myTypeCombo->insertItem("Cut Lines");   // item 3
704   myTypeId2ComboId[TCUTLINES_ITEM] = myComboId2TypeId.size();
705   myComboId2TypeId.push_back(TCUTLINES_ITEM);;
706
707   myTypeCombo->insertItem("Plot 3D");      // item 4
708   myTypeId2ComboId[TPLOT3D_ITEM] = myComboId2TypeId.size();
709   myComboId2TypeId.push_back(TPLOT3D_ITEM);;
710
711   bool anEnableItems = false;
712   bool anEnableGP = false;
713   VISU::VISUType aPrsType;
714   if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) { // parallel animation mode
715     
716     FieldData& aData = myAnimator->getFieldData(theIndex);
717     _PTR(SObject) aSObject = aData.myField;
718     VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
719     long aNumComp = aRestoringMap["myNumComponent"].toLong();
720     anEnableItems = (aNumComp > 1);
721     
722     long anEntityId = aRestoringMap["myEntityId"].toLong();
723     anEnableGP = (anEntityId == VISU::CELL);
724
725     aPrsType = aData.myPrsType;
726
727   }
728   else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) { // successive animation mode
729     
730     for (int i = 0; i < myAnimator->getNbFields(); i++) {
731       _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
732       VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSO);
733       long aNumComp = aRestoringMap["myNumComponent"].toLong();
734       anEnableItems = (aNumComp > 1);
735      
736       long anEntityId = aRestoringMap["myEntityId"].toLong();
737       anEnableGP = (anEntityId == VISU::CELL);
738
739       if ( !anEnableItems && !anEnableGP ) break;
740     }
741
742     aPrsType = myAnimator->getFieldData(0).myPrsType;
743
744   }
745
746   if (anEnableItems) {
747     myTypeCombo->insertItem("Deformed Shape"); // item 5
748     myTypeId2ComboId[TDEFORMEDSHAPE_ITEM] = myComboId2TypeId.size();
749     myComboId2TypeId.push_back(TDEFORMEDSHAPE_ITEM);;
750
751     myTypeCombo->insertItem("Vectors");        // item 6
752     myTypeId2ComboId[TVECTORS_ITEM] = myComboId2TypeId.size();
753     myComboId2TypeId.push_back(TVECTORS_ITEM);;
754
755     myTypeCombo->insertItem("Stream Lines");   // item 7
756     myTypeId2ComboId[TSTREAMLINES_ITEM] = myComboId2TypeId.size();
757     myComboId2TypeId.push_back(TSTREAMLINES_ITEM);;
758
759     myTypeCombo->insertItem("Scalar map on Deformed shape");   // item 9
760     myTypeId2ComboId[TSCALARMAPONDEFORMEDSHAPE_ITEM] = myComboId2TypeId.size();
761     myComboId2TypeId.push_back(TSCALARMAPONDEFORMEDSHAPE_ITEM);;
762   }
763
764   if(anEnableGP){
765     myTypeCombo->insertItem("Gauss Points");   // item 8
766     myTypeId2ComboId[TGAUSSPOINTS_ITEM] = myComboId2TypeId.size();
767     myComboId2TypeId.push_back(TGAUSSPOINTS_ITEM);;
768   }
769
770   switch (aPrsType) {
771   case VISU::TSCALARMAP: //Scalar Map
772     myTypeCombo->setCurrentItem(myTypeId2ComboId[TSCALARMAP_ITEM]);
773     break;
774   case VISU::TISOSURFACES: //Iso Surfaces
775     myTypeCombo->setCurrentItem(myTypeId2ComboId[TISOSURFACES_ITEM]);
776     break;
777   case VISU::TCUTPLANES: //Cut Planes
778     myTypeCombo->setCurrentItem(myTypeId2ComboId[TCUTPLANES_ITEM]);
779     break;
780   case VISU::TCUTLINES: //Cut Lines
781     myTypeCombo->setCurrentItem(myTypeId2ComboId[TCUTLINES_ITEM]);
782     break;
783   case VISU::TPLOT3D: //Plot 3D
784     myTypeCombo->setCurrentItem(myTypeId2ComboId[TPLOT3D_ITEM]);
785     break;
786   case VISU::TDEFORMEDSHAPE: //Deformed Shape
787     myTypeCombo->setCurrentItem(myTypeId2ComboId[TDEFORMEDSHAPE_ITEM]);
788     break;
789   case VISU::TSCALARMAPONDEFORMEDSHAPE: //Scalar Map on Deformed Shape
790     myTypeCombo->setCurrentItem(myTypeId2ComboId[TSCALARMAPONDEFORMEDSHAPE_ITEM]);
791     break;
792   case VISU::TVECTORS: //Vectors
793     myTypeCombo->setCurrentItem(myTypeId2ComboId[TVECTORS_ITEM]);
794     break;
795   case VISU::TSTREAMLINES: //Stream Lines
796     myTypeCombo->setCurrentItem(myTypeId2ComboId[TSTREAMLINES_ITEM]);
797     break;
798   case VISU::TGAUSSPOINTS: //Gauss Points
799     myTypeCombo->setCurrentItem(myTypeId2ComboId[TGAUSSPOINTS_ITEM]);
800     break;
801   }
802   //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
803 }
804
805 //------------------------------------------------------------------------
806 void SetupDlg::onTypeChanged (int theIndex)
807 {
808   int aType = myComboId2TypeId[theIndex];
809   
810   for (int i = 0; i < myAnimator->getNbFields(); i++) {
811     FieldData& aData = ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) ?
812       myAnimator->getFieldData(myFieldLst->currentItem()) :
813       myAnimator->getFieldData(i);
814
815     switch (aType) {
816     case TSCALARMAP_ITEM: //Scalar Map
817       aData.myPrsType = VISU::TSCALARMAP;
818       break;
819     case TISOSURFACES_ITEM: //Iso Surfaces
820       aData.myPrsType = VISU::TISOSURFACES;
821       break;
822     case TCUTPLANES_ITEM: //Cut Planes
823       aData.myPrsType = VISU::TCUTPLANES;
824       break;
825     case TCUTLINES_ITEM: //Cut Lines
826       aData.myPrsType = VISU::TCUTLINES;
827       break;
828     case TPLOT3D_ITEM: //Plot 3D
829       aData.myPrsType = VISU::TPLOT3D;
830       break;
831     case TDEFORMEDSHAPE_ITEM: //Deformed Shape
832       aData.myPrsType = VISU::TDEFORMEDSHAPE;
833       break;
834     case TSCALARMAPONDEFORMEDSHAPE_ITEM: //Scalar Map on Deformed Shape
835       aData.myPrsType = VISU::TSCALARMAPONDEFORMEDSHAPE;
836       break;
837     case TVECTORS_ITEM: //Vectors
838       aData.myPrsType = VISU::TVECTORS;
839       break;
840     case TSTREAMLINES_ITEM: //Stream Lines
841       aData.myPrsType = VISU::TSTREAMLINES;
842       break;
843     case TGAUSSPOINTS_ITEM: //Gauss Points
844       aData.myPrsType = VISU::TGAUSSPOINTS;
845       break;
846     }
847     myAnimator->clearData(aData);
848
849     if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) // parallel animation mode
850       break;
851   }
852   //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
853   //myAnimator->generatePresentations(myFieldLst->currentItem());
854 }
855
856
857 //------------------------------------------------------------------------
858 namespace
859 {
860   template<class TPrs3d, class TDialog>
861   void
862   EditPrs(VisuGUI* theModule,
863           FieldData& theData,
864           VISU_TimeAnimation* theAnimator)
865   {
866     TDialog* aDlg = new TDialog(theModule);
867     TPrs3d* aPrs3d = dynamic_cast<TPrs3d*>(theData.myPrs[0]);
868     aDlg->initFromPrsObject(aPrs3d, true);
869     if (aDlg->exec() && aDlg->storeToPrsObject(dynamic_cast<TPrs3d*>(aPrs3d))) {
870
871       for (long aFrameId = 1; aFrameId < theData.myNbFrames; aFrameId++){
872         VISU::ColoredPrs3d_i* aColoredPrs3d = theData.myPrs[aFrameId];
873         aColoredPrs3d->SameAs(aPrs3d);
874       }
875
876       if ( theAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
877         for (int aFieldId = 1; aFieldId < theAnimator->getNbFields(); aFieldId++) {
878           FieldData& aFieldData = theAnimator->getFieldData(aFieldId);
879           for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
880             VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
881             std::string aTitle = aColoredPrs3d->GetCTitle();
882             aColoredPrs3d->SameAs(aPrs3d);
883             aColoredPrs3d->SetTitle(aTitle.c_str());
884           }
885         }
886       }
887     }
888     delete aDlg;
889   }
890 }
891
892
893 void SetupDlg::onPreferencesDlg()
894 {
895   SUIT_OverrideCursor c;
896
897   VISU::Animation::AnimationMode aMode = myAnimator->getAnimationMode();
898   int aRefFieldId = ( aMode == VISU::Animation::PARALLEL ) ? myFieldLst->currentItem() : 0;
899   FieldData& aData = myAnimator->getFieldData(aRefFieldId);
900   if (aData.myPrs.empty()) 
901     myAnimator->generatePresentations(aRefFieldId);
902
903   if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
904     for (int i = 0; i < myAnimator->getNbFields(); i++) {
905       if ( i != aRefFieldId && myAnimator->getFieldData(i).myPrs.empty() ) 
906         myAnimator->generatePresentations(i);
907     }
908   }
909
910   if(!aData.myNbFrames || !aData.myPrs[0]){
911     QApplication::restoreOverrideCursor();
912     SUIT_MessageBox::warn1(this,
913                            tr("ERROR"),
914                            VisuGUI_TimeAnimationDlg::tr("MSG_NO_ANIMATIONDATA"),
915                            tr("&OK"));
916     return;
917   }
918
919   int aType = myComboId2TypeId[myTypeCombo->currentItem()];
920   switch (aType) {
921   case TSCALARMAP_ITEM: //Scalar Map
922     c.suspend();
923     EditPrs<VISU::ScalarMap_i, VisuGUI_ScalarBarDlg>(myModule, aData, myAnimator);
924     break;
925   case TISOSURFACES_ITEM: //Iso Surfaces
926     c.suspend();
927     EditPrs<VISU::IsoSurfaces_i, VisuGUI_IsoSurfacesDlg>(myModule, aData, myAnimator);
928     break;
929   case TCUTPLANES_ITEM: //Cut Planes
930     c.suspend();
931     EditPrs<VISU::CutPlanes_i, VisuGUI_CutPlanesDlg>(myModule, aData, myAnimator);
932     break;
933   case TCUTLINES_ITEM: //Cut Lines
934     c.suspend();
935     EditPrs<VISU::CutLines_i, VisuGUI_CutLinesDlg>(myModule, aData, myAnimator);
936     break;
937   case TPLOT3D_ITEM: //Plot 3D
938     c.suspend();
939     EditPrs<VISU::Plot3D_i, VisuGUI_Plot3DDlg>(myModule, aData, myAnimator);
940     break;
941   case TDEFORMEDSHAPE_ITEM: //Deformed Shape
942     c.suspend();
943     EditPrs<VISU::DeformedShape_i, VisuGUI_DeformedShapeDlg>(myModule, aData, myAnimator);
944     break;
945   case TSCALARMAPONDEFORMEDSHAPE_ITEM: //Scalar Map on Deformed Shape
946     c.suspend();
947     {
948       typedef VisuGUI_ScalarMapOnDeformedShapeDlg DLG;
949       typedef VISU::ScalarMapOnDeformedShape_i TYPE;
950       DLG* aDlg = new DLG (myModule);
951       TYPE* aPrs3d = dynamic_cast<TYPE*>(aData.myPrs[0]);
952       aDlg->initFromPrsObject(aPrs3d, true);
953       if (aDlg->exec() && aDlg->storeToPrsObject(aData.myPrs[0])) { 
954         for (int i = 1; i < aData.myNbFrames; i++){
955           aData.myPrs[i]->SameAs(aData.myPrs[0]);
956         }
957       }
958       delete aDlg;
959     }
960     break;
961   case TVECTORS_ITEM: //Vectors
962     c.suspend();
963     EditPrs<VISU::Vectors_i, VisuGUI_VectorsDlg>(myModule, aData, myAnimator);
964     break;
965   case TSTREAMLINES_ITEM: //Stream Lines
966     c.suspend();
967     EditPrs<VISU::StreamLines_i, VisuGUI_StreamLinesDlg>(myModule, aData, myAnimator);
968     break;
969   case TGAUSSPOINTS_ITEM: //Gauss Points
970     c.suspend();
971     EditPrs<VISU::GaussPoints_i, VisuGUI_GaussPointsDlg>(myModule, aData, myAnimator);
972     break;
973   }
974 }
975
976
977 //------------------------------------------------------------------------
978 void SetupDlg::onArrangeDlg()
979 {
980   ArrangeDlg aDlg(this, myAnimator);
981   aDlg.exec();
982 }
983
984 //------------------------------------------------------------------------
985 void SetupDlg::onRangeCheck (bool theCheck)
986 {
987   if( theCheck )
988   {
989     myUseSequenceBox->blockSignals( true );
990     myUseSequenceBox->setChecked( false );
991     myUseSequenceBox->blockSignals( false );
992   }
993
994   if (!theCheck)
995     myAnimator->setAnimationRange(0, 0);
996   else
997     myAnimator->setAnimationRange(myMinVal->value(), myMaxVal->value());
998
999   setIsRegenerate( true );
1000 }
1001
1002 //------------------------------------------------------------------------
1003 void SetupDlg::onMinValue (double theVal)
1004 {
1005   if (theVal > myAnimator->getMaxRange()) {
1006     myMinVal->setValue( myAnimator->getMinTime() );
1007     myMinVal->setFocus();
1008     return;
1009   }
1010   myAnimator->setAnimationRange(theVal, myAnimator->getMaxRange());
1011
1012   setIsRegenerate( true );
1013 }
1014
1015 //------------------------------------------------------------------------
1016 void SetupDlg::onMaxValue (double theVal)
1017 {
1018   if (theVal < myAnimator->getMinRange()) {
1019     myMaxVal->setValue( myAnimator->getMaxTime() );
1020     myMaxVal->setFocus();
1021     return;
1022   }
1023   myAnimator->setAnimationRange(myAnimator->getMinRange(), theVal);
1024
1025   setIsRegenerate( true );
1026 }
1027
1028 //------------------------------------------------------------------------
1029 void SetupDlg::onSequenceCheck( bool theCheck )
1030 {
1031   if( theCheck )
1032   {
1033     myUseRangeBox->blockSignals( true );
1034     myUseRangeBox->setChecked( false );
1035     myUseRangeBox->blockSignals( false );
1036   }
1037
1038   QString anIndices = myIndices->text();
1039   myAnimator->setAnimationSequence( anIndices.latin1() );
1040
1041   setIsRegenerate( true );
1042 }
1043
1044 //------------------------------------------------------------------------
1045 void SetupDlg::onIndicesChanged( const QString& theIndices )
1046 {
1047   bool aCorrect = true;
1048   int aLimit = myValues->count();
1049
1050   QValueList<long> anIndicesList;
1051   aCorrect = myAnimator->getIndicesFromSequence( theIndices, anIndicesList );
1052
1053   myValues->blockSignals( true );
1054   myValues->clearSelection();
1055
1056   QValueList<long>::iterator indIt = anIndicesList.begin();
1057   QValueList<long>::iterator indItEnd = anIndicesList.end();
1058   for( int i = 0; indIt != indItEnd; ++indIt, i++ )
1059   {
1060     long anIndex = *indIt;
1061     if( anIndex < 1 || anIndex > aLimit )
1062     {
1063       aCorrect = false;
1064       myValues->clearSelection();
1065       break;
1066     }
1067     myValues->setSelected( anIndex-1, true );
1068   }
1069
1070   myValues->blockSignals( false );
1071
1072   if( !aCorrect )
1073   {
1074     myIndices->setPaletteForegroundColor( Qt::red );
1075     return;
1076   }
1077
1078   myIndices->setPaletteForegroundColor( Qt::black );
1079
1080   myAnimator->setAnimationSequence( theIndices.latin1() );
1081
1082   setIsRegenerate( true );
1083 }
1084
1085 //------------------------------------------------------------------------
1086 void SetupDlg::onValuesChanged()
1087 {
1088   int aLimit = myValues->count();
1089
1090   QString anIndices;
1091
1092   for( int i = 0; i < aLimit; i++ )
1093   {
1094     if( !myValues->isSelected( i ) )
1095       continue;
1096
1097     QString aString = QString::number( i+1 );
1098
1099     bool aPrevSelected = i != 0 && myValues->isSelected( i-1 );
1100     bool aNextSelected = i != aLimit - 1 && myValues->isSelected( i+1 );
1101     if( aPrevSelected )
1102     {
1103       if( aNextSelected )
1104         aString = "";
1105       else
1106         aString += ",";
1107     }
1108     else
1109     {
1110       if( aNextSelected )
1111         aString += "-";
1112       else
1113         aString += ",";
1114     }
1115
1116     anIndices += aString;
1117   }
1118
1119   if( anIndices.right( 1 ) == "," )
1120     anIndices.truncate( anIndices.length() - 1 );
1121
1122   myIndices->blockSignals( true );
1123   myIndices->setPaletteForegroundColor( Qt::black );
1124   myIndices->setText( anIndices );
1125   myIndices->blockSignals( false );
1126
1127   myAnimator->setAnimationSequence( anIndices.latin1() );
1128
1129   setIsRegenerate( true );
1130 }
1131
1132 //------------------------------------------------------------------------
1133 static const char * firstIco[] = {
1134 "18 10 2 1",
1135 "       g None",
1136 ".      g #000000",
1137 "         .     .  ",
1138 "  ..    ..    ..  ",
1139 "  ..   ...   ...  ",
1140 "  ..  ....  ....  ",
1141 "  .. ..... .....  ",
1142 "  .. ..... .....  ",
1143 "  ..  ....  ....  ",
1144 "  ..   ...   ...  ",
1145 "  ..    ..    ..  ",
1146 "         .     .  "};
1147
1148
1149 static const char * lastIco[] = {
1150 "18 10 2 1",
1151 "       g None",
1152 ".      g #000000",
1153 "  .     .         ",
1154 "  ..    ..    ..  ",
1155 "  ...   ...   ..  ",
1156 "  ....  ....  ..  ",
1157 "  ..... ..... ..  ",
1158 "  ..... ..... ..  ",
1159 "  ....  ....  ..  ",
1160 "  ...   ...   ..  ",
1161 "  ..    ..    ..  ",
1162 "  .     .         "};
1163
1164
1165 static const char * leftIco[] = {
1166 "11 10 2 1",
1167 "       g None",
1168 ".      g #000000",
1169 "    .     .",
1170 "   ..    ..",
1171 "  ...   ...",
1172 " ....  ....",
1173 "..... .....",
1174 "..... .....",
1175 " ....  ....",
1176 "  ...   ...",
1177 "   ..    ..",
1178 "    .     ."};
1179
1180 static const char * playIco[] = {
1181 "14 14 2 1",
1182 "       g None",
1183 ".      g #000000",
1184 "              ",
1185 "              ",
1186 "  ..          ",
1187 "  ....        ",
1188 "  ......      ",
1189 "  ........    ",
1190 "  ..........  ",
1191 "  ..........  ",
1192 "  ........    ",
1193 "  ......      ",
1194 "  ....        ",
1195 "  ..          ",
1196 "              ",
1197 "              "};
1198
1199 static QPixmap MYplayPixmap(playIco);
1200
1201
1202 static const char * rightIco[] = {
1203 "11 10 2 1",
1204 "       g None",
1205 ".      g #000000",
1206 ".     .    ",
1207 "..    ..   ",
1208 "...   ...  ",
1209 "....  .... ",
1210 "..... .....",
1211 "..... .....",
1212 "....  .... ",
1213 "...   ...  ",
1214 "..    ..   ",
1215 ".     .    "};
1216
1217
1218 static const char * pauseIco[] = {
1219 "14 14 2 1",
1220 "       g None",
1221 ".      g #000000",
1222 "              ",
1223 "              ",
1224 "   ..    ..   ",
1225 "   ..    ..   ",
1226 "   ..    ..   ",
1227 "   ..    ..   ",
1228 "   ..    ..   ",
1229 "   ..    ..   ",
1230 "   ..    ..   ",
1231 "   ..    ..   ",
1232 "   ..    ..   ",
1233 "   ..    ..   ",
1234 "              ",
1235 "              "};
1236
1237 static QPixmap MYpausePixmap(pauseIco);
1238
1239
1240 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (VisuGUI* theModule,
1241                                                     _PTR(Study) theStudy, 
1242                                                     VISU::Animation::AnimationMode theMode) :
1243   QDialog(VISU::GetDesktop(theModule), 
1244           "VisuGUI_TimeAnimationDlg", 
1245           false, 
1246           WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
1247   myModule(theModule),
1248   mySetupDlg(NULL)
1249 {
1250   if ( theMode == VISU::Animation::PARALLEL )
1251     setCaption(tr("PARALLEL_ANIMATION"));
1252   else
1253     setCaption(tr("SUCCESSIVE_ANIMATION"));
1254   setSizeGripEnabled( TRUE );
1255
1256   myAnimator = new VISU_TimeAnimation (theStudy);
1257   myAnimator->setViewer(VISU::GetActiveViewWindow<SVTK_ViewWindow>(theModule));
1258   connect(myAnimator, SIGNAL(frameChanged(long, double)), this, SLOT(onExecution(long, double)));
1259   connect(myAnimator, SIGNAL(stopped()),                  this, SLOT(onStop()));
1260   myAnimator->setAnimationMode(theMode);
1261
1262   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
1263   aMainLayout->setSpacing(5);
1264
1265   mySetupBtn = new QPushButton("Setup Animation...", this);
1266   connect( mySetupBtn, SIGNAL( clicked() ),
1267            this, SLOT( onSetupDlg() ) );
1268   aMainLayout->addWidget(mySetupBtn);
1269
1270   myGenBtn = new QPushButton("Generate frames", this);
1271   connect( myGenBtn, SIGNAL( clicked() ),
1272            this, SLOT( createFrames() ) );
1273   aMainLayout->addWidget(myGenBtn);
1274
1275   myPlayFrame = new QFrame(this);
1276   myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
1277   myPlayFrame->setLineWidth( 1 );
1278
1279
1280   // --- Play controls ---
1281   QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
1282   TopLayout->setSpacing( 6 );
1283   TopLayout->setMargin( 11 );
1284
1285   myTimeLbl = new QLabel("0", myPlayFrame);
1286   TopLayout->addMultiCellWidget(myTimeLbl, 0, 0, 0, 2, Qt::AlignHCenter);
1287
1288   mySlider = new QSlider(Qt::Horizontal, myPlayFrame);
1289   mySlider->setMinValue(0);
1290   mySlider->setMaxValue(3);
1291   mySlider->setTickInterval(1);
1292   //mySlider->setTickmarks(QSlider::Below);
1293   mySlider->setTracking(false);
1294   connect( mySlider, SIGNAL( valueChanged(int) ),
1295            this, SLOT( onWindowChanged(int) ) );
1296   TopLayout->addMultiCellWidget(mySlider, 1, 1, 0, 2);
1297
1298   myPlayBtn = new QToolButton(myPlayFrame);
1299   myPlayBtn->setIconSet(MYplayPixmap);
1300   myPlayBtn->setToggleButton(true);
1301   connect( myPlayBtn, SIGNAL( clicked() ),
1302            this, SLOT( onPlayPressed() ) );
1303   TopLayout->addMultiCellWidget(myPlayBtn, 2, 2, 0, 1);
1304
1305   QToolButton* aBackBtn = new QToolButton(myPlayFrame);
1306   aBackBtn->setIconSet(QPixmap(leftIco));
1307   connect( aBackBtn, SIGNAL( clicked() ),
1308            this, SLOT( onBackPressed() ) );
1309   TopLayout->addWidget(aBackBtn, 3, 0);
1310
1311   QToolButton* aForvardBtn = new QToolButton(myPlayFrame);
1312   aForvardBtn->setIconSet(QPixmap(rightIco));
1313   connect( aForvardBtn, SIGNAL( clicked() ),
1314            this, SLOT( onForvardPressed() ) );
1315   TopLayout->addWidget(aForvardBtn, 3, 1);
1316
1317   QToolButton* aFirstBtn = new QToolButton(myPlayFrame);
1318   aFirstBtn->setIconSet(QPixmap(firstIco));
1319   connect( aFirstBtn, SIGNAL( clicked() ),
1320            this, SLOT( onFirstPressed() ) );
1321   TopLayout->addWidget(aFirstBtn, 4, 0);
1322
1323   QToolButton* aLastBtn = new QToolButton(myPlayFrame);
1324   aLastBtn->setIconSet(QPixmap(lastIco));
1325   connect( aLastBtn, SIGNAL( clicked() ),
1326            this, SLOT( onLastPressed() ) );
1327   TopLayout->addWidget(aLastBtn, 4, 1);
1328
1329   QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
1330   TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
1331
1332   QLCDNumber* aSpeedNum  = new QLCDNumber( 2, myPlayFrame );
1333   aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
1334   aSpeedNum->display((int)myAnimator->getSpeed());
1335   TopLayout->addWidget(aSpeedNum, 4, 3);
1336
1337   QwtWheel* aWheel = new QwtWheel(myPlayFrame);
1338   aWheel->setOrientation(Qt::Vertical);
1339   aWheel->setRange(1, 99, 1);
1340   aWheel->setValue((int)myAnimator->getSpeed());
1341   connect( aWheel, SIGNAL(valueChanged(double)),
1342            aSpeedNum, SLOT(display(double)) );
1343   connect( aWheel, SIGNAL(valueChanged(double)),
1344            this, SLOT(onSpeedChange(double)) );
1345   TopLayout->addMultiCellWidget(aWheel, 1, 3, 3, 3, Qt::AlignRight);
1346
1347   QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
1348   aCycleCheck->setChecked(myAnimator->isCycling());
1349   connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
1350   TopLayout->addMultiCellWidget(aCycleCheck, 5, 5, 0, 3);
1351
1352   QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
1353   aPropCheck->setChecked(myAnimator->isProportional());
1354   connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
1355   TopLayout->addMultiCellWidget(aPropCheck, 6, 6, 0, 3);
1356
1357   // Pictures saving on disk
1358   QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
1359   aSaveBox->setColumnLayout(0, Qt::Horizontal );
1360   QGridLayout* aSaveLay = new QGridLayout(aSaveBox->layout());
1361   aSaveLay->setSpacing( 5 );
1362   aSaveLay->setMargin( 5 );
1363
1364   mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
1365   connect(mySaveCheck, SIGNAL( toggled(bool)),
1366           this, SLOT( onCheckDump(bool) ));
1367   aSaveLay->addMultiCellWidget(mySaveCheck, 0, 0, 0, 2);
1368
1369   QLabel* aFormatLbl = new QLabel("Saving format:", aSaveBox);
1370   aFormatLbl->setEnabled(false);
1371   connect(mySaveCheck, SIGNAL( toggled(bool)),
1372           aFormatLbl, SLOT( setEnabled(bool) ));
1373   aSaveLay->addMultiCellWidget(aFormatLbl, 1, 1, 0, 1);
1374
1375   myPicsFormat = new QComboBox(aSaveBox);
1376   QStrList aDumpFormats = QImageIO::outputFormats();
1377   for (unsigned int i = 0; i < aDumpFormats.count(); i++) {
1378     myPicsFormat->insertItem(aDumpFormats.at(i));
1379   }
1380   if (aDumpFormats.find("JPEG"))
1381     myPicsFormat->setCurrentItem(aDumpFormats.find("JPEG"));
1382   else
1383     myPicsFormat->setCurrentItem(0);
1384   myPicsFormat->setEnabled(false);
1385   aSaveLay->addWidget(myPicsFormat, 1, 2);
1386   connect(mySaveCheck, SIGNAL( toggled(bool)),
1387           myPicsFormat, SLOT( setEnabled(bool) ));
1388   connect(myPicsFormat, SIGNAL(  activated (int)),
1389           this, SLOT( onPicsFormatChanged()));
1390
1391   QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
1392   aPathLbl->setEnabled(false);
1393   connect(mySaveCheck, SIGNAL( toggled(bool)),
1394           aPathLbl, SLOT( setEnabled(bool) ));
1395   aSaveLay->addWidget(aPathLbl, 2, 0);
1396
1397   myPathEdit = new QLineEdit(aSaveBox);
1398   myPathEdit->setReadOnly(true);
1399   myPathEdit->setEnabled(false);
1400   connect(mySaveCheck, SIGNAL( toggled(bool)),
1401           myPathEdit, SLOT( setEnabled(bool) ));
1402   aSaveLay->addWidget(myPathEdit, 2, 1);
1403
1404   QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
1405   aBrowseBtn->setEnabled(false);
1406   connect(mySaveCheck, SIGNAL( toggled(bool)),
1407           aBrowseBtn, SLOT( setEnabled(bool) ));
1408   connect(aBrowseBtn, SIGNAL( clicked()),
1409           this, SLOT( onBrowse() ));
1410   mySaveCheck->setChecked(false);
1411   aSaveLay->addWidget(aBrowseBtn, 2, 2);
1412
1413   mySaveAVICheck = new QCheckBox("Save animation to AVI file", aSaveBox);
1414   connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1415           this, SLOT( onCheckDump(bool) ));
1416   aSaveLay->addMultiCellWidget(mySaveAVICheck, 3, 3, 0, 2);
1417
1418   myPathAVILbl = new QLabel("Path:", aSaveBox);
1419   myPathAVILbl->setEnabled(false);
1420   //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1421   //        myPathAVILbl, SLOT( setEnabled(bool) ));
1422   aSaveLay->addWidget(myPathAVILbl, 4, 0);
1423
1424   myPathAVIEdit = new QLineEdit(aSaveBox);
1425   myPathAVIEdit->setReadOnly(true);
1426   myPathAVIEdit->setEnabled(false);
1427   //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1428   //        myPathAVIEdit, SLOT( setEnabled(bool) ));
1429   aSaveLay->addWidget(myPathAVIEdit, 4, 1);
1430
1431   myBrowseAVIBtn = new QPushButton("Browse...", aSaveBox);
1432   myBrowseAVIBtn->setEnabled(false);
1433   //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1434   //        myBrowseAVIBtn, SLOT( setEnabled(bool) ));
1435   connect(myBrowseAVIBtn, SIGNAL( clicked()),
1436           this, SLOT( onBrowseAVI() ));
1437   aSaveLay->addWidget(myBrowseAVIBtn, 4, 2);
1438
1439   mySaveAVICheck->setChecked(false);
1440   //mySaveAVICheck->setEnabled(myAnimator->checkAVIMaker());
1441
1442   TopLayout->addMultiCellWidget(aSaveBox, 7, 7, 0, 3);
1443
1444   QCheckBox* aCleanMemCheck = new QCheckBox("Clean memory at each frame",myPlayFrame);
1445   aCleanMemCheck->setChecked(myAnimator->isCleaningMemoryAtEachFrame());
1446   connect(aCleanMemCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCleaningMemoryAtEachFrameSlot(bool)));
1447   TopLayout->addMultiCellWidget(aCleanMemCheck, 8, 8, 0, 3);
1448
1449   aMainLayout->addWidget(myPlayFrame);
1450
1451   // Animation publishing in study
1452   QHBox* aPublishBox = new QHBox(this);
1453   aPublishBox->setSpacing(5);
1454
1455   myPublishBtn = new QPushButton("Publish to study", aPublishBox);
1456   connect(myPublishBtn, SIGNAL(clicked()), this, SLOT(publishToStudy()));
1457
1458   mySaveBtn = new QPushButton("Save Animation", aPublishBox);
1459   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1460   connect(mySaveBtn, SIGNAL(clicked()), this, SLOT(saveToStudy()));
1461
1462   aMainLayout->addWidget(aPublishBox);
1463
1464
1465   QHBox* aBtnBox = new QHBox(this);
1466   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
1467   aBtnLayout->addStretch();
1468
1469   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
1470   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
1471
1472   QPushButton* aHelpBtn = new QPushButton(tr("BUT_HELP"), aBtnBox);
1473   connect(aHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp()));
1474
1475   SUIT_Study* aStudy = VISU::GetAppStudy(myModule);
1476   connect(aStudy, SIGNAL(destroyed()), this, SLOT(close()));
1477
1478   connect(myAnimator->getViewer(), SIGNAL(destroyed()), this, SLOT(close()));
1479   connect(myAnimator->getViewer(), SIGNAL(closing(SUIT_ViewWindow*)), this, SLOT(close()));
1480
1481   aMainLayout->addWidget(aBtnBox);
1482
1483   myPlayFrame->setEnabled(false);
1484 }
1485
1486 //------------------------------------------------------------------------
1487 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg()
1488 {
1489   if (myAnimator != NULL) {
1490     delete myAnimator;
1491     myAnimator = NULL;
1492     if ( VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule) )
1493       VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule)->Repaint();
1494   }
1495 }
1496
1497 //------------------------------------------------------------------------
1498 void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
1499 {
1500   stopAnimation();
1501   myPropBtn->setEnabled(index != 0);
1502
1503   clearView();
1504   myPlayFrame->setEnabled(false);
1505 }
1506
1507 //------------------------------------------------------------------------
1508 bool VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
1509 {
1510   myPlayFrame->setEnabled(false);
1511   return myAnimator->addField(theSObject);
1512 }
1513
1514 //------------------------------------------------------------------------
1515 void VisuGUI_TimeAnimationDlg::createFrames()
1516 {
1517   stopAnimation();
1518   SUIT_OverrideCursor c;
1519
1520   bool isRegenerate = mySetupDlg->isRegenerate();
1521
1522   for (int i = 0; i < myAnimator->getNbFields(); i++) {
1523     FieldData& aFieldData = myAnimator->getFieldData(i);
1524     if( aFieldData.myPrs.empty() )
1525     {
1526       myAnimator->generatePresentations(i);
1527       continue;
1528     }
1529
1530     // ouv : IPAL18064
1531     // even if aFieldData is not empty, we must regenerate presentations,
1532     // when a range or a sequence of the animation has been changed
1533     if( isRegenerate )
1534     {
1535       VISU::ColoredPrs3d_i* aPrs3d = dynamic_cast<VISU::ColoredPrs3d_i*>(aFieldData.myPrs[0]);
1536       if( !aPrs3d )
1537         continue;
1538
1539       myAnimator->generatePresentations(i);
1540
1541       aFieldData = myAnimator->getFieldData(i);
1542       for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1543         VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
1544         std::string aTitle = aColoredPrs3d->GetCTitle();
1545         aColoredPrs3d->SameAs(aPrs3d);
1546         if ( aFrameId != 0 && myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1547           aColoredPrs3d->SetTitle(aTitle.c_str());
1548         }
1549       }
1550     }
1551   }
1552   if( isRegenerate )
1553     mySetupDlg->setIsRegenerate( false );
1554
1555   if (myAnimator->getNbFrames() == 0) {
1556     myPlayFrame->setEnabled(false);
1557     c.suspend();
1558     SUIT_MessageBox::warn1(this,
1559                            tr("ERROR"),
1560                            tr("MSG_NO_ANIMATIONDATA"),
1561                            tr("&OK"));
1562     return;
1563   }
1564   mySlider->setMaxValue(myAnimator->getNbFrames()-1);
1565   myPlayFrame->setEnabled(true);
1566   if (!myAnimator->generateFrames()) {
1567     c.suspend();
1568     //myPlayFrame->setEnabled(false);
1569     SUIT_MessageBox::warn1(this,
1570                            tr("ERROR"),
1571                            myAnimator->getLastErrorMsg(),
1572                            tr("&OK"));
1573     return;
1574   }
1575   //myPlayFrame->setEnabled(true);
1576 }
1577
1578 //------------------------------------------------------------------------
1579 void VisuGUI_TimeAnimationDlg::onPlayPressed()
1580 {
1581   if (myPlayBtn->isOn() && (!myAnimator->running())) {
1582     myPlayBtn->setIconSet(MYpausePixmap);
1583     if (mySaveCheck->isChecked()) {
1584       onPicsFormatChanged();
1585       onPathChanged();
1586       
1587     } else if (mySaveAVICheck->isChecked()) {
1588       myAnimator->setDumpFormat("AVI");
1589       myAnimator->dumpTo(myPathAVIEdit->text());
1590     } else {
1591       myAnimator->dumpTo("");
1592     }
1593     mySetupBtn->setEnabled(false);
1594     myGenBtn->setEnabled(false);
1595     myAnimator->startAnimation();
1596   } else {
1597     myPlayBtn->setIconSet(MYplayPixmap);
1598     myAnimator->stopAnimation();
1599     mySetupBtn->setEnabled(true);
1600     myGenBtn->setEnabled(true);
1601   }
1602 }
1603
1604 //------------------------------------------------------------------------
1605 void VisuGUI_TimeAnimationDlg::onBackPressed()
1606 {
1607   //stopAnimation();
1608   myAnimator->prevFrame();
1609 }
1610
1611 //------------------------------------------------------------------------
1612 void VisuGUI_TimeAnimationDlg::onForvardPressed()
1613 {
1614   myAnimator->nextFrame();
1615 }
1616
1617 //------------------------------------------------------------------------
1618 void VisuGUI_TimeAnimationDlg::onLastPressed()
1619 {
1620   myAnimator->lastFrame();
1621 }
1622
1623 //------------------------------------------------------------------------
1624 void VisuGUI_TimeAnimationDlg::onFirstPressed()
1625 {
1626   myAnimator->firstFrame();
1627 }
1628
1629 //------------------------------------------------------------------------
1630 void VisuGUI_TimeAnimationDlg::clearView()
1631 {
1632   myAnimator->clearView();
1633 }
1634
1635 //------------------------------------------------------------------------
1636 void VisuGUI_TimeAnimationDlg::showEvent(QShowEvent* theEvent)
1637 {
1638   mySetupDlg = new SetupDlg(this,myModule, myAnimator);
1639   mySetupDlg->initialize();
1640 }
1641
1642 //------------------------------------------------------------------------
1643 void VisuGUI_TimeAnimationDlg::closeEvent (QCloseEvent* theEvent)
1644 {
1645   if (myAnimator != NULL) {
1646     myAnimator->stopAnimation();
1647     myAnimator->wait(500);
1648     if (myAnimator->running() && (! myAnimator->finished())) {
1649       theEvent->ignore();
1650       QCloseEvent* aNewCloseEvent = new QCloseEvent;
1651       QApplication::postEvent( this, aNewCloseEvent );
1652     } else {
1653       QDialog::closeEvent(theEvent);
1654     }
1655   } else {
1656     QDialog::closeEvent(theEvent);
1657   }
1658 }
1659
1660 //------------------------------------------------------------------------
1661 void VisuGUI_TimeAnimationDlg::onWindowChanged (int index)
1662 {
1663   if (myAnimator->isRunning()) return;
1664   myAnimator->gotoFrame(index);
1665 }
1666
1667 //------------------------------------------------------------------------
1668 void VisuGUI_TimeAnimationDlg::onSpeedChange (double theSpeed)
1669 {
1670   myAnimator->setSpeed((int)theSpeed);
1671 }
1672
1673 //------------------------------------------------------------------------
1674 void VisuGUI_TimeAnimationDlg::stopAnimation()
1675 {
1676   myAnimator->stopAnimation();
1677   myPlayBtn->setOn(false);
1678   myPlayBtn->setIconSet(MYplayPixmap);
1679   mySetupBtn->setEnabled(true);
1680   myGenBtn->setEnabled(true);
1681 }
1682
1683 //------------------------------------------------------------------------
1684 void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
1685 {
1686   myTimeLbl->setText(QString("%1").arg(theTime));
1687   mySlider->setValue(theNewFrame);
1688 }
1689
1690 //------------------------------------------------------------------------
1691 void VisuGUI_TimeAnimationDlg::onSetupDlg()
1692 {
1693   if (myAnimator->getNbFrames() > 0) 
1694     myAnimator->firstFrame();
1695   mySetupDlg->exec();
1696   myPlayFrame->setEnabled(false);
1697 }
1698
1699 //------------------------------------------------------------------------
1700 void VisuGUI_TimeAnimationDlg::onBrowse()
1701 {
1702   //  QString aPath = SUIT_FileDlg::getExistingDirectory(this, "/", "Select path");
1703   QString aDir;
1704   if (myPathEdit->text().isEmpty())
1705     aDir = getenv("HOME");
1706   else 
1707     aDir = myPathEdit->text();
1708   QString aPath = SUIT_FileDlg::getExistingDirectory(this, aDir, "Select path");
1709   if (!aPath.isEmpty())
1710     myPathEdit->setText(Qtx::addSlash(aPath));
1711   onPathChanged();
1712 }
1713
1714 //------------------------------------------------------------------------
1715 void VisuGUI_TimeAnimationDlg::onBrowseAVI()
1716 {
1717   QStringList aFilter;
1718   aFilter.append( "AVI Files (*.avi)" );
1719   aFilter.append( "All Files (*.*)" );
1720
1721   QString aDir;
1722   if (myPathAVIEdit->text().isEmpty())
1723     aDir = getenv("HOME");
1724   else {
1725     QFileInfo aFile(myPathAVIEdit->text());
1726     aDir = aFile.dirPath(true);
1727   }
1728   QString aPath = SUIT_FileDlg::getFileName(this, aDir, aFilter, "Select file", false);
1729   if (!aPath.isEmpty())
1730     myPathAVIEdit->setText(aPath);
1731 }
1732
1733 //------------------------------------------------------------------------
1734 void VisuGUI_TimeAnimationDlg::onCheckDump(bool)
1735 {
1736   const QObject* source = sender();
1737   if (source == mySaveCheck) {
1738     if (mySaveCheck->isChecked()) {
1739       onPicsFormatChanged();
1740       onPathChanged();
1741       if (mySaveAVICheck->isChecked())
1742         mySaveAVICheck->setChecked(false);
1743     } else {
1744       myAnimator->dumpTo("");
1745     }
1746     //mySaveAVICheck->setEnabled(!mySaveCheck->isChecked() && myAnimator->checkAVIMaker());
1747     mySaveAVICheck->setEnabled(!mySaveCheck->isChecked());
1748   }
1749   else if (source == mySaveAVICheck) {
1750     if (mySaveAVICheck->isChecked()) {
1751       if (!myAnimator->checkAVIMaker()) {
1752         // AVI maker is not available
1753         SUIT_MessageBox::warn1(this, tr("ERROR"), tr("MSG_NO_AVI_MAKER"), tr("&OK"));
1754         mySaveAVICheck->setChecked(false);
1755       }
1756       else {
1757         if (mySaveCheck->isChecked()) {
1758           mySaveCheck->setChecked(false);
1759         }
1760         myPathAVILbl->setEnabled(true);
1761         myPathAVIEdit->setEnabled(true);
1762         myBrowseAVIBtn->setEnabled(true);
1763       }
1764     }
1765     else {
1766       // it is necessary in case of not available AVI maker,
1767       // because otherwise they will stay enabled
1768       // (??? slots, connected on SIGNAL(toggled(bool)) of mySaveAVICheck,
1769       // works in wrong order ???)
1770       myPathAVILbl->setEnabled(false);
1771       myPathAVIEdit->setEnabled(false);
1772       myBrowseAVIBtn->setEnabled(false);
1773     }
1774     mySaveCheck->setEnabled(!mySaveAVICheck->isChecked());
1775   }
1776 }
1777
1778 //------------------------------------------------------------------------
1779 void VisuGUI_TimeAnimationDlg::onStop()
1780 {
1781   myPlayBtn->setOn(false);
1782   myPlayBtn->setIconSet(MYplayPixmap);
1783   mySetupBtn->setEnabled(true);
1784   myGenBtn->setEnabled(true);
1785 }
1786
1787 //------------------------------------------------------------------------
1788 void VisuGUI_TimeAnimationDlg::onHelp()
1789 {
1790   QString aHelpFileName = "animating_page.html";
1791   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
1792   if (app)
1793     app->onHelpContextModule(myModule ? app->moduleName(myModule->moduleName()) : QString(""), aHelpFileName);
1794   else {
1795                 QString platform;
1796 #ifdef WIN32
1797                 platform = "winapplication";
1798 #else
1799                 platform = "application";
1800 #endif
1801     SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
1802                            QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
1803                            arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName),
1804                            QObject::tr("BUT_OK"));
1805   }
1806 }
1807
1808 //------------------------------------------------------------------------
1809 void VisuGUI_TimeAnimationDlg::saveToStudy()
1810 {
1811   myAnimator->saveAnimation();
1812   VISU::UpdateObjBrowser(myModule, true);
1813 }
1814
1815 //------------------------------------------------------------------------
1816 void VisuGUI_TimeAnimationDlg::publishToStudy()
1817 {
1818   myAnimator->publishInStudy();
1819   VISU::UpdateObjBrowser(myModule, true);
1820   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1821 }
1822
1823 //------------------------------------------------------------------------
1824 void VisuGUI_TimeAnimationDlg::restoreFromStudy(_PTR(SObject) theAnimation)
1825 {
1826   myAnimator->restoreFromStudy(theAnimation);
1827   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1828   if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) 
1829     setCaption(tr("SUCCESSIVE_ANIMATION"));
1830 }
1831
1832 //------------------------------------------------------------------------
1833 void VisuGUI_TimeAnimationDlg::onPicsFormatChanged()
1834 {
1835   QStrList aDumpFormats = QImageIO::outputFormats();
1836   myAnimator->setDumpFormat(aDumpFormats.at(myPicsFormat->currentItem()));
1837 }
1838
1839 //------------------------------------------------------------------------
1840 void VisuGUI_TimeAnimationDlg::onPathChanged()
1841 {
1842   myAnimator->dumpTo(myPathEdit->text());
1843 }
1844
1845 //------------------------------------------------------------------------
1846 void VisuGUI_TimeAnimationDlg::keyPressEvent( QKeyEvent* e )
1847 {
1848   QDialog::keyPressEvent( e );
1849   if ( e->isAccepted() )
1850     return;
1851
1852   if ( e->key() == Key_F1 )
1853     {
1854       e->accept();
1855       onHelp();
1856     }
1857 }