+ SUIT_CameraProperties props = cameraProperties();
+ if ( !props.isValid() )
+ return;
+
+ QAction* anAction = synchronizeAction();
+ if ( anAction && anAction->menu() ) {
+ int currentId = anAction->data().toInt();
+ anAction->menu()->clear();
+ SUIT_Application* app = SUIT_Session::session()->activeApplication();
+ if ( app ) {
+ SUIT_Desktop* d = app->desktop();
+ QList<SUIT_ViewWindow*> allViews = qFindChildren<SUIT_ViewWindow*>( d );
+ foreach( SUIT_ViewWindow* vw, allViews ) {
+ if ( !vw || vw == this ) continue; // skip invalid views and this one
+ SUIT_CameraProperties otherProps = vw->cameraProperties();
+ if ( otherProps.isCompatible( props ) ) {
+ QAction* a = anAction->menu()->addAction( vw->windowTitle() );
+ if ( vw->getId() == currentId ) {
+ QFont f = a->font();
+ f.setBold( true );
+ a->setFont( f );
+ }
+ a->setData( vw->getId() );
+ connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onSynchronizeView( bool ) ) );
+ }
+ else if ( vw->getId() == currentId ) {
+ // other view, this one is being currently synchronized to, seems has become incompatible
+ // we have to break synchronization
+ vw->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), this, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ this->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), vw, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ //
+ bool blocked = anAction->blockSignals( true );
+ anAction->setChecked( false );
+ anAction->blockSignals( blocked );
+ anAction->setData( 0 );
+ //
+ QAction* a = vw->synchronizeAction();
+ if ( a ) {
+ blocked = a->blockSignals( true );
+ a->setChecked( false );
+ a->blockSignals( blocked );
+ }
+ }
+ }
+ }
+ if ( anAction->menu()->actions().isEmpty() ) {
+ anAction->setData( 0 );
+ anAction->menu()->addAction( tr( "MNU_SYNC_NO_VIEW" ) );
+ }
+ }
+}
+
+/*!
+ "Synchronize View" action slot.
+*/
+void SUIT_ViewWindow::onSynchronizeView( bool checked )
+{
+ QAction* a = qobject_cast<QAction*>( sender() );
+ if ( a ) {
+ synchronizeView( this, a->data().toInt() );
+ }
+}
+
+/*!
+ Synchronize camera properties of view \a viewWindow with
+ camera properties of view specified via \a id
+*/
+void SUIT_ViewWindow::synchronizeView( SUIT_ViewWindow* viewWindow, int id )
+{
+ SUIT_ViewWindow* sourceView = 0;
+ QList<SUIT_ViewWindow*> otherViews;
+
+ bool isSync = viewWindow->synchronizeAction() && viewWindow->synchronizeAction()->isChecked();
+
+ int vwid = viewWindow->getId();
+
+ SUIT_Application* app = SUIT_Session::session()->activeApplication();
+ if ( !app ) return;
+ SUIT_Desktop* d = app->desktop();
+ if ( !d ) return;
+
+ QList<SUIT_ViewWindow*> allViews = qFindChildren<SUIT_ViewWindow*>( d );
+ foreach( SUIT_ViewWindow* vw, allViews ) {
+ if ( !vw->cameraProperties().isValid() )
+ continue; // omit views not supporting camera properties
+ if ( vw->getId() == id )
+ sourceView = vw; // remember source view
+ else if ( vw != viewWindow )
+ otherViews.append( vw ); // collect all remaining views
+ }
+
+ if ( isSync && id ) {
+ // remove all possible disconnections
+ foreach( SUIT_ViewWindow* vw, otherViews ) {
+ // disconnect target view
+ vw->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), viewWindow, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ viewWindow->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), vw, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ if ( sourceView ) {
+ // disconnect source view
+ vw->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), sourceView, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ sourceView->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), vw, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ }
+ QAction* a = vw->synchronizeAction();
+ 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 ( sourceView ) {
+ // reconnect source and target views
+ sourceView->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), viewWindow, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ viewWindow->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), sourceView, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ sourceView->connect( viewWindow, SIGNAL( viewModified( SUIT_ViewWindow* ) ), SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ viewWindow->connect( sourceView, SIGNAL( viewModified( SUIT_ViewWindow* ) ), SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ // synchronize target view with source view
+ viewWindow->synchronize( sourceView );
+ if ( viewWindow->synchronizeAction() )
+ viewWindow->synchronizeAction()->setData( sourceView->getId() );
+ QAction* sourceAction = sourceView->synchronizeAction();
+ if ( sourceAction ) {
+ sourceAction->setData( viewWindow->getId() );
+ if ( !sourceAction->isChecked() ) {
+ bool blocked = sourceAction->blockSignals( true );
+ sourceAction->setChecked( true );
+ sourceAction->blockSignals( blocked );
+ }
+ }
+ }
+ }
+ else if ( sourceView ) {
+ // reconnect source and target view
+ sourceView->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), viewWindow, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ viewWindow->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), sourceView, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+ viewWindow->synchronize( sourceView );
+ if ( viewWindow->synchronizeAction() )
+ viewWindow->synchronizeAction() ->setData( sourceView->getId() );
+ QAction* sourceAction = sourceView->synchronizeAction();
+ if ( sourceAction ) {
+ if ( sourceAction->data().toInt() == viewWindow->getId() && sourceAction->isChecked() ) {
+ bool blocked = sourceAction->blockSignals( true );
+ sourceAction->setChecked( false );
+ sourceAction->blockSignals( blocked );
+ }
+ }
+ }