Merge fixes related to #1901 Perforation COMPDAT export errors

This commit is contained in:
Jacob Støren
2017-09-20 11:02:41 +02:00
72 changed files with 2694 additions and 686 deletions

View File

@@ -53,6 +53,7 @@
#include "RimGeoMechView.h"
#include "RimIdenticalGridCaseGroup.h"
#include "RimMainPlotCollection.h"
#include "RimObservedDataCollection.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimReservoirCellResultsStorage.h"
@@ -484,6 +485,11 @@ bool RiaApplication::loadProject(const QString& projectFileName, ProjectLoadActi
oilField->summaryCaseMainCollection()->createSummaryCasesFromRelevantEclipseResultCases();
oilField->summaryCaseMainCollection()->loadAllSummaryCaseData();
if (!oilField->observedDataCollection())
{
oilField->observedDataCollection = new RimObservedDataCollection();
}
#ifdef USE_PROTOTYPE_FEATURE_FRACTURES
oilField->fractureDefinitionCollection()->loadAndUpdateData();

View File

@@ -33,6 +33,8 @@ ${CEE_CURRENT_LIST_DIR}RicWellLogsImportFileFeature.h
${CEE_CURRENT_LIST_DIR}RicTogglePerspectiveViewFeature.h
${CEE_CURRENT_LIST_DIR}RicImportGeoMechCaseFeature.h
${CEE_CURRENT_LIST_DIR}RicImportSummaryCaseFeature.h
${CEE_CURRENT_LIST_DIR}RicImportObservedDataFeature.h
${CEE_CURRENT_LIST_DIR}RicImportObservedDataInMenuFeature.h
${CEE_CURRENT_LIST_DIR}RicExportFeatureImpl.h
${CEE_CURRENT_LIST_DIR}RicSelectOrCreateViewFeatureImpl.h
@@ -97,6 +99,8 @@ ${CEE_CURRENT_LIST_DIR}RicReloadFormationNamesFeature.cpp
${CEE_CURRENT_LIST_DIR}RicTogglePerspectiveViewFeature.cpp
${CEE_CURRENT_LIST_DIR}RicImportGeoMechCaseFeature.cpp
${CEE_CURRENT_LIST_DIR}RicImportSummaryCaseFeature.cpp
${CEE_CURRENT_LIST_DIR}RicImportObservedDataFeature.cpp
${CEE_CURRENT_LIST_DIR}RicImportObservedDataInMenuFeature.cpp
${CEE_CURRENT_LIST_DIR}RicExportFeatureImpl.cpp
${CEE_CURRENT_LIST_DIR}RicSelectOrCreateViewFeatureImpl.cpp

View File

@@ -110,10 +110,13 @@ bool RicCutReferencesToClipboardFeature::isAnyCuttableObjectSelected()
//--------------------------------------------------------------------------------------------------
bool RicCutReferencesToClipboardFeature::isCuttingOfObjectSupported(caf::PdmObject* pdmObject)
{
if (dynamic_cast<RimSummaryCase*>(pdmObject))
if (RimSummaryCase* summaryCase = dynamic_cast<RimSummaryCase*>(pdmObject))
{
if (!summaryCase->isObservedData())
{
return true;
}
}
return false;
}

View File

@@ -77,7 +77,19 @@ bool RicCloseSummaryCaseFeature::isCommandEnabled()
std::vector<RimSummaryCase*> selection;
caf::SelectionManager::instance()->objectsByType(&selection);
return (selection.size() > 0);
if (selection.size() == 0)
{
return false;
}
for (RimSummaryCase* summaryCase : selection)
{
if (summaryCase->isObservedData())
{
return false;
}
}
return true;
}
//--------------------------------------------------------------------------------------------------

View File

