Salome HOME
Merge branch 'ASL_TREE_STATE' into asl/hydro_porting_741
[modules/gui.git] / src / SVTK / SVTK_ViewWindow.cxx
index 3a81fc72a29871a7ed2a78224cedd9ff22767375..d56dde955cb163a7d2ecb1ae12e500e2f75d6d9c 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -35,6 +35,7 @@
 #include <QToolBar>
 #include <QEvent>
 #include <QFileInfo>
+#include <QSignalMapper>
 #include <QXmlStreamWriter>
 #include <QXmlStreamReader>
 #include <QXmlStreamAttributes>
 #include "SUIT_ViewManager.h"
 #include "QtxActionToolMgr.h"
 #include "QtxMultiAction.h"
+#include "QtxActionGroup.h"
 
 #include "VTKViewer_Utilities.h"
 #include "VTKViewer_Trihedron.h"
 
 #include "SVTK_View.h"
-//#include "SVTK_MainWindow.h"
 #include "SVTK_Selector.h"
 
 #include "SVTK_Event.h"
@@ -147,12 +148,18 @@ SVTK_ViewWindow::SVTK_ViewWindow(SUIT_Desktop* theDesktop):
 */
 void SVTK_ViewWindow::Initialize(SVTK_ViewModelBase* theModel)
 {
+  myModel = theModel;
   myInteractor = new SVTK_RenderWindowInteractor(this,"SVTK_RenderWindowInteractor");
   
-  SVTK_Selector* aSelector = SVTK_Selector::New(); 
-  aSelector->SetDynamicPreSelection( SUIT_Session::session()->resourceMgr()->
-                                    booleanValue( "VTKViewer", "dynamic_preselection", true ) );
-  
+  SVTK_Selector* aSelector = SVTK_Selector::New();
+  int aPreselectionMode =  SUIT_Session::session()->resourceMgr()->
+    integerValue( "VTKViewer", "preselection", Standard_Preselection );
+  aSelector->SetDynamicPreSelection( aPreselectionMode == Dynamic_Preselection );
+  aSelector->SetPreSelectionEnabled( aPreselectionMode != Preselection_Disabled );
+  bool isSelectionEnabled = SUIT_Session::session()->resourceMgr()->
+    booleanValue( "VTKViewer", "enable_selection", true );
+  aSelector->SetSelectionEnabled( isSelectionEnabled );
+    
   SVTK_GenericRenderWindowInteractor* aDevice = SVTK_GenericRenderWindowInteractor::New();
   aDevice->SetRenderWidget(myInteractor);
   aDevice->SetSelector(aSelector);
@@ -229,6 +236,8 @@ void SVTK_ViewWindow::Initialize(SVTK_ViewModelBase* theModel)
 
   GetInteractor()->GetInteractorStyle()->AddObserver(SVTK::OperationFinished, 
                                                     myEventCallbackCommand.GetPointer(), 0.0);
+  myKeyFreeInteractorStyle->AddObserver(SVTK::OperationFinished, 
+                                       myEventCallbackCommand.GetPointer(), 0.0);
 
 
   
@@ -259,6 +268,8 @@ void SVTK_ViewWindow::Initialize(SVTK_View* theView,
           this,SIGNAL(contextMenuRequested(QContextMenuEvent *)));
   connect(theView,SIGNAL(selectionChanged()),
           theModel,SLOT(onSelectionChanged()));
+
+  connect( this, SIGNAL( transformed( SVTK_ViewWindow* ) ), SLOT( emitViewModified() ) );
 }
 
 /*!
@@ -788,9 +799,9 @@ bool SVTK_ViewWindow::isCubeAxesDisplayed()
 /*!
   Redirect the request to #SVTK_Renderer::OnViewTrihedron
 */
-void SVTK_ViewWindow::onViewTrihedron()
+void SVTK_ViewWindow::onViewTrihedron(bool show)
 {
-  GetRenderer()->OnViewTrihedron();
+  GetRenderer()->SetTrihedronVisibility(show);
   Repaint();
 }
 
