Introduce RimGridPlotWindow and RiuQwtPlotWidget

This commit is contained in:
Gaute Lindkvist 2019-10-11 15:54:19 +02:00
parent 2857a13e7c
commit c578a43b53
89 changed files with 5249 additions and 3809 deletions

View File

@ -45,18 +45,22 @@ CAF_CMD_SOURCE_INIT( RicExportToLasFileFeature, "RicExportToLasFileFeature" );
//--------------------------------------------------------------------------------------------------
std::vector<QString> RicExportToLasFileFeature::exportToLasFiles( const QString& exportFolder,
const QString& exportPrefix,
const RimWellLogPlot* plot,
const RimWellLogPlot* plotWindow,
bool exportTvdRkb,
bool capitalizeFileNames,
double resampleInterval )
{
std::vector<RimWellLogCurve*> allCurves;
std::vector<RimWellLogTrack*> tracks = plot->visibleTracks();
std::vector<RimWellLogCurve*> allCurves;
std::vector<RimPlotInterface*> plots = plotWindow->visiblePlots();
for ( RimWellLogTrack* track : tracks )
for ( RimPlotInterface* plot : plots )
{
std::vector<RimWellLogCurve*> curves = track->visibleCurvesVector();
allCurves.insert( allCurves.end(), curves.begin(), curves.end() );
RimWellLogTrack* track = dynamic_cast<RimWellLogTrack*>( plot );
if ( track )
{
std::vector<RimWellLogCurve*> curves = track->visibleCurves();
allCurves.insert( allCurves.end(), curves.begin(), curves.end() );
}
}
std::vector<QString> wellNames;

View File

@ -38,7 +38,7 @@ class RicExportToLasFileFeature : public caf::CmdFeature
public:
static std::vector<QString> exportToLasFiles( const QString& exportFolder,
const QString& filePrefix,
const RimWellLogPlot* plot,
const RimWellLogPlot* plotWindow,
bool exportTvdRkb = false,
bool capitalizeFileNames = false,
double resampleInterval = 0.0 );

View File

@ -200,7 +200,7 @@ void RicDeleteItemExec::redo()
if ( wellLogPlot )
{
wellLogPlot->calculateAvailableDepthRange();
wellLogPlot->updateDepthZoom();
wellLogPlot->updateZoom();
RiuPlotMainWindow* mainPlotWindow = RiaGuiApplication::instance()->mainPlotWindow();
mainPlotWindow->updateWellLogPlotToolBar();
}
@ -209,7 +209,8 @@ void RicDeleteItemExec::redo()
parentObj->firstAncestorOrThisOfType( wellLogPlotTrack );
if ( wellLogPlotTrack )
{
wellLogPlotTrack->calculateXZoomRangeAndUpdateQwt();
wellLogPlotTrack->setAutoScaleXEnabled( true );
wellLogPlotTrack->updateZoomInQwt();
RiuPlotMainWindow* mainPlotWindow = RiaGuiApplication::instance()->mainPlotWindow();
mainPlotWindow->updateWellLogPlotToolBar();
}

View File

@ -658,7 +658,7 @@ void RicSummaryCurveCreator::updateTargetPlot()
copyEnsembleCurveAndAddToCurveSet( editedCurve, editedCurveSet );
}
newCurveSet->setParentQwtPlotNoReplot( m_targetPlot->qwtPlot() );
newCurveSet->setParentQwtPlotNoReplot( m_targetPlot->viewer() );
}
m_targetPlot->enableAutoPlotTitle( m_useAutoPlotTitleProxy() );
@ -874,7 +874,7 @@ void RicSummaryCurveCreator::updateCurveNames()
curve->updateCurveNameNoLegendUpdate();
}
if ( m_previewPlot && m_previewPlot->qwtPlot() ) m_previewPlot->qwtPlot()->updateLegend();
if ( m_previewPlot && m_previewPlot->viewer() ) m_previewPlot->viewer()->updateLegend();
}
//--------------------------------------------------------------------------------------------------

View File

@ -13,7 +13,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewWellLogPlotFeatureImpl.h
${CMAKE_CURRENT_LIST_DIR}/RicNewWellLogPlotTrackFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicWellLogPlotCurveFeatureImpl.h
${CMAKE_CURRENT_LIST_DIR}/RicWellLogsImportFileFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellLogPlotTrackFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicDeleteSubPlotFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicWellLogPlotTrackFeatureImpl.h
${CMAKE_CURRENT_LIST_DIR}/RicPasteWellLogCurveFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicPasteWellLogTrackFeature.h
@ -44,7 +44,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewWellLogPlotFeatureImpl.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewWellLogPlotTrackFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicWellLogPlotCurveFeatureImpl.cpp
${CMAKE_CURRENT_LIST_DIR}/RicWellLogsImportFileFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellLogPlotTrackFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicDeleteSubPlotFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicWellLogPlotTrackFeatureImpl.cpp
${CMAKE_CURRENT_LIST_DIR}/RicPasteWellLogCurveFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicPasteWellLogTrackFeature.cpp

View File

@ -37,7 +37,7 @@
#include "RigWellLogFile.h"
#include "RiaApplication.h"
#include "RiuWellLogTrack.h"
#include "RiuQwtPlotWidget.h"
#include "cafSelectionManager.h"
@ -65,8 +65,8 @@ void RicAddWellLogToPlotFeature::onActionTriggered( bool isChecked )
RimWellLogPlot* plot = RicNewWellLogPlotFeatureImpl::createWellLogPlot();
RimWellLogTrack* plotTrack = new RimWellLogTrack();
plot->addTrack( plotTrack );
plotTrack->setDescription( QString( "Track %1" ).arg( plot->trackCount() ) );
plot->addPlot( plotTrack );
plotTrack->setDescription( QString( "Track %1" ).arg( plot->plotCount() ) );
plot->loadDataAndUpdate();
@ -103,9 +103,7 @@ void RicAddWellLogToPlotFeature::onActionTriggered( bool isChecked )
curve->loadDataAndUpdate( true );
}
}
plot->calculateAvailableDepthRange();
plot->updateDepthZoom();
plotTrack->viewer()->replot();
plot->updateLayout();
RiaApplication::instance()->project()->updateConnectedEditors();

View File

@ -17,38 +17,38 @@
//
/////////////////////////////////////////////////////////////////////////////////
#include "RicDeleteWellLogPlotTrackFeature.h"
#include "RicDeleteSubPlotFeature.h"
#include "RicWellLogPlotCurveFeatureImpl.h"
#include "RiaGuiApplication.h"
#include "RiuGridPlotWindow.h"
#include "RiuPlotMainWindow.h"
#include "RiuWellLogPlot.h"
#include "RiuWellLogTrack.h"
#include "RiuQwtPlotWidget.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RimGridPlotWindow.h"
#include "RimPlotInterface.h"
#include "cafSelectionManager.h"
#include <QAction>
CAF_CMD_SOURCE_INIT( RicDeleteWellLogPlotTrackFeature, "RicDeleteWellLogPlotTrackFeature" );
CAF_CMD_SOURCE_INIT( RicDeleteSubPlotFeature, "RicDeleteWellLogPlotTrackFeature" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicDeleteWellLogPlotTrackFeature::isCommandEnabled()
bool RicDeleteSubPlotFeature::isCommandEnabled()
{
if ( RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot() ) return false;
std::vector<RimWellLogTrack*> selection;
std::vector<caf::PdmObject*> selection;
caf::SelectionManager::instance()->objectsByType( &selection );
if ( selection.size() > 0 )
{
RimWellLogPlot* wellLogPlot = nullptr;
RimGridPlotWindow* wellLogPlot = nullptr;
selection[0]->firstAncestorOrThisOfType( wellLogPlot );
if ( wellLogPlot && wellLogPlot->trackCount() > 1 )
if ( dynamic_cast<RimPlotInterface*>( selection[0] ) && wellLogPlot && wellLogPlot->plotCount() > 1 )
{
return true;
}
@ -60,38 +60,39 @@ bool RicDeleteWellLogPlotTrackFeature::isCommandEnabled()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicDeleteWellLogPlotTrackFeature::onActionTriggered( bool isChecked )
void RicDeleteSubPlotFeature::onActionTriggered( bool isChecked )
{
if ( RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot() ) return;
std::vector<RimWellLogTrack*> selection;
std::vector<caf::PdmObject*> selection;
caf::SelectionManager::instance()->objectsByType( &selection );
RiuPlotMainWindow* plotWindow = RiaGuiApplication::instance()->getOrCreateMainPlotWindow();
std::set<RimWellLogPlot*> alteredWellLogPlots;
RiuPlotMainWindow* plotWindow = RiaGuiApplication::instance()->getOrCreateMainPlotWindow();
std::set<RimGridPlotWindow*> alteredWellLogPlots;
for ( size_t i = 0; i < selection.size(); i++ )
{
RimWellLogTrack* track = selection[i];
RimPlotInterface* plot = dynamic_cast<RimPlotInterface*>( selection[i] );
RimWellLogPlot* wellLogPlot = nullptr;
track->firstAncestorOrThisOfType( wellLogPlot );
if ( wellLogPlot && wellLogPlot->trackCount() > 1 )
RimGridPlotWindow* wellLogPlot = nullptr;
selection[i]->firstAncestorOrThisOfType( wellLogPlot );
if ( plot && wellLogPlot && wellLogPlot->plotCount() > 1 )
{
alteredWellLogPlots.insert( wellLogPlot );
wellLogPlot->removeTrack( track );
caf::SelectionManager::instance()->removeObjectFromAllSelections( track );
wellLogPlot->removePlot( plot );
caf::SelectionManager::instance()->removeObjectFromAllSelections( selection[i] );
wellLogPlot->updateConnectedEditors();
delete track;
delete plot;
}
}
for ( RimWellLogPlot* wellLogPlot : alteredWellLogPlots )
for ( RimGridPlotWindow* wellLogPlot : alteredWellLogPlots )
{
RiuWellLogPlot* viewWidget = dynamic_cast<RiuWellLogPlot*>( wellLogPlot->viewWidget() );
RiuGridPlotWindow* viewWidget = dynamic_cast<RiuGridPlotWindow*>( wellLogPlot->viewWidget() );
plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredWidth() );
wellLogPlot->calculateAvailableDepthRange();
wellLogPlot->updateDepthZoom();
// TODO: add back with virtual methods
// wellLogPlot->calculateAvailableDepthRange();
// wellLogPlot->updateDepthZoom();
wellLogPlot->uiCapability()->updateConnectedEditors();
}
}
@ -99,7 +100,7 @@ void RicDeleteWellLogPlotTrackFeature::onActionTriggered( bool isChecked )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicDeleteWellLogPlotTrackFeature::setupActionLook( QAction* actionToSetup )
void RicDeleteSubPlotFeature::setupActionLook( QAction* actionToSetup )
{
actionToSetup->setText( "Delete Track" );
actionToSetup->setIcon( QIcon( ":/Erase.png" ) );

View File

@ -24,7 +24,7 @@
//==================================================================================================
///
//==================================================================================================
class RicDeleteWellLogPlotTrackFeature : public caf::CmdFeature
class RicDeleteSubPlotFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;

View File

@ -112,8 +112,8 @@ void RicNewPltPlotFeature::onActionTriggered( bool isChecked )
pltPlot->setCurrentWellName( wellPathName );
RimWellLogTrack* plotTrack = new RimWellLogTrack();
pltPlot->addTrack( plotTrack );
plotTrack->setDescription( QString( "Track %1" ).arg( pltPlot->trackCount() ) );
pltPlot->addPlot( plotTrack );
plotTrack->setDescription( QString( "Track %1" ).arg( pltPlot->plotCount() ) );
pltPlotColl->addPlot( pltPlot );
pltPlot->setDescription( plotName );

View File

@ -73,8 +73,8 @@ void RicNewRftPlotFeature::onActionTriggered( bool isChecked )
rftPlot->setSimWellOrWellPathName( wellName );
RimWellLogTrack* plotTrack = new RimWellLogTrack();
rftPlot->addTrack( plotTrack );
plotTrack->setDescription( QString( "Track %1" ).arg( rftPlot->trackCount() ) );
rftPlot->addPlot( plotTrack );
plotTrack->setDescription( QString( "Track %1" ).arg( rftPlot->plotCount() ) );
rftPlotColl->addPlot( rftPlot );
rftPlot->applyInitialSelections();

View File

@ -99,10 +99,10 @@ RimWellBoreStabilityPlot*
plot->enableAllAutoNameTags( true );
plot->setPlotTitleVisible( true );
plot->setTrackLegendsVisible( true );
plot->setTrackLegendsHorizontal( true );
plot->setLegendsVisible( true );
plot->setLegendsHorizontal( true );
plot->setDepthType( RimWellLogPlot::TRUE_VERTICAL_DEPTH );
plot->setDepthAutoZoom( true );
plot->setAutoScaleYEnabled( true );
RicNewWellLogPlotFeatureImpl::updateAfterCreation( plot );
}
@ -191,7 +191,7 @@ void RicNewWellBoreStabilityPlotFeature::createFormationTrack( RimWellBoreStabil
formationTrack->setFormationCase( geoMechCase );
formationTrack->setAnnotationType( RiuPlotAnnotationTool::FORMATION_ANNOTATIONS );
formationTrack->setVisibleXRange( 0.0, 0.0 );
formationTrack->setWidthScaleFactor( RimWellLogTrack::NARROW_TRACK );
formationTrack->setWidthScaleFactor( RimWellLogTrack::NARROW );
}
//--------------------------------------------------------------------------------------------------
@ -202,7 +202,7 @@ void RicNewWellBoreStabilityPlotFeature::createCasingShoeTrack( RimWellBoreStabi
RimGeoMechCase* geoMechCase )
{
RimWellLogTrack* casingShoeTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false, "Well Design", plot );
casingShoeTrack->setWidthScaleFactor( RimWellLogTrack::NARROW_TRACK );
casingShoeTrack->setWidthScaleFactor( RimWellLogTrack::NARROW );
casingShoeTrack->setFormationWellPath( wellPath );
casingShoeTrack->setFormationCase( geoMechCase );
casingShoeTrack->setAnnotationType( RiuPlotAnnotationTool::FORMATION_ANNOTATIONS );
@ -226,7 +226,7 @@ void RicNewWellBoreStabilityPlotFeature::createParametersTrack( RimWellBoreStabi
RimWellLogTrack* paramCurvesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false,
"WBS Parameters",
plot );
paramCurvesTrack->setWidthScaleFactor( RimWellLogTrack::WIDE_TRACK );
paramCurvesTrack->setWidthScaleFactor( RimWellLogTrack::WIDE );
paramCurvesTrack->setAutoScaleXEnabled( true );
paramCurvesTrack->setTickIntervals( 0.5, 0.05 );
paramCurvesTrack->setXAxisGridVisibility( RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR );
@ -234,7 +234,7 @@ void RicNewWellBoreStabilityPlotFeature::createParametersTrack( RimWellBoreStabi
paramCurvesTrack->setFormationCase( geoMechCase );
paramCurvesTrack->setAnnotationType( RiuPlotAnnotationTool::CURVE_ANNOTATIONS );
paramCurvesTrack->setShowRegionLabels( true );
paramCurvesTrack->setVisible( false );
paramCurvesTrack->setChecked( false );
std::vector<QString> resultNames = RiaDefines::wellPathStabilityParameterNames();
std::vector<cvf::Color3f> colors = {cvf::Color3f::CRIMSON, cvf::Color3f::DARK_YELLOW};
@ -258,7 +258,7 @@ void RicNewWellBoreStabilityPlotFeature::createParametersTrack( RimWellBoreStabi
curve->loadDataAndUpdate( false );
curve->setAutoNameComponents( false, true, false, false, false );
}
paramCurvesTrack->calculateXZoomRangeAndUpdateQwt();
paramCurvesTrack->setAutoScaleXEnabled( true );
}
//--------------------------------------------------------------------------------------------------
@ -272,7 +272,7 @@ void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack( RimWellBore
RimWellLogTrack* stabilityCurvesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false,
"Stability Curves",
plot );
stabilityCurvesTrack->setWidthScaleFactor( RimWellLogTrack::EXTRA_WIDE_TRACK );
stabilityCurvesTrack->setWidthScaleFactor( RimWellLogTrack::EXTRA_WIDE );
stabilityCurvesTrack->setAutoScaleXEnabled( true );
stabilityCurvesTrack->setTickIntervals( 0.5, 0.05 );
stabilityCurvesTrack->setXAxisGridVisibility( RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR );
@ -309,7 +309,7 @@ void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack( RimWellBore
curve->setSmoothCurve( true );
curve->setSmoothingThreshold( 0.002 );
}
stabilityCurvesTrack->calculateXZoomRangeAndUpdateQwt();
stabilityCurvesTrack->setAutoScaleXEnabled( true );
}
//--------------------------------------------------------------------------------------------------
@ -366,7 +366,7 @@ void RicNewWellBoreStabilityPlotFeature::createAnglesTrack( RimWellBoreStability
maxValue = cvf::Math::clamp( maxValue, angleIncrement, 360.0 );
minValue = cvf::Math::clamp( minValue, 0.0, maxValue - 90.0 );
}
wellPathAnglesTrack->setWidthScaleFactor( RimWellLogTrack::NORMAL_TRACK );
wellPathAnglesTrack->setWidthScaleFactor( RimWellLogTrack::NORMAL );
wellPathAnglesTrack->setVisibleXRange( minValue, maxValue );
wellPathAnglesTrack->setTickIntervals( 90.0, 30.0 );
wellPathAnglesTrack->setXAxisGridVisibility( RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR );

View File

@ -165,14 +165,14 @@ RimWellLogTrack* RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( bool
}
RimWellLogTrack* plotTrack = new RimWellLogTrack();
plot->addTrack( plotTrack );
plot->addPlot( plotTrack );
if ( !trackDescription.isEmpty() )
{
plotTrack->setDescription( trackDescription );
}
else
{
plotTrack->setDescription( QString( "Track %1" ).arg( plot->trackCount() ) );
plotTrack->setDescription( QString( "Track %1" ).arg( plot->plotCount() ) );
}
if ( caseToApply )
@ -224,10 +224,6 @@ void RicNewWellLogPlotFeatureImpl::updateAfterCreation( RimWellLogPlot* plot )
{
CVF_ASSERT( plot );
plot->loadDataAndUpdate();
plot->updateDepthZoom();
plot->updateConnectedEditors();
plot->updateTracks();
RiaApplication::instance()->project()->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------

View File

@ -21,8 +21,8 @@
#include "RiaGuiApplication.h"
#include "RiuPlotMainWindow.h"
#include "RiuQwtPlotWidget.h"
#include "RiuWellLogPlot.h"
#include "RiuWellLogTrack.h"
#include "RicNewWellLogCurveExtractionFeature.h"
#include "RicWellLogPlotCurveFeatureImpl.h"
@ -62,8 +62,8 @@ void RicNewWellLogPlotTrackFeature::onActionTriggered( bool isChecked )
if ( wellLogPlot )
{
RimWellLogTrack* plotTrack = new RimWellLogTrack;
wellLogPlot->addTrack( plotTrack );
plotTrack->setDescription( QString( "Track %1" ).arg( wellLogPlot->trackCount() ) );
wellLogPlot->addPlot( plotTrack );
plotTrack->setDescription( QString( "Track %1" ).arg( wellLogPlot->plotCount() ) );
RiuPlotMainWindow* plotWindow = RiaGuiApplication::instance()->getOrCreateMainPlotWindow();
RiuWellLogPlot* viewWidget = dynamic_cast<RiuWellLogPlot*>( wellLogPlot->viewWidget() );
RicWellLogTools::addWellLogExtractionCurve( plotTrack, nullptr, nullptr, nullptr, nullptr, -1, true );

View File

@ -81,9 +81,9 @@ void RicPasteWellLogTrackFeature::onActionTriggered( bool isChecked )
fileCurve->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
CVF_ASSERT( newObject );
wellLogPlot->addTrack( newObject );
wellLogPlot->addPlot( newObject );
newObject->setDescription( QString( "Track %1" ).arg( wellLogPlot->trackCount() ) );
newObject->setDescription( QString( "Track %1" ).arg( wellLogPlot->plotCount() ) );
// Resolve references after object has been inserted into the project data model
newObject->resolveReferencesRecursively();

View File

@ -21,8 +21,8 @@
#include "RiaGuiApplication.h"
#include "RiuPlotMainWindow.h"
#include "RiuQwtPlotWidget.h"
#include "RiuWellLogPlot.h"
#include "RiuWellLogTrack.h"
#include "RimWellLogCurve.h"
#include "RimWellLogPlot.h"
@ -74,59 +74,42 @@ void RicWellLogPlotTrackFeatureImpl::moveCurvesToWellLogPlotTrack( RimWellLogTra
for ( std::set<RimWellLogTrack*>::iterator tIt = srcTracks.begin(); tIt != srcTracks.end(); ++tIt )
{
( *tIt )->setAutoScaleXEnabled( true );
( *tIt )->updateParentPlotZoom();
( *tIt )->calculateXZoomRangeAndUpdateQwt();
}
destTrack->loadDataAndUpdate();
destTrack->setAutoScaleXEnabled( true );
destTrack->updateParentPlotZoom();
destTrack->calculateXZoomRangeAndUpdateQwt();
destTrack->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( RimWellLogPlot* dstWellLogPlot,
const std::vector<RimWellLogTrack*>& tracksToMove,
RimWellLogTrack* trackToInsertAfter )
void RicWellLogPlotTrackFeatureImpl::movePlotsToGridPlotWindow( RimGridPlotWindow* gridPlotWindow,
const std::vector<RimPlotInterface*>& plotsToMove,
RimPlotInterface* plotToInsertAfter )
{
CVF_ASSERT( dstWellLogPlot );
CVF_ASSERT( gridPlotWindow );
std::set<RimWellLogPlot*> srcPlots;
for ( size_t tIdx = 0; tIdx < tracksToMove.size(); tIdx++ )
for ( size_t tIdx = 0; tIdx < plotsToMove.size(); tIdx++ )
{
RimWellLogTrack* track = tracksToMove[tIdx];
RimWellLogPlot* srcPlot;
track->firstAncestorOrThisOfType( srcPlot );
RimPlotInterface* plot = plotsToMove[tIdx];
caf::PdmObject* pdmObject = dynamic_cast<caf::PdmObject*>( plot );
RimGridPlotWindow* srcPlot;
pdmObject->firstAncestorOrThisOfType( srcPlot );
if ( srcPlot )
{
srcPlot->removeTrack( track );
srcPlots.insert( srcPlot );
srcPlot->removePlot( plot );
}
}
for ( std::set<RimWellLogPlot*>::iterator pIt = srcPlots.begin(); pIt != srcPlots.end(); ++pIt )
{
( *pIt )->calculateAvailableDepthRange();
( *pIt )->updateDepthZoom();
( *pIt )->updateTrackNames();
( *pIt )->updateConnectedEditors();
}
size_t insertionStartIndex = 0;
if ( trackToInsertAfter ) insertionStartIndex = dstWellLogPlot->trackIndex( trackToInsertAfter ) + 1;
if ( plotToInsertAfter ) insertionStartIndex = gridPlotWindow->plotIndex( plotToInsertAfter ) + 1;
for ( size_t tIdx = 0; tIdx < tracksToMove.size(); tIdx++ )
for ( size_t tIdx = 0; tIdx < plotsToMove.size(); tIdx++ )
{
dstWellLogPlot->insertTrack( tracksToMove[tIdx], insertionStartIndex + tIdx );
gridPlotWindow->insertPlot( plotsToMove[tIdx], insertionStartIndex + tIdx );
}
dstWellLogPlot->calculateAvailableDepthRange();
dstWellLogPlot->updateDepthZoom();
dstWellLogPlot->updateTrackNames();
dstWellLogPlot->updateTracks();
dstWellLogPlot->updateConnectedEditors();
}

View File

@ -21,6 +21,8 @@
#include <vector>
class RimGridPlotWindow;
class RimPlotInterface;
class RimWellLogPlot;
class RimWellLogTrack;
class RimWellLogCurve;
@ -34,7 +36,7 @@ public:
static void moveCurvesToWellLogPlotTrack( RimWellLogTrack* dstTrack,
const std::vector<RimWellLogCurve*>& curves,
RimWellLogCurve* insertAfterCurve );
static void moveTracksToWellLogPlot( RimWellLogPlot* wellLogPlot,
const std::vector<RimWellLogTrack*>& tracks,
RimWellLogTrack* trackToInsertAfter );
static void movePlotsToGridPlotWindow( RimGridPlotWindow* gridPlotWindow,
const std::vector<RimPlotInterface*>& plots,
RimPlotInterface* plotToInsertAfter );
};

View File

@ -72,7 +72,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RimMainPlotCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimWellLogPlotCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimRftPlotCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimPltPlotCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimPlot.h
${CMAKE_CURRENT_LIST_DIR}/RimPlotInterface.h
${CMAKE_CURRENT_LIST_DIR}/RimPlotWindow.h
${CMAKE_CURRENT_LIST_DIR}/RimGridPlotWindow.h
${CMAKE_CURRENT_LIST_DIR}/RimWellLogPlot.h
${CMAKE_CURRENT_LIST_DIR}/RimWellLogTrack.h
${CMAKE_CURRENT_LIST_DIR}/RimWellLogCurve.h
@ -212,7 +214,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RimMainPlotCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellLogPlotCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimRftPlotCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimPltPlotCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RimPlotInterface.cpp
${CMAKE_CURRENT_LIST_DIR}/RimPlotWindow.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGridPlotWindow.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellLogPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellBoreStabilityPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellLogTrack.cpp

View File

@ -46,8 +46,8 @@
#include "RimWellLogFile.h"
#include "RimWellPlotTools.h"
#include "RiuPlotMainWindow.h"
#include "RiuQwtPlotWidget.h"
#include "RiuWellAllocationPlot.h"
#include "RiuWellLogTrack.h"
CAF_PDM_SOURCE_INIT( RimWellAllocationPlot, "WellAllocationPlot" );
@ -100,7 +100,7 @@ RimWellAllocationPlot::RimWellAllocationPlot()
m_accumulatedWellFlowPlot = new RimWellLogPlot;
m_accumulatedWellFlowPlot->setDepthUnit( RiaDefines::UNIT_NONE );
m_accumulatedWellFlowPlot->setDepthType( RimWellLogPlot::CONNECTION_NUMBER );
m_accumulatedWellFlowPlot->setTrackLegendsVisible( false );
m_accumulatedWellFlowPlot->setLegendsVisible( false );
m_accumulatedWellFlowPlot->uiCapability()->setUiIconFromResourceString( ":/WellFlowPlot16x16.png" );
CAF_PDM_InitFieldNoDefault( &m_totalWellAllocationPlot, "TotalWellFlowPlot", "Total Well Flow", "", "", "" );
@ -189,12 +189,12 @@ void RimWellAllocationPlot::updateFromWell()
for ( RimWellLogTrack* t : tracks )
{
accumulatedWellFlowPlot()->removeTrack( t );
accumulatedWellFlowPlot()->removePlot( t );
delete t;
}
}
CVF_ASSERT( accumulatedWellFlowPlot()->trackCount() == 0 );
CVF_ASSERT( accumulatedWellFlowPlot()->plotCount() == 0 );
QString description;
if ( m_flowType() == ACCUMULATED ) description = "Accumulated Flow";
@ -270,7 +270,7 @@ void RimWellAllocationPlot::updateFromWell()
plotTrack->setFormationsForCaseWithSimWellOnly( true );
plotTrack->setFormationBranchIndex( (int)brIdx );
accumulatedWellFlowPlot()->addTrack( plotTrack );
accumulatedWellFlowPlot()->addPlot( plotTrack );
const std::vector<double>& depthValues = depthType == RimWellLogPlot::CONNECTION_NUMBER
? wfCalculator->connectionNumbersFromTop( brIdx )
@ -865,9 +865,13 @@ cvf::Color3f RimWellAllocationPlot::getTracerColor( const QString& tracerName )
//--------------------------------------------------------------------------------------------------
void RimWellAllocationPlot::updateFormationNamesData() const
{
for ( size_t i = 0; i < m_accumulatedWellFlowPlot->trackCount(); ++i )
for ( size_t i = 0; i < m_accumulatedWellFlowPlot->plotCount(); ++i )
{
RimWellLogTrack* track = m_accumulatedWellFlowPlot->trackByIndex( i );
track->setAndUpdateSimWellFormationNamesData( m_case, m_wellName );
RimWellLogTrack* track = dynamic_cast<RimWellLogTrack*>( m_accumulatedWellFlowPlot->plotByIndex( i ) );
CAF_ASSERT( track );
if ( track )
{
track->setAndUpdateSimWellFormationNamesData( m_case, m_wellName );
}
}
}

View File

@ -216,7 +216,7 @@ void RimWellFlowRateCurve::updateStackedPlotData()
RimWellLogTrack* wellLogTrack;
firstAncestorOrThisOfTypeAsserted( wellLogTrack );
bool isFirstTrack = ( wellLogTrack == wellLogPlot->trackByIndex( 0 ) );
bool isFirstTrack = ( wellLogTrack == wellLogPlot->plotByIndex( 0 ) );
RiaDefines::DepthUnitType displayUnit = RiaDefines::UNIT_NONE;
@ -271,7 +271,7 @@ void RimWellFlowRateCurve::updateStackedPlotData()
stackedValues.insert( stackedValues.begin(), 0.0 );
polyLineStartStopIndices.front().second += 1;
if ( wellLogPlot->trackCount() > 1 && isFirstTrack )
if ( wellLogPlot->plotCount() > 1 && isFirstTrack )
{
// Add a dummy negative depth value to make the contribution
// from other branches connected to well head visible

View File

@ -229,26 +229,31 @@ void RimWellPltPlot::setPlotXAxisTitles( RimWellLogTrack* plotTrack )
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot::updateFormationsOnPlot() const
{
if ( trackCount() > 0 )
if ( plotCount() > 0 )
{
RimProject* proj = RiaApplication::instance()->project();
RimWellPath* wellPath = proj->wellPathByName( m_wellPathName );
RimCase* formationNamesCase = trackByIndex( 0 )->formationNamesCase();
if ( !formationNamesCase )
RimWellLogTrack* track = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( track );
if ( track )
{
/// Set default case. Todo : Use the first of the selected cases in the plot
std::vector<RimCase*> cases;
proj->allCases( cases );
RimCase* formationNamesCase = track->formationNamesCase();
if ( !cases.empty() )
if ( !formationNamesCase )
{
formationNamesCase = cases[0];
}
}
/// Set default case. Todo : Use the first of the selected cases in the plot
std::vector<RimCase*> cases;
proj->allCases( cases );
trackByIndex( 0 )->setAndUpdateWellPathFormationNamesData( formationNamesCase, wellPath );
if ( !cases.empty() )
{
formationNamesCase = cases[0];
}
}
track->setAndUpdateWellPathFormationNamesData( formationNamesCase, wellPath );
}
}
}
@ -486,7 +491,11 @@ public:
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot::syncCurvesFromUiSelection()
{
RimWellLogTrack* plotTrack = trackByIndex( 0 );
RimWellLogTrack* plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( plotTrack );
if ( !plotTrack ) return;
const std::set<RiaRftPltCurveDefinition>& curveDefs = selectedCurveDefs();
setPlotXAxisTitles( plotTrack );
@ -700,8 +709,8 @@ void RimWellPltPlot::syncCurvesFromUiSelection()
curveGroupId++;
}
plotTrack->setAutoScaleXEnabled( true );
RimWellLogPlot::onLoadDataAndUpdate();
plotTrack->calculateXZoomRange();
}
//--------------------------------------------------------------------------------------------------
@ -886,11 +895,15 @@ void RimWellPltPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
if ( changedField == &m_wellPathName )
{
RimWellLogTrack* const plotTrack = trackByIndex( 0 );
plotTrack->deleteAllCurves();
m_selectedSources.v().clear();
m_selectedTimeSteps.v().clear();
updateFormationsOnPlot();
RimWellLogTrack* const plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( plotTrack );
if ( plotTrack )
{
plotTrack->deleteAllCurves();
m_selectedSources.v().clear();
m_selectedTimeSteps.v().clear();
updateFormationsOnPlot();
}
}
else if ( changedField == &m_selectedSources )
{
@ -924,20 +937,28 @@ void RimWellPltPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
updateFormationsOnPlot();
syncSourcesIoFieldFromGuiField();
syncCurvesFromUiSelection();
updateDepthZoom();
RimWellLogTrack* const plotTrack = trackByIndex( 0 );
plotTrack->calculateXZoomRangeAndUpdateQwt();
RimWellLogTrack* const plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( plotTrack );
if ( plotTrack )
{
plotTrack->setAutoScaleXEnabled( true );
}
updateZoom();
}
if ( changedField == &m_useStandardConditionCurves || changedField == &m_useReservoirConditionCurves ||
changedField == &m_phases )
{
syncCurvesFromUiSelection();
updateDepthZoom();
RimWellLogTrack* const plotTrack = trackByIndex( 0 );
plotTrack->calculateXZoomRangeAndUpdateQwt();
RimWellLogTrack* const plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( plotTrack );
if ( plotTrack )
{
plotTrack->setAutoScaleXEnabled( true );
}
updateZoom();
}
}
@ -970,20 +991,23 @@ void RimWellPltPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
flowGroup->add( &m_phases );
if ( trackCount() > 0 )
if ( plotCount() > 0 )
{
RimWellLogTrack* track = trackByIndex( 0 );
RimWellLogTrack* const track = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( track );
if ( track )
{
track->uiOrderingForRftPltFormations( uiOrdering );
track->uiOrderingForRftPltFormations( uiOrdering );
caf::PdmUiGroup* legendAndAxisGroup = uiOrdering.addNewGroup( "Legend and Axis" );
legendAndAxisGroup->setCollapsedByDefault( true );
caf::PdmUiGroup* legendAndAxisGroup = uiOrdering.addNewGroup( "Legend and Axis" );
legendAndAxisGroup->setCollapsedByDefault( true );
createPlotSettingsUiGroup( *legendAndAxisGroup );
uiOrderingForPlotSettings( *legendAndAxisGroup );
track->uiOrderingForXAxisSettings( *legendAndAxisGroup );
track->uiOrderingForXAxisSettings( *legendAndAxisGroup );
uiOrderingForDepthAxis( *legendAndAxisGroup );
uiOrderingForDepthAxis( *legendAndAxisGroup );
}
}
uiOrdering.skipRemainingFields( true );
@ -1098,9 +1122,14 @@ void RimWellPltPlot::onLoadDataAndUpdate()
if ( m_isOnLoad )
{
if ( trackCount() > 0 )
if ( plotCount() > 0 )
{
trackByIndex( 0 )->setAnnotationType( RiuPlotAnnotationTool::FORMATION_ANNOTATIONS );
RimWellLogTrack* const plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( plotTrack );
if ( plotTrack )
{
plotTrack->setAnnotationType( RiuPlotAnnotationTool::FORMATION_ANNOTATIONS );
}
}
m_isOnLoad = false;
}

View File

@ -53,7 +53,7 @@
#include "RimWellPlotTools.h"
#include "RimWellPltPlot.h"
#include "RiuWellLogTrack.h"
#include "RiuQwtPlotWidget.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafPdmUiTreeSelectionEditor.h"
@ -118,7 +118,7 @@ RimWellRftPlot::RimWellRftPlot()
m_wellPathCollection = RiaApplication::instance()->project()->activeOilField()->wellPathCollection();
m_nameConfig->setCustomName( "RFT Plot" );
m_trackLegendsHorizontal = true;
m_plotLegendsHorizontal = true;
this->setAsPlotMdiWindow();
m_isOnLoad = true;
@ -150,10 +150,10 @@ void RimWellRftPlot::applyCurveAppearance( RimWellLogCurve* newCurve )
currentColor = m_dataSourceColors[sourceAddress];
if ( m_showStatisticsCurves )
{
if ( trackByIndex( 0 ) && trackByIndex( 0 )->viewer() )
if ( plotByIndex( 0 ) && plotByIndex( 0 )->viewer() )
{
cvf::Color3f backgroundColor = RiaColorTools::fromQColorTo3f(
trackByIndex( 0 )->viewer()->canvasBackground().color() );
plotByIndex( 0 )->viewer()->canvasBackground().color() );
currentColor = RiaColorTools::blendCvfColors( backgroundColor, currentColor, 2, 1 );
}
}
@ -185,35 +185,41 @@ void RimWellRftPlot::applyCurveAppearance( RimWellLogCurve* newCurve )
//--------------------------------------------------------------------------------------------------
void RimWellRftPlot::updateFormationsOnPlot() const
{
if ( trackCount() > 0 )
if ( plotCount() > 0 )
{
RimProject* proj = RiaApplication::instance()->project();
RimWellPath* wellPath = proj->wellPathByName( m_wellPathNameOrSimWellName );
RimCase* formationNamesCase = trackByIndex( 0 )->formationNamesCase();
if ( !formationNamesCase )
RimCase* formationNamesCase = nullptr;
RimWellLogTrack* track = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( track );
if ( track )
{
/// Set default case. Todo : Use the first of the selected cases in the plot
std::vector<RimCase*> cases;
proj->allCases( cases );
formationNamesCase = track->formationNamesCase();
if ( !cases.empty() )
if ( !formationNamesCase )
{
formationNamesCase = cases[0];
}
}
/// Set default case. Todo : Use the first of the selected cases in the plot
std::vector<RimCase*> cases;
proj->allCases( cases );
if ( wellPath )
{
trackByIndex( 0 )->setAndUpdateWellPathFormationNamesData( formationNamesCase, wellPath );
}
else
{
trackByIndex( 0 )->setAndUpdateSimWellFormationNamesAndBranchData( formationNamesCase,
associatedSimWellName(),
m_branchIndex,
m_branchDetection );
if ( !cases.empty() )
{
formationNamesCase = cases[0];
}
}
if ( wellPath )
{
track->setAndUpdateWellPathFormationNamesData( formationNamesCase, wellPath );
}
else
{
track->setAndUpdateSimWellFormationNamesAndBranchData( formationNamesCase,
associatedSimWellName(),
m_branchIndex,
m_branchDetection );
}
}
}
}
@ -360,7 +366,10 @@ void RimWellRftPlot::updateEditorsFromCurves()
//--------------------------------------------------------------------------------------------------
void RimWellRftPlot::syncCurvesFromUiSelection()
{
RimWellLogTrack* plotTrack = trackByIndex( 0 );
RimWellLogTrack* plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( plotTrack );
if ( !plotTrack ) return;
const std::set<RiaRftPltCurveDefinition>& allCurveDefs = selectedCurveDefs();
const std::set<RiaRftPltCurveDefinition>& curveDefsInPlot = curveDefsFromCurves();
@ -379,7 +388,7 @@ void RimWellRftPlot::syncCurvesFromUiSelection()
allCurveDefs.end(),
std::inserter( deleteCurveDefs, deleteCurveDefs.end() ) );
for ( RimWellLogCurve* const curve : plotTrack->curvesVector() )
for ( RimWellLogCurve* const curve : plotTrack->curves() )
{
RiaRftPltCurveDefinition curveDef = RimWellPlotTools::curveDefFromCurve( curve );
if ( deleteCurveDefs.count( curveDef ) > 0 )
@ -422,10 +431,14 @@ std::set<RiaRftPltCurveDefinition> RimWellRftPlot::curveDefsFromCurves() const
{
std::set<RiaRftPltCurveDefinition> curveDefs;
RimWellLogTrack* const plotTrack = trackByIndex( 0 );
for ( RimWellLogCurve* const curve : plotTrack->curvesVector() )
RimWellLogTrack* const plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( plotTrack );
if ( plotTrack )
{
curveDefs.insert( RimWellPlotTools::curveDefFromCurve( curve ) );
for ( RimWellLogCurve* const curve : plotTrack->curves() )
{
curveDefs.insert( RimWellPlotTools::curveDefFromCurve( curve ) );
}
}
return curveDefs;
}
@ -437,8 +450,11 @@ void RimWellRftPlot::updateCurvesInPlot( const std::set<RiaRftPltCurveDefinition
const std::set<RiaRftPltCurveDefinition>& curveDefsToAdd,
const std::set<RimWellLogCurve*>& curvesToDelete )
{
const QString simWellName = associatedSimWellName();
RimWellLogTrack* const plotTrack = trackByIndex( 0 );
const QString simWellName = associatedSimWellName();
RimWellLogTrack* const plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( plotTrack );
if ( !plotTrack ) return;
// Delete curves
plotTrack->deleteAllCurves();
@ -666,16 +682,20 @@ const char* RimWellRftPlot::plotNameFormatString()
//--------------------------------------------------------------------------------------------------
void RimWellRftPlot::deleteCurvesAssosicatedWithObservedData( const RimObservedFmuRftData* observedFmuRftData )
{
for ( auto track : tracks() )
for ( auto plot : plots() )
{
auto curves = track->curvesVector();
for ( auto curve : curves )
RimWellLogTrack* const track = dynamic_cast<RimWellLogTrack*>( plot );
if ( track )
{
RimWellLogRftCurve* rftCurve = dynamic_cast<RimWellLogRftCurve*>( curve );
if ( rftCurve && rftCurve->observedFmuRftData() == observedFmuRftData )
auto curves = track->curves();
for ( auto curve : curves )
{
track->takeOutCurve( rftCurve );
delete rftCurve;
RimWellLogRftCurve* rftCurve = dynamic_cast<RimWellLogRftCurve*>( curve );
if ( rftCurve && rftCurve->observedFmuRftData() == observedFmuRftData )
{
track->takeOutCurve( rftCurve );
delete rftCurve;
}
}
}
}
@ -821,7 +841,7 @@ void RimWellRftPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
m_branchIndex = 0;
RimWellLogTrack* const plotTrack = trackByIndex( 0 );
RimWellLogTrack* const plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
if ( plotTrack )
{
plotTrack->deleteAllCurves();
@ -899,18 +919,21 @@ void RimWellRftPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
caf::PdmUiGroup* timeStepsGroup = uiOrdering.addNewGroupWithKeyword( "Time Steps", "TimeSteps" );
timeStepsGroup->add( &m_selectedTimeSteps );
if ( trackCount() > 0 )
if ( plotCount() > 0 )
{
RimWellLogTrack* track = trackByIndex( 0 );
RimWellLogTrack* const track = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( track );
if ( track )
{
track->uiOrderingForRftPltFormations( uiOrdering );
track->uiOrderingForRftPltFormations( uiOrdering );
caf::PdmUiGroup* legendAndAxisGroup = uiOrdering.addNewGroup( "Legend and Axis" );
legendAndAxisGroup->setCollapsedByDefault( true );
caf::PdmUiGroup* legendAndAxisGroup = uiOrdering.addNewGroup( "Legend and Axis" );
legendAndAxisGroup->setCollapsedByDefault( true );
uiOrderingForPlotSettings( *legendAndAxisGroup );
track->uiOrderingForXAxisSettings( *legendAndAxisGroup );
uiOrderingForDepthAxis( *legendAndAxisGroup );
createPlotSettingsUiGroup( *legendAndAxisGroup );
track->uiOrderingForXAxisSettings( *legendAndAxisGroup );
uiOrderingForDepthAxis( *legendAndAxisGroup );
}
}
uiOrdering.skipRemainingFields( true );
@ -985,9 +1008,14 @@ void RimWellRftPlot::onLoadDataAndUpdate()
{
if ( m_isOnLoad )
{
if ( trackCount() > 0 )
if ( plotCount() > 0 )
{
trackByIndex( 0 )->setAnnotationType( RiuPlotAnnotationTool::FORMATION_ANNOTATIONS );
RimWellLogTrack* const plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( plotTrack );
if ( plotTrack )
{
plotTrack->setAnnotationType( RiuPlotAnnotationTool::FORMATION_ANNOTATIONS );
}
}
m_isOnLoad = false;
@ -1042,13 +1070,18 @@ void RimWellRftPlot::assignWellPathToExtractionCurves()
if ( wellPath )
{
for ( RimWellLogCurve* curve : trackByIndex( 0 )->curvesVector() )
RimWellLogTrack* const plotTrack = dynamic_cast<RimWellLogTrack*>( plotByIndex( 0 ) );
CAF_ASSERT( plotTrack );
if ( plotTrack )
{
auto extractionCurve = dynamic_cast<RimWellLogExtractionCurve*>( curve );
if ( extractionCurve )
for ( RimWellLogCurve* curve : plotTrack->curves() )
{
extractionCurve->setTrajectoryType( RimWellLogExtractionCurve::WELL_PATH );
extractionCurve->setWellPath( wellPath );
auto extractionCurve = dynamic_cast<RimWellLogExtractionCurve*>( curve );
if ( extractionCurve )
{
extractionCurve->setTrajectoryType( RimWellLogExtractionCurve::WELL_PATH );
extractionCurve->setWellPath( wellPath );
}
}
}
}
@ -1138,14 +1171,6 @@ void RimWellRftPlot::defineCurveColorsAndSymbols( const std::set<RiaRftPltCurveD
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellRftPlot::onDepthTypeChanged()
{
loadDataAndUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -130,8 +130,6 @@ private:
void defineCurveColorsAndSymbols( const std::set<RiaRftPltCurveDefinition>& allCurveDefs );
void onDepthTypeChanged() override;
private:
caf::PdmField<QString> m_wellPathNameOrSimWellName;
caf::PdmField<int> m_branchIndex;

View File

@ -88,6 +88,14 @@ RimGridCrossPlot::~RimGridCrossPlot()
deleteViewWidget();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGridCrossPlot::isChecked() const
{
return isWindowVisible();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -139,7 +147,15 @@ std::vector<RimGridCrossPlotDataSet*> RimGridCrossPlot::dataSets() const
//--------------------------------------------------------------------------------------------------
QWidget* RimGridCrossPlot::viewWidget()
{
return m_qwtPlot;
return m_plotWidget;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtPlotWidget* RimGridCrossPlot::viewer()
{
return m_plotWidget;
}
//--------------------------------------------------------------------------------------------------
@ -149,9 +165,9 @@ QImage RimGridCrossPlot::snapshotWindowContent()
{
QImage image;
if ( m_qwtPlot )
if ( m_plotWidget )
{
QPixmap pix = m_qwtPlot->grab();
QPixmap pix = m_plotWidget->grab();
image = pix.toImage();
}
@ -163,16 +179,10 @@ QImage RimGridCrossPlot::snapshotWindowContent()
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::zoomAll()
{
if ( !m_qwtPlot ) return;
setAutoScaleXEnabled( true );
setAutoScaleYEnabled( true );
setAutoZoomForAllAxes( true );
updateAxisInQwt( RiaDefines::PLOT_AXIS_LEFT );
updateAxisInQwt( RiaDefines::PLOT_AXIS_BOTTOM );
m_qwtPlot->replot();
updateAxisFromQwt( RiaDefines::PLOT_AXIS_LEFT );
updateAxisFromQwt( RiaDefines::PLOT_AXIS_BOTTOM );
updateZoomInQwt();
}
//--------------------------------------------------------------------------------------------------
@ -180,9 +190,9 @@ void RimGridCrossPlot::zoomAll()
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::calculateZoomRangeAndUpdateQwt()
{
if ( m_qwtPlot )
if ( m_plotWidget )
{
m_qwtPlot->replot();
m_plotWidget->scheduleReplot();
}
}
@ -191,17 +201,17 @@ void RimGridCrossPlot::calculateZoomRangeAndUpdateQwt()
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::reattachCurvesToQwtAndReplot()
{
if ( m_qwtPlot )
if ( m_plotWidget )
{
for ( auto dataSet : m_crossPlotDataSets )
{
dataSet->detachAllCurves();
if ( dataSet->isChecked() )
{
dataSet->setParentQwtPlotNoReplot( m_qwtPlot );
dataSet->setParentQwtPlotNoReplot( m_plotWidget );
}
}
updateAxisDisplay();
updateZoomInQwt();
}
}
@ -289,68 +299,39 @@ void RimGridCrossPlot::detachAllCurves()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updateAxisScaling()
void RimGridCrossPlot::loadDataAndUpdate()
{
loadDataAndUpdate();
onLoadDataAndUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updateAxisDisplay()
void RimGridCrossPlot::setAutoScaleXEnabled( bool enabled )
{
if ( !m_qwtPlot ) return;
updateAxisInQwt( RiaDefines::PLOT_AXIS_BOTTOM );
updateAxisInQwt( RiaDefines::PLOT_AXIS_LEFT );
m_qwtPlot->updateAnnotationObjects( m_xAxisProperties );
m_qwtPlot->updateAnnotationObjects( m_yAxisProperties );
m_qwtPlot->replot();
m_xAxisProperties->setAutoZoom( enabled );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updateZoomWindowFromQwt()
void RimGridCrossPlot::setAutoScaleYEnabled( bool enabled )
{
if ( !m_qwtPlot ) return;
updateAxisFromQwt( RiaDefines::PLOT_AXIS_LEFT );
updateAxisFromQwt( RiaDefines::PLOT_AXIS_BOTTOM );
setAutoZoomForAllAxes( false );
m_yAxisProperties->setAutoZoom( enabled );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::selectAxisInPropertyEditor( int axis )
void RimGridCrossPlot::createPlotWidget()
{
RiuPlotMainWindowTools::showPlotMainWindow();
if ( axis == QwtPlot::yLeft )
{
RiuPlotMainWindowTools::selectAsCurrentItem( m_yAxisProperties );
}
else if ( axis == QwtPlot::xBottom )
{
RiuPlotMainWindowTools::selectAsCurrentItem( m_xAxisProperties );
}
createViewWidget( nullptr );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::setAutoZoomForAllAxes( bool enableAutoZoom )
{
m_xAxisProperties->setAutoZoom( enableAutoZoom );
m_yAxisProperties->setAutoZoom( enableAutoZoom );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmObject* RimGridCrossPlot::findRimPlotObjectFromQwtCurve( const QwtPlotCurve* qwtCurve ) const
caf::PdmObject* RimGridCrossPlot::findPdmObjectFromQwtCurve( const QwtPlotCurve* qwtCurve ) const
{
for ( auto dataSet : m_crossPlotDataSets )
{
@ -365,23 +346,49 @@ caf::PdmObject* RimGridCrossPlot::findRimPlotObjectFromQwtCurve( const QwtPlotCu
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::onAxisSelected( int axis, bool toggle )
{
RiuPlotMainWindowTools::showPlotMainWindow();
RimPlotAxisProperties* properties = nullptr;
if ( axis == QwtPlot::yLeft )
{
properties = m_yAxisProperties;
}
else if ( axis == QwtPlot::xBottom )
{
properties = m_xAxisProperties;
}
if ( toggle )
{
RiuPlotMainWindowTools::toggleItemInSelection( properties );
}
else
{
RiuPlotMainWindowTools::selectAsCurrentItem( properties );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* RimGridCrossPlot::createViewWidget( QWidget* mainWindowParent )
{
if ( !m_qwtPlot )
if ( !m_plotWidget )
{
m_qwtPlot = new RiuGridCrossQwtPlot( this, mainWindowParent );
m_plotWidget = new RiuGridCrossQwtPlot( this, mainWindowParent );
for ( auto dataSet : m_crossPlotDataSets )
{
dataSet->setParentQwtPlotNoReplot( m_qwtPlot );
dataSet->setParentQwtPlotNoReplot( m_plotWidget );
}
m_qwtPlot->replot();
m_plotWidget->scheduleReplot();
}
return m_qwtPlot;
return m_plotWidget;
}
//--------------------------------------------------------------------------------------------------
@ -390,10 +397,10 @@ QWidget* RimGridCrossPlot::createViewWidget( QWidget* mainWindowParent )
void RimGridCrossPlot::deleteViewWidget()
{
detachAllCurves();
if ( m_qwtPlot )
if ( m_plotWidget )
{
m_qwtPlot->deleteLater();
m_qwtPlot = nullptr;
m_plotWidget->deleteLater();
m_plotWidget = nullptr;
}
}
@ -501,39 +508,55 @@ void RimGridCrossPlot::performAutoNameUpdate()
updateCurveNamesAndPlotTitle();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updateAxisDisplay()
{
if ( !m_plotWidget ) return;
updateAxisInQwt( RiaDefines::PLOT_AXIS_BOTTOM );
updateAxisInQwt( RiaDefines::PLOT_AXIS_LEFT );
m_plotWidget->updateAnnotationObjects( m_xAxisProperties );
m_plotWidget->updateAnnotationObjects( m_yAxisProperties );
m_plotWidget->scheduleReplot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updatePlot()
{
if ( m_qwtPlot )
if ( m_plotWidget )
{
RiuQwtPlotTools::setCommonPlotBehaviour( m_qwtPlot );
RiuQwtPlotTools::setDefaultAxes( m_qwtPlot );
RiuQwtPlotTools::setCommonPlotBehaviour( m_plotWidget );
RiuQwtPlotTools::setDefaultAxes( m_plotWidget );
updateAxisDisplay();
for ( auto dataSet : m_crossPlotDataSets )
{
dataSet->setParentQwtPlotNoReplot( m_qwtPlot );
dataSet->setParentQwtPlotNoReplot( m_plotWidget );
}
if ( m_showLegend() )
{
// Will be released in plot destructor or when a new legend is set
QwtLegend* legend = new QwtLegend( m_qwtPlot );
QwtLegend* legend = new QwtLegend( m_plotWidget );
auto font = legend->font();
font.setPointSize( m_legendFontSize() );
legend->setFont( font );
m_qwtPlot->insertLegend( legend, QwtPlot::BottomLegend );
m_plotWidget->insertLegend( legend, QwtPlot::BottomLegend );
}
else
{
m_qwtPlot->insertLegend( nullptr );
m_plotWidget->insertLegend( nullptr );
}
m_qwtPlot->updateLegendSizesToMatchPlot();
m_qwtPlot->replot();
m_plotWidget->updateLegendSizesToMatchPlot();
m_plotWidget->scheduleReplot();
}
}
@ -547,9 +570,9 @@ void RimGridCrossPlot::updateCurveNamesAndPlotTitle()
m_crossPlotDataSets[i]->updateCurveNames( i, m_crossPlotDataSets.size() );
}
if ( m_qwtPlot )
if ( m_plotWidget )
{
m_qwtPlot->setTitle( this->createAutoName() );
m_plotWidget->setTitle( this->createAutoName() );
}
updateMdiWindowTitle();
}
@ -621,14 +644,6 @@ QString RimGridCrossPlot::asciiDataForPlotExport( int dataSetIndex ) const
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuGridCrossQwtPlot* RimGridCrossPlot::qwtPlot() const
{
return m_qwtPlot;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -691,34 +706,66 @@ bool RimGridCrossPlot::applyFontSize( RiaDefines::FontSettingType fontSettingTyp
int fontSize,
bool forceChange /*= false*/ )
{
if ( fontSettingType != RiaDefines::PLOT_FONT ) return false;
bool anyChange = false;
for ( auto plotAxis : allPlotAxes() )
if ( fontSettingType == RiaDefines::PLOT_FONT && m_plotWidget )
{
if ( forceChange || plotAxis->titleFontSize() == oldFontSize )
for ( auto plotAxis : allPlotAxes() )
{
plotAxis->setTitleFontSize( fontSize );
anyChange = true;
if ( forceChange || plotAxis->titleFontSize() == oldFontSize )
{
plotAxis->setTitleFontSize( fontSize );
anyChange = true;
}
if ( forceChange || plotAxis->valuesFontSize() == oldFontSize )
{
plotAxis->setValuesFontSize( fontSize );
anyChange = true;
}
}
if ( forceChange || plotAxis->valuesFontSize() == oldFontSize )
if ( forceChange || legendFontSize() == oldFontSize )
{
plotAxis->setValuesFontSize( fontSize );
anyChange = true;
m_legendFontSize = fontSize;
anyChange = true;
}
if ( anyChange ) loadDataAndUpdate();
}
if ( forceChange || legendFontSize() == oldFontSize )
{
m_legendFontSize = fontSize;
anyChange = true;
}
if ( anyChange ) loadDataAndUpdate();
return anyChange;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updateLayout()
{
updatePlot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updateZoomInQwt()
{
if ( m_plotWidget )
{
updateAxisInQwt( RiaDefines::PLOT_AXIS_LEFT );
updateAxisInQwt( RiaDefines::PLOT_AXIS_BOTTOM );
m_plotWidget->updateAxes();
updateZoomFromQwt();
m_plotWidget->scheduleReplot();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updateZoomFromQwt()
{
updateAxisFromQwt( RiaDefines::PLOT_AXIS_LEFT );
updateAxisFromQwt( RiaDefines::PLOT_AXIS_BOTTOM );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -772,7 +819,7 @@ QString RimGridCrossPlot::yAxisParameterString() const
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updateAxisInQwt( RiaDefines::PlotAxis axisType )
{
if ( !m_qwtPlot ) return;
if ( !m_plotWidget ) return;
RimPlotAxisProperties* axisProperties = m_xAxisProperties();
QString axisParameterString = xAxisParameterString();
@ -787,17 +834,17 @@ void RimGridCrossPlot::updateAxisInQwt( RiaDefines::PlotAxis axisType )
if ( axisProperties->isActive() )
{
m_qwtPlot->enableAxis( qwtAxisId, true );
m_plotWidget->enableAxis( qwtAxisId, true );
QwtText axisTitle( axisParameterString );
QFont titleFont = m_qwtPlot->axisTitle( qwtAxisId ).font();
QFont titleFont = m_plotWidget->axisTitle( qwtAxisId ).font();
titleFont.setBold( true );
titleFont.setPointSize( axisProperties->titleFontSize() );
axisTitle.setFont( titleFont );
QFont valuesFont = m_qwtPlot->axisFont( qwtAxisId );
QFont valuesFont = m_plotWidget->axisFont( qwtAxisId );
valuesFont.setPointSize( axisProperties->valuesFontSize() );
m_qwtPlot->setAxisFont( qwtAxisId, valuesFont );
m_plotWidget->setAxisFont( qwtAxisId, valuesFont );
switch ( axisProperties->titlePosition() )
{
@ -809,16 +856,16 @@ void RimGridCrossPlot::updateAxisInQwt( RiaDefines::PlotAxis axisType )
break;
}
m_qwtPlot->setAxisTitle( qwtAxisId, axisTitle );
m_plotWidget->setAxisTitle( qwtAxisId, axisTitle );
if ( axisProperties->isLogarithmicScaleEnabled )
{
QwtLogScaleEngine* currentScaleEngine = dynamic_cast<QwtLogScaleEngine*>(
m_qwtPlot->axisScaleEngine( axisProperties->qwtPlotAxisType() ) );
m_plotWidget->axisScaleEngine( axisProperties->qwtPlotAxisType() ) );
if ( !currentScaleEngine )
{
m_qwtPlot->setAxisScaleEngine( axisProperties->qwtPlotAxisType(), new QwtLogScaleEngine );
m_qwtPlot->setAxisMaxMinor( axisProperties->qwtPlotAxisType(), 5 );
m_plotWidget->setAxisScaleEngine( axisProperties->qwtPlotAxisType(), new QwtLogScaleEngine );
m_plotWidget->setAxisMaxMinor( axisProperties->qwtPlotAxisType(), 5 );
}
if ( axisProperties->isAutoZoom() )
@ -833,38 +880,38 @@ void RimGridCrossPlot::updateAxisInQwt( RiaDefines::PlotAxis axisType )
std::swap( min, max );
}
m_qwtPlot->setAxisScale( qwtAxisId, min, max );
m_plotWidget->setAxisScale( qwtAxisId, min, max );
}
else
{
m_qwtPlot->setAxisScale( qwtAxisId, axisProperties->visibleRangeMin, axisProperties->visibleRangeMax );
m_plotWidget->setAxisScale( qwtAxisId, axisProperties->visibleRangeMin, axisProperties->visibleRangeMax );
}
}
else
{
QwtLinearScaleEngine* currentScaleEngine = dynamic_cast<QwtLinearScaleEngine*>(
m_qwtPlot->axisScaleEngine( axisProperties->qwtPlotAxisType() ) );
m_plotWidget->axisScaleEngine( axisProperties->qwtPlotAxisType() ) );
if ( !currentScaleEngine )
{
m_qwtPlot->setAxisScaleEngine( axisProperties->qwtPlotAxisType(), new QwtLinearScaleEngine );
m_qwtPlot->setAxisMaxMinor( axisProperties->qwtPlotAxisType(), 3 );
m_plotWidget->setAxisScaleEngine( axisProperties->qwtPlotAxisType(), new QwtLinearScaleEngine );
m_plotWidget->setAxisMaxMinor( axisProperties->qwtPlotAxisType(), 3 );
}
if ( axisProperties->isAutoZoom() )
{
m_qwtPlot->setAxisAutoScale( qwtAxisId );
m_plotWidget->setAxisAutoScale( qwtAxisId );
}
else
{
m_qwtPlot->setAxisScale( qwtAxisId, axisProperties->visibleRangeMin, axisProperties->visibleRangeMax );
m_plotWidget->setAxisScale( qwtAxisId, axisProperties->visibleRangeMin, axisProperties->visibleRangeMax );
}
}
m_qwtPlot->axisScaleEngine( axisProperties->qwtPlotAxisType() )
m_plotWidget->axisScaleEngine( axisProperties->qwtPlotAxisType() )
->setAttribute( QwtScaleEngine::Inverted, axisProperties->isAxisInverted() );
}
else
{
m_qwtPlot->enableAxis( qwtAxisId, false );
m_plotWidget->enableAxis( qwtAxisId, false );
}
}
@ -873,10 +920,10 @@ void RimGridCrossPlot::updateAxisInQwt( RiaDefines::PlotAxis axisType )
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updateAxisFromQwt( RiaDefines::PlotAxis axisType )
{
CVF_ASSERT( m_qwtPlot );
if ( !m_plotWidget ) return;
QwtInterval xAxisRange = m_qwtPlot->currentAxisRange( QwtPlot::xBottom );
QwtInterval yAxisRange = m_qwtPlot->currentAxisRange( QwtPlot::yLeft );
QwtInterval xAxisRange = m_plotWidget->axisRange( QwtPlot::xBottom );
QwtInterval yAxisRange = m_plotWidget->axisRange( QwtPlot::yLeft );
RimPlotAxisProperties* axisProperties = m_xAxisProperties();
QwtInterval axisRange = xAxisRange;
@ -952,7 +999,37 @@ void RimGridCrossPlot::setShowInfoBox( bool enable )
//--------------------------------------------------------------------------------------------------
std::set<RimPlotAxisPropertiesInterface*> RimGridCrossPlot::allPlotAxes() const
{
return {m_xAxisProperties, m_yAxisProperties};
return { m_xAxisProperties, m_yAxisProperties };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::updatePlotTitle()
{
updateCurveNamesAndPlotTitle();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::addOrUpdateDataSetLegend( RimGridCrossPlotDataSet* dataSet )
{
if ( m_plotWidget )
{
m_plotWidget->addOrUpdateDataSetLegend( dataSet );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::removeDataSetLegend( RimGridCrossPlotDataSet* dataSet )
{
if ( m_plotWidget )
{
m_plotWidget->removeDataSetLegend( dataSet );
}
}
//--------------------------------------------------------------------------------------------------

View File

@ -23,7 +23,8 @@
#include "RiaDefines.h"
#include "RimNameConfig.h"
#include "RimPlot.h"
#include "RimPlotInterface.h"
#include "RimPlotWindow.h"
#include "RimRiuQwtPlotOwnerInterface.h"
#include <QPointer>
@ -49,7 +50,7 @@ protected:
virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
};
class RimGridCrossPlot : public RimPlot, public RimRiuQwtPlotOwnerInterface, public RimNameConfigHolderInterface
class RimGridCrossPlot : public RimPlotWindow, public RimPlotInterface, public RimNameConfigHolderInterface
{
CAF_PDM_HEADER_INIT;
@ -57,32 +58,36 @@ public:
RimGridCrossPlot();
~RimGridCrossPlot();
bool isChecked() const override;
RimGridCrossPlotDataSet* createDataSet();
int indexOfDataSet( const RimGridCrossPlotDataSet* dataSet ) const;
void addDataSet( RimGridCrossPlotDataSet* dataSet );
std::vector<RimGridCrossPlotDataSet*> dataSets() const;
QWidget* viewWidget() override;
QImage snapshotWindowContent() override;
void zoomAll() override;
void calculateZoomRangeAndUpdateQwt();
void reattachCurvesToQwtAndReplot();
QString createAutoName() const override;
QWidget* viewWidget() override;
RiuQwtPlotWidget* viewer() override;
QImage snapshotWindowContent() override;
void zoomAll() override;
void calculateZoomRangeAndUpdateQwt();
void reattachCurvesToQwtAndReplot();
QString createAutoName() const override;
bool showInfoBox() const;
caf::PdmFieldHandle* userDescriptionField() override;
void detachAllCurves();
void detachAllCurves() override;
void performAutoNameUpdate() override;
void updateCurveNamesAndPlotTitle();
void swapAxes();
QString asciiTitleForPlotExport( int dataSetIndex ) const;
QString asciiDataForPlotExport( int dataSetIndex ) const;
RiuGridCrossQwtPlot* qwtPlot() const;
bool isXAxisLogarithmic() const;
bool isYAxisLogarithmic() const;
void setYAxisInverted( bool inverted );
int legendFontSize() const;
bool isXAxisLogarithmic() const;
bool isYAxisLogarithmic() const;
void setYAxisInverted( bool inverted );
int legendFontSize() const;
bool hasCustomFontSizes( RiaDefines::FontSettingType fontSettingType, int defaultFontSize ) const override;
bool applyFontSize( RiaDefines::FontSettingType fontSettingType,
@ -90,14 +95,21 @@ public:
int fontSize,
bool forceChange = false ) override;
public:
// Rim2dPlotInterface overrides
void updateAxisScaling() override;
void updateAxisDisplay() override;
void updateZoomWindowFromQwt() override;
void selectAxisInPropertyEditor( int axis ) override;
void setAutoZoomForAllAxes( bool enableAutoZoom ) override;
caf::PdmObject* findRimPlotObjectFromQwtCurve( const QwtPlotCurve* curve ) const override;
void updateLayout() override;
void updateZoomInQwt() override;
void updateZoomFromQwt() override;
void loadDataAndUpdate();
void setAutoScaleXEnabled( bool enabled ) override;
void setAutoScaleYEnabled( bool enabled ) override;
void createPlotWidget() override;
caf::PdmObject* findPdmObjectFromQwtCurve( const QwtPlotCurve* curve ) const override;
void onAxisSelected( int axis, bool toggle ) override;
void addOrUpdateDataSetLegend( RimGridCrossPlotDataSet* dataSet );
void removeDataSetLegend( RimGridCrossPlotDataSet* dataSet );
protected:
QWidget* createViewWidget( QWidget* mainWindowParent ) override;
@ -111,8 +123,8 @@ protected:
const QVariant& newValue ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void updatePlot();
void updateAxisDisplay();
void updatePlot();
virtual QString xAxisParameterString() const;
QString yAxisParameterString() const;
@ -129,6 +141,8 @@ protected:
std::set<RimPlotAxisPropertiesInterface*> allPlotAxes() const;
void updatePlotTitle() override;
private:
caf::PdmField<bool> m_showInfoBox;
caf::PdmField<bool> m_showLegend;
@ -140,5 +154,5 @@ private:
caf::PdmChildArrayField<RimGridCrossPlotDataSet*> m_crossPlotDataSets;
QPointer<RiuGridCrossQwtPlot> m_qwtPlot;
QPointer<RiuGridCrossQwtPlot> m_plotWidget;
};

View File

@ -943,10 +943,10 @@ QList<caf::PdmOptionItemInfo>
}
else if ( fieldNeedingOptions == &m_grouping )
{
std::set<RigGridCrossPlotCurveGrouping> validOptions = {NO_GROUPING,
GROUP_BY_TIME,
GROUP_BY_FORMATION,
GROUP_BY_RESULT};
std::set<RigGridCrossPlotCurveGrouping> validOptions = { NO_GROUPING,
GROUP_BY_TIME,
GROUP_BY_FORMATION,
GROUP_BY_RESULT };
if ( !hasMultipleTimeSteps() )
{
validOptions.erase( GROUP_BY_TIME );
@ -977,7 +977,7 @@ void RimGridCrossPlotDataSet::updateLegendRange()
RimGridCrossPlot* parent;
this->firstAncestorOrThisOfTypeAsserted( parent );
if ( parent->qwtPlot() )
if ( parent->viewer() )
{
if ( groupingEnabled() && m_case() && isChecked() && legendConfig()->showLegend() )
{
@ -1020,11 +1020,11 @@ void RimGridCrossPlotDataSet::updateLegendRange()
m_groupingProperty->updateLegendData( eclipseCase, m_timeStep() );
}
}
parent->qwtPlot()->addOrUpdateDataSetLegend( this );
parent->addOrUpdateDataSetLegend( this );
}
else
{
parent->qwtPlot()->removeDataSetLegend( this );
parent->removeDataSetLegend( this );
}
}
}

View File

@ -460,7 +460,7 @@ void Rim2dIntersectionView::setName( const QString& name )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Rim2dIntersectionView::isWindowVisible()
bool Rim2dIntersectionView::isWindowVisible() const
{
return m_showWindow();
}

View File

@ -96,7 +96,7 @@ protected:
cvf::Transform* scaleTransform() override;
void resetLegendsInViewer() override;
void onLoadDataAndUpdate() override;
bool isWindowVisible() override;
bool isWindowVisible() const override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,

View File

@ -24,6 +24,7 @@
#include "RimCase.h"
#include "RimTools.h"
#include "RimWellLogTrack.h"
#include "RiuPlotMainWindowTools.h"
#include "cafAssert.h"
#include "cafPdmUiFilePathEditor.h"
@ -113,6 +114,7 @@ void RimFormationNames::updateConnectedViews()
std::vector<RimCase*> objects;
this->objectsWithReferringPtrFieldsOfType( objects );
bool updatedTracks = false;
for ( RimCase* caseObj : objects )
{
if ( caseObj )
@ -126,11 +128,13 @@ void RimFormationNames::updateConnectedViews()
// The track may be referring to the case for other reasons than formations.
if ( track->formationNamesCase() == caseObj )
{
track->loadDataAndUpdate( true );
track->loadDataAndUpdate();
updatedTracks = true;
}
}
}
}
RiuPlotMainWindowTools::refreshToolbars();
}
//--------------------------------------------------------------------------------------------------

View File

@ -0,0 +1,628 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor ASA
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimGridPlotWindow.h"
#include "RimPlotInterface.h"
#include "RiuPlotMainWindow.h"
#include "RiuPlotMainWindowTools.h"
#include <QRegularExpression>
#include <cvfAssert.h>
namespace caf
{
template <>
void RimGridPlotWindow::ColumnCountEnum::setUp()
{
addItem( RimGridPlotWindow::COLUMNS_1, "1", "1 Column" );
addItem( RimGridPlotWindow::COLUMNS_2, "2", "2 Columns" );
addItem( RimGridPlotWindow::COLUMNS_3, "3", "3 Columns" );
addItem( RimGridPlotWindow::COLUMNS_4, "4", "4 Columns" );
addItem( RimGridPlotWindow::COLUMNS_UNLIMITED, "UNLIMITED", "Unlimited" );
setDefault( RimGridPlotWindow::COLUMNS_UNLIMITED );
}
} // namespace caf
CAF_PDM_SOURCE_INIT( RimGridPlotWindow, "GridPlotWindow" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridPlotWindow::RimGridPlotWindow()
{
CAF_PDM_InitObject( "Grid Plot Window", ":/WellLogPlot16x16.png", "", "" );
CAF_PDM_InitFieldNoDefault( &m_plots, "Tracks", "", "", "", "" );
m_plots.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_columnCountEnum, "NumberOfColumns", "Number of Columns", "", "", "" );
m_viewer = nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridPlotWindow::~RimGridPlotWindow()
{
removeMdiWindowFromMdiArea();
m_plots.deleteAllChildObjects();
deleteViewWidget();
}
//--------------------------------------------------------------------------------------------------
/// Move-assignment operator. Argument has to be passed with std::move()
//--------------------------------------------------------------------------------------------------
RimGridPlotWindow& RimGridPlotWindow::operator=( RimGridPlotWindow&& rhs )
{
RimPlotWindow::operator=( std::move( rhs ) );
// Move all tracks
std::vector<caf::PdmObject*> plots = rhs.m_plots.childObjects();
rhs.m_plots.clear();
for ( caf::PdmObject* plot : plots )
{
CAF_ASSERT( dynamic_cast<RimPlotInterface*>( plot ) );
m_plots.push_back( plot );
}
m_columnCountEnum = rhs.m_columnCountEnum;
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* RimGridPlotWindow::viewWidget()
{
return m_viewer;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::addPlot( RimPlotInterface* plot )
{
insertPlot( plot, m_plots.size() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::insertPlot( RimPlotInterface* plot, size_t index )
{
if ( plot )
{
m_plots.insert( index, toPdmObjectAsserted( plot ) );
if ( m_viewer )
{
plot->createPlotWidget();
m_viewer->insertPlot( plot->viewer(), index );
}
onPlotAdditionOrRemoval();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::removePlot( RimPlotInterface* plot )
{
if ( plot )
{
if ( m_viewer )
{
m_viewer->removePlot( plot->viewer() );
}
m_plots.removeChildObject( toPdmObjectAsserted( plot ) );
onPlotAdditionOrRemoval();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimGridPlotWindow::plotCount() const
{
return m_plots.size();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimGridPlotWindow::plotIndex( const RimPlotInterface* plot ) const
{
return m_plots.index( toPdmObjectAsserted( plot ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPlotInterface* RimGridPlotWindow::plotByIndex( size_t index ) const
{
return toPlotInterfaceAsserted( m_plots[index] );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimPlotInterface*> RimGridPlotWindow::plots() const
{
std::vector<RimPlotInterface*> allPlots;
allPlots.reserve( m_plots.size() );
for ( caf::PdmObject* pdmObject : m_plots )
{
allPlots.push_back( toPlotInterfaceAsserted( pdmObject ) );
}
return allPlots;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimPlotInterface*> RimGridPlotWindow::visiblePlots() const
{
std::vector<RimPlotInterface*> allPlots;
for ( caf::PdmObject* pdmObject : m_plots() )
{
RimPlotInterface* plot = toPlotInterfaceAsserted( pdmObject );
if ( plot->isChecked() )
{
allPlots.push_back( plot );
}
}
return allPlots;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::updateLayout()
{
if ( m_showWindow )
{
m_viewer->scheduleUpdate();
}
}
#if 0
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::updatePlotNames()
{
auto plotVector = plots();
for ( size_t tIdx = 0; tIdx < plotVector.size(); ++tIdx )
{
QString description = plotVector[tIdx]->description();
QRegularExpression regexp( "Track \\d+" );
description.replace( regexp, QString( "Track %1" ).arg( tIdx + 1 ) );
plotVector[tIdx]->setDescription( description );
}
}
#endif
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::updatePlotOrderFromGridWidget()
{
std::sort( m_plots.begin(), m_plots.end(), [this]( caf::PdmObject* lhs, caf::PdmObject* rhs ) {
auto indexLhs = m_viewer->indexOfPlotWidget( toPlotInterfaceAsserted( lhs )->viewer() );
auto indexRhs = m_viewer->indexOfPlotWidget( toPlotInterfaceAsserted( rhs )->viewer() );
return indexLhs < indexRhs;
} );
// updatePlotNames();
updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::setAutoScaleXEnabled( bool enabled )
{
for ( RimPlotInterface* plot : plots() )
{
plot->setAutoScaleXEnabled( enabled );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::setAutoScaleYEnabled( bool enabled )
{
for ( RimPlotInterface* plot : plots() )
{
plot->setAutoScaleYEnabled( enabled );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimGridPlotWindow::columnCount() const
{
if ( m_columnCountEnum() == COLUMNS_UNLIMITED )
{
return static_cast<int>( visiblePlots().size() );
}
return static_cast<int>( m_columnCountEnum() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimGridPlotWindow::columnCountField()
{
return &m_columnCountEnum;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::zoomAll()
{
setAutoScaleXEnabled( true );
setAutoScaleYEnabled( true );
updateZoom();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmUiGroup* RimGridPlotWindow::createPlotSettingsUiGroup( caf::PdmUiOrdering& uiOrdering )
{
caf::PdmUiGroup* titleAndLegendsGroup = RimPlotWindow::createPlotSettingsUiGroup( uiOrdering );
titleAndLegendsGroup->add( &m_columnCountEnum );
return titleAndLegendsGroup;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGridPlotWindow::asciiDataForPlotExport() const
{
QString out = description() + "\n";
for ( RimPlotInterface* plot : plots() )
{
if ( plot->isChecked() )
{
out += plot->asciiDataForPlotExport();
}
}
return out;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::onPlotAdditionOrRemoval()
{
// updatePlotNames();
updateColumnCount();
updateConnectedEditors();
updateLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QImage RimGridPlotWindow::snapshotWindowContent()
{
QImage image;
if ( m_viewer )
{
m_viewer->setScrollbarVisible( false );
m_viewer->setSelectionsVisible( false );
QPixmap pix = m_viewer->grab();
image = pix.toImage();
m_viewer->setScrollbarVisible( true );
m_viewer->setSelectionsVisible( true );
}
return image;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* RimGridPlotWindow::createViewWidget( QWidget* mainWindowParent )
{
m_viewer = new RiuGridPlotWindow( this, mainWindowParent );
recreatePlotWidgets();
return m_viewer;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::deleteViewWidget()
{
detachAllCurves();
if ( m_viewer )
{
m_viewer->deleteLater();
m_viewer = nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
RimPlotWindow::fieldChangedByUi( changedField, oldValue, newValue );
if ( changedField == &m_columnCountEnum )
{
updateLayout();
updateColumnCount();
}
updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
createPlotSettingsUiGroup( uiOrdering );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimGridPlotWindow::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options = RimPlotWindow::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
if ( fieldNeedingOptions == &m_columnCountEnum )
{
for ( size_t i = 0; i < ColumnCountEnum::size(); ++i )
{
ColumnCount enumVal = ColumnCountEnum::fromIndex( i );
if ( enumVal == COLUMNS_UNLIMITED )
{
QString iconPath( ":/ColumnsUnlimited.png" );
options.push_back( caf::PdmOptionItemInfo( ColumnCountEnum::uiText( enumVal ),
enumVal,
false,
caf::QIconProvider( iconPath ) ) );
}
else
{
QString iconPath = QString( ":/Columns%1.png" ).arg( static_cast<int>( enumVal ) );
options.push_back( caf::PdmOptionItemInfo( ColumnCountEnum::uiText( enumVal ),
enumVal,
false,
caf::QIconProvider( iconPath ) ) );
}
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::onLoadDataAndUpdate()
{
updateMdiWindowVisibility();
setPlotTitleInWidget( this->fullPlotTitle() );
updatePlots();
updateLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::initAfterRead()
{
RimPlotWindow::initAfterRead();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::updatePlotTitle()
{
m_viewer->setTitleVisible( m_showTitleInPlot() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::setPlotTitleInWidget( const QString& title )
{
if ( m_viewer )
{
m_viewer->setPlotTitle( title );
}
updateMdiWindowTitle();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::updatePlots()
{
if ( m_showWindow )
{
for ( RimPlotInterface* plot : plots() )
{
plot->loadDataAndUpdate();
}
this->updateZoom();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::updateZoom()
{
for ( RimPlotInterface* plot : plots() )
{
plot->updateZoomInQwt();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::recreatePlotWidgets()
{
CVF_ASSERT( m_viewer );
auto plotVector = plots();
for ( size_t tIdx = 0; tIdx < plotVector.size(); ++tIdx )
{
plotVector[tIdx]->createPlotWidget();
m_viewer->addPlot( plotVector[tIdx]->viewer() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGridPlotWindow::hasCustomFontSizes( RiaDefines::FontSettingType fontSettingType, int defaultFontSize ) const
{
if ( fontSettingType == RiaDefines::PLOT_FONT && m_viewer )
{
if ( m_viewer->fontSize() != defaultFontSize )
{
return true;
}
for ( const RimPlotInterface* plot : plots() )
{
if ( plot->hasCustomFontSizes( fontSettingType, defaultFontSize ) )
{
return true;
}
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGridPlotWindow::applyFontSize( RiaDefines::FontSettingType fontSettingType,
int oldFontSize,
int fontSize,
bool forceChange /*= false */ )
{
bool somethingChanged = false;
if ( fontSettingType == RiaDefines::PLOT_FONT && m_viewer )
{
if ( oldFontSize == m_viewer->fontSize() || forceChange )
{
m_viewer->setFontSize( fontSize );
somethingChanged = true;
}
for ( RimPlotInterface* plot : plots() )
{
if ( plot->applyFontSize( fontSettingType, oldFontSize, fontSize, forceChange ) )
{
somethingChanged = true;
}
}
if ( somethingChanged )
{
m_viewer->scheduleUpdate();
}
}
return somethingChanged;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::detachAllCurves()
{
auto plotVector = plots();
for ( size_t tIdx = 0; tIdx < plotVector.size(); ++tIdx )
{
plotVector[tIdx]->detachAllCurves();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridPlotWindow::updateColumnCount()
{
RiuPlotMainWindowTools::refreshToolbars();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPlotInterface* RimGridPlotWindow::toPlotInterfaceAsserted( caf::PdmObject* pdmObject )
{
RimPlotInterface* plotInterface = dynamic_cast<RimPlotInterface*>( pdmObject );
CAF_ASSERT( plotInterface );
return plotInterface;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimPlotInterface* RimGridPlotWindow::toPlotInterfaceAsserted( const caf::PdmObject* pdmObject )
{
const RimPlotInterface* plotInterface = dynamic_cast<const RimPlotInterface*>( pdmObject );
CAF_ASSERT( plotInterface );
return plotInterface;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmObject* RimGridPlotWindow::toPdmObjectAsserted( RimPlotInterface* plotInterface )
{
caf::PdmObject* pdmObject = dynamic_cast<caf::PdmObject*>( plotInterface );
CAF_ASSERT( pdmObject );
return pdmObject;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::PdmObject* RimGridPlotWindow::toPdmObjectAsserted( const RimPlotInterface* plotInterface )
{
const caf::PdmObject* pdmObject = dynamic_cast<const caf::PdmObject*>( plotInterface );
CAF_ASSERT( pdmObject );
return pdmObject;
}

View File

@ -0,0 +1,132 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor ASA
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimPlotWindow.h"
#include "RiuGridPlotWindow.h"
#include "cafAppEnum.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmFieldHandle.h"
#include "cafPdmObject.h"
#include <QPointer>
#include <QString>
class RimPlotInterface;
class RimGridPlotWindow : public RimPlotWindow
{
CAF_PDM_HEADER_INIT;
public:
enum ColumnCount
{
COLUMNS_1 = 1,
COLUMNS_2 = 2,
COLUMNS_3 = 3,
COLUMNS_4 = 4,
COLUMNS_UNLIMITED = 1000,
};
typedef caf::AppEnum<ColumnCount> ColumnCountEnum;
public:
RimGridPlotWindow();
~RimGridPlotWindow();
RimGridPlotWindow& operator=( RimGridPlotWindow&& rhs );
QWidget* viewWidget() override;
void addPlot( RimPlotInterface* plot );
void insertPlot( RimPlotInterface* plot, size_t index );
void removePlot( RimPlotInterface* plot );
size_t plotCount() const;
size_t plotIndex( const RimPlotInterface* plot ) const;
RimPlotInterface* plotByIndex( size_t index ) const;
std::vector<RimPlotInterface*> plots() const;
std::vector<RimPlotInterface*> visiblePlots() const;
void updateLayout() override;
// void updatePlotNames();
void updatePlotOrderFromGridWidget();
virtual void setAutoScaleXEnabled( bool enabled );
virtual void setAutoScaleYEnabled( bool enabled );
int columnCount() const;
caf::PdmFieldHandle* columnCountField();
void zoomAll() override;
caf::PdmUiGroup* createPlotSettingsUiGroup( caf::PdmUiOrdering& uiOrdering ) override;
QString asciiDataForPlotExport() const;
virtual void onPlotAdditionOrRemoval();
protected:
QImage snapshotWindowContent() override;
QWidget* createViewWidget( QWidget* mainWindowParent ) override;
void deleteViewWidget() override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void onLoadDataAndUpdate() override;
void initAfterRead() override;
void updatePlotTitle() override;
void setPlotTitleInWidget( const QString& plotTitle );
void updatePlots();
virtual void updateZoom();
void recreatePlotWidgets();
bool hasCustomFontSizes( RiaDefines::FontSettingType fontSettingType, int defaultFontSize ) const override;
bool applyFontSize( RiaDefines::FontSettingType fontSettingType,
int oldFontSize,
int fontSize,
bool forceChange = false ) override;
private:
void detachAllCurves() override;
void updateColumnCount();
static RimPlotInterface* toPlotInterfaceAsserted( caf::PdmObject* pdmObject );
static const RimPlotInterface* toPlotInterfaceAsserted( const caf::PdmObject* pdmObject );
static caf::PdmObject* toPdmObjectAsserted( RimPlotInterface* plotInterface );
static const caf::PdmObject* toPdmObjectAsserted( const RimPlotInterface* plotInterface );
protected:
caf::PdmField<ColumnCountEnum> m_columnCountEnum;
friend class RiuGridPlotWindow;
QPointer<RiuGridPlotWindow> m_viewer;
private:
caf::PdmChildArrayField<caf::PdmObject*> m_plots;
};

View File

@ -44,8 +44,8 @@
#include "RiuFemTimeHistoryResultAccessor.h"
#include "RiuQwtPlotCurve.h"
#include "qwt_plot.h"
#include "SummaryPlotCommands/RicSummaryPlotFeatureImpl.h"
#include "qwt_plot.h"
CAF_PDM_SOURCE_INIT( RimGridTimeHistoryCurve, "GridTimeHistoryCurve" );
@ -336,7 +336,7 @@ QString RimGridTimeHistoryCurve::caseName() const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
RimCase* RimGridTimeHistoryCurve::gridCase() const
{

View File

@ -0,0 +1,30 @@
#include "RimPlotInterface.h"
#include "RimPlotWindow.h"
#include "RiuQwtPlotWidget.h"
#define RI_PLOT_MIN_DEFAULT -10.0
#define RI_PLOT_MAX_DEFAULT 100.0
namespace caf
{
template <>
void RimPlotInterface::WidthScaleFactorEnum::setUp()
{
addItem( RimPlotInterface::EXTRA_NARROW, "EXTRA_NARROW_TRACK", "Extra Narrow" );
addItem( RimPlotInterface::NARROW, "NARROW_TRACK", "Narrow" );
addItem( RimPlotInterface::NORMAL, "NORMAL_TRACK", "Normal" );
addItem( RimPlotInterface::WIDE, "WIDE_TRACK", "Wide" );
addItem( RimPlotInterface::EXTRA_WIDE, "EXTRA_WIDE_TRACK", "Extra wide" );
setDefault( RimPlotInterface::NORMAL );
}
} // namespace caf
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimPlotInterface::asciiDataForPlotExport() const
{
return "";
}

View File

@ -0,0 +1,83 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor ASA
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiaDefines.h"
#include "cafAppEnum.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include <QPointer>
class RiuQwtPlotWidget;
class RimPlotCurve;
class QwtPlotCurve;
class RimPlotInterface
{
public:
enum WidthScaleFactor
{
EXTRA_NARROW = 3,
NARROW = 4,
NORMAL = 5,
WIDE = 7,
EXTRA_WIDE = 10
};
typedef caf::AppEnum<WidthScaleFactor> WidthScaleFactorEnum;
public:
virtual RiuQwtPlotWidget* viewer() = 0;
virtual bool isChecked() const = 0;
virtual int widthScaleFactor() const
{
return NORMAL;
}
virtual void setWidthScaleFactor( WidthScaleFactor scaleFactor ) {}
virtual bool hasCustomFontSizes( RiaDefines::FontSettingType fontSettingType, int defaultFontSize ) const = 0;
virtual bool applyFontSize( RiaDefines::FontSettingType fontSettingType,
int oldFontSize,
int fontSize,
bool forceChange = false ) = 0;
virtual void setAutoScaleXEnabled( bool enabled ) = 0;
virtual void setAutoScaleYEnabled( bool enabled ) = 0;
virtual void updateZoomInQwt() = 0;
virtual void updateZoomFromQwt() = 0;
virtual QString asciiDataForPlotExport() const;
virtual void createPlotWidget() = 0;
virtual void detachAllCurves() = 0;
virtual caf::PdmObject* findPdmObjectFromQwtCurve( const QwtPlotCurve* curve ) const = 0;
virtual void loadDataAndUpdate() = 0;
virtual void onAxisSelected( int axis, bool toggle ) {}
protected:
virtual void updatePlotWindowLayout() {}
virtual void onWidthScaleFactorChange() {}
};

View File

@ -0,0 +1,173 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor ASA
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimPlotWindow.h"
#include "cafPdmUiComboBoxEditor.h"
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimPlotWindow, "RimPlotWindow" ); // Do not use. Abstract class
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPlotWindow::RimPlotWindow()
{
CAF_PDM_InitObject( "Plot", "", "", "" );
CAF_PDM_InitField( &m_description, "PlotDescription", QString( "" ), "Name", "", "", "" );
CAF_PDM_InitField( &m_showTitleInPlot, "ShowTitleInPlot", false, "Show Title", "", "", "" );
CAF_PDM_InitField( &m_showPlotLegends, "ShowTrackLegends", true, "Show Legends", "", "", "" );
CAF_PDM_InitField( &m_plotLegendsHorizontal, "TrackLegendsHorizontal", false, "Legend Orientation", "", "", "" );
m_plotLegendsHorizontal.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPlotWindow::~RimPlotWindow() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPlotWindow& RimPlotWindow::operator=( RimPlotWindow&& rhs )
{
m_showTitleInPlot = rhs.m_showTitleInPlot();
m_showPlotLegends = rhs.m_showPlotLegends();
m_plotLegendsHorizontal = rhs.m_plotLegendsHorizontal();
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotWindow::setDescription( const QString& description )
{
m_description = description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimPlotWindow::description() const
{
return m_description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimPlotWindow::fullPlotTitle() const
{
return m_description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimPlotWindow::isPlotTitleVisible() const
{
return m_showTitleInPlot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotWindow::setPlotTitleVisible( bool visible )
{
m_showTitleInPlot = visible;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimPlotWindow::legendsVisible() const
{
return m_showPlotLegends();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotWindow::setLegendsVisible( bool doShow )
{
m_showPlotLegends = doShow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimPlotWindow::legendsHorizontal() const
{
return m_plotLegendsHorizontal;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotWindow::setLegendsHorizontal( bool horizontal )
{
m_plotLegendsHorizontal = horizontal;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotWindow::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
RimViewWindow::fieldChangedByUi( changedField, oldValue, newValue );
if ( changedField == &m_showPlotLegends || changedField == &m_plotLegendsHorizontal )
{
updateLayout();
}
else if ( changedField == &m_showTitleInPlot )
{
updatePlotTitle();
}
updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimPlotWindow::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_plotLegendsHorizontal )
{
options.push_back( caf::PdmOptionItemInfo( "Vertical", QVariant::fromValue( false ) ) );
options.push_back( caf::PdmOptionItemInfo( "Horizontal", QVariant::fromValue( true ) ) );
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmUiGroup* RimPlotWindow::createPlotSettingsUiGroup( caf::PdmUiOrdering& uiOrdering )
{
caf::PdmUiGroup* titleAndLegendsGroup = uiOrdering.addNewGroup( "Title and Legends" );
titleAndLegendsGroup->add( &m_showPlotLegends );
titleAndLegendsGroup->add( &m_plotLegendsHorizontal );
titleAndLegendsGroup->add( &m_showTitleInPlot );
return titleAndLegendsGroup;
}

View File

@ -0,0 +1,69 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor ASA
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimNameConfig.h"
#include "RimViewWindow.h"
#include "cafPdmField.h"
#include "cafPdmFieldHandle.h"
#include "cafPdmObject.h"
class QKeyEvent;
class RimPlotWindow : public RimViewWindow
{
CAF_PDM_HEADER_INIT;
public:
RimPlotWindow();
~RimPlotWindow();
RimPlotWindow& operator=( RimPlotWindow&& rhs );
virtual void setDescription( const QString& description );
virtual QString description() const;
virtual QString fullPlotTitle() const;
bool isPlotTitleVisible() const;
void setPlotTitleVisible( bool visible );
bool legendsVisible() const;
void setLegendsVisible( bool doShow );
bool legendsHorizontal() const;
void setLegendsHorizontal( bool horizontal );
virtual void detachAllCurves() = 0;
virtual void handleKeyPressEvent( QKeyEvent* keyEvent ) {}
virtual void updateLayout() = 0;
protected:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
virtual caf::PdmUiGroup* createPlotSettingsUiGroup( caf::PdmUiOrdering& uiOrdering );
virtual void updatePlotTitle() = 0;
protected:
caf::PdmField<QString> m_description;
caf::PdmField<bool> m_showTitleInPlot;
caf::PdmField<bool> m_showPlotLegends;
caf::PdmField<bool> m_plotLegendsHorizontal;
};

View File

@ -196,6 +196,14 @@ void RimViewWindow::viewNavigationChanged()
//--------------------------------------------------------------------------------------------------
void RimViewWindow::onViewNavigationChanged() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimViewWindow::isWindowVisible() const
{
return m_showWindow();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -113,10 +113,7 @@ protected:
virtual void deleteViewWidget() = 0;
virtual void onLoadDataAndUpdate() = 0;
virtual void onViewNavigationChanged();
virtual bool isWindowVisible()
{
return m_showWindow();
} // Virtual To allow special visibility control
virtual bool isWindowVisible() const; // Virtual To allow special visibility control
//////////
// Derived classes are not supposed to override this function. The intention is to always use m_showWindow

View File

@ -127,7 +127,7 @@ void RimWellBoreStabilityPlot::defineUiOrdering( QString uiConfigName, caf::PdmU
{
RimViewWindow::defineUiOrdering( uiConfigName, uiOrdering );
m_commonDataSource->uiOrdering( uiConfigName, uiOrdering );
m_commonDataSource->uiOrdering( RimWellLogCurveCommonDataSource::smoothingUiOrderinglabel(), uiOrdering );
caf::PdmUiGroup* parameterSources = uiOrdering.addNewGroup( "Parameter Sources" );
parameterSources->add( &m_porePressureSource );
@ -137,7 +137,7 @@ void RimWellBoreStabilityPlot::defineUiOrdering( QString uiConfigName, caf::PdmU
parameterSources->add( &m_userDefinedUcs );
uiOrderingForDepthAxis( uiOrdering );
uiOrderingForPlotSettings( uiOrdering );
createPlotSettingsUiGroup( uiOrdering );
uiOrdering.skipRemainingFields( true );
}

View File

@ -26,7 +26,7 @@
#include "RimWellLogTrack.h"
#include "RiuQwtPlotCurve.h"
#include "RiuWellLogTrack.h"
#include "RiuQwtPlotWidget.h"
#include "cafPdmUiComboBoxEditor.h"
@ -84,6 +84,47 @@ bool RimWellLogCurve::xValueRangeInData( double* minimumValue, double* maximumVa
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellLogCurve::yValueRangeInData( double* minimumValue, double* maximumValue ) const
{
CAF_ASSERT( minimumValue && maximumValue );
if ( !( minimumValue && maximumValue ) )
{
return false;
}
RimWellLogPlot* wellLogPlot = nullptr;
firstAncestorOrThisOfTypeAsserted( wellLogPlot );
if ( wellLogPlot->depthType() == RimWellLogPlot::MEASURED_DEPTH )
{
if ( m_curveDataMDRange.first == -std::numeric_limits<double>::infinity() ||
m_curveDataMDRange.second == std::numeric_limits<double>::infinity() )
{
return false;
}
*minimumValue = m_curveDataMDRange.first;
*maximumValue = m_curveDataMDRange.second;
}
else
{
if ( m_curveDataTVDRange.first == -std::numeric_limits<double>::infinity() ||
m_curveDataTVDRange.second == std::numeric_limits<double>::infinity() )
{
return false;
}
*minimumValue = m_curveDataTVDRange.first;
*maximumValue = m_curveDataTVDRange.second;
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -93,7 +134,7 @@ void RimWellLogCurve::setValuesAndMD( const std::vector<double>& xValues,
bool isExtractionCurve )
{
m_curveData->setValuesAndMD( xValues, measuredDepths, depthUnit, isExtractionCurve );
calculateCurveDataXRange();
calculateCurveDataRanges();
}
//--------------------------------------------------------------------------------------------------
@ -106,7 +147,7 @@ void RimWellLogCurve::setValuesWithTVD( const std::vector<double>& xValues,
bool isExtractionCurve )
{
m_curveData->setValuesWithTVD( xValues, measuredDepths, tvDepths, depthUnit, isExtractionCurve );
calculateCurveDataXRange();
calculateCurveDataRanges();
}
//--------------------------------------------------------------------------------------------------
@ -126,15 +167,8 @@ void RimWellLogCurve::updateZoomInParentPlot()
firstAncestorOrThisOfType( wellLogPlot );
if ( wellLogPlot )
{
wellLogPlot->calculateAvailableDepthRange();
wellLogPlot->updateDepthZoom();
}
RimWellLogTrack* plotTrack;
firstAncestorOrThisOfType( plotTrack );
if ( plotTrack )
{
plotTrack->calculateXZoomRangeAndUpdateQwt();
wellLogPlot->setAutoScaleYEnabled( true );
wellLogPlot->updateZoom();
}
}
@ -162,11 +196,18 @@ void RimWellLogCurve::setOverrideCurveDataXRange( double minimumValue, double ma
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogCurve::calculateCurveDataXRange()
void RimWellLogCurve::calculateCurveDataRanges()
{
// Invalidate range first
m_curveDataXRange = std::make_pair( std::numeric_limits<double>::infinity(),
m_curveDataXRange = std::make_pair( std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity() );
m_curveDataMDRange = std::make_pair( std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity() );
m_curveDataTVDRange = std::make_pair( std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity() );
m_curveData->calculateMDRange( &m_curveDataMDRange.first, &m_curveDataMDRange.second );
m_curveData->calculateTVDRange( &m_curveDataTVDRange.first, &m_curveDataTVDRange.second );
for ( double xValue : m_curveData->xValues() )
{

View File

@ -40,6 +40,7 @@ public:
~RimWellLogCurve() override;
bool xValueRangeInData( double* minimumValue, double* maximumValue ) const;
bool yValueRangeInData( double* minimumValue, double* maximumValue ) const;
void setValuesAndMD( const std::vector<double>& xValues,
const std::vector<double>& measuredDepths,
@ -67,9 +68,11 @@ protected:
void setOverrideCurveDataXRange( double minimumValue, double maximumValue );
private:
void calculateCurveDataXRange();
void calculateCurveDataRanges();
private:
cvf::ref<RigWellLogCurveData> m_curveData;
std::pair<double, double> m_curveDataXRange;
std::pair<double, double> m_curveDataMDRange;
std::pair<double, double> m_curveDataTVDRange;
};

View File

@ -679,6 +679,14 @@ std::vector<caf::PdmFieldHandle*> RimWellLogCurveCommonDataSource::fieldsToShowI
return fieldsToDisplay;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellLogCurveCommonDataSource::smoothingUiOrderinglabel()
{
return "ApplySmoothing";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -894,7 +902,7 @@ void RimWellLogCurveCommonDataSource::defineUiOrdering( QString uiConfigName, ca
}
group->add( &m_timeStep );
if ( dynamic_cast<RimGeoMechCase*>( m_case() ) )
if ( uiConfigName == smoothingUiOrderinglabel() )
{
group->add( &m_wbsSmoothing );
group->add( &m_wbsSmoothingThreshold );

View File

@ -87,6 +87,8 @@ public:
void applyNextTimeStep();
std::vector<caf::PdmFieldHandle*> fieldsToShowInToolbar();
static QString smoothingUiOrderinglabel();
protected:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,

View File

@ -59,7 +59,7 @@
#include "RiuPlotMainWindowTools.h"
#include "RiuQwtPlotCurve.h"
#include "RiuWellLogTrack.h"
#include "RiuQwtPlotWidget.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafUtils.h"
@ -371,10 +371,10 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate( bool updateParentPlot )
firstAncestorOrThisOfType( wellLogTrack );
CVF_ASSERT( wellLogTrack );
RiuWellLogTrack* viewer = wellLogTrack->viewer();
RiuQwtPlotWidget* viewer = wellLogTrack->viewer();
if ( viewer )
{
viewer->setDepthTitle( "PL/" + wellLogPlot->depthPlotTitle() );
viewer->setYTitle( "PL/" + wellLogPlot->depthAxisTitle() );
}
}

View File

@ -34,7 +34,7 @@
#include "RimWellRftPlot.h"
#include "RiuQwtPlotCurve.h"
#include "RiuWellLogTrack.h"
#include "RiuQwtPlotWidget.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,7 @@
#include "cafPdmObject.h"
#include "RiaDefines.h"
#include "RimPlot.h"
#include "RimViewWindow.h"
#include "RimGridPlotWindow.h"
#include "RimWellLogPlotNameConfig.h"
#include <QPointer>
@ -36,15 +35,15 @@
#include <set>
class RimWellLogCurveCommonDataSource;
class RiuWellLogPlot;
class RimWellLogTrack;
class RiuGridPlotWindow;
class RimPlotInterface;
class QKeyEvent;
//==================================================================================================
///
///
//==================================================================================================
class RimWellLogPlot : public RimPlot, public RimNameConfigHolderInterface
class RimWellLogPlot : public RimGridPlotWindow, public RimNameConfigHolderInterface
{
CAF_PDM_HEADER_INIT;
@ -57,16 +56,6 @@ public:
CONNECTION_NUMBER
};
enum ColumnCount
{
COLUMNS_1 = 1,
COLUMNS_2 = 2,
COLUMNS_3 = 3,
COLUMNS_4 = 4,
COLUMNS_UNLIMITED = 1000,
};
typedef caf::AppEnum<ColumnCount> ColumnCountEnum;
enum AxisGridVisibility
{
AXIS_GRID_NONE,
@ -80,114 +69,66 @@ public:
RimWellLogPlot();
~RimWellLogPlot() override;
QWidget* createPlotWidget( QWidget* mainWindowParent = nullptr );
QString fullPlotTitle() const override;
RimWellLogPlot& operator=( RimWellLogPlot&& rhs );
QWidget* viewWidget() override;
void setDescription( const QString& description );
QString description() const;
DepthTypeEnum depthType() const;
void setDepthType( DepthTypeEnum depthType );
RiaDefines::DepthUnitType depthUnit() const;
void setDepthUnit( RiaDefines::DepthUnitType depthUnit );
QString depthPlotTitle() const;
void enableDepthGridLines( AxisGridVisibility gridVisibility );
AxisGridVisibility depthGridLinesVisibility() const;
QString depthAxisTitle() const;
void enableDepthAxisGridLines( AxisGridVisibility gridVisibility );
AxisGridVisibility depthAxisGridLinesEnabled() const;
bool isPlotTitleVisible() const;
void setPlotTitleVisible( bool visible );
bool areTrackLegendsVisible() const;
void setTrackLegendsVisible( bool doShow );
bool areTrackLegendsHorizontal() const;
void setTrackLegendsHorizontal( bool horizontal );
int columnCount() const;
caf::PdmFieldHandle* columnCountField();
void addTrack( RimWellLogTrack* track );
void insertTrack( RimWellLogTrack* track, size_t index );
size_t trackCount() const
{
return m_tracks.size();
}
void removeTrack( RimWellLogTrack* track );
size_t trackIndex( const RimWellLogTrack* track ) const;
RimWellLogTrack* trackByIndex( size_t index ) const;
size_t firstVisibleTrackIndex() const;
std::vector<RimWellLogTrack*> tracks() const;
std::vector<RimWellLogTrack*> visibleTracks() const;
void updateTracks( bool autoScaleXAxis = false );
void updateTrackNames();
void updateDepthZoom();
void setDepthZoomByFactorAndCenter( double zoomFactor, double zoomCenter );
void panDepth( double panFactor );
void setDepthZoomMinMax( double minimumDepth, double maximumDepth );
void depthZoomMinMax( double* minimumDepth, double* maximumDepth ) const;
void updateZoom() override;
void setDepthAxisRangeByFactorAndCenter( double zoomFactor, double zoomCenter );
void setDepthAxisRangeByPanDepth( double panFactor );
void setDepthAxisRange( double minimumDepth, double maximumDepth );
void calculateAvailableDepthRange();
void availableDepthRange( double* minimumDepth, double* maximumDepth ) const;
bool hasAvailableDepthRange() const;
void zoomAll() override;
void setDepthAutoZoom( bool on );
void setAutoScaleYEnabled( bool enabled ) override;
void enableAllAutoNameTags( bool enable );
QString asciiDataForPlotExport() const;
void uiOrderingForDepthAxis( caf::PdmUiOrdering& uiOrdering );
void uiOrderingForPlotSettings( caf::PdmUiOrdering& uiOrdering );
void uiOrderingForDepthAxis( caf::PdmUiOrdering& uiOrdering );
caf::PdmUiGroup* createPlotSettingsUiGroup( caf::PdmUiOrdering& uiOrdering );
QString createAutoName() const override;
void handleKeyPressEvent( QKeyEvent* keyEvent );
RimWellLogCurveCommonDataSource* commonDataSource() const;
void updateCommonDataSource();
void setAvailableDepthUnits( const std::set<RiaDefines::DepthUnitType>& depthUnits );
void setAvailableDepthTypes( const std::set<RimWellLogPlot::DepthTypeEnum>& depthTypes );
void updateTrackOrderFromWidget();
void onPlotAdditionOrRemoval() override;
protected:
void performAutoNameUpdate() override;
QWidget* createViewWidget( QWidget* mainWindowParent ) override;
void performAutoNameUpdate() override;
void handleKeyPressEvent( QKeyEvent* keyEvent ) override;
caf::PdmFieldHandle* userDescriptionField() override;
// Overridden PDM methods
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
caf::PdmFieldHandle* userDescriptionField() override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void onLoadDataAndUpdate() override;
QImage snapshotWindowContent() override;
QWidget* createViewWidget( QWidget* mainWindowParent ) override;
void deleteViewWidget() override;
void initAfterRead() override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
private:
void applyZoomAllDepths();
void applyDepthZoomFromVisibleDepth();
void recreateTrackPlots();
void detachAllCurves();
void updatePlotTitle();
virtual void onDepthTypeChanged();
void updateColumnCount();
protected:
caf::PdmField<QString> m_userName_OBSOLETE;
caf::PdmChildField<RimWellLogCurveCommonDataSource*> m_commonDataSource;
caf::PdmChildArrayField<RimWellLogTrack*> m_tracks;
caf::PdmField<caf::AppEnum<DepthTypeEnum>> m_depthType;
caf::PdmField<caf::AppEnum<RiaDefines::DepthUnitType>> m_depthUnit;
@ -196,11 +137,6 @@ protected:
caf::PdmField<AxisGridEnum> m_depthAxisGridVisibility;
caf::PdmField<bool> m_isAutoScaleDepthEnabled;
caf::PdmField<bool> m_showTitleInPlot;
caf::PdmField<bool> m_showTrackLegends;
caf::PdmField<bool> m_trackLegendsHorizontal;
caf::PdmField<ColumnCountEnum> m_columnCountEnum;
caf::PdmChildField<RimWellLogPlotNameConfig*> m_nameConfig;
std::set<RiaDefines::DepthUnitType> m_availableDepthUnits;
@ -208,7 +144,4 @@ protected:
double m_minAvailableDepth;
double m_maxAvailableDepth;
friend class RiuWellLogPlot;
QPointer<RiuWellLogPlot> m_viewer;
};

View File

@ -33,7 +33,6 @@ class RigGeoMechCaseData;
class RigWellPath;
class RimWellPath;
class RimEclipseCase;
class RiuWellLogPlot;
//==================================================================================================
///

View File

@ -50,7 +50,7 @@
#include "RimWellRftPlot.h"
#include "RiuQwtPlotCurve.h"
#include "RiuWellLogTrack.h"
#include "RiuQwtPlotWidget.h"
#include "cafPdmObject.h"
#include "cafVecIjk.h"
@ -459,24 +459,24 @@ void RimWellLogRftCurve::onLoadDataAndUpdate( bool updateParentPlot )
firstAncestorOrThisOfType( wellLogTrack );
CVF_ASSERT( wellLogTrack );
RiuWellLogTrack* viewer = wellLogTrack->viewer();
RiuQwtPlotWidget* viewer = wellLogTrack->viewer();
if ( viewer )
{
if ( m_derivedMDSource == NO_SOURCE )
{
viewer->setDepthTitle( "TVDMSL" );
viewer->setYTitle( "TVDMSL" );
}
else if ( m_derivedMDSource == PSEUDO_LENGTH )
{
viewer->setDepthTitle( "PL/" + wellLogPlot->depthPlotTitle() );
viewer->setYTitle( "PL/" + wellLogPlot->depthAxisTitle() );
}
else if ( m_derivedMDSource == WELL_PATH )
{
viewer->setDepthTitle( "WELL/" + wellLogPlot->depthPlotTitle() );
viewer->setYTitle( "WELL/" + wellLogPlot->depthAxisTitle() );
}
else
{
viewer->setDepthTitle( "OBS/" + wellLogPlot->depthPlotTitle() );
viewer->setYTitle( "OBS/" + wellLogPlot->depthAxisTitle() );
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,7 @@
#include "RigWellPathFormations.h"
#include "RiuPlotAnnotationTool.h"
#include "RimPlotInterface.h"
#include "RimRegularLegendConfig.h"
#include "cafPdmChildArrayField.h"
@ -31,6 +32,8 @@
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
#include "qwt_plot.h"
#include <QPointer>
#include <map>
@ -64,7 +67,7 @@ struct CurveSamplingPointData
///
///
//==================================================================================================
class RimWellLogTrack : public caf::PdmObject
class RimWellLogTrack : public caf::PdmObject, public RimPlotInterface
{
CAF_PDM_HEADER_INIT;
@ -82,21 +85,17 @@ public:
CASE,
WELL_PICK_FILTER
};
enum WidthScaleFactor
{
EXTRA_NARROW_TRACK = 3,
NARROW_TRACK = 4,
NORMAL_TRACK = 5,
WIDE_TRACK = 7,
EXTRA_WIDE_TRACK = 10
};
typedef caf::AppEnum<RiuPlotAnnotationTool::RegionAnnotationType> RegionAnnotationTypeEnum;
typedef caf::AppEnum<RiuPlotAnnotationTool::RegionDisplay> RegionAnnotationDisplayEnum;
void setDescription( const QString& description );
bool isVisible();
void setVisible( bool visible );
bool isChecked() const override;
void setChecked( bool checked );
const QString description() const;
void setDescription( const QString& description );
int widthScaleFactor() const override;
void setWidthScaleFactor( WidthScaleFactor scaleFactor ) override;
void addCurve( RimWellLogCurve* curve );
void insertCurve( RimWellLogCurve* curve, size_t index );
void takeOutCurve( RimWellLogCurve* curve );
@ -105,13 +104,11 @@ public:
size_t curveIndex( RimWellLogCurve* curve );
size_t curveCount()
{
return curves.size();
return m_curves.size();
}
void setXAxisTitle( const QString& text );
QString depthPlotTitle() const;
int widthScaleFactor() const;
void setWidthScaleFactor( WidthScaleFactor scaleFactor );
QString yAxisTitle() const;
void setFormationWellPath( RimWellPath* wellPath );
RimWellPath* formationWellPath() const;
@ -126,11 +123,11 @@ public:
void setFormationTrajectoryType( TrajectoryType trajectoryType );
TrajectoryType formationTrajectoryType() const;
void recreateViewer();
void createPlotWidget();
void detachAllCurves();
void reattachAllCurves();
void loadDataAndUpdate( bool updateParentPlotAndToolbars = false );
void loadDataAndUpdate() override;
void setAndUpdateWellPathFormationNamesData( RimCase* rimCase, RimWellPath* wellPath );
@ -140,14 +137,22 @@ public:
bool useBranchDetection );
void setAndUpdateSimWellFormationNamesData( RimCase* rimCase, const QString& simWellName );
void setAutoScaleXEnabled( bool enabled );
void setAutoScaleXEnabled( bool enabled ) override;
void setAutoScaleYEnabled( bool enabled ) override;
void availableXAxisRange( double* minX, double* maxX );
void availableDepthRange( double* minimumDepth, double* maximumDepth );
void updateParentPlotZoom();
void calculateXZoomRangeAndUpdateQwt();
void applyXZoomFromVisibleRange();
void calculateXZoomRange();
void updateEditors();
void setVisibleXRange( double minValue, double maxValue );
void setVisibleYRange( double minValue, double maxValue );
void updateZoomInQwt() override;
void updateZoomFromQwt() override;
void updateParentPlotZoom();
void updateEditors();
void setTickIntervals( double majorTickInterval, double minorTickInterval );
void setXAxisGridVisibility( RimWellLogPlot::AxisGridVisibility gridLines );
@ -165,42 +170,60 @@ public:
void setShowWellPathAttributes( bool on );
void setWellPathAttributesSource( RimWellPath* wellPath );
RimWellPath* wellPathAttributeSource() const;
RiuWellLogTrack* viewer();
RimWellPath* wellPathAttributeSource() const;
RiuQwtPlotWidget* viewer() override;
RimWellLogCurve* curveDefinitionFromCurve( const QwtPlotCurve* curve ) const;
caf::PdmObject* findPdmObjectFromQwtCurve( const QwtPlotCurve* curve ) const override;
void setLogarithmicScale( bool enable );
std::map<int, std::vector<RimWellFlowRateCurve*>> visibleStackedCurves();
QString description();
std::vector<RimWellLogCurve*> curvesVector();
std::vector<RimWellLogCurve*> visibleCurvesVector();
std::vector<RimWellLogCurve*> curves() const;
std::vector<RimWellLogCurve*> visibleCurves() const;
void uiOrderingForRftPltFormations( caf::PdmUiOrdering& uiOrdering );
void uiOrderingForXAxisSettings( caf::PdmUiOrdering& uiOrdering );
void setFormationsForCaseWithSimWellOnly( bool caseWithSimWellOnly );
void updateAxisAndGridTickIntervals();
void updateXAxisAndGridTickIntervals();
void updateAllLegendItems();
QString asciiDataForPlotExport() const;
bool hasCustomFontSizes( RiaDefines::FontSettingType fontSettingType, int defaultFontSize ) const override;
bool applyFontSize( RiaDefines::FontSettingType fontSettingType,
int oldFontSize,
int fontSize,
bool forceChange = false ) override;
void updatePlotWindowLayout() override;
void onAxisSelected( int axis, bool toggle ) override;
private:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue ) override;
void updateParentPlotLayout();
void calculateXZoomRange();
void calculateYZoomRange();
void updateXZoom();
void updateYZoom();
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void initAfterRead() override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
caf::PdmFieldHandle* objectToggleField() override;
caf::PdmFieldHandle* userDescriptionField() override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void initAfterRead() override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
void computeAndSetXRangeMinForLogarithmicScale();
@ -239,14 +262,23 @@ private:
void updateWellPathAttributesCollection();
void onWidthScaleFactorChange() override;
RimWellLogPlot* parentWellLogPlot() const;
private:
QString m_xAxisTitle;
caf::PdmField<bool> m_show;
caf::PdmField<QString> m_userName;
caf::PdmChildArrayField<RimWellLogCurve*> curves;
caf::PdmField<double> m_visibleXRangeMin;
caf::PdmField<double> m_visibleXRangeMax;
caf::PdmField<bool> m_show;
caf::PdmField<QString> m_description;
caf::PdmField<RimPlotInterface::WidthScaleFactorEnum> m_widthScaleFactor;
caf::PdmChildArrayField<RimWellLogCurve*> m_curves;
caf::PdmField<double> m_visibleXRangeMin;
caf::PdmField<double> m_visibleXRangeMax;
caf::PdmField<double> m_visibleYRangeMin;
caf::PdmField<double> m_visibleYRangeMax;
caf::PdmField<bool> m_isAutoScaleXEnabled;
caf::PdmField<bool> m_isLogarithmicScaleEnabled;
caf::PdmField<RimWellLogPlot::AxisGridEnum> m_xAxisGridVisibility;
@ -268,7 +300,6 @@ private:
caf::PdmField<int> m_formationBranchIndex;
caf::PdmField<caf::AppEnum<RigWellPathFormations::FormationLevel>> m_formationLevel;
caf::PdmField<bool> m_showformationFluids;
caf::PdmField<caf::AppEnum<WidthScaleFactor>> m_widthScaleFactor;
caf::PdmField<bool> m_formationBranchDetection;
caf::PdmField<bool> m_showWellPathAttributes;
caf::PdmField<bool> m_showWellPathCompletions;
@ -285,7 +316,6 @@ private:
bool m_formationsForCaseWithSimWellOnly;
QPointer<RiuWellLogTrack> m_wellLogTrackPlotWidget;
QPointer<RiuWellLogTrack> m_plotWidget;
std::unique_ptr<RiuPlotAnnotationTool> m_annotationTool;
};

View File

@ -186,10 +186,10 @@ RimEnsembleCurveSet::~RimEnsembleCurveSet()
RimSummaryPlot* parentPlot;
firstAncestorOrThisOfType( parentPlot );
if ( parentPlot && parentPlot->qwtPlot() )
if ( parentPlot && parentPlot->viewer() )
{
m_qwtPlotCurveForLegendText->detach();
parentPlot->qwtPlot()->removeEnsembleCurveSetLegend( this );
parentPlot->removeEnsembleCurveSetLegend( this );
}
delete m_qwtPlotCurveForLegendText;
@ -272,7 +272,7 @@ void RimEnsembleCurveSet::reattachQwtCurves()
firstAncestorOrThisOfType( plot );
if ( plot )
{
m_qwtPlotCurveForLegendText->attach( plot->qwtPlot() );
m_qwtPlotCurveForLegendText->attach( plot->viewer() );
}
}
@ -285,7 +285,7 @@ void RimEnsembleCurveSet::addCurve( RimSummaryCurve* curve )
{
RimSummaryPlot* plot;
firstAncestorOrThisOfType( plot );
if ( plot ) curve->setParentQwtPlotNoReplot( plot->qwtPlot() );
if ( plot ) curve->setParentQwtPlotNoReplot( plot->viewer() );
curve->setColor( m_color );
m_curves.push_back( curve );
@ -635,7 +635,7 @@ void RimEnsembleCurveSet::defineUiOrdering( QString uiConfigName, caf::PdmUiOrde
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector Y" );
curveDataGroup->add( &m_yValuesSummaryCaseCollection );
curveDataGroup->add( &m_yValuesSummaryAddressUiField );
curveDataGroup->add( &m_yPushButtonSelectSummaryAddress, {false, 1, 0} );
curveDataGroup->add( &m_yPushButtonSelectSummaryAddress, { false, 1, 0 } );
curveDataGroup->add( &m_plotAxis );
}
@ -946,18 +946,18 @@ void RimEnsembleCurveSet::updateCurveColors()
RimSummaryPlot* plot;
firstAncestorOrThisOfType( plot );
if ( plot && plot->qwtPlot() )
if ( plot && plot->viewer() )
{
if ( m_yValuesSummaryCaseCollection() && isCurvesVisible() && m_colorMode == BY_ENSEMBLE_PARAM &&
m_legendConfig->showLegend() )
{
plot->qwtPlot()->addOrUpdateEnsembleCurveSetLegend( this );
plot->addOrUpdateEnsembleCurveSetLegend( this );
}
else
{
plot->qwtPlot()->removeEnsembleCurveSetLegend( this );
plot->removeEnsembleCurveSetLegend( this );
}
plot->qwtPlot()->replot();
plot->viewer()->scheduleReplot();
}
}
@ -1011,13 +1011,13 @@ void RimEnsembleCurveSet::updateEnsembleCurves( const std::vector<RimSummaryCase
}
}
if ( plot->qwtPlot() ) m_qwtPlotCurveForLegendText->attach( plot->qwtPlot() );
if ( plot->viewer() ) m_qwtPlotCurveForLegendText->attach( plot->viewer() );
}
if ( plot->qwtPlot() )
if ( plot->viewer() )
{
plot->qwtPlot()->updateLegend();
plot->qwtPlot()->replot();
plot->viewer()->updateLegend();
plot->viewer()->scheduleReplot();
plot->updateAxes();
plot->updatePlotInfoLabel();
}
@ -1079,7 +1079,7 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
for ( auto address : addresses )
{
auto curve = new RimSummaryCurve();
curve->setParentQwtPlotNoReplot( plot->qwtPlot() );
curve->setParentQwtPlotNoReplot( plot->viewer() );
m_curves.push_back( curve );
curve->setColor( m_statistics->color() );
curve->setColor( m_statistics->color() );
@ -1103,9 +1103,9 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
curve->updateQwtPlotAxis();
}
if ( plot->qwtPlot() )
if ( plot->viewer() )
{
plot->qwtPlot()->updateLegend();
plot->viewer()->updateLegend();
plot->updateAxes();
}
}
@ -1163,7 +1163,7 @@ void RimEnsembleCurveSet::updateAllTextInPlot()
RimSummaryPlot* summaryPlot = nullptr;
this->firstAncestorOrThisOfTypeAsserted( summaryPlot );
if ( summaryPlot->qwtPlot() )
if ( summaryPlot->viewer() )
{
summaryPlot->updatePlotTitle();
}

View File

@ -637,10 +637,10 @@ void RimSummaryCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering
QString curveDataGroupName = "Summary Vector";
if ( isCrossPlotCurve() ) curveDataGroupName += " Y";
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroupWithKeyword( curveDataGroupName, "Summary Vector Y" );
curveDataGroup->add( &m_yValuesSummaryCase, {true, 3, 1} );
curveDataGroup->add( &m_yValuesSummaryAddressUiField, {true, 2, 1} );
curveDataGroup->add( &m_yPushButtonSelectSummaryAddress, {false, 1, 0} );
curveDataGroup->add( &m_plotAxis, {true, 3, 1} );
curveDataGroup->add( &m_yValuesSummaryCase, { true, 3, 1 } );
curveDataGroup->add( &m_yValuesSummaryAddressUiField, { true, 2, 1 } );
curveDataGroup->add( &m_yPushButtonSelectSummaryAddress, { false, 1, 0 } );
curveDataGroup->add( &m_plotAxis, { true, 3, 1 } );
if ( isCrossPlotCurve() )
m_showErrorBars = false;
@ -651,9 +651,9 @@ void RimSummaryCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering
if ( isCrossPlotCurve() )
{
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector X" );
curveDataGroup->add( &m_xValuesSummaryCase, {true, 3, 1} );
curveDataGroup->add( &m_xValuesSummaryAddressUiField, {true, 2, 1} );
curveDataGroup->add( &m_xPushButtonSelectSummaryAddress, {false, 1, 0} );
curveDataGroup->add( &m_xValuesSummaryCase, { true, 3, 1 } );
curveDataGroup->add( &m_xValuesSummaryAddressUiField, { true, 2, 1 } );
curveDataGroup->add( &m_xPushButtonSelectSummaryAddress, { false, 1, 0 } );
}
caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup( "Appearance" );

View File

@ -309,7 +309,7 @@ void RimSummaryCurveCollection::updateCaseNameHasChanged()
firstAncestorOrThisOfTypeAsserted( parentPlot );
parentPlot->updatePlotTitle();
if ( parentPlot->qwtPlot() ) parentPlot->qwtPlot()->updateLegend();
if ( parentPlot->viewer() ) parentPlot->viewer()->updateLegend();
}
//--------------------------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,8 @@
#include "RifEclipseSummaryAddress.h"
#include "RimPlot.h"
#include "RimPlotInterface.h"
#include "RimPlotWindow.h"
#include "RimRiuQwtPlotOwnerInterface.h"
#include "qwt_plot_textlabel.h"
@ -64,7 +65,7 @@ class QKeyEvent;
///
///
//==================================================================================================
class RimSummaryPlot : public RimPlot, public RimRiuQwtPlotOwnerInterface
class RimSummaryPlot : public RimPlotWindow, public RimPlotInterface
{
CAF_PDM_HEADER_INIT;
@ -74,6 +75,7 @@ public:
void setDescription( const QString& description );
QString description() const;
bool isChecked() const override;
void enableShowPlotTitle( bool enable );
void enableAutoPlotTitle( bool enable );
@ -104,16 +106,14 @@ public:
void updateCaseNameHasChanged();
void updateAxes();
void zoomAll() override;
void updateZoomInQwt();
bool isLogarithmicScaleEnabled( RiaDefines::PlotAxis plotAxis ) const;
RimSummaryTimeAxisProperties* timeAxisProperties();
time_t firstTimeStepOfFirstCurve();
QWidget* viewWidget() override;
QWidget* viewWidget() override;
RiuQwtPlotWidget* viewer() override;
QString asciiDataForPlotExport( DateTimePeriod resamplingPeriod, bool showTimeAsLongString ) const;
@ -122,11 +122,10 @@ public:
std::vector<RimSummaryCurve*> summaryCurves() const;
void deleteAllSummaryCurves();
RimSummaryCurveCollection* summaryCurveCollection() const;
RiuSummaryQwtPlot* qwtPlot() const;
std::vector<RimEnsembleCurveSet*> curveSets() const;
void updatePlotTitle();
void updatePlotTitle() override;
const RimSummaryPlotNameHelper* activePlotTitleHelperAllCurves() const;
void updateCurveNames();
@ -134,6 +133,8 @@ public:
void copyAxisPropertiesFromOther( const RimSummaryPlot& sourceSummaryPlot );
void updateLayout() override;
void updateAll();
void updateAllLegendItems();
@ -163,14 +164,21 @@ public:
virtual RimSummaryPlotSourceStepping* sourceSteppingObjectForKeyEventHandling() const;
virtual std::vector<caf::PdmFieldHandle*> fieldsToShowInToolbar();
public:
// Rim2dPlotInterface overrides
void updateAxisScaling() override;
void updateAxisDisplay() override;
void updateZoomWindowFromQwt() override;
void selectAxisInPropertyEditor( int axis ) override;
void setAutoZoomForAllAxes( bool enableAutoZoom ) override;
caf::PdmObject* findRimPlotObjectFromQwtCurve( const QwtPlotCurve* curve ) const override;
void setAutoScaleXEnabled( bool enabled ) override;
void setAutoScaleYEnabled( bool enabled ) override;
void zoomAll() override;
void updateZoomInQwt() override;
void updateZoomFromQwt() override;
void createPlotWidget() override;
caf::PdmObject* findPdmObjectFromQwtCurve( const QwtPlotCurve* curve ) const override;
void onAxisSelected( int axis, bool toggle ) override;
void loadDataAndUpdate();
void addOrUpdateEnsembleCurveSetLegend( RimEnsembleCurveSet* curveSet );
void removeEnsembleCurveSetLegend( RimEnsembleCurveSet* curveSet );
public:
// RimViewWindow overrides
@ -208,15 +216,13 @@ private:
bool hasVisibleCurvesForAxis( RiaDefines::PlotAxis plotAxis ) const;
RimPlotAxisProperties* yAxisPropertiesLeftOrRight( RiaDefines::PlotAxis leftOrRightPlotAxis ) const;
void updateAxis( RiaDefines::PlotAxis plotAxis );
void updateYAxis( RiaDefines::PlotAxis plotAxis );
void updateZoomForAxis( RiaDefines::PlotAxis plotAxis );
void updateTimeAxis();
void updateBottomXAxis();
void updateAxisRangesFromQwt();
std::set<RimPlotAxisPropertiesInterface*> allPlotAxes() const;
private:
@ -226,8 +232,7 @@ private:
caf::PdmField<int> m_legendFontSize;
caf::PdmField<bool> m_useAutoPlotTitle;
caf::PdmField<QString> m_userDefinedPlotTitle;
caf::PdmField<bool> m_useAutoPlotTitle;
caf::PdmChildArrayField<RimGridTimeHistoryCurve*> m_gridTimeHistoryCurves;
caf::PdmChildField<RimSummaryCurveCollection*> m_summaryCurveCollection;
@ -245,7 +250,7 @@ private:
caf::PdmChildField<RimSummaryPlotFilterTextCurveSetEditor*> m_textCurveSetEditor;
QPointer<RiuSummaryQwtPlot> m_qwtPlot;
QPointer<RiuSummaryQwtPlot> m_plotWidget;
std::unique_ptr<QwtPlotTextLabel> m_plotInfoLabel;
bool m_isCrossPlot;

View File

@ -356,6 +356,42 @@ bool RigWellLogCurveData::calculateMDRange( double* minimumDepth, double* maximu
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigWellLogCurveData::calculateTVDRange( double* minTVD, double* maxTVD ) const
{
CVF_ASSERT( minTVD && maxTVD );
double minValue = HUGE_VAL;
double maxValue = -HUGE_VAL;
for ( size_t vIdx = 0; vIdx < m_tvDepths.size(); vIdx++ )
{
double value = m_tvDepths[vIdx];
if ( value < minValue )
{
minValue = value;
}
if ( value > maxValue )
{
maxValue = value;
}
}
if ( maxValue >= minValue )
{
*minTVD = minValue;
*maxTVD = maxValue;
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -51,6 +51,7 @@ public:
const std::vector<double>& measuredDepths() const;
const std::vector<double>& tvDepths() const;
bool calculateMDRange( double* minMD, double* maxMD ) const;
bool calculateTVDRange( double* minTVD, double* maxTVD ) const;
RiaDefines::DepthUnitType depthUnit() const;

View File

@ -37,7 +37,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuRmsNavigation.h
${CMAKE_CURRENT_LIST_DIR}/RiuSelectionChangedHandler.h
${CMAKE_CURRENT_LIST_DIR}/Riu3dSelectionManager.h
${CMAKE_CURRENT_LIST_DIR}/RiuSimpleHistogramWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuDockedQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuGridCrossQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQwtPlot.h
@ -52,6 +51,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuViewerCommands.h
${CMAKE_CURRENT_LIST_DIR}/RiuPickItemInfo.h
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogTrack.h
${CMAKE_CURRENT_LIST_DIR}/RiuGridPlotWindow.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotLegend.h
${CMAKE_CURRENT_LIST_DIR}/RiuPlotAnnotationTool.h
${CMAKE_CURRENT_LIST_DIR}/RiuGeoMechXfTensorResultAccessor.h
${CMAKE_CURRENT_LIST_DIR}/RiuFemTimeHistoryResultAccessor.h
@ -123,7 +125,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuRmsNavigation.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuSelectionChangedHandler.cpp
${CMAKE_CURRENT_LIST_DIR}/Riu3dSelectionManager.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuSimpleHistogramWidget.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuDockedQwtPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuGridCrossQwtPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQwtPlot.cpp
@ -135,8 +136,11 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuTreeViewEventFilter.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuViewer.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuViewerCommands.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuPickItemInfo.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogTrack.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuGridPlotWindow.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWidget.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotLegend.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuPlotAnnotationTool.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuGeoMechXfTensorResultAccessor.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuFemTimeHistoryResultAccessor.cpp
@ -195,8 +199,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuViewerCommands.h
${CMAKE_CURRENT_LIST_DIR}/RiuTreeViewEventFilter.h
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuWellLogTrack.h
${CMAKE_CURRENT_LIST_DIR}/RiuGridPlotWindow.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotLegend.h
${CMAKE_CURRENT_LIST_DIR}/RiuRecentFileActionProvider.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuDockedQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuGridCrossQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQwtPlot.h

View File

@ -27,6 +27,7 @@
#include "RimCaseCollection.h"
#include "RimEclipseCase.h"
#include "RimEclipseResultCase.h"
#include "RimGridPlotWindow.h"
#include "RimIdenticalGridCaseGroup.h"
#include "RimMimeData.h"
#include "RimSummaryCase.h"
@ -57,15 +58,15 @@ class RiuTypedPdmObjects
public:
explicit RiuTypedPdmObjects( const caf::PdmObjectGroup& objectGroup )
{
objectGroup.objectsByType( &m_typedObjects );
objectGroup.objectsByType( &m_objects );
}
explicit RiuTypedPdmObjects( const std::vector<caf::PdmPointer<caf::PdmObjectHandle>>& objectHandles )
{
for ( size_t i = 0; i < objectHandles.size(); i++ )
{
T* obj = dynamic_cast<T*>( objectHandles[i].p() );
if ( obj ) m_typedObjects.push_back( obj );
caf::PdmObject* obj = dynamic_cast<caf::PdmObject*>( objectHandles[i].p() );
if ( obj ) m_objects.push_back( obj );
}
}
@ -91,16 +92,20 @@ private:
std::vector<T*> typedObjects()
{
std::vector<T*> typedObjectsVec;
for ( size_t i = 0; i < m_typedObjects.size(); i++ )
for ( size_t i = 0; i < m_objects.size(); i++ )
{
typedObjectsVec.push_back( m_typedObjects[i].p() );
T* typedObject = dynamic_cast<T*>( m_objects[i].p() );
if ( typedObject )
{
typedObjectsVec.push_back( typedObject );
}
}
return typedObjectsVec;
}
private:
std::vector<caf::PdmPointer<T>> m_typedObjects;
std::vector<caf::PdmPointer<caf::PdmObject>> m_objects;
};
//--------------------------------------------------------------------------------------------------
@ -284,11 +289,11 @@ bool RiuDragDrop::dropMimeData( const QMimeData* data, Qt::DropAction action, in
return handleWellLogPlotTrackDrop( action, draggedObjects, wellLogPlotTrack, row );
}
RimWellLogPlot* wellLogPlot;
dropTarget->firstAncestorOrThisOfType( wellLogPlot );
if ( wellLogPlot )
RimGridPlotWindow* gridPlotWindow;
dropTarget->firstAncestorOrThisOfType( gridPlotWindow );
if ( gridPlotWindow )
{
return handleWellLogPlotDrop( action, draggedObjects, wellLogPlot, row );
return handleGridPlotWindowDrop( action, draggedObjects, gridPlotWindow, row );
}
RimSummaryCaseCollection* summaryCaseCollection;
@ -404,7 +409,7 @@ bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action,
RimWellLogCurve* insertAfter = nullptr;
if ( insertAtPosition > 0 )
{
auto visibleCurves = trackTarget->visibleCurvesVector();
auto visibleCurves = trackTarget->visibleCurves();
if ( !visibleCurves.empty() )
{
int insertAfterPosition = std::min( insertAtPosition - 1, (int)visibleCurves.size() - 1 );
@ -424,7 +429,7 @@ bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action,
{
RimWellLogPlot* wellLogPlot;
trackTarget->firstAncestorOrThisOfType( wellLogPlot );
return handleWellLogPlotDrop( action, draggedObjects, wellLogPlot, insertAtPosition );
return handleGridPlotWindowDrop( action, draggedObjects, wellLogPlot, insertAtPosition );
}
}
@ -434,28 +439,27 @@ bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action,
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuDragDrop::handleWellLogPlotDrop( Qt::DropAction action,
caf::PdmObjectGroup& draggedObjects,
RimWellLogPlot* wellLogPlotTarget,
int insertAtPosition )
bool RiuDragDrop::handleGridPlotWindowDrop( Qt::DropAction action,
caf::PdmObjectGroup& draggedObjects,
RimGridPlotWindow* gridPlotWindow,
int insertAtPosition )
{
std::vector<RimWellLogTrack*> wellLogPlotTracks = RiuTypedPdmObjects<RimWellLogTrack>::typedObjectsFromGroup(
draggedObjects );
if ( wellLogPlotTracks.size() > 0 )
std::vector<RimPlotInterface*> plots = RiuTypedPdmObjects<RimPlotInterface>::typedObjectsFromGroup( draggedObjects );
if ( plots.size() > 0 )
{
if ( action == Qt::MoveAction )
{
RimWellLogTrack* insertAfter = nullptr;
RimPlotInterface* insertAfter = nullptr;
if ( insertAtPosition > 0 )
{
auto visibleTracks = wellLogPlotTarget->visibleTracks();
auto visibleTracks = gridPlotWindow->visiblePlots();
if ( !visibleTracks.empty() )
{
int insertAfterPosition = std::min( insertAtPosition - 1, (int)visibleTracks.size() - 1 );
insertAfter = visibleTracks[insertAfterPosition];
insertAfter = dynamic_cast<RimPlotInterface*>( visibleTracks[insertAfterPosition] );
}
}
RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( wellLogPlotTarget, wellLogPlotTracks, insertAfter );
RicWellLogPlotTrackFeatureImpl::movePlotsToGridPlotWindow( gridPlotWindow, plots, insertAfter );
return true;
}
}

View File

@ -29,6 +29,7 @@ namespace caf
class PdmObjectHandle;
}
class RimGridPlotWindow;
class RimIdenticalGridCaseGroup;
class RimSummaryCaseCollection;
class RimSummaryCaseMainCollection;
@ -64,10 +65,10 @@ private:
caf::PdmObjectGroup& objectGroup,
RimWellLogTrack* wellLogPlotTrack,
int insertAtPosition );
bool handleWellLogPlotDrop( Qt::DropAction action,
caf::PdmObjectGroup& objectGroup,
RimWellLogPlot* wellLogPlot,
int insertAtPosition );
bool handleGridPlotWindowDrop( Qt::DropAction action,
caf::PdmObjectGroup& objectGroup,
RimGridPlotWindow* gridPlotWindow,
int insertAtPosition );
bool handleWellLogPlotCurveDrop( Qt::DropAction action,
caf::PdmObjectGroup& objectGroup,
RimWellLogCurve* wellLogPlotCurve );

View File

@ -21,12 +21,16 @@
#include "RiuCvfOverlayItemWidget.h"
#include "RiuQwtCurvePointTracker.h"
#include "RiuQwtPlotTools.h"
#include "RiuQwtPlotWheelZoomer.h"
#include "RiuQwtPlotZoomer.h"
#include "RiuRimQwtPlotCurve.h"
#include "RiuWidgetDragger.h"
#include "RimGridCrossPlot.h"
#include "RimGridCrossPlotCurve.h"
#include "RimGridCrossPlotDataSet.h"
#include "RimPlotInterface.h"
#include "RimRegularLegendConfig.h"
#include "cafCmdFeatureMenuBuilder.h"
@ -38,12 +42,12 @@
#include "RimPlotAxisProperties.h"
#include "RiuPlotAnnotationTool.h"
#include "qwt_plot_panner.h"
#include "qwt_scale_draw.h"
#include "qwt_scale_widget.h"
#include "qwt_text.h"
#include "qwt_text_engine.h"
#include <QGraphicsDropShadowEffect>
#include <QLabel>
#include <QMenu>
#include <QResizeEvent>
@ -52,9 +56,35 @@
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuGridCrossQwtPlot::RiuGridCrossQwtPlot( RimViewWindow* ownerViewWindow, QWidget* parent /*= nullptr*/ )
: RiuQwtPlot( ownerViewWindow, parent )
RiuGridCrossQwtPlot::RiuGridCrossQwtPlot( RimPlotInterface* plotDefinition, QWidget* parent /*= nullptr*/ )
: RiuQwtPlotWidget( plotDefinition, parent )
{
// LeftButton for the zooming
m_zoomerLeft = new RiuQwtPlotZoomer( canvas() );
m_zoomerLeft->setRubberBandPen( QColor( Qt::black ) );
m_zoomerLeft->setTrackerMode( QwtPicker::AlwaysOff );
m_zoomerLeft->setTrackerPen( QColor( Qt::black ) );
m_zoomerLeft->initMousePattern( 1 );
m_zoomerLeft->setMousePattern( QwtEventPattern::MouseSelect1, Qt::LeftButton, Qt::ShiftModifier );
// Attach a zoomer for the right axis
m_zoomerRight = new RiuQwtPlotZoomer( canvas() );
m_zoomerRight->setAxis( xTop, yRight );
m_zoomerRight->setTrackerMode( QwtPicker::AlwaysOff );
m_zoomerRight->initMousePattern( 1 );
m_zoomerRight->setMousePattern( QwtEventPattern::MouseSelect1, Qt::LeftButton, Qt::ShiftModifier );
// MidButton for the panning
QwtPlotPanner* panner = new QwtPlotPanner( canvas() );
panner->setMouseButton( Qt::MidButton );
auto wheelZoomer = new RiuQwtPlotWheelZoomer( this );
connect( wheelZoomer, SIGNAL( zoomUpdated() ), SLOT( onZoomedSlot() ) );
connect( m_zoomerLeft, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) );
connect( m_zoomerRight, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) );
connect( panner, SIGNAL( panned( int, int ) ), SLOT( onZoomedSlot() ) );
m_annotationTool = std::unique_ptr<RiuPlotAnnotationTool>( new RiuPlotAnnotationTool() );
m_infoBox = new RiuDraggableOverlayFrame( this, canvas() );
@ -69,21 +99,11 @@ RiuGridCrossQwtPlot::RiuGridCrossQwtPlot( RimViewWindow* ownerViewWindow, QWidge
m_selectedPointMarker->setLabelAlignment( Qt::AlignRight | Qt::AlignVCenter );
m_selectedPointMarker->setSpacing( 3 );
canvas()->setContentsMargins( 0, 0, 0, 0 );
QFrame* canvasFrame = dynamic_cast<QFrame*>( canvas() );
canvasFrame->setFrameShape( QFrame::Box );
canvasFrame->setStyleSheet( "border: 1px solid black" );
RiuQwtPlotTools::setCommonPlotBehaviour( this );
RiuQwtPlotTools::setDefaultAxes( this );
QGraphicsDropShadowEffect* dropShadowEffect = new QGraphicsDropShadowEffect( canvas() );
dropShadowEffect->setOffset( 1.0, 1.0 );
dropShadowEffect->setBlurRadius( 3.0 );
dropShadowEffect->setColor( QColor( 60, 60, 60, 60 ) );
canvas()->setGraphicsEffect( dropShadowEffect );
axisScaleDraw( QwtPlot::xBottom )->enableComponent( QwtAbstractScaleDraw::Backbone, false );
axisScaleDraw( QwtPlot::yLeft )->enableComponent( QwtAbstractScaleDraw::Backbone, false );
axisWidget( QwtPlot::xBottom )->setMargin( 0 );
axisWidget( QwtPlot::yLeft )->setMargin( 0 );
this->installEventFilter( this );
this->canvas()->installEventFilter( this );
}
//--------------------------------------------------------------------------------------------------
@ -174,7 +194,7 @@ void RiuGridCrossQwtPlot::removeDanglingDataSetLegends()
//--------------------------------------------------------------------------------------------------
void RiuGridCrossQwtPlot::updateLegendSizesToMatchPlot()
{
RimGridCrossPlot* crossPlot = dynamic_cast<RimGridCrossPlot*>( ownerPlotDefinition() );
RimGridCrossPlot* crossPlot = dynamic_cast<RimGridCrossPlot*>( plotDefinition() );
if ( !crossPlot ) return;
bool anyLegendResized = false;
@ -215,6 +235,14 @@ void RiuGridCrossQwtPlot::updateAnnotationObjects( RimPlotAxisProperties* axisPr
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimViewWindow* RiuGridCrossQwtPlot::ownerViewWindow() const
{
return dynamic_cast<RimViewWindow*>( plotDefinition() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -230,7 +258,7 @@ void RiuGridCrossQwtPlot::updateLayout()
//--------------------------------------------------------------------------------------------------
void RiuGridCrossQwtPlot::updateInfoBoxLayout()
{
RimGridCrossPlot* crossPlot = dynamic_cast<RimGridCrossPlot*>( ownerPlotDefinition() );
RimGridCrossPlot* crossPlot = dynamic_cast<RimGridCrossPlot*>( plotDefinition() );
if ( !crossPlot ) return;
bool showInfo = false;
@ -300,7 +328,7 @@ void RiuGridCrossQwtPlot::updateLegendLayout()
removeDanglingDataSetLegends();
RimGridCrossPlot* crossPlot = dynamic_cast<RimGridCrossPlot*>( ownerPlotDefinition() );
RimGridCrossPlot* crossPlot = dynamic_cast<RimGridCrossPlot*>( plotDefinition() );
if ( !crossPlot ) return;
@ -402,9 +430,9 @@ void RiuGridCrossQwtPlot::contextMenuEvent( QContextMenuEvent* event )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridCrossQwtPlot::selectSample( QwtPlotCurve* curve, int sampleNumber )
void RiuGridCrossQwtPlot::selectPoint( QwtPlotCurve* curve, int pointNumber )
{
QPointF sample = curve->sample( sampleNumber );
QPointF sample = curve->sample( pointNumber );
m_selectedPointMarker->setValue( sample );
m_selectedPointMarker->setAxes( QwtPlot::xBottom, QwtPlot::yLeft );
m_selectedPointMarker->attach( this );
@ -426,7 +454,7 @@ void RiuGridCrossQwtPlot::selectSample( QwtPlotCurve* curve, int sampleNumber )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridCrossQwtPlot::clearSampleSelection()
void RiuGridCrossQwtPlot::clearPointSelection()
{
m_selectedPointMarker->detach();
}
@ -472,3 +500,11 @@ void RiuGridCrossQwtPlot::applyFontSizeToOverlayItem( caf::TitledOverlayFrame* o
cvf::ref<cvf::Font> cafFont = RiaFontCache::getFont( RiaFontCache::fontSizeEnumFromPointSize( fontSize ) );
overlayItem->setFont( cafFont.p() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridCrossQwtPlot::onZoomedSlot()
{
plotDefinition()->updateZoomFromQwt();
}

View File

@ -19,7 +19,7 @@
#include "RiuInterfaceToViewWindow.h"
#include "RiuPlotAnnotationTool.h"
#include "RiuQwtPlot.h"
#include "RiuQwtPlotWidget.h"
#include "cafPdmPointer.h"
@ -29,9 +29,11 @@
class RimGridCrossPlotDataSet;
class RimPlotAxisProperties;
class RimPlotInterface;
class RiuCvfOverlayItemWidget;
class RiuDraggableOverlayFrame;
class RiuPlotAnnotationTool;
class RiuQwtPlotZoomer;
namespace caf
{
@ -43,12 +45,12 @@ class TitledOverlayFrame;
//
//
//==================================================================================================
class RiuGridCrossQwtPlot : public RiuQwtPlot
class RiuGridCrossQwtPlot : public RiuQwtPlotWidget, public RiuInterfaceToViewWindow
{
Q_OBJECT;
public:
RiuGridCrossQwtPlot( RimViewWindow* ownerViewWindow, QWidget* parent = nullptr );
RiuGridCrossQwtPlot( RimPlotInterface* plotDefinition, QWidget* parent = nullptr );
~RiuGridCrossQwtPlot();
void addOrUpdateDataSetLegend( RimGridCrossPlotDataSet* dataSetToShowLegendFor );
void removeDataSetLegend( RimGridCrossPlotDataSet* dataSetToShowLegendFor );
@ -56,6 +58,8 @@ public:
void updateLegendSizesToMatchPlot();
void updateAnnotationObjects( RimPlotAxisProperties* axisProperties );
RimViewWindow* ownerViewWindow() const override;
protected:
void updateLayout() override;
void updateInfoBoxLayout();
@ -64,11 +68,14 @@ protected:
bool resizeOverlayItemToFitPlot( caf::TitledOverlayFrame* overlayItem );
void contextMenuEvent( QContextMenuEvent* ) override;
void selectSample( QwtPlotCurve* curve, int sampleNumber ) override;
void clearSampleSelection() override;
void selectPoint( QwtPlotCurve* curve, int pointNumber ) override;
void clearPointSelection() override;
bool curveText( const QwtPlotCurve* curve, QString* curveTitle, QString* xParamName, QString* yParamName ) const;
void applyFontSizeToOverlayItem( caf::TitledOverlayFrame* overlayItem );
private slots:
void onZoomedSlot();
private:
typedef caf::PdmPointer<RimGridCrossPlotDataSet> DataSetPtr;
typedef QPointer<RiuCvfOverlayItemWidget> LegendPtr;
@ -78,4 +85,7 @@ private:
std::map<DataSetPtr, LegendPtr> m_legendWidgets;
std::unique_ptr<RiuPlotAnnotationTool> m_annotationTool;
QwtPlotMarker* m_selectedPointMarker;
QPointer<RiuQwtPlotZoomer> m_zoomerLeft;
QPointer<RiuQwtPlotZoomer> m_zoomerRight;
};

View File

@ -0,0 +1,687 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuGridPlotWindow.h"
#include "RiaApplication.h"
#include "RiaPlotWindowRedrawScheduler.h"
#include "RiaPreferences.h"
#include "WellLogCommands/RicWellLogPlotTrackFeatureImpl.h"
#include "RimContextCommandBuilder.h"
#include "RimGridPlotWindow.h"
#include "RimWellLogTrack.h"
#include "RiuMainWindow.h"
#include "RiuPlotMainWindow.h"
#include "RiuPlotObjectPicker.h"
#include "RiuQwtPlotLegend.h"
#include "RiuQwtPlotWidget.h"
#include "cafCmdFeatureMenuBuilder.h"
#include "cafSelectionManager.h"
#include "cvfAssert.h"
#include "qwt_legend.h"
#include "qwt_plot_layout.h"
#include "qwt_scale_draw.h"
#include <QDebug>
#include <QFocusEvent>
#include <QHBoxLayout>
#include <QMdiSubWindow>
#include <QMenu>
#include <QScrollBar>
#include <QTimer>
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuGridPlotWindow::RiuGridPlotWindow( RimGridPlotWindow* plotDefinition, QWidget* parent )
: QWidget( parent )
{
Q_ASSERT( plotDefinition );
m_plotDefinition = plotDefinition;
m_layout = new QVBoxLayout( this );
m_layout->setMargin( 0 );
m_layout->setSpacing( 2 );
m_plotTitle = createTitleLabel();
m_layout->addWidget( m_plotTitle );
m_plotLayout = new QHBoxLayout;
m_layout->addLayout( m_plotLayout );
m_plotWidgetFrame = new QFrame;
m_plotWidgetFrame->setVisible( true );
m_plotLayout->addWidget( m_plotWidgetFrame, 1 );
m_gridLayout = new QGridLayout( m_plotWidgetFrame );
m_gridLayout->setMargin( 0 );
m_gridLayout->setSpacing( 2 );
QPalette newPalette( palette() );
newPalette.setColor( QPalette::Background, Qt::white );
setPalette( newPalette );
setAutoFillBackground( true );
m_scrollBar = new QScrollBar( nullptr );
m_scrollBar->setOrientation( Qt::Vertical );
m_scrollBar->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred );
m_scrollBarLayout = new QVBoxLayout;
m_scrollBarLayout->addWidget( m_scrollBar, 0 );
new RiuPlotObjectPicker( m_plotTitle, m_plotDefinition );
this->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding );
setFocusPolicy( Qt::StrongFocus );
setAcceptDrops( true );
RiaApplication* app = RiaApplication::instance();
int defaultFontSize = RiaFontCache::pointSizeFromFontSizeEnum( app->preferences()->defaultPlotFontSize() );
setFontSize( defaultFontSize );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuGridPlotWindow::~RiuGridPlotWindow()
{
if ( m_plotDefinition )
{
m_plotDefinition->detachAllCurves();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridPlotWindow* RiuGridPlotWindow::ownerPlotDefinition()
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimViewWindow* RiuGridPlotWindow::ownerViewWindow() const
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::addPlot( RiuQwtPlotWidget* plotWidget )
{
// Insert the plot to the left of the scroll bar
insertPlot( plotWidget, m_plotWidgets.size() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::insertPlot( RiuQwtPlotWidget* plotWidget, size_t index )
{
m_plotWidgets.insert( static_cast<int>( index ), plotWidget );
RiuQwtPlotLegend* legend = new RiuQwtPlotLegend( this );
int legendColumns = 1;
if ( m_plotDefinition->legendsHorizontal() )
{
legendColumns = 0; // unlimited
}
legend->setMaxColumns( legendColumns );
legend->horizontalScrollBar()->setVisible( false );
legend->verticalScrollBar()->setVisible( false );
legend->connect( plotWidget,
SIGNAL( legendDataChanged( const QVariant&, const QList<QwtLegendData>& ) ),
SLOT( updateLegend( const QVariant&, const QList<QwtLegendData>& ) ) );
legend->contentsWidget()->layout()->setAlignment( Qt::AlignBottom | Qt::AlignHCenter );
plotWidget->updateLegend();
m_legends.insert( static_cast<int>( index ), legend );
m_legendColumns.insert( static_cast<int>( index ), -1 );
scheduleUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::removePlot( RiuQwtPlotWidget* plotWidget )
{
if ( !plotWidget ) return;
int plotWidgetIdx = m_plotWidgets.indexOf( plotWidget );
CVF_ASSERT( plotWidgetIdx >= 0 );
m_plotWidgets.removeAt( plotWidgetIdx );
plotWidget->setParent( nullptr );
RiuQwtPlotLegend* legend = m_legends[plotWidgetIdx];
m_legends.removeAt( plotWidgetIdx );
m_legendColumns.removeAt( plotWidgetIdx );
delete legend;
scheduleUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::setPlotTitle( const QString& plotTitle )
{
m_plotTitle->setText( plotTitle );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuGridPlotWindow::preferredWidth() const
{
int titleWidth = 0;
if ( m_plotTitle && m_plotTitle->isVisible() )
{
titleWidth = m_plotTitle->width();
}
QList<QPointer<RiuQwtPlotWidget>> visiblePlotWidgets = this->visiblePlotWidgets();
auto rowAndColumnCount = this->rowAndColumnCount( visiblePlotWidgets.size() );
int sumColumnWidths = 0;
for ( int visibleIndex = 0; visibleIndex < rowAndColumnCount.second; ++visibleIndex )
{
sumColumnWidths += visiblePlotWidgets[visibleIndex]->width();
}
return std::max( titleWidth, sumColumnWidths );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::setTitleVisible( bool visible )
{
m_plotTitle->setVisible( visible );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::setScrollbarVisible( bool visible )
{
m_scrollBar->setVisible( visible );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::setSelectionsVisible( bool visible )
{
for ( RiuQwtPlotWidget* plotWidget : m_plotWidgets )
{
if ( !visible )
{
plotWidget->setDefaultStyleSheet( false );
}
else
{
plotWidget->setSelected( caf::SelectionManager::instance()->isSelected( plotWidget->plotOwner(), 0 ) );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::setFontSize( int fontSize )
{
QFont font = m_plotTitle->font();
font.setPointSize( fontSize + 1 );
font.setBold( true );
m_plotTitle->setFont( font );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuGridPlotWindow::fontSize() const
{
return m_plotTitle->font().pointSize() - 1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuGridPlotWindow::indexOfPlotWidget( RiuQwtPlotWidget* plotWidget )
{
return m_plotWidgets.indexOf( plotWidget );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::scheduleUpdate()
{
RiaPlotWindowRedrawScheduler::instance()->schedulePlotWindowUpdate( this );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::scheduleReplotOfAllPlots()
{
for ( RiuQwtPlotWidget* plotWidget : visiblePlotWidgets() )
{
plotWidget->scheduleReplot();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::contextMenuEvent( QContextMenuEvent* event )
{
QMenu menu;
caf::CmdFeatureMenuBuilder menuBuilder;
caf::SelectionManager::instance()->setSelectedItem( ownerPlotDefinition() );
menuBuilder << "RicShowPlotDataFeature";
menuBuilder << "RicShowContributingWellsFromPlotFeature";
menuBuilder.appendToMenu( &menu );
if ( menu.actions().size() > 0 )
{
menu.exec( event->globalPos() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::keyPressEvent( QKeyEvent* keyEvent )
{
m_plotDefinition->handleKeyPressEvent( keyEvent );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QLabel* RiuGridPlotWindow::createTitleLabel() const
{
QLabel* plotTitle = new QLabel( "PLOT TITLE HERE", nullptr );
plotTitle->setVisible( m_plotDefinition->isPlotTitleVisible() );
plotTitle->setAlignment( Qt::AlignHCenter );
plotTitle->setWordWrap( true );
plotTitle->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
return plotTitle;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::resizeEvent( QResizeEvent* event )
{
QWidget::resizeEvent( event );
bool needsUpdate = false;
for ( int i = 0; i < m_legends.size(); ++i )
{
if ( m_legends[i]->isVisible() )
{
int columnCount = m_legends[i]->columnCount();
if ( columnCount != m_legendColumns[i] )
{
int oldColumnCount = m_legendColumns[i];
m_legendColumns[i] = columnCount;
if ( oldColumnCount != -1 )
{
needsUpdate = true;
}
}
}
}
if ( needsUpdate )
{
performUpdate();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::showEvent( QShowEvent* event )
{
QWidget::showEvent( event );
performUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::dragEnterEvent( QDragEnterEvent* event )
{
if ( this->geometry().contains( event->pos() ) )
{
event->acceptProposedAction();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::dragMoveEvent( QDragMoveEvent* event )
{
if ( this->geometry().contains( event->pos() ) )
{
RiuQwtPlotWidget* source = dynamic_cast<RiuQwtPlotWidget*>( event->source() );
if ( source )
{
QRect originalGeometry = source->geometry();
QPoint offset = source->dragStartPosition();
QRect newRect( event->pos() - offset, originalGeometry.size() );
QList<QPointer<RiuQwtPlotWidget>> visiblePlotWidgets = this->visiblePlotWidgets();
int insertBeforeIndex = visiblePlotWidgets.size();
for ( int visibleIndex = 0; visibleIndex < visiblePlotWidgets.size(); ++visibleIndex )
{
visiblePlotWidgets[visibleIndex]->setDefaultStyleSheet();
if ( visiblePlotWidgets[visibleIndex]->frameIsInFrontOfThis( newRect ) )
{
insertBeforeIndex = std::min( insertBeforeIndex, visibleIndex );
}
}
if ( insertBeforeIndex >= 0 && insertBeforeIndex < visiblePlotWidgets.size() )
{
visiblePlotWidgets[insertBeforeIndex]->setStyleSheetForThisObject(
"border-left: 2px solid red; border-top: none; border-bottom: none; border-right: none;" );
}
if ( insertBeforeIndex > 0 )
{
int insertAfterIndex = insertBeforeIndex - 1;
visiblePlotWidgets[insertAfterIndex]->setStyleSheetForThisObject(
"border-left: none; border-top: none; border-bottom: none; border-right: 2px solid red;" );
}
event->acceptProposedAction();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::dragLeaveEvent( QDragLeaveEvent* event )
{
for ( int tIdx = 0; tIdx < m_plotWidgets.size(); ++tIdx )
{
m_plotWidgets[tIdx]->setDefaultStyleSheet();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::dropEvent( QDropEvent* event )
{
for ( int tIdx = 0; tIdx < m_plotWidgets.size(); ++tIdx )
{
m_plotWidgets[tIdx]->setDefaultStyleSheet();
}
if ( this->geometry().contains( event->pos() ) )
{
RiuQwtPlotWidget* source = dynamic_cast<RiuQwtPlotWidget*>( event->source() );
if ( source )
{
event->acceptProposedAction();
QRect originalGeometry = source->geometry();
QPoint offset = source->dragStartPosition();
QRect newRect( event->pos() - offset, originalGeometry.size() );
int beforeIndex = m_plotWidgets.size();
for ( int tIdx = 0; tIdx < m_plotWidgets.size(); ++tIdx )
{
if ( m_plotWidgets[tIdx]->isVisible() )
{
if ( m_plotWidgets[tIdx]->frameIsInFrontOfThis( newRect ) )
{
beforeIndex = tIdx;
break;
}
}
}
RimPlotInterface* insertAfter = nullptr;
if ( beforeIndex > 0 )
{
insertAfter = m_plotWidgets[beforeIndex - 1]->plotDefinition();
}
RimPlotInterface* plotWidget = source->plotDefinition();
if ( insertAfter != plotWidget )
{
RicWellLogPlotTrackFeatureImpl::movePlotsToGridPlotWindow( m_plotDefinition, { plotWidget }, insertAfter );
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<int, int> RiuGridPlotWindow::rowAndColumnCount( int plotWidgetCount ) const
{
int columnCount = std::max( 1, std::min( m_plotDefinition->columnCount(), plotWidgetCount ) );
int rowCount = static_cast<int>( std::ceil( plotWidgetCount / static_cast<double>( columnCount ) ) );
return std::make_pair( rowCount, columnCount );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::onSelectionManagerSelectionChanged( const std::set<int>& changedSelectionLevels )
{
for ( RiuQwtPlotWidget* plotWidget : m_plotWidgets )
{
bool isSelected = false;
for ( int changedLevel : changedSelectionLevels )
{
isSelected = isSelected ||
caf::SelectionManager::instance()->isSelected( plotWidget->plotOwner(), changedLevel );
}
plotWidget->setSelected( isSelected );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::performUpdate()
{
reinsertPlotWidgetsAndScrollbar();
alignCanvasTopsAndScrollbar();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::alignCanvasTopsAndScrollbar()
{
CVF_ASSERT( m_legends.size() == m_plotWidgets.size() );
QList<QPointer<RiuQwtPlotWidget>> plotWidgets = visiblePlotWidgets();
if ( plotWidgets.empty() ) return;
auto rowAndColumnCount = this->rowAndColumnCount( plotWidgets.size() );
std::vector<double> maxExtents( rowAndColumnCount.first, 0.0 );
for ( int visibleIndex = 0; visibleIndex < plotWidgets.size(); ++visibleIndex )
{
int row = visibleIndex / rowAndColumnCount.second;
QFont font = m_plotWidgets[visibleIndex]->axisFont( QwtPlot::xTop );
maxExtents[row] = std::max( maxExtents[row],
plotWidgets[visibleIndex]->axisScaleDraw( QwtPlot::xTop )->extent( font ) );
}
for ( int visibleIndex = 0; visibleIndex < plotWidgets.size(); ++visibleIndex )
{
int row = visibleIndex / rowAndColumnCount.second;
plotWidgets[visibleIndex]->axisScaleDraw( QwtPlot::xTop )->setMinimumExtent( maxExtents[row] );
}
m_scrollBarLayout->setContentsMargins( 0, maxExtents[0], 0, 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::reinsertPlotWidgetsAndScrollbar()
{
clearGridLayout();
for ( int tIdx = 0; tIdx < m_plotWidgets.size(); ++tIdx )
{
m_plotWidgets[tIdx]->hide();
m_legends[tIdx]->hide();
}
QList<QPointer<RiuQwtPlotWidget>> plotWidgets = this->visiblePlotWidgets();
QList<QPointer<RiuQwtPlotLegend>> legends = this->visibleLegends();
auto rowAndColumnCount = this->rowAndColumnCount( plotWidgets.size() );
for ( int visibleIndex = 0; visibleIndex < plotWidgets.size(); ++visibleIndex )
{
int row = visibleIndex / rowAndColumnCount.second;
int column = visibleIndex % rowAndColumnCount.second;
m_gridLayout->addWidget( legends[visibleIndex], 2 * row, column );
m_gridLayout->addWidget( plotWidgets[visibleIndex], 2 * row + 1, column );
if ( m_plotDefinition->legendsVisible() )
{
int legendColumns = 1;
if ( m_plotDefinition->legendsHorizontal() )
{
legendColumns = 0; // unlimited
}
legends[visibleIndex]->setMaxColumns( legendColumns );
int minimumHeight = legends[visibleIndex]->heightForWidth( plotWidgets[visibleIndex]->width() );
legends[visibleIndex]->setMinimumHeight( minimumHeight );
QFont legendFont = legends[visibleIndex]->font();
legendFont.setPointSize( fontSize() - 1 );
legends[visibleIndex]->setFont( legendFont );
legends[visibleIndex]->show();
}
else
{
legends[visibleIndex]->hide();
}
plotWidgets[visibleIndex]->setYAxisLabelsAndTicksEnabled( column == 0 );
plotWidgets[visibleIndex]->setYTitleEnabled( column == 0 );
plotWidgets[visibleIndex]->show();
int widthScaleFactor = plotWidgets[visibleIndex]->widthScaleFactor();
if ( column == 0 )
{
widthScaleFactor += 1; // Give it a bit extra room due to axis
}
m_gridLayout->setColumnStretch( column,
std::max( m_gridLayout->columnStretch( column ),
plotWidgets[visibleIndex]->widthScaleFactor() ) );
m_gridLayout->setRowStretch( 2 * row + 1, 1 );
}
m_gridLayout->addLayout( m_scrollBarLayout, 1, rowAndColumnCount.second, rowAndColumnCount.first * 2 - 1, 1 );
m_gridLayout->setColumnStretch( rowAndColumnCount.second, 0 );
m_scrollBar->setVisible( plotWidgets.size() > 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridPlotWindow::clearGridLayout()
{
if ( m_gridLayout )
{
for ( int tIdx = 0; tIdx < m_plotWidgets.size(); ++tIdx )
{
m_gridLayout->removeWidget( m_legends[tIdx] );
m_gridLayout->removeWidget( m_plotWidgets[tIdx] );
}
QLayoutItem* item;
while ( ( item = m_gridLayout->takeAt( 0 ) ) != 0 )
{
}
QWidget().setLayout( m_gridLayout );
delete m_gridLayout;
m_gridLayout = new QGridLayout( m_plotWidgetFrame );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<QPointer<RiuQwtPlotWidget>> RiuGridPlotWindow::visiblePlotWidgets() const
{
QList<QPointer<RiuQwtPlotWidget>> plotWidgets;
for ( QPointer<RiuQwtPlotWidget> plotWidget : m_plotWidgets )
{
if ( plotWidget->isChecked() )
{
plotWidgets.push_back( plotWidget );
}
}
return plotWidgets;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<QPointer<RiuQwtPlotLegend>> RiuGridPlotWindow::visibleLegends() const
{
QList<QPointer<RiuQwtPlotLegend>> legends;
for ( int i = 0; i < m_plotWidgets.size(); ++i )
{
if ( m_plotWidgets[i]->isChecked() )
{
legends.push_back( m_legends[i] );
}
}
return legends;
}

View File

@ -0,0 +1,124 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuInterfaceToViewWindow.h"
#include "cafPdmPointer.h"
#include "cafSelectionChangedReceiver.h"
#include <QFrame>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QList>
#include <QPointer>
#include <QWidget>
#include <map>
class RiaPlotWindowRedrawScheduler;
class RimGridPlotWindow;
class RiuQwtPlotLegend;
class RiuQwtPlotWidget;
class QFocusEvent;
class QLabel;
class QScrollBar;
//==================================================================================================
//
// RiuGridPlotWindow
//
//==================================================================================================
class RiuGridPlotWindow : public QWidget, public RiuInterfaceToViewWindow, public caf::SelectionChangedReceiver
{
Q_OBJECT
public:
RiuGridPlotWindow( RimGridPlotWindow* plotDefinition, QWidget* parent = nullptr );
~RiuGridPlotWindow() override;
RimGridPlotWindow* ownerPlotDefinition();
RimViewWindow* ownerViewWindow() const override;
void addPlot( RiuQwtPlotWidget* plotWidget );
void insertPlot( RiuQwtPlotWidget* plotWidget, size_t index );
void removePlot( RiuQwtPlotWidget* plotWidget );
void setPlotTitle( const QString& plotTitle );
int preferredWidth() const;
void setTitleVisible( bool visible );
void setScrollbarVisible( bool visible );
void setSelectionsVisible( bool visible );
void setFontSize( int fontSize );
int fontSize() const;
int indexOfPlotWidget( RiuQwtPlotWidget* plotWidget );
void scheduleUpdate();
void scheduleReplotOfAllPlots();
virtual void updateVerticalScrollBar( double visibleMin, double visibleMax, double totalMin, double totalMax ) {}
protected:
void contextMenuEvent( QContextMenuEvent* ) override;
void keyPressEvent( QKeyEvent* keyEvent ) override;
QLabel* createTitleLabel() const;
void resizeEvent( QResizeEvent* event ) override;
void showEvent( QShowEvent* event ) override;
void dragEnterEvent( QDragEnterEvent* event ) override;
void dragMoveEvent( QDragMoveEvent* event ) override;
void dragLeaveEvent( QDragLeaveEvent* event ) override;
void dropEvent( QDropEvent* event ) override;
std::pair<int, int> rowAndColumnCount( int plotWidgetCount ) const;
virtual void onSelectionManagerSelectionChanged( const std::set<int>& changedSelectionLevels ) override;
private slots:
void performUpdate();
private:
void alignCanvasTopsAndScrollbar();
void reinsertPlotWidgetsAndScrollbar();
void clearGridLayout();
QList<QPointer<RiuQwtPlotWidget>> visiblePlotWidgets() const;
QList<QPointer<RiuQwtPlotLegend>> visibleLegends() const;
protected:
QPointer<QVBoxLayout> m_layout;
QPointer<QHBoxLayout> m_plotLayout;
QPointer<QFrame> m_plotWidgetFrame;
QPointer<QGridLayout> m_gridLayout;
QPointer<QLabel> m_plotTitle;
QPointer<QVBoxLayout> m_scrollBarLayout;
QScrollBar* m_scrollBar;
QList<QPointer<RiuQwtPlotLegend>> m_legends;
QList<int> m_legendColumns;
QList<QPointer<RiuQwtPlotWidget>> m_plotWidgets;
caf::PdmPointer<RimGridPlotWindow> m_plotDefinition;
private:
friend class RiaPlotWindowRedrawScheduler;
};

View File

@ -206,6 +206,35 @@ void RiuMainWindowBase::selectAsCurrentItem( const caf::PdmObject* object, bool
m_allowActiveViewChangeFromSelection = true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMainWindowBase::toggleItemInSelection( const caf::PdmObject* object, bool allowActiveViewChange )
{
m_allowActiveViewChangeFromSelection = allowActiveViewChange;
std::vector<caf::PdmUiItem*> currentSelection;
m_projectTreeView->selectedUiItems( currentSelection );
std::vector<const caf::PdmUiItem*> updatedSelection;
bool alreadySelected = false;
for ( caf::PdmUiItem* uiItem : currentSelection )
{
if ( object == uiItem )
{
alreadySelected = true;
}
else
{
updatedSelection.push_back( uiItem );
}
}
if ( !alreadySelected )
{
updatedSelection.push_back( object );
}
m_projectTreeView->selectItems( updatedSelection );
m_allowActiveViewChangeFromSelection = true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -67,6 +67,7 @@ public:
void setExpanded( const caf::PdmUiItem* uiItem, bool expanded = true );
void selectAsCurrentItem( const caf::PdmObject* object, bool allowActiveViewChange = true );
void toggleItemInSelection( const caf::PdmObject* object, bool allowActiveViewChange = true );
void enableShowFirstVisibleMdiWindowMaximized( bool enable );

View File

@ -27,7 +27,6 @@
#include "RiuMainWindow.h"
#include "RiuPlotMainWindow.h"
#include "RiuViewer.h"
#include "RiuWellLogPlot.h"
#include <QWindowStateChangeEvent>

View File

@ -37,11 +37,11 @@
#include "RiuDockWidgetTools.h"
#include "RiuDragDrop.h"
#include "RiuGridPlotWindow.h"
#include "RiuMdiSubWindow.h"
#include "RiuToolTipMenu.h"
#include "RiuTreeViewEventFilter.h"
#include "RiuWellAllocationPlot.h"
#include "RiuWellLogPlot.h"
#include "cafCmdFeatureManager.h"
#include "cafPdmObjectHandle.h"
@ -606,7 +606,7 @@ void RiuPlotMainWindow::addViewer( QWidget* viewer, const RimMdiWindowGeometry&
}
else
{
RiuWellLogPlot* wellLogPlot = dynamic_cast<RiuWellLogPlot*>( viewer );
RiuGridPlotWindow* wellLogPlot = dynamic_cast<RiuGridPlotWindow*>( viewer );
if ( wellLogPlot )
{
subWindowSize = QSize( wellLogPlot->preferredWidth(), m_mdiArea->height() );

View File

@ -70,6 +70,19 @@ void RiuPlotMainWindowTools::selectAsCurrentItem( const caf::PdmObject* object,
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotMainWindowTools::toggleItemInSelection( const caf::PdmObject* object, bool allowActiveViewChange /*= true*/ )
{
if ( RiaGuiApplication::isRunning() )
{
RiuPlotMainWindow* mpw = RiaGuiApplication::instance()->mainPlotWindow();
if ( mpw ) mpw->toggleItemInSelection( object, allowActiveViewChange );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -33,5 +33,6 @@ public:
static void setActiveViewer( QWidget* subWindow );
static void setExpanded( const caf::PdmUiItem* uiItem, bool expanded = true );
static void selectAsCurrentItem( const caf::PdmObject* object, bool allowActiveViewChange = true );
static void toggleItemInSelection( const caf::PdmObject* object, bool allowActiveViewChange = true );
static void refreshToolbars();
};

View File

@ -1,350 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016- Statoil ASA
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuQwtPlot.h"
#include "RiaColorTools.h"
#include "RimProject.h"
#include "RiuPlotMainWindowTools.h"
#include "RiuQwtCurvePointTracker.h"
#include "RiuQwtPlotTools.h"
#include "RiuQwtPlotWheelZoomer.h"
#include "RiuQwtPlotZoomer.h"
#include "RiuQwtScalePicker.h"
#include "qwt_date_scale_draw.h"
#include "qwt_date_scale_engine.h"
#include "qwt_legend.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_grid.h"
#include "qwt_plot_layout.h"
#include "qwt_plot_magnifier.h"
#include "qwt_plot_marker.h"
#include "qwt_plot_panner.h"
#include "qwt_plot_zoomer.h"
#include "qwt_scale_engine.h"
#include "qwt_symbol.h"
#include <QEvent>
#include <QMenu>
#include <QWheelEvent>
#include <cfloat>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtPlot::RiuQwtPlot( RimViewWindow* viewWindow, QWidget* parent )
: QwtPlot( parent )
{
Q_ASSERT( viewWindow );
m_ownerViewWindow = viewWindow;
// LeftButton for the zooming
m_zoomerLeft = new RiuQwtPlotZoomer( canvas() );
m_zoomerLeft->setRubberBandPen( QColor( Qt::black ) );
m_zoomerLeft->setTrackerMode( QwtPicker::AlwaysOff );
m_zoomerLeft->setTrackerPen( QColor( Qt::black ) );
m_zoomerLeft->initMousePattern( 1 );
// Attach a zoomer for the right axis
m_zoomerRight = new RiuQwtPlotZoomer( canvas() );
m_zoomerRight->setAxis( xTop, yRight );
m_zoomerRight->setTrackerMode( QwtPicker::AlwaysOff );
m_zoomerRight->initMousePattern( 1 );
// MidButton for the panning
QwtPlotPanner* panner = new QwtPlotPanner( canvas() );
panner->setMouseButton( Qt::MidButton );
auto wheelZoomer = new RiuQwtPlotWheelZoomer( this );
connect( wheelZoomer, SIGNAL( zoomUpdated() ), SLOT( onZoomedSlot() ) );
connect( m_zoomerLeft, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) );
connect( panner, SIGNAL( panned( int, int ) ), SLOT( onZoomedSlot() ) );
RiuQwtScalePicker* scalePicker = new RiuQwtScalePicker( this );
connect( scalePicker, SIGNAL( clicked( int, double ) ), this, SLOT( onAxisClicked( int, double ) ) );
RiuQwtPlotTools::setCommonPlotBehaviour( this );
RiuQwtPlotTools::setDefaultAxes( this );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtPlot::~RiuQwtPlot()
{
if ( ownerPlotDefinition() )
{
ownerPlotDefinition()->detachAllCurves();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimRiuQwtPlotOwnerInterface* RiuQwtPlot::ownerPlotDefinition() const
{
RimRiuQwtPlotOwnerInterface* plotDefinition = dynamic_cast<RimRiuQwtPlotOwnerInterface*>( ownerViewWindow() );
return plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimViewWindow* RiuQwtPlot::ownerViewWindow() const
{
return m_ownerViewWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuQwtPlot::minimumSizeHint() const
{
return QSize( 0, 100 );
}
//--------------------------------------------------------------------------------------------------
/// Empty default implementation
//--------------------------------------------------------------------------------------------------
void RiuQwtPlot::selectSample( QwtPlotCurve* curve, int sampleNumber ) {}
//--------------------------------------------------------------------------------------------------
/// Empty default implementation
//--------------------------------------------------------------------------------------------------
void RiuQwtPlot::clearSampleSelection() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlot::hideEvent( QHideEvent* event )
{
resetCurveHighlighting();
QwtPlot::hideEvent( event );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuQwtPlot::sizeHint() const
{
return QSize( 0, 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QwtInterval RiuQwtPlot::currentAxisRange( QwtPlot::Axis axis )
{
return axisScaleDiv( axis ).interval();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuQwtPlot::eventFilter( QObject* watched, QEvent* event )
{
if ( watched == canvas() )
{
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>( event );
if ( mouseEvent )
{
if ( mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonRelease )
{
bool anyZoomingActive = false;
if ( m_zoomerLeft && m_zoomerLeft->isActiveAndValid() )
{
anyZoomingActive = true;
}
if ( m_zoomerRight && m_zoomerRight->isActiveAndValid() )
{
anyZoomingActive = true;
}
if ( !anyZoomingActive )
{
selectClosestCurve( mouseEvent->pos() );
}
}
}
}
return QwtPlot::eventFilter( watched, event );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlot::selectClosestCurve( const QPoint& pos )
{
QwtPlotCurve* closestCurve = nullptr;
double distMin = DBL_MAX;
int closestCurvePoint = -1;
const QwtPlotItemList& itmList = itemList();
for ( QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); it++ )
{
if ( ( *it )->rtti() == QwtPlotItem::Rtti_PlotCurve )
{
QwtPlotCurve* candidateCurve = static_cast<QwtPlotCurve*>( *it );
double dist = DBL_MAX;
int curvePoint = candidateCurve->closestPoint( pos, &dist );
if ( dist < distMin )
{
closestCurve = candidateCurve;
distMin = dist;
closestCurvePoint = curvePoint;
}
}
}
resetCurveHighlighting();
if ( closestCurve && distMin < 20 )
{
CVF_ASSERT( closestCurvePoint >= 0 );
caf::PdmObject* selectedPlotObject = ownerPlotDefinition()->findRimPlotObjectFromQwtCurve( closestCurve );
if ( selectedPlotObject )
{
RimProject* proj = nullptr;
selectedPlotObject->firstAncestorOrThisOfType( proj );
if ( proj )
{
RiuPlotMainWindowTools::showPlotMainWindow();
RiuPlotMainWindowTools::selectAsCurrentItem( selectedPlotObject );
highlightCurve( closestCurve );
}
}
}
if ( closestCurve && distMin < 10 )
{
selectSample( closestCurve, closestCurvePoint );
}
else
{
clearSampleSelection();
}
replot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlot::highlightCurve( const QwtPlotCurve* closestCurve )
{
// NB! Create a copy of the item list before the loop to avoid invalidated iterators when iterating the list
// plotCurve->setZ() causes the ordering of items in the list to change
auto plotItemList = this->itemList();
for ( QwtPlotItem* plotItem : plotItemList )
{
QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve*>( plotItem );
if ( plotCurve )
{
QPen existingPen = plotCurve->pen();
QColor bgColor = this->canvasBackground().color();
QColor curveColor = existingPen.color();
QColor symbolColor;
QColor symbolLineColor;
QwtSymbol* symbol = const_cast<QwtSymbol*>( plotCurve->symbol() );
if ( symbol )
{
symbolColor = symbol->brush().color();
symbolLineColor = symbol->pen().color();
}
double zValue = plotCurve->z();
if ( plotCurve == closestCurve )
{
plotCurve->setZ( zValue + 100.0 );
}
else
{
QColor blendedColor = RiaColorTools::blendQColors( bgColor, curveColor, 3, 1 );
QColor blendedSymbolColor = RiaColorTools::blendQColors( bgColor, symbolColor, 3, 1 );
QColor blendedSymbolLineColor = RiaColorTools::blendQColors( bgColor, symbolLineColor, 3, 1 );
plotCurve->setPen( blendedColor, existingPen.width(), existingPen.style() );
if ( symbol )
{
symbol->setColor( blendedSymbolColor );
symbol->setPen( blendedSymbolLineColor, symbol->pen().width(), symbol->pen().style() );
}
}
CurveColors curveColors = {curveColor, symbolColor, symbolLineColor};
m_originalCurveColors.insert( std::make_pair( plotCurve, curveColors ) );
m_originalZValues.insert( std::make_pair( plotCurve, zValue ) );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlot::resetCurveHighlighting()
{
// NB! Create a copy of the item list before the loop to avoid invalidated iterators when iterating the list
// plotCurve->setZ() causes the ordering of items in the list to change
auto plotItemList = this->itemList();
for ( QwtPlotItem* plotItem : plotItemList )
{
QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve*>( plotItem );
if ( plotCurve && m_originalCurveColors.count( plotCurve ) )
{
const QPen& existingPen = plotCurve->pen();
auto colors = m_originalCurveColors[plotCurve];
double zValue = m_originalZValues[plotCurve];
plotCurve->setPen( colors.lineColor, existingPen.width(), existingPen.style() );
plotCurve->setZ( zValue );
QwtSymbol* symbol = const_cast<QwtSymbol*>( plotCurve->symbol() );
if ( symbol )
{
symbol->setColor( colors.symbolColor );
symbol->setPen( colors.symbolLineColor, symbol->pen().width(), symbol->pen().style() );
}
}
}
m_originalCurveColors.clear();
m_originalZValues.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlot::onZoomedSlot()
{
ownerPlotDefinition()->updateZoomWindowFromQwt();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlot::onAxisClicked( int axis, double value )
{
ownerPlotDefinition()->selectAxisInPropertyEditor( axis );
}

View File

@ -1,92 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016- Statoil ASA
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuInterfaceToViewWindow.h"
#include "RimRiuQwtPlotOwnerInterface.h"
#include "cafPdmPointer.h"
#include "qwt_plot.h"
#include <QPointer>
class RiuQwtPlotZoomer;
class QwtPlotCurve;
class QwtPlotGrid;
class QwtInterval;
class QwtPicker;
class QwtPlotMarker;
class QwtScaleWidget;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuQwtPlot : public QwtPlot, public RiuInterfaceToViewWindow
{
Q_OBJECT;
public:
RiuQwtPlot( RimViewWindow* viewWindow, QWidget* parent = nullptr );
~RiuQwtPlot() override;
RimRiuQwtPlotOwnerInterface* ownerPlotDefinition() const;
RimViewWindow* ownerViewWindow() const override;
QwtInterval currentAxisRange( QwtPlot::Axis axis );
protected:
bool eventFilter( QObject* watched, QEvent* event ) override;
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
virtual void selectSample( QwtPlotCurve* curve, int sampleNumber );
virtual void clearSampleSelection();
virtual void hideEvent( QHideEvent* event ) override;
private:
void selectClosestCurve( const QPoint& pos );
void highlightCurve( const QwtPlotCurve* closestCurve );
void resetCurveHighlighting();
private slots:
void onZoomedSlot();
void onAxisClicked( int axis, double value );
private:
struct CurveColors
{
QColor lineColor;
QColor symbolColor;
QColor symbolLineColor;
};
caf::PdmPointer<RimViewWindow> m_ownerViewWindow;
QPointer<RiuQwtPlotZoomer> m_zoomerLeft;
QPointer<RiuQwtPlotZoomer> m_zoomerRight;
std::map<QwtPlotCurve*, CurveColors> m_originalCurveColors;
std::map<QwtPlotCurve*, double> m_originalZValues;
};

View File

@ -15,22 +15,41 @@
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimPlot.h"
#include "RiuQwtPlotLegend.h"
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimPlot, "RimPlot" ); // Do not use. Abstract class
#include "qwt_dyngrid_layout.h"
#include <QResizeEvent>
#include <utility>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPlot::RimPlot()
RiuQwtPlotLegend::RiuQwtPlotLegend( QWidget* parent /*= nullptr */ )
: QwtLegend( parent )
, m_columnCount( -1 )
{
CAF_PDM_InitObject( "Plot", "", "", "" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* RimPlot::createPlotWidget()
void RiuQwtPlotLegend::resizeEvent( QResizeEvent* event )
{
return createViewWidget( nullptr );
QWidget::resizeEvent( event );
QSize size = event->size();
const QwtDynGridLayout* legendLayout = qobject_cast<QwtDynGridLayout*>( contentsWidget()->layout() );
if ( legendLayout )
{
m_columnCount = legendLayout->columnsForWidth( size.width() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuQwtPlotLegend::columnCount() const
{
return m_columnCount;
}

View File

@ -17,15 +17,16 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimNameConfig.h"
#include "RimViewWindow.h"
#include "qwt_legend.h"
class RimPlot : public RimViewWindow
class RiuQwtPlotLegend : public QwtLegend
{
CAF_PDM_HEADER_INIT;
Q_OBJECT
public:
RimPlot();
RiuQwtPlotLegend( QWidget* parent = nullptr );
void resizeEvent( QResizeEvent* event );
int columnCount() const;
QWidget* createPlotWidget();
private:
mutable int m_columnCount;
};

View File

@ -25,7 +25,9 @@
#include "qwt_plot.h"
#include "qwt_plot_grid.h"
#include "qwt_plot_layout.h"
#include "qwt_scale_widget.h"
#include <QGraphicsDropShadowEffect>
#include <QRegExp>
#include <vector>
@ -43,11 +45,15 @@ void RiuQwtPlotTools::setCommonPlotBehaviour( QwtPlot* plot )
plot->setAutoFillBackground( true );
plot->setCanvasBackground( Qt::white );
plot->canvas()->setContentsMargins( 1, 1, 1, 1 );
QFrame* canvasFrame = dynamic_cast<QFrame*>( plot->canvas() );
if ( canvasFrame )
{
canvasFrame->setFrameShape( QFrame::NoFrame );
}
canvasFrame->setFrameShape( QFrame::Box );
QGraphicsDropShadowEffect* dropShadowEffect = new QGraphicsDropShadowEffect( plot->canvas() );
dropShadowEffect->setOffset( 1.0, 1.0 );
dropShadowEffect->setBlurRadius( 3.0 );
dropShadowEffect->setColor( QColor( 60, 60, 60, 60 ) );
plot->canvas()->setGraphicsEffect( dropShadowEffect );
// Grid
@ -57,9 +63,11 @@ void RiuQwtPlotTools::setCommonPlotBehaviour( QwtPlot* plot )
gridPen.setColor( Qt::lightGray );
grid->setPen( gridPen );
int fontSize = RiaFontCache::pointSizeFromFontSizeEnum(
RiaApplication::instance()->preferences()->defaultPlotFontSize() );
// Axis number font
QFont axisFont = plot->axisFont( QwtPlot::xBottom );
axisFont.setPointSize( 10 );
axisFont.setPointSize( fontSize );
plot->setAxisFont( QwtPlot::xBottom, axisFont );
plot->setAxisFont( QwtPlot::xTop, axisFont );
@ -67,13 +75,13 @@ void RiuQwtPlotTools::setCommonPlotBehaviour( QwtPlot* plot )
plot->setAxisFont( QwtPlot::yRight, axisFont );
// Axis title font
std::vector<QwtPlot::Axis> axes = {QwtPlot::xBottom, QwtPlot::xTop, QwtPlot::yLeft, QwtPlot::yRight};
std::vector<QwtPlot::Axis> axes = { QwtPlot::xBottom, QwtPlot::xTop, QwtPlot::yLeft, QwtPlot::yRight };
for ( QwtPlot::Axis axis : axes )
{
QwtText axisTitle = plot->axisTitle( axis );
QFont axisTitleFont = axisTitle.font();
axisTitleFont.setPointSize( 10 );
axisTitleFont.setPointSize( fontSize );
axisTitleFont.setBold( false );
axisTitle.setFont( axisTitleFont );
axisTitle.setRenderFlags( Qt::AlignRight );
@ -89,10 +97,16 @@ void RiuQwtPlotTools::setCommonPlotBehaviour( QwtPlot* plot )
// Enable mousetracking and event filter
plot->canvas()->setMouseTracking( true );
plot->canvas()->installEventFilter( plot );
plot->plotLayout()->setAlignCanvasToScales( true );
plot->setContentsMargins( 4, 4, 4, 4 );
plot->setContentsMargins( 2, 2, 2, 2 );
// Store the pointer address as an object name. This way each plot can be identified uniquely for CSS-stylesheets
QString objectName = QString( "%1" ).arg( reinterpret_cast<uint64_t>( plot ) );
plot->setObjectName( objectName );
QString canvasName = QString( "%1" ).arg( reinterpret_cast<uint64_t>( plot->canvas() ) );
plot->canvas()->setObjectName( canvasName );
}
//--------------------------------------------------------------------------------------------------
@ -105,6 +119,11 @@ void RiuQwtPlotTools::setDefaultAxes( QwtPlot* plot )
plot->enableAxis( QwtPlot::xTop, false );
plot->enableAxis( QwtPlot::yRight, false );
plot->axisScaleDraw( QwtPlot::xBottom )->enableComponent( QwtAbstractScaleDraw::Backbone, false );
plot->axisScaleDraw( QwtPlot::yLeft )->enableComponent( QwtAbstractScaleDraw::Backbone, false );
plot->axisWidget( QwtPlot::xBottom )->setMargin( 0 );
plot->axisWidget( QwtPlot::yLeft )->setMargin( 0 );
plot->setAxisMaxMinor( QwtPlot::xBottom, 2 );
plot->setAxisMaxMinor( QwtPlot::yLeft, 3 );
}
@ -120,14 +139,14 @@ void RiuQwtPlotTools::enableDateBasedBottomXAxis( QwtPlot*
{
QwtDateScaleDraw* scaleDraw = new QwtDateScaleDraw( Qt::UTC );
std::set<QwtDate::IntervalType> intervals = {QwtDate::Year,
QwtDate::Month,
QwtDate::Week,
QwtDate::Day,
QwtDate::Hour,
QwtDate::Minute,
QwtDate::Second,
QwtDate::Millisecond};
std::set<QwtDate::IntervalType> intervals = { QwtDate::Year,
QwtDate::Month,
QwtDate::Week,
QwtDate::Day,
QwtDate::Hour,
QwtDate::Minute,
QwtDate::Second,
QwtDate::Millisecond };
for ( QwtDate::IntervalType interval : intervals )
{

View File

@ -0,0 +1,830 @@
////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuQwtPlotWidget.h"
#include "RiaApplication.h"
#include "RiaColorTools.h"
#include "RiaPlotWindowRedrawScheduler.h"
#include "RimPlotCurve.h"
#include "RimPlotInterface.h"
#include "RiuPlotMainWindowTools.h"
#include "RiuQwtCurvePointTracker.h"
#include "RiuQwtPlotTools.h"
#include "RiuQwtLinearScaleEngine.h"
#include "RiuQwtScalePicker.h"
#include "cafAssert.h"
#include "qwt_legend.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_grid.h"
#include "qwt_plot_layout.h"
#include "qwt_plot_marker.h"
#include "qwt_plot_picker.h"
#include "qwt_scale_draw.h"
#include "qwt_scale_widget.h"
#include "qwt_symbol.h"
#include "qwt_text.h"
#include <QDrag>
#include <QFont>
#include <QGraphicsDropShadowEffect>
#include <QMimeData>
#include <QMouseEvent>
#include <QScrollArea>
#include <QWheelEvent>
#include <cfloat>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtPlotWidget::RiuQwtPlotWidget( RimPlotInterface* plotTrackDefinition, QWidget* parent )
: QwtPlot( parent )
{
m_plotOwner = dynamic_cast<caf::PdmObject*>( plotTrackDefinition );
CAF_ASSERT( m_plotOwner );
setDefaults();
this->installEventFilter( this );
this->canvas()->installEventFilter( this );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtPlotWidget::~RiuQwtPlotWidget() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuQwtPlotWidget::isChecked() const
{
if ( plotDefinition() )
{
return plotDefinition()->isChecked();
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuQwtPlotWidget::fontSize() const
{
for ( int axisId = 0; axisId < QwtPlot::axisCnt; ++axisId )
{
if ( this->axisEnabled( axisId ) )
{
return this->axisFont( axisId ).pointSize();
}
}
return -1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setFontSize( int fontSize )
{
// Axis number font
QFont axisFont = this->axisFont( QwtPlot::xBottom );
axisFont.setPointSize( fontSize );
setAxisFont( QwtPlot::xBottom, axisFont );
setAxisFont( QwtPlot::xTop, axisFont );
setAxisFont( QwtPlot::yLeft, axisFont );
setAxisFont( QwtPlot::yRight, axisFont );
// Axis title font
std::vector<QwtPlot::Axis> axes = { QwtPlot::xBottom, QwtPlot::xTop, QwtPlot::yLeft, QwtPlot::yRight };
for ( QwtPlot::Axis axis : axes )
{
QwtText axisTitle = this->axisTitle( axis );
QFont axisTitleFont = axisTitle.font();
axisTitleFont.setPointSize( fontSize );
axisTitleFont.setBold( false );
axisTitle.setFont( axisTitleFont );
axisTitle.setRenderFlags( Qt::AlignRight );
setAxisTitle( axis, axisTitle );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPlotInterface* RiuQwtPlotWidget::plotDefinition() const
{
return dynamic_cast<RimPlotInterface*>( m_plotOwner.p() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmObject* RiuQwtPlotWidget::plotOwner() const
{
return m_plotOwner.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setEnabledAxes( const std::set<QwtPlot::Axis> enabledAxes )
{
for ( int axisId = 0; axisId < QwtPlot::axisCnt; ++axisId )
{
QwtPlot::Axis axis = static_cast<QwtPlot::Axis>( axisId );
if ( enabledAxes.count( axis ) )
{
enableAxis( axis, true );
// Align the canvas with the actual min and max values of the curves
axisScaleEngine( axis )->setAttribute( QwtScaleEngine::Floating, true );
setAxisScale( axis, 0.0, 100.0 );
axisScaleDraw( axis )->setMinimumExtent( axisExtent( axis ) );
setMinimumWidth( defaultMinimumWidth() );
axisScaleDraw( axis )->enableComponent( QwtAbstractScaleDraw::Backbone, false );
axisWidget( axis )->setMargin( 0 );
}
else
{
enableAxis( axis, false );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setXTitle( const QString& title )
{
QwtText axisTitleX = axisTitle( QwtPlot::xTop );
if ( title != axisTitleX.text() )
{
axisTitleX.setText( title );
setAxisTitle( QwtPlot::xTop, axisTitleX );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setYTitle( const QString& title )
{
m_yAxisTitle = title;
applyYTitleToQwt();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setYTitleEnabled( bool enable )
{
m_yAxisTitleEnabled = enable;
applyYTitleToQwt();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QwtInterval RiuQwtPlotWidget::axisRange( QwtPlot::Axis axis )
{
return axisScaleDiv( axis ).interval();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setXRange( double min, double max, QwtPlot::Axis axis )
{
setAxisScale( axis, min, max );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setYRange( double min, double max )
{
// Note: Y-axis may be inverted
if ( axisScaleEngine( QwtPlot::yLeft )->testAttribute( QwtScaleEngine::Inverted ) )
{
setAxisScale( QwtPlot::yLeft, max, min );
}
else
{
setAxisScale( QwtPlot::yLeft, min, max );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setAxisInverted( QwtPlot::Axis axis )
{
axisScaleEngine( axis )->setAttribute( QwtScaleEngine::Inverted, true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setYAxisLabelsAndTicksEnabled( bool enable )
{
this->axisScaleDraw( QwtPlot::yLeft )->enableComponent( QwtAbstractScaleDraw::Ticks, enable );
this->axisScaleDraw( QwtPlot::yLeft )->enableComponent( QwtAbstractScaleDraw::Labels, enable );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::enableXGridLines( bool majorGridLines, bool minorGridLines )
{
QwtPlotItemList plotItems = this->itemList( QwtPlotItem::Rtti_PlotGrid );
for ( QwtPlotItem* plotItem : plotItems )
{
QwtPlotGrid* grid = static_cast<QwtPlotGrid*>( plotItem );
grid->setXAxis( QwtPlot::xTop );
grid->enableX( majorGridLines );
grid->enableXMin( minorGridLines );
grid->setMajorPen( Qt::lightGray, 1.0, Qt::SolidLine );
grid->setMinorPen( Qt::lightGray, 1.0, Qt::DashLine );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::enableYGridLines( bool majorGridLines, bool minorGridLines )
{
QwtPlotItemList plotItems = this->itemList( QwtPlotItem::Rtti_PlotGrid );
for ( QwtPlotItem* plotItem : plotItems )
{
QwtPlotGrid* grid = static_cast<QwtPlotGrid*>( plotItem );
grid->setYAxis( QwtPlot::yLeft );
grid->enableY( majorGridLines );
grid->enableYMin( minorGridLines );
grid->setMajorPen( Qt::lightGray, 1.0, Qt::SolidLine );
grid->setMinorPen( Qt::lightGray, 1.0, Qt::DashLine );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setMajorAndMinorTickIntervals( double majorTickInterval,
double minorTickInterval,
double minValue,
double maxValue,
QwtPlot::Axis axis /*= QwtPlot::xTop */ )
{
RiuQwtLinearScaleEngine* scaleEngine = dynamic_cast<RiuQwtLinearScaleEngine*>( this->axisScaleEngine( axis ) );
if ( scaleEngine )
{
QwtScaleDiv scaleDiv = scaleEngine->divideScaleWithExplicitIntervals( minValue,
maxValue,
majorTickInterval,
minorTickInterval );
this->setAxisScaleDiv( axis, scaleDiv );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setAutoTickIntervalCounts( int maxMajorTickIntervalCount,
int maxMinorTickIntervalCount,
QwtPlot::Axis axis )
{
this->setAxisMaxMajor( axis, maxMajorTickIntervalCount );
this->setAxisMaxMinor( axis, maxMinorTickIntervalCount );
// Reapply axis limits to force Qwt to use the tick settings.
QwtInterval currentRange = this->axisInterval( axis );
setAxisScale( currentRange.minValue(), currentRange.maxValue(), axis );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiuQwtPlotWidget::getCurrentMajorTickInterval() const
{
QwtScaleDiv scaleDiv = this->axisScaleDiv( QwtPlot::xTop );
QList<double> majorTicks = scaleDiv.ticks( QwtScaleDiv::MajorTick );
if ( majorTicks.size() < 2 ) return 0.0;
return majorTicks.at( 1 ) - majorTicks.at( 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiuQwtPlotWidget::getCurrentMinorTickInterval() const
{
QwtScaleDiv scaleDiv = this->axisScaleDiv( QwtPlot::xTop );
QList<double> minorTicks = scaleDiv.ticks( QwtScaleDiv::MinorTick );
if ( minorTicks.size() < 2 ) return 0.0;
return minorTicks.at( 1 ) - minorTicks.at( 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuQwtPlotWidget::axisExtent( QwtPlot::Axis axis ) const
{
QFont tickLabelFont = axisFont( axis );
int lineExtent = static_cast<int>( std::ceil( axisScaleDraw( axis )->extent( tickLabelFont ) ) );
if ( !axisTitle( axis ).text().isEmpty() )
{
QFont titleFont = axisTitle( axis ).font();
lineExtent += QFontMetrics( titleFont ).height();
}
return lineExtent;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuQwtPlotWidget::frameIsInFrontOfThis( const QRect& frameGeometry )
{
QRect ownGeometry = this->canvas()->geometry();
ownGeometry.translate( this->geometry().topLeft() );
if ( frameGeometry.bottom() < ownGeometry.center().y() )
{
return true;
}
else if ( frameGeometry.left() < ownGeometry.left() && frameGeometry.top() < ownGeometry.center().y() )
{
return true;
}
else
{
QRect intersection = ownGeometry.intersected( frameGeometry );
double ownArea = double( ownGeometry.height() ) * double( ownGeometry.width() );
double frameArea = double( frameGeometry.height() ) * double( frameGeometry.width() );
double intersectionArea = double( intersection.height() ) * double( intersection.width() );
if ( intersectionArea > 0.8 * std::min( ownArea, frameArea ) )
{
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QPoint RiuQwtPlotWidget::dragStartPosition() const
{
return m_clickPosition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setDefaultStyleSheet( bool includeHoverFrame )
{
setStyleSheetForThisObject( "background-color: white; border: 1px solid transparent;" );
if ( includeHoverFrame )
{
QString styleSheet = createHoverStyleSheet( "dotted" );
appendStyleSheetForThisObject( styleSheet, "hover" );
}
this->canvas()->setStyleSheet( QString( "QwtPlotCanvas#%1 { background-color: white; border: 1px solid black; }" )
.arg( this->canvas()->objectName() ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setStyleSheetForThisObject( const QString& content, const QString& state /*= "" */ )
{
QString stateTag = !state.isEmpty() ? QString( ":%1" ).arg( state ) : "";
QString stylesheet = QString( "QwtPlot#%1%2 { %3 }\n" ).arg( this->objectName() ).arg( stateTag ).arg( content );
setStyleSheet( stylesheet );
this->canvas()->setStyleSheet( QString( "QwtPlotCanvas#%1 { background-color: white; border: 1px solid black; }" )
.arg( this->canvas()->objectName() ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::appendStyleSheetForThisObject( const QString& content, const QString& state /*= ""*/ )
{
QString stateTag = !state.isEmpty() ? QString( ":%1" ).arg( state ) : "";
QString stylesheet = QString( "QwtPlot#%1%2 { %3 }\n" ).arg( this->objectName() ).arg( stateTag ).arg( content );
QString completeStyleSheet = this->styleSheet() + stylesheet;
setStyleSheet( completeStyleSheet );
this->canvas()->setStyleSheet( QString( "QwtPlotCanvas#%1 { background-color: white; border: 1px solid black; }" )
.arg( this->canvas()->objectName() ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuQwtPlotWidget::widthScaleFactor() const
{
if ( plotOwner() )
{
return plotDefinition()->widthScaleFactor();
}
return 1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::scheduleReplot()
{
RiaPlotWindowRedrawScheduler::instance()->schedulePlotWidgetReplot( this );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setSelected( bool selected )
{
if ( selected )
{
QColor defaultHighlightColor = this->palette().highlight().color();
QString styleSheet = createHoverStyleSheet( "solid" );
setStyleSheetForThisObject( styleSheet, "hover" );
appendStyleSheetForThisObject( QString( "border: 1px solid %1;" ).arg( defaultHighlightColor.name() ) );
}
else
{
setDefaultStyleSheet();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuQwtPlotWidget::sizeHint() const
{
return QSize( 0, 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuQwtPlotWidget::minimumSizeHint() const
{
return QSize( 0, 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuQwtPlotWidget::eventFilter( QObject* watched, QEvent* event )
{
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>( event );
if ( mouseEvent )
{
// Shift is the zoom modifier and is reserved for QwtZoomPickers
bool zoomModifierApplied = ( mouseEvent->modifiers() & Qt::ShiftModifier ) != 0;
if ( zoomModifierApplied ) return false;
bool toggleItemInSelection = ( mouseEvent->modifiers() & Qt::ControlModifier ) != 0;
if ( mouseEvent->type() == QMouseEvent::MouseButtonPress && mouseEvent->button() == Qt::LeftButton )
{
m_clickPosition = mouseEvent->pos();
}
if ( watched == this && !this->canvas()->geometry().contains( mouseEvent->pos() ) )
{
if ( mouseEvent->type() == QMouseEvent::MouseMove && ( mouseEvent->buttons() & Qt::LeftButton ) &&
!m_clickPosition.isNull() )
{
int dragLength = ( mouseEvent->pos() - m_clickPosition ).manhattanLength();
if ( dragLength >= QApplication::startDragDistance() )
{
QPoint dragPositionOffset = this->geometry().topLeft() - mouseEvent->pos();
QPixmap pixmap = this->grab();
QDrag* drag = new QDrag( this );
QMimeData* mimeData = new QMimeData;
mimeData->setImageData( pixmap );
drag->setMimeData( mimeData );
drag->setPixmap( pixmap );
drag->setHotSpot( mouseEvent->pos() );
drag->exec( Qt::MoveAction );
return true;
}
}
else if ( mouseEvent->type() == QMouseEvent::MouseButtonRelease &&
( mouseEvent->button() == Qt::LeftButton ) && !m_clickPosition.isNull() )
{
QWidget* childClicked = this->childAt( m_clickPosition );
if ( childClicked )
{
QwtScaleWidget* scaleWidget = qobject_cast<QwtScaleWidget*>( childClicked );
if ( scaleWidget )
{
onAxisSelected( scaleWidget, toggleItemInSelection );
return true;
}
}
else
{
selectPlotOwner( toggleItemInSelection );
return true;
}
}
}
else if ( watched == canvas() )
{
if ( mouseEvent->type() == QMouseEvent::MouseButtonRelease && mouseEvent->button() == Qt::LeftButton &&
!m_clickPosition.isNull() )
{
selectClosestCurve( mouseEvent->pos(), toggleItemInSelection );
return true;
}
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::hideEvent( QHideEvent* event )
{
resetCurveHighlighting();
QwtPlot::hideEvent( event );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::applyYTitleToQwt()
{
QString titleToApply = m_yAxisTitleEnabled ? m_yAxisTitle : QString( "" );
QwtText axisTitleY = axisTitle( QwtPlot::yLeft );
if ( titleToApply != axisTitleY.text() )
{
axisTitleY.setText( titleToApply );
setAxisTitle( QwtPlot::yLeft, axisTitleY );
setMinimumWidth( defaultMinimumWidth() + axisExtent( QwtPlot::yLeft ) );
}
}
//--------------------------------------------------------------------------------------------------
/// Empty default implementation
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::selectPoint( QwtPlotCurve* curve, int pointNumber ) {}
//--------------------------------------------------------------------------------------------------
/// Empty default implementation
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::clearPointSelection() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuQwtPlotWidget::createHoverStyleSheet( const QString& borderType )
{
QColor highlightColor = this->palette().highlight().color();
QColor backgroundColor = this->palette().background().color();
QColor blendedHighlightColor = RiaColorTools::blendQColors( highlightColor, backgroundColor, 2, 1 );
QColor nearlyBackgroundColor = RiaColorTools::blendQColors( highlightColor, backgroundColor, 1, 20 );
QString styleSheet = QString( "border: 1px %1 %2; background: qlineargradient(x1: 1, y1: 0, x2: 1, y2: 1, "
"stop: 0 %3, stop: 0.04 %4, stop:1 %5 );" )
.arg( borderType )
.arg( highlightColor.name() )
.arg( blendedHighlightColor.name() )
.arg( nearlyBackgroundColor.name() )
.arg( backgroundColor.name() );
return styleSheet;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::onAxisSelected( QwtScaleWidget* scale, bool toggleItemInSelection )
{
int axisId = -1;
for ( int i = 0; i < QwtPlot::axisCnt; ++i )
{
if ( scale == this->axisWidget( i ) )
{
axisId = i;
}
}
plotDefinition()->onAxisSelected( axisId, toggleItemInSelection );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::setDefaults()
{
setEnabledAxes( { QwtPlot::xTop, QwtPlot::yLeft } );
RiuQwtPlotTools::setCommonPlotBehaviour( this );
setDefaultStyleSheet();
}
void RiuQwtPlotWidget::selectPlotOwner( bool toggleItemInSelection )
{
if ( toggleItemInSelection )
{
RiuPlotMainWindowTools::toggleItemInSelection( plotOwner() );
}
else
{
RiuPlotMainWindowTools::selectAsCurrentItem( plotOwner() );
}
scheduleReplot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::selectClosestCurve( const QPoint& pos, bool toggleItemInSelection /*= false*/ )
{
QwtPlotCurve* closestCurve = nullptr;
double distMin = DBL_MAX;
int closestCurvePoint = -1;
const QwtPlotItemList& itmList = itemList();
for ( QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); it++ )
{
if ( ( *it )->rtti() == QwtPlotItem::Rtti_PlotCurve )
{
QwtPlotCurve* candidateCurve = static_cast<QwtPlotCurve*>( *it );
double dist = DBL_MAX;
int curvePoint = candidateCurve->closestPoint( pos, &dist );
if ( dist < distMin )
{
closestCurve = candidateCurve;
distMin = dist;
closestCurvePoint = curvePoint;
}
}
}
RiuPlotMainWindowTools::showPlotMainWindow();
resetCurveHighlighting();
if ( closestCurve && distMin < 20 )
{
if ( plotDefinition() )
{
RimPlotCurve* selectedCurve = dynamic_cast<RimPlotCurve*>(
plotDefinition()->findPdmObjectFromQwtCurve( closestCurve ) );
if ( selectedCurve )
{
if ( toggleItemInSelection )
{
RiuPlotMainWindowTools::toggleItemInSelection( selectedCurve );
}
else
{
RiuPlotMainWindowTools::selectAsCurrentItem( selectedCurve );
}
// TODO: highlight all selected curves
highlightCurve( closestCurve );
}
}
if ( distMin < 10 )
{
selectPoint( closestCurve, closestCurvePoint );
}
else
{
clearPointSelection();
}
scheduleReplot();
}
else
{
selectPlotOwner( toggleItemInSelection );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuQwtPlotWidget::defaultMinimumWidth()
{
return 80;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::replot()
{
QwtPlot::replot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::highlightCurve( const QwtPlotCurve* closestCurve )
{
// NB! Create a copy of the item list before the loop to avoid invalidated iterators when iterating the list
// plotCurve->setZ() causes the ordering of items in the list to change
auto plotItemList = this->itemList();
for ( QwtPlotItem* plotItem : plotItemList )
{
QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve*>( plotItem );
if ( plotCurve )
{
QPen existingPen = plotCurve->pen();
QColor bgColor = this->canvasBackground().color();
QColor curveColor = existingPen.color();
QColor symbolColor;
QColor symbolLineColor;
QwtSymbol* symbol = const_cast<QwtSymbol*>( plotCurve->symbol() );
if ( symbol )
{
symbolColor = symbol->brush().color();
symbolLineColor = symbol->pen().color();
}
double zValue = plotCurve->z();
if ( plotCurve == closestCurve )
{
plotCurve->setZ( zValue + 100.0 );
}
else
{
QColor blendedColor = RiaColorTools::blendQColors( bgColor, curveColor, 3, 1 );
QColor blendedSymbolColor = RiaColorTools::blendQColors( bgColor, symbolColor, 3, 1 );
QColor blendedSymbolLineColor = RiaColorTools::blendQColors( bgColor, symbolLineColor, 3, 1 );
plotCurve->setPen( blendedColor, existingPen.width(), existingPen.style() );
if ( symbol )
{
symbol->setColor( blendedSymbolColor );
symbol->setPen( blendedSymbolLineColor, symbol->pen().width(), symbol->pen().style() );
}
}
CurveColors curveColors = { curveColor, symbolColor, symbolLineColor };
m_originalCurveColors.insert( std::make_pair( plotCurve, curveColors ) );
m_originalCurveColors.insert( std::make_pair( plotCurve, curveColors ) );
m_originalZValues.insert( std::make_pair( plotCurve, zValue ) );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotWidget::resetCurveHighlighting()
{
// NB! Create a copy of the item list before the loop to avoid invalidated iterators when iterating the list
// plotCurve->setZ() causes the ordering of items in the list to change
auto plotItemList = this->itemList();
for ( QwtPlotItem* plotItem : plotItemList )
{
QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve*>( plotItem );
if ( plotCurve && m_originalCurveColors.count( plotCurve ) )
{
const QPen& existingPen = plotCurve->pen();
auto colors = m_originalCurveColors[plotCurve];
double zValue = m_originalZValues[plotCurve];
plotCurve->setPen( colors.lineColor, existingPen.width(), existingPen.style() );
plotCurve->setZ( zValue );
QwtSymbol* symbol = const_cast<QwtSymbol*>( plotCurve->symbol() );
if ( symbol )
{
symbol->setColor( colors.symbolColor );
symbol->setPen( colors.symbolLineColor, symbol->pen().width(), symbol->pen().style() );
}
}
}
m_originalCurveColors.clear();
m_originalZValues.clear();
}

View File

@ -0,0 +1,146 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "qwt_plot.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include <QPointer>
#include <set>
class RiaPlotWindowRedrawScheduler;
class RimPlotInterface;
class QwtLegend;
class QwtPicker;
class QwtPlotCurve;
class QwtPlotGrid;
class QwtPlotMarker;
class QwtPlotPicker;
class QEvent;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuQwtPlotWidget : public QwtPlot
{
Q_OBJECT
public:
RiuQwtPlotWidget( RimPlotInterface* plotTrackDefinition, QWidget* parent = nullptr );
~RiuQwtPlotWidget() override;
RimPlotInterface* plotDefinition() const;
caf::PdmObject* plotOwner() const;
bool isChecked() const;
int fontSize() const;
void setFontSize( int fontSize );
void setEnabledAxes( const std::set<QwtPlot::Axis> enabledAxes );
void setXTitle( const QString& title );
void setYTitle( const QString& title );
void setYTitleEnabled( bool enable );
QwtInterval axisRange( QwtPlot::Axis axis );
void setXRange( double min, double max, QwtPlot::Axis axis = QwtPlot::xTop );
void setYRange( double min, double max );
void setAxisInverted( QwtPlot::Axis axis );
void setYAxisLabelsAndTicksEnabled( bool enable );
void enableXGridLines( bool majorGridLines, bool minorGridLines );
void enableYGridLines( bool majorGridLines, bool minorGridLines );
void setMajorAndMinorTickIntervals( double majorTickInterval,
double minorTickInterval,
double minValue,
double maxValue,
QwtPlot::Axis axis = QwtPlot::xTop );
void setAutoTickIntervalCounts( int maxMajorTickIntervalCount,
int maxMinorTickIntervalCount,
QwtPlot::Axis axis = QwtPlot::xTop );
double getCurrentMajorTickInterval() const;
double getCurrentMinorTickInterval() const;
int axisExtent( QwtPlot::Axis axis ) const;
bool frameIsInFrontOfThis( const QRect& frameGeometry );
QPoint dragStartPosition() const;
void setDefaultStyleSheet( bool includeHoverFrame = true );
void setStyleSheetForThisObject( const QString& content, const QString& state = "" );
void appendStyleSheetForThisObject( const QString& content, const QString& state = "" );
int widthScaleFactor() const;
void scheduleReplot();
void setSelected( bool selected );
protected:
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
bool eventFilter( QObject* watched, QEvent* event ) override;
void hideEvent( QHideEvent* event ) override;
void applyYTitleToQwt();
virtual void selectPoint( QwtPlotCurve* curve, int pointNumber );
virtual void clearPointSelection();
QString createHoverStyleSheet( const QString& borderType = "solid" );
private:
void setDefaults();
void selectPlotOwner( bool toggleItemInSelection = false );
void selectClosestCurve( const QPoint& pos, bool toggleItemInSelection = false );
static int defaultMinimumWidth();
void replot() override;
void highlightCurve( const QwtPlotCurve* closestCurve );
void resetCurveHighlighting();
void onAxisSelected( QwtScaleWidget* scale, bool toggleItemInSelection );
private:
caf::PdmPointer<caf::PdmObject> m_plotOwner;
QPoint m_clickPosition;
QString m_yAxisTitle;
bool m_yAxisTitleEnabled;
QPointer<QwtPlotPicker> m_plotPicker;
struct CurveColors
{
QColor lineColor;
QColor symbolColor;
QColor symbolLineColor;
};
std::map<QwtPlotCurve*, CurveColors> m_originalCurveColors;
std::map<QwtPlotCurve*, double> m_originalZValues;
friend class RiaPlotWindowRedrawScheduler;
};

View File

@ -1,6 +1,7 @@
// Based on the example scalepicker from the Qwt/examples/event_filter
#include "RiuQwtScalePicker.h"
#include "RiuQwtPlotWidget.h"
#include <QMouseEvent>
@ -31,7 +32,7 @@ bool RiuQwtScalePicker::eventFilter( QObject* object, QEvent* event )
if ( scaleWidget )
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>( event );
mouseClicked( scaleWidget, mouseEvent->pos() );
Q_EMIT( mouseClicked( scaleWidget, mouseEvent->pos() ) );
return true;
}
@ -43,7 +44,7 @@ bool RiuQwtScalePicker::eventFilter( QObject* object, QEvent* event )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtScalePicker::mouseClicked( const QwtScaleWidget* scale, const QPoint& pos )
double RiuQwtScalePicker::axisValueAtPosition( const QwtScaleWidget* scale, const QPoint& pos )
{
QRect rect = scale->rect();
@ -85,6 +86,7 @@ void RiuQwtScalePicker::mouseClicked( const QwtScaleWidget* scale, const QPoint&
break;
}
}
Q_EMIT clicked( axis, value );
return value;
}
return std::numeric_limits<double>::infinity();
}

View File

@ -16,9 +16,8 @@ public:
bool eventFilter( QObject*, QEvent* ) override;
Q_SIGNALS:
void clicked( int axis, double value );
static double axisValueAtPosition( const QwtScaleWidget*, const QPoint& );
private:
void mouseClicked( const QwtScaleWidget*, const QPoint& );
Q_SIGNALS:
void mouseClicked( QwtScaleWidget*, const QPoint& );
};

View File

@ -23,6 +23,7 @@
#include "RimEnsembleCurveSet.h"
#include "RimEnsembleCurveSetCollection.h"
#include "RimMainPlotCollection.h"
#include "RimPlotInterface.h"
#include "RimRegularLegendConfig.h"
#include "RimSummaryCase.h"
#include "RimSummaryCurve.h"
@ -32,6 +33,7 @@
#include "RiuCvfOverlayItemWidget.h"
#include "RiuQwtCurvePointTracker.h"
#include "RiuQwtPlotWheelZoomer.h"
#include "RiuRimQwtPlotCurve.h"
#include "RiuWidgetDragger.h"
@ -89,11 +91,43 @@ static EnsembleCurveInfoTextProvider ensembleCurveInfoTextProvider;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuSummaryQwtPlot::RiuSummaryQwtPlot( RimViewWindow* viewWindow, QWidget* parent /*= nullptr*/ )
: RiuQwtPlot( viewWindow, parent )
RiuSummaryQwtPlot::RiuSummaryQwtPlot( RimPlotInterface* plotDefinition, QWidget* parent /*= nullptr*/ )
: RiuQwtPlotWidget( plotDefinition, parent )
{
// LeftButton for the zooming
m_zoomerLeft = new RiuQwtPlotZoomer( canvas() );
m_zoomerLeft->setRubberBandPen( QColor( Qt::black ) );
m_zoomerLeft->setTrackerMode( QwtPicker::AlwaysOff );
m_zoomerLeft->setTrackerPen( QColor( Qt::black ) );
m_zoomerLeft->initMousePattern( 1 );
m_zoomerLeft->setMousePattern( QwtEventPattern::MouseSelect1, Qt::LeftButton, Qt::ShiftModifier );
// Attach a zoomer for the right axis
m_zoomerRight = new RiuQwtPlotZoomer( canvas() );
m_zoomerRight->setAxis( xTop, yRight );
m_zoomerRight->setTrackerMode( QwtPicker::AlwaysOff );
m_zoomerRight->initMousePattern( 1 );
m_zoomerRight->setMousePattern( QwtEventPattern::MouseSelect1, Qt::LeftButton, Qt::ShiftModifier );
// MidButton for the panning
QwtPlotPanner* panner = new QwtPlotPanner( canvas() );
panner->setMouseButton( Qt::MidButton );
auto wheelZoomer = new RiuQwtPlotWheelZoomer( this );
connect( wheelZoomer, SIGNAL( zoomUpdated() ), SLOT( onZoomedSlot() ) );
connect( m_zoomerLeft, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) );
connect( m_zoomerRight, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) );
connect( panner, SIGNAL( panned( int, int ) ), SLOT( onZoomedSlot() ) );
setDefaults();
new RiuQwtCurvePointTracker( this, true, &ensembleCurveInfoTextProvider );
RiuQwtPlotTools::setCommonPlotBehaviour( this );
RiuQwtPlotTools::setDefaultAxes( this );
this->installEventFilter( this );
this->canvas()->installEventFilter( this );
}
//--------------------------------------------------------------------------------------------------
@ -162,12 +196,20 @@ void RiuSummaryQwtPlot::removeEnsembleCurveSetLegend( RimEnsembleCurveSet* curve
this->updateLegendLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimViewWindow* RiuSummaryQwtPlot::ownerViewWindow() const
{
return dynamic_cast<RimViewWindow*>( plotDefinition() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQwtPlot::keyPressEvent( QKeyEvent* keyEvent )
{
RimSummaryPlot* summaryPlot = dynamic_cast<RimSummaryPlot*>( ownerPlotDefinition() );
RimSummaryPlot* summaryPlot = dynamic_cast<RimSummaryPlot*>( plotDefinition() );
if ( summaryPlot )
{
@ -183,7 +225,7 @@ void RiuSummaryQwtPlot::contextMenuEvent( QContextMenuEvent* event )
QMenu menu;
caf::CmdFeatureMenuBuilder menuBuilder;
caf::SelectionManager::instance()->setSelectedItem( ownerViewWindow() );
caf::SelectionManager::instance()->setSelectedItem( plotOwner() );
menuBuilder << "RicShowPlotDataFeature";
menuBuilder << "RicSavePlotTemplateFeature";
@ -221,6 +263,14 @@ void RiuSummaryQwtPlot::updateLayout()
updateLegendLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQwtPlot::onZoomedSlot()
{
plotDefinition()->updateZoomFromQwt();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -234,7 +284,7 @@ void RiuSummaryQwtPlot::updateLegendLayout()
int ypos = startMarginY;
int maxColumnWidth = 0;
RimSummaryPlot* summaryPlot = dynamic_cast<RimSummaryPlot*>( ownerPlotDefinition() );
RimSummaryPlot* summaryPlot = dynamic_cast<RimSummaryPlot*>( plotDefinition() );
if ( !summaryPlot || !summaryPlot->ensembleCurveSetCollection() ) return;

View File

@ -20,7 +20,7 @@
#include "RiaQDateTimeTools.h"
#include "RiuInterfaceToViewWindow.h"
#include "RiuQwtPlot.h"
#include "RiuQwtPlotWidget.h"
#include "cafPdmPointer.h"
@ -28,18 +28,19 @@
class RimEnsembleCurveSet;
class RiuCvfOverlayItemWidget;
class RiuQwtPlotZoomer;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuSummaryQwtPlot : public RiuQwtPlot
class RiuSummaryQwtPlot : public RiuQwtPlotWidget, public RiuInterfaceToViewWindow
{
Q_OBJECT;
public:
RiuSummaryQwtPlot( RimViewWindow* ownerViewWindow, QWidget* parent = nullptr );
RiuSummaryQwtPlot( RimPlotInterface* plotDefinition, QWidget* parent = nullptr );
void useDateBasedTimeAxis(
const QString& dateFormat,
@ -52,13 +53,22 @@ public:
void addOrUpdateEnsembleCurveSetLegend( RimEnsembleCurveSet* curveSetToShowLegendFor );
void removeEnsembleCurveSetLegend( RimEnsembleCurveSet* curveSetToShowLegendFor );
RimViewWindow* ownerViewWindow() const override;
protected:
void keyPressEvent( QKeyEvent* ) override;
void contextMenuEvent( QContextMenuEvent* ) override;
void setDefaults();
void updateLayout() override;
private slots:
void onZoomedSlot();
private:
void updateLegendLayout();
void updateLegendLayout();
std::map<caf::PdmPointer<RimEnsembleCurveSet>, QPointer<RiuCvfOverlayItemWidget>> m_ensembleLegendWidgets;
QPointer<RiuQwtPlotZoomer> m_zoomerLeft;
QPointer<RiuQwtPlotZoomer> m_zoomerRight;
};

View File

@ -1,632 +1,51 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuWellLogPlot.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "WellLogCommands/RicWellLogPlotTrackFeatureImpl.h"
#include "RimContextCommandBuilder.h"
#include "RimPlotWindow.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RiuMainWindow.h"
#include "RiuPlotMainWindow.h"
#include "RiuPlotObjectPicker.h"
#include "RiuWellLogTrack.h"
#include "cafAssert.h"
#include "cafPdmPointer.h"
#include "cafCmdFeatureMenuBuilder.h"
#include "cafSelectionManager.h"
#include "cvfAssert.h"
#include "qwt_legend.h"
#include "qwt_plot_layout.h"
#include "qwt_scale_draw.h"
#include <QDebug>
#include <QFocusEvent>
#include <QHBoxLayout>
#include <QMdiSubWindow>
#include <QMenu>
#include <QScrollBar>
#include <QTimer>
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogPlot::RiuWellLogPlot( RimWellLogPlot* plotDefinition, QWidget* parent )
: QWidget( parent )
: RiuGridPlotWindow( plotDefinition, parent )
{
Q_ASSERT( plotDefinition );
m_plotDefinition = plotDefinition;
m_layout = new QVBoxLayout( this );
m_layout->setMargin( 0 );
m_layout->setSpacing( 2 );
m_plotTitle = createTitleLabel();
m_layout->addWidget( m_plotTitle );
m_plotLayout = new QHBoxLayout;
m_layout->addLayout( m_plotLayout );
m_trackFrame = new QFrame;
m_trackFrame->setVisible( true );
m_plotLayout->addWidget( m_trackFrame, 1 );
m_trackLayout = new QGridLayout( m_trackFrame );
m_trackLayout->setMargin( 0 );
m_trackLayout->setSpacing( 2 );
QPalette newPalette( palette() );
newPalette.setColor( QPalette::Background, Qt::white );
setPalette( newPalette );
setAutoFillBackground( true );
m_scrollBar = new QScrollBar( nullptr );
m_scrollBar->setOrientation( Qt::Vertical );
m_scrollBar->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred );
m_scrollBarLayout = new QVBoxLayout;
m_scrollBarLayout->addWidget( m_scrollBar, 0 );
new RiuPlotObjectPicker( m_plotTitle, m_plotDefinition );
this->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding );
setFocusPolicy( Qt::StrongFocus );
connect( m_scrollBar, SIGNAL( valueChanged( int ) ), this, SLOT( slotSetMinDepth( int ) ) );
setAcceptDrops( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogPlot::~RiuWellLogPlot()
RimWellLogPlot* RiuWellLogPlot::wellLogPlotDefinition()
{
if ( m_plotDefinition )
{
m_plotDefinition->detachAllCurves();
}
RimWellLogPlot* wellLogPlot = dynamic_cast<RimWellLogPlot*>( m_plotDefinition.p() );
CAF_ASSERT( wellLogPlot );
return wellLogPlot;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::addTrackPlot( RiuWellLogTrack* trackPlot )
void RiuWellLogPlot::updateVerticalScrollBar( double minVisible, double maxVisible, double minAvailable, double maxAvailable )
{
// Insert the plot to the left of the scroll bar
insertTrackPlot( trackPlot, m_trackPlots.size() );
}
maxAvailable += 0.01 * ( maxAvailable - minAvailable );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::insertTrackPlot( RiuWellLogTrack* trackPlot, size_t index, bool updateLayoutAfter )
{
m_trackPlots.insert( static_cast<int>( index ), trackPlot );
QwtLegend* legend = new QwtLegend( nullptr );
int legendColumns = 1;
if ( m_plotDefinition->areTrackLegendsHorizontal() )
{
legendColumns = 0; // unlimited
}
legend->setMaxColumns( legendColumns );
legend->horizontalScrollBar()->setVisible( false );
legend->verticalScrollBar()->setVisible( false );
legend->connect( trackPlot,
SIGNAL( legendDataChanged( const QVariant&, const QList<QwtLegendData>& ) ),
SLOT( updateLegend( const QVariant&, const QList<QwtLegendData>& ) ) );
legend->contentsWidget()->layout()->setAlignment( Qt::AlignBottom | Qt::AlignHCenter );
trackPlot->updateLegend();
m_legends.insert( static_cast<int>( index ), legend );
if ( updateLayoutAfter )
{
updateChildrenLayout();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::removeTrackPlot( RiuWellLogTrack* trackPlot, bool updateLayoutAfter )
{
if ( !trackPlot ) return;
int trackIdx = m_trackPlots.indexOf( trackPlot );
CVF_ASSERT( trackIdx >= 0 );
m_trackPlots.removeAt( trackIdx );
trackPlot->setParent( nullptr );
QwtLegend* legend = m_legends[trackIdx];
m_legends.removeAt( trackIdx );
delete legend;
if ( updateLayoutAfter )
{
updateChildrenLayout();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::setDepthZoomAndReplot( double minDepth, double maxDepth )
{
for ( int tpIdx = 0; tpIdx < m_trackPlots.count(); tpIdx++ )
{
m_trackPlots[tpIdx]->setDepthZoom( minDepth, maxDepth );
m_trackPlots[tpIdx]->replot();
}
updateScrollBar( minDepth, maxDepth );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::setPlotTitle( const QString& plotTitle )
{
m_plotTitle->setText( plotTitle );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuWellLogPlot::preferredWidth() const
{
int titleWidth = 0;
if ( m_plotTitle && m_plotTitle->isVisible() )
{
titleWidth = m_plotTitle->width();
}
int sumTrackWidth = 0;
for ( QPointer<RiuWellLogTrack> track : m_trackPlots )
{
if ( track->isVisible() )
{
sumTrackWidth += track->width();
}
}
return std::max( titleWidth, sumTrackWidth );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::setTitleVisible( bool visible )
{
m_plotTitle->setVisible( visible );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::setScrollbarVisible( bool visible )
{
m_scrollBar->setVisible( visible );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuWellLogPlot::indexOfTrackPlot( RiuWellLogTrack* track )
{
return m_trackPlots.indexOf( track );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::updateChildrenLayout()
{
reinsertTracksAndScrollbar();
alignCanvasTopsAndScrollbar();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::contextMenuEvent( QContextMenuEvent* event )
{
QMenu menu;
caf::CmdFeatureMenuBuilder menuBuilder;
caf::SelectionManager::instance()->setSelectedItem( ownerPlotDefinition() );
menuBuilder << "RicShowPlotDataFeature";
menuBuilder << "RicShowContributingWellsFromPlotFeature";
menuBuilder.appendToMenu( &menu );
if ( menu.actions().size() > 0 )
{
menu.exec( event->globalPos() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::keyPressEvent( QKeyEvent* keyEvent )
{
m_plotDefinition->handleKeyPressEvent( keyEvent );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QLabel* RiuWellLogPlot::createTitleLabel() const
{
QLabel* plotTitle = new QLabel( "PLOT TITLE HERE", nullptr );
RiaApplication* app = RiaApplication::instance();
QFont font = plotTitle->font();
int defaultFontSize = RiaFontCache::pointSizeFromFontSizeEnum( app->preferences()->defaultPlotFontSize() );
font.setPointSize( defaultFontSize + 1 );
font.setBold( true );
plotTitle->setFont( font );
plotTitle->setVisible( m_plotDefinition->isPlotTitleVisible() );
plotTitle->setAlignment( Qt::AlignHCenter );
plotTitle->setWordWrap( true );
plotTitle->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
return plotTitle;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::resizeEvent( QResizeEvent* event )
{
QWidget::resizeEvent( event );
updateChildrenLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::showEvent( QShowEvent* event )
{
QWidget::showEvent( event );
updateChildrenLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::changeEvent( QEvent* event )
{
QWidget::changeEvent( event );
if ( event->type() == QEvent::WindowStateChange )
{
updateChildrenLayout();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::dragEnterEvent( QDragEnterEvent* event )
{
if ( this->geometry().contains( event->pos() ) )
{
event->acceptProposedAction();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::dragMoveEvent( QDragMoveEvent* event )
{
if ( this->geometry().contains( event->pos() ) )
{
RiuWellLogTrack* source = dynamic_cast<RiuWellLogTrack*>( event->source() );
if ( source )
{
QRect originalGeometry = source->geometry();
QPoint offset = source->dragStartPosition();
QRect newRect( event->pos() - offset, originalGeometry.size() );
QList<QPointer<RiuWellLogTrack>> visibleTracks = this->visibleTracks();
int insertBeforeIndex = visibleTracks.size();
for ( int visibleIndex = 0; visibleIndex < visibleTracks.size(); ++visibleIndex )
{
visibleTracks[visibleIndex]->setDefaultStyleSheet();
if ( visibleTracks[visibleIndex]->frameIsInFrontOfThis( newRect ) )
{
insertBeforeIndex = std::min( insertBeforeIndex, visibleIndex );
}
}
if ( insertBeforeIndex >= 0 && insertBeforeIndex < visibleTracks.size() )
{
visibleTracks[insertBeforeIndex]->setStyleSheetForThisObject(
"border-left: 2px solid red; border-top: none; border-bottom: none; border-right: none;" );
}
if ( insertBeforeIndex > 0 )
{
int insertAfterIndex = insertBeforeIndex - 1;
visibleTracks[insertAfterIndex]->setStyleSheetForThisObject(
"border-left: none; border-top: none; border-bottom: none; border-right: 2px solid red;" );
}
event->acceptProposedAction();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::dragLeaveEvent( QDragLeaveEvent* event )
{
for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx )
{
m_trackPlots[tIdx]->setDefaultStyleSheet();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::dropEvent( QDropEvent* event )
{
for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx )
{
m_trackPlots[tIdx]->setDefaultStyleSheet();
}
if ( this->geometry().contains( event->pos() ) )
{
RiuWellLogTrack* source = dynamic_cast<RiuWellLogTrack*>( event->source() );
if ( source )
{
event->acceptProposedAction();
QRect originalGeometry = source->geometry();
QPoint offset = source->dragStartPosition();
QRect newRect( event->pos() - offset, originalGeometry.size() );
int beforeIndex = m_trackPlots.size();
for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx )
{
if ( m_trackPlots[tIdx]->isVisible() )
{
if ( m_trackPlots[tIdx]->frameIsInFrontOfThis( newRect ) )
{
beforeIndex = tIdx;
break;
}
}
}
RimWellLogTrack* insertAfter = nullptr;
if ( beforeIndex > 0 )
{
insertAfter = m_trackPlots[beforeIndex - 1]->plotDefinition();
}
RimWellLogTrack* rimTrack = source->plotDefinition();
if ( insertAfter != rimTrack )
{
RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( m_plotDefinition, {rimTrack}, insertAfter );
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<int, int> RiuWellLogPlot::rowAndColumnCount( int trackCount ) const
{
int columnCount = std::max( 1, std::min( m_plotDefinition->columnCount(), trackCount ) );
int rowCount = static_cast<int>( std::ceil( trackCount / static_cast<double>( columnCount ) ) );
return std::make_pair( rowCount, columnCount );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::updateScrollBar( double minDepth, double maxDepth )
{
double availableMinDepth;
double availableMaxDepth;
m_plotDefinition->availableDepthRange( &availableMinDepth, &availableMaxDepth );
availableMaxDepth += 0.01 * ( availableMaxDepth - availableMinDepth );
double visibleDepth = maxDepth - minDepth;
double visibleRange = maxVisible - minVisible;
m_scrollBar->blockSignals( true );
{
m_scrollBar->setRange( (int)availableMinDepth, (int)( ( availableMaxDepth - visibleDepth ) ) );
m_scrollBar->setPageStep( (int)visibleDepth );
m_scrollBar->setValue( (int)minDepth );
m_scrollBar->setRange( (int)minAvailable, (int)( ( maxAvailable - visibleRange ) ) );
m_scrollBar->setPageStep( (int)visibleRange );
m_scrollBar->setValue( (int)minVisible );
m_scrollBar->setVisible( true );
}
m_scrollBar->blockSignals( false );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::alignCanvasTopsAndScrollbar()
{
CVF_ASSERT( m_legends.size() == m_trackPlots.size() );
QList<QPointer<RiuWellLogTrack>> tracks = visibleTracks();
auto rowAndColumnCount = this->rowAndColumnCount( tracks.size() );
std::vector<double> maxExtents( rowAndColumnCount.first, 0.0 );
for ( int visibleIndex = 0; visibleIndex < tracks.size(); ++visibleIndex )
{
int row = visibleIndex / rowAndColumnCount.second;
QFont font = m_trackPlots[visibleIndex]->axisFont( QwtPlot::xTop );
maxExtents[row] = std::max( maxExtents[row],
tracks[visibleIndex]->axisScaleDraw( QwtPlot::xTop )->extent( font ) );
}
for ( int visibleIndex = 0; visibleIndex < tracks.size(); ++visibleIndex )
{
int row = visibleIndex / rowAndColumnCount.second;
tracks[visibleIndex]->axisScaleDraw( QwtPlot::xTop )->setMinimumExtent( maxExtents[row] );
}
m_scrollBarLayout->setContentsMargins( 0, maxExtents[0], 0, 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::reinsertTracksAndScrollbar()
{
clearTrackLayout();
for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx )
{
m_trackPlots[tIdx]->hide();
}
QList<QPointer<RiuWellLogTrack>> tracks = this->visibleTracks();
QList<QPointer<QwtLegend>> legends = this->visibleLegends();
auto rowAndColumnCount = this->rowAndColumnCount( tracks.size() );
for ( int visibleIndex = 0; visibleIndex < tracks.size(); ++visibleIndex )
{
int row = visibleIndex / rowAndColumnCount.second;
int column = visibleIndex % rowAndColumnCount.second;
m_trackLayout->addWidget( legends[visibleIndex], 2 * row, column );
m_trackLayout->addWidget( tracks[visibleIndex], 2 * row + 1, column );
if ( m_plotDefinition->areTrackLegendsVisible() )
{
int legendColumns = 1;
if ( m_plotDefinition->areTrackLegendsHorizontal() )
{
legendColumns = 0; // unlimited
}
legends[visibleIndex]->setMaxColumns( legendColumns );
int minimumHeight = legends[visibleIndex]->heightForWidth( tracks[visibleIndex]->width() );
legends[visibleIndex]->setMinimumHeight( minimumHeight );
legends[visibleIndex]->show();
}
else
{
legends[visibleIndex]->hide();
}
tracks[visibleIndex]->setDepthTitle( column == 0 ? m_plotDefinition->depthPlotTitle() : "" );
tracks[visibleIndex]->enableDepthAxisLabelsAndTicks( column == 0 );
tracks[visibleIndex]->show();
int widthScaleFactor = tracks[visibleIndex]->widthScaleFactor();
if ( column == 0 )
{
widthScaleFactor += 1; // Give it a bit extra room due to depth axis
}
m_trackLayout->setColumnStretch( column,
std::max( m_trackLayout->columnStretch( column ),
tracks[visibleIndex]->widthScaleFactor() ) );
m_trackLayout->setRowStretch( 2 * row + 1, 1 );
}
m_trackLayout->addLayout( m_scrollBarLayout, 1, rowAndColumnCount.second, rowAndColumnCount.first * 2 - 1, 1 );
m_trackLayout->setColumnStretch( rowAndColumnCount.second, 0 );
m_scrollBar->setVisible( tracks.size() > 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::clearTrackLayout()
{
if ( m_trackLayout )
{
for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx )
{
m_trackLayout->removeWidget( m_legends[tIdx] );
m_trackLayout->removeWidget( m_trackPlots[tIdx] );
}
QLayoutItem* item;
while ( ( item = m_trackLayout->takeAt( 0 ) ) != 0 )
{
}
QWidget().setLayout( m_trackLayout );
delete m_trackLayout;
m_trackLayout = new QGridLayout( m_trackFrame );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<QPointer<RiuWellLogTrack>> RiuWellLogPlot::visibleTracks() const
{
QList<QPointer<RiuWellLogTrack>> tracks;
for ( QPointer<RiuWellLogTrack> track : m_trackPlots )
{
if ( track->isRimTrackVisible() )
{
tracks.push_back( track );
}
}
return tracks;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<QPointer<QwtLegend>> RiuWellLogPlot::visibleLegends() const
{
QList<QPointer<QwtLegend>> legends;
for ( int i = 0; i < m_trackPlots.size(); ++i )
{
if ( m_trackPlots[i]->isRimTrackVisible() )
{
legends.push_back( m_legends[i] );
}
}
return legends;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -634,25 +53,9 @@ void RiuWellLogPlot::slotSetMinDepth( int value )
{
double minimumDepth;
double maximumDepth;
m_plotDefinition->depthZoomMinMax( &minimumDepth, &maximumDepth );
wellLogPlotDefinition()->availableDepthRange( &minimumDepth, &maximumDepth );
double delta = value - minimumDepth;
m_plotDefinition->setDepthZoomMinMax( minimumDepth + delta, maximumDepth + delta );
m_plotDefinition->setDepthAutoZoom( false );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogPlot* RiuWellLogPlot::ownerPlotDefinition()
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimViewWindow* RiuWellLogPlot::ownerViewWindow() const
{
return m_plotDefinition;
wellLogPlotDefinition()->setDepthAxisRange( minimumDepth + delta, maximumDepth + delta );
wellLogPlotDefinition()->setAutoScaleYEnabled( false );
}

View File

@ -1,7 +1,6 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
// Copyright (C) 2019- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -16,99 +15,22 @@
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuInterfaceToViewWindow.h"
#include "cafPdmPointer.h"
#include <QFrame>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QList>
#include <QPointer>
#include <QWidget>
#include <map>
#include "RiuGridPlotWindow.h"
class RimWellLogPlot;
class RiuWellLogTrack;
class QFocusEvent;
class QLabel;
class QScrollBar;
class QwtLegend;
//==================================================================================================
//
// RiuWellLogPlot
//
//==================================================================================================
class RiuWellLogPlot : public QWidget, public RiuInterfaceToViewWindow
class RiuWellLogPlot : public RiuGridPlotWindow
{
Q_OBJECT
public:
RiuWellLogPlot( RimWellLogPlot* plotDefinition, QWidget* parent = nullptr );
~RiuWellLogPlot() override;
RimWellLogPlot* ownerPlotDefinition();
RimViewWindow* ownerViewWindow() const override;
void addTrackPlot( RiuWellLogTrack* trackPlot );
void insertTrackPlot( RiuWellLogTrack* trackPlot, size_t index, bool updateLayoutAfter = true );
void removeTrackPlot( RiuWellLogTrack* trackPlot, bool updateLayoutAfter = true );
void setDepthZoomAndReplot( double minDepth, double maxDepth );
void setPlotTitle( const QString& plotTitle );
int preferredWidth() const;
void setTitleVisible( bool visible );
void setScrollbarVisible( bool visible );
int indexOfTrackPlot( RiuWellLogTrack* track );
public slots:
void updateChildrenLayout();
protected:
void contextMenuEvent( QContextMenuEvent* ) override;
void keyPressEvent( QKeyEvent* keyEvent ) override;
QLabel* createTitleLabel() const;
void resizeEvent( QResizeEvent* event ) override;
void showEvent( QShowEvent* event ) override;
void changeEvent( QEvent* ) override;
void dragEnterEvent( QDragEnterEvent* event ) override;
void dragMoveEvent( QDragMoveEvent* event ) override;
void dragLeaveEvent( QDragLeaveEvent* event ) override;
void dropEvent( QDropEvent* event ) override;
std::pair<int, int> rowAndColumnCount( int trackCount ) const;
RiuWellLogPlot( RimWellLogPlot* plotDefinition, QWidget* parent );
void updateVerticalScrollBar( double minVisible, double maxVisible, double minAvailable, double maxAvailable );
private:
void updateScrollBar( double minDepth, double maxDepth );
void alignCanvasTopsAndScrollbar();
void reinsertTracksAndScrollbar();
void clearTrackLayout();
QList<QPointer<RiuWellLogTrack>> visibleTracks() const;
QList<QPointer<QwtLegend>> visibleLegends() const;
RimWellLogPlot* wellLogPlotDefinition();
private slots:
void slotSetMinDepth( int value );
protected:
QPointer<QVBoxLayout> m_layout;
QPointer<QHBoxLayout> m_plotLayout;
QPointer<QFrame> m_trackFrame;
QPointer<QGridLayout> m_trackLayout;
QPointer<QLabel> m_plotTitle;
QPointer<QVBoxLayout> m_scrollBarLayout;
QScrollBar* m_scrollBar;
QList<QPointer<QwtLegend>> m_legends;
QList<QPointer<RiuWellLogTrack>> m_trackPlots;
caf::PdmPointer<RimWellLogPlot> m_plotDefinition;
};

View File

@ -1,521 +1,83 @@
////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuWellLogTrack.h"
#include "RiaApplication.h"
#include "RimWellLogCurve.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RiuPlotMainWindowTools.h"
#include "RiuQwtCurvePointTracker.h"
#include "RiuQwtPlotTools.h"
#include "RiuQwtLinearScaleEngine.h"
#include "qwt_legend.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_grid.h"
#include "qwt_plot_layout.h"
#include "qwt_plot_marker.h"
#include "qwt_plot_picker.h"
#include "qwt_scale_draw.h"
#include "qwt_scale_widget.h"
#include "qwt_symbol.h"
#include "qwt_text.h"
#include <QDrag>
#include <QFont>
#include <QGraphicsDropShadowEffect>
#include <QMimeData>
#include <QMouseEvent>
#include <QScrollArea>
#include <QWheelEvent>
#include <cfloat>
#define RIU_SCROLLWHEEL_ZOOMFACTOR 1.1
#define RIU_SCROLLWHEEL_PANFACTOR 0.1
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack::RiuWellLogTrack( RimWellLogTrack* plotTrackDefinition, QWidget* parent )
: QwtPlot( parent )
{
Q_ASSERT( plotTrackDefinition );
m_plotTrackDefinition = plotTrackDefinition;
setDefaults();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack::~RiuWellLogTrack() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setDepthZoom( double minDepth, double maxDepth )
{
// Note: Y-axis is inverted
setAxisScale( QwtPlot::yLeft, maxDepth, minDepth );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setXRange( double min, double max, QwtPlot::Axis axis )
{
setAxisScale( axis, min, max );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setDepthTitle( const QString& title )
{
QwtText axisTitleY = axisTitle( QwtPlot::yLeft );
if ( title != axisTitleY.text() )
{
axisTitleY.setText( title );
setAxisTitle( QwtPlot::yLeft, axisTitleY );
setMinimumWidth( defaultMinimumWidth() + axisExtent( QwtPlot::yLeft ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setXTitle( const QString& title )
{
QwtText axisTitleX = axisTitle( QwtPlot::xTop );
if ( title != axisTitleX.text() )
{
axisTitleX.setText( title );
setAxisTitle( QwtPlot::xTop, axisTitleX );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuWellLogTrack::isRimTrackVisible()
{
if ( m_plotTrackDefinition )
{
return m_plotTrackDefinition->isVisible();
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::enableDepthAxisLabelsAndTicks( bool enable )
{
this->axisScaleDraw( QwtPlot::yLeft )->enableComponent( QwtAbstractScaleDraw::Ticks, enable );
this->axisScaleDraw( QwtPlot::yLeft )->enableComponent( QwtAbstractScaleDraw::Labels, enable );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuWellLogTrack::widthScaleFactor() const
{
if ( m_plotTrackDefinition )
{
return m_plotTrackDefinition->widthScaleFactor();
}
return 1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::enableXGridLines( bool majorGridLines, bool minorGridLines )
{
QwtPlotItemList plotItems = this->itemList( QwtPlotItem::Rtti_PlotGrid );
for ( QwtPlotItem* plotItem : plotItems )
{
QwtPlotGrid* grid = static_cast<QwtPlotGrid*>( plotItem );
grid->setXAxis( QwtPlot::xTop );
grid->enableX( majorGridLines );
grid->enableXMin( minorGridLines );
grid->setMajorPen( Qt::lightGray, 1.0, Qt::SolidLine );
grid->setMinorPen( Qt::lightGray, 1.0, Qt::DashLine );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::enableDepthGridLines( bool majorGridLines, bool minorGridLines )
{
QwtPlotItemList plotItems = this->itemList( QwtPlotItem::Rtti_PlotGrid );
for ( QwtPlotItem* plotItem : plotItems )
{
QwtPlotGrid* grid = static_cast<QwtPlotGrid*>( plotItem );
grid->setYAxis( QwtPlot::yLeft );
grid->enableY( majorGridLines );
grid->enableYMin( minorGridLines );
grid->setMajorPen( Qt::lightGray, 1.0, Qt::SolidLine );
grid->setMinorPen( Qt::lightGray, 1.0, Qt::DashLine );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setMajorAndMinorTickIntervals( double majorTickInterval, double minorTickInterval )
{
RiuQwtLinearScaleEngine* scaleEngine = dynamic_cast<RiuQwtLinearScaleEngine*>(
this->axisScaleEngine( QwtPlot::xTop ) );
if ( scaleEngine )
{
QwtInterval currentRange = this->axisInterval( QwtPlot::xTop );
QwtScaleDiv scaleDiv = scaleEngine->divideScaleWithExplicitIntervals( currentRange.minValue(),
currentRange.maxValue(),
majorTickInterval,
minorTickInterval );
this->setAxisScaleDiv( QwtPlot::xTop, scaleDiv );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setAutoTickIntervalCounts( int maxMajorTickIntervalCount, int maxMinorTickIntervalCount )
{
this->setAxisMaxMajor( QwtPlot::xTop, maxMajorTickIntervalCount );
this->setAxisMaxMinor( QwtPlot::xTop, maxMinorTickIntervalCount );
// Reapply axis limits to force Qwt to use the tick settings.
QwtInterval currentRange = this->axisInterval( QwtPlot::xTop );
this->setXRange( currentRange.minValue(), currentRange.maxValue() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiuWellLogTrack::getCurrentMajorTickInterval() const
{
QwtScaleDiv scaleDiv = this->axisScaleDiv( QwtPlot::xTop );
QList<double> majorTicks = scaleDiv.ticks( QwtScaleDiv::MajorTick );
if ( majorTicks.size() < 2 ) return 0.0;
return majorTicks.at( 1 ) - majorTicks.at( 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiuWellLogTrack::getCurrentMinorTickInterval() const
{
QwtScaleDiv scaleDiv = this->axisScaleDiv( QwtPlot::xTop );
QList<double> minorTicks = scaleDiv.ticks( QwtScaleDiv::MinorTick );
if ( minorTicks.size() < 2 ) return 0.0;
return minorTicks.at( 1 ) - minorTicks.at( 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuWellLogTrack::axisExtent( QwtPlot::Axis axis ) const
{
QFont tickLabelFont = axisFont( axis );
int lineExtent = static_cast<int>( std::ceil( axisScaleDraw( axis )->extent( tickLabelFont ) ) );
if ( !axisTitle( axis ).text().isEmpty() )
{
QFont titleFont = axisTitle( axis ).font();
lineExtent += QFontMetrics( titleFont ).height();
}
return lineExtent;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuWellLogTrack::frameIsInFrontOfThis( const QRect& frameGeometry )
{
QRect ownGeometry = this->canvas()->geometry();
ownGeometry.translate( this->geometry().topLeft() );
if ( frameGeometry.bottom() < ownGeometry.center().y() )
{
return true;
}
else if ( frameGeometry.left() < ownGeometry.left() && frameGeometry.top() < ownGeometry.center().y() )
{
return true;
}
else
{
QRect intersection = ownGeometry.intersected( frameGeometry );
double ownArea = double( ownGeometry.height() ) * double( ownGeometry.width() );
double frameArea = double( frameGeometry.height() ) * double( frameGeometry.width() );
double intersectionArea = double( intersection.height() ) * double( intersection.width() );
if ( intersectionArea > 0.8 * std::min( ownArea, frameArea ) )
{
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QPoint RiuWellLogTrack::dragStartPosition() const
{
return m_dragStartPosition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setDefaultStyleSheet()
{
this->setStyleSheetForThisObject( "border: 1px dashed blue;", "hover" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setStyleSheetForThisObject( const QString& content, const QString& state /*= "" */ )
{
QString stateTag = !state.isEmpty() ? QString( ":%1" ).arg( state ) : "";
QString stylesheet = QString( "QwtPlot#%1%2 { %3 }" ).arg( this->objectName() ).arg( stateTag ).arg( content );
this->setStyleSheet( stylesheet );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogTrack* RiuWellLogTrack::plotDefinition() const
{
return m_plotTrackDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuWellLogTrack::eventFilter( QObject* watched, QEvent* event )
{
if ( watched == canvas() )
{
QWheelEvent* wheelEvent = dynamic_cast<QWheelEvent*>( event );
if ( wheelEvent )
{
if ( !m_plotTrackDefinition )
{
return QwtPlot::eventFilter( watched, event );
}
RimWellLogPlot* plotDefinition;
m_plotTrackDefinition->firstAncestorOrThisOfType( plotDefinition );
if ( !plotDefinition )
{
return QwtPlot::eventFilter( watched, event );
}
if ( wheelEvent->modifiers() & Qt::ControlModifier )
{
QwtScaleMap scaleMap = canvasMap( QwtPlot::yLeft );
double zoomCenter = scaleMap.invTransform( wheelEvent->pos().y() );
if ( wheelEvent->delta() > 0 )
{
plotDefinition->setDepthZoomByFactorAndCenter( RIU_SCROLLWHEEL_ZOOMFACTOR, zoomCenter );
}
else
{
plotDefinition->setDepthZoomByFactorAndCenter( 1.0 / RIU_SCROLLWHEEL_ZOOMFACTOR, zoomCenter );
}
}
else
{
plotDefinition->panDepth( wheelEvent->delta() < 0 ? RIU_SCROLLWHEEL_PANFACTOR
: -RIU_SCROLLWHEEL_PANFACTOR );
}
event->accept();
return true;
}
else
{
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>( event );
if ( mouseEvent )
{
if ( mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonRelease )
{
selectClosestCurve( mouseEvent->pos() );
}
}
}
}
return QwtPlot::eventFilter( watched, event );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellLogTrack::sizeHint() const
{
return QSize( 0, 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellLogTrack::minimumSizeHint() const
{
return QSize( 0, 0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::mousePressEvent( QMouseEvent* event )
{
if ( event->button() == Qt::LeftButton && this->underMouse() )
{
m_dragStartPosition = event->pos();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::mouseMoveEvent( QMouseEvent* event )
{
if ( !( event->buttons() & Qt::LeftButton ) ) return;
if ( ( event->pos() - m_dragStartPosition ).manhattanLength() < QApplication::startDragDistance() ) return;
QPoint dragPositionOffset = this->canvas()->geometry().topLeft() - m_dragStartPosition;
QPixmap pixmap = this->canvas()->grab();
QDrag* drag = new QDrag( this );
QMimeData* mimeData = new QMimeData;
mimeData->setImageData( pixmap );
drag->setMimeData( mimeData );
drag->setPixmap( pixmap );
drag->setHotSpot( m_dragStartPosition );
drag->exec( Qt::MoveAction );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setDefaults()
{
RiuQwtPlotTools::setCommonPlotBehaviour( this );
enableAxis( QwtPlot::xTop, true );
enableAxis( QwtPlot::yLeft, true );
enableAxis( QwtPlot::xBottom, false );
enableAxis( QwtPlot::yRight, false );
axisScaleEngine( QwtPlot::yLeft )->setAttribute( QwtScaleEngine::Inverted, true );
// Align the canvas with the actual min and max values of the curves
axisScaleEngine( QwtPlot::xTop )->setAttribute( QwtScaleEngine::Floating, true );
axisScaleEngine( QwtPlot::yLeft )->setAttribute( QwtScaleEngine::Floating, true );
setAxisScale( QwtPlot::yLeft, 1000, 0 );
setXRange( 0, 100 );
axisScaleDraw( QwtPlot::xTop )->setMinimumExtent( axisExtent( QwtPlot::xTop ) );
setMinimumWidth( defaultMinimumWidth() );
canvas()->setContentsMargins( 0, 0, 0, 0 );
QFrame* canvasFrame = dynamic_cast<QFrame*>( canvas() );
canvasFrame->setFrameShape( QFrame::Box );
canvasFrame->setStyleSheet( "border: 1px solid black" );
QGraphicsDropShadowEffect* dropShadowEffect = new QGraphicsDropShadowEffect( canvas() );
dropShadowEffect->setOffset( 1.0, 1.0 );
dropShadowEffect->setBlurRadius( 3.0 );
dropShadowEffect->setColor( QColor( 60, 60, 60, 60 ) );
canvas()->setGraphicsEffect( dropShadowEffect );
axisScaleDraw( QwtPlot::xTop )->enableComponent( QwtAbstractScaleDraw::Backbone, false );
axisScaleDraw( QwtPlot::yLeft )->enableComponent( QwtAbstractScaleDraw::Backbone, false );
axisWidget( QwtPlot::xTop )->setMargin( 0 );
axisWidget( QwtPlot::yLeft )->setMargin( 0 );
// Store the pointer address as an object name. This way each track can be identified uniquely for CSS-stylesheets
QString objectName = QString( "%1" ).arg( reinterpret_cast<uint64_t>( this ) );
setObjectName( objectName );
setDefaultStyleSheet();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::selectClosestCurve( const QPoint& pos )
{
QwtPlotCurve* closestCurve = nullptr;
double distMin = DBL_MAX;
const QwtPlotItemList& itmList = itemList();
for ( QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); it++ )
{
if ( ( *it )->rtti() == QwtPlotItem::Rtti_PlotCurve )
{
QwtPlotCurve* candidateCurve = static_cast<QwtPlotCurve*>( *it );
double dist = DBL_MAX;
candidateCurve->closestPoint( pos, &dist );
if ( dist < distMin )
{
closestCurve = candidateCurve;
distMin = dist;
}
}
}
if ( closestCurve && distMin < 20 )
{
RimWellLogCurve* selectedCurve = m_plotTrackDefinition->curveDefinitionFromCurve( closestCurve );
if ( selectedCurve )
{
RiuPlotMainWindowTools::showPlotMainWindow();
RiuPlotMainWindowTools::selectAsCurrentItem( selectedCurve );
return;
}
}
RiuPlotMainWindowTools::showPlotMainWindow();
RiuPlotMainWindowTools::selectAsCurrentItem( m_plotTrackDefinition );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuWellLogTrack::defaultMinimumWidth()
{
return 80;
}
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuWellLogTrack.h"
#include "RimWellLogTrack.h"
#include <QWheelEvent>
#define RIU_SCROLLWHEEL_ZOOMFACTOR 1.1
#define RIU_SCROLLWHEEL_PANFACTOR 0.1
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack::RiuWellLogTrack( RimWellLogTrack* plotTrackDefinition, QWidget* parent /*= nullptr */ )
: RiuQwtPlotWidget( plotTrackDefinition, parent )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack::~RiuWellLogTrack() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuWellLogTrack::eventFilter( QObject* watched, QEvent* event )
{
QWheelEvent* wheelEvent = dynamic_cast<QWheelEvent*>( event );
if ( wheelEvent && watched == canvas() )
{
RimWellLogTrack* track = dynamic_cast<RimWellLogTrack*>( plotDefinition() );
CAF_ASSERT( track );
RimWellLogPlot* wellLogPlot = nullptr;
track->firstAncestorOrThisOfType( wellLogPlot );
if ( wellLogPlot )
{
if ( wheelEvent->modifiers() & Qt::ControlModifier )
{
QwtScaleMap scaleMap = canvasMap( QwtPlot::yLeft );
double zoomCenter = scaleMap.invTransform( wheelEvent->pos().y() );
if ( wheelEvent->delta() > 0 )
{
wellLogPlot->setDepthAxisRangeByFactorAndCenter( RIU_SCROLLWHEEL_ZOOMFACTOR, zoomCenter );
}
else
{
wellLogPlot->setDepthAxisRangeByFactorAndCenter( 1.0 / RIU_SCROLLWHEEL_ZOOMFACTOR, zoomCenter );
}
}
else
{
wellLogPlot->setDepthAxisRangeByPanDepth( wheelEvent->delta() < 0 ? RIU_SCROLLWHEEL_PANFACTOR
: -RIU_SCROLLWHEEL_PANFACTOR );
}
event->accept();
return true;
}
}
return RiuQwtPlotWidget::eventFilter( watched, event );
}

View File

@ -1,86 +1,40 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "qwt_plot.h"
#include "cafPdmPointer.h"
class RimWellLogTrack;
class QwtLegend;
class QwtPicker;
class QwtPlotGrid;
class QwtPlotMarker;
class QEvent;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuWellLogTrack : public QwtPlot
{
Q_OBJECT
public:
RiuWellLogTrack( RimWellLogTrack* plotTrackDefinition, QWidget* parent = nullptr );
~RiuWellLogTrack() override;
void setDepthZoom( double minDepth, double maxDepth );
void setDepthTitle( const QString& title );
void setXTitle( const QString& title );
void setXRange( double min, double max, QwtPlot::Axis axis = QwtPlot::xTop );
bool isRimTrackVisible();
void enableDepthAxisLabelsAndTicks( bool enable );
int widthScaleFactor() const;
void enableXGridLines( bool majorGridLines, bool minorGridLines );
void enableDepthGridLines( bool majorGridLines, bool minorGridLines );
void setMajorAndMinorTickIntervals( double majorTickInterval, double minorTickInterval );
void setAutoTickIntervalCounts( int maxMajorTickIntervalCount, int maxMinorTickIntervalCount );
double getCurrentMajorTickInterval() const;
double getCurrentMinorTickInterval() const;
int axisExtent( QwtPlot::Axis axis ) const;
bool frameIsInFrontOfThis( const QRect& frameGeometry );
QPoint dragStartPosition() const;
void setDefaultStyleSheet();
void setStyleSheetForThisObject( const QString& content, const QString& state = "" );
RimWellLogTrack* plotDefinition() const;
protected:
bool eventFilter( QObject* watched, QEvent* event ) override;
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
void mousePressEvent( QMouseEvent* event ) override;
void mouseMoveEvent( QMouseEvent* event ) override;
private:
void setDefaults();
void selectClosestCurve( const QPoint& pos );
static int defaultMinimumWidth();
private:
caf::PdmPointer<RimWellLogTrack> m_plotTrackDefinition;
QPoint m_dragStartPosition;
};
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuQwtPlotWidget.h"
class RimWellLogTrack;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuWellLogTrack : public RiuQwtPlotWidget
{
Q_OBJECT
public:
RiuWellLogTrack( RimWellLogTrack* plotTrackDefinition, QWidget* parent = nullptr );
~RiuWellLogTrack() override;
protected:
bool eventFilter( QObject* watched, QEvent* event ) override;
};

View File

@ -171,6 +171,14 @@ void PdmUiTreeView::selectAsCurrentItem(const PdmUiItem* uiItem)
m_treeViewEditor->selectAsCurrentItem(uiItem);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeView::selectItems(const std::vector<const PdmUiItem*>& uiItems)
{
m_treeViewEditor->selectItems(uiItems);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -76,6 +76,7 @@ public:
void selectedUiItems(std::vector<PdmUiItem*>& objects); // TODO: rename
void selectAsCurrentItem(const PdmUiItem* uiItem);
void selectItems(const std::vector<const PdmUiItem*>& uiItems);
void setExpanded(const PdmUiItem* uiItem, bool doExpand) const ;
// QModelIndex access

View File

@ -316,9 +316,36 @@ PdmChildArrayFieldHandle* PdmUiTreeViewEditor::currentChildArrayFieldHandle()
void PdmUiTreeViewEditor::selectAsCurrentItem(const PdmUiItem* uiItem)
{
QModelIndex index = m_treeViewModel->findModelIndex(uiItem);
QModelIndex currentIndex = m_treeView->currentIndex();
m_treeView->clearSelection();
m_treeView->setCurrentIndex(index);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewEditor::selectItems(std::vector<const PdmUiItem*> uiItems)
{
m_treeView->clearSelection();
if (uiItems.empty())
{
return;
}
QModelIndex index = findModelIndex(uiItems.back());
m_treeView->setCurrentIndex(index);
for (const PdmUiItem* uiItem : uiItems)
{
QModelIndex itemIndex = findModelIndex(uiItem);
m_treeView->selectionModel()->select(itemIndex, QItemSelectionModel::Select);
}
m_treeView->setFocus(Qt::MouseFocusReason);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -391,7 +418,6 @@ void PdmUiTreeViewEditor::updateSelectionManager()
{
std::vector<PdmUiItem*> items;
this->selectedUiItems(items);
SelectionManager::instance()->setSelectedItems(items);
}
}

View File

@ -102,6 +102,7 @@ public:
bool isTreeItemEditWidgetActive() const;
void selectAsCurrentItem(const PdmUiItem* uiItem);
void selectItems(std::vector<const PdmUiItem*> uiItems);
void selectedUiItems(std::vector<PdmUiItem*>& objects);
void setExpanded(const PdmUiItem* uiItem, bool doExpand) const;