From 749dc4fb567204b3b3a6f54e48ead72d0a65ccd7 Mon Sep 17 00:00:00 2001 From: vsr Date: Sat, 24 Sep 2011 11:56:04 +0000 Subject: [PATCH] Issue 0021319: EDF 1616 ALL: synchronization of 3D viewers --- src/OCCViewer/Makefile.am | 3 +- src/OCCViewer/OCCViewer_ViewWindow.cxx | 186 ++++++++++++++------ src/OCCViewer/OCCViewer_ViewWindow.h | 9 +- src/OCCViewer/resources/OCCViewer_images.ts | 4 + src/OCCViewer/resources/OCCViewer_msg_en.ts | 12 ++ src/OCCViewer/resources/occ_view_sync.png | Bin 0 -> 627 bytes src/SUIT/SUIT_Application.h | 11 +- src/SVTK/Makefile.am | 3 +- src/SVTK/SVTK_ViewWindow.cxx | 162 +++++++++++++---- src/SVTK/SVTK_ViewWindow.h | 7 +- src/SVTK/resources/SVTK_images.ts | 4 + src/SVTK/resources/SVTK_msg_en.ts | 12 ++ src/SVTK/resources/vtk_view_sync.png | Bin 0 -> 627 bytes 13 files changed, 315 insertions(+), 98 deletions(-) create mode 100755 src/OCCViewer/resources/occ_view_sync.png create mode 100755 src/SVTK/resources/vtk_view_sync.png diff --git a/src/OCCViewer/Makefile.am b/src/OCCViewer/Makefile.am index fb3081744..f30b953f7 100755 --- a/src/OCCViewer/Makefile.am +++ b/src/OCCViewer/Makefile.am @@ -116,7 +116,8 @@ dist_salomeres_DATA = \ resources/occ_view_style_switch.png \ resources/occ_view_zooming_style_switch.png \ resources/occ_view_maximized.png \ - resources/occ_view_minimized.png + resources/occ_view_minimized.png \ + resources/occ_view_sync.png nodist_salomeres_DATA = \ OCCViewer_images.qm \ diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index 2388b95de..bc78de401 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,7 @@ #include #include #include +#include #include #include @@ -277,6 +279,11 @@ void OCCViewer_ViewWindow::initLayout() myCubeAxesDlg->initialize(); } +OCCViewer_ViewWindow* OCCViewer_ViewWindow::getView( const int mode ) const +{ + return mode == get2dMode() ? const_cast( this ) : 0; +} + /*! \brief Detect viewer operation according the the mouse button pressed and key modifiers used. @@ -1219,6 +1226,15 @@ void OCCViewer_ViewWindow::createActions() aAction->setStatusTip(tr("DSC_MINIMIZE_VIEW")); connect(aAction, SIGNAL(triggered()), this, SLOT(onMaximizedView())); toolMgr()->registerAction( aAction, MaximizedId ); + + // Synchronize view + aAction = new QtxAction(tr("MNU_SYNCHRONIZE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SYNC" ) ), + tr( "MNU_SYNCHRONIZE_VIEW" ), 0, this ); + aAction->setStatusTip(tr("DSC_SYNCHRONIZE_VIEW")); + aAction->setMenu( new QMenu( this ) ); + connect(aAction->menu(), SIGNAL(aboutToShow()), this, SLOT(updateSyncViews())); + connect(aAction, SIGNAL(triggered()), this, SLOT(onSynchronizeView())); + toolMgr()->registerAction( aAction, SynchronizeId ); } /*! @@ -1297,7 +1313,8 @@ void OCCViewer_ViewWindow::createToolBar() #endif toolMgr()->append( AmbientId, tid ); - toolMgr()->append( MaximizedId, tid); + toolMgr()->append( MaximizedId, tid ); + toolMgr()->append( SynchronizeId, tid ); } /*! @@ -1571,7 +1588,7 @@ void OCCViewer_ViewWindow::onRestoreView() \brief Restore view parameters. \param anItem view parameters */ -void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem ) +void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool baseParamsOnly ) { Handle(V3d_View) aView3d = myViewPort->getView(); @@ -1584,57 +1601,62 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem ) aView3d->SetEye( anItem.eyeX, anItem.eyeY, anItem.eyeZ ); aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ ); aView3d->SetAxialScale( anItem.scaleX, anItem.scaleY, anItem.scaleZ ); - myModel->setTrihedronShown( anItem.isVisible ); - myModel->setTrihedronSize( anItem.size ); + + if ( !baseParamsOnly ) { + + myModel->setTrihedronShown( anItem.isVisible ); + myModel->setTrihedronSize( anItem.size ); #if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version - // graduated trihedron - bool anIsVisible = anItem.gtIsVisible; - OCCViewer_AxisWidget::AxisData anAxisData[3]; - anAxisData[0].DrawName = anItem.gtDrawNameX; - anAxisData[1].DrawName = anItem.gtDrawNameZ; - anAxisData[2].DrawName = anItem.gtDrawNameZ; - anAxisData[0].Name = anItem.gtNameX; - anAxisData[1].Name = anItem.gtNameZ; - anAxisData[2].Name = anItem.gtNameZ; - anAxisData[0].NameColor = QColor( anItem.gtNameColorRX, - anItem.gtNameColorGX, - anItem.gtNameColorBX ); - anAxisData[1].NameColor = QColor( anItem.gtNameColorRY, - anItem.gtNameColorGY, - anItem.gtNameColorBY ); - anAxisData[2].NameColor = QColor( anItem.gtNameColorRZ, - anItem.gtNameColorGZ, - anItem.gtNameColorBZ ); - anAxisData[0].DrawValues = anItem.gtDrawValuesX; - anAxisData[1].DrawValues = anItem.gtDrawValuesY; - anAxisData[2].DrawValues = anItem.gtDrawValuesZ; - anAxisData[0].NbValues = anItem.gtNbValuesX; - anAxisData[1].NbValues = anItem.gtNbValuesY; - anAxisData[2].NbValues = anItem.gtNbValuesZ; - anAxisData[0].Offset = anItem.gtOffsetX; - anAxisData[1].Offset = anItem.gtOffsetY; - anAxisData[2].Offset = anItem.gtOffsetZ; - anAxisData[0].Color = QColor( anItem.gtColorRX, - anItem.gtColorGX, - anItem.gtColorBX ); - anAxisData[1].Color = QColor( anItem.gtColorRY, - anItem.gtColorGY, - anItem.gtColorBY ); - anAxisData[2].Color = QColor( anItem.gtColorRZ, - anItem.gtColorGZ, - anItem.gtColorBZ ); - anAxisData[0].DrawTickmarks = anItem.gtDrawTickmarksX; - anAxisData[1].DrawTickmarks = anItem.gtDrawTickmarksY; - anAxisData[2].DrawTickmarks = anItem.gtDrawTickmarksZ; - anAxisData[0].TickmarkLength = anItem.gtTickmarkLengthX; - anAxisData[1].TickmarkLength = anItem.gtTickmarkLengthY; - anAxisData[2].TickmarkLength = anItem.gtTickmarkLengthZ; - - myCubeAxesDlg->SetData( anIsVisible, anAxisData ); - myCubeAxesDlg->ApplyData( aView3d ); + // graduated trihedron + bool anIsVisible = anItem.gtIsVisible; + OCCViewer_AxisWidget::AxisData anAxisData[3]; + anAxisData[0].DrawName = anItem.gtDrawNameX; + anAxisData[1].DrawName = anItem.gtDrawNameZ; + anAxisData[2].DrawName = anItem.gtDrawNameZ; + anAxisData[0].Name = anItem.gtNameX; + anAxisData[1].Name = anItem.gtNameZ; + anAxisData[2].Name = anItem.gtNameZ; + anAxisData[0].NameColor = QColor( anItem.gtNameColorRX, + anItem.gtNameColorGX, + anItem.gtNameColorBX ); + anAxisData[1].NameColor = QColor( anItem.gtNameColorRY, + anItem.gtNameColorGY, + anItem.gtNameColorBY ); + anAxisData[2].NameColor = QColor( anItem.gtNameColorRZ, + anItem.gtNameColorGZ, + anItem.gtNameColorBZ ); + anAxisData[0].DrawValues = anItem.gtDrawValuesX; + anAxisData[1].DrawValues = anItem.gtDrawValuesY; + anAxisData[2].DrawValues = anItem.gtDrawValuesZ; + anAxisData[0].NbValues = anItem.gtNbValuesX; + anAxisData[1].NbValues = anItem.gtNbValuesY; + anAxisData[2].NbValues = anItem.gtNbValuesZ; + anAxisData[0].Offset = anItem.gtOffsetX; + anAxisData[1].Offset = anItem.gtOffsetY; + anAxisData[2].Offset = anItem.gtOffsetZ; + anAxisData[0].Color = QColor( anItem.gtColorRX, + anItem.gtColorGX, + anItem.gtColorBX ); + anAxisData[1].Color = QColor( anItem.gtColorRY, + anItem.gtColorGY, + anItem.gtColorBY ); + anAxisData[2].Color = QColor( anItem.gtColorRZ, + anItem.gtColorGZ, + anItem.gtColorBZ ); + anAxisData[0].DrawTickmarks = anItem.gtDrawTickmarksX; + anAxisData[1].DrawTickmarks = anItem.gtDrawTickmarksY; + anAxisData[2].DrawTickmarks = anItem.gtDrawTickmarksZ; + anAxisData[0].TickmarkLength = anItem.gtTickmarkLengthX; + anAxisData[1].TickmarkLength = anItem.gtTickmarkLengthY; + anAxisData[2].TickmarkLength = anItem.gtTickmarkLengthZ; + + myCubeAxesDlg->SetData( anIsVisible, anAxisData ); + myCubeAxesDlg->ApplyData( aView3d ); #endif + } // if ( !baseParamsOnly ) + myRestoreFlag = 0; } @@ -2434,3 +2456,69 @@ void OCCViewer_ViewWindow::updateViewAspects( const viewAspectList& aViewList ) { myViewAspects = aViewList; } + +/*! + "Synchronize View" action slot. +*/ +void OCCViewer_ViewWindow::onSynchronizeView() +{ + QAction* a = qobject_cast( sender() ); + if ( a ) { + int id = a->data().toInt(); + if ( id != 0 ) { + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( !app ) return; + QList wmlist; + app->viewManagers( getViewManager()->getType(), wmlist ); + foreach( SUIT_ViewManager* wm, wmlist ) { + QVector vwlist = wm->getViews(); + foreach ( SUIT_ViewWindow* vw, vwlist ) { + OCCViewer_ViewWindow* occVW = dynamic_cast( vw ); + if ( !occVW ) continue; + // list only compatible types + OCCViewer_ViewWindow* subWindow = occVW->getView( get2dMode() ); + if ( subWindow && subWindow->getId() == id && subWindow != this ) { + // perform synchronization + performRestoring( subWindow->getViewParams(), true ); + } + } + } + + if ( a != toolMgr()->action( SynchronizeId ) ) + toolMgr()->action( SynchronizeId )->setData( id ); + } + } +} + +/*! + Update list of available view for the "Synchronize View" action +*/ +void OCCViewer_ViewWindow::updateSyncViews() +{ + QAction* anAction = toolMgr()->action( SynchronizeId ); + if ( anAction && anAction->menu() ) { + anAction->menu()->clear(); + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( app ) { + QList wmlist; + app->viewManagers( getViewManager()->getType(), wmlist ); + foreach( SUIT_ViewManager* wm, wmlist ) { + QVector vwlist = wm->getViews(); + foreach ( SUIT_ViewWindow* vw, vwlist ) { + OCCViewer_ViewWindow* occVW = dynamic_cast( vw ); + if ( !occVW || occVW == this ) continue; + // list only compatible types + OCCViewer_ViewWindow* subWindow = occVW->getView( get2dMode() ); + if ( subWindow && subWindow != this ) { + QAction* a = anAction->menu()->addAction( occVW->windowTitle() ); + a->setData( subWindow->getId() ); + connect( a, SIGNAL( triggered() ), this, SLOT( onSynchronizeView() ) ); + } + } + } + } + if ( anAction->menu()->actions().isEmpty() ) { + anAction->menu()->addAction( tr( "MNU_SYNC_NO_VIEW" ) ); + } + } +} diff --git a/src/OCCViewer/OCCViewer_ViewWindow.h b/src/OCCViewer/OCCViewer_ViewWindow.h index 7eb3f87f8..01a393e6b 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.h +++ b/src/OCCViewer/OCCViewer_ViewWindow.h @@ -120,7 +120,7 @@ public: FrontId, BackId, TopId, BottomId, LeftId, RightId, ClockWiseId, AntiClockWiseId, ResetId, CloneId, ClippingId, MemId, RestoreId, TrihedronShowId, AxialScaleId, GraduatedAxesId, AmbientId, - SwitchInteractionStyleId, SwitchZoomingStyleId, MaximizedId, UserId }; + SwitchInteractionStyleId, SwitchZoomingStyleId, MaximizedId, SynchronizeId, UserId }; enum OperationType{ NOTHING, PANVIEW, ZOOMVIEW, ROTATE, PANGLOBAL, WINDOWFIT, FITALLVIEW, RESETVIEW, @@ -137,11 +137,13 @@ public: OCCViewer_ViewWindow(SUIT_Desktop* theDesktop, OCCViewer_Viewer* theModel); virtual ~OCCViewer_ViewWindow(); + virtual OCCViewer_ViewWindow* getView( const int ) const; + virtual OCCViewer_ViewPort3d* getViewPort(); virtual bool eventFilter(QObject* watched, QEvent* e); - virtual void performRestoring( const viewAspect& ); + virtual void performRestoring( const viewAspect&, bool = false ); virtual void initLayout(); @@ -229,6 +231,9 @@ public slots: virtual void onMaximizedView(); + virtual void onSynchronizeView(); + virtual void updateSyncViews(); + signals: void vpTransformationStarted(OCCViewer_ViewWindow::OperationType type); void vpTransformationFinished(OCCViewer_ViewWindow::OperationType type); diff --git a/src/OCCViewer/resources/OCCViewer_images.ts b/src/OCCViewer/resources/OCCViewer_images.ts index 40bb07511..21c1ae705 100644 --- a/src/OCCViewer/resources/OCCViewer_images.ts +++ b/src/OCCViewer/resources/OCCViewer_images.ts @@ -123,5 +123,9 @@ ICON_OCCVIEWER_MINIMIZE occ_view_minimized.png + + ICON_OCCVIEWER_SYNC + occ_view_sync.png + diff --git a/src/OCCViewer/resources/OCCViewer_msg_en.ts b/src/OCCViewer/resources/OCCViewer_msg_en.ts index 6b065ead4..6ad0d76d3 100644 --- a/src/OCCViewer/resources/OCCViewer_msg_en.ts +++ b/src/OCCViewer/resources/OCCViewer_msg_en.ts @@ -283,6 +283,10 @@ DSC_MINIMIZE_VIEW Minimize view + + DSC_SYNCHRONIZE_VIEW + Synchronize view + MNU_MAXIMIZE_VIEW Maximize @@ -291,6 +295,14 @@ MNU_MINIMIZE_VIEW Minimize + + MNU_SYNCHRONIZE_VIEW + Synchronize + + + MNU_SYNC_NO_VIEW + [ No appropriate view ] + OCCViewer_CreateRestoreViewDlg diff --git a/src/OCCViewer/resources/occ_view_sync.png b/src/OCCViewer/resources/occ_view_sync.png new file mode 100755 index 0000000000000000000000000000000000000000..32b95228a8b97c791405a2b82d9a472aecf37c1b GIT binary patch literal 627 zcmV-(0*w8MP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipl4 z3JE46$lxyk00Hw!L_t(I%axR|Yuiu|hrcs|q>D9Vh|v%-G{c)ab#!py(IJZ|9ZL-{ zT?!Gz7(=1zR7?UIv;-Fn?XJZ`2qaW<|A643OX;AxLnshQR>$Nc0wC)uoT|!)0R%9aLf=&G|T-TmeK{i{-N-Eru*LP^!6(1GJI z@L~WeWuM>gon^2xwZ5;YJ5CD4_f>WeR$BDr^*gqA_cC=UEdTDhV*{Yn7=Tfl&p9Cj zZtw2#`^Wc!l00mYUuV5)EjnBlTU$GGxxt?ua9)7tL8?&eU?ra{^Q+bY79bZFZ?j|+ z$Aw#+7Mgs`>}>N& ) const = 0; signals: void applicationClosed( SUIT_Application* ); diff --git a/src/SVTK/Makefile.am b/src/SVTK/Makefile.am index 6a3f71fcf..f7f57dccd 100755 --- a/src/SVTK/Makefile.am +++ b/src/SVTK/Makefile.am @@ -132,7 +132,8 @@ dist_salomeres_DATA=\ resources/vtk_view_recording_start.png \ resources/vtk_view_recording_play.png \ resources/vtk_view_recording_pause.png \ - resources/vtk_view_recording_stop.png + resources/vtk_view_recording_stop.png \ + resources/vtk_view_sync.png nodist_salomeres_DATA = \ SVTK_msg_en.qm \ diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index dab457576..1a853416b 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -28,6 +28,7 @@ #include "SALOME_Actor.h" +#include #include #include #include @@ -55,6 +56,7 @@ #include "SUIT_ResourceMgr.h" #include "SUIT_Accel.h" #include "SUIT_OverrideCursor.h" +#include "SUIT_ViewManager.h" #include "QtxActionToolMgr.h" #include "QtxMultiAction.h" @@ -1422,7 +1424,7 @@ void SVTK_ViewWindow::setVisualParameters( const QString& parameters ) /*! The method restores visual parameters of this view from a formated string */ -void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters ) +void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters, bool baseParamsOnly ) { double pos[3], focalPnt[3], viewUp[3], parScale, scale[3]; @@ -1455,24 +1457,33 @@ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters ) scale[1] = aAttr.value("Y").toString().toDouble(); scale[2] = aAttr.value("Z").toString().toDouble(); //printf("#### ViewScale %f; %f; %f\n", scale[0], scale[1], scale[2]); - } else if (aReader.name() == "DisplayCubeAxis") { - if (aAttr.value("Show") == "0") - gradAxesActor->VisibilityOff(); - else - gradAxesActor->VisibilityOn(); - } else if (aReader.name() == "GraduatedAxis") { - if(aAttr.value("Axis") == "X") - setGradAxisVisualParams(aReader, gradAxesActor->GetXAxisActor2D()); - else if(aAttr.value("Axis") == "Y") - setGradAxisVisualParams(aReader, gradAxesActor->GetYAxisActor2D()); - else if(aAttr.value("Axis") == "Z") - setGradAxisVisualParams(aReader, gradAxesActor->GetZAxisActor2D()); - } else if (aReader.name() == "Trihedron") { - if (aAttr.value("isShown") == "0") - GetTrihedron()->VisibilityOff(); - else - GetTrihedron()->VisibilityOn(); - SetTrihedronSize(aAttr.value("Size").toString().toDouble()); + } + else if (aReader.name() == "DisplayCubeAxis") { + if ( !baseParamsOnly ) { + if (aAttr.value("Show") == "0") + gradAxesActor->VisibilityOff(); + else + gradAxesActor->VisibilityOn(); + } + } + else if (aReader.name() == "GraduatedAxis") { + if ( !baseParamsOnly ) { + if(aAttr.value("Axis") == "X") + setGradAxisVisualParams(aReader, gradAxesActor->GetXAxisActor2D()); + else if(aAttr.value("Axis") == "Y") + setGradAxisVisualParams(aReader, gradAxesActor->GetYAxisActor2D()); + else if(aAttr.value("Axis") == "Z") + setGradAxisVisualParams(aReader, gradAxesActor->GetZAxisActor2D()); + } + } + else if (aReader.name() == "Trihedron") { + if ( !baseParamsOnly ) { + if (aAttr.value("isShown") == "0") + GetTrihedron()->VisibilityOff(); + else + GetTrihedron()->VisibilityOn(); + SetTrihedronSize(aAttr.value("Size").toString().toDouble()); + } } } } @@ -1483,7 +1494,8 @@ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters ) camera->SetViewUp( viewUp ); camera->SetParallelScale( parScale ); SetScale( scale ); - } else { + } + else { QStringList paramsLst = parameters.split( '*' ); if ( paramsLst.size() >= nNormalParams ) { // 'reading' list of parameters @@ -1510,26 +1522,29 @@ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters ) SetScale( scale ); // apply graduated axes parameters - SVTK_CubeAxesActor2D* gradAxesActor = GetCubeAxes(); - if ( gradAxesActor && paramsLst.size() == nAllParams ) { - int i = nNormalParams+1, j = i + nGradAxisParams - 1; - ::setGradAxisVisualParams( gradAxesActor->GetXAxisActor2D(), parameters.section( '*', i, j ) ); - i = j + 1; j += nGradAxisParams; - ::setGradAxisVisualParams( gradAxesActor->GetYAxisActor2D(), parameters.section( '*', i, j ) ); - i = j + 1; j += nGradAxisParams; - ::setGradAxisVisualParams( gradAxesActor->GetZAxisActor2D(), parameters.section( '*', i, j ) ); + if ( !baseParamsOnly ) { + SVTK_CubeAxesActor2D* gradAxesActor = GetCubeAxes(); + if ( gradAxesActor && paramsLst.size() == nAllParams ) { + int i = nNormalParams+1, j = i + nGradAxisParams - 1; + ::setGradAxisVisualParams( gradAxesActor->GetXAxisActor2D(), parameters.section( '*', i, j ) ); + i = j + 1; j += nGradAxisParams; + ::setGradAxisVisualParams( gradAxesActor->GetYAxisActor2D(), parameters.section( '*', i, j ) ); + i = j + 1; j += nGradAxisParams; + ::setGradAxisVisualParams( gradAxesActor->GetZAxisActor2D(), parameters.section( '*', i, j ) ); - if ( paramsLst[13].toUShort() ) - gradAxesActor->VisibilityOn(); - else - gradAxesActor->VisibilityOff(); - } else if ( paramsLst.size() == nAllParams ) { - if ( paramsLst[90].toUShort() ) - GetTrihedron()->VisibilityOn(); - else - GetTrihedron()->VisibilityOff(); + if ( paramsLst[13].toUShort() ) + gradAxesActor->VisibilityOn(); + else + gradAxesActor->VisibilityOff(); + } + else if ( paramsLst.size() == nAllParams ) { + if ( paramsLst[90].toUShort() ) + GetTrihedron()->VisibilityOn(); + else + GetTrihedron()->VisibilityOff(); - SetTrihedronSize(paramsLst[91].toDouble()); + SetTrihedronSize(paramsLst[91].toDouble()); + } } } } @@ -1825,6 +1840,16 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr) connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onViewParameters(bool))); 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 ) ); + connect(anAction->menu(), SIGNAL(aboutToShow()), this, SLOT(updateSyncViews())); + connect(anAction, SIGNAL(triggered()), this, SLOT(onSynchronizeView())); + mgr->registerAction( anAction, SynchronizeId ); + // Switch between interaction styles anAction = new QtxAction(tr("MNU_SVTK_STYLE_SWITCH"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_STYLE_SWITCH" ) ), @@ -1925,7 +1950,10 @@ void SVTK_ViewWindow::createToolBar() mgr->append( GraduatedAxes, myToolBar ); mgr->append( ViewParametersId, myToolBar ); + mgr->append( SynchronizeId, myToolBar ); + mgr->append( toolMgr()->separator(), myToolBar ); + mgr->append( ParallelModeId, myToolBar ); mgr->append( ProjectionModeId, myToolBar ); @@ -2098,3 +2126,61 @@ void SVTK_ViewWindow::hideEvent( QHideEvent * theEvent ) emit Hide( theEvent ); } +/*! + "Synchronize View" action slot. +*/ +void SVTK_ViewWindow::onSynchronizeView() +{ + QAction* a = qobject_cast( sender() ); + if ( a ) { + int id = a->data().toInt(); + if ( id != 0 ) { + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( !app ) return; + QList wmlist; + app->viewManagers( getViewManager()->getType(), wmlist ); + foreach( SUIT_ViewManager* wm, wmlist ) { + QVector vwlist = wm->getViews(); + foreach ( SUIT_ViewWindow* vw, vwlist ) { + SVTK_ViewWindow* vtkVW = dynamic_cast( vw ); + if ( vtkVW && vtkVW->getId() == id && vtkVW != this ) { + // perform synchronization + doSetVisualParameters( vtkVW->getVisualParameters(), true ); + } + } + } + + if ( a != toolMgr()->action( SynchronizeId ) ) + toolMgr()->action( SynchronizeId )->setData( id ); + } + } +} + +/*! + Update list of available view for the "Synchronize View" action +*/ +void SVTK_ViewWindow::updateSyncViews() +{ + QAction* anAction = toolMgr()->action( SynchronizeId ); + if ( anAction && anAction->menu() ) { + anAction->menu()->clear(); + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( app ) { + QList wmlist; + app->viewManagers( getViewManager()->getType(), wmlist ); + foreach( SUIT_ViewManager* wm, wmlist ) { + QVector vwlist = wm->getViews(); + foreach ( SUIT_ViewWindow* vw, vwlist ) { + SVTK_ViewWindow* vtkVW = dynamic_cast( vw ); + if ( !vtkVW || vtkVW == this ) continue; + QAction* a = anAction->menu()->addAction( vtkVW->windowTitle() ); + a->setData( vtkVW->getId() ); + connect( a, SIGNAL( triggered() ), this, SLOT( onSynchronizeView() ) ); + } + } + } + if ( anAction->menu()->actions().isEmpty() ) { + anAction->menu()->addAction( tr( "MNU_SYNC_NO_VIEW" ) ); + } + } +} diff --git a/src/SVTK/SVTK_ViewWindow.h b/src/SVTK/SVTK_ViewWindow.h index fddddef2e..24f29d9aa 100755 --- a/src/SVTK/SVTK_ViewWindow.h +++ b/src/SVTK/SVTK_ViewWindow.h @@ -307,6 +307,9 @@ public slots: void onPauseRecording(); void onStopRecording(); + void onSynchronizeView(); + void updateSyncViews(); + signals: void selectionChanged(); void actorAdded(VTKViewer_Actor*); @@ -367,7 +370,7 @@ protected: virtual void Initialize(SVTK_View* theView, SVTK_ViewModelBase* theModel); - void doSetVisualParameters( const QString& ); + void doSetVisualParameters( const QString&, bool = false ); void SetEventDispatcher(vtkObject* theDispatcher); QImage dumpViewContent(); @@ -385,7 +388,7 @@ protected: ChangeRotationPointId, RotationId, FrontId, BackId, TopId, BottomId, LeftId, RightId, ClockWiseId, AntiClockWiseId, ResetId, ViewTrihedronId, NonIsometric, GraduatedAxes, UpdateRate, - ParallelModeId, ProjectionModeId, ViewParametersId, SwitchInteractionStyleId, + ParallelModeId, ProjectionModeId, ViewParametersId, SynchronizeId, SwitchInteractionStyleId, SwitchZoomingStyleId, StartRecordingId, PlayRecordingId, PauseRecordingId, StopRecordingId }; diff --git a/src/SVTK/resources/SVTK_images.ts b/src/SVTK/resources/SVTK_images.ts index 8ac1e43a1..c2afa1b8e 100644 --- a/src/SVTK/resources/SVTK_images.ts +++ b/src/SVTK/resources/SVTK_images.ts @@ -55,5 +55,9 @@ ICON_SVTK_RECORDING_STOP vtk_view_recording_stop.png + + ICON_SVTK_SYNCHRONIZE + vtk_view_sync.png + diff --git a/src/SVTK/resources/SVTK_msg_en.ts b/src/SVTK/resources/SVTK_msg_en.ts index d76686531..d5ef2af33 100644 --- a/src/SVTK/resources/SVTK_msg_en.ts +++ b/src/SVTK/resources/SVTK_msg_en.ts @@ -179,6 +179,18 @@ DSC_VIEWPARAMETERS_VIEW Change the parameters of the view + + MNU_SYNCHRONIZE_VIEW + Synchronize + + + DSC_SYNCHRONIZE_VIEW + Synchronize view + + + MNU_SYNC_NO_VIEW + [ No appropriate view ] + MNU_SVTK_PARALLEL_MODE Orthogonal Mode diff --git a/src/SVTK/resources/vtk_view_sync.png b/src/SVTK/resources/vtk_view_sync.png new file mode 100755 index 0000000000000000000000000000000000000000..32b95228a8b97c791405a2b82d9a472aecf37c1b GIT binary patch literal 627 zcmV-(0*w8MP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipl4 z3JE46$lxyk00Hw!L_t(I%axR|Yuiu|hrcs|q>D9Vh|v%-G{c)ab#!py(IJZ|9ZL-{ zT?!Gz7(=1zR7?UIv;-Fn?XJZ`2qaW<|A643OX;AxLnshQR>$Nc0wC)uoT|!)0R%9aLf=&G|T-TmeK{i{-N-Eru*LP^!6(1GJI z@L~WeWuM>gon^2xwZ5;YJ5CD4_f>WeR$BDr^*gqA_cC=UEdTDhV*{Yn7=Tfl&p9Cj zZtw2#`^Wc!l00mYUuV5)EjnBlTU$GGxxt?ua9)7tL8?&eU?ra{^Q+bY79bZFZ?j|+ z$Aw#+7Mgs`>}>N