@@ -822,7 +833,7 @@ SVTK_CubeAxesActor2D* SVTK_ViewWindow::GetCubeAxes()
 /*!
   \return trihedron size
 */
-vtkFloatingPointType SVTK_ViewWindow::GetTrihedronSize() const
+double SVTK_ViewWindow::GetTrihedronSize() const
 {
   return GetRenderer()->GetTrihedronSize();
 }
@@ -888,12 +899,28 @@ void SVTK_ViewWindow::SetZoomingStyle(const int theStyle)
 }
 
 /*!
-  Switch dynamic preselection on / off
-  \param theDynPreselection - dynamic pre-selection mode
+  Set preselection mode.
+  \param theMode the mode to set (standard, dynamic or disabled)
+*/
+void SVTK_ViewWindow::SetPreSelectionMode( Preselection_Mode theMode )
+{
+  onSwitchPreSelectionMode( theMode );
+}
+
+/*!
+  Enables/disables selection.
+  \param theEnable if true - selection will be enabled
 */
-void SVTK_ViewWindow::SetDynamicPreSelection( bool theDynPreselection )
+void SVTK_ViewWindow::SetSelectionEnabled( bool theEnable )
 {
-  onSwitchDynamicPreSelection( theDynPreselection );
+  GetSelector()->SetSelectionEnabled( theEnable );
+  QtxAction* a = getAction( EnableSelectionId );
+  if ( a->isChecked() !=  theEnable)
+    a->setChecked( theEnable );
+  QtxActionGroup* aPreselectionGroup = 
+    dynamic_cast<QtxActionGroup*>( getAction( PreselectionId ) );
+  if ( aPreselectionGroup )
+    aPreselectionGroup->setEnabled( theEnable );
 }
 
 /*!
@@ -943,16 +970,29 @@ void SVTK_ViewWindow::onSwitchZoomingStyle( bool theOn )
 }
 
 /*!
-  Toogles dynamic preselection on/off
+  Switch preselection mode.
+  \param theMode the preselection mode
 */
-void SVTK_ViewWindow::onSwitchDynamicPreSelection( bool theOn )
+void SVTK_ViewWindow::onSwitchPreSelectionMode( int theMode )
 {
-  GetSelector()->SetDynamicPreSelection( theOn );
+  GetSelector()->SetDynamicPreSelection( theMode == Dynamic_Preselection );
+  GetSelector()->SetPreSelectionEnabled( theMode != Preselection_Disabled );
 
   // update action state if method is called outside
-  QtxAction* a = getAction( SwitchDynamicPreselectionId );
-  if ( a->isChecked() != theOn )
-    a->setChecked( theOn );
+  QtxAction* a = getAction( StandardPreselectionId + theMode );
+  if ( a && !a->isChecked() )
+    a->setChecked( true );
+}
+
+/*!
+  Enables/disables selection.
+  \param theOn if true - selection will be enabled
+*/
+void SVTK_ViewWindow::onEnableSelection( bool on )
+{
+  SVTK_Viewer* aViewer = dynamic_cast<SVTK_Viewer*>(myModel);
+  if(aViewer)
+    aViewer->enableSelection(on);  
 }
 
 /*!
@@ -989,7 +1029,7 @@ void SVTK_ViewWindow::SetSpacemouseButtons(const int theBtn1,
   \param theSize - new trihedron size
   \param theRelative - trihedron relativeness
 */
