Salome HOME
Join modifications from branch OCC_development_for_3_2_0a2
[modules/visu.git] / src / VISUGUI / VisuGUI_TimeAnimation.cxx
index edc926a81646e6c5413d3e3e72d9c9c67ebf6903..de4de17ef4c8fd15baec5a08295bfb72b8cc797b 100644 (file)
-//  File      : VisuGUI_TimeAnimation.cxx
-//  Created   : 28 / 03 / 2003
-//  Author    : Vitaly SMETANNIKOV
-//  Project   : SALOME 
-//  Module    : VISUGUI
-//  Copyright : Open CASCADE 
-
+//  VISU VISUGUI : GUI of VISU component
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : VisuGUI_TimeAnimation.cxx
+//  Author : Vitaly SMETANNIKOV
+//  Module : VISU
 
 #include "VisuGUI_TimeAnimation.h"
+
 #include "VisuGUI.h"
+#include "VisuGUI_Tools.h"
+#include "VisuGUI_ViewTools.h"
+#include "VisuGUI_DeformedShapeDlg.h"
+#include "VisuGUI_CutPlanesDlg.h"
+#include "VisuGUI_CutLinesDlg.h"
+#include "VisuGUI_Plot3DDlg.h"
+#include "VisuGUI_VectorsDlg.h"
+#include "VisuGUI_IsoSurfacesDlg.h"
+#include "VisuGUI_StreamLinesDlg.h"
+#include "VisuGUI_ScalarMapOnDeformedShapeDlg.h"
+#include "VisuGUI_GaussPointsDlg.h"
+
+#include "VISU_TimeAnimation.h"
+
+#include "VISU_ScalarMap_i.hh"
+#include "VISU_IsoSurfaces_i.hh"
+#include "VISU_DeformedShape_i.hh"
+#include "VISU_CutPlanes_i.hh"
+#include "VISU_Plot3D_i.hh"
+#include "VISU_CutLines_i.hh"
+#include "VISU_Vectors_i.hh"
+#include "VISU_StreamLines_i.hh"
+#include "VISU_ScalarMapOnDeformedShape_i.hh"
+#include "VISU_GaussPoints_i.hh"
+
+#include "VISU_ViewManager_i.hh"
+
+#include "VISU_ScalarBarActor.hxx"
+#include "VISU_Actor.h"
+
+#include "SalomeApp_Study.h"
+#include "SalomeApp_Application.h"
+
+#include "SVTK_ViewWindow.h"
+
+#include "SUIT_OverrideCursor.h"
+#include "SUIT_MessageBox.h"
+#include "SUIT_Desktop.h"
+#include "SUIT_FileDlg.h"
+
+#include <vtkRenderer.h>
+#include <vtkMapper.h>
 
-#include <qlayout.h>
 #include <qhbox.h>
-#include <qhgroupbox.h>
-#include <qmessagebox.h>
+#include <qgrid.h>
+#include <qimage.h>
+#include <qlayout.h>
+#include <qslider.h>
+#include <qthread.h>
+#include <qlistbox.h>
 #include <qwt_wheel.h>
+#include <qhgroupbox.h>
 #include <qlcdnumber.h>
-#include <qlistbox.h>
 #include <qvgroupbox.h>
 
+#define  MAXVAL 1e10
 
