Merge pull request #4902 from OPM/summary-text-edit-in-toolbar

Summary text editor in toolbar
This commit is contained in:
Magne Sjaastad
2019-10-24 21:44:33 +02:00
committed by GitHub
17 changed files with 666 additions and 105 deletions

View File

@@ -41,6 +41,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicClearSourceSteppingSummaryCurveFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicSetSourceSteppingSummaryCurveFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicClearSourceSteppingEnsembleCurveSetFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicSetSourceSteppingEnsembleCurveSetFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicActivateCurveFilterInToolbarFeature.h
)
set (SOURCE_GROUP_SOURCE_FILES
@@ -85,6 +86,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicClearSourceSteppingSummaryCurveFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicSetSourceSteppingSummaryCurveFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicClearSourceSteppingEnsembleCurveSetFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicSetSourceSteppingEnsembleCurveSetFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicActivateCurveFilterInToolbarFeature.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@@ -0,0 +1,58 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RicActivateCurveFilterInToolbarFeature.h"
#include "RiaGuiApplication.h"
#include "RiuPlotMainWindow.h"
#include <QAction>
CAF_CMD_SOURCE_INIT( RicActivateCurveFilterInToolbarFeature, "RicActivateCurveFilterInToolbarFeature" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicActivateCurveFilterInToolbarFeature::isCommandEnabled()
{
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicActivateCurveFilterInToolbarFeature::onActionTriggered( bool isChecked )
{
if ( RiaGuiApplication::isRunning() )
{
auto plotWindow = RiaGuiApplication::instance()->mainPlotWindow();
if ( plotWindow )
{
plotWindow->setFocusToLineEditInSummaryToolBar();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicActivateCurveFilterInToolbarFeature::setupActionLook( QAction* actionToSetup )
{
actionToSetup->setText( "Activate Summary Curve Filter Editor" );
actionToSetup->setShortcut( QKeySequence( tr( "Ctrl+F" ) ) );
}

View File

@@ -0,0 +1,34 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "cafCmdFeature.h"
//==================================================================================================
///
//==================================================================================================
class RicActivateCurveFilterInToolbarFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
bool isCommandEnabled() override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};

View File

@@ -47,11 +47,13 @@
#include "RiuPlotMainWindowTools.h"
#include "RiuSummaryQwtPlot.h"
#include "RiuTreeViewEventFilter.h"
#include "cvfColor3.h"
#include "cafPdmUiCheckBoxEditor.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafSelectionManager.h"
#include "qwt_abstract_legend.h"
#include "qwt_legend.h"
@@ -67,7 +69,6 @@
#include <QRectF>
#include <QString>
#include "cafSelectionManager.h"
#include <limits>
#include <set>
@@ -1520,6 +1521,8 @@ void RimSummaryPlot::onLoadDataAndUpdate()
if ( m_plotWidget ) m_plotWidget->updateLegend();
this->updateAxes();
m_textCurveSetEditor->updateTextFilter();
}
//--------------------------------------------------------------------------------------------------
@@ -1975,6 +1978,11 @@ void RimSummaryPlot::handleKeyPressEvent( QKeyEvent* keyEvent )
{
if ( !keyEvent ) return;
if ( RiuTreeViewEventFilter::activateFeatureFromKeyEvent( keyEvent ) )
{
return;
}
RimSummaryPlotSourceStepping* sourceStepping = sourceSteppingObjectForKeyEventHandling();
if ( !sourceStepping ) return;
@@ -2050,17 +2058,27 @@ std::vector<caf::PdmFieldHandle*> RimSummaryPlot::fieldsToShowInToolbar()
{
std::vector<caf::PdmFieldHandle*> toolBarFields;
auto sourceObject = sourceSteppingObjectForKeyEventHandling();
if ( sourceObject )
{
toolBarFields = sourceObject->fieldsToShowInToolbar();
auto fields = m_textCurveSetEditor->fieldsToShowInToolbar();
toolBarFields.insert( std::end( toolBarFields ), std::begin( fields ), std::end( fields ) );
}
if ( toolBarFields.empty() )
bool anyFieldsAvailableForSummary = false;
auto sourceObject = sourceSteppingObjectForKeyEventHandling();
if ( sourceObject )
{
auto fields = sourceObject->fieldsToShowInToolbar();
toolBarFields.insert( std::end( toolBarFields ), std::begin( fields ), std::end( fields ) );
anyFieldsAvailableForSummary = !fields.empty();
}
if ( !anyFieldsAvailableForSummary )
{
// Show ensemble stepping if no fields are available from summary stepping
toolBarFields = ensembleCurveSetCollection()->fieldsToShowInToolbar();
auto fields = ensembleCurveSetCollection()->fieldsToShowInToolbar();
toolBarFields.insert( std::end( toolBarFields ), std::begin( fields ), std::end( fields ) );
}
return toolBarFields;

View File

@@ -19,12 +19,14 @@
#include "RimSummaryPlotFilterTextCurveSetEditor.h"
#include "RiaApplication.h"
#include "RiaGuiApplication.h"
#include "RiaLogging.h"
#include "RiaSummaryCurveDefinition.h"
#include "RifSummaryReaderInterface.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RimEclipseCase.h"
#include "RimEnsembleCurveSet.h"
#include "RimEnsembleCurveSetCollection.h"
@@ -41,12 +43,16 @@
#include "RimSummaryCurve.h"
#include "RimSummaryCurveCollection.h"
#include "RimSummaryPlot.h"
#include "RiuPlotMainWindow.h"
#include "RiuSummaryCurveDefSelection.h"
#include "SummaryPlotCommands/RicSummaryPlotFeatureImpl.h"
#include "WellLogCommands/RicWellLogPlotCurveFeatureImpl.h"
#include "cafPdmUiTextEditor.h"
#include "cafPdmUiLabelEditor.h"
#include "cafPdmUiLineEditor.h"
#include "cafPdmUiToolBarEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
#include <QRegularExpression>
@@ -64,17 +70,29 @@ RimSummaryPlotFilterTextCurveSetEditor::RimSummaryPlotFilterTextCurveSetEditor()
CAF_PDM_InitObject( "Curve Set Filter Text", "", "", "" );
// clang-format off
QString filterTextHeading = "Text to Create Summary Vectors";
QString filterTextShortcut = " (Ctrl + F)";
QString filterTextToolTip =
"A space separated list of vector addresses in the syntax: <vectorshortname>[:<item>[:<subitem>[:i,j,k]]]\n"
"A list of vector addresses separated by spaces using the syntax: <vectorshortname>[:<item>[:<subitem>[:i,j,k]]]\n"
"Wildcards can also be used. Examples:\n"
" \"WOPT:*\" One total oil production curve for each well.\n"
" \"FOPT FWPT\" Two curves with oil and water total production.\n"
" \"BPR:15,28,*\" (no space) Oil phase pressure for all blocks along k as separate curves.\n";
// clang-format on
CAF_PDM_InitFieldNoDefault( &m_curveFilterText, "CurveFilterText", "Curve Filter Text", "", filterTextToolTip, "" );
QString toolTipPropertyEditor = filterTextHeading + "\n\n" + filterTextToolTip;
QString toolTipToolbar = filterTextHeading + filterTextShortcut + "\n\n" + filterTextToolTip;
CAF_PDM_InitFieldNoDefault( &m_curveFilterLabelText, "Summary", "Summary", "", "", "" );
m_curveFilterLabelText.uiCapability()->setUiEditorTypeName( caf::PdmUiLabelEditor::uiEditorTypeName() );
m_curveFilterLabelText.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_curveFilterText, "CurveFilterText", "Curve Filter Text", "", toolTipPropertyEditor, "" );
m_curveFilterText.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
// m_curveFilterText.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() );
// Special tool tip for toolbar
m_curveFilterText.uiCapability()->setUiToolTip( toolTipToolbar, caf::PdmUiToolBarEditor::uiEditorConfigName() );
CAF_PDM_InitFieldNoDefault( &m_selectedSources, "SummaryCases", "Sources", "", "", "" );
m_selectedSources.uiCapability()->setAutoAddingOptionFromValue( false );
@@ -87,6 +105,102 @@ RimSummaryPlotFilterTextCurveSetEditor::RimSummaryPlotFilterTextCurveSetEditor()
//--------------------------------------------------------------------------------------------------
RimSummaryPlotFilterTextCurveSetEditor::~RimSummaryPlotFilterTextCurveSetEditor() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<caf::PdmFieldHandle*> RimSummaryPlotFilterTextCurveSetEditor::fieldsToShowInToolbar()
{
std::vector<caf::PdmFieldHandle*> fields;
fields.push_back( &m_curveFilterLabelText );
fields.push_back( &m_curveFilterText );
return fields;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryPlotFilterTextCurveSetEditor::curveFilterFieldKeyword()
{
return "CurveFilterText";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotFilterTextCurveSetEditor::updateTextFilter()
{
RimSummaryPlot* parentPlot;
this->firstAncestorOrThisOfType( parentPlot );
std::set<SummarySource*> sourcesFromExistingCurves;
std::set<RifEclipseSummaryAddress> addressesInUse;
std::vector<RigGridCellResultAddress> gridaddressesInUse;
if ( parentPlot )
{
std::vector<RimEnsembleCurveSet*> ensembleCurveSets = parentPlot->ensembleCurveSetCollection()->curveSets();
for ( auto ensCurvSet : ensembleCurveSets )
{
sourcesFromExistingCurves.insert( ensCurvSet->summaryCaseCollection() );
addressesInUse.insert( ensCurvSet->summaryAddress() );
}
std::vector<RimSummaryCurve*> sumCurves = parentPlot->summaryCurveCollection()->curves();
for ( auto sumCurve : sumCurves )
{
sourcesFromExistingCurves.insert( sumCurve->summaryCaseY() );
addressesInUse.insert( sumCurve->summaryAddressY() );
}
std::vector<RimGridTimeHistoryCurve*> gridTimeHistoryCurves = parentPlot->gridTimeHistoryCurves();
for ( auto grCurve : gridTimeHistoryCurves )
{
RimEclipseCase* eclCase = dynamic_cast<RimEclipseCase*>( grCurve->gridCase() );
if ( eclCase )
{
sourcesFromExistingCurves.insert( eclCase );
gridaddressesInUse.push_back( grCurve->resultAddress() );
}
}
}
std::vector<caf::PdmPointer<SummarySource>> usedSources( sourcesFromExistingCurves.begin(),
sourcesFromExistingCurves.end() );
if ( !usedSources.empty() )
{
m_selectedSources.clear();
m_selectedSources.setValue( usedSources );
}
// Check if existing filter text matches all the curves
// Todo: possibly check grid time history curves also
QStringList allCurveAddressFilters = curveFilterTextWithoutOutdatedLabel().split( QRegExp( "\\s+" ),
QString::SkipEmptyParts );
std::vector<bool> accumulatedUsedFilters( allCurveAddressFilters.size(), false );
std::vector<bool> usedFilters;
std::set<RifEclipseSummaryAddress> filteredAddressesFromSource;
RicSummaryPlotFeatureImpl::filteredSummaryAdressesFromCase( allCurveAddressFilters,
addressesInUse,
&filteredAddressesFromSource,
&usedFilters );
if ( filteredAddressesFromSource != addressesInUse )
{
// m_curveFilterText = FILTER_TEXT_OUTDATED_TEXT + curveFilterTextWithoutOutdatedLabel();
m_curveFilterText = "";
}
else
{
m_curveFilterText = curveFilterTextWithoutOutdatedLabel();
}
m_curveFilterText.uiCapability()->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -266,9 +380,20 @@ void RimSummaryPlotFilterTextCurveSetEditor::fieldChangedByUi( const caf::PdmFie
if ( changedField == &m_curveFilterText )
{
m_curveFilterText = curveFilterTextWithoutOutdatedLabel();
m_curveFilterText.uiCapability()->updateConnectedEditors();
}
m_isFieldRecentlyChangedFromGui = true;
if ( RiaGuiApplication::isRunning() )
{
RiuPlotMainWindow* mainPlotWindow = RiaGuiApplication::instance()->mainPlotWindow();
if ( mainPlotWindow )
{
mainPlotWindow->updateSummaryPlotToolBar();
}
}
}
//--------------------------------------------------------------------------------------------------
@@ -276,72 +401,13 @@ void RimSummaryPlotFilterTextCurveSetEditor::fieldChangedByUi( const caf::PdmFie
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotFilterTextCurveSetEditor::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_curveFilterText );
uiOrdering.add( &m_selectedSources );
uiOrdering.skipRemainingFields();
if ( !m_isFieldRecentlyChangedFromGui )
{
// Sync gui from existing curves
RimSummaryPlot* parentPlot;
this->firstAncestorOrThisOfType( parentPlot );
std::set<SummarySource*> sourcesFromExistingCurves;
std::set<RifEclipseSummaryAddress> addressesInUse;
std::vector<RigGridCellResultAddress> gridaddressesInUse;
if ( parentPlot )
{
std::vector<RimEnsembleCurveSet*> ensembleCurveSets = parentPlot->ensembleCurveSetCollection()->curveSets();
for ( auto ensCurvSet : ensembleCurveSets )
{
sourcesFromExistingCurves.insert( ensCurvSet->summaryCaseCollection() );
addressesInUse.insert( ensCurvSet->summaryAddress() );
}
std::vector<RimSummaryCurve*> sumCurves = parentPlot->summaryCurveCollection()->curves();
for ( auto sumCurve : sumCurves )
{
sourcesFromExistingCurves.insert( sumCurve->summaryCaseY() );
addressesInUse.insert( sumCurve->summaryAddressY() );
}
std::vector<RimGridTimeHistoryCurve*> gridTimeHistoryCurves = parentPlot->gridTimeHistoryCurves();
for ( auto grCurve : gridTimeHistoryCurves )
{
RimEclipseCase* eclCase = dynamic_cast<RimEclipseCase*>( grCurve->gridCase() );
if ( eclCase )
{
sourcesFromExistingCurves.insert( eclCase );
gridaddressesInUse.push_back( grCurve->resultAddress() );
}
}
}
std::vector<caf::PdmPointer<SummarySource>> usedSources( sourcesFromExistingCurves.begin(),
sourcesFromExistingCurves.end() );
m_selectedSources.clear();
m_selectedSources.setValue( usedSources );
// Check if existing filtertext matches all the curves
// Todo: possibly check grid time history curves also
QStringList allCurveAddressFilters = curveFilterTextWithoutOutdatedLabel().split( QRegExp( "\\s+" ),
QString::SkipEmptyParts );
std::vector<bool> accumulatedUsedFilters( allCurveAddressFilters.size(), false );
std::vector<bool> usedFilters;
std::set<RifEclipseSummaryAddress> filteredAddressesFromSource;
RicSummaryPlotFeatureImpl::filteredSummaryAdressesFromCase( allCurveAddressFilters,
addressesInUse,
&filteredAddressesFromSource,
&usedFilters );
if ( filteredAddressesFromSource != addressesInUse )
{
m_curveFilterText = FILTER_TEXT_OUTDATED_TEXT + curveFilterTextWithoutOutdatedLabel();
}
else
{
m_curveFilterText = curveFilterTextWithoutOutdatedLabel();
}
updateTextFilter();
}
m_isFieldRecentlyChangedFromGui = false;
@@ -355,6 +421,30 @@ void RimSummaryPlotFilterTextCurveSetEditor::setupBeforeSave()
m_curveFilterText = curveFilterTextWithoutOutdatedLabel();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotFilterTextCurveSetEditor::defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
if ( field == &m_curveFilterText )
{
auto attr = dynamic_cast<caf::PdmUiLineEditorAttribute*>( attribute );
if ( attr )
{
if ( uiConfigName == caf::PdmUiToolBarEditor::uiEditorConfigName() )
{
// Special config for toolbar
attr->maximumWidth = 150;
}
attr->selectAllOnFocusEvent = true;
attr->placeholderText = "Click to define filter";
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -31,14 +31,23 @@ public:
RimSummaryPlotFilterTextCurveSetEditor();
~RimSummaryPlotFilterTextCurveSetEditor() override;
std::vector<caf::PdmFieldHandle*> fieldsToShowInToolbar();
static QString curveFilterFieldKeyword();
void updateTextFilter();
protected:
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
virtual void setupBeforeSave() override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void setupBeforeSave() override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
private:
static void appendOptionItemsForSources( QList<caf::PdmOptionItemInfo>& options,
@@ -49,7 +58,9 @@ private:
QString curveFilterTextWithoutOutdatedLabel() const;
caf::PdmPtrArrayField<SummarySource*> m_selectedSources;
caf::PdmField<QString> m_curveFilterText;
caf::PdmField<QString> m_curveFilterLabelText;
caf::PdmField<QString> m_curveFilterText;
bool m_isFieldRecentlyChangedFromGui;
};

View File

@@ -29,6 +29,7 @@
#include "RimSummaryCurveCollection.h"
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
#include "RimSummaryPlotFilterTextCurveSetEditor.h"
#include "RimViewWindow.h"
#include "RimWellAllocationPlot.h"
#include "RimWellLogCurveCommonDataSource.h"
@@ -202,6 +203,19 @@ void RiuPlotMainWindow::closeEvent( QCloseEvent* event )
app->closeProject();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotMainWindow::keyPressEvent( QKeyEvent* keyEvent )
{
if ( RiuTreeViewEventFilter::activateFeatureFromKeyEvent( keyEvent ) )
{
return;
}
RiuMainWindowBase::keyPressEvent( keyEvent );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -559,29 +573,40 @@ void RiuPlotMainWindow::updateSummaryPlotToolBar( bool forceUpdateUi )
{
std::vector<caf::PdmFieldHandle*> toolBarFields = summaryPlot->fieldsToShowInToolbar();
QString keyword;
if ( !m_summaryPlotToolBarEditor->isEditorDataValid( toolBarFields ) )
{
keyword = m_summaryPlotToolBarEditor->keywordForFocusWidget();
m_summaryPlotToolBarEditor->setFields( toolBarFields );
}
else if ( forceUpdateUi )
{
m_summaryPlotToolBarEditor->updateUi();
}
m_summaryPlotToolBarEditor->updateUi();
m_summaryPlotToolBarEditor->updateUi( caf::PdmUiToolBarEditor::uiEditorConfigName() );
m_summaryPlotToolBarEditor->show();
m_summaryPlotToolBarEditor->setFocusWidgetFromKeyword( keyword );
}
else
{
m_summaryPlotToolBarEditor->clear();
m_summaryPlotToolBarEditor->hide();
}
refreshToolbars();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPlotMainWindow::setFocusToLineEditInSummaryToolBar()
{
if ( m_summaryPlotToolBarEditor )
{
m_summaryPlotToolBarEditor->setFocusWidgetFromKeyword(
RimSummaryPlotFilterTextCurveSetEditor::curveFilterFieldKeyword() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -828,8 +853,8 @@ void RiuPlotMainWindow::customMenuRequested( const QPoint& pos )
RiaApplication* app = RiaApplication::instance();
app->project()->actionsBasedOnSelection( menu );
// Qt doc: QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the viewport().
// Since we might get this signal from different treeViews, we need to map the position accordingly.
// Qt doc: QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the
// viewport(). Since we might get this signal from different treeViews, we need to map the position accordingly.
QObject* senderObj = this->sender();
QTreeView* treeView = dynamic_cast<QTreeView*>( senderObj );
if ( treeView )

View File

@@ -81,9 +81,11 @@ public:
void updateWellLogPlotToolBar();
void updateSummaryPlotToolBar( bool forceUpdateUi = false );
void setFocusToLineEditInSummaryToolBar();
protected:
void closeEvent( QCloseEvent* event ) override;
void keyPressEvent( QKeyEvent* ) override;
private:
void setPdmRoot( caf::PdmObject* pdmRoot );

View File

@@ -49,6 +49,44 @@ RiuTreeViewEventFilter::RiuTreeViewEventFilter( QObject* parent )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuTreeViewEventFilter::activateFeatureFromKeyEvent( QKeyEvent* keyEvent )
{
QKeySequence keySeq( keyEvent->modifiers() + keyEvent->key() );
auto matches = caf::CmdFeatureManager::instance()->commandFeaturesMatchingKeyboardShortcut( keySeq );
bool wasFeatureActivated = activateFirstEnabledFeature( matches );
if ( wasFeatureActivated )
{
keyEvent->setAccepted( true );
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuTreeViewEventFilter::activateFirstEnabledFeature( const std::vector<caf::CmdFeature*>& features )
{
for ( caf::CmdFeature* feature : features )
{
if ( feature->canFeatureBeExecuted() )
{
feature->actionTriggered( false );
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -93,15 +131,11 @@ bool RiuTreeViewEventFilter::eventFilter( QObject* obj, QEvent* event )
matches = caf::CmdFeatureManager::instance()->commandFeaturesMatchingKeyboardShortcut( keySeq );
}
for ( caf::CmdFeature* feature : matches )
bool wasFeatureActivated = RiuTreeViewEventFilter::activateFirstEnabledFeature( matches );
if ( wasFeatureActivated )
{
if ( feature->canFeatureBeExecuted() )
{
feature->actionTriggered( false );
keyEvent->setAccepted( true );
return true;
}
keyEvent->setAccepted( true );
return true;
}
}

View File

@@ -21,7 +21,15 @@
#include <QObject>
#include <vector>
class QEvent;
class QKeyEvent;
namespace caf
{
class CmdFeature;
}
//--------------------------------------------------------------------------------------------------
class RiuTreeViewEventFilter : public QObject
@@ -30,6 +38,9 @@ class RiuTreeViewEventFilter : public QObject
public:
explicit RiuTreeViewEventFilter( QObject* parent );
static bool activateFeatureFromKeyEvent( QKeyEvent* keyEvent );
static bool activateFirstEnabledFeature( const std::vector<caf::CmdFeature*>& features );
protected:
bool eventFilter( QObject* obj, QEvent* event ) override;
};
};

View File

@@ -45,6 +45,7 @@ set (MOC_HEADER_FILES
cafPdmUniqueIdValidator.h
cafPdmDoubleStringValidator.h
cafPdmUiPickableLineEditor.h
cafPdmUiLabelEditor.h
)
if (CEE_USE_QT5)
@@ -99,6 +100,8 @@ set( PROJECT_FILES
cafPdmUiTreeSelectionQModel.cpp
cafPdmUiFieldEditorHelper.h
cafPdmUiFieldEditorHelper.cpp
cafPdmUiLabelEditor.cpp
# object editors
cafPdmUiDefaultObjectEditor.cpp

View File

@@ -0,0 +1,98 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmUiLabelEditor.h"
namespace caf
{
CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiLabelEditor);
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiLabelEditor::PdmUiLabelEditor()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiLabelEditor::~PdmUiLabelEditor()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiLabelEditor::configureAndUpdateUi(const QString& uiConfigName)
{
CAF_ASSERT(!m_label.isNull());
PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* PdmUiLabelEditor::createEditorWidget(QWidget * parent)
{
return createLabelWidget(parent);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* PdmUiLabelEditor::createLabelWidget(QWidget * parent)
{
if (m_label.isNull())
{
m_label = new QShortenedLabel(parent);
}
return m_label;
}
} // end namespace caf

View File

@@ -0,0 +1,77 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cafPdmUiFieldEditorHandle.h"
#include "cafQShortenedLabel.h"
#include <QLabel>
#include <QPointer>
#include <QString>
#include <QWidget>
class QGridLayout;
namespace caf
{
//==================================================================================================
/// An editor to show (and possibly edit?) formatted larger portions of text
//==================================================================================================
class PdmUiLabelEditor : public PdmUiFieldEditorHandle
{
Q_OBJECT
CAF_PDM_UI_FIELD_EDITOR_HEADER_INIT;
public:
PdmUiLabelEditor();
~PdmUiLabelEditor() override;
protected:
QWidget* createEditorWidget(QWidget * parent) override;
QWidget* createLabelWidget(QWidget * parent) override;
void configureAndUpdateUi(const QString& uiConfigName) override;
private:
QPointer<QShortenedLabel> m_label;
};
} // end namespace caf

View File

@@ -38,29 +38,29 @@
#include "cafPdmUiLineEditor.h"
#include "cafFactory.h"
#include "cafQShortenedLabel.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmUiDefaultObjectEditor.h"
#include "cafPdmUiFieldEditorHandle.h"
#include "cafPdmUiOrdering.h"
#include "cafPdmUniqueIdValidator.h"
#include "cafQShortenedLabel.h"
#include "cafSelectionManager.h"
#include <QAbstractItemView>
#include <QAbstractProxyModel>
#include <QApplication>
#include <QKeyEvent>
#include <QCompleter>
#include <QDebug>
#include <QIntValidator>
#include <QKeyEvent>
#include <QLabel>
#include <QMainWindow>
#include <QMessageBox>
#include <QPalette>
#include <QStatusBar>
#include <QString>
#include <QCompleter>
#include <QStringListModel>
#include <QAbstractProxyModel>
#include <QAbstractItemView>
#include <QDebug>
namespace caf
@@ -131,6 +131,16 @@ void PdmUiLineEditor::configureAndUpdateUi(const QString& uiConfigName)
}
m_lineEdit->setAvoidSendingEnterEventToParentWidget(leab.avoidSendingEnterEventToParentWidget);
if (leab.maximumWidth != -1)
{
m_lineEdit->setMaximumWidth(leab.maximumWidth);
}
if (!leab.placeholderText.isEmpty())
{
m_lineEdit->setPlaceholderText(leab.placeholderText);
}
}
bool fromMenuOnly = true;

View File

@@ -64,6 +64,9 @@ public:
avoidSendingEnterEventToParentWidget = false;
completerCaseSensitivity = Qt::CaseInsensitive;
completerFilterMode = Qt::MatchContains;
maximumWidth = -1;
selectAllOnFocusEvent = false;
placeholderText = "";
}
public:
@@ -73,6 +76,9 @@ public:
// Completer setup
Qt::CaseSensitivity completerCaseSensitivity;
Qt::MatchFlags completerFilterMode;
int maximumWidth;
bool selectAllOnFocusEvent;
QString placeholderText;
};
//--------------------------------------------------------------------------------------------------

View File

@@ -42,12 +42,14 @@
#include "cafPdmUiFieldEditorHandle.h"
#include "cafPdmUiFieldEditorHelper.h"
#include "cafPdmUiFieldHandle.h"
#include "cafPdmUiLineEditor.h"
#include "cafPdmUiObjectHandle.h"
#include "cafPdmUiOrdering.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiToolButtonEditor.h"
#include <QAction>
#include <QLineEdit>
#include <QMainWindow>
#include <QToolBar>
@@ -232,6 +234,47 @@ void PdmUiToolBarEditor::clear()
m_actions.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiToolBarEditor::setFocusWidgetFromKeyword(const QString& fieldKeyword)
{
if (!m_toolbar->isVisible()) return;
auto fieldView = m_fieldViews.find(fieldKeyword);
if (fieldView != m_fieldViews.end() && fieldView->second)
{
auto editorWidget = fieldView->second->editorWidget();
if (editorWidget)
{
editorWidget->setFocus(Qt::ActiveWindowFocusReason);
PdmUiLineEditorAttribute attributes;
for (auto field : m_fields)
{
if (field->keyword() == fieldKeyword)
{
caf::PdmUiObjectHandle* uiObject = uiObj(field->ownerObject());
if (uiObject)
{
uiObject->editorAttribute(field, uiEditorConfigName(), &attributes);
}
}
}
if (attributes.selectAllOnFocusEvent)
{
auto lineEdit = dynamic_cast<QLineEdit*>(editorWidget);
if (lineEdit )
{
lineEdit->selectAll();
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -254,4 +297,38 @@ void PdmUiToolBarEditor::hide()
}
}
//--------------------------------------------------------------------------------------------------
/// Special config name used to configure toolbar UI (tooltip etc.)
//--------------------------------------------------------------------------------------------------
QString PdmUiToolBarEditor::uiEditorConfigName()
{
return "ToolbarConfigName";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmUiToolBarEditor::keywordForFocusWidget()
{
QString keyword;
if (m_toolbar->isVisible())
{
for (auto fieldViewPair : m_fieldViews)
{
auto fieldView = fieldViewPair.second;
if (fieldView)
{
auto editorWidget = fieldView->editorWidget();
if (editorWidget && editorWidget->hasFocus())
{
keyword = fieldViewPair.first;
}
}
}
}
return keyword;
}
} // end namespace caf

View File

@@ -64,10 +64,15 @@ public:
bool isEditorDataValid(const std::vector<caf::PdmFieldHandle*>& fields) const;
void setFields(std::vector<caf::PdmFieldHandle*>& fields);
void clear();
void setFocusWidgetFromKeyword(const QString& fieldKeyword);
QString keywordForFocusWidget();
void show();
void hide();
static QString uiEditorConfigName();
private:
void configureAndUpdateUi(const QString& uiConfigName) override;