///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2015- Statoil ASA // Copyright (C) 2015- Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RimViewLinker.h" #include "RiaOptionItemFactory.h" #include "RigFemResultAddress.h" #include "RigMainGrid.h" #include "Rim3dView.h" #include "RimCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseInputCase.h" #include "RimEclipseResultCase.h" #include "RimEclipseResultDefinition.h" #include "RimEclipseView.h" #include "RimGeoMechCase.h" #include "RimGeoMechCellColors.h" #include "RimGeoMechResultDefinition.h" #include "RimGeoMechView.h" #include "RimIntersectionCollection.h" #include "RimProject.h" #include "RimRegularLegendConfig.h" #include "RimTernaryLegendConfig.h" #include "RimViewController.h" #include "RimViewLinkerCollection.h" #include "RimViewManipulator.h" #include "RiuViewer.h" #include "cafIconProvider.h" #include "cafPdmUiTreeOrdering.h" #include "cvfCamera.h" #include "cvfScene.h" CAF_PDM_SOURCE_INIT( RimViewLinker, "ViewLinker" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimViewLinker::RimViewLinker() { CAF_PDM_InitObject( "Linked Views" ); CAF_PDM_InitField( &m_name, "Name", QString( "View Group Name" ), "View Group Name" ); m_name.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &m_masterView, "MainView", "Main View" ); m_masterView.uiCapability()->setUiTreeChildrenHidden( true ); m_masterView.uiCapability()->setUiTreeHidden( true ); m_masterView.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &m_viewControllers, "ManagedViews", "Managed Views" ); m_viewControllers.uiCapability()->setUiTreeHidden( true ); m_viewControllers.uiCapability()->setUiTreeChildrenHidden( true ); setDeletable( true ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimViewLinker::~RimViewLinker() { removeOverrides(); m_viewControllers.deleteChildren(); auto masterView = m_masterView(); m_masterView = nullptr; if ( masterView ) masterView->updateAutoName(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateTimeStep( Rim3dView* sourceView, int timeStep ) { CVF_ASSERT( sourceView ); if ( !isActive() ) return; if ( masterView() != sourceView ) { RimViewController* sourceViewLink = sourceView->viewController(); CVF_ASSERT( sourceViewLink ); if ( !sourceViewLink->isTimeStepLinked() ) { return; } } if ( m_masterView && m_masterView->viewer() && sourceView != m_masterView ) { m_masterView->viewer()->setCurrentFrame( timeStep ); } for ( RimViewController* viewController : m_viewControllers ) { if ( !viewController->isTimeStepLinked() ) continue; if ( viewController->managedView() && viewController->managedView() != sourceView && viewController->managedView()->viewer() ) { viewController->managedView()->viewer()->setCurrentFrame( timeStep ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateCellResult() { Rim3dView* rimView = m_masterView; RimEclipseView* masterEclipseView = dynamic_cast( rimView ); if ( masterEclipseView && masterEclipseView->cellResult() ) { RimEclipseResultDefinition* eclipseCellResultDefinition = masterEclipseView->cellResult(); for ( RimViewController* viewController : m_viewControllers ) { if ( viewController->managedView() ) { Rim3dView* managedView = viewController->managedView(); RimEclipseView* eclipseView = dynamic_cast( managedView ); if ( eclipseView ) { if ( viewController->isResultColorControlled() ) { eclipseView->cellResult()->simpleCopy( eclipseCellResultDefinition ); eclipseView->cellResult()->loadResult(); if ( viewController->isLegendDefinitionsControlled() ) { eclipseView->cellResult()->legendConfig()->setUiValuesFromLegendConfig( masterEclipseView->cellResult()->legendConfig() ); eclipseView->cellResult()->legendConfig()->updateLegend(); eclipseView->cellResult()->ternaryLegendConfig()->setUiValuesFromLegendConfig( masterEclipseView->cellResult()->ternaryLegendConfig() ); } eclipseView->scheduleCreateDisplayModelAndRedraw(); eclipseView->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } eclipseView->cellResult()->updateIconState(); } } } } RimGeoMechView* masterGeoView = dynamic_cast( rimView ); if ( masterGeoView && masterGeoView->cellResult() ) { RimGeoMechResultDefinition* geoMechResultDefinition = masterGeoView->cellResult(); for ( RimViewController* viewController : m_viewControllers ) { if ( viewController->managedView() ) { Rim3dView* managedView = viewController->managedView(); RimGeoMechView* geoView = dynamic_cast( managedView ); if ( geoView ) { if ( viewController->isResultColorControlled() ) { geoView->cellResult()->setResultAddress( geoMechResultDefinition->resultAddress() ); if ( viewController->isLegendDefinitionsControlled() ) { geoView->cellResult()->legendConfig()->setUiValuesFromLegendConfig( masterGeoView->cellResult()->legendConfig() ); geoView->cellResult()->legendConfig()->updateLegend(); } geoView->scheduleCreateDisplayModelAndRedraw(); geoView->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } geoView->cellResult()->updateIconState(); } } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateCellFilters( const RimCellFilter* changedFilter ) { for ( RimViewController* viewController : m_viewControllers ) { viewController->updateCellFilterOverrides( changedFilter ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateOverrides() { for ( RimViewController* viewController : m_viewControllers ) { if ( viewController->isActive() ) { viewController->updateOverrides(); } else { viewController->removeOverrides(); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateWindowTitles() { if ( m_masterView ) m_masterView->updateMdiWindowTitle(); for ( RimViewController* viewController : m_viewControllers ) { if ( auto view = viewController->managedView() ) { view->updateMdiWindowTitle(); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateDuplicatedPropertyFilters() { for ( RimViewController* viewController : m_viewControllers ) { viewController->updateDuplicatedPropertyFilters(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::removeOverrides() { for ( const auto& viewController : m_viewControllers ) { if ( viewController->managedView() ) { viewController->removeOverrides(); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateScaleWidgetVisibility() { // Create new display model that will call RimEclipseContourMapView::onUpdateLegends() where the visibility of scale // widgets is controlled if ( masterView() ) masterView()->scheduleCreateDisplayModelAndRedraw(); for ( RimViewController* viewController : m_viewControllers ) { if ( viewController->managedView() ) { viewController->managedView()->scheduleCreateDisplayModelAndRedraw(); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::allViewsForCameraSync( const Rim3dView* source, std::vector& views ) const { if ( !isActive() ) return; if ( source != m_masterView() ) { views.push_back( m_masterView() ); } for ( const auto& viewController : m_viewControllers ) { if ( viewController->managedView() && source != viewController->managedView() ) { if ( viewController->isCameraLinked() ) { views.push_back( viewController->managedView() ); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateDependentViews() { if ( m_viewControllers.empty() ) return; updateOverrides(); updateDuplicatedPropertyFilters(); updateCellResult(); updateScaleZ( m_masterView, m_masterView->scaleZ() ); updateCamera( m_masterView ); updateTimeStep( m_masterView, m_masterView->currentTimeStep() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimViewLinker::displayNameForView( Rim3dView* view ) { QString displayName = "None"; if ( view ) { displayName = view->autoName(); } return displayName; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::setMasterView( Rim3dView* view ) { RimViewController* previousViewController = nullptr; if ( view ) previousViewController = view->viewController(); // Remove the view as dependent view if ( previousViewController ) { delete previousViewController; m_viewControllers.removeChild( nullptr ); } removeOverrides(); m_masterView = view; updateUiNameAndIcon(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- Rim3dView* RimViewLinker::masterView() const { return m_masterView; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimViewLinker::allViews() const { std::vector views; views.push_back( m_masterView() ); for ( const auto& viewController : m_viewControllers ) { if ( viewController->managedView() ) { views.push_back( viewController->managedView() ); } } return views; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::initAfterRead() { updateUiNameAndIcon(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateScaleZ( Rim3dView* sourceView, double scaleZ ) { if ( !isActive() ) return; if ( masterView() != sourceView ) { RimViewController* sourceViewLink = sourceView->viewController(); CVF_ASSERT( sourceViewLink ); if ( !sourceViewLink->isCameraLinked() ) { return; } } std::vector views; allViewsForCameraSync( sourceView, views ); // Make sure scale factors are identical for ( auto& view : views ) { view->setScaleZAndUpdate( scaleZ ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimViewLinker::isActive() const { RimViewLinkerCollection* viewLinkerCollection = firstAncestorOrThisOfType(); if ( !viewLinkerCollection ) { // This will happen when the all linked views are about to be deleted // The viewLinker is taken out of the viewLinkerCollection, and no parent can be found // See RicDeleteAllLinkedViewsFeature return false; } return viewLinkerCollection->isActive(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateUiNameAndIcon() { caf::IconProvider iconProvider; QString name; RimViewLinker::findNameAndIconFromView( &name, &iconProvider, m_masterView ); name += " (Primary)"; m_name.v() = name; if ( m_masterView ) m_masterView->updateAutoName(); setUiIcon( iconProvider ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::scheduleGeometryRegenForDepViews( RivCellSetEnum geometryType ) { for ( const auto& viewController : m_viewControllers ) { viewController->scheduleGeometryRegenForDepViews( geometryType ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::scheduleCreateDisplayModelAndRedrawForDependentViews() { for ( const auto& viewController : m_viewControllers ) { viewController->scheduleCreateDisplayModelAndRedrawForDependentView(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::findNameAndIconFromView( QString* name, caf::IconProvider* icon, Rim3dView* view ) { CVF_ASSERT( name && icon ); if ( view ) { *name = displayNameForView( view ); *icon = view->uiIconProvider(); } else { *icon = caf::IconProvider(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateCursorPosition( const Rim3dView* sourceView, const cvf::Vec3d& domainCoord ) { RimViewController* sourceViewLink = sourceView->viewController(); if ( sourceViewLink && !sourceViewLink->showCursor() ) { return; } std::vector viewsToUpdate; allViewsForCameraSync( sourceView, viewsToUpdate ); for ( Rim3dView* destinationView : viewsToUpdate ) { if ( destinationView == sourceView ) continue; if ( destinationView != m_masterView ) { RimViewController* viewLink = destinationView->viewController(); if ( !viewLink ) continue; if ( !viewLink->showCursor() ) continue; } RiuViewer* destinationViewer = destinationView->viewer(); if ( destinationViewer ) { destinationViewer->setCursorPosition( domainCoord ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector& referringObjects ) { RimViewLinkerCollection* viewLinkerCollection = firstAncestorOrThisOfType(); if ( viewLinkerCollection ) viewLinkerCollection->updateConnectedEditors(); updateScaleWidgetVisibility(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QList RimViewLinker::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) { QList options; Rim3dView* actualComparisonView = nullptr; if ( m_masterView() ) { actualComparisonView = m_masterView->activeComparisonView(); } bool isActiveCompViewInList = false; for ( const auto& viewController : m_viewControllers ) { if ( viewController->managedView() ) { RiaOptionItemFactory::appendOptionItemFromViewNameAndCaseName( viewController->managedView(), &options ); if ( viewController->managedView() == actualComparisonView ) { isActiveCompViewInList = true; } } } if ( !isActiveCompViewInList && actualComparisonView != nullptr ) { // Add the actually used comparison view to the option list, even though it is not one of the linked views options.push_front( caf::PdmOptionItemInfo( actualComparisonView->autoName(), actualComparisonView, false, actualComparisonView->uiCapability()->uiIconProvider() ) ); } options.push_front( caf::PdmOptionItemInfo( "None", nullptr ) ); return options; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateCamera( Rim3dView* sourceView ) { if ( !sourceView || !sourceView->viewer() ) return; if ( !isActive() ) return; RimViewController* viewLink = sourceView->viewController(); if ( viewLink ) { if ( !viewLink->isCameraLinked() ) { return; } } std::vector viewsToUpdate; allViewsForCameraSync( sourceView, viewsToUpdate ); RimViewManipulator::applySourceViewCameraOnDestinationViews( sourceView, viewsToUpdate ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::addDependentView( Rim3dView* view ) { CVF_ASSERT( view && view != m_masterView ); if ( !view->viewController() ) { RimViewController* viewContr = new RimViewController; m_viewControllers.push_back( viewContr ); viewContr->setManagedView( view ); } updateScaleWidgetVisibility(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimViewLinker::isFirstViewDependentOnSecondView( const Rim3dView* firstView, const Rim3dView* secondView ) const { for ( const RimViewController* controller : m_viewControllers() ) { if ( controller->masterView() == secondView && controller->managedView() == firstView ) { return true; } } return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::addViewControllers( caf::PdmUiTreeOrdering& uiTreeOrdering ) const { for ( const auto& viewController : m_viewControllers ) { if ( viewController ) uiTreeOrdering.add( viewController ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::applyCellFilterCollectionByUserChoice() { for ( const auto& viewController : m_viewControllers ) { viewController->applyCellFilterCollectionByUserChoice(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updatePropertyFilters( RimPropertyFilter* changedPropertyFilter ) { for ( RimViewController* viewLink : m_viewControllers ) { viewLink->updatePropertyFilterOverrides( changedPropertyFilter ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimViewLinker::removeViewController( RimViewController* viewController ) { m_viewControllers.removeChild( viewController ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- Rim3dView* RimViewLinker::firstControlledView() { if ( m_viewControllers.empty() ) return nullptr; return m_viewControllers[0]->managedView(); }