-#include "QAD_Application.h"
-#include "QAD_Desktop.h"
-#include "QAD_FileDlg.h"
+ArrangeDlg::ArrangeDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
+  : QDialog(theParent, "ArrangeDlg", true,
+            WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
+    myAnimator(theAnimator),
+    myViewWindow(theAnimator->getViewer())
+{
+  myCurrent = 0;
+  init();
+  QStringList aFieldNames;
+  // Find names of fields
+  for (int i = 0; i < myAnimator->getNbFields(); i++) {
+    aFieldNames.append(VISU::getValue(myAnimator->getFieldData(i).myField, "myName"));
+    Offset aOffs;
+    aOffs.myOffset[0] = myAnimator->getFieldData(i).myOffset[0];
+    aOffs.myOffset[1] = myAnimator->getFieldData(i).myOffset[1];
+    aOffs.myOffset[2] = myAnimator->getFieldData(i).myOffset[2];
+    myOffsets.append(aOffs);
+  }
+  myFieldLst->insertStringList(aFieldNames);
+  myFieldLst->setSelected(0, true);
+}
 
-#include "VTKViewer_ViewFrame.h"
-#include "VISU_ScalarBarActor.hxx"
+ArrangeDlg::ArrangeDlg(QWidget* theParent, SVTK_ViewWindow* theViewWindow)
+  : QDialog(theParent, "ArrangeDlg", true, WStyle_Customize |
+            WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
+    myAnimator(NULL), myViewWindow(theViewWindow)
+{
+  myCurrent = 0;
+  init();
+  QStringList aPrsNames;
+  vtkActor* anActor;
+  vtkActorCollection *anActColl = myViewWindow->getRenderer()->GetActors();
+  for (anActColl->InitTraversal(); (anActor = anActColl->GetNextActor()) != NULL;) {
+    VISU_Actor* anVISUActor = dynamic_cast<VISU_Actor*>(anActor);
+    if (anVISUActor)
+      if (anVISUActor->GetVisibility() != 0) {
+       VISU::Prs3d_i* aPrs = anVISUActor->GetPrs3d();
+       if (aPrs) {
+         if (!myPrsMap.contains(aPrs)) {
+           SALOMEDS::SObject_var aSObject = aPrs->GetSObject();
+           if(!aSObject->_is_nil()){
+             SALOMEDS::GenericAttribute_var anAttr;
+             if (aSObject->FindAttribute(anAttr, "AttributeName")) {
+               SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
+               string aNam = aName->Value();
+               QString strIn(aNam.c_str());
+               aPrsNames.append(strIn);
+               myPrsMap[aPrs] = myOffsets.count();
+               Offset aOffs;
+               anVISUActor->GetPosition(aOffs.myOffset);
+               myOffsets.append(aOffs);
+             }
+           }
+         }
+       }
+      }
+  }
+  myFieldLst->insertStringList(aPrsNames);
+  myFieldLst->setSelected(0, true);
+}
 
-#include "VisuGUI_MagnitudeDlg.h"
-#include "VisuGUI_CutPlanesDlg.h"
-#include "VisuGUI_VectorsDlg.h"
-#include "VisuGUI_IsoSurfacesDlg.h"
-#include "VisuGUI_StreamLinesDlg.h"
-#include "VISU_TimeAnimation.h"
+void ArrangeDlg::init()
+{
+  setCaption("Arrange Presentations");
+  setSizeGripEnabled( TRUE );
+
+  QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
+  aMainLayout->setSpacing(5);
+
+  QButtonGroup* aBtnGrp = new QButtonGroup(2, Qt::Horizontal, this);
+  aBtnGrp->setExclusive(true);
+  aMainLayout->addWidget(aBtnGrp);
+
+  QRadioButton* aAutoBtn = new QRadioButton("Auto", aBtnGrp);
+  aBtnGrp->insert(aAutoBtn, AutoMode);
+
+  QRadioButton* aManualBtn = new QRadioButton("Manual", aBtnGrp);
+  aBtnGrp->insert(aManualBtn, ManualMode);
+  aBtnGrp->setButton(AutoMode);
+
+  myStackWgt = new QWidgetStack(this);
+  aMainLayout->addWidget(myStackWgt);
+
+  //  AUTO Pane
+  QVBox* aAutoPane = new QVBox(myStackWgt);
+  aAutoPane->setSpacing(5);
+  // Axis Group
+  myAxisGrp = new QButtonGroup(3, Qt::Horizontal,"Axis", aAutoPane);
+
+  QRadioButton* aXBtn = new QRadioButton("X",myAxisGrp );
+  myAxisGrp->insert(aXBtn, XAxis);
+
+  QRadioButton* aYBtn = new QRadioButton("Y",myAxisGrp );
+  myAxisGrp->insert(aYBtn, YAxis);
+
+  QRadioButton* aZBtn = new QRadioButton("Z",myAxisGrp );
+  myAxisGrp->insert(aZBtn, ZAxis);
+
+  myAxisGrp->setButton(XAxis);
+
+  //Distance Input
+  QHBox* aDistPane = new QHBox(aAutoPane);
+  aDistPane->setSpacing(5);
+  new QLabel("Relative Distance", aDistPane);
+  myDistVal = new QtxDblSpinBox (-10,10, 0.5, aDistPane);
+  myDistVal->setValue(1);
+
+  myStackWgt->addWidget(aAutoPane, AutoMode);
+
+  // Manual Pane
+  QHBox* aManualPane = new QHBox(myStackWgt);
+  aManualPane->setSpacing(10);
+
+  myFieldLst = new QListBox(aManualPane);
+  connect( myFieldLst, SIGNAL( highlighted(int) ),
+          this, SLOT( onFieldChange(int) ) );
+
+  QGrid* aCoordPane = new QGrid(2, aManualPane);
+  aCoordPane->setSpacing(5);
+
+  new QLabel("X", aCoordPane);
+  myCoord[0] = new QtxDblSpinBox(aCoordPane);
+  myCoord[0]->setRange(-MAXVAL, MAXVAL);
+
+  new QLabel("Y", aCoordPane);
+  myCoord[1] = new QtxDblSpinBox(aCoordPane);
+  myCoord[1]->setRange(-MAXVAL, MAXVAL);
+
+  new QLabel("Z", aCoordPane);
+  myCoord[2] = new QtxDblSpinBox(aCoordPane);
+  myCoord[2]->setRange(-MAXVAL, MAXVAL);
+
+  myStackWgt->addWidget(aManualPane, ManualMode);
+
+  myStackWgt->raiseWidget(AutoMode);
+
+  connect(aBtnGrp, SIGNAL(clicked(int)), myStackWgt, SLOT(raiseWidget(int)) );
 
-static double MAXVALUE = 1.0E+300;
+  SUIT_Study* aSUITStudy = myViewWindow->getViewManager()->study();
+  SalomeApp_Study* anAppStudy = dynamic_cast<SalomeApp_Study*>(aSUITStudy);
+  _PTR(Study) aCStudy = VISU::GetCStudy(anAppStudy);
+  if (!myAnimator && !aCStudy->GetProperties()->IsLocked()) {
+    mySaveChk = new QCheckBox ("Save to presentation", this);
+    mySaveChk->setChecked(false);
+    aMainLayout->addWidget(mySaveChk);
+  } else {
+    mySaveChk = 0;
+  }
+
+  // Common buttons ===========================================================
+  QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
+  GroupButtons->setColumnLayout(0, Qt::Vertical );
+  GroupButtons->layout()->setSpacing( 0 );
+  GroupButtons->layout()->setMargin( 0 );
+  QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+  GroupButtonsLayout->setAlignment( Qt::AlignTop );
+  GroupButtonsLayout->setSpacing( 6 );
+  GroupButtonsLayout->setMargin( 11 );
+
+  QPushButton* buttonOk = new QPushButton( tr( "&OK" ), GroupButtons, "buttonOk" );
+  buttonOk->setAutoDefault( TRUE );
+  buttonOk->setDefault( TRUE );
+  GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
+  GroupButtonsLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
+
+  QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ) , GroupButtons, "buttonCancel" );
+  buttonCancel->setAutoDefault( TRUE );
+  GroupButtonsLayout->addWidget( buttonCancel, 0, 2 );
+
+  aMainLayout->addWidget( GroupButtons );
+
+  connect( buttonOk,     SIGNAL( clicked() ),      this, SLOT( accept() ) );
+  connect( buttonCancel, SIGNAL( clicked() ),      this, SLOT( reject() ) );
+}
+
+void ArrangeDlg::accept()
+{
+  if (myAnimator != NULL) {
+    acceptAnimation();
+  } else {
+    acceptViewWindow();
+  }
+  QDialog::accept();
+}
+
+void ArrangeDlg::onFieldChange(int theCurrent)
+{
+  if (myCurrent != theCurrent) {
+    Offset& aOffs = myOffsets[myCurrent];
+    aOffs.myOffset[0] = myCoord[0]->value();
+    aOffs.myOffset[1] = myCoord[1]->value();
+    aOffs.myOffset[2] = myCoord[2]->value();
+  }
+  myCurrent = theCurrent;
+  const Offset& aNewOffs = myOffsets[myCurrent];
+  myCoord[0]->setValue(aNewOffs.myOffset[0]);
+  myCoord[1]->setValue(aNewOffs.myOffset[1]);
+  myCoord[2]->setValue(aNewOffs.myOffset[2]);
+}
+
+void ArrangeDlg::acceptAnimation()
+{
+  if (getMode() == ManualMode) {
+    // Save from GUI
+    Offset& aOffs = myOffsets[myCurrent];
+    aOffs.myOffset[0] = myCoord[0]->value();
+    aOffs.myOffset[1] = myCoord[1]->value();
+    aOffs.myOffset[2] = myCoord[2]->value();
+
+    for (int i = 0; i < myAnimator->getNbFields(); i++) {
+      Offset aOffs = myOffsets[i];
+      myAnimator->getFieldData(i).myOffset[0] = aOffs.myOffset[0];
+      myAnimator->getFieldData(i).myOffset[1] = aOffs.myOffset[1];
+      myAnimator->getFieldData(i).myOffset[2] = aOffs.myOffset[2];
+    }
+  } else {
+    QApplication::setOverrideCursor( Qt::waitCursor );
+    FieldData& aData = myAnimator->getFieldData(0);
+    if (aData.myPrs.empty())
+      myAnimator->generatePresentations(0);
+    VISU_Actor* aActor = aData.myPrs[0]->CreateActor();
+    float aBounds[6];
+    aActor->GetBounds(aBounds);
+    aActor->Delete();
+    float aDist = 0;
+    int aAxis = getAxis();
+    switch (aAxis) {
+    case XAxis:
+      aDist = fabs(aBounds[1] - aBounds[0]);
+      break;
+    case YAxis:
+      aDist = fabs(aBounds[3] - aBounds[2]);
+      break;
+    case ZAxis:
+      aDist = fabs(aBounds[5] - aBounds[4]);
+    }
 
+    float dx = fabs(aBounds[1] - aBounds[0]);
+    float dy = fabs(aBounds[3] - aBounds[2]);
+    float dz = fabs(aBounds[5] - aBounds[4]);
+    float max = (dx > dy) ? dx : dy;
+    max = (dz > max) ? dz : max;
+    max /= 100.0;
+
+    if (aDist < max) {
+      // set base distance between centers of bounding boxes
+      // to minimal (but big enough) size of current bounding box
+      if (dx < max) dx = FLT_MAX;
+      if (dy < max) dy = FLT_MAX;
+      if (dz < max) dz = FLT_MAX;
+
+      aDist = (dx < dy) ? dx : dy;
+      aDist = (dz < aDist) ? dz : aDist;
+    }
+    aDist = aDist * getDistance();
+    for (int i = 0; i < myAnimator->getNbFields(); i++) {
+      myAnimator->getFieldData(i).myOffset[0] = 0;
+      myAnimator->getFieldData(i).myOffset[1] = 0;
+      myAnimator->getFieldData(i).myOffset[2] = 0;
+      myAnimator->getFieldData(i).myOffset[aAxis] = aDist * i;
+    }
 
+    QApplication::restoreOverrideCursor();
+  }
+}
 