-void SVTK_ViewWindow::SetTrihedronSize(const vtkFloatingPointType theSize, const bool theRelative)
+void SVTK_ViewWindow::SetTrihedronSize(const double theSize, const bool theRelative)
 {
   GetRenderer()->SetTrihedronSize(theSize, theRelative);
   Repaint();
@@ -1098,6 +1138,10 @@ void SVTK_ViewWindow::RemoveActor( VTKViewer_Actor* theActor,
                                    bool theIsAdjustActors )
 {
   GetRenderer()->RemoveActor(theActor, theIsAdjustActors);
+  if ( myDefaultInteractorStyle )
+    myDefaultInteractorStyle->FreeActors();
+  if ( myKeyFreeInteractorStyle )
+    myKeyFreeInteractorStyle->FreeActors();
   if(theUpdate) 
     Repaint();
   emit actorRemoved(theActor);
@@ -1294,7 +1338,7 @@ void getGradAxisVisualParams( QXmlStreamWriter& writer, vtkAxisActor2D* actor, Q
   // Name
   bool isVisible = actor->GetTitleVisibility();
   QString title ( actor->GetTitle() );
-  vtkFloatingPointType color[ 3 ];
+  double color[ 3 ];
   int font = VTK_ARIAL;
   int bold = 0;
   int italic = 0;
@@ -1408,7 +1452,7 @@ void setGradAxisVisualParams(QXmlStreamReader& reader, vtkAxisActor2D* actor)
   // Read title color
   aAttr = reader.attributes();
 
-  vtkFloatingPointType color[3];
+  double color[3];
   color[0] = aAttr.value("R").toString().toDouble();
   color[1] = aAttr.value("G").toString().toDouble();
   color[2] = aAttr.value("B").toString().toDouble();
@@ -1490,7 +1534,7 @@ void setGradAxisVisualParams( vtkAxisActor2D* actor, const QString& params )
     // retrieve and set name parameters
     bool isVisible = paramsLst[2].toUShort();
     QString title = paramsLst[3];
-    vtkFloatingPointType color[3];
+    double color[3];
     color[0] = paramsLst[4].toDouble();
     color[1] = paramsLst[5].toDouble();
     color[2] = paramsLst[6].toDouble();
@@ -1822,10 +1866,11 @@ void SVTK_ViewWindow::activateSetRotationSelected(void* theData)
 }
 
 /*!
-  Set the point selected by user as a rotation point
+  Set the gravity center of element selected by user as a rotation point
 */
-void SVTK_ViewWindow::activateStartPointSelection()
+void SVTK_ViewWindow::activateStartPointSelection( Selection_Mode theSelectionMode )
 {
+  SetSelectionMode( theSelectionMode );
   myEventDispatcher->InvokeEvent(SVTK::StartPointSelection,0);
 }
 
@@ -1843,6 +1888,8 @@ void SVTK_ViewWindow::onPerspectiveMode()
   vtkCamera* aCamera = getRenderer()->GetActiveCamera();
   aCamera->SetParallelProjection(anIsParallelMode);
   GetInteractor()->GetDevice()->CreateTimer(VTKI_TIMER_FIRST);
+
+  emit transformed( this );
 }
 
 void SVTK_ViewWindow::SetEventDispatcher(vtkObject* theDispatcher)
@@ -2003,8 +2050,11 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr)
   anAction = new QtxAction(tr("MNU_SHOW_TRIHEDRON"), 
                            theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_TRIHEDRON" ) ),
                            tr( "MNU_SHOW_TRIHEDRON" ), 0, this);
+  anAction->setCheckable( true );
+  anAction->setChecked( true );
+  
   anAction->setStatusTip(tr("DSC_SHOW_TRIHEDRON"));
-  connect(anAction, SIGNAL(activated()), this, SLOT(onViewTrihedron()));
+  connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onViewTrihedron(bool)));
   mgr->registerAction( anAction, ViewTrihedronId );
 
   // onNonIsometric: Manage non-isometric params
@@ -2065,15 +2115,7 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr)
   mgr->registerAction( anAction, ViewParametersId );
 
   // Synchronize View 
-  anAction = new QtxAction(tr("MNU_SYNCHRONIZE_VIEW"), 
-                           theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_SYNCHRONIZE" ) ),
-                           tr( "MNU_SYNCHRONIZE_VIEW" ), 0, this);
-  anAction->setStatusTip(tr("DSC_SYNCHRONIZE_VIEW"));
-  anAction->setMenu( new QMenu( this ) );
-  anAction->setCheckable(true);
-  connect(anAction->menu(), SIGNAL(aboutToShow()), this, SLOT(updateSyncViews()));
-  connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onSynchronizeView(bool)));
-  mgr->registerAction( anAction, SynchronizeId );
+  mgr->registerAction( synchronizeAction(), SynchronizeId );
 
   // Switch between interaction styles
   anAction = new QtxAction(tr("MNU_SVTK_STYLE_SWITCH"), 
@@ -2093,14 +2135,51 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr)
   connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchZoomingStyle(bool)));
   mgr->registerAction( anAction, SwitchZoomingStyleId );
 
