From 08f4bf79de4b41f7682918b159c56ddcb171b5d0 Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 29 Sep 2011 12:48:47 +0000 Subject: [PATCH] 0021319: EDF 1616 ALL: synchronization of 3D viewers --- src/OCCViewer/OCCViewer_ViewPort.cxx | 10 ++ src/OCCViewer/OCCViewer_ViewPort.h | 4 + src/OCCViewer/OCCViewer_ViewPort3d.cxx | 35 ++++++- src/OCCViewer/OCCViewer_ViewPort3d.h | 3 + src/OCCViewer/OCCViewer_ViewWindow.cxx | 123 +++++++++++++++++++------ src/OCCViewer/OCCViewer_ViewWindow.h | 10 +- 6 files changed, 151 insertions(+), 34 deletions(-) diff --git a/src/OCCViewer/OCCViewer_ViewPort.cxx b/src/OCCViewer/OCCViewer_ViewPort.cxx index 1c7917b72..ea81421cb 100755 --- a/src/OCCViewer/OCCViewer_ViewPort.cxx +++ b/src/OCCViewer/OCCViewer_ViewPort.cxx @@ -490,6 +490,16 @@ QPaintEngine* OCCViewer_ViewPort::paintEngine() const } }*/ +/*! + Performs synchronization of view parameters with the specified view. + Returns \c true if synchronization is done successfully or \c false otherwise. + Default implementation does nothing (return \c false) +*/ +bool OCCViewer_ViewPort::synchronize( OCCViewer_ViewPort* ) +{ + return false; +} + /*! Sets the background color with color selection dialog. [ virtual protected slot ] */ diff --git a/src/OCCViewer/OCCViewer_ViewPort.h b/src/OCCViewer/OCCViewer_ViewPort.h index ba3938b32..69b80490b 100755 --- a/src/OCCViewer/OCCViewer_ViewPort.h +++ b/src/OCCViewer/OCCViewer_ViewPort.h @@ -95,6 +95,9 @@ protected: // void onCreatePopup( QPopupMenu* ); // void onDestroyPopup( QPopupMenu* ); +public slots: + virtual bool synchronize( OCCViewer_ViewPort* ); + protected slots: virtual void onChangeBgColor(); @@ -103,6 +106,7 @@ signals: void vpMouseEvent( QMouseEvent* ); void vpDrawExternal( QPainter* ); void vpChangeBGColor( QColor ); + void vpTransformed( OCCViewer_ViewPort* ); private: void initialize(); diff --git a/src/OCCViewer/OCCViewer_ViewPort3d.cxx b/src/OCCViewer/OCCViewer_ViewPort3d.cxx index 06801b37a..ed188195a 100755 --- a/src/OCCViewer/OCCViewer_ViewPort3d.cxx +++ b/src/OCCViewer/OCCViewer_ViewPort3d.cxx @@ -330,8 +330,10 @@ void OCCViewer_ViewPort3d::onUpdate() */ void OCCViewer_ViewPort3d::fitRect( const QRect& rect ) { - if ( !activeView().IsNull() ) + if ( !activeView().IsNull() ) { activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() ); + emit vpTransformed( this ); + } } /*! @@ -360,6 +362,7 @@ void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y ) else #endif activeView()->Zoom( x0 + y0, 0, x + y, 0 ); + emit vpTransformed( this ); } } @@ -368,8 +371,10 @@ void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y ) */ void OCCViewer_ViewPort3d::setCenter( int x, int y ) { - if ( !activeView().IsNull() ) + if ( !activeView().IsNull() ) { activeView()->Place( x, y, myScale ); + emit vpTransformed( this ); + } } /*! @@ -377,8 +382,10 @@ void OCCViewer_ViewPort3d::setCenter( int x, int y ) */ void OCCViewer_ViewPort3d::pan( int dx, int dy ) { - if ( !activeView().IsNull() ) + if ( !activeView().IsNull() ) { activeView()->Pan( dx, dy, 1.0 ); + emit vpTransformed( this ); + } } /*! @@ -462,6 +469,7 @@ void OCCViewer_ViewPort3d::rotate( int x, int y, default: break; } + emit vpTransformed( this ); } // setZSize( getZSize() ); } @@ -478,6 +486,7 @@ void OCCViewer_ViewPort3d::endRotation() activeView()->ZFitAll(1.); activeView()->SetZSize(0.); activeView()->Update(); + emit vpTransformed( this ); } } @@ -530,6 +539,7 @@ void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd ) Standard_Real margin = 0.01; activeView()->FitAll( margin, withZ, upd ); activeView()->SetZSize(0.); + emit vpTransformed( this ); } /*! @@ -538,9 +548,11 @@ void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd ) void OCCViewer_ViewPort3d::reset() { // double zsize = getZSize(); - if ( !activeView().IsNull() ) + if ( !activeView().IsNull() ) { activeView()->Reset(); + emit vpTransformed( this ); // setZSize( zsize ); + } } /*! @@ -555,6 +567,7 @@ void OCCViewer_ViewPort3d::rotateXY( double degrees ) double X, Y, Z; activeView()->Convert( x, y, X, Y, Z ); activeView()->Rotate( 0, 0, degrees * Standard_PI180, X, Y, Z ); + emit vpTransformed( this ); } /*! @@ -612,3 +625,17 @@ bool OCCViewer_ViewPort3d::mapped( const Handle(V3d_View)& view ) const { return ( !view.IsNull() && view->View()->IsDefined() ); } + +/*! + Performs synchronization of view parameters with the specified view. + Returns \c true if synchronization is done successfully or \c false otherwise. + Default implementation does nothing (return \c false) +*/ +bool OCCViewer_ViewPort3d::synchronize( OCCViewer_ViewPort* view ) +{ + bool ok = false; + OCCViewer_ViewPort3d* vp3d = qobject_cast( view ); + if ( vp3d ) ok = syncronize( vp3d ); + return ok; +} + diff --git a/src/OCCViewer/OCCViewer_ViewPort3d.h b/src/OCCViewer/OCCViewer_ViewPort3d.h index 7eccb6c43..4ea26c854 100755 --- a/src/OCCViewer/OCCViewer_ViewPort3d.h +++ b/src/OCCViewer/OCCViewer_ViewPort3d.h @@ -86,6 +86,9 @@ public: void setAdvancedZoomingEnabled( const bool theState ) { myIsAdvancedZoomingEnabled = theState; } bool isAdvancedZoomingEnabled() const { return myIsAdvancedZoomingEnabled; } +public slots: + virtual bool synchronize( OCCViewer_ViewPort* ); + protected: // EVENTS virtual void paintEvent( QPaintEvent* ); diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index bc78de401..902558586 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -1232,8 +1232,9 @@ void OCCViewer_ViewWindow::createActions() tr( "MNU_SYNCHRONIZE_VIEW" ), 0, this ); aAction->setStatusTip(tr("DSC_SYNCHRONIZE_VIEW")); aAction->setMenu( new QMenu( this ) ); + aAction->setCheckable(true); connect(aAction->menu(), SIGNAL(aboutToShow()), this, SLOT(updateSyncViews())); - connect(aAction, SIGNAL(triggered()), this, SLOT(onSynchronizeView())); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onSynchronizeView(bool))); toolMgr()->registerAction( aAction, SynchronizeId ); } @@ -2457,36 +2458,99 @@ void OCCViewer_ViewWindow::updateViewAspects( const viewAspectList& aViewList ) myViewAspects = aViewList; } +void OCCViewer_ViewWindow::synchronizeView( OCCViewer_ViewWindow* viewWindow, int id ) +{ + OCCViewer_ViewWindow* otherViewWindow = 0; + QList compatibleViews; + + bool isSync = viewWindow->toolMgr()->action( SynchronizeId )->isChecked(); + + int vwid = viewWindow->getId(); + + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( !app ) return; + + QList wmlist; + app->viewManagers( viewWindow->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; + + // check only compatible types + occVW = occVW->getView( viewWindow->get2dMode() ); + if ( occVW ) { + if ( occVW->getId() == id ) + otherViewWindow = occVW; + else if ( occVW != viewWindow ) + compatibleViews.append( occVW ); + } + } + } + + if ( isSync && id ) { + // remove all possible disconnections + foreach( OCCViewer_ViewWindow* vw, compatibleViews ) { + // disconnect target view + vw->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), viewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) ); + viewWindow->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), vw->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) ); + if ( otherViewWindow ) { + // disconnect source view + vw->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), otherViewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) ); + otherViewWindow->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), vw->getViewPort(), SLOT( synchronize( OCCViewer_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->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), viewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) ); + viewWindow->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), otherViewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) ); + otherViewWindow->getViewPort()->connect( viewWindow->getViewPort(), SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), SLOT( synchronize( OCCViewer_ViewPort* ) ) ); + viewWindow->getViewPort()->connect( otherViewWindow->getViewPort(), SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), SLOT( synchronize( OCCViewer_ViewPort* ) ) ); + // synchronize target view with source view + viewWindow->getViewPort()->synchronize( otherViewWindow->getViewPort() ); + 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->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), viewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) ); + viewWindow->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), otherViewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) ); + viewWindow->getViewPort()->synchronize( otherViewWindow->getViewPort() ); + 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 OCCViewer_ViewWindow::onSynchronizeView() +void OCCViewer_ViewWindow::onSynchronizeView(bool checked) { 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 ); - } + synchronizeView( this, a->data().toInt() ); } } @@ -2497,6 +2561,7 @@ void OCCViewer_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 ) { @@ -2511,13 +2576,19 @@ void OCCViewer_ViewWindow::updateSyncViews() OCCViewer_ViewWindow* subWindow = occVW->getView( get2dMode() ); if ( subWindow && subWindow != this ) { QAction* a = anAction->menu()->addAction( occVW->windowTitle() ); + if ( subWindow->getId() == currentId ) { + QFont f = a->font(); + f.setBold( true ); + a->setFont( f ); + } a->setData( subWindow->getId() ); - connect( a, SIGNAL( triggered() ), this, SLOT( onSynchronizeView() ) ); + 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" ) ); } } diff --git a/src/OCCViewer/OCCViewer_ViewWindow.h b/src/OCCViewer/OCCViewer_ViewWindow.h index 01a393e6b..9717f60ec 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.h +++ b/src/OCCViewer/OCCViewer_ViewWindow.h @@ -186,7 +186,7 @@ public: virtual QString backgroundImageFilename() const; virtual void setBackgroundImage( const QString& ,const Aspect_FillMethod& theFillMethod); - virtual const viewAspectList& getViewAspects(); + virtual const viewAspectList& getViewAspects(); virtual void appendViewAspect( const viewAspect& ); virtual void updateViewAspects( const viewAspectList& ); virtual void clearViewAspects(); @@ -231,9 +231,6 @@ public slots: virtual void onMaximizedView(); - virtual void onSynchronizeView(); - virtual void updateSyncViews(); - signals: void vpTransformationStarted(OCCViewer_ViewWindow::OperationType type); void vpTransformationFinished(OCCViewer_ViewWindow::OperationType type); @@ -313,6 +310,11 @@ protected: double myCurScale; +private slots: + void onSynchronizeView(bool); + void updateSyncViews(); + static void synchronizeView( OCCViewer_ViewWindow*, int ); + private: OCCViewer_ClippingDlg* myClippingDlg; QtxAction* myClippingAction; -- 2.39.2