-SetupDlg::SetupDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator) 
-  : QDialog( theParent, "SetupDlg", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )  
+void ArrangeDlg::acceptViewWindow()
+{
+  if (getMode() == ManualMode) {
+    // Save from GUI
+    Offset& aOffs = myOffsets[myCurrent];
+    aOffs.myOffset[0] = myCoord[0]->value();
+    aOffs.myOffset[1] = myCoord[1]->value();
+    aOffs.myOffset[2] = myCoord[2]->value();
+
+    QMap<VISU::Prs3d_i*, int>::Iterator it;
+    for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it) {
+      VISU::Prs3d_i* aPrs = it.key();
+      Offset& aOffs = myOffsets[it.data()];
+      if (VISU_Actor* anActor = VISU::GetActor(aPrs, myViewWindow))
+        anActor->SetPosition(aOffs.myOffset);
+      if (mySaveChk)
+       if (mySaveChk->isChecked())
+         aPrs->SetOffset(aOffs.myOffset);
+    }
+  } else {
+    float aDist = 0;
+    float aShift = 0;
+    float aPrevDist = 0;
+    float aPrevShift = 0;
+    int i;
+    QMap<VISU::Prs3d_i*, int>::Iterator it;
+    for (it = myPrsMap.begin(), i = 0; it != myPrsMap.end(); ++it, i++) {
+      VISU::Prs3d_i* aPrs = it.key();
+      if (VISU_Actor* aActor = VISU::GetActor(aPrs, myViewWindow)) {
+       int aAxis = getAxis();
+
+       float aZeroOffset[3];
+        aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
+       aActor->SetPosition(aZeroOffset);
+        aActor->GetMapper()->Update();
+
+       float aBounds[6];
+       aActor->GetBounds(aBounds);
+       switch (aAxis) {
+       case XAxis:
+         aDist = fabs(aBounds[1] - aBounds[0]);
+         break;
+       case YAxis:
+         aDist = fabs(aBounds[3] - aBounds[2]);
+         break;
+       case ZAxis:
+         aDist = fabs(aBounds[5] - aBounds[4]);
+       }
+       float aOffset[3];
+        aOffset[0] = aOffset[1] = aOffset[2] = 0;
+        aOffset[aAxis] =
+          (aBounds[2*aAxis+1] < aBounds[2*aAxis]) ? -aBounds[2*aAxis+1] : -aBounds[2*aAxis];
+
+        if (i > 0) {
+          float aCCDist = (aDist + aPrevDist) / 2.0;
+
+          float dx = fabs(aBounds[1] - aBounds[0]);
+          float dy = fabs(aBounds[3] - aBounds[2]);
+          float dz = fabs(aBounds[5] - aBounds[4]);
+          float max = (dx > dy) ? dx : dy;
+          max = (dz > max) ? dz : max;
+          max /= 100.0;
+
+          if (aCCDist < max) {
+            // set base distance between centers of bounding boxes
+            // to minimal (but big enough) size of current bounding box
+            if (dx < max) dx = FLT_MAX;
+            if (dy < max) dy = FLT_MAX;
+            if (dz < max) dz = FLT_MAX;
+
+            aCCDist = (dx < dy) ? dx : dy;
+            aCCDist = (dz < aCCDist) ? dz : aCCDist;
+          }
+
+          //-------------------------------->
+          //             aShift
+          //                                 aDist / 2
+          //                                 <-->
+          //            .--------------.     .------.
+          //----------->|              |     |      |
+          // aPrevShift '--------------'     '------'
+          //            <------>
+          //            aPrevDist / 2
+          //
+          //                    <--------------->
+          //                    (aDist + aPrevDist) * getDistance() / 2
+
+          aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
+        }
+
+       aOffset[aAxis] += aShift;
+       aActor->SetPosition(aOffset);
+       if (mySaveChk)
+         if (mySaveChk->isChecked())
+           aPrs->SetOffset(aOffset);
+
+       aPrevDist = aDist;
+       aPrevShift = aShift;
+      }
+    }
+  }
+  myViewWindow->getRenderer()->ResetCameraClippingRange();
+  myViewWindow->Repaint();
+}
+
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+SetupDlg::SetupDlg (QWidget* theParent,
+                   VisuGUI* theModule, 
+                   VISU_TimeAnimation* theAnimator) :
+  QDialog(theParent, 
+         "SetupDlg", 
+         true, 
+         WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
+  myAnimator(theAnimator),
+  myModule(theModule)
 {
   setCaption("Setup Animation");
   setSizeGripEnabled( TRUE );
-  myAnimator = theAnimator;
-  
+
   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
   aMainLayout->setSpacing(5);
 
-
+  // Range of time stamps
   QFrame* aRangeGrp = new QFrame(this);
-  QGridLayout* aRangeLayout = new QGridLayout( aRangeGrp ); 
+  QGridLayout* aRangeLayout = new QGridLayout( aRangeGrp );
   aRangeLayout->setSpacing( 6 );
   aRangeLayout->setMargin( 11 );
   aRangeGrp->setFrameStyle(QFrame::Box | QFrame::Raised);
@@ -57,13 +469,21 @@ SetupDlg::SetupDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
   myUseRangeChk = new QCheckBox("Use range of time stamps", aRangeGrp);
   aRangeLayout->addMultiCellWidget(myUseRangeChk, 0, 0, 0, 3);
   myUseRangeChk->setChecked(myAnimator->isRangeDefined());
-  
+
+  double aMaxTime = myAnimator->getMaxTime();
+  double aMinTime = myAnimator->getMinTime();
+  double aStep = (aMaxTime - aMinTime) / (myAnimator->getFieldData(0).myNbTimes - 1);
+
   QLabel* aMinLbl = new QLabel("From", aRangeGrp);
   aMinLbl->setEnabled(myUseRangeChk->isChecked());
   aRangeLayout->addWidget(aMinLbl, 1, 0);
-  myMinVal = new QAD_SpinBoxDbl(aRangeGrp, -MAXVALUE, MAXVALUE, 0.1 );
+  myMinVal = new QtxDblSpinBox( aMinTime, aMaxTime, aStep, aRangeGrp );
   myMinVal->setEnabled(myUseRangeChk->isChecked());
-  myMinVal->setValue( 0 );
+  if (myUseRangeChk->isChecked())
+    myMinVal->setValue( myAnimator->getMinRange() );
+  else
+    myMinVal->setValue( aMinTime );
+
   connect(myMinVal, SIGNAL( valueChanged(double)),
          this, SLOT( onMinValue(double) ));
   aRangeLayout->addWidget(myMinVal, 1, 1);
@@ -71,13 +491,17 @@ SetupDlg::SetupDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
   QLabel* aMaxLbl = new QLabel("To", aRangeGrp);
   aMaxLbl->setEnabled(myUseRangeChk->isChecked());
   aRangeLayout->addWidget(aMaxLbl, 1, 2);
-  myMaxVal = new QAD_SpinBoxDbl(aRangeGrp, -MAXVALUE, MAXVALUE, 0.1 );
+  myMaxVal = new QtxDblSpinBox( aMinTime, aMaxTime, aStep, aRangeGrp );
   myMaxVal->setEnabled(myUseRangeChk->isChecked());
-  myMaxVal->setValue( 0 );
+  if (myUseRangeChk->isChecked())
+    myMaxVal->setValue( myAnimator->getMaxRange() );
+  else
+    myMaxVal->setValue( aMaxTime );
+
   connect(myMaxVal, SIGNAL( valueChanged(double)),
          this, SLOT( onMaxValue(double) ));
   aRangeLayout->addWidget(myMaxVal, 1, 3);
-  
+
   connect(myUseRangeChk, SIGNAL( toggled(bool)),
          aMinLbl, SLOT( setEnabled(bool) ));
   connect(myUseRangeChk, SIGNAL( toggled(bool)),
@@ -87,200 +511,308 @@ SetupDlg::SetupDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
 
   aMainLayout->addWidget(aRangeGrp);
 
-  
+
+  // Fields and Properties
   QHBox* aPropFrame = new QHBox(this);
   aPropFrame->setSpacing(5);
-  
-  QVGroupBox* aNamesBox = new QVGroupBox("Fields",aPropFrame);  
+
+  QVGroupBox* aNamesBox = new QVGroupBox("Fields",aPropFrame);
   myFieldLst = new QListBox(aNamesBox);
   QStringList aFieldNames;
   // Find names of fields
-  for (int i = 0; i < theAnimator->getNbFields(); i++) {
-    aFieldNames.append(VisuGUI::getValue(theAnimator->getFieldData(i).myField, "myName"));
+  for (int i = 0; i < myAnimator->getNbFields(); i++) {
+    _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
+    aFieldNames.append(VISU::getValue(aSO, "myName"));
   }
   myFieldLst->insertStringList(aFieldNames);
   myFieldLst->setSelected(0, true);
-  connect( myFieldLst, SIGNAL( highlighted(int) ), 
+  connect( myFieldLst, SIGNAL( highlighted(int) ),
           this, SLOT( onFieldChange(int) ) );
 
-  
-  QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);  
+
+  QVBox* aSetupBox = new QVBox(aPropFrame);
+  aSetupBox->setSpacing(5);
+
+  QVGroupBox* aPropBox = new QVGroupBox("Properties", aSetupBox);
+  //QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
   myTypeCombo = new QComboBox(aPropBox);
-  connect( myTypeCombo, SIGNAL( activated(int) ), 
+  connect( myTypeCombo, SIGNAL( activated(int) ),
           this, SLOT( onTypeChanged(int) ) );
-  
-  QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
-  connect( aBarBtn, SIGNAL( clicked() ), 
-          this, SLOT( onScalarBarDlg() ) );
+
+  //  QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
+  //connect( aBarBtn, SIGNAL( clicked() ),
+  //      this, SLOT( onScalarBarDlg() ) );
+
   myPropBtn = new QPushButton("Properties...", aPropBox);
-  myPropBtn->setEnabled(theAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
-  connect( myPropBtn, SIGNAL( clicked() ), 
+  //  myPropBtn->setEnabled(myAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
+  connect( myPropBtn, SIGNAL( clicked() ),
           this, SLOT( onPreferencesDlg() ) );
 
+  if (myAnimator->getNbFields() > 1) {
+    myArrangeBtn = new QPushButton("Arrange...", aSetupBox);
+    connect( myArrangeBtn, SIGNAL( clicked() ), this, SLOT( onArrangeDlg() ) );
+  }
   onFieldChange(0);
   aMainLayout->addWidget(aPropFrame);
-  
+
   QHBox* aBtnBox = new QHBox(this);
-  QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout()); 
+  QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
   aBtnLayout->addStretch();
-  
-  QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
+
+  QPushButton* aCloseBtn = new QPushButton(tr("BUT_OK"), aBtnBox);
   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
-  
+
   aMainLayout->addWidget(aBtnBox);
 }
 
-
-//************************************************************************
-void SetupDlg::onFieldChange(int theIndex) {
+//------------------------------------------------------------------------
+enum PrsComboItem {
+  TSCALARMAP_ITEM     = 0, // VISU::TSCALARMAP
+  TISOSURFACE_ITEM    = 1, // VISU::TISOSURFACE
+  TCUTPLANES_ITEM     = 2, // VISU::TCUTPLANES
+  TCUTLINES_ITEM      = 3, // VISU::TCUTLINES
+  TPLOT3D_ITEM        = 4, // VISU::TPLOT3D
+  TDEFORMEDSHAPE_ITEM = 5, // VISU::TDEFORMEDSHAPE
+  TVECTORS_ITEM       = 6, // VISU::TVECTORS
+  TSTREAMLINES_ITEM   = 7, // VISU::TSTREAMLINES
+  TGAUSSPOINTS_ITEM   = 8, // VISU::TGAUSSPOINTS
+  TSCALARMAPONDEFORMEDSHAPE_ITEM = 9 // VISU::TSCALARMAPONDEFORMEDSHAPE
+};
+
+//------------------------------------------------------------------------
+void SetupDlg::onFieldChange (int theIndex)
+{
   FieldData& aData = myAnimator->getFieldData(theIndex);
   myTypeCombo->clear();
-  myTypeCombo->insertItem("Scalar Map");
-  myTypeCombo->insertItem("Iso Surfaces");
-  myTypeCombo->insertItem("Cut Planes");
+  myTypeId2ComboId.clear();
+  myComboId2TypeId.clear();
+
+  // ATTENTION: append items in the same order like it is done in the PrsComboItem enumeration
+  myTypeCombo->insertItem("Scalar Map");   // item 0
+  myTypeId2ComboId[TSCALARMAP_ITEM] = myComboId2TypeId.size();
+  myComboId2TypeId.push_back(TSCALARMAP_ITEM);;
+
+  myTypeCombo->insertItem("Iso Surfaces"); // item 1
+  myTypeId2ComboId[TISOSURFACE_ITEM] = myComboId2TypeId.size();
+  myComboId2TypeId.push_back(TISOSURFACE_ITEM);;
 
-  SALOMEDS::SObject_var aSObject = aData.myField;
-  long aNumComp = VisuGUI::getValue(aSObject, "myNumComponent").toLong();
+  myTypeCombo->insertItem("Cut Planes");   // item 2
+  myTypeId2ComboId[TCUTPLANES_ITEM] = myComboId2TypeId.size();
+  myComboId2TypeId.push_back(TCUTPLANES_ITEM);;
+
+  myTypeCombo->insertItem("Cut Lines");   // item 3
+  myTypeId2ComboId[TCUTLINES_ITEM] = myComboId2TypeId.size();
+  myComboId2TypeId.push_back(TCUTLINES_ITEM);;
+
+  myTypeCombo->insertItem("Plot 3D");      // item 4
+  myTypeId2ComboId[TPLOT3D_ITEM] = myComboId2TypeId.size();
+  myComboId2TypeId.push_back(TPLOT3D_ITEM);;
+
+  _PTR(SObject) aSObject = aData.myField;
+  long aNumComp = VISU::getValue(aSObject, "myNumComponent").toLong();
   if (aNumComp > 1) {
-    myTypeCombo->insertItem("Deformed Shape");
-    myTypeCombo->insertItem("Vectors");
-    myTypeCombo->insertItem("Stream Lines");
+    myTypeCombo->insertItem("Deformed Shape"); // item 5
+    myTypeId2ComboId[TDEFORMEDSHAPE_ITEM] = myComboId2TypeId.size();
+    myComboId2TypeId.push_back(TDEFORMEDSHAPE_ITEM);;
+
+    myTypeCombo->insertItem("Vectors");        // item 6
+    myTypeId2ComboId[TVECTORS_ITEM] = myComboId2TypeId.size();
+    myComboId2TypeId.push_back(TVECTORS_ITEM);;
+
+    myTypeCombo->insertItem("Stream Lines");   // item 7
+    myTypeId2ComboId[TSTREAMLINES_ITEM] = myComboId2TypeId.size();
+    myComboId2TypeId.push_back(TSTREAMLINES_ITEM);;
+
+    myTypeCombo->insertItem("Scalar map on Deformed shape");   // item 9
+    myTypeId2ComboId[TSCALARMAPONDEFORMEDSHAPE_ITEM] = myComboId2TypeId.size();
+    myComboId2TypeId.push_back(TSCALARMAPONDEFORMEDSHAPE_ITEM);;
+  }
+
+  long anEntityId = VISU::getValue(aSObject, "myEntityId").toLong();
+  if(anEntityId == VISU::CELL){
+    myTypeCombo->insertItem("Gauss Points");   // item 8
+    myTypeId2ComboId[TGAUSSPOINTS_ITEM] = myComboId2TypeId.size();
+    myComboId2TypeId.push_back(TGAUSSPOINTS_ITEM);;
   }
+
   switch (aData.myPrsType) {
   case VISU::TSCALARMAP: //Scalar Map
-    myTypeCombo->setCurrentItem(0);
+    myTypeCombo->setCurrentItem(myTypeId2ComboId[TSCALARMAP_ITEM]);
     break;
   case VISU::TISOSURFACE: //Iso Surfaces
-    myTypeCombo->setCurrentItem(1);
+    myTypeCombo->setCurrentItem(myTypeId2ComboId[TISOSURFACE_ITEM]);
     break;
   case VISU::TCUTPLANES: //Cut Planes
-    myTypeCombo->setCurrentItem(2);
+    myTypeCombo->setCurrentItem(myTypeId2ComboId[TCUTPLANES_ITEM]);
+    break;
+  case VISU::TCUTLINES: //Cut Lines
+    myTypeCombo->setCurrentItem(myTypeId2ComboId[TCUTLINES_ITEM]);
+    break;
+  case VISU::TPLOT3D: //Plot 3D
+    myTypeCombo->setCurrentItem(myTypeId2ComboId[TPLOT3D_ITEM]);
     break;
   case VISU::TDEFORMEDSHAPE: //Deformed Shape
-    myTypeCombo->setCurrentItem(3);
+    myTypeCombo->setCurrentItem(myTypeId2ComboId[TDEFORMEDSHAPE_ITEM]);
+    break;
+  case VISU::TSCALARMAPONDEFORMEDSHAPE: //Scalar Map on Deformed Shape
+    myTypeCombo->setCurrentItem(myTypeId2ComboId[TSCALARMAPONDEFORMEDSHAPE_ITEM]);
     break;
   case VISU::TVECTORS: //Vectors
-    myTypeCombo->setCurrentItem(4);
+    myTypeCombo->setCurrentItem(myTypeId2ComboId[TVECTORS_ITEM]);
     break;
   case VISU::TSTREAMLINES: //Stream Lines
-    myTypeCombo->setCurrentItem(5);
-    aData.myPrsType = VISU::TSTREAMLINES;
+    myTypeCombo->setCurrentItem(myTypeId2ComboId[TSTREAMLINES_ITEM]);
+    break;
+  case VISU::TGAUSSPOINTS: //Gauss Points
+    myTypeCombo->setCurrentItem(myTypeId2ComboId[TGAUSSPOINTS_ITEM]);
     break;
-  }  
-  myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
+  }
+  //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
 }
 
-//************************************************************************
-void SetupDlg::onTypeChanged(int theIndex) {
+//------------------------------------------------------------------------
+void SetupDlg::onTypeChanged (int theIndex)
+{
   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
-  switch (theIndex) {
-  case 0: //Scalar Map
+  int aType = myComboId2TypeId[theIndex];
+  switch (aType) {
+  case TSCALARMAP_ITEM: //Scalar Map
     aData.myPrsType = VISU::TSCALARMAP;
     break;
-  case 1: //Iso Surfaces
+  case TISOSURFACE_ITEM: //Iso Surfaces
     aData.myPrsType = VISU::TISOSURFACE;
     break;
-  case 2: //Cut Planes
+  case TCUTPLANES_ITEM: //Cut Planes
     aData.myPrsType = VISU::TCUTPLANES;
     break;
-  case 3: //Deformed Shape
+  case TCUTLINES_ITEM: //Cut Lines
+    aData.myPrsType = VISU::TCUTLINES;
+    break;
+  case TPLOT3D_ITEM: //Plot 3D
+    aData.myPrsType = VISU::TPLOT3D;
+    break;
+  case TDEFORMEDSHAPE_ITEM: //Deformed Shape
     aData.myPrsType = VISU::TDEFORMEDSHAPE;
     break;
-  case 4: //Vectors
+  case TSCALARMAPONDEFORMEDSHAPE_ITEM: //Scalar Map on Deformed Shape
+    aData.myPrsType = VISU::TSCALARMAPONDEFORMEDSHAPE;
+    break;
+  case TVECTORS_ITEM: //Vectors
     aData.myPrsType = VISU::TVECTORS;
     break;
-  case 5: //Stream Lines
+  case TSTREAMLINES_ITEM: //Stream Lines
     aData.myPrsType = VISU::TSTREAMLINES;
     break;
+  case TGAUSSPOINTS_ITEM: //Gauss Points
+    aData.myPrsType = VISU::TGAUSSPOINTS;
+    break;
   }
   myAnimator->clearData(aData);
-  myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
+  //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
   //myAnimator->generatePresentations(myFieldLst->currentItem());
 }
 
 
-//************************************************************************
-void SetupDlg::onScalarBarDlg() {
-  QApplication::setOverrideCursor( Qt::waitCursor );
-  FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
-  if (aData.myPrs == 0) 
-    myAnimator->generatePresentations(myFieldLst->currentItem());
-  QApplication::restoreOverrideCursor();
-
-  VisuGUI_ScalarBarDlg* aScalarBarDlg = new VisuGUI_ScalarBarDlg();
-  aScalarBarDlg->initFromPrsObject(aData.myPrs[0]);
-  if (aScalarBarDlg->exec()) {
-    for (int i = 0; i < aData.myNbTimes; i++)
-      aScalarBarDlg->storeToPrsObject(aData.myPrs[i]);
+//------------------------------------------------------------------------
+namespace
+{
+  template<class TPrs3d, class TDialog>
+  void
+  EditPrs(VisuGUI* theModule,
+         FieldData& theData)
+  {
+    TDialog* aDlg = new TDialog(theModule);
+    aDlg->initFromPrsObject(dynamic_cast<TPrs3d*>(theData.myPrs[0]));
+    if (aDlg->exec())
+      for (int i = 0; i < theData.myNbFrames; i++)
+       aDlg->storeToPrsObject(dynamic_cast<TPrs3d*>(theData.myPrs[i]));
+    delete aDlg;
   }
 }
 
-//************************************************************************
-void SetupDlg::onPreferencesDlg() {
-  QApplication::setOverrideCursor( Qt::waitCursor );
+
+void SetupDlg::onPreferencesDlg()
+{
+  SUIT_OverrideCursor c;
   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
-  if (aData.myPrs == 0)
+  if (aData.myPrs.empty())
     myAnimator->generatePresentations(myFieldLst->currentItem());
-  QApplication::restoreOverrideCursor();
 
-  switch (myTypeCombo->currentItem()) {
-  case 1: //Iso Surfaces
-    {
-      VisuGUI_IsoSurfacesDlg* aDlg = new VisuGUI_IsoSurfacesDlg();
-      aDlg->initFromPrsObject(dynamic_cast<VISU::IsoSurfaces_i*>(aData.myPrs[0]));
-      if (aDlg->exec()) {
-       for (int i = 0; i < aData.myNbTimes; i++)
-         aDlg->storeToPrsObject(dynamic_cast<VISU::IsoSurfaces_i*>(aData.myPrs[i]));
-      }
-    }
+  int aType = myComboId2TypeId[myTypeCombo->currentItem()];
+  switch (aType) {
+  case TSCALARMAP_ITEM: //Scalar Map
+    c.suspend();
+    EditPrs<VISU::ScalarMap_i,VisuGUI_ScalarBarDlg>(myModule,aData);
     break;
-  case 2: //Cut Planes
-    {
-      VisuGUI_CutPlanesDlg* aDlg = new VisuGUI_CutPlanesDlg();
-      aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[0]));
-      if (aDlg->exec()) {
-       for (int i = 0; i < aData.myNbTimes; i++)
-         aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[i]));
-      }
-    }
+  case TISOSURFACE_ITEM: //Iso Surfaces
+    c.suspend();
+    EditPrs<VISU::IsoSurfaces_i,VisuGUI_IsoSurfacesDlg>(myModule,aData);
     break;
-  case 3: //Deformed Shape
-    {
-      VisuGUI_MagnitudeDlg* aDlg = new VisuGUI_MagnitudeDlg();
-      aDlg->initFromPrsObject(dynamic_cast<VISU::DeformedShape_i*>(aData.myPrs[0]));      
-      if (aDlg->exec()) {
-       for (int i = 0; i < aData.myNbTimes; i++)
-         aDlg->storeToPrsObject(dynamic_cast<VISU::DeformedShape_i*>(aData.myPrs[i]));
-      }
-    }
+  case TCUTPLANES_ITEM: //Cut Planes
+    c.suspend();
+    EditPrs<VISU::CutPlanes_i,VisuGUI_CutPlanesDlg>(myModule,aData);
     break;
-  case 4: //Vectors
-    {
-      VisuGUI_VectorsDlg* aDlg = new VisuGUI_VectorsDlg();
-      aDlg->initFromPrsObject(dynamic_cast<VISU::Vectors_i*>(aData.myPrs[0]));
-      if (aDlg->exec()) {
-       for (int i = 0; i < aData.myNbTimes; i++)
-         aDlg->storeToPrsObject(dynamic_cast<VISU::Vectors_i*>(aData.myPrs[i]));
-      }
-    }
+  case TCUTLINES_ITEM: //Cut Lines
+    c.suspend();
+    EditPrs<VISU::CutLines_i,VisuGUI_CutLinesDlg>(myModule,aData);
     break;
-  case 5: //Stream Lines
+  case TPLOT3D_ITEM: //Plot 3D
+    c.suspend();
+    EditPrs<VISU::Plot3D_i,VisuGUI_Plot3DDlg>(myModule,aData);
+    break;
+  case TDEFORMEDSHAPE_ITEM: //Deformed Shape
+    c.suspend();
+    EditPrs<VISU::DeformedShape_i,VisuGUI_DeformedShapeDlg>(myModule,aData);
+    break;
+  case TSCALARMAPONDEFORMEDSHAPE_ITEM: //Scalar Map on Deformed Shape
+    c.suspend();
     {
-      VisuGUI_StreamLinesDlg* aDlg = new VisuGUI_StreamLinesDlg();
-      aDlg->initFromPrsObject(dynamic_cast<VISU::StreamLines_i*>(aData.myPrs[0]));
-      if (aDlg->exec()) {
-       for (int i = 0; i < aData.myNbTimes; i++)
-         aDlg->storeToPrsObject(dynamic_cast<VISU::StreamLines_i*>(aData.myPrs[i]));
-      }
+      typedef VisuGUI_ScalarMapOnDeformedShapeDlg DLG;
+      typedef VISU::ScalarMapOnDeformedShape_i TYPE;
+      DLG* aDlg = new DLG (myModule);
+      aDlg->initFromPrsObject(dynamic_cast<TYPE*>(aData.myPrs[0]),true);
+      if (aDlg->exec())
+        { 
+         int anbFrames=aDlg->getCurrentScalarNbIterations();
+         int aIter = 0;
+         for (int i = 0; i < aData.myNbFrames; i++){
+           TYPE* aCurrPrs_i = dynamic_cast<TYPE*>(aData.myPrs[i]);
+           aIter = i+1;
+           if(i+1 > anbFrames)
+             aIter=anbFrames;
+           aDlg->storeToPrsObject(aCurrPrs_i,false,aIter);
+         }
+       }
+      delete aDlg;
     }
     break;
+  case TVECTORS_ITEM: //Vectors
+    c.suspend();
+    EditPrs<VISU::Vectors_i,VisuGUI_VectorsDlg>(myModule,aData);
+    break;
+  case TSTREAMLINES_ITEM: //Stream Lines
+    c.suspend();
+    EditPrs<VISU::StreamLines_i,VisuGUI_StreamLinesDlg>(myModule,aData);
+    break;
+  case TGAUSSPOINTS_ITEM: //Gauss Points
+    c.suspend();
+    EditPrs<VISU::GaussPoints_i,VisuGUI_GaussPointsDlg>(myModule,aData);
+    break;
   }
 }
 
-//************************************************************************
-void SetupDlg::onRangeCheck(bool theCheck) {
-  for (int i = 0; i < myAnimator->getNbFields(); i++) 
+
+//------------------------------------------------------------------------
+void SetupDlg::onArrangeDlg()
+{
+  ArrangeDlg aDlg(this, myAnimator);
+  aDlg.exec();
+}
+
+//------------------------------------------------------------------------
+void SetupDlg::onRangeCheck (bool theCheck)
+{
+  for (int i = 0; i < myAnimator->getNbFields(); i++)
     myAnimator->clearData(myAnimator->getFieldData(i));
 
   myMinVal->setEnabled(theCheck);
@@ -288,23 +820,42 @@ void SetupDlg::onRangeCheck(bool theCheck) {
 
   if (!theCheck)
     myAnimator->setAnimationRange(0, 0);
+  else {
+    //    if (myMinVal->value() < myMaxVal->value())
+    myAnimator->setAnimationRange(myMinVal->value(), myMaxVal->value());
+//     else if (myMinVal->value() > myMaxVal->value())
+//       myAnimator->setAnimationRange(myMaxVal->value(), myMinVal->value());
+//     else // equal case
+//       myAnimator->setAnimationRange(0, 0);
+  }
 }
 
-//************************************************************************
-void SetupDlg::onMinValue(double theVal) {
-  for (int i = 0; i < myAnimator->getNbFields(); i++) 
+//------------------------------------------------------------------------
+void SetupDlg::onMinValue (double theVal)
+{
+  if (theVal > myAnimator->getMaxRange()) {
+    myMinVal->setValue( myAnimator->getMinTime() );
+    myMinVal->setFocus();
+    return;
+  }
+  for (int i = 0; i < myAnimator->getNbFields(); i++)
     myAnimator->clearData(myAnimator->getFieldData(i));
   myAnimator->setAnimationRange(theVal, myAnimator->getMaxRange());
 }
 
-//************************************************************************
-void SetupDlg::onMaxValue(double theVal) {
-  for (int i = 0; i < myAnimator->getNbFields(); i++) 
+//------------------------------------------------------------------------
+void SetupDlg::onMaxValue (double theVal)
+{
+  if (theVal < myAnimator->getMinRange()) {
+    myMaxVal->setValue( myAnimator->getMaxTime() );
+    myMaxVal->setFocus();
+    return;
+  }
+  for (int i = 0; i < myAnimator->getNbFields(); i++)
     myAnimator->clearData(myAnimator->getFieldData(i));
   myAnimator->setAnimationRange(myAnimator->getMinRange(), theVal);
 }
 
-
 static const char * firstIco[] = {
 "18 10 2 1",
 "      g None",
@@ -374,7 +925,6 @@ static const char * playIco[] = {
 static QPixmap MYplayPixmap(playIco);
 
 
-
 static const char * rightIco[] = {
 "11 10 2 1",
 "      g None",
@@ -413,39 +963,45 @@ static const char * pauseIco[] = {
 static QPixmap MYpausePixmap(pauseIco);
 
 
-VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg(SALOMEDS::Study_var theStudy) 
-  : QDialog( QAD_Application::getDesktop(), "VisuGUI_TimeAnimationDlg", false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose)
+VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (VisuGUI* theModule, _PTR(Study) theStudy) :
+  QDialog(VISU::GetDesktop(theModule), 
+         "VisuGUI_TimeAnimationDlg", 
+         false, 
+         WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
+  myModule(theModule),
+  myStudy(theStudy),
+  mySetupDlg(NULL)
 {
   setCaption("Animation");
   setSizeGripEnabled( TRUE );
+  isClosing = false;
 
-  myStudy = theStudy;
-  myAnimator = new VISU_TimeAnimation(theStudy);
+  myAnimator = new VISU_TimeAnimation (theStudy);
   myAnimator->setSpeed(1);
-  myAnimator->setViewer(VisuGUI::GetVtkViewFrame());
-  connect( myAnimator, SIGNAL( frameChanged(long, double) ), 
-          this, SLOT( onExecution(long, double) ) );
+  myAnimator->setViewer(VISU::GetActiveViewWindow<SVTK_ViewWindow>(theModule));
+  connect(myAnimator, SIGNAL(frameChanged(long, double)), this, SLOT(onExecution(long, double)));
+  connect(myAnimator, SIGNAL(stopped()),                 this, SLOT(onStop()));
 
   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
   aMainLayout->setSpacing(5);
 
-  QPushButton* aSetupBtn = new QPushButton("Setup Animation...", this);
-  connect( aSetupBtn, SIGNAL( clicked() ), 
+  mySetupBtn = new QPushButton("Setup Animation...", this);
+  connect( mySetupBtn, SIGNAL( clicked() ),
           this, SLOT( onSetupDlg() ) );
-  aMainLayout->addWidget(aSetupBtn);  
-  
-  QPushButton* aGenBtn = new QPushButton("Generate frames", this);
-  connect( aGenBtn, SIGNAL( clicked() ), 
+  aMainLayout->addWidget(mySetupBtn);
+
+  myGenBtn = new QPushButton("Generate frames", this);
+  connect( myGenBtn, SIGNAL( clicked() ),
           this, SLOT( createFrames() ) );
-  aMainLayout->addWidget(aGenBtn);
+  aMainLayout->addWidget(myGenBtn);
 
   myPlayFrame = new QFrame(this);
   myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
   myPlayFrame->setLineWidth( 1 );
+
 
   // --- Play controls ---
-  QGridLayout* TopLayout = new QGridLayout( myPlayFrame ); 
+  QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
   TopLayout->setSpacing( 6 );
   TopLayout->setMargin( 11 );
 
@@ -458,41 +1014,41 @@ VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg(SALOMEDS::Study_var theStudy)
   mySlider->setTickInterval(1);
   //mySlider->setTickmarks(QSlider::Below);
   mySlider->setTracking(false);
-  connect( mySlider, SIGNAL( valueChanged(int) ), 
-          this, SLOT( onFrameChanged(int) ) );
+  connect( mySlider, SIGNAL( valueChanged(int) ),
+          this, SLOT( onWindowChanged(int) ) );
   TopLayout->addMultiCellWidget(mySlider, 1, 1, 0, 2);
 
   myPlayBtn = new QToolButton(myPlayFrame);
   myPlayBtn->setIconSet(MYplayPixmap);
   myPlayBtn->setToggleButton(true);
-  connect( myPlayBtn, SIGNAL( clicked() ), 
+  connect( myPlayBtn, SIGNAL( clicked() ),
           this, SLOT( onPlayPressed() ) );
   TopLayout->addMultiCellWidget(myPlayBtn, 2, 2, 0, 1);
 
   QToolButton* aBackBtn = new QToolButton(myPlayFrame);
   aBackBtn->setIconSet(QPixmap(leftIco));
-  connect( aBackBtn, SIGNAL( clicked() ), 
+  connect( aBackBtn, SIGNAL( clicked() ),
           this, SLOT( onBackPressed() ) );
   TopLayout->addWidget(aBackBtn, 3, 0);
 
   QToolButton* aForvardBtn = new QToolButton(myPlayFrame);
   aForvardBtn->setIconSet(QPixmap(rightIco));
-  connect( aForvardBtn, SIGNAL( clicked() ), 
+  connect( aForvardBtn, SIGNAL( clicked() ),
           this, SLOT( onForvardPressed() ) );
   TopLayout->addWidget(aForvardBtn, 3, 1);
 
   QToolButton* aFirstBtn = new QToolButton(myPlayFrame);
   aFirstBtn->setIconSet(QPixmap(firstIco));
-  connect( aFirstBtn, SIGNAL( clicked() ), 
+  connect( aFirstBtn, SIGNAL( clicked() ),
           this, SLOT( onFirstPressed() ) );
   TopLayout->addWidget(aFirstBtn, 4, 0);
-  
+
   QToolButton* aLastBtn = new QToolButton(myPlayFrame);
   aLastBtn->setIconSet(QPixmap(lastIco));
-  connect( aLastBtn, SIGNAL( clicked() ), 
+  connect( aLastBtn, SIGNAL( clicked() ),
           this, SLOT( onLastPressed() ) );
   TopLayout->addWidget(aLastBtn, 4, 1);
-  
+
   QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
   TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
 
@@ -504,194 +1060,332 @@ VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg(SALOMEDS::Study_var theStudy)
   QwtWheel* aWheel = new QwtWheel(myPlayFrame);
   aWheel->setOrientation(Qt::Vertical);
   aWheel->setRange(1, 99, 1);
-  connect( aWheel, SIGNAL(valueChanged(double)), 
+  connect( aWheel, SIGNAL(valueChanged(double)),
           aSpeedNum, SLOT(display(double)) );
-  connect( aWheel, SIGNAL(valueChanged(double)), 
+  connect( aWheel, SIGNAL(valueChanged(double)),
           this, SLOT(onSpeedChange(double)) );
   TopLayout->addMultiCellWidget(aWheel, 1, 3, 3, 3, Qt::AlignRight);
 
+  QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
+  aCycleCheck->setChecked(myAnimator->isCycling());
+  connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
+  TopLayout->addMultiCellWidget(aCycleCheck, 5, 5, 0, 3);
+
   QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
   aPropCheck->setChecked(myAnimator->isProportional());
-  connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportional(bool)));
-  TopLayout->addMultiCellWidget(aPropCheck, 5, 5, 0, 3);
+  connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
+  TopLayout->addMultiCellWidget(aPropCheck, 6, 6, 0, 3);
 
-  mySaveCheck = new QCheckBox("Save pictures to directory",myPlayFrame);
-  mySaveCheck->setChecked(false);
-  TopLayout->addMultiCellWidget(mySaveCheck, 6, 6, 0, 3);
+  // Pictures saving on disk
+  QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
+  aSaveBox->setColumnLayout(0, Qt::Horizontal );
+  QGridLayout* aSaveLay = new QGridLayout(aSaveBox->layout());
+  aSaveLay->setSpacing( 5 );
+  aSaveLay->setMargin( 5 );
+
+  mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
+  aSaveLay->addMultiCellWidget(mySaveCheck, 0, 0, 0, 2);
+
+  QLabel* aFormatLbl = new QLabel("Saving format:", aSaveBox);
+  aFormatLbl->setEnabled(false);
+  connect(mySaveCheck, SIGNAL( toggled(bool)),
+          aFormatLbl, SLOT( setEnabled(bool) ));
+  aSaveLay->addMultiCellWidget(aFormatLbl, 1, 1, 0, 1);
 
-  QLabel* aPathLbl = new QLabel("Path:", myPlayFrame);
+  myPicsFormat = new QComboBox(aSaveBox);
+  QStrList aDumpFormats = QImageIO::outputFormats();
+  for (unsigned int i = 0; i < aDumpFormats.count(); i++) {
+    myPicsFormat->insertItem(aDumpFormats.at(i));
+  }
+  if (aDumpFormats.find("JPEG"))
+    myPicsFormat->setCurrentItem(aDumpFormats.find("JPEG"));
+  else
+    myPicsFormat->setCurrentItem(0);
+  myPicsFormat->setEnabled(false);
+  aSaveLay->addWidget(myPicsFormat, 1, 2);
+  connect(mySaveCheck, SIGNAL( toggled(bool)),
+          myPicsFormat, SLOT( setEnabled(bool) ));
+
+  QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
   aPathLbl->setEnabled(false);
   connect(mySaveCheck, SIGNAL( toggled(bool)),
-         aPathLbl, SLOT( setEnabled(bool) ));
-  TopLayout->addWidget(aPathLbl, 7, 0);
-  
-  myPathEdit = new QLineEdit(myPlayFrame);
+          aPathLbl, SLOT( setEnabled(bool) ));
+  aSaveLay->addWidget(aPathLbl, 2, 0);
+
+  myPathEdit = new QLineEdit(aSaveBox);
+  myPathEdit->setReadOnly(true);
+  myPathEdit->setEnabled(false);
   connect(mySaveCheck, SIGNAL( toggled(bool)),
-         myPathEdit, SLOT( setEnabled(bool) ));
-  TopLayout->addMultiCellWidget(myPathEdit, 7, 7, 1, 2);
+          myPathEdit, SLOT( setEnabled(bool) ));
+  aSaveLay->addWidget(myPathEdit, 2, 1);
 
-  QPushButton* aBrowseBtn = new QPushButton("Browse...", myPlayFrame);
+  QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
+  aBrowseBtn->setEnabled(false);
   connect(mySaveCheck, SIGNAL( toggled(bool)),
          aBrowseBtn, SLOT( setEnabled(bool) ));
   connect(aBrowseBtn, SIGNAL( clicked()),
          this, SLOT( onBrowse() ));
-  TopLayout->addWidget(aBrowseBtn, 7, 3);
+  mySaveCheck->setChecked(false);
+  aSaveLay->addWidget(aBrowseBtn, 2, 2);
+
+  TopLayout->addMultiCellWidget(aSaveBox, 7, 7, 0, 3);
 
   aMainLayout->addWidget(myPlayFrame);
 
+  // Animation publishing in study
+  QHBox* aPublishBox = new QHBox(this);
+  aPublishBox->setSpacing(5);
+
+  myPublishBtn = new QPushButton("Publish to study", aPublishBox);
+  connect(myPublishBtn, SIGNAL(clicked()), this, SLOT(publishToStudy()));
+
+  mySaveBtn = new QPushButton("Save Animation", aPublishBox);
+  mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
+  connect(mySaveBtn, SIGNAL(clicked()), this, SLOT(saveToStudy()));
+
+  aMainLayout->addWidget(aPublishBox);
+
+
   QHBox* aBtnBox = new QHBox(this);
-  QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout()); 
+  QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
   aBtnLayout->addStretch();
 
   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
-  
+
+  SUIT_Study* aStudy = VISU::GetAppStudy(myModule);
+  connect(aStudy, SIGNAL(destroyed()), this, SLOT(close()));
+
+  connect(myAnimator->getViewer(), SIGNAL(destroyed()), this, SLOT(close()));
+  connect(myAnimator->getViewer(), SIGNAL(closing(SUIT_ViewWindow*)), this, SLOT(close()));
+
   aMainLayout->addWidget(aBtnBox);
 
   myPlayFrame->setEnabled(false);
 }
 
-
-//************************************************************************
-VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg() {
-  VTKViewer_ViewFrame* aView = myAnimator->getViewer();
-  delete myAnimator;
-  aView->Repaint();
+//------------------------------------------------------------------------
+VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg()
+{
+  if(myAnimator != NULL){
+    delete myAnimator;
+    myAnimator = NULL;
+  }
 }
 
-
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onTypeChange(int index) {
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
+{
   stopAnimation();
   myPropBtn->setEnabled(index != 0);
-  
+
   clearView();
   myPlayFrame->setEnabled(false);
 }
 
-
-//************************************************************************
-void  VisuGUI_TimeAnimationDlg::addField(SALOMEDS::SObject_var theSObject) {
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
+{
   myPlayFrame->setEnabled(false);
   myAnimator->addField(theSObject);
 }
 
-
-
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::createFrames() {
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::createFrames()
+{
   stopAnimation();
-  QApplication::setOverrideCursor( Qt::waitCursor );
+  SUIT_OverrideCursor c;
 
   for (int i = 0; i < myAnimator->getNbFields(); i++) {
-    if (myAnimator->getFieldData(i).myPrs == 0) 
+    if (myAnimator->getFieldData(i).myPrs.empty())
       myAnimator->generatePresentations(i);
   }
+  if (myAnimator->getNbFrames() == 0) {
+    myPlayFrame->setEnabled(false);
+    c.suspend();
+    SUIT_MessageBox::warn1(this,
+                           tr("ERROR"),
+                           tr("MSG_NO_ANIMATIONDATA"),
+                           tr("&OK"));
+    return;
+  }
   mySlider->setMaxValue(myAnimator->getNbFrames()-1);
+  myPlayFrame->setEnabled(true);
   if (!myAnimator->generateFrames()) {
-    QApplication::restoreOverrideCursor();
-    QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), "Defined presentation can not be created"); 
+    c.suspend();
+    //myPlayFrame->setEnabled(false);
+    SUIT_MessageBox::warn1(this,
+                           tr("ERROR"),
+                           myAnimator->getLastErrorMsg(),
+                           tr("&OK"));
     return;
   }
-  myPlayFrame->setEnabled(true);
-  QApplication::restoreOverrideCursor();
+  //myPlayFrame->setEnabled(true);
 }
-  
 
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onPlayPressed() {
-  if (myPlayBtn->isOn()) {
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onPlayPressed()
+{
+  if (myPlayBtn->isOn() && (!myAnimator->running())) {
     myPlayBtn->setIconSet(MYpausePixmap);
-    if (mySaveCheck->isChecked())
+    if (mySaveCheck->isChecked()) {
+      QStrList aDumpFormats = QImageIO::outputFormats();
+      myAnimator->setDumpFormat(aDumpFormats.at(myPicsFormat->currentItem()));
       myAnimator->dumpTo(myPathEdit->text());
-    else
+    } else {
       myAnimator->dumpTo("");
+    }
+    mySetupBtn->setEnabled(false);
+    myGenBtn->setEnabled(false);
     myAnimator->startAnimation();
   } else {
     myPlayBtn->setIconSet(MYplayPixmap);
     myAnimator->stopAnimation();
+    mySetupBtn->setEnabled(true);
+    myGenBtn->setEnabled(true);
   }
 }
 
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onBackPressed() {
-  stopAnimation();
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onBackPressed()
+{
+  //stopAnimation();
   myAnimator->prevFrame();
 }
 
-
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onForvardPressed() {
-  stopAnimation();
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onForvardPressed()
+{
   myAnimator->nextFrame();
 }
 
-
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onLastPressed() {
-  stopAnimation();
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onLastPressed()
+{
   myAnimator->lastFrame();
 }
 
-
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onFirstPressed() {
-  stopAnimation();
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onFirstPressed()
+{
   myAnimator->firstFrame();
 }
 
-
-
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::clearView() {
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::clearView()
+{
   myAnimator->clearView();
 }
 
-
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::closeEvent(QCloseEvent* theEvent) {
-  stopAnimation();
-  clearView();
-  QDialog::closeEvent(theEvent);
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::showEvent(QShowEvent* theEvent)
+{
+  mySetupDlg = new SetupDlg(this,myModule, myAnimator);
 }
 
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::closeEvent (QCloseEvent* theEvent)
+{
+  if(myAnimator != NULL){
+    myAnimator->stopAnimation();
+    myAnimator->wait(500);
+    if (myAnimator->running() && (! myAnimator->finished())) {
+      isClosing = true;
+      myEvent = theEvent;
+      //        * Destroing data in myAnimator before study closed.
+      //        * It needed for correcting destroing of myAnimator, which 
+      //        * depend from SVTK_RenderWindowInteractor() e.t.c.
+      if(theEvent->type() == QEvent::Close){
+       for (int i = 0; i < myAnimator->getNbFields(); i++)
+         myAnimator->clearData(myAnimator->getFieldData(i));
+       myAnimator->clearFieldData();
+      }
+    } else {
+      QDialog::closeEvent(theEvent);
+    }
+  } else {
+    QDialog::closeEvent(theEvent);
+  }
+}
 
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onFrameChanged(int index) {
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onWindowChanged (int index)
+{
   if (myAnimator->isRunning()) return;
   myAnimator->gotoFrame(index);
 }
 
-
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onSpeedChange(double theSpeed) {
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onSpeedChange (double theSpeed)
+{
   myAnimator->setSpeed((int)theSpeed);
 }
-    
 
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::stopAnimation() {
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::stopAnimation()
+{
   myAnimator->stopAnimation();
   myPlayBtn->setOn(false);
   myPlayBtn->setIconSet(MYplayPixmap);
+  mySetupBtn->setEnabled(true);
+  myGenBtn->setEnabled(true);
 }
 
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onExecution(long theNewFrame, double theTime) {
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
+{
   myTimeLbl->setText(QString("%1").arg(theTime));
   mySlider->setValue(theNewFrame);
 }
 
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onSetupDlg()
+{
+  if (myAnimator->getNbFrames() > 0) 
+    myAnimator->firstFrame();
+  mySetupDlg->exec();
+  myPlayFrame->setEnabled(false);
+}
+
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onBrowse()
+{
+  QString aPath = SUIT_FileDlg::getExistingDirectory(this, "/", "Select path");
+  if (!aPath.isEmpty())
+    myPathEdit->setText(Qtx::addSlash(aPath));
+}
+
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::onStop()
+{
+  if (isClosing) {
+    QDialog::closeEvent(myEvent);
+  } else {
+    myPlayBtn->setOn(false);
+    myPlayBtn->setIconSet(MYplayPixmap);
+    mySetupBtn->setEnabled(true);
+    myGenBtn->setEnabled(true);
+  }
+}
+
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::saveToStudy()
+{
+  myAnimator->saveAnimation();
+  VISU::UpdateObjBrowser(myModule, true);
+}
 
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onSetupDlg() {
-  SetupDlg* aDlg = new SetupDlg(this, myAnimator);
-  aDlg->exec();
-  delete aDlg;
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::publishToStudy()
+{
+  myAnimator->publishInStudy();
+  VISU::UpdateObjBrowser(myModule, true);
+  mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
 }
 
-//************************************************************************
-void VisuGUI_TimeAnimationDlg::onBrowse() {
-  myPathEdit->setText(QAD_FileDlg::getExistingDirectory(this, "/","Select path"));
+//------------------------------------------------------------------------
+void VisuGUI_TimeAnimationDlg::restoreFromStudy(_PTR(SObject) theAnimation)
+{
+  myAnimator->restoreFromStudy(theAnimation);
+  mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
 }