-  // Turn on/off dynamic pre-selection
-  anAction = new QtxAction(tr("MNU_SVTK_DYNAMIC_PRESLECTION_SWITCH"), 
-                           theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_DYNAMIC_PRESLECTION_SWITCH" ) ),
-                           tr( "MNU_SVTK_DYNAMIC_PRESLECTION_SWITCH" ), 0, this);
-  anAction->setStatusTip(tr("DSC_SVTK_DYNAMIC_PRESLECTION_SWITCH"));
+  // Pre-selection
+  QSignalMapper* aSignalMapper = new QSignalMapper( this );
+  connect(aSignalMapper, SIGNAL(mapped(int)), this, SLOT(onSwitchPreSelectionMode(int)));
+
+  anAction = new QtxAction(tr("MNU_SVTK_PRESELECTION_STANDARD"), 
+                           theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_PRESELECTION_STANDARD" ) ),
+                           tr( "MNU_SVTK_PRESELECTION_STANDARD" ), 0, this);
+  anAction->setStatusTip(tr("DSC_SVTK_PRESELECTION_STANDARD"));
+  anAction->setCheckable(true);
+  connect(anAction, SIGNAL(activated()), aSignalMapper, SLOT(map()));
+  aSignalMapper->setMapping( anAction, Standard_Preselection );
+  mgr->registerAction( anAction, StandardPreselectionId );
+  
+  anAction = new QtxAction(tr("MNU_SVTK_PRESELECTION_DYNAMIC"), 
+                           theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_PRESELECTION_DYNAMIC" ) ),
+                           tr( "MNU_SVTK_PRESELECTION_DYNAMIC" ), 0, this);
+  anAction->setStatusTip(tr("DSC_SVTK_PRESELECTION_DYNAMIC"));
   anAction->setCheckable(true);
-  connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchDynamicPreSelection(bool)));
-  mgr->registerAction( anAction, SwitchDynamicPreselectionId );
+  connect(anAction, SIGNAL(activated()), aSignalMapper, SLOT(map()));
+  aSignalMapper->setMapping( anAction, Dynamic_Preselection );
+  mgr->registerAction( anAction, DynamicPreselectionId );
+
+  anAction = new QtxAction(tr("MNU_SVTK_PRESELECTION_DISABLED"), 
+                           theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_PRESELECTION_DISABLED" ) ),
+                           tr( "MNU_SVTK_PRESELECTION_DISABLED" ), 0, this);
+  anAction->setStatusTip(tr("DSC_SVTK_PRESELECTION_DISABLED"));
+  anAction->setCheckable(true);
+  connect(anAction, SIGNAL(activated()), aSignalMapper, SLOT(map()));
+  aSignalMapper->setMapping( anAction, Preselection_Disabled );
+  mgr->registerAction( anAction, DisablePreselectionId );
+
+  QtxActionGroup* aPreselectionAction = new QtxActionGroup( this, true );
+  aPreselectionAction->add( getAction( StandardPreselectionId ) );
+  aPreselectionAction->add( getAction( DynamicPreselectionId ) );
+  aPreselectionAction->add( getAction( DisablePreselectionId ) );
+  mgr->registerAction( aPreselectionAction, PreselectionId );
+
+  // Selection
+  anAction = new QtxAction(tr("MNU_SVTK_ENABLE_SELECTION"), 
+                           theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_SELECTION" ) ),
+                           tr( "MNU_SVTK_ENABLE_SELECTION" ), 0, this);
+  anAction->setStatusTip(tr("DSC_SVTK_ENABLE_SELECTION"));
+  anAction->setCheckable(true);
+  connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onEnableSelection(bool)));
+  mgr->registerAction( anAction, EnableSelectionId );
 
   // Start recording
   myStartAction = new QtxAction(tr("MNU_SVTK_RECORDING_START"), 
@@ -2148,7 +2227,14 @@ void SVTK_ViewWindow::createToolBar()
   mgr->append( DumpId, myToolBar );
   mgr->append( SwitchInteractionStyleId, myToolBar );
   mgr->append( SwitchZoomingStyleId, myToolBar );
-  mgr->append( SwitchDynamicPreselectionId, myToolBar );
+
+  mgr->append( mgr->separator(), myToolBar );
+  mgr->append( PreselectionId, myToolBar );
+  mgr->append( EnableSelectionId, myToolBar );
+
+  mgr->append( mgr->separator(), myToolBar );
+
   mgr->append( ViewTrihedronId, myToolBar );
 
   QtxMultiAction* aScaleAction = new QtxMultiAction( this );
@@ -2361,134 +2447,6 @@ void SVTK_ViewWindow::hideEvent( QHideEvent * theEvent )
   emit Hide( theEvent );
 }
 
-void SVTK_ViewWindow::synchronizeView( SVTK_ViewWindow* viewWindow, int id )
-{
-  SVTK_ViewWindow* otherViewWindow = 0;
-  QList<SVTK_ViewWindow*> compatibleViews;
-
-  bool isSync = viewWindow->toolMgr()->action( SynchronizeId )->isChecked();
-
-  int vwid = viewWindow->getId();
-  
-  SUIT_Application* app = SUIT_Session::session()->activeApplication();
-  if ( !app ) return;
-
-  QList<SUIT_ViewManager*> wmlist;
-  app->viewManagers( viewWindow->getViewManager()->getType(), wmlist );
-
-  foreach( SUIT_ViewManager* wm, wmlist ) {
-    QVector<SUIT_ViewWindow*> vwlist = wm->getViews();
-
-    foreach( SUIT_ViewWindow* vw, vwlist ) {
-      SVTK_ViewWindow* vtkVW = dynamic_cast<SVTK_ViewWindow*>( vw );
-      if ( !vtkVW ) continue;
-      if ( vtkVW->getId() == id ) 
-       otherViewWindow = vtkVW;
-      else if ( vtkVW != viewWindow )
-       compatibleViews.append( vtkVW );
-    }
-  }
-
-  if ( isSync && id ) {
-    // remove all possible disconnections
-    foreach( SVTK_ViewWindow* vw, compatibleViews ) {
-      // disconnect target view
-      vw->disconnect( SIGNAL( transformed( SVTK_ViewPort* ) ), viewWindow, SLOT( synchronize( SVTK_ViewPort* ) ) );
-      viewWindow->disconnect( SIGNAL( transformed( SVTK_ViewPort* ) ), vw, SLOT( synchronize( SVTK_ViewPort* ) ) );
-      if ( otherViewWindow ) {
-       // disconnect source view
-       vw->disconnect( SIGNAL( transformed( SVTK_ViewPort* ) ), otherViewWindow, SLOT( synchronize( SVTK_ViewPort* ) ) );
-       otherViewWindow->disconnect( SIGNAL( transformed( SVTK_ViewPort* ) ), vw, SLOT( synchronize( SVTK_ViewPort* ) ) );
-      }
-      QAction* a = vw->toolMgr()->action( SynchronizeId );
-      if ( a ) {
-       int anid = a->data().toInt();
-       if ( a->isChecked() && ( anid == id || anid == vwid ) ) {
-         bool blocked = a->blockSignals( true );
-         a->setChecked( false );
-         a->blockSignals( blocked );
-       }
-      }
-    }
-    if ( otherViewWindow ) {
-      // reconnect source and target view
-      otherViewWindow->disconnect( SIGNAL( transformed( SVTK_ViewWindow* ) ), viewWindow, SLOT( synchronize( SVTK_ViewWindow* ) ) );
-      viewWindow->disconnect( SIGNAL( transformed( SVTK_ViewWindow* ) ), otherViewWindow, SLOT( synchronize( SVTK_ViewWindow* ) ) );
-      otherViewWindow->connect( viewWindow, SIGNAL( transformed( SVTK_ViewWindow* ) ), SLOT( synchronize( SVTK_ViewWindow* ) ) );
-      viewWindow->connect( otherViewWindow, SIGNAL( transformed( SVTK_ViewWindow* ) ), SLOT( synchronize( SVTK_ViewWindow* ) ) );
-      // synchronize target view with source view
-      viewWindow->doSetVisualParameters( otherViewWindow->getVisualParameters(), true );
-      viewWindow->toolMgr()->action( SynchronizeId )->setData( otherViewWindow->getId() );
-      otherViewWindow->toolMgr()->action( SynchronizeId )->setData( viewWindow->getId() );
-      if ( !otherViewWindow->toolMgr()->action( SynchronizeId )->isChecked() ) {
-       bool blocked = otherViewWindow->toolMgr()->action( SynchronizeId )->blockSignals( true );
-       otherViewWindow->toolMgr()->action( SynchronizeId )->setChecked( true );
-       otherViewWindow->toolMgr()->action( SynchronizeId )->blockSignals( blocked );
-      }
-    }
-  }
-  else if ( otherViewWindow ) {
-    // reconnect source and target view
-    otherViewWindow->disconnect( SIGNAL( transformed( SVTK_ViewWindow* ) ), viewWindow, SLOT( synchronize( SVTK_ViewWindow* ) ) );
-    viewWindow->disconnect( SIGNAL( transformed( SVTK_ViewWindow* ) ), otherViewWindow, SLOT( synchronize( SVTK_ViewWindow* ) ) );
-    viewWindow->doSetVisualParameters( otherViewWindow->getVisualParameters(), true );
-    viewWindow->toolMgr()->action( SynchronizeId )->setData( otherViewWindow->getId() );
-    if ( otherViewWindow->toolMgr()->action( SynchronizeId )->data().toInt() == viewWindow->getId() && otherViewWindow->toolMgr()->action( SynchronizeId )->isChecked() ) {
-      bool blocked = otherViewWindow->toolMgr()->action( SynchronizeId )->blockSignals( true );
-      otherViewWindow->toolMgr()->action( SynchronizeId )->setChecked( false );
-      otherViewWindow->toolMgr()->action( SynchronizeId )->blockSignals( blocked );
-    }
-  }
-}
-
-/*!
-  "Synchronize View" action slot.
-*/
-void SVTK_ViewWindow::onSynchronizeView(bool checked)
-{
-  QAction* a = qobject_cast<QAction*>( sender() );
-  if ( a ) {
-    synchronizeView( this, a->data().toInt() );
-  }
-}
-
-/*!
-  Update list of available view for the "Synchronize View" action
-*/
-void SVTK_ViewWindow::updateSyncViews()
-{
-  QAction* anAction = toolMgr()->action( SynchronizeId );
-  if ( anAction && anAction->menu() ) {
-    int currentId = anAction->data().toInt();
-    anAction->menu()->clear();
-    SUIT_Application* app = SUIT_Session::session()->activeApplication();
-    if ( app ) { 
-      QList<SUIT_ViewManager*> wmlist;
-      app->viewManagers( getViewManager()->getType(), wmlist );
-      foreach( SUIT_ViewManager* wm, wmlist ) {
-       QVector<SUIT_ViewWindow*> vwlist = wm->getViews();
-       foreach ( SUIT_ViewWindow* vw, vwlist ) {
-         SVTK_ViewWindow* vtkVW = dynamic_cast<SVTK_ViewWindow*>( vw );
-         if ( !vtkVW || vtkVW == this ) continue;
-         QAction* a = anAction->menu()->addAction( vtkVW->windowTitle() );
-          if ( vtkVW->getId() == currentId ) {
-            QFont f = a->font();
-           f.setBold( true );
-           a->setFont( f );
-         }
-         a->setData( vtkVW->getId() );
-         connect( a, SIGNAL( triggered(bool) ), this, SLOT( onSynchronizeView(bool) ) );
-       }
-      }
-    }
-    if ( anAction->menu()->actions().isEmpty() ) {
-      anAction->setData( 0 );
-      anAction->menu()->addAction( tr( "MNU_SYNC_NO_VIEW" ) );
-    }
-  }
-}
-
-
 /*!
   Emit transformed signal.
 */
@@ -2508,3 +2466,99 @@ void SVTK_ViewWindow::ProcessEvents(vtkObject* vtkNotUsed(theObject),
   if(self)
     self->emitTransformed();
 }
+
+/*!
+  Get camera properties for the SVTK view window.
+  \return shared pointer on camera properties.
+*/
+SUIT_CameraProperties SVTK_ViewWindow::cameraProperties()
+{
+  SUIT_CameraProperties aProps;
+
+  // get vtk camera
+  vtkCamera* aCamera = getRenderer()->GetActiveCamera();
+  if ( !aCamera )
+    return aProps;
+  
+  aProps.setDimension( SUIT_CameraProperties::Dim3D );
+  if ( toolMgr()->action( ParallelModeId ) ) {
+    if ( toolMgr()->action( ParallelModeId )->isChecked() )
+      aProps.setProjection( SUIT_CameraProperties::PrjOrthogonal );
+    else
+      aProps.setProjection( SUIT_CameraProperties::PrjPerspective );
+  }
+
+  double aFocalPoint[3];
+  double aPosition[3];
+  double aViewUp[3];
+  double anAxialScale[3];
+
+  aCamera->OrthogonalizeViewUp();
+  aCamera->GetFocalPoint( aFocalPoint );
+  aCamera->GetPosition( aPosition );
+  aCamera->GetViewUp( aViewUp );
+  
+  aProps.setFocalPoint( aFocalPoint[0], aFocalPoint[1], aFocalPoint[2] );
+  aProps.setPosition( aPosition[0], aPosition[1], aPosition[2] );
+  aProps.setViewUp( aViewUp[0], aViewUp[1], aViewUp[2] );
+  aProps.setMappingScale( aCamera->GetParallelScale() * 2.0 );
+
+  if ( aProps.getProjection() == SUIT_CameraProperties::PrjPerspective )
+  {
+    aProps.setViewAngle( aCamera->GetViewAngle() );
+  }
+
+  GetRenderer()->GetScale( anAxialScale );
+  aProps.setAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] );
+  
+  return aProps;
+}
+
+/*!
+  Synchronize views.
+  This implementation synchronizes camera propreties.
+*/
+void SVTK_ViewWindow::synchronize( SUIT_ViewWindow* theView )
+{
+  bool blocked = blockSignals( true );
+
+  SUIT_CameraProperties aProps = theView->cameraProperties();
+  if ( !cameraProperties().isCompatible( aProps ) ) {
+    // other view, this one is being currently synchronized to, seems has become incompatible
+    // we have to break synchronization
+    updateSyncViews();
+    return;
+  }
+
+  // get camera
+  vtkCamera* aCamera = getRenderer()->GetActiveCamera();
+  
+  double aFocalPoint[3];
+  double aPosition[3];
+  double aViewUp[3];
+  double anAxialScale[3];
+
+  // get common properties
+  aProps.getViewUp( aViewUp[0], aViewUp[1], aViewUp[2] );
+  aProps.getPosition( aPosition[0], aPosition[1], aPosition[2] );
+  aProps.getFocalPoint( aFocalPoint[0], aFocalPoint[1], aFocalPoint[2] );
+  aProps.getAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] );
+  
+  // restore properties to the camera
+  aCamera->SetViewUp( aViewUp );
+  aCamera->SetPosition( aPosition );
+  aCamera->SetFocalPoint( aFocalPoint );
+  aCamera->SetParallelScale( aProps.getMappingScale() / 2.0 );
+
+  if ( aProps.getProjection() == SUIT_CameraProperties::PrjPerspective )
+  {
+    aCamera->SetViewAngle( aProps.getViewAngle() );
+  }
+
+  GetRenderer()->SetScale( anAxialScale );
+
+  getRenderer()->ResetCameraClippingRange();
+  Repaint( false );
+
+  blockSignals( blocked );
+}