@@ -37,7 +37,19 @@ bool RicCreateSummaryCaseCollectionFeature::isCommandEnabled()
std::vector<RimSummaryCase*> selection;
caf::SelectionManager::instance()->objectsByType(&selection);
return (selection.size() > 0);
if (selection.size() == 0)
{
return false;
}
for (RimSummaryCase* summaryCase : selection)
{
if (summaryCase->isObservedData())
{
return false;
}
}
return true;
}
//--------------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,115 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 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 "RicImportObservedDataFeature.h"
#include "RiaApplication.h"
#include "RimObservedData.h"
#include "RimObservedDataCollection.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimSummaryObservedDataFile.h"
#include "cafSelectionManager.h"
#include <QAction>
#include <QFileDialog>
CAF_CMD_SOURCE_INIT(RicImportObservedDataFeature, "RicImportObservedDataFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicImportObservedDataFeature::RicImportObservedDataFeature()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicImportObservedDataFeature::selectObservedDataFileInDialog()
{
RiaApplication* app = RiaApplication::instance();
QString defaultDir = app->lastUsedDialogDirectory("INPUT_FILES");
QStringList fileNames = QFileDialog::getOpenFileNames(NULL, "Import Observed Data", defaultDir, "All Files (*.*)");
if (fileNames.isEmpty()) return;
// Remember the path to next time
app->setLastUsedDialogDirectory("INPUT_FILES", QFileInfo(fileNames.last()).absolutePath());
RimProject* proj = app->project();
RimObservedDataCollection* observedDataCollection = proj->activeOilField() ? proj->activeOilField()->observedDataCollection() : nullptr;
if (!observedDataCollection) return;
for (auto fileName : fileNames)
{
RicImportObservedDataFeature::createAndAddObservedDataFromFile(fileName);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicImportObservedDataFeature::isCommandEnabled()
{
std::vector<RimObservedDataCollection*> selectionObservedDataCollection;
caf::SelectionManager::instance()->objectsByType(&selectionObservedDataCollection);
std::vector<RimObservedData*> selectionObservedData;
caf::SelectionManager::instance()->objectsByType(&selectionObservedData);
return (selectionObservedDataCollection.size() > 0 || selectionObservedData.size() > 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicImportObservedDataFeature::onActionTriggered(bool isChecked)
{
RicImportObservedDataFeature::selectObservedDataFileInDialog();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicImportObservedDataFeature::setupActionLook(QAction* actionToSetup)
{
actionToSetup->setIcon(QIcon(":/Default.png"));
actionToSetup->setText("Import Observed Data");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicImportObservedDataFeature::createAndAddObservedDataFromFile(const QString& fileName)
{
RiaApplication* app = RiaApplication::instance();
RimProject* proj = app->project();
RimObservedDataCollection* observedDataCollection = proj->activeOilField() ? proj->activeOilField()->observedDataCollection() : nullptr;
if (!observedDataCollection) return false;
RimSummaryObservedDataFile* newObservedData = observedDataCollection->createAndAddObservedDataFromFileName(fileName);
newObservedData->loadCase();
return true;
}

View File

@@ -0,0 +1,44 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 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 "cafCmdFeature.h"
#include "cafPdmField.h"
//==================================================================================================
//
//
//
//==================================================================================================
class RicImportObservedDataFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
public:
RicImportObservedDataFeature();
static void selectObservedDataFileInDialog();
private:
virtual bool isCommandEnabled() override;
virtual void onActionTriggered(bool isChecked) override;
virtual void setupActionLook(QAction* actionToSetup) override;
static bool createAndAddObservedDataFromFile(const QString& fileName);
};

View File

@@ -0,0 +1,67 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 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 "RicImportObservedDataInMenuFeature.h"
#include "RiaApplication.h"
#include "RicImportObservedDataFeature.h"
#include "RimObservedDataCollection.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimSummaryObservedDataFile.h"
#include <QAction>
#include <QFileDialog>
CAF_CMD_SOURCE_INIT(RicImportObservedDataInMenuFeature, "RicImportObservedDataInMenuFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicImportObservedDataInMenuFeature::RicImportObservedDataInMenuFeature()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicImportObservedDataInMenuFeature::isCommandEnabled()
{
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicImportObservedDataInMenuFeature::onActionTriggered(bool isChecked)
{
RicImportObservedDataFeature::selectObservedDataFileInDialog();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicImportObservedDataInMenuFeature::setupActionLook(QAction* actionToSetup)
{
actionToSetup->setIcon(QIcon(":/Default.png"));
actionToSetup->setText("Import Observed Data");
}

View File

@@ -0,0 +1,41 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 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 "cafCmdFeature.h"
#include "cafPdmField.h"
//==================================================================================================
//
//
//
//==================================================================================================
class RicImportObservedDataInMenuFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
public:
RicImportObservedDataInMenuFeature();
private:
virtual bool isCommandEnabled() override;
virtual void onActionTriggered(bool isChecked) override;
virtual void setupActionLook(QAction* actionToSetup) override;
};

View File

@@ -43,7 +43,20 @@ bool RicReloadSummaryCaseFeature::isCommandEnabled()
{
std::vector<RimSummaryCase*> caseSelection = selectedSummaryCases();
return (caseSelection.size() > 0);
if (caseSelection.size() == 0)
{
return false;
}
for (RimSummaryCase* summaryCase : caseSelection)
{
if (summaryCase->isObservedData())
{
return false;
}
}
return true;
}
//--------------------------------------------------------------------------------------------------

View File

@@ -34,6 +34,22 @@
CAF_CMD_SOURCE_INIT(RicEditSummaryCurves, "RicEditSummaryCurves");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicEditSummaryCurves::closeDialogAndResetTargetPlot()
{
if (m_dialogWithSplitter && m_dialogWithSplitter->isVisible())
{
m_dialogWithSplitter->hide();
}
if (m_curveCreator)
{
m_curveCreator->updateFromSummaryPlot(nullptr);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -64,7 +80,7 @@ void RicEditSummaryCurves::onActionTriggered(bool isChecked)
caf::SelectionManager::instance()->objectsByType(&plots);
if (plots.size() == 1)
{
m_curveCreator->setTargetPlot(plots.front());
m_curveCreator->updateFromSummaryPlot(plots.front());
}
}

View File

@@ -35,6 +35,9 @@ class RicEditSummaryCurves : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
public:
void closeDialogAndResetTargetPlot();
protected:
// Overrides
virtual bool isCommandEnabled();

View File

@@ -55,7 +55,21 @@ bool RicPasteSummaryCaseFeature::isCommandEnabled()
return false;
}
return RicPasteSummaryCaseFeature::summaryCases().size() > 0;
std::vector<caf::PdmPointer<RimSummaryCase> > summaryCases = RicPasteSummaryCaseFeature::summaryCases();
if (summaryCases.size() == 0)
{
return false;
}
for (RimSummaryCase* summaryCase : summaryCases)
{
if (summaryCase->isObservedData())
{
return false;
}
}
return true;
}
//--------------------------------------------------------------------------------------------------

View File

@@ -91,13 +91,9 @@ QList<caf::PdmOptionItemInfo> RicSelectSummaryPlotUI::calculateValueOptions(cons
if (fieldNeedingOptions == &m_selectedSummaryPlot)
{
for (RimSummaryPlot* plot : RicSelectSummaryPlotUI::summaryPlots())
{
QIcon icon = plot->uiCapability()->uiIcon();
QString displayName = plot->description();
RimSummaryPlotCollection* summaryPlotColl = summaryPlotCollection();
options.push_back(caf::PdmOptionItemInfo(displayName, plot, false, icon));
}
summaryPlotColl->summaryPlotItemInfos(&options);
}
return options;
@@ -108,7 +104,7 @@ QList<caf::PdmOptionItemInfo> RicSelectSummaryPlotUI::calculateValueOptions(cons
//--------------------------------------------------------------------------------------------------
void RicSelectSummaryPlotUI::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
if (RicSelectSummaryPlotUI::summaryPlots().size() == 0)
if (summaryPlotCollection()->summaryPlots().size() == 0)
{
m_createNewPlot = true;
}
@@ -128,20 +124,11 @@ void RicSelectSummaryPlotUI::defineUiOrdering(QString uiConfigName, caf::PdmUiOr
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryPlot*> RicSelectSummaryPlotUI::summaryPlots()
RimSummaryPlotCollection* RicSelectSummaryPlotUI::summaryPlotCollection()
{
RimProject* project = RiaApplication::instance()->project();
CVF_ASSERT(project);
RimMainPlotCollection* mainPlotColl = project->mainPlotCollection();
CVF_ASSERT(mainPlotColl);
RimSummaryPlotCollection* summaryPlotColl = mainPlotColl->summaryPlotCollection();
CVF_ASSERT(summaryPlotColl);
std::vector<RimSummaryPlot*> sumPlots;
summaryPlotColl->descendantsIncludingThisOfType(sumPlots);
return sumPlots;
return project->mainPlotCollection()->summaryPlotCollection();
}

View File

@@ -23,6 +23,7 @@
#include "cafPdmPtrField.h"
class RimSummaryPlot;
class RimSummaryPlotCollection;
//==================================================================================================
///
@@ -47,7 +48,7 @@ protected:
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
private:
static std::vector<RimSummaryPlot*> summaryPlots();
static RimSummaryPlotCollection* summaryPlotCollection();
private:
caf::PdmPtrField<RimSummaryPlot*> m_selectedSummaryPlot;

View File

@@ -21,22 +21,35 @@
#include "RiaApplication.h"
#include "RicSummaryCurveCreatorUiKeywords.h"
#include "RicSelectSummaryPlotUI.h"
#include "RifReaderEclipseSummary.h"
#include "RigSummaryCaseData.h"
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RimSummaryCase.h"
#include "RimSummaryCase.h"
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
#include "RimSummaryCurveCollection.h"
#include "RimObservedDataCollection.h"
#include "RimObservedData.h"
#include "RiuMainPlotWindow.h"
#include "cafPdmUiListEditor.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
#include <QInputDialog>
#include <algorithm>
#include <sstream>
#include <stack>
#include "RimSummaryCaseMainCollection.h"
#include "RimOilField.h"
#include "RimSummaryCaseCollection.h"
CAF_PDM_SOURCE_INIT(RicSummaryCurveCreator, "RicSummaryCurveCreator");
@@ -107,10 +120,10 @@ RicSummaryCurveCreator::RicSummaryCurveCreator() : m_identifierFieldsMap(
} }
})
{
//CAF_PDM_InitObject("Curve Filter", ":/SummaryCurveFilter16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(&m_selectedCases, "SummaryCases", "Cases", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_selectedSummaryCategory, "IdentifierTypes", "Identifier types", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_currentSummaryCategory, "CurrentSummaryCategory", "Current Summary Category", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_selectedSummaryCategories, "SelectedSummaryCategories", "Summary Categories", "", "", "");
CAF_PDM_InitFieldNoDefault(m_identifierFieldsMap[RifEclipseSummaryAddress::SUMMARY_FIELD][0]->pdmField(), "FieldVectors", "Field vectors", "", "", "");
@@ -157,19 +170,16 @@ RicSummaryCurveCreator::RicSummaryCurveCreator() : m_identifierFieldsMap(
CAF_PDM_InitFieldNoDefault(m_identifierFieldsMap[RifEclipseSummaryAddress::SUMMARY_BLOCK_LGR][1]->pdmField(), "BlockLgrIjk", "Cell IJK", "", "", "");
CAF_PDM_InitFieldNoDefault(m_identifierFieldsMap[RifEclipseSummaryAddress::SUMMARY_BLOCK_LGR][2]->pdmField(), "BlockLgrVectors", "Block Vectors", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_previewPlot, "PreviewPlot", "PreviewPlot", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_targetPlot, "TargetPlot", "TargetPlot", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_targetPlot, "TargetPlot", "Target Plot", "", "", "");
CAF_PDM_InitField(&m_useAutoAppearanceAssignment, "UseAutoAppearanceAssignment", true, "Auto", "", "", "");
CAF_PDM_InitField(&m_appearanceApplyButton, "AppearanceApplyButton", false, "", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_caseAppearanceType, "CaseAppearanceType", "Case", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_variableAppearanceType, "VariableAppearanceType", "Vector", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_wellAppearanceType, "WellAppearanceType", "Well", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_groupAppearanceType, "GroupAppearanceType", "Group", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_regionAppearanceType, "RegionAppearanceType", "Region", "", "", "");
//CAF_PDM_InitFieldNoDefault(&m_selectedCurveTexts, "CurveTexts", "Selected Curves", "", "", "");
//m_selectedCurveTexts.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_previewPlot = new RimSummaryPlot();
for (const auto& itemTypes : m_identifierFieldsMap)
@@ -186,11 +196,28 @@ RicSummaryCurveCreator::RicSummaryCurveCreator() : m_identifierFieldsMap(
m_selectedCases.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName());
m_selectedCases.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_selectedSummaryCategory.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName());
m_selectedSummaryCategory.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_selectedSummaryCategories.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName());
m_selectedSummaryCategories.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_previewPlot.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
//m_previewPlot.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName());
m_currentSummaryCategory.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&m_applyButtonField, "ApplySelection", "", "", "", "");
m_applyButtonField = false;
m_applyButtonField.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
m_applyButtonField.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitFieldNoDefault(&m_closeButtonField, "Close", "", "", "", "");
m_closeButtonField = false;
m_closeButtonField.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
m_closeButtonField.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&m_createNewPlot, "CreateNewPlot", false, "Create New Plot", "", "", "");
m_createNewPlot.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
m_createNewPlot.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_appearanceApplyButton = false;
m_appearanceApplyButton.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
m_appearanceApplyButton.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::LEFT);
}
//--------------------------------------------------------------------------------------------------
@@ -205,19 +232,46 @@ RicSummaryCurveCreator::~RicSummaryCurveCreator()
delete identifierAndField->pdmField();
}
}
delete m_previewPlot;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::setTargetPlot(RimSummaryPlot* targetPlot)
void RicSummaryCurveCreator::updateFromSummaryPlot(RimSummaryPlot* targetPlot)
{
m_targetPlot = targetPlot;
if (targetPlot != nullptr)
if (m_targetPlot != targetPlot)
{
populateCurveCreator(*targetPlot);
updateConnectedEditors();
resetAllFields();
}
m_targetPlot = targetPlot;
m_useAutoAppearanceAssignment = true;
if (m_targetPlot)
{
populateCurveCreator(*m_targetPlot);
loadDataAndUpdatePlot();
}
caf::PdmUiItem::updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicSummaryCurveCreator::isCloseButtonPressed() const
{
return m_closeButtonField();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::clearCloseButton()
{
m_closeButtonField = false;
}
//--------------------------------------------------------------------------------------------------
@@ -225,19 +279,65 @@ void RicSummaryCurveCreator::setTargetPlot(RimSummaryPlot* targetPlot)
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
if (changedField == &m_applyButtonField)
{
m_applyButtonField = false;
updateTargetPlot();
}
else if (changedField == &m_createNewPlot)
{
m_createNewPlot = false;
RimProject* proj = RiaApplication::instance()->project();
RimSummaryPlotCollection* summaryPlotColl = proj->mainPlotCollection()->summaryPlotCollection();
if (summaryPlotColl)
{
QString summaryPlotName = QString("SummaryPlot %1").arg(summaryPlotColl->summaryPlots().size() + 1);
bool ok = false;
summaryPlotName = QInputDialog::getText(NULL, "New Summary Plot Name", "New Summary Plot Name", QLineEdit::Normal, summaryPlotName, &ok);
if (ok)
{
RimSummaryPlot* plot = new RimSummaryPlot();
summaryPlotColl->summaryPlots().push_back(plot);
plot->setDescription(summaryPlotName);
plot->loadDataAndUpdate();
summaryPlotColl->updateConnectedEditors();
RiuMainPlotWindow* mainPlotWindow = RiaApplication::instance()->mainPlotWindow();
if (mainPlotWindow)
{
mainPlotWindow->selectAsCurrentItem(plot);
mainPlotWindow->setExpanded(plot, true);
}
m_createNewPlot = false;
m_targetPlot = plot;
updateTargetPlot();
}
}
}
else if (changedField == &m_appearanceApplyButton)
{
applyAppearanceToAllPreviewCurves();
m_previewPlot->loadDataAndUpdate();
m_appearanceApplyButton = false;
}
else
{
// Lookup item type input field
auto identifierAndField = findIdentifierAndField(changedField);
auto identifierAndField = lookupIdentifierAndFieldFromFieldHandle(changedField);
if (changedField == &m_selectedCases ||
changedField == &m_useAutoAppearanceAssignment ||
changedField == &m_caseAppearanceType ||
changedField == &m_variableAppearanceType ||
changedField == &m_wellAppearanceType ||
changedField == &m_groupAppearanceType ||
changedField == &m_regionAppearanceType ||
identifierAndField != nullptr)
{
loadDataAndUpdatePlot();
}
}
}
//--------------------------------------------------------------------------------------------------
@@ -250,24 +350,76 @@ QList<caf::PdmOptionItemInfo> RicSummaryCurveCreator::calculateValueOptions(cons
if (fieldNeedingOptions == &m_selectedCases)
{
RimProject* proj = RiaApplication::instance()->project();
std::vector<RimSummaryCase*> cases;
std::vector<RimSummaryCase*> topLevelCases;
std::vector<RimOilField*> oilFields;
proj->allSummaryCases(cases);
for (RimSummaryCase* rimCase : cases)
proj->allOilFields(oilFields);
for (RimOilField* oilField : oilFields)
{
options.push_back(caf::PdmOptionItemInfo(rimCase->caseName(), rimCase));
RimSummaryCaseMainCollection* sumCaseMainColl = oilField->summaryCaseMainCollection();
if (sumCaseMainColl)
{
// Top level cases
for (const auto& sumCase : sumCaseMainColl->topLevelSummaryCases())
{
options.push_back(caf::PdmOptionItemInfo(sumCase->caseName(), sumCase));
}
// Grouped cases
for (const auto& sumCaseColl : sumCaseMainColl->summaryCaseCollections())
{
options.push_back(caf::PdmOptionItemInfo::createHeader(sumCaseColl->name(), true));
for (const auto& sumCase : sumCaseColl->allSummaryCases())
{
auto optionItem = caf::PdmOptionItemInfo(sumCase->caseName(), sumCase);
optionItem.setLevel(1);
options.push_back(optionItem);
}
}
// Observed data
auto observedDataColl = oilField->observedDataCollection();
if (observedDataColl->allObservedData().size() > 0)
{
options.push_back(caf::PdmOptionItemInfo::createHeader("Observed Data", true));
for (const auto& obsData : observedDataColl->allObservedData())
{
auto optionItem = caf::PdmOptionItemInfo(obsData->caseName(), obsData);
optionItem.setLevel(1);
options.push_back(optionItem);
}
}
}
}
}
else if (fieldNeedingOptions == &m_targetPlot)
{
RimProject* proj = RiaApplication::instance()->project();
RimSummaryPlotCollection* summaryPlotColl = proj->mainPlotCollection()->summaryPlotCollection();
if (summaryPlotColl)
{
summaryPlotColl->summaryPlotItemInfos(&options);
}
}
else if (fieldNeedingOptions == &m_selectedSummaryCategories)
{
for (size_t i = 0; i < caf::AppEnum<RifEclipseSummaryAddress::SummaryVarCategory>::size(); ++i)
{
options.push_back(caf::PdmOptionItemInfo(caf::AppEnum<RifEclipseSummaryAddress::SummaryVarCategory>::uiTextFromIndex(i),
caf::AppEnum<RifEclipseSummaryAddress::SummaryVarCategory>::fromIndex(i)));
}
}
else
{
// Lookup item type input field
auto identifierAndField = findIdentifierAndField(fieldNeedingOptions);
auto identifierAndField = lookupIdentifierAndFieldFromFieldHandle(fieldNeedingOptions);
if (identifierAndField != nullptr)
{
auto pdmField = identifierAndField->pdmField();
std::set<RifEclipseSummaryAddress> addrUnion =
findPossibleSummaryAddresses(identifierAndField);
std::set<RifEclipseSummaryAddress> addrUnion = findPossibleSummaryAddresses(identifierAndField);
std::set<QString> itemNames;
for (const auto& address : addrUnion)
@@ -293,12 +445,12 @@ void RicSummaryCurveCreator::defineUiOrdering(QString uiConfigName, caf::PdmUiOr
caf::PdmUiGroup* sourcesGroup = uiOrdering.addNewGroupWithKeyword("Sources", RicSummaryCurveCreatorUiKeywords::sources());
sourcesGroup->add(&m_selectedCases);
caf::PdmUiGroup* itemTypesGroup = uiOrdering.addNewGroupWithKeyword("Identifier Types", RicSummaryCurveCreatorUiKeywords::summaryTypes());
itemTypesGroup->add(&m_selectedSummaryCategory);
caf::PdmUiGroup* itemTypesGroup = uiOrdering.addNewGroupWithKeyword("Summary Types", RicSummaryCurveCreatorUiKeywords::summaryTypes());
itemTypesGroup->add(&m_selectedSummaryCategories);
caf::PdmField<std::vector<QString>>* summaryiesField = nullptr;
RifEclipseSummaryAddress::SummaryVarCategory sumCategory = m_selectedSummaryCategory();
RifEclipseSummaryAddress::SummaryVarCategory sumCategory = m_currentSummaryCategory();
if (sumCategory == RifEclipseSummaryAddress::SUMMARY_FIELD)
{
summaryiesField = m_identifierFieldsMap[RifEclipseSummaryAddress::SUMMARY_FIELD][0]->pdmField();
@@ -318,7 +470,7 @@ void RicSummaryCurveCreator::defineUiOrdering(QString uiConfigName, caf::PdmUiOr
else if (sumCategory == RifEclipseSummaryAddress::SUMMARY_REGION)
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroupWithKeyword("Regions", "RegionsKeyword");
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup("Regions");
myGroup->add(m_identifierFieldsMap[RifEclipseSummaryAddress::SUMMARY_REGION][0]->pdmField());
}
@@ -420,13 +572,15 @@ void RicSummaryCurveCreator::defineUiOrdering(QString uiConfigName, caf::PdmUiOr
// Appearance settings
caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroupWithKeyword("Appearance Settings", RicSummaryCurveCreatorUiKeywords::appearance());
//appearanceGroup->setCollapsedByDefault(true);
appearanceGroup->setCollapsedByDefault(true);
appearanceGroup->add(&m_useAutoAppearanceAssignment);
appearanceGroup->add(&m_caseAppearanceType);
appearanceGroup->add(&m_variableAppearanceType);
appearanceGroup->add(&m_wellAppearanceType);
appearanceGroup->add(&m_groupAppearanceType);
appearanceGroup->add(&m_regionAppearanceType);
appearanceGroup->add(&m_appearanceApplyButton);
// Appearance option sensitivity
{
m_caseAppearanceType.uiCapability()->setUiReadOnly(m_useAutoAppearanceAssignment);
@@ -436,18 +590,13 @@ void RicSummaryCurveCreator::defineUiOrdering(QString uiConfigName, caf::PdmUiOr
m_regionAppearanceType.uiCapability()->setUiReadOnly(m_useAutoAppearanceAssignment);
}
// Fields to be displayed directly in UI
uiOrdering.add(&m_createNewPlot);
uiOrdering.add(&m_targetPlot);
uiOrdering.add(&m_applyButtonField);
uiOrdering.add(&m_closeButtonField);
// Dynamic item input editors
/*
auto pdmFields = m_selectedIdentifiers[m_selectedSummaryCategory()];
if (pdmFields.size() > 0)
{
auto groupLabel = QString("%1 input").arg(m_selectedSummaryCategory().uiText());
caf::PdmUiGroup* itemInputGroup = uiOrdering.addNewGroup(groupLabel);
for (const auto& pdmField : pdmFields)
itemInputGroup->add(pdmField->pdmField());
}
*/
m_targetPlot.uiCapability()->setUiReadOnly(m_createNewPlot);
uiOrdering.skipRemainingFields(true);
}
@@ -476,22 +625,18 @@ std::set<RifEclipseSummaryAddress> RicSummaryCurveCreator::findPossibleSummaryAd
int addressCount = static_cast<int>(allAddresses.size());
bool applySelections = identifierAndField == nullptr || (!isVectorField && controllingIdentifierAndField != nullptr);
std::vector<SummaryIdentifierAndField*> selections;
std::vector<SummaryIdentifierAndField*> controllingFields;
if (applySelections)
{
// Build selections vector
selections = buildControllingFieldList(identifierAndField);
controllingFields = buildControllingFieldList(identifierAndField);
}
for (int i = 0; i < addressCount; i++)
{
if (allAddresses[i].category() == m_selectedSummaryCategory())
if (allAddresses[i].category() == m_currentSummaryCategory())
{
bool addressSelected = applySelections ? isAddressSelected(allAddresses[i], selections) : true;
// Todo: Add text filter
//if (!m_summaryFilter->isIncludedByFilter(allAddresses[i])) continue;
bool addressSelected = applySelections ? isAddressCompatibleWithControllingFieldSelection(allAddresses[i], controllingFields) : true;
if (addressSelected)
{
addrUnion.insert(allAddresses[i]);
@@ -508,23 +653,23 @@ std::set<RifEclipseSummaryAddress> RicSummaryCurveCreator::findPossibleSummaryAd
//--------------------------------------------------------------------------------------------------
std::vector<RicSummaryCurveCreator::SummaryIdentifierAndField*> RicSummaryCurveCreator::buildControllingFieldList(const SummaryIdentifierAndField *identifierAndField)
{
std::vector<RicSummaryCurveCreator::SummaryIdentifierAndField*> selections;
auto identifierAndFieldList = m_identifierFieldsMap[m_selectedSummaryCategory()];
std::vector<RicSummaryCurveCreator::SummaryIdentifierAndField*> controllingFields;
auto identifierAndFieldList = m_identifierFieldsMap[m_currentSummaryCategory()];
for (const auto& identifierAndFieldItem : identifierAndFieldList)
{
if (identifierAndFieldItem == identifierAndField)
{
break;
}
selections.push_back(identifierAndFieldItem);
controllingFields.push_back(identifierAndFieldItem);
}
return selections;
return controllingFields;
}
//--------------------------------------------------------------------------------------------------
/// Returns pdm field info from the specified pdm field
///
//--------------------------------------------------------------------------------------------------
RicSummaryCurveCreator::SummaryIdentifierAndField* RicSummaryCurveCreator::findIdentifierAndField(const caf::PdmFieldHandle* pdmFieldHandle)
RicSummaryCurveCreator::SummaryIdentifierAndField* RicSummaryCurveCreator::lookupIdentifierAndFieldFromFieldHandle(const caf::PdmFieldHandle* pdmFieldHandle)
{
for (const auto& itemTypes : m_identifierFieldsMap)
{
@@ -540,17 +685,18 @@ RicSummaryCurveCreator::SummaryIdentifierAndField* RicSummaryCurveCreator::findI
}
//--------------------------------------------------------------------------------------------------
/// Returns the parent pdm field info for the specified pdm field info.
/// Returns the Controlling pdm field info for the specified pdm field info.
/// Controlling means the field controlling the dependent field
/// If the specified pdm field info is the topmost (i.e. index is 0), null pointer is returned
//--------------------------------------------------------------------------------------------------
RicSummaryCurveCreator::SummaryIdentifierAndField* RicSummaryCurveCreator::lookupControllingField(const RicSummaryCurveCreator::SummaryIdentifierAndField *identifierAndField)
RicSummaryCurveCreator::SummaryIdentifierAndField* RicSummaryCurveCreator::lookupControllingField(const RicSummaryCurveCreator::SummaryIdentifierAndField *dependentField)
{
for (const auto& identifierAndFieldList : m_identifierFieldsMap)
{
int index = 0;
for (const auto& iaf : identifierAndFieldList.second)
{
if (iaf == identifierAndField)
if (iaf == dependentField)
{
return index > 0 ? identifierAndFieldList.second[index - 1] : nullptr;
}
@@ -561,9 +707,9 @@ RicSummaryCurveCreator::SummaryIdentifierAndField* RicSummaryCurveCreator::looku
}
//--------------------------------------------------------------------------------------------------
/// Returns true if the specified address object matches the selections
///
//--------------------------------------------------------------------------------------------------
bool RicSummaryCurveCreator::isAddressSelected(const RifEclipseSummaryAddress &address, const std::vector<SummaryIdentifierAndField*>& identifierAndFieldList)
bool RicSummaryCurveCreator::isAddressCompatibleWithControllingFieldSelection(const RifEclipseSummaryAddress &address, const std::vector<SummaryIdentifierAndField*>& identifierAndFieldList)
{
for (const auto& identifierAndField : identifierAndFieldList)
{
@@ -576,26 +722,34 @@ bool RicSummaryCurveCreator::isAddressSelected(const RifEclipseSummaryAddress &a
break;
}
}
if (!match)
{
return false;
}
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseSummaryAddress> RicSummaryCurveCreator::buildAddressListFromSelections()
{
std::set<RifEclipseSummaryAddress> addressSet;
for (const auto& identifierAndFieldList : m_identifierFieldsMap)
{
std::vector<std::pair<RifEclipseSummaryAddress::SummaryIdentifierType, QString>> selectionStack;
addSelectionAddress(identifierAndFieldList.first, identifierAndFieldList.second.begin(), addressSet, selectionStack);
buildAddressListForCategoryRecursively(identifierAndFieldList.first, identifierAndFieldList.second.begin(), addressSet, selectionStack);
}
return addressSet;
}
void RicSummaryCurveCreator::addSelectionAddress(RifEclipseSummaryAddress::SummaryVarCategory category,
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::buildAddressListForCategoryRecursively(RifEclipseSummaryAddress::SummaryVarCategory category,
std::vector<SummaryIdentifierAndField*>::const_iterator identifierAndFieldItr,
std::set<RifEclipseSummaryAddress>& addressSet,
std::vector<std::pair<RifEclipseSummaryAddress::SummaryIdentifierType, QString>>& identifierPath)
@@ -605,7 +759,7 @@ void RicSummaryCurveCreator::addSelectionAddress(RifEclipseSummaryAddress::Summa
identifierPath.push_back(std::make_pair((*identifierAndFieldItr)->summaryIdentifier(), identifierText));
if ((*identifierAndFieldItr)->summaryIdentifier() != RifEclipseSummaryAddress::INPUT_VECTOR_NAME)
{
addSelectionAddress(category, std::next(identifierAndFieldItr, 1), addressSet, identifierPath);
buildAddressListForCategoryRecursively(category, std::next(identifierAndFieldItr, 1), addressSet, identifierPath);
}
else
{
@@ -626,18 +780,13 @@ void RicSummaryCurveCreator::addSelectionAddress(RifEclipseSummaryAddress::Summa
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::loadDataAndUpdatePlot()
{
syncCurvesFromUiSelection();
//loadDataAndUpdate();
//RimSummaryPlot* plot = nullptr;
//firstAncestorOrThisOfType(plot);
//plot->updateAxes();
syncPreviewCurvesFromUiSelection();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::syncCurvesFromUiSelection()
void RicSummaryCurveCreator::syncPreviewCurvesFromUiSelection()
{
// Create a search map containing whats supposed to be curves
@@ -647,7 +796,7 @@ void RicSummaryCurveCreator::syncCurvesFromUiSelection()
std::set<RifEclipseSummaryAddress> selectedAddresses = buildAddressListFromSelections();
// Todo: Move to separate method
// Find the addresses to display
std::set<RifEclipseSummaryAddress> addrUnion;
for (RimSummaryCase* currCase : m_selectedCases)
{
@@ -665,26 +814,23 @@ void RicSummaryCurveCreator::syncCurvesFromUiSelection()
addrUnion.insert(allAddresses[i]);
allCurveDefinitions.insert(std::make_pair(currCase, allAddresses[i]));
}
// Todo: Add text filter
//if (!m_summaryFilter->isIncludedByFilter(allAddresses[i])) continue;
}
}
}
std::vector<RimSummaryCurve*> currentCurvesInPlot = m_previewPlot->summaryCurves();
if (allCurveDefinitions.size() != currentCurvesInPlot.size())
std::vector<RimSummaryCurve*> currentCurvesInPreviewPlot = m_previewPlot->summaryCurves();
if (allCurveDefinitions.size() != currentCurvesInPreviewPlot.size())
{
std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress>> currentCurveDefs;
std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress>> newCurveDefs;
std::set<RimSummaryCurve*> deleteCurves;
std::set<RimSummaryCurve*> curvesToDelete;
for (const auto& curve : currentCurvesInPlot)
for (const auto& curve : currentCurvesInPreviewPlot)
{
currentCurveDefs.insert(std::make_pair(curve->summaryCase(), curve->summaryAddress()));
}
if (allCurveDefinitions.size() < currentCurvesInPlot.size())
if (allCurveDefinitions.size() < currentCurvesInPreviewPlot.size())
{
// Determine which curves to delete from plot
std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress>> deleteCurveDefs;
@@ -692,11 +838,11 @@ void RicSummaryCurveCreator::syncCurvesFromUiSelection()
allCurveDefinitions.begin(), allCurveDefinitions.end(),
std::inserter(deleteCurveDefs, deleteCurveDefs.end()));
for (const auto& curve : currentCurvesInPlot)
for (const auto& curve : currentCurvesInPreviewPlot)
{
std::pair<RimSummaryCase*, RifEclipseSummaryAddress> curveDef = std::make_pair(curve->summaryCase(), curve->summaryAddress());
if (deleteCurveDefs.count(curveDef))
deleteCurves.insert(curve);
if (deleteCurveDefs.count(curveDef) > 0)
curvesToDelete.insert(curve);
}
}
else
@@ -706,48 +852,23 @@ void RicSummaryCurveCreator::syncCurvesFromUiSelection()
currentCurveDefs.begin(), currentCurveDefs.end(),
std::inserter(newCurveDefs, newCurveDefs.end()));
}
updateCurvesFromCurveDefinitions(newCurveDefs, deleteCurves);
updatePreviewCurvesFromCurveDefinitions(allCurveDefinitions, newCurveDefs, curvesToDelete);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::updateCurvesFromCurveDefinitions(const std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress> >& curveDefsToAdd,
void RicSummaryCurveCreator::updatePreviewCurvesFromCurveDefinitions(const std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress> >& allCurveDefsToDisplay,
const std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress> >& curveDefsToAdd,
const std::set<RimSummaryCurve*>& curvesToDelete)
{
RimSummaryCase* prevCase = nullptr;
RimPlotCurve::LineStyleEnum lineStyle = RimPlotCurve::STYLE_SOLID;
RimSummaryCurveAppearanceCalculator curveLookCalc(curveDefsToAdd, getAllSummaryCaseNames(), getAllSummaryWellNames());
RimSummaryCurveAppearanceCalculator curveLookCalc(allCurveDefsToDisplay, getAllSummaryCaseNames(), getAllSummaryWellNames());
if (!m_useAutoAppearanceAssignment())
{
curveLookCalc.assignDimensions(m_caseAppearanceType(),
m_variableAppearanceType(),
m_wellAppearanceType(),
m_groupAppearanceType(),
m_regionAppearanceType());
}
else
{
RimSummaryCurveAppearanceCalculator::CurveAppearanceType caseAppearance;
RimSummaryCurveAppearanceCalculator::CurveAppearanceType variAppearance;
RimSummaryCurveAppearanceCalculator::CurveAppearanceType wellAppearance;
RimSummaryCurveAppearanceCalculator::CurveAppearanceType gropAppearance;
RimSummaryCurveAppearanceCalculator::CurveAppearanceType regiAppearance;
curveLookCalc.getDimensions(&caseAppearance,
&variAppearance,
&wellAppearance,
&gropAppearance,
&regiAppearance);
m_caseAppearanceType = caseAppearance;
m_variableAppearanceType = variAppearance;
m_wellAppearanceType = wellAppearance;
m_groupAppearanceType = gropAppearance;
m_regionAppearanceType = regiAppearance;
}
initCurveAppearanceCalculator(curveLookCalc);
// Delete curves
for (const auto& curve : curvesToDelete)
@@ -756,7 +877,6 @@ void RicSummaryCurveCreator::updateCurvesFromCurveDefinitions(const std::set<std
}
// Add new curves
//m_previewPlot->deleteAllTopLevelCurves();
for (const auto& curveDef : curveDefsToAdd)
{
RimSummaryCase* currentCase = curveDef.first;
@@ -765,30 +885,11 @@ void RicSummaryCurveCreator::updateCurvesFromCurveDefinitions(const std::set<std
curve->setSummaryAddress(curveDef.second);
m_previewPlot->addCurve(curve);
curveLookCalc.setupCurveLook(curve);
//m_currentCurvesInPlot.insert(std::make_pair(curveDef, curve));
//curveTexts.push_back(QString::fromStdString( curveDef.second.uiText()));
}
//m_selectedCurveTexts = curveTexts;
m_previewPlot->loadDataAndUpdate();
m_previewPlot->updateConnectedEditors();
m_previewPlot->zoomAll();
//for (auto& caseAddrPair : curveDefinitions)
//{
// RimSummaryCase* currentCase = caseAddrPair.first;
// RimSummaryCurve* curve = new RimSummaryCurve();
// curve->setParentQwtPlot(m_parentQwtPlot);
// curve->setSummaryCase(currentCase);
// curve->setSummaryAddress(caseAddrPair.second);
// curve->setYAxis(m_plotAxis());
// curve->applyCurveAutoNameSettings(*m_curveNameConfig());
// m_curves.push_back(curve);
// curveLookCalc.setupCurveLook(curve);
//}
updateEditorsConnectedToPreviewPlot();
}
//--------------------------------------------------------------------------------------------------
@@ -844,11 +945,67 @@ std::set<std::string> RicSummaryCurveCreator::getAllSummaryWellNames()
return summaryWellNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
{
if (&m_applyButtonField == field)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*> (attribute);
if (attrib)
{
attrib->m_buttonText = "Apply";
}
}
else if (&m_closeButtonField == field)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*> (attribute);
if (attrib)
{
attrib->m_buttonText = "Cancel";
}
}
else if (&m_createNewPlot == field)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*> (attribute);
if (attrib)
{
attrib->m_buttonText = "New Plot";
}
}
else if (&m_appearanceApplyButton == field)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*> (attribute);
if (attrib)
{
attrib->m_buttonText = "Apply";
}
}
else if (&m_selectedSummaryCategories == field)
{
caf::PdmUiTreeSelectionEditorAttribute* attrib = dynamic_cast<caf::PdmUiTreeSelectionEditorAttribute*> (attribute);
if (attrib)
{
attrib->fieldToReceiveCurrentItemValue = &m_currentSummaryCategory;
attrib->showTextFilter = false;
attrib->showToggleAllCheckbox = false;
}
}
}
//--------------------------------------------------------------------------------------------------
/// Populate curve creator from the given curve collection
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::populateCurveCreator(const RimSummaryPlot& sourceSummaryPlot)
{
m_selectedSummaryCategories.v().clear();
for (size_t i = 0; i < caf::AppEnum<RifEclipseSummaryAddress::SummaryVarCategory>::size(); ++i)
{
m_selectedSummaryCategories.v().push_back(caf::AppEnum<RifEclipseSummaryAddress::SummaryVarCategory>::fromIndex(i));
}
m_previewPlot->deleteAllSummaryCurves();
for (const auto& curve : sourceSummaryPlot.summaryCurves())
{
// Select case if not already selected
@@ -871,10 +1028,60 @@ void RicSummaryCurveCreator::populateCurveCreator(const RimSummaryPlot& sourceSu
}
// Copy curve object to the preview plot
copyCurveAndAddToPlot(curve, m_previewPlot, true);
}
syncPreviewCurvesFromUiSelection();
// Set visibility for imported curves which were not checked in source plot
std::set <std::pair<RimSummaryCase*, RifEclipseSummaryAddress>> sourceCurveDefs;
for (const auto& curve : sourceSummaryPlot.summaryCurves())
{
sourceCurveDefs.insert(std::make_pair(curve->summaryCase(), curve->summaryAddress()));
}
for (const auto& curve : m_previewPlot->summaryCurves())
{
auto curveDef = std::make_pair(curve->summaryCase(), curve->summaryAddress());
if (sourceCurveDefs.count(curveDef) == 0)
curve->setCurveVisiblity(false);
}
updateEditorsConnectedToPreviewPlot();
updateAppearanceEditor();
}
//--------------------------------------------------------------------------------------------------
/// Copy curves from preview plot to target plot
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::updateTargetPlot()
{
if (m_targetPlot == nullptr)
m_targetPlot = new RimSummaryPlot();
m_targetPlot->deleteAllSummaryCurves();
// Add edited curves to target plot
for (const auto& editedCurve : m_previewPlot->summaryCurves())
{
if (!editedCurve->isCurveVisible())
{
continue;
}
copyCurveAndAddToPlot(editedCurve, m_targetPlot);
}
m_targetPlot->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::copyCurveAndAddToPlot(const RimSummaryCurve *curve, RimSummaryPlot *plot, bool forceVisible)
{
RimSummaryCurve* curveCopy = dynamic_cast<RimSummaryCurve*>(curve->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance()));
CVF_ASSERT(curveCopy);
m_previewPlot->addCurve(curveCopy);
if (forceVisible)
curveCopy->setCurveVisiblity(true);
plot->addCurve(curveCopy);
// Resolve references after object has been inserted into the project data model
curveCopy->resolveReferencesRecursively();
@@ -883,24 +1090,110 @@ void RicSummaryCurveCreator::populateCurveCreator(const RimSummaryPlot& sourceSu
curveCopy->setSummaryCase(curve->summaryCase());
curveCopy->initAfterReadRecursively();
curveCopy->loadDataAndUpdate();
}
m_previewPlot->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
/// Copy curves from
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::updateTargetPlot()
void RicSummaryCurveCreator::resetAllFields()
{
// Q: What about hidden curves?
m_selectedCases.clear();
if (m_targetPlot == nullptr)
m_targetPlot = new RimSummaryPlot();
m_previewPlot->deleteAllSummaryCurves();
m_targetPlot = nullptr;
// clear all state in fields
for (auto& identifierAndFieldList : m_identifierFieldsMap)
{
for (auto a : identifierAndFieldList.second)
{
a->pdmField()->v().clear();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::updateEditorsConnectedToPreviewPlot()
{
m_previewPlot->updateConnectedEditors();
m_previewPlot->summaryCurveCollection()->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::initCurveAppearanceCalculator(RimSummaryCurveAppearanceCalculator& curveAppearanceCalc)
{
if (!m_useAutoAppearanceAssignment())
{
curveAppearanceCalc.assignDimensions(m_caseAppearanceType(),
m_variableAppearanceType(),
m_wellAppearanceType(),
m_groupAppearanceType(),
m_regionAppearanceType());
}
else
{
RimSummaryCurveAppearanceCalculator::CurveAppearanceType caseAppearance;
RimSummaryCurveAppearanceCalculator::CurveAppearanceType variAppearance;
RimSummaryCurveAppearanceCalculator::CurveAppearanceType wellAppearance;
RimSummaryCurveAppearanceCalculator::CurveAppearanceType gropAppearance;
RimSummaryCurveAppearanceCalculator::CurveAppearanceType regiAppearance;
curveAppearanceCalc.getDimensions(&caseAppearance,
&variAppearance,
&wellAppearance,
&gropAppearance,
&regiAppearance);
m_caseAppearanceType = caseAppearance;
m_variableAppearanceType = variAppearance;
m_wellAppearanceType = wellAppearance;
m_groupAppearanceType = gropAppearance;
m_regionAppearanceType = regiAppearance;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::applyAppearanceToAllPreviewCurves()
{
std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress>> allCurveDefs = allPreviewCurveDefs();
RimSummaryCurveAppearanceCalculator curveLookCalc(allCurveDefs, getAllSummaryCaseNames(), getAllSummaryWellNames());
initCurveAppearanceCalculator(curveLookCalc);
for (auto& curve : m_previewPlot->summaryCurves())
{
curve->resetAppearance();
curveLookCalc.setupCurveLook(curve);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreator::updateAppearanceEditor()
{
std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress>> allCurveDefs = allPreviewCurveDefs();
RimSummaryCurveAppearanceCalculator curveLookCalc(allCurveDefs, getAllSummaryCaseNames(), getAllSummaryWellNames());
initCurveAppearanceCalculator(curveLookCalc);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress>> RicSummaryCurveCreator::allPreviewCurveDefs() const
{
std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress>> allCurveDefs;
for (const auto& curve : m_previewPlot->summaryCurves())
{
m_targetPlot->addCurve(curve);
allCurveDefs.insert(std::make_pair(curve->summaryCase(), curve->summaryAddress()));
}
m_targetPlot->loadDataAndUpdate();
return allCurveDefs;
}

View File

@@ -75,7 +75,10 @@ public:
virtual ~RicSummaryCurveCreator();
RimSummaryPlot* previewPlot() { return m_previewPlot;}
void setTargetPlot(RimSummaryPlot* targetPlot);
void updateFromSummaryPlot(RimSummaryPlot* targetPlot);
bool isCloseButtonPressed() const;
void clearCloseButton();
private:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField,
@@ -83,42 +86,62 @@ private:
const QVariant& newValue);
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly);
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName,
caf::PdmUiEditorAttribute* attribute) override;
std::set<RifEclipseSummaryAddress> findPossibleSummaryAddresses(const SummaryIdentifierAndField *identifierAndField);
std::vector<SummaryIdentifierAndField*> buildControllingFieldList(const SummaryIdentifierAndField *identifierAndField);
SummaryIdentifierAndField* findIdentifierAndField(const caf::PdmFieldHandle* pdmFieldHandle);
SummaryIdentifierAndField* lookupControllingField(const SummaryIdentifierAndField *identifierAndField);
bool isAddressSelected(const RifEclipseSummaryAddress &address,
SummaryIdentifierAndField* lookupIdentifierAndFieldFromFieldHandle(const caf::PdmFieldHandle* pdmFieldHandle);
SummaryIdentifierAndField* lookupControllingField(const SummaryIdentifierAndField *dependentField);
bool isAddressCompatibleWithControllingFieldSelection(const RifEclipseSummaryAddress &address,
const std::vector<SummaryIdentifierAndField*>& identifierAndFieldList);
std::set<RifEclipseSummaryAddress> buildAddressListFromSelections();
void addSelectionAddress(RifEclipseSummaryAddress::SummaryVarCategory category,
void buildAddressListForCategoryRecursively(RifEclipseSummaryAddress::SummaryVarCategory category,
std::vector<SummaryIdentifierAndField*>::const_iterator identifierAndFieldItr,
std::set<RifEclipseSummaryAddress>& addressSet,
std::vector<std::pair<RifEclipseSummaryAddress::SummaryIdentifierType, QString>>& identifierPath);
void loadDataAndUpdatePlot();
void syncCurvesFromUiSelection();
void updateCurvesFromCurveDefinitions(const std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress> >& curveDefsToAdd,
void syncPreviewCurvesFromUiSelection();
void updatePreviewCurvesFromCurveDefinitions(const std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress> >& allCurveDefsToDisplay,
const std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress> >& curveDefsToAdd,
const std::set<RimSummaryCurve*>& curvesToDelete);
std::set<std::string> getAllSummaryCaseNames();
std::set<std::string> getAllSummaryWellNames();
void populateCurveCreator(const RimSummaryPlot& sourceSummaryPlot);
void updateTargetPlot();
static void copyCurveAndAddToPlot(const RimSummaryCurve *curve, RimSummaryPlot *plot, bool forceVisible = false);
void resetAllFields();
void updateEditorsConnectedToPreviewPlot();
void initCurveAppearanceCalculator(RimSummaryCurveAppearanceCalculator& curveAppearanceCalc);
void applyAppearanceToAllPreviewCurves();
void updateAppearanceEditor();
std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress>>
allPreviewCurveDefs() const;
private:
caf::PdmPtrArrayField<RimSummaryCase*> m_selectedCases;
caf::PdmField<caf::AppEnum<RifEclipseSummaryAddress::SummaryVarCategory>> m_selectedSummaryCategory;
caf::PdmField<std::vector<caf::AppEnum<RifEclipseSummaryAddress::SummaryVarCategory>>> m_selectedSummaryCategories;
caf::PdmField<caf::AppEnum<RifEclipseSummaryAddress::SummaryVarCategory>> m_currentSummaryCategory;
std::map<RifEclipseSummaryAddress::SummaryVarCategory, std::vector<SummaryIdentifierAndField*>> m_identifierFieldsMap;
caf::PdmPtrField<RimSummaryPlot*> m_targetPlot;
caf::PdmChildField<RimSummaryPlot*> m_previewPlot;
RimSummaryPlot* m_previewPlot;
caf::PdmField<bool> m_useAutoAppearanceAssignment;
caf::PdmField<bool> m_appearanceApplyButton;
caf::PdmField< AppearanceTypeAppEnum > m_caseAppearanceType;
caf::PdmField< AppearanceTypeAppEnum > m_variableAppearanceType;
caf::PdmField< AppearanceTypeAppEnum > m_wellAppearanceType;
caf::PdmField< AppearanceTypeAppEnum > m_groupAppearanceType;
caf::PdmField< AppearanceTypeAppEnum > m_regionAppearanceType;
caf::PdmField<bool> m_createNewPlot;
caf::PdmField<bool> m_applyButtonField;
caf::PdmField<bool> m_closeButtonField;
};

View File

@@ -39,6 +39,8 @@ RicSummaryCurveCreatorDialog::RicSummaryCurveCreatorDialog(QWidget* parent, RicS
m_curveCreatorSplitterUi->setPdmObject(summaryCurveCreator);
m_curveCreatorSplitterUi->updateUi();
connect(m_curveCreatorSplitterUi, SIGNAL(signalCloseButtonPressed()), this, SLOT(accept()));
}
//--------------------------------------------------------------------------------------------------

View File

@@ -23,6 +23,10 @@
class RicSummaryCurveCreatorSplitterUi;
class RicSummaryCurveCreator;
//==================================================================================================
///
///
//==================================================================================================
class RicSummaryCurveCreatorDialog : public QDialog
{
public:

View File

@@ -20,6 +20,9 @@
#include "RicSummaryCurveCreator.h"
#include "RicSummaryCurveCreatorUiKeywords.h"
#include "cafPdmUiFieldEditorHandle.h"
#include "cafPdmUiFieldHandle.h"
#include "cafPdmUiGroup.h"
#include "cafPdmUiTreeView.h"
@@ -29,7 +32,8 @@
#include <QSplitter>
#include <QFrame>
#include <QTreeView>
#include "RimSummaryPlot.h"
#include "RimSummaryCurveCollection.h"
//--------------------------------------------------------------------------------------------------
///
@@ -51,6 +55,17 @@ RicSummaryCurveCreatorSplitterUi::~RicSummaryCurveCreatorSplitterUi()
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreatorSplitterUi::recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector<caf::PdmUiItem *>& topLevelUiItems, const QString& uiConfigName)
{
RicSummaryCurveCreator* sumCurveCreator = dynamic_cast<RicSummaryCurveCreator*>(this->pdmItem());
if (sumCurveCreator)
{
if (sumCurveCreator->isCloseButtonPressed())
{
sumCurveCreator->clearCloseButton();
emit signalCloseButtonPressed();
}
}
if (!m_layout) return;
int splitterPositionIndex = 0;
@@ -77,24 +92,26 @@ void RicSummaryCurveCreatorSplitterUi::recursivelyConfigureAndUpdateTopLevelUiIt
}
m_lowerLeftLayout->insertWidget(0, getOrCreateCurveTreeWidget(), 1);
{
caf::PdmUiGroup* group = findGroupByKeyword(topLevelUiItems, RicSummaryCurveCreatorUiKeywords::appearance(), uiConfigName);
QMinimizePanel* groupBox = findOrCreateGroupBox(this->widget(), group, uiConfigName);
m_lowerLeftLayout->insertWidget(0, groupBox);
m_lowerLeftLayout->insertWidget(1, groupBox);
const std::vector<caf::PdmUiItem*>& groupChildren = group->uiItems();
recursivelyConfigureAndUpdateUiItemsInGridLayoutColumn(groupChildren, groupBox->contentFrame(), uiConfigName);
}
m_lowerLeftLayout->insertWidget(1, getOrCreateCurveTreeWidget());
m_secondRowLayout->insertWidget(1, getOrCreatePlotWidget());
// NB! Only groups at top level are handled, fields at top level are not added to layout
// Fields at bottom of dialog
configureAndUpdateFields(1, m_bottomFieldLayout, topLevelUiItems, uiConfigName);
}
//--------------------------------------------------------------------------------------------------
@@ -125,6 +142,10 @@ QWidget* RicSummaryCurveCreatorSplitterUi::createWidget(QWidget* parent)
m_layout->addWidget(m_firstColumnSplitter);
m_bottomFieldLayout = new QHBoxLayout;
m_layout->addLayout(m_bottomFieldLayout);
m_bottomFieldLayout->insertStretch(0, 1);
return widget;
}
@@ -167,7 +188,8 @@ QWidget* RicSummaryCurveCreatorSplitterUi::getOrCreateCurveTreeWidget()
RicSummaryCurveCreator* sumCurveCreator = dynamic_cast<RicSummaryCurveCreator*>(this->pdmItem());
if (sumCurveCreator)
{
curveTreeView->setPdmItem(sumCurveCreator->previewPlot());
RimSummaryCurveCollection* sumColl = sumCurveCreator->previewPlot()->summaryCurveCollection();
curveTreeView->setPdmItem(sumColl);
}
curveTreeView->treeView()->setHeaderHidden(true);
@@ -192,3 +214,72 @@ QWidget* RicSummaryCurveCreatorSplitterUi::getOrCreatePlotWidget()
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCreatorSplitterUi::configureAndUpdateFields(int widgetStartIndex,
QBoxLayout* layout,
const std::vector<caf::PdmUiItem *>& uiItems,
const QString& uiConfigName)
{
int currentWidgetIndex = widgetStartIndex;
for (size_t i = 0; i < uiItems.size(); ++i)
{
if (uiItems[i]->isUiHidden(uiConfigName)) continue;
if (uiItems[i]->isUiGroup()) continue;
{
caf::PdmUiFieldHandle* field = dynamic_cast<caf::PdmUiFieldHandle*>(uiItems[i]);
caf::PdmUiFieldEditorHandle* fieldEditor = findOrCreateFieldEditor(this->widget(), field, uiConfigName);
if (fieldEditor)
{
fieldEditor->setField(field);
// Place the widget(s) into the correct parent and layout
QWidget* fieldCombinedWidget = fieldEditor->combinedWidget();
if (fieldCombinedWidget)
{
fieldCombinedWidget->setParent(this->widget());
layout->insertWidget(currentWidgetIndex++, fieldCombinedWidget);
}
else
{
caf::PdmUiItemInfo::LabelPosType labelPos = field->uiLabelPosition(uiConfigName);
QWidget* fieldEditorWidget = fieldEditor->editorWidget();
if (labelPos != caf::PdmUiItemInfo::HIDDEN)
{
QWidget* fieldLabelWidget = fieldEditor->labelWidget();
if (fieldLabelWidget)
{
fieldLabelWidget->setParent(this->widget());
layout->insertWidget(currentWidgetIndex++, fieldLabelWidget);
fieldLabelWidget->show();
}
}
else
{
QWidget* fieldLabelWidget = fieldEditor->labelWidget();
if (fieldLabelWidget) fieldLabelWidget->hide();
}
if (fieldEditorWidget)
{
fieldEditorWidget->setParent(this->widget()); // To make sure this widget has the current group box as parent.
layout->insertWidget(currentWidgetIndex++, fieldEditorWidget);
}
}
fieldEditor->updateUi(uiConfigName);
}
}
}
}

View File

@@ -24,19 +24,26 @@
class RicSummaryCurveCreator;
class QHBoxLayout;
class QMinimizePanel;
class QSplitter;
class QString;
class QVBoxLayout;
class QHBoxLayout;
class QBoxLayout;
namespace caf {
class PdmUiItem;
}
//==================================================================================================
///
///
//==================================================================================================
class RicSummaryCurveCreatorSplitterUi : public caf::PdmUiWidgetBasedObjectEditor
{
Q_OBJECT
public:
RicSummaryCurveCreatorSplitterUi(QWidget* parent);
~RicSummaryCurveCreatorSplitterUi();
@@ -54,6 +61,15 @@ private:
const QString& keyword,
const QString& uiConfigName);
void configureAndUpdateFields(int widgetStartIndex,
QBoxLayout* layout,
const std::vector<caf::PdmUiItem *>& topLevelUiItems,
const QString& uiConfigName);
signals:
void signalCloseButtonPressed();
private:
QPointer<QVBoxLayout> m_layout;
QPointer<QSplitter> m_firstColumnSplitter;
@@ -63,4 +79,6 @@ private:
QPointer<QHBoxLayout> m_firstRowLayout;
QPointer<QHBoxLayout> m_secondRowLayout;
QPointer<QVBoxLayout> m_lowerLeftLayout;
QPointer<QHBoxLayout> m_bottomFieldLayout;
};

View File

@@ -15,6 +15,8 @@ ${CEE_CURRENT_LIST_DIR}RifEclipseUnifiedRestartFileAccess.h
${CEE_CURRENT_LIST_DIR}RifPerforationIntervalReader.h
${CEE_CURRENT_LIST_DIR}RifReaderEclipseInput.h
${CEE_CURRENT_LIST_DIR}RifReaderEclipseOutput.h
${CEE_CURRENT_LIST_DIR}RifSummaryReaderInterface.h
${CEE_CURRENT_LIST_DIR}RifReaderObservedData.h
${CEE_CURRENT_LIST_DIR}RifReaderEclipseSummary.h
${CEE_CURRENT_LIST_DIR}RifJsonEncodeDecode.h
${CEE_CURRENT_LIST_DIR}RifReaderInterface.h
@@ -45,6 +47,8 @@ ${CEE_CURRENT_LIST_DIR}RifEclipseSummaryTools.cpp
${CEE_CURRENT_LIST_DIR}RifPerforationIntervalReader.cpp
${CEE_CURRENT_LIST_DIR}RifReaderEclipseInput.cpp
${CEE_CURRENT_LIST_DIR}RifReaderEclipseOutput.cpp
${CEE_CURRENT_LIST_DIR}RifSummaryReaderInterface.cpp
${CEE_CURRENT_LIST_DIR}RifReaderObservedData.cpp
${CEE_CURRENT_LIST_DIR}RifReaderEclipseSummary.cpp
${CEE_CURRENT_LIST_DIR}RifJsonEncodeDecode.cpp
${CEE_CURRENT_LIST_DIR}RifReaderInterface.cpp

View File

@@ -191,6 +191,9 @@ std::string RifEclipseSummaryAddress::uiText(RifEclipseSummaryAddress::SummaryId
return "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RifEclipseSummaryAddress::formatUiTextIJK() const
{
return std::to_string(this->cellI()) + ", "
@@ -198,7 +201,9 @@ std::string RifEclipseSummaryAddress::formatUiTextIJK() const
+ std::to_string(this->cellK());
}
// todo: Make class member
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::tuple<int, int, int> RifEclipseSummaryAddress::ijkTupleFromUiText(const std::string &s)
{
auto firstSep = s.find(',');

View File

@@ -231,16 +231,6 @@ RifEclipseSummaryAddress addressFromErtSmSpecNode(const smspec_node_type * ertSu
cellI, cellJ, cellK);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<RifEclipseSummaryAddress>& RifReaderEclipseSummary::allResultAddresses()
{
buildMetaData();
return m_allResultAddresses;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -293,38 +283,6 @@ const std::vector<time_t>& RifReaderEclipseSummary::timeSteps() const
return m_timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QDateTime> RifReaderEclipseSummary::fromTimeT(const std::vector<time_t>& timeSteps)
{
std::vector<QDateTime> a;
for (size_t i = 0; i < timeSteps.size(); i++)
{
QDateTime dt = QDateTime::fromTime_t(timeSteps[i]);
a.push_back(dt);
}
return a;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifReaderEclipseSummary::indexFromAddress(const RifEclipseSummaryAddress& resultAddress)
{
this->buildMetaData();
auto it = m_resultAddressToErtNodeIdx.find(resultAddress);
if (it != m_resultAddressToErtNodeIdx.end())
{
return it->second;
}
return -1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -343,17 +301,6 @@ void RifReaderEclipseSummary::buildMetaData()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifReaderEclipseSummary::hasAddress(const RifEclipseSummaryAddress& resultAddress)
{
this->buildMetaData();
auto it = m_resultAddressToErtNodeIdx.find(resultAddress);
return (it != m_resultAddressToErtNodeIdx.end());
}
//--------------------------------------------------------------------------------------------------
///

View File

@@ -19,6 +19,7 @@
#pragma once
#include "RifEclipseSummaryAddress.h"
#include "RifSummaryReaderInterface.h"
#include <string>
#include <vector>
@@ -34,30 +35,23 @@ class QDateTime;
//
//
//==================================================================================================
class RifReaderEclipseSummary : public cvf::Object
class RifReaderEclipseSummary : public RifSummaryReaderInterface
{
public:
RifReaderEclipseSummary();
~RifReaderEclipseSummary();
bool open(const std::string& headerFileName, const std::vector<std::string>& dataFileNames);
virtual bool open(const std::string& headerFileName, const std::vector<std::string>& dataFileNames) override;
bool hasAddress(const RifEclipseSummaryAddress& resultAddress);
const std::vector<RifEclipseSummaryAddress>& allResultAddresses();
const std::vector<time_t>& timeSteps() const;
virtual const std::vector<time_t>& timeSteps() const override;
bool values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values);
std::string unitName(const RifEclipseSummaryAddress& resultAddress);
// TODO: Move this to a tools class with static members
static std::vector<QDateTime> fromTimeT(const std::vector<time_t>& timeSteps);
virtual bool values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values) override;
std::string unitName(const RifEclipseSummaryAddress& resultAddress) override;
private:
virtual int timeStepCount() const override;
int timeStepCount() const;
int indexFromAddress(const RifEclipseSummaryAddress& resultAddress);
void buildMetaData();
virtual void buildMetaData() override;
private:
// Taken from ecl_sum.h
typedef struct ecl_sum_struct ecl_sum_type;
@@ -66,9 +60,5 @@ private:
ecl_sum_type* m_ecl_sum;
const ecl_smspec_type * m_ecl_SmSpec;
std::vector<time_t> m_timeSteps;
std::vector<RifEclipseSummaryAddress> m_allResultAddresses;
std::map<RifEclipseSummaryAddress, int> m_resultAddressToErtNodeIdx;
};

View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "RifReaderObservedData.h"
#include "ert/ecl/ecl_sum.h"
#include <string>
#include <assert.h>
#include <QDateTime>
#include "ert/ecl/smspec_node.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifReaderObservedData::RifReaderObservedData()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifReaderObservedData::~RifReaderObservedData()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifReaderObservedData::open(const std::string& headerFileName, const std::vector<std::string>& dataFileNames)
{
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifReaderObservedData::values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values)
{
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifReaderObservedData::timeStepCount() const
{
return 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<time_t>& RifReaderObservedData::timeSteps() const
{
std::vector<time_t> steps;
return steps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderObservedData::buildMetaData()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RifReaderObservedData::unitName(const RifEclipseSummaryAddress& resultAddress)
{
std::string str = "";
return str;
}

View File

@@ -0,0 +1,59 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "RifEclipseSummaryAddress.h"
#include "RifSummaryReaderInterface.h"
#include <string>
#include <vector>
#include <map>
#include "cvfObject.h"
class QDateTime;
//==================================================================================================
//
//
//==================================================================================================
class RifReaderObservedData : public RifSummaryReaderInterface
{
public:
RifReaderObservedData();
~RifReaderObservedData();
virtual bool open(const std::string& headerFileName, const std::vector<std::string>& dataFileNames) override;
virtual const std::vector<time_t>& timeSteps() const override;
virtual bool values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values) override;
std::string unitName(const RifEclipseSummaryAddress& resultAddress) override;
private:
virtual int timeStepCount() const override;
virtual void buildMetaData() override;
private:
};

View File

@@ -0,0 +1,78 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "RifSummaryReaderInterface.h"
#include <string>
#include <QDateTime>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<RifEclipseSummaryAddress>& RifSummaryReaderInterface::allResultAddresses()
{
this->buildMetaData();
return m_allResultAddresses;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QDateTime> RifSummaryReaderInterface::fromTimeT(const std::vector<time_t>& timeSteps)
{
std::vector<QDateTime> a;
for (size_t i = 0; i < timeSteps.size(); i++)
{
QDateTime dt = QDateTime::fromTime_t(timeSteps[i]);
a.push_back(dt);
}
return a;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifSummaryReaderInterface::indexFromAddress(const RifEclipseSummaryAddress& resultAddress)
{
this->buildMetaData();
auto it = m_resultAddressToErtNodeIdx.find(resultAddress);
if (it != m_resultAddressToErtNodeIdx.end())
{
return it->second;
}
return -1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifSummaryReaderInterface::hasAddress(const RifEclipseSummaryAddress& resultAddress)
{
this->buildMetaData();
auto it = m_resultAddressToErtNodeIdx.find(resultAddress);
return (it != m_resultAddressToErtNodeIdx.end());
}

View File

@@ -0,0 +1,63 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "RifEclipseSummaryAddress.h"
#include <string>
#include <vector>
#include <map>
#include "cvfObject.h"
class QDateTime;
//==================================================================================================
//
//
//==================================================================================================
class RifSummaryReaderInterface : public cvf::Object
{
public:
virtual bool open(const std::string& headerFileName, const std::vector<std::string>& dataFileNames) = 0;
bool hasAddress(const RifEclipseSummaryAddress& resultAddress);
const std::vector<RifEclipseSummaryAddress>& allResultAddresses();
virtual const std::vector<time_t>& timeSteps() const = 0;
virtual bool values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values) = 0;
virtual std::string unitName(const RifEclipseSummaryAddress& resultAddress) = 0;
// TODO: Move this to a tools class with static members
static std::vector<QDateTime> fromTimeT(const std::vector<time_t>& timeSteps);
protected:
virtual int timeStepCount() const = 0;
int indexFromAddress(const RifEclipseSummaryAddress& resultAddress);
virtual void buildMetaData() = 0;
protected:
std::vector<RifEclipseSummaryAddress> m_allResultAddresses;
std::map<RifEclipseSummaryAddress, int> m_resultAddressToErtNodeIdx;
};

View File

@@ -90,6 +90,9 @@ ${CEE_CURRENT_LIST_DIR}RimGeometrySelectionItem.h
${CEE_CURRENT_LIST_DIR}RimEclipseGeometrySelectionItem.h
${CEE_CURRENT_LIST_DIR}RimDialogData.h
${CEE_CURRENT_LIST_DIR}RimTimeStepFilter.h
${CEE_CURRENT_LIST_DIR}RimObservedData.h
${CEE_CURRENT_LIST_DIR}RimObservedDataCollection.h
${CEE_CURRENT_LIST_DIR}RimSummaryObservedDataFile.h
)
if (RESINSIGHT_ENABLE_PROTOTYPE_FEATURE_FRACTURES)
@@ -185,6 +188,9 @@ ${CEE_CURRENT_LIST_DIR}RimGeometrySelectionItem.cpp
${CEE_CURRENT_LIST_DIR}RimEclipseGeometrySelectionItem.cpp
${CEE_CURRENT_LIST_DIR}RimDialogData.cpp
${CEE_CURRENT_LIST_DIR}RimTimeStepFilter.cpp
${CEE_CURRENT_LIST_DIR}RimObservedData.cpp
${CEE_CURRENT_LIST_DIR}RimObservedDataCollection.cpp
${CEE_CURRENT_LIST_DIR}RimSummaryObservedDataFile.cpp
)
if (RESINSIGHT_ENABLE_PROTOTYPE_FEATURE_FRACTURES)

View File

@@ -35,9 +35,9 @@
#include "RimEclipseWell.h"
#include "RimEclipseWellCollection.h"
#include "RimFault.h"
#include "RimFlowCharacteristicsPlot.h"
#include "RimFlowDiagSolution.h"
#include "RimFlowPlotCollection.h"
#include "RimFlowCharacteristicsPlot.h"
#include "RimFormationNames.h"
#include "RimFormationNamesCollection.h"
#include "RimGeoMechCase.h"
@@ -48,6 +48,7 @@
#include "RimIntersection.h"
#include "RimIntersectionBox.h"
#include "RimIntersectionCollection.h"
#include "RimObservedData.h"
#include "RimScriptCollection.h"
#include "RimSummaryCase.h"
#include "RimSummaryCurve.h"
@@ -321,9 +322,12 @@ QStringList RimContextCommandBuilder::commandsFromSelection()
commandIds << "RicCopyReferencesToClipboardFeature";
}
else if (dynamic_cast<RimSummaryCase*>(uiItem))
{
if (!dynamic_cast<RimObservedData*>(uiItem))
{
commandIds << "RicNewSummaryPlotFeature";
}
}
else if (dynamic_cast<RimWellLogFileChannel*>(uiItem))
{
commandIds << "RicAddWellLogToPlotFeature";
@@ -445,14 +449,16 @@ QStringList RimContextCommandBuilder::commandsFromSelection()
commandIds << "RicFlyToObjectFeature";
commandIds << "RicExportCarfin";
commandIds << "RicImportObservedDataFeature";
commandIds << "RicPasteSummaryCaseFeature";
commandIds << "RicReloadSummaryCaseFeature";
commandIds << "RicCreateSummaryCaseCollectionFeature";
commandIds << "Separator";
commandIds << "RicCutReferencesToClipboardFeature";
commandIds << "Separator";
commandIds << "RicCloseSummaryCaseFeature";
commandIds << "RicCloseSummaryCaseInCollectionFeature";
commandIds << "RicDeleteSummaryCaseCollectionFeature";
commandIds << "RicCutReferencesToClipboardFeature";
// Fracture commands
#ifdef USE_PROTOTYPE_FEATURE_FRACTURES

View File

@@ -0,0 +1,61 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "RimObservedData.h"
#include "RimTools.h"
#include <QFileInfo>
CAF_PDM_SOURCE_INIT(RimObservedData, "ObservedData");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimObservedData::RimObservedData()
{
m_isObservedData = true;
CAF_PDM_InitFieldNoDefault(&m_summaryCategory, "SummaryType", "Summary Type", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_identifierName, "IdentifierName", "Identifier Name", "", "", "");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimObservedData::summaryHeaderFilename() const
{
return m_summaryHeaderFilename();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimObservedData::caseName()
{
QFileInfo caseFileName(this->summaryHeaderFilename());
return caseFileName.completeBaseName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimObservedData::updateFilePathsFromProjectPath(const QString & newProjectPath, const QString & oldProjectPath)
{
m_summaryHeaderFilename = RimTools::relocateFile(m_summaryHeaderFilename(), newProjectPath, oldProjectPath, nullptr, nullptr);
}

View File

@@ -0,0 +1,46 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "RimSummaryCase.h"
#include "RifEclipseSummaryAddress.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cvfObject.h"
//==================================================================================================
//
//==================================================================================================
class RimObservedData : public RimSummaryCase
{
CAF_PDM_HEADER_INIT;
public:
RimObservedData();
virtual QString summaryHeaderFilename() const override;
virtual QString caseName() override;
virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override;
private:
caf::PdmField<caf::AppEnum<RifEclipseSummaryAddress::SummaryVarCategory> > m_summaryCategory;
caf::PdmField<QString> m_identifierName;
};

View File

@@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "RimObservedDataCollection.h"
#include "RimObservedData.h"
#include "RimSummaryObservedDataFile.h"
CAF_PDM_SOURCE_INIT(RimObservedDataCollection, "ObservedDataCollection");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimObservedDataCollection::RimObservedDataCollection()
{
CAF_PDM_InitObject("Observed Data", ":/Folder.png", "", "");
CAF_PDM_InitFieldNoDefault(&m_observedDataArray, "ObservedDataArray", "", "", "", "");
m_observedDataArray.uiCapability()->setUiHidden(true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimObservedDataCollection::~RimObservedDataCollection()
{
m_observedDataArray.deleteAllChildObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimObservedDataCollection::removeObservedData(RimObservedData* observedData)
{
m_observedDataArray.removeChildObject(observedData);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimObservedDataCollection::addObservedData(RimObservedData* observedData)
{
m_observedDataArray.push_back(observedData);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryObservedDataFile* RimObservedDataCollection::createAndAddObservedDataFromFileName(const QString& fileName)
{
RimSummaryObservedDataFile* newObservedData = new RimSummaryObservedDataFile();
this->m_observedDataArray.push_back(newObservedData);
newObservedData->setSummaryHeaderFilename(fileName);
newObservedData->updateOptionSensitivity();
this->updateConnectedEditors();
return newObservedData;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimObservedData*> RimObservedDataCollection::allObservedData()
{
std::vector<RimObservedData*> allObservedData;
allObservedData.insert(allObservedData.begin(), m_observedDataArray.begin(), m_observedDataArray.end());
return allObservedData;
}

View File

@@ -0,0 +1,45 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "cafPdmObject.h"
#include "cafPdmChildArrayField.h"
class RimObservedData;
class RimSummaryObservedDataFile;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RimObservedDataCollection : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimObservedDataCollection();
virtual ~RimObservedDataCollection();
void removeObservedData(RimObservedData* observedData);
void addObservedData(RimObservedData* observedData);
RimSummaryObservedDataFile* createAndAddObservedDataFromFileName(const QString& fileName);
std::vector<RimObservedData*> allObservedData();
private:
caf::PdmChildArrayField<RimObservedData*> m_observedDataArray;
};

View File

@@ -28,6 +28,9 @@
#endif // USE_PROTOTYPE_FEATURE_FRACTURES
#include "RimGeoMechModels.h"
#include "RimObservedData.h"
#include "RimObservedDataCollection.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseMainCollection.h"
#include "RimWellPathCollection.h"
@@ -50,6 +53,7 @@ RimOilField::RimOilField(void)
CAF_PDM_InitFieldNoDefault(&summaryCaseMainCollection,"SummaryCaseCollection","Summary Cases",":/GridModels.png","","");
CAF_PDM_InitFieldNoDefault(&formationNamesCollection,"FormationNamesCollection","Formations","","","");
CAF_PDM_InitFieldNoDefault(&observedDataCollection, "ObservedDataCollection", "Observed data", ":/Cases16x16.png", "", "");
#ifdef USE_PROTOTYPE_FEATURE_FRACTURES
fractureDefinitionCollection = new RimFractureTemplateCollection();
@@ -58,6 +62,7 @@ RimOilField::RimOilField(void)
analysisModels = new RimEclipseCaseCollection();
wellPathCollection = new RimWellPathCollection();
summaryCaseMainCollection = new RimSummaryCaseMainCollection();
observedDataCollection = new RimObservedDataCollection();
}
//--------------------------------------------------------------------------------------------------
@@ -75,5 +80,74 @@ RimOilField::~RimOilField(void)
if (analysisModels()) delete analysisModels();
if (summaryCaseMainCollection()) delete summaryCaseMainCollection();
if (formationNamesCollection()) delete formationNamesCollection();
if (observedDataCollection()) delete observedDataCollection();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimOilField::uniqueShortNameForCase(RimSummaryCase* summaryCase)
{
std::set<QString> allAutoShortNames;
std::vector<RimSummaryCase*> allCases = summaryCaseMainCollection->allSummaryCases();
std::vector<RimObservedData*> observedDataCases = observedDataCollection->allObservedData();
for (RimObservedData* observedData : observedDataCases)
{
allCases.push_back(dynamic_cast<RimSummaryCase*>(observedData));
}
for (RimSummaryCase* sumCase : allCases)
{
if (sumCase && sumCase != summaryCase)
{
allAutoShortNames.insert(sumCase->shortName());
}
}
bool foundUnique = false;
QString caseName = summaryCase->caseName();
QString shortName;
if (caseName.size() > 2)
{
QString candidate;
candidate += caseName[0];
for (int i = 1; i < caseName.size(); ++i)
{
if (allAutoShortNames.count(candidate + caseName[i]) == 0)
{
shortName = candidate + caseName[i];
foundUnique = true;
break;
}
}
}
else
{
shortName = caseName.left(2);
if (allAutoShortNames.count(shortName) == 0)
{
foundUnique = true;
}
}
QString candidate = shortName;
int autoNumber = 0;
while (!foundUnique)
{
candidate = shortName + QString::number(autoNumber++);
if (allAutoShortNames.count(candidate) == 0)
{
shortName = candidate;
foundUnique = true;
}
}
return shortName;
}

View File

@@ -26,11 +26,13 @@
#include "cafPdmPointer.h"
class RimEclipseCaseCollection;
class RimGeoMechModels;
class RimWellPathCollection;
class RimFractureTemplateCollection;
class RimSummaryCaseMainCollection;
class RimFormationNamesCollection;
class RimFractureTemplateCollection;
class RimGeoMechModels;
class RimObservedDataCollection;
class RimSummaryCase;
class RimSummaryCaseMainCollection;
class RimWellPathCollection;
//==================================================================================================
///
@@ -44,11 +46,14 @@ public:
RimOilField(void);
virtual ~RimOilField(void);
QString uniqueShortNameForCase(RimSummaryCase* summaryCase);
caf::PdmChildField<RimEclipseCaseCollection*> analysisModels;
caf::PdmChildField<RimGeoMechModels*> geoMechModels;
caf::PdmChildField<RimWellPathCollection*> wellPathCollection;
caf::PdmChildField<RimFractureTemplateCollection*> fractureDefinitionCollection;
caf::PdmChildField<RimSummaryCaseMainCollection*> summaryCaseMainCollection;
caf::PdmChildField<RimObservedDataCollection*> observedDataCollection;
caf::PdmChildField<RimFormationNamesCollection*> formationNamesCollection;
};

View File

@@ -272,6 +272,14 @@ bool RimPlotCurve::isCurveVisible() const
return m_showCurve;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotCurve::setCurveVisiblity(bool visible)
{
m_showCurve = visible;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -472,6 +480,18 @@ void RimPlotCurve::setLineThickness(int thickness)
m_curveThickness = thickness;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPlotCurve::resetAppearance()
{
setColor(cvf::Color3f(cvf::Color3::BLACK));
setLineThickness(2);
setLineStyle(STYLE_SOLID);
setSymbol(SYMBOL_NONE);
setSymbolSkipDinstance(10);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -80,8 +80,9 @@ public:
void setSymbol(PointSymbolEnum symbolStyle);
void setSymbolSkipDinstance(float distance);
void setLineThickness(int thickness);
void resetAppearance();
bool isCurveVisible() const;
void setCurveVisiblity(bool visible);
void updateCurveName();
QString curveName() const { return m_curveName; }

View File

@@ -47,6 +47,7 @@
#include "RimIdenticalGridCaseGroup.h"
#include "RimMainPlotCollection.h"
#include "RimMultiSnapshotDefinition.h"
#include "RimObservedDataCollection.h"
#include "RimOilField.h"
#include "RimScriptCollection.h"
#include "RimSummaryCaseMainCollection.h"
@@ -548,6 +549,24 @@ void RimProject::allSummaryCases(std::vector<RimSummaryCase*>& sumCases)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimProject::allObservedData(std::vector<RimObservedData*>& observedData)
{
for (RimOilField* oilField : oilFields)
{
if (!oilField) continue;
RimObservedDataCollection* observedDataCollection = oilField->observedDataCollection();
if (observedDataCollection)
{
observedData.clear();
std::vector<RimObservedData*> allObservedData = observedDataCollection->allObservedData();
observedData.insert(observedData.end(), allObservedData.begin(), allObservedData.end());
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -630,6 +649,18 @@ void RimProject::createDisplayModelAndRedrawAllViews()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimProject::allOilFields(std::vector<RimOilField*>& oilFields)
{
oilFields.clear();
for (const auto& oilField : this->oilFields)
{
oilFields.push_back(oilField);
}
}
//--------------------------------------------------------------------------------------------------
/// Currently there will be only one oil field in Resinsight, so return hardcoded first oil field
/// from the RimOilField collection.
@@ -855,7 +886,14 @@ void RimProject::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QS
RimOilField* oilField = activeOilField();
if (oilField)
{
if (oilField->summaryCaseMainCollection()) uiTreeOrdering.add(oilField->summaryCaseMainCollection());
if (oilField->summaryCaseMainCollection())
{
uiTreeOrdering.add( oilField->summaryCaseMainCollection() );
}
if (oilField->observedDataCollection())
{
uiTreeOrdering.add( oilField->observedDataCollection() );
}
}
if (mainPlotCollection)

View File

@@ -39,6 +39,7 @@ class RimEclipseCase;
class RimIdenticalGridCaseGroup;
class RimMainPlotCollection;
class RimMultiSnapshotDefinition;
class RimObservedData;
class RimOilField;
class RimScriptCollection;
class RimSummaryCase;
@@ -94,6 +95,7 @@ public:
void allCases(std::vector<RimCase*>& cases);
void allSummaryCases(std::vector<RimSummaryCase*>& sumCases);
void allObservedData(std::vector<RimObservedData*>& observedData);
void allNotLinkedViews(std::vector<RimView*>& views);
void allVisibleViews(std::vector<RimView*>& views);
@@ -101,6 +103,7 @@ public:
void computeUtmAreaOfInterest();
void allOilFields(std::vector<RimOilField*>& oilFields);
RimOilField* activeOilField();
const RimOilField* activeOilField() const;

View File

@@ -0,0 +1,54 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "RimSummaryObservedDataFile.h"
#include "RigObservedData.h"
#include "RimTools.h"
#include <QFileInfo>
CAF_PDM_SOURCE_INIT(RimSummaryObservedDataFile, "SummaryObservedDataFile");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryObservedDataFile::RimSummaryObservedDataFile()
{
CAF_PDM_InitObject("Observed data file", ":/Default.png", "", "");
m_summaryHeaderFilename.uiCapability()->setUiName("File");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryObservedDataFile::~RimSummaryObservedDataFile()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryObservedDataFile::setSummaryHeaderFilename(const QString& fileName)
{
m_summaryHeaderFilename = fileName;
this->updateAutoShortName();
this->updateTreeItemName();
}

View File

@@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "RimObservedData.h"
#include "cafPdmObject.h"
#include "cafPdmField.h"
#include "cvfObject.h"
//==================================================================================================
//
//==================================================================================================
class RimSummaryObservedDataFile : public RimObservedData
{
CAF_PDM_HEADER_INIT;
public:
RimSummaryObservedDataFile();
virtual ~RimSummaryObservedDataFile();
void setSummaryHeaderFilename(const QString& fileName);
};

View File

@@ -19,13 +19,15 @@
#include "RimSummaryCase.h"
#include "RigSummaryCaseData.h"
#include "RimEclipseCase.h"
#include "RimMainPlotCollection.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimSummaryCaseMainCollection.h"
#include "RimSummaryPlotCollection.h"
#include <QFileInfo>
#include "RimProject.h"
#include "RimSummaryPlotCollection.h"
#include "RimMainPlotCollection.h"
CAF_PDM_ABSTRACT_SOURCE_INIT(RimSummaryCase,"SummaryCase");
@@ -41,6 +43,8 @@ RimSummaryCase::RimSummaryCase()
CAF_PDM_InitFieldNoDefault(&m_summaryHeaderFilename, "SummaryHeaderFilename", "Summary Header File", "", "", "");
m_summaryHeaderFilename.uiCapability()->setUiReadOnly(true);
m_isObservedData = false;
}
//--------------------------------------------------------------------------------------------------
@@ -78,6 +82,14 @@ RigSummaryCaseData* RimSummaryCase::caseData()
return m_summaryCaseData.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimSummaryCase::isObservedData()
{
return m_isObservedData;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -147,16 +159,16 @@ void RimSummaryCase::updateAutoShortName()
{
if(m_useAutoShortName)
{
RimSummaryCaseMainCollection* summaryCaseMainCollection = NULL;
this->firstAncestorOrThisOfType(summaryCaseMainCollection);
CVF_ASSERT(summaryCaseMainCollection);
RimOilField* oilField = NULL;
this->firstAncestorOrThisOfType(oilField);
CVF_ASSERT(oilField);
m_shortName = summaryCaseMainCollection->uniqueShortNameForCase(this);
updateTreeItemName();
m_shortName = oilField->uniqueShortNameForCase(this);
}
else if (m_shortName() == QString("Display Name"))
{
m_shortName = caseName();
updateTreeItemName();
}
updateTreeItemName();
}

View File

@@ -51,14 +51,16 @@ public:
virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) = 0;
bool isObservedData();
protected:
void updateTreeItemName();
caf::PdmField<QString> m_shortName;
caf::PdmField<bool> m_useAutoShortName;
caf::PdmField<QString> m_summaryHeaderFilename;
cvf::ref<RigSummaryCaseData> m_summaryCaseData;
bool m_isObservedData;
private:
// Overridden PDM methods

View File

@@ -36,6 +36,7 @@ public:
void addCase(RimSummaryCase* summaryCase);
std::vector<RimSummaryCase*> allSummaryCases();
QString name() const { return m_name; }
private:
virtual caf::PdmFieldHandle* userDescriptionField() override;

View File

@@ -225,6 +225,32 @@ std::vector<RimSummaryCase*> RimSummaryCaseMainCollection::allSummaryCases()
return cases;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCase*> RimSummaryCaseMainCollection::topLevelSummaryCases() const
{
std::vector<RimSummaryCase*> cases;
for (const auto& sumCase : m_cases)
{
cases.push_back(sumCase);
}
return cases;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCaseCollection*> RimSummaryCaseMainCollection::summaryCaseCollections() const
{
std::vector<RimSummaryCaseCollection*> summaryCaseCollections;
for (const auto& caseColl : m_caseCollections)
{
summaryCaseCollections.push_back(caseColl);
}
return summaryCaseCollections;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -40,6 +40,8 @@ public:
size_t summaryCaseCount() const;
std::vector<RimSummaryCase*> allSummaryCases();
std::vector<RimSummaryCase*> topLevelSummaryCases() const;
std::vector<RimSummaryCaseCollection*> summaryCaseCollections() const;
void createSummaryCasesFromRelevantEclipseResultCases();
RimSummaryCase* createAndAddSummaryCaseFromEclipseResultCase(RimEclipseResultCase* eclResCase);

View File

@@ -201,7 +201,7 @@ void RimSummaryCurve::setSummaryCase(RimSummaryCase* sumCase)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCase* RimSummaryCurve::summaryCase()
RimSummaryCase* RimSummaryCurve::summaryCase() const
{
return m_summaryCase();
}

View File

@@ -78,7 +78,7 @@ public:
virtual ~RimSummaryCurve();
void setSummaryCase(RimSummaryCase* sumCase);
RimSummaryCase* summaryCase();
RimSummaryCase* summaryCase() const;
RifEclipseSummaryAddress summaryAddress();
void setSummaryAddress(const RifEclipseSummaryAddress& address);

View File

@@ -176,6 +176,14 @@ void RimSummaryCurveCollection::deleteCurvesAssosiatedWithCase(RimSummaryCase* s
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCurveCollection::deleteAllCurves()
{
m_curves.deleteAllChildObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -60,7 +60,7 @@ public:
std::vector<RimSummaryCurve*> curves();
void deleteCurvesAssosiatedWithCase(RimSummaryCase* summaryCase);
void deleteAllCurves();
void updateCaseNameHasChanged();
private:

View File

@@ -453,21 +453,23 @@ QString RimSummaryPlot::asciiDataForPlotExport() const
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCurve*> RimSummaryPlot::summaryCurves() const
{
std::vector<RimSummaryCurve*> curves;
curves.reserve(m_summaryCurves.size());
for (const auto& curve : m_summaryCurveCollection->curves())
{
curves.push_back(curve);
}
return curves;
return m_summaryCurveCollection->curves();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::deleteAllCurves()
void RimSummaryPlot::deleteAllSummaryCurves()
{
m_summaryCurveCollection->curves().clear();
m_summaryCurveCollection->deleteAllCurves();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCurveCollection* RimSummaryPlot::summaryCurveCollection() const
{
return m_summaryCurveCollection();
}
//--------------------------------------------------------------------------------------------------

View File

@@ -100,8 +100,8 @@ public:
QString asciiDataForPlotExport() const;
std::vector<RimSummaryCurve*> summaryCurves() const;
void deleteAllCurves();
void deleteAllSummaryCurves();
RimSummaryCurveCollection* summaryCurveCollection() const;
// RimViewWindow overrides
public:
virtual QWidget* createViewWidget(QWidget* mainWindowParent) override;

View File

@@ -130,3 +130,17 @@ void RimSummaryPlotCollection::updateSummaryNameHasChanged()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotCollection::summaryPlotItemInfos(QList<caf::PdmOptionItemInfo>* optionInfos) const
{
for (RimSummaryPlot* plot : summaryPlots())
{
QIcon icon = plot->uiCapability()->uiIcon();
QString displayName = plot->description();
optionInfos->push_back(caf::PdmOptionItemInfo(displayName, plot, false, icon));
}
}

View File

@@ -46,6 +46,9 @@ public:
caf::PdmChildArrayField<RimSummaryPlot*> summaryPlots;
void updateSummaryNameHasChanged();
void summaryPlotItemInfos(QList<caf::PdmOptionItemInfo>* optionInfos) const;
private:
RifReaderEclipseSummary* createSummaryFileReader(const QString& eclipseCaseFilePathBasename);
RifReaderEclipseSummary* getOrCreateSummaryFileReader(const QString& eclipseCaseFilePathBasename);

View File

@@ -53,6 +53,7 @@ ${CEE_CURRENT_LIST_DIR}RigHexIntersectionTools.h
${CEE_CURRENT_LIST_DIR}RigTimeHistoryResultAccessor.h
${CEE_CURRENT_LIST_DIR}RigCurveDataTools.h
${CEE_CURRENT_LIST_DIR}RigSummaryCaseData.h
${CEE_CURRENT_LIST_DIR}RigObservedData.h
${CEE_CURRENT_LIST_DIR}RigLasFileExporter.h
${CEE_CURRENT_LIST_DIR}RigSimulationWellCoordsAndMD.h
${CEE_CURRENT_LIST_DIR}RigFishbonesGeometry.h
@@ -123,6 +124,7 @@ ${CEE_CURRENT_LIST_DIR}RigHexIntersectionTools.cpp
${CEE_CURRENT_LIST_DIR}RigTimeHistoryResultAccessor.cpp
${CEE_CURRENT_LIST_DIR}RigCurveDataTools.cpp
${CEE_CURRENT_LIST_DIR}RigSummaryCaseData.cpp
${CEE_CURRENT_LIST_DIR}RigObservedData.cpp
${CEE_CURRENT_LIST_DIR}RigLasFileExporter.cpp
${CEE_CURRENT_LIST_DIR}RigSimulationWellCoordsAndMD.cpp
${CEE_CURRENT_LIST_DIR}RigFishbonesGeometry.cpp

View File

@@ -0,0 +1,46 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "RigObservedData.h"
#include <QDir>
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigObservedData::RigObservedData(const QString& observedDataFileName)
{
openOrReloadCase(observedDataFileName);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigObservedData::~RigObservedData()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigObservedData::openOrReloadCase(const QString& observedDataFileName)
{
}

View File

@@ -0,0 +1,35 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- 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 "cvfBase.h"
#include "cvfObject.h"
class QString;
class RigObservedData: public cvf::Object
{
public:
explicit RigObservedData(const QString& observedDataFileName );
~RigObservedData();
void openOrReloadCase(const QString& observedDataFileName);
private:
};

View File

@@ -184,6 +184,7 @@ void RiuMainPlotWindow::createMenus()
importMenu->addAction(cmdFeatureMgr->action("RicImportEclipseCaseFeature"));
importMenu->addAction(cmdFeatureMgr->action("RicImportInputEclipseCaseFeature"));
importMenu->addAction(cmdFeatureMgr->action("RicImportSummaryCaseFeature"));
importMenu->addAction(cmdFeatureMgr->action("RicImportObservedDataInMenuFeature"));
importMenu->addAction(cmdFeatureMgr->action("RicCreateGridCaseGroupFeature"));
importMenu->addSeparator();
#ifdef USE_ODB_API

View File

@@ -59,6 +59,7 @@
#include "cafUtils.h"
#include "ExportCommands/RicSnapshotAllViewsToFileFeature.h"
#include "SummaryPlotCommands/RicEditSummaryCurves.h"
#include "cvfTimer.h"
@@ -183,6 +184,12 @@ void RiuMainWindow::cleanupGuiCaseClose()
}
}
m_processMonitor->startMonitorWorkProcess(NULL);
RicEditSummaryCurves* editSumCurves = dynamic_cast<RicEditSummaryCurves*>(caf::CmdFeatureManager::instance()->getCommandFeature("RicEditSummaryCurves"));
if (editSumCurves)
{
editSumCurves->closeDialogAndResetTargetPlot();
}
}
//--------------------------------------------------------------------------------------------------

View File

@@ -85,6 +85,14 @@ namespace caf
/// for (size_t i = 0; i < caf::AppEnum<SomeClass::SomeEnumType>::size(); ++i)
/// cout << caf::AppEnum<SomeClass::SomeEnumType>::text(caf::AppEnum<SomeClass::SomeEnumType>::fromIndex(i)) << endl;
///
///
///
/// Create a list of OptionItemInfos from AppEnum
/// QList<caf::PdmOptionItemInfo> options;
/// for (size_t i = 0; i < caf::AppEnum<TestEnumType>::size(); ++i)
/// {
/// options.push_back(caf::PdmOptionItemInfo(caf::AppEnum<TestEnumType>::uiTextFromIndex(i), caf::AppEnum<TestEnumType>::fromIndex(i)));
/// }
//==================================================================================================
template <class T>
@@ -319,15 +327,19 @@ bool operator != ( T value, const caf::AppEnum<T>& appEnum)
//==================================================================================================
template < typename T >
void operator >> (QTextStream& str, caf::AppEnum<T>& appEnum)
QTextStream& operator >> (QTextStream& str, caf::AppEnum<T>& appEnum)
{
QString text;
str >> text;
appEnum.setFromText(text);
return str;
}
template < typename T >
void operator << (QTextStream& str, const caf::AppEnum<T>& appEnum)
QTextStream& operator << (QTextStream& str, const caf::AppEnum<T>& appEnum)
{
str << appEnum.text();
return str;
}

View File

@@ -134,17 +134,21 @@ void caf::Tristate::setFromText(const QString& valueText)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void operator >> (QTextStream& str, caf::Tristate& triplet)
QTextStream& operator >> (QTextStream& str, caf::Tristate& triplet)
{
QString text;
str >> text;
triplet.setFromText(text);
return str;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void operator << (QTextStream& str, const caf::Tristate& triplet)
QTextStream& operator << (QTextStream& str, const caf::Tristate& triplet)
{
str << triplet.text();
return str;
}

View File

@@ -46,7 +46,7 @@ protected:
//==================================================================================================
// Overload of QTextStream for caf::Triplet
//==================================================================================================
void operator >> (QTextStream& str, caf::Tristate& triplet);
void operator << (QTextStream& str, const caf::Tristate& triplet);
QTextStream& operator >> (QTextStream& str, caf::Tristate& triplet);
QTextStream& operator << (QTextStream& str, const caf::Tristate& triplet);
Q_DECLARE_METATYPE(caf::Tristate);

View File

@@ -225,6 +225,11 @@ public:
m_proxyEnumMember = T2;
m_testEnumField.capability<caf::PdmUiFieldHandle>()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&m_multipleAppEnum, "MultipleAppEnumValue", "MultipleAppEnumValue", "", "", "");
m_multipleAppEnum.capability<caf::PdmUiFieldHandle>()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&m_highlightedEnum, "HighlightedEnum", "HighlightedEnum", "", "", "");
m_highlightedEnum.uiCapability()->setUiHidden(true);
}
caf::PdmField<double> m_doubleField;
@@ -239,6 +244,9 @@ public:
TestEnumType m_proxyEnumMember;
// vector of app enum
caf::PdmField< std::vector< caf::AppEnum<TestEnumType> > > m_multipleAppEnum;
caf::PdmField< caf::AppEnum<TestEnumType> > m_highlightedEnum;
caf::PdmField<bool> m_toggleField;
virtual caf::PdmFieldHandle* objectToggleField()
@@ -252,13 +260,16 @@ public:
{
std::cout << "Toggle Field changed" << std::endl;
}
else if (changedField == &m_highlightedEnum)
{
std::cout << "Highlight value " << m_highlightedEnum() << std::endl;
}
}
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
{
QList<caf::PdmOptionItemInfo> options;
if (&m_ptrField == fieldNeedingOptions)
{
caf::PdmFieldHandle* field;
@@ -287,6 +298,13 @@ public:
}
}
}
else if (&m_multipleAppEnum == fieldNeedingOptions)
{
for (size_t i = 0; i < caf::AppEnum<TestEnumType>::size(); ++i)
{
options.push_back(caf::PdmOptionItemInfo(caf::AppEnum<TestEnumType>::uiTextFromIndex(i), caf::AppEnum<TestEnumType>::fromIndex(i)));
}
}
if (useOptionsOnly) *useOptionsOnly = true;
@@ -301,6 +319,22 @@ public:
return &m_textField;
}
protected:
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override
{
if (field == &m_multipleAppEnum)
{
caf::PdmUiTreeSelectionEditorAttribute* attr = dynamic_cast<caf::PdmUiTreeSelectionEditorAttribute*>(attribute);
if (attr)
{
attr->fieldToReceiveCurrentFieldValue = &m_highlightedEnum;
}
}
}
};
CAF_PDM_SOURCE_INIT(SmallDemoPdmObjectA, "SmallDemoPdmObjectA");

View File

@@ -121,6 +121,10 @@ QList<caf::PdmOptionItemInfo> ManyGroups::calculateValueOptions(const caf::PdmFi
//--------------------------------------------------------------------------------------------------
void ManyGroups::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
uiOrdering.add(&m_toggleField);
uiOrdering.add(&m_multiSelectList);
/*
{
caf::PdmUiGroup* group = uiOrdering.addNewGroup("First");
@@ -156,4 +160,21 @@ void ManyGroups::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOr
subGroup->add(&m_proxyDoubleField);
}
*/
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ManyGroups::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
{
if (field == &m_multiSelectList)
{
caf::PdmUiTreeSelectionEditorAttribute* myAttr = dynamic_cast<caf::PdmUiTreeSelectionEditorAttribute*>(attribute);
if (myAttr)
{
//myAttr->showTextFilter = false;
//myAttr->showToggleAllCheckbox = false;
}
}
}

View File

@@ -40,5 +40,8 @@ protected:
///
//--------------------------------------------------------------------------------------------------
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override;
};

View File

@@ -38,10 +38,15 @@
#include "cafAssert.h"
#include "cafPdmObject.h"
#include "cafPdmUiCommandSystemProxy.h"
#include "cafPdmUiTreeSelectionQModel.h"
#include <QBoxLayout>
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QSortFilterProxyModel>
#include <QTreeView>
#include <algorithm>
@@ -99,6 +104,8 @@ CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiTreeSelectionEditor);
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeSelectionEditor::PdmUiTreeSelectionEditor()
: m_model(nullptr),
m_proxyModel(nullptr)
{
}
@@ -119,44 +126,133 @@ void PdmUiTreeSelectionEditor::configureAndUpdateUi(const QString& uiConfigName)
PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName);
// Tree view
if (!m_model)
{
m_model = new caf::PdmUiTreeSelectionQModel(m_treeView);
m_proxyModel = new QSortFilterProxyModel;
m_proxyModel->setSourceModel(m_model);
m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
m_treeView->setModel(m_proxyModel);
connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)),
this, SLOT(slotCurrentChanged(QModelIndex, QModelIndex)));
}
bool optionsOnly = true;
QList<PdmOptionItemInfo> options = field()->valueOptions(&optionsOnly);
if (!m_treeView->model())
{
caf::PdmUiTreeSelectionQModel* model = new caf::PdmUiTreeSelectionQModel(m_treeView);
m_treeView->setModel(model);
connect(model, SIGNAL(signalSelectionStateForIndexHasChanged(int, bool)), this, SLOT(slotSetSelectionStateForIndex(int, bool)));
}
caf::PdmUiTreeSelectionQModel* treeSelectionQModel = dynamic_cast<caf::PdmUiTreeSelectionQModel*>(m_treeView->model());
if (treeSelectionQModel)
{
bool itemCountHasChaged = false;
if (treeSelectionQModel->optionItemCount() != options.size()) itemCountHasChaged = true;
if (m_model->optionItemCount() != options.size()) itemCountHasChaged = true;
// TODO: If the count is different between incoming and current list of items,
// use cafQTreeViewStateSerializer to restore collapsed state
treeSelectionQModel->setOptions(this, options);
m_model->setOptions(this, options);
if (itemCountHasChaged)
{
m_treeView->expandAll();
}
QVariant fieldValue = field()->uiValue();
if (PdmUiTreeSelectionQModel::isSingleValueField(fieldValue))
{
m_textFilterLineEdit->hide();
m_toggleAllCheckBox->hide();
}
else if (PdmUiTreeSelectionQModel::isMultipleValueField(fieldValue))
{
m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_treeView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint)));
caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject());
if (uiObject)
{
uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes);
}
if (!m_attributes.showTextFilter)
{
m_textFilterLineEdit->hide();
}
if (!m_attributes.showToggleAllCheckbox)
{
m_toggleAllCheckBox->hide();
}
else
{
if (options.size() == 0)
{
m_toggleAllCheckBox->setChecked(false);
}
else
{
bool allItemsChecked = true;
QModelIndexList indices = allVisibleSourceModelIndices();
for (auto mi : indices)
{
if (m_model->data(mi, Qt::CheckStateRole).toBool() == false)
{
allItemsChecked = false;
}
}
m_toggleAllCheckBox->setChecked(allItemsChecked);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::slotSetSelectionStateForIndex(int index, bool setSelected)
QWidget* PdmUiTreeSelectionEditor::createEditorWidget(QWidget* parent)
{
std::vector<int> indices;
indices.push_back(index);
QFrame* frame = new QFrame(parent);
QVBoxLayout* layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
frame->setLayout(layout);
setSelectionStateForIndices(indices, setSelected);
{
QHBoxLayout* headerLayout = new QHBoxLayout;
headerLayout->setContentsMargins(0, 0, 0, 0);
layout->addLayout(headerLayout);
PdmUiTreeSelectionEditorAttribute attrib;
m_toggleAllCheckBox = new QCheckBox();
headerLayout->addWidget(m_toggleAllCheckBox);
connect(m_toggleAllCheckBox, SIGNAL(clicked(bool)), this, SLOT(slotToggleAll()));
m_textFilterLineEdit = new QLineEdit();
headerLayout->addWidget(m_textFilterLineEdit);
connect(m_textFilterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotTextFilterChanged()));
}
QTreeViewHeightHint* treeViewHeightHint = new QTreeViewHeightHint(parent);
treeViewHeightHint->setHeightHint(2000);
treeViewHeightHint->setHeaderHidden(true);
m_treeView = treeViewHeightHint;
layout->addWidget(treeViewHeightHint);
return frame;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* PdmUiTreeSelectionEditor::createLabelWidget(QWidget * parent)
{
m_label = new QLabel(parent);
return m_label;
}
//--------------------------------------------------------------------------------------------------
@@ -166,9 +262,35 @@ void PdmUiTreeSelectionEditor::customMenuRequested(const QPoint& pos)
{
QMenu menu;
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
bool onlyHeadersInSelection = true;
for (auto mi : selectedIndexes)
{
std::vector<int> items = selectedCheckableItems();
if (items.size() > 0)
QVariant v = m_proxyModel->data(mi, PdmUiTreeSelectionQModel::headingRole());
if (v.toBool() == false)
{
onlyHeadersInSelection = false;
}
}
if (onlyHeadersInSelection)
{
{
QAction* act = new QAction("Sub Items On", this);
connect(act, SIGNAL(triggered()), SLOT(slotSetSubItemsOn()));
menu.addAction(act);
}
{
QAction* act = new QAction("Sub Items Off", this);
connect(act, SIGNAL(triggered()), SLOT(slotSetSubItemsOff()));
menu.addAction(act);
}
}
else if (selectedIndexes.size() > 0)
{
{
QAction* act = new QAction("Set Selected On", this);
@@ -184,27 +306,6 @@ void PdmUiTreeSelectionEditor::customMenuRequested(const QPoint& pos)
menu.addAction(act);
}
}
}
{
std::vector<int> items = selectedHeaderItems();
if (items.size() > 0)
{
{
QAction* act = new QAction("Set Sub Items On", this);
connect(act, SIGNAL(triggered()), SLOT(slotSetSubItemsOn()));
menu.addAction(act);
}
{
QAction* act = new QAction("Set Sub Items Off", this);
connect(act, SIGNAL(triggered()), SLOT(slotSetSubItemsOff()));
menu.addAction(act);
}
}
}
if (menu.actions().size() > 0)
{
@@ -220,10 +321,12 @@ void PdmUiTreeSelectionEditor::customMenuRequested(const QPoint& pos)
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::slotSetSelectedOn()
{
std::vector<int> items = selectedCheckableItems();
if (items.size() > 0)
if (!m_proxyModel) return;
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
for (auto mi : selectedIndexes)
{
setSelectionStateForIndices(items, true);
m_proxyModel->setData(mi, true, Qt::CheckStateRole);
}
}
@@ -232,10 +335,12 @@ void PdmUiTreeSelectionEditor::slotSetSelectedOn()
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::slotSetSelectedOff()
{
std::vector<int> items = selectedCheckableItems();
if (items.size() > 0)
if (!m_proxyModel) return;
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
for (auto mi : selectedIndexes)
{
setSelectionStateForIndices(items, false);
m_proxyModel->setData(mi, false, Qt::CheckStateRole);
}
}
@@ -244,14 +349,14 @@ void PdmUiTreeSelectionEditor::slotSetSelectedOff()
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::slotSetSubItemsOn()
{
caf::PdmUiTreeSelectionQModel* treeSelectionQModel = dynamic_cast<caf::PdmUiTreeSelectionQModel*>(m_treeView->model());
std::vector<int> items = selectedHeaderItems();
for (auto i : items)
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
for (auto mi : selectedIndexes)
{
std::vector<int> children = treeSelectionQModel->allSubItemIndices(i);
setSelectionStateForIndices(children, true);
for (int i = 0; i < m_proxyModel->rowCount(mi); i++)
{
QModelIndex childIndex = m_proxyModel->index(i, 0, mi);
m_proxyModel->setData(childIndex, true, Qt::CheckStateRole);
}
}
}
@@ -260,145 +365,115 @@ void PdmUiTreeSelectionEditor::slotSetSubItemsOn()
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::slotSetSubItemsOff()
{
caf::PdmUiTreeSelectionQModel* treeSelectionQModel = dynamic_cast<caf::PdmUiTreeSelectionQModel*>(m_treeView->model());
std::vector<int> items = selectedHeaderItems();
for (auto i : items)
{
std::vector<int> children = treeSelectionQModel->allSubItemIndices(i);
setSelectionStateForIndices(children, false);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<int> PdmUiTreeSelectionEditor::selectedCheckableItems() const
{
std::vector<int> items;
caf::PdmUiTreeSelectionQModel* treeSelectionQModel = dynamic_cast<caf::PdmUiTreeSelectionQModel*>(m_treeView->model());
if (treeSelectionQModel)
{
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
for (auto mi : selectedIndexes)
{
auto optionItem = treeSelectionQModel->optionItem(mi);
if (!optionItem->isHeading())
for (int i = 0; i < m_proxyModel->rowCount(mi); i++)
{
items.push_back(treeSelectionQModel->optionItemIndex(mi));
QModelIndex childIndex = m_proxyModel->index(i, 0, mi);
m_proxyModel->setData(childIndex, false, Qt::CheckStateRole);
}
}
}
return items;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<int> PdmUiTreeSelectionEditor::selectedHeaderItems() const
void PdmUiTreeSelectionEditor::slotToggleAll()
{
std::vector<int> items;
caf::PdmUiTreeSelectionQModel* treeSelectionQModel = dynamic_cast<caf::PdmUiTreeSelectionQModel*>(m_treeView->model());
if (treeSelectionQModel)
if (m_toggleAllCheckBox->isChecked())
{
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
for (auto mi : selectedIndexes)
{
auto optionItem = treeSelectionQModel->optionItem(mi);
if (optionItem->isHeading())
{
items.push_back(treeSelectionQModel->optionItemIndex(mi));
}
}
}
return items;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::setSelectionStateForIndices(const std::vector<int>& indices, bool setSelected)
{
std::vector<unsigned int> selectedIndices;
{
QVariant fieldValue = field()->uiValue();
QList<QVariant> fieldValueSelection = fieldValue.toList();
for (auto v : fieldValueSelection)
{
selectedIndices.push_back(v.toUInt());
}
}
for (auto index : indices)
{
unsigned int unsignedIndex = static_cast<unsigned int>(index);
if (setSelected)
{
bool isIndexPresent = false;
for (auto indexInField : selectedIndices)
{
if (indexInField == unsignedIndex)
{
isIndexPresent = true;
}
}
if (!isIndexPresent)
{
selectedIndices.push_back(unsignedIndex);
}
checkAllItems();
}
else
{
selectedIndices.erase(std::remove(selectedIndices.begin(), selectedIndices.end(), unsignedIndex), selectedIndices.end());
}
unCheckAllItems();
}
}
QList<QVariant> fieldValueSelection;
for (auto v : selectedIndices)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::slotTextFilterChanged()
{
QString searchString = m_textFilterLineEdit->text();
searchString += "*";
m_proxyModel->setFilterWildcard(searchString);
updateUi();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::slotCurrentChanged(const QModelIndex& current, const QModelIndex& previous)
{
if (m_attributes.fieldToReceiveCurrentItemValue)
{
fieldValueSelection.push_back(QVariant(v));
PdmUiFieldHandle* uiFieldHandle = m_attributes.fieldToReceiveCurrentItemValue->uiCapability();
if (uiFieldHandle)
{
QVariant v = m_proxyModel->data(current, PdmUiTreeSelectionQModel::optionItemValueRole());
PdmUiCommandSystemProxy::instance()->setUiValueToField(uiFieldHandle, v);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::checkAllItems()
{
QModelIndexList indices = allVisibleSourceModelIndices();
m_model->setCheckedStateForItems(indices, true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::unCheckAllItems()
{
QModelIndexList indices = allVisibleSourceModelIndices();
m_model->setCheckedStateForItems(indices, false);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndexList PdmUiTreeSelectionEditor::allVisibleSourceModelIndices() const
{
QModelIndexList indices;
recursiveAppendVisibleSourceModelIndices(QModelIndex(), &indices);
return indices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeSelectionEditor::recursiveAppendVisibleSourceModelIndices(const QModelIndex& parent, QModelIndexList* sourceModelIndices) const
{
for (int row = 0; row < m_proxyModel->rowCount(parent); row++)
{
QModelIndex mi = m_proxyModel->index(row, 0, parent);
if (mi.isValid())
{
QVariant v = m_proxyModel->data(mi, PdmUiTreeSelectionQModel::headingRole());
if (v.toBool() == false)
{
sourceModelIndices->push_back(m_proxyModel->mapToSource(mi));
}
this->setValueToField(fieldValueSelection);
recursiveAppendVisibleSourceModelIndices(mi, sourceModelIndices);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* PdmUiTreeSelectionEditor::createEditorWidget(QWidget * parent)
{
QTreeViewHeightHint* treeViewHeightHint = new QTreeViewHeightHint(parent);
treeViewHeightHint->setHeightHint(2000);
treeViewHeightHint->setHeaderHidden(true);
treeViewHeightHint->setSelectionMode(QAbstractItemView::ExtendedSelection);
treeViewHeightHint->setContextMenuPolicy(Qt::CustomContextMenu);
connect(treeViewHeightHint, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint)));
m_treeView = treeViewHeightHint;
return treeViewHeightHint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* PdmUiTreeSelectionEditor::createLabelWidget(QWidget * parent)
{
m_label = new QLabel(parent);
return m_label;
}
} // end namespace caf

View File

@@ -38,12 +38,45 @@
#include "cafPdmUiFieldEditorHandle.h"
#include <QAbstractItemModel>
class QLabel;
class QTreeView;
class QAbstractItemModel;
class QCheckBox;
class QLineEdit;
class QSortFilterProxyModel;
class QModelIndex;
class QItemSelection;
namespace caf
{
class PdmUiTreeSelectionQModel;
//==================================================================================================
///
//==================================================================================================
class PdmUiTreeSelectionEditorAttribute : public PdmUiEditorAttribute
{
public:
bool showTextFilter;
bool showToggleAllCheckbox;
/// fieldToReceiveCurrentFieldValue is used to communicate the value of current item in the tree view
/// This is useful when displaying a list of appEnums, and a dependent view is displaying content based on
/// the current item in the tree view
/// Make sure the type of the receiving field is of the same type as the field used in PdmUiTreeSelectionEditor
caf::PdmFieldHandle* fieldToReceiveCurrentItemValue;
public:
PdmUiTreeSelectionEditorAttribute()
{
showTextFilter = true;
showToggleAllCheckbox = true;
fieldToReceiveCurrentItemValue = nullptr;
}
};
//==================================================================================================
///
@@ -58,12 +91,11 @@ public:
virtual ~PdmUiTreeSelectionEditor();
protected:
virtual QWidget* createEditorWidget(QWidget * parent);
virtual QWidget* createLabelWidget(QWidget * parent);
virtual void configureAndUpdateUi(const QString& uiConfigName);
virtual QWidget* createEditorWidget(QWidget* parent);
virtual QWidget* createLabelWidget(QWidget* parent);
private slots:
void slotSetSelectionStateForIndex(int index, bool setSelected);
void customMenuRequested(const QPoint& pos);
void slotSetSelectedOn();
@@ -71,14 +103,30 @@ private slots:
void slotSetSubItemsOn();
void slotSetSubItemsOff();
void slotToggleAll();
void slotTextFilterChanged();
void slotCurrentChanged(const QModelIndex& current, const QModelIndex& previous);
private:
std::vector<int> selectedCheckableItems() const;
std::vector<int> selectedHeaderItems() const;
void setSelectionStateForIndices(const std::vector<int>& indices, bool setSelected);
void checkAllItems();
void unCheckAllItems();
QModelIndexList allVisibleSourceModelIndices() const;
void recursiveAppendVisibleSourceModelIndices(const QModelIndex& parent,
QModelIndexList* sourceModelIndices) const;
private:
QPointer<QTreeView> m_treeView;
QPointer<QLabel> m_label;
QPointer<QCheckBox> m_toggleAllCheckBox;
QPointer<QLineEdit> m_textFilterLineEdit;
PdmUiTreeSelectionQModel* m_model;
QSortFilterProxyModel* m_proxyModel;
PdmUiTreeSelectionEditorAttribute m_attributes;
};
} // end namespace caf

View File

@@ -36,13 +36,16 @@
#include "cafPdmUiTreeSelectionQModel.h"
#include "cafPdmUiTreeViewModel.h"
#include "cafPdmObject.h"
#include "cafPdmUiCommandSystemProxy.h"
#include "cafPdmUiTreeViewModel.h"
#include <QAbstractItemModel>
#include <QLabel>
#include <QTreeView>
#include <algorithm>
//--------------------------------------------------------------------------------------------------
///
@@ -50,29 +53,78 @@
caf::PdmUiTreeSelectionQModel::PdmUiTreeSelectionQModel(QObject *parent /*= 0*/) : QAbstractItemModel(parent)
{
m_uiFieldHandle = nullptr;
m_zeroLevelRowCount = 0;
m_tree = nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::PdmUiTreeSelectionQModel::setOptions(caf::PdmUiFieldEditorHandle* field, const QList<caf::PdmOptionItemInfo>& options)
caf::PdmUiTreeSelectionQModel::~PdmUiTreeSelectionQModel()
{
bool itemCountHasChanged = false;
if (optionItemCount() != options.size())
m_uiFieldHandle = nullptr;
delete m_tree;
m_tree = nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int caf::PdmUiTreeSelectionQModel::headingRole()
{
return Qt::UserRole + 1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int caf::PdmUiTreeSelectionQModel::optionItemValueRole()
{
return Qt::UserRole + 2;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::PdmUiTreeSelectionQModel::setCheckedStateForItems(const QModelIndexList& sourceModelIndices, bool checked)
{
if (!m_uiFieldHandle || !m_uiFieldHandle->field()) return;
std::set<unsigned int> selectedIndices;
{
itemCountHasChanged = true;
QVariant fieldValue = m_uiFieldHandle->field()->uiValue();
QList<QVariant> fieldValueSelection = fieldValue.toList();
for (auto v : fieldValueSelection)
{
selectedIndices.insert(v.toUInt());
}
}
m_uiFieldHandle = field;
m_options = options;
computeOptionItemTreeData();
if (itemCountHasChanged)
if (checked)
{
reset();
for (auto mi : sourceModelIndices)
{
selectedIndices.insert(static_cast<unsigned int>(optionIndex(mi)));
}
}
else
{
for (auto mi : sourceModelIndices)
{
selectedIndices.erase(static_cast<unsigned int>(optionIndex(mi)));
}
}
QList<QVariant> fieldValueSelection;
for (auto v : selectedIndices)
{
fieldValueSelection.push_back(QVariant(v));
}
beginResetModel();
PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->field(), fieldValueSelection);
endResetModel();
}
//--------------------------------------------------------------------------------------------------
@@ -86,16 +138,51 @@ int caf::PdmUiTreeSelectionQModel::optionItemCount() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::PdmOptionItemInfo* caf::PdmUiTreeSelectionQModel::optionItem(const QModelIndex &index) const
void caf::PdmUiTreeSelectionQModel::setOptions(caf::PdmUiFieldEditorHandle* field, const QList<caf::PdmOptionItemInfo>& options)
{
if (index.isValid())
{
int opIndex = optionItemIndex(index);
m_uiFieldHandle = field;
return &(m_options[opIndex]);
if (m_options.size() != options.size())
{
beginResetModel();
m_options = options;
if (m_tree)
{
delete m_tree;
m_tree = nullptr;
}
return nullptr;
m_tree = new TreeItemType(nullptr, -1, 0);
buildOptionItemTree(0, m_tree);
endResetModel();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::PdmOptionItemInfo* caf::PdmUiTreeSelectionQModel::optionItem(const QModelIndex &index) const
{
int opIndex = optionIndex(index);
return &m_options[opIndex];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int caf::PdmUiTreeSelectionQModel::optionIndex(const QModelIndex &index) const
{
CAF_ASSERT(index.isValid());
TreeItemType* item = static_cast<TreeItemType*>(index.internalPointer());
int optionIndex = item->dataObject();
return optionIndex;
}
//--------------------------------------------------------------------------------------------------
@@ -105,13 +192,13 @@ Qt::ItemFlags caf::PdmUiTreeSelectionQModel::flags(const QModelIndex &index) con
{
if (index.isValid())
{
int opIndex = optionItemIndex(index);
const caf::PdmOptionItemInfo* optionItemInfo = optionItem(index);
if (m_options[opIndex].isReadOnly())
if (optionItemInfo->isReadOnly())
{
return QAbstractItemModel::flags(index)^Qt::ItemIsEnabled;
}
else if (!m_options[opIndex].isHeading())
else if (!optionItemInfo->isHeading())
{
return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
}
@@ -128,23 +215,18 @@ QModelIndex caf::PdmUiTreeSelectionQModel::index(int row, int column, const QMod
if (!hasIndex(row, column, parent))
return QModelIndex();
if (m_zeroLevelRowToOptionIndex.size() == 0)
return QModelIndex();
TreeItemType* parentItem;
int opIndex = -1;
if (parent.isValid())
{
opIndex = optionItemIndex(parent) + row + 1;
}
if (!parent.isValid())
parentItem = m_tree;
else
{
opIndex = m_zeroLevelRowToOptionIndex.at(row);
}
parentItem = static_cast<TreeItemType*>(parent.internalPointer());
CAF_ASSERT(opIndex > -1);
CAF_ASSERT(opIndex < m_options.size());
return createIndex(row, column, opIndex);
TreeItemType* childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
//--------------------------------------------------------------------------------------------------
@@ -158,12 +240,18 @@ int caf::PdmUiTreeSelectionQModel::columnCount(const QModelIndex &parent /*= QMo
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndex caf::PdmUiTreeSelectionQModel::parent(const QModelIndex &child) const
QModelIndex caf::PdmUiTreeSelectionQModel::parent(const QModelIndex &index) const
{
if (!child.isValid())
if (!index.isValid())
return QModelIndex();
return m_optionsTreeData[optionItemIndex(child)].parentModelIndex;
TreeItemType* childItem = static_cast<TreeItemType*>(index.internalPointer());
TreeItemType* parentItem = childItem->parent();
if (parentItem == m_tree)
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
//--------------------------------------------------------------------------------------------------
@@ -171,12 +259,18 @@ QModelIndex caf::PdmUiTreeSelectionQModel::parent(const QModelIndex &child) cons
//--------------------------------------------------------------------------------------------------
int caf::PdmUiTreeSelectionQModel::rowCount(const QModelIndex &parent /*= QModelIndex()*/) const
{
if (!parent.isValid())
{
return m_zeroLevelRowCount;
}
if (!m_tree) return 0;
return m_optionsTreeData[optionItemIndex(parent)].childCount;
if (parent.column() > 0)
return 0;
TreeItemType* parentItem;
if (!parent.isValid())
parentItem = m_tree;
else
parentItem = static_cast<TreeItemType*>(parent.internalPointer());
return parentItem->childCount();
}
//--------------------------------------------------------------------------------------------------
@@ -186,27 +280,36 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role
{
if (index.isValid())
{
CAF_ASSERT(index.internalId() < m_options.size());
int opIndex = optionItemIndex(index);
const caf::PdmOptionItemInfo* optionItemInfo = optionItem(index);
if (role == Qt::DisplayRole)
{
return m_options[opIndex].optionUiText();
return optionItemInfo->optionUiText();
}
else if (role == Qt::DecorationRole)
{
return m_options[opIndex].icon();
return optionItemInfo->icon();
}
else if (role == Qt::CheckStateRole && !m_options[opIndex].isHeading())
else if (role == Qt::CheckStateRole && !optionItemInfo->isHeading())
{
CAF_ASSERT(m_uiFieldHandle);
if (m_uiFieldHandle && m_uiFieldHandle->field())
{
QVariant fieldValue = m_uiFieldHandle->field()->uiValue();
if (isSingleValueField(fieldValue))
{
int row = fieldValue.toInt();
if (row == optionIndex(index))
{
return Qt::Checked;
}
}
else if (isMultipleValueField(fieldValue))
{
QList<QVariant> valuesSelectedInField = fieldValue.toList();
int opIndex = optionIndex(index);
for (QVariant v : valuesSelectedInField)
{
int indexInField = v.toInt();
@@ -216,12 +319,13 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role
}
}
}
}
return Qt::Unchecked;
}
else if (role == Qt::FontRole)
{
if (m_options[opIndex].isHeading())
if (optionItemInfo->isHeading())
{
QFont font;
font.setBold(true);
@@ -229,6 +333,16 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role
return font;
}
}
else if (role == headingRole())
{
return optionItemInfo->isHeading();
}
else if (role == optionItemValueRole())
{
QVariant v = optionItemInfo->value();
return v;
}
}
return QVariant();
@@ -239,12 +353,121 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role
//--------------------------------------------------------------------------------------------------
bool caf::PdmUiTreeSelectionQModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/)
{
if (!m_uiFieldHandle || !m_uiFieldHandle->field()) return false;
if (role == Qt::CheckStateRole)
{
bool isSelected = value.toBool();
QVariant fieldValue = m_uiFieldHandle->field()->uiValue();
if (isSingleValueField(fieldValue))
{
if (value.toBool() == true)
{
// Reset model to make sure other check boxes are invalidated
beginResetModel();
emit signalSelectionStateForIndexHasChanged(optionItemIndex(index), isSelected);
QVariant v = static_cast<unsigned int>(optionIndex(index));
PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->field(), v);
endResetModel();
return true;
}
}
else if (isMultipleValueField(fieldValue))
{
std::vector<unsigned int> selectedIndices;
{
QVariant fieldValue = m_uiFieldHandle->field()->uiValue();
QList<QVariant> fieldValueSelection = fieldValue.toList();
for (auto v : fieldValueSelection)
{
selectedIndices.push_back(v.toUInt());
}
}
bool setSelected = value.toBool();
unsigned int opIndex = static_cast<unsigned int>(optionIndex(index));
if (setSelected)
{
bool isIndexPresent = false;
for (auto indexInField : selectedIndices)
{
if (indexInField == opIndex)
{
isIndexPresent = true;
}
}
if (!isIndexPresent)
{
selectedIndices.push_back(opIndex);
}
}
else
{
selectedIndices.erase(std::remove(selectedIndices.begin(), selectedIndices.end(), opIndex), selectedIndices.end());
}
QList<QVariant> fieldValueSelection;
for (auto v : selectedIndices)
{
fieldValueSelection.push_back(QVariant(v));
}
PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->field(), fieldValueSelection);
emit dataChanged(index, index);
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::PdmUiTreeSelectionQModel::buildOptionItemTree(int parentOptionIndex, TreeItemType* parentNode)
{
if (parentNode == m_tree)
{
for (int i = 0; i < m_options.size(); i++)
{
if (m_options[i].level() == 0)
{
TreeItemType* node = new TreeItemType(parentNode, -1, i);
buildOptionItemTree(i, node);
}
}
}
else
{
int currentOptionIndex = parentOptionIndex + 1;
while (currentOptionIndex < m_options.size() && m_options[currentOptionIndex].level() > m_options[parentNode->dataObject()].level())
{
if (m_options[currentOptionIndex].level() == m_options[parentNode->dataObject()].level() + 1)
{
TreeItemType* node = new TreeItemType(parentNode, -1, currentOptionIndex);
buildOptionItemTree(currentOptionIndex, node);
}
currentOptionIndex++;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool caf::PdmUiTreeSelectionQModel::isSingleValueField(const QVariant& fieldValue)
{
if (fieldValue.type() == QVariant::Int || fieldValue.type() == QVariant::UInt)
{
return true;
}
@@ -254,106 +477,13 @@ bool caf::PdmUiTreeSelectionQModel::setData(const QModelIndex &index, const QVar
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int caf::PdmUiTreeSelectionQModel::optionItemIndex(const QModelIndex& modelIndex) const
bool caf::PdmUiTreeSelectionQModel::isMultipleValueField(const QVariant& fieldValue)
{
CAF_ASSERT(modelIndex.isValid());
CAF_ASSERT(modelIndex.internalId() < m_options.size());
if (fieldValue.type() == QVariant::List)
{
return true;
}
return modelIndex.internalId();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<int> caf::PdmUiTreeSelectionQModel::allSubItemIndices(int headingIndex) const
{
std::vector<int> children;
int parentLevel = m_options[headingIndex].level();
int currentIndex = headingIndex + 1;
while (currentIndex < m_options.size() && m_options[currentIndex].level() > parentLevel)
{
children.push_back(currentIndex);
currentIndex++;
}
return children;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::PdmUiTreeSelectionQModel::computeOptionItemTreeData()
{
m_optionsTreeData.clear();
m_zeroLevelRowToOptionIndex.clear();
if (m_options.size() == 0) return;
m_optionsTreeData.resize(m_options.size());
m_zeroLevelRowCount = 0;
for (int i = 0; i < m_options.size(); i++)
{
if (m_options[i].level() == 0)
{
m_zeroLevelRowToOptionIndex[m_zeroLevelRowCount] = i;
m_zeroLevelRowCount++;
m_optionsTreeData[i].parentModelIndex = QModelIndex();
}
else if (m_options[i].level() > 0)
{
// Compute parent model index
int childLevel = m_options[i].level();
int parentOptionIndex = i - 1;
while (parentOptionIndex > -1)
{
if (m_options[parentOptionIndex].level() == childLevel - 1)
{
int parentRow = 0;
int parentLevelOptionIndex = parentOptionIndex - 1;
while (parentLevelOptionIndex > -1 && m_options[parentLevelOptionIndex].level() > childLevel - 2)
{
if (m_options[parentLevelOptionIndex].level() == childLevel - 1)
{
parentRow++;
}
parentLevelOptionIndex--;
}
m_optionsTreeData[i].parentModelIndex = createIndex(parentRow, 0, parentOptionIndex);
break;
}
parentOptionIndex--;
}
}
int childCount = 0;
{
int parentLevel = m_options[i].level();
int currentOptionIndex = i + 1;
while (currentOptionIndex < m_options.size() && m_options[currentOptionIndex].level() > parentLevel)
{
if (m_options[currentOptionIndex].level() == parentLevel + 1)
{
childCount++;
}
currentOptionIndex++;
}
}
m_optionsTreeData[i].childCount = childCount;
}
return false;
}

View File

@@ -37,6 +37,7 @@
#pragma once
#include "cafPdmUiFieldEditorHandle.h"
#include "cafUiTreeItem.h"
#include <QAbstractItemModel>
@@ -50,16 +51,6 @@ class PdmOptionItemInfo;
class PdmUiFieldHandle;
//==================================================================================================
///
//==================================================================================================
class OptionItemTreeData
{
public:
int childCount;
QModelIndex parentModelIndex;
};
//==================================================================================================
///
//==================================================================================================
@@ -68,13 +59,15 @@ class PdmUiTreeSelectionQModel : public QAbstractItemModel
Q_OBJECT
public:
explicit PdmUiTreeSelectionQModel(QObject *parent = 0);
~PdmUiTreeSelectionQModel();
void setOptions(caf::PdmUiFieldEditorHandle* field, const QList<caf::PdmOptionItemInfo>& options);
static int headingRole();
static int optionItemValueRole();
void setCheckedStateForItems(const QModelIndexList& indices, bool checked);
int optionItemCount() const;
const caf::PdmOptionItemInfo* optionItem(const QModelIndex &index) const;
int optionItemIndex(const QModelIndex& modelIndex) const;
std::vector<int> allSubItemIndices(int headingIndex) const;
void setOptions(caf::PdmUiFieldEditorHandle* field, const QList<caf::PdmOptionItemInfo>& options);
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
@@ -84,19 +77,23 @@ public:
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
signals:
void signalSelectionStateForIndexHasChanged(int index, bool isSelected);
// Consider moving these functions to PdmUiFieldHandle
static bool isSingleValueField(const QVariant& fieldValue);
static bool isMultipleValueField(const QVariant& fieldValue);
private:
void computeOptionItemTreeData();
typedef caf::UiTreeItem<int> TreeItemType;
const caf::PdmOptionItemInfo* optionItem(const QModelIndex &index) const;
int optionIndex(const QModelIndex &index) const;
void buildOptionItemTree(int optionIndex, TreeItemType* parentNode);
private:
QList<caf::PdmOptionItemInfo> m_options;
caf::PdmUiFieldEditorHandle* m_uiFieldHandle;
std::vector<OptionItemTreeData> m_optionsTreeData;
int m_zeroLevelRowCount;
std::map<int, int> m_zeroLevelRowToOptionIndex;
TreeItemType* m_tree;
};

View File

@@ -44,6 +44,9 @@ QList<caf::PdmOptionItemInfo> createOptions()
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -54,6 +57,8 @@ TEST(PdmUiTreeSelectionQModelTest, BasicUsage)
caf::PdmUiTreeSelectionQModel myModel;
myModel.setOptions(nullptr, options);
EXPECT_EQ(options.size(), myModel.optionItemCount());
EXPECT_EQ(4, myModel.rowCount(myModel.index(-1, -1)));
EXPECT_EQ(0, myModel.rowCount(myModel.index(0, 0)));
@@ -105,3 +110,24 @@ TEST(PdmUiTreeSelectionQModelTest, SetDataAndSignal)
myModel.setData(parentIndex, QVariant(true));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(PdmUiTreeSelectionQModelTest, SetCheckedStateForItems)
{
QList<caf::PdmOptionItemInfo> options = createOptions();
caf::PdmUiTreeSelectionQModel myModel;
myModel.setOptions(nullptr, options);
QModelIndex parentIndex = myModel.index(1, 0);
QModelIndex firstChildIndex = myModel.index(0, 0, parentIndex);
QModelIndexList indices;
indices << firstChildIndex;
myModel.setCheckedStateForItems(indices, false);
// No test code for this behaviour, only making sure this runs without any errors
}