mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#2018 CSV import. Select time series column. Columnify preview. Refactoring
This commit is contained in:
parent
1d2067882d
commit
11100fb6e0
@ -85,7 +85,7 @@ void RicPasteAsciiDataToSummaryPlotFeature::onActionTriggered(bool isChecked)
|
|||||||
|
|
||||||
RicPasteAsciiDataToSummaryPlotFeatureUi pasteOptions;
|
RicPasteAsciiDataToSummaryPlotFeatureUi pasteOptions;
|
||||||
if (!summaryPlot) pasteOptions.createNewPlot();
|
if (!summaryPlot) pasteOptions.createNewPlot();
|
||||||
pasteOptions.setPreviewText(text);
|
pasteOptions.setUiModePasteText(text);
|
||||||
caf::PdmSettings::readFieldsFromApplicationStore(&pasteOptions);
|
caf::PdmSettings::readFieldsFromApplicationStore(&pasteOptions);
|
||||||
|
|
||||||
caf::PdmUiPropertyViewDialog propertyDialog(NULL, &pasteOptions, "Set Paste Options", "");
|
caf::PdmUiPropertyViewDialog propertyDialog(NULL, &pasteOptions, "Set Paste Options", "");
|
||||||
|
@ -18,7 +18,10 @@
|
|||||||
|
|
||||||
#include "RicPasteAsciiDataToSummaryPlotFeatureUi.h"
|
#include "RicPasteAsciiDataToSummaryPlotFeatureUi.h"
|
||||||
|
|
||||||
|
#include "RifCsvUserDataParser.h"
|
||||||
|
|
||||||
#include "cafPdmUiTextEditor.h"
|
#include "cafPdmUiTextEditor.h"
|
||||||
|
#include "cafPdmUiItem.h"
|
||||||
|
|
||||||
namespace caf {
|
namespace caf {
|
||||||
|
|
||||||
@ -60,6 +63,23 @@ namespace caf {
|
|||||||
|
|
||||||
CAF_PDM_SOURCE_INIT(RicPasteAsciiDataToSummaryPlotFeatureUi, "RicPasteAsciiDataToSummaryPlotFeatureUi");
|
CAF_PDM_SOURCE_INIT(RicPasteAsciiDataToSummaryPlotFeatureUi, "RicPasteAsciiDataToSummaryPlotFeatureUi");
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RicPasteAsciiDataToSummaryPlotFeatureUi::CellSeparator mapCellSeparator(const QString& sep)
|
||||||
|
{
|
||||||
|
if (sep == "\t") return RicPasteAsciiDataToSummaryPlotFeatureUi::CELL_TAB;
|
||||||
|
if (sep == ";") return RicPasteAsciiDataToSummaryPlotFeatureUi::CELL_SEMICOLON;
|
||||||
|
if (sep == ",") return RicPasteAsciiDataToSummaryPlotFeatureUi::CELL_COMMA;
|
||||||
|
|
||||||
|
return RicPasteAsciiDataToSummaryPlotFeatureUi::CELL_TAB;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
@ -84,12 +104,38 @@ RicPasteAsciiDataToSummaryPlotFeatureUi::RicPasteAsciiDataToSummaryPlotFeatureUi
|
|||||||
|
|
||||||
CAF_PDM_InitFieldNoDefault(&m_cellSeparator, "CellSeparator", "Cell Separator", "", "", "");
|
CAF_PDM_InitFieldNoDefault(&m_cellSeparator, "CellSeparator", "Cell Separator", "", "", "");
|
||||||
|
|
||||||
|
CAF_PDM_InitFieldNoDefault(&m_timeSeriesColumnName, "TimeSeriesColumn", "Time Series Column", "", "", "");
|
||||||
|
|
||||||
CAF_PDM_InitFieldNoDefault(&m_previewText, "PreviewText", "Preview Text", "", "", "");
|
CAF_PDM_InitFieldNoDefault(&m_previewText, "PreviewText", "Preview Text", "", "", "");
|
||||||
m_previewText.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName());
|
m_previewText.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName());
|
||||||
m_previewText.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
m_previewText.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||||
m_previewText.uiCapability()->setUiReadOnly(true);
|
m_previewText.uiCapability()->setUiReadOnly(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RicPasteAsciiDataToSummaryPlotFeatureUi::setUiModeImport(const QString& fileName)
|
||||||
|
{
|
||||||
|
m_uiMode = UI_MODE_IMPORT;
|
||||||
|
m_fileName = fileName;
|
||||||
|
|
||||||
|
RifCsvUserDataFileParser parser(fileName);
|
||||||
|
m_previewText = parser.previewText();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RicPasteAsciiDataToSummaryPlotFeatureUi::setUiModePasteText(const QString& text)
|
||||||
|
{
|
||||||
|
m_uiMode = UI_MODE_PASTE;
|
||||||
|
m_pastedText = text;
|
||||||
|
|
||||||
|
RifCsvUserDataPastedTextParser parser(text);
|
||||||
|
m_previewText = parser.previewText();
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -131,6 +177,8 @@ const AsciiDataParseOptions RicPasteAsciiDataToSummaryPlotFeatureUi::parseOption
|
|||||||
parseOptions.dateFormat = dateFormat;
|
parseOptions.dateFormat = dateFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseOptions.timeSeriesColumnName = m_timeSeriesColumnName();
|
||||||
|
|
||||||
parseOptions.timeFormat = m_timeFormat() != TIME_NONE ? m_timeFormat().text() : QString("");
|
parseOptions.timeFormat = m_timeFormat() != TIME_NONE ? m_timeFormat().text() : QString("");
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -168,19 +216,12 @@ void RicPasteAsciiDataToSummaryPlotFeatureUi::createNewPlot()
|
|||||||
m_createNewPlot = true;
|
m_createNewPlot = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
void RicPasteAsciiDataToSummaryPlotFeatureUi::setPreviewText(const QString& previewText)
|
|
||||||
{
|
|
||||||
m_previewText = previewText;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicPasteAsciiDataToSummaryPlotFeatureUi::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
void RicPasteAsciiDataToSummaryPlotFeatureUi::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||||
{
|
{
|
||||||
|
if(m_uiMode == UI_MODE_PASTE)
|
||||||
{
|
{
|
||||||
caf::PdmUiGroup* namingGroup = uiOrdering.addNewGroup("Naming");
|
caf::PdmUiGroup* namingGroup = uiOrdering.addNewGroup("Naming");
|
||||||
if (m_createNewPlot)
|
if (m_createNewPlot)
|
||||||
@ -197,6 +238,8 @@ void RicPasteAsciiDataToSummaryPlotFeatureUi::defineUiOrdering(QString uiConfigN
|
|||||||
|
|
||||||
{
|
{
|
||||||
caf::PdmUiGroup* dateGroup = uiOrdering.addNewGroup("Dates");
|
caf::PdmUiGroup* dateGroup = uiOrdering.addNewGroup("Dates");
|
||||||
|
dateGroup->add(&m_timeSeriesColumnName);
|
||||||
|
|
||||||
dateGroup->add(&m_useCustomDateFormat);
|
dateGroup->add(&m_useCustomDateFormat);
|
||||||
if (m_useCustomDateFormat())
|
if (m_useCustomDateFormat())
|
||||||
{
|
{
|
||||||
@ -215,6 +258,7 @@ void RicPasteAsciiDataToSummaryPlotFeatureUi::defineUiOrdering(QString uiConfigN
|
|||||||
cellGroup->add(&m_cellSeparator);
|
cellGroup->add(&m_cellSeparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_uiMode == UI_MODE_PASTE)
|
||||||
{
|
{
|
||||||
caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup("Appearance");
|
caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup("Appearance");
|
||||||
|
|
||||||
@ -232,6 +276,53 @@ void RicPasteAsciiDataToSummaryPlotFeatureUi::defineUiOrdering(QString uiConfigN
|
|||||||
uiOrdering.skipRemainingFields();
|
uiOrdering.skipRemainingFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QList<caf::PdmOptionItemInfo> RicPasteAsciiDataToSummaryPlotFeatureUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||||
|
bool* useOptionsOnly)
|
||||||
|
{
|
||||||
|
QList<caf::PdmOptionItemInfo> options;
|
||||||
|
|
||||||
|
if (fieldNeedingOptions == &m_timeSeriesColumnName)
|
||||||
|
{
|
||||||
|
QString cellSep;
|
||||||
|
RifCsvUserDataParser* parser;
|
||||||
|
|
||||||
|
if (m_uiMode == UI_MODE_IMPORT)
|
||||||
|
{
|
||||||
|
parser = new RifCsvUserDataFileParser(m_fileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parser = new RifCsvUserDataPastedTextParser(m_pastedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
cellSep = parser->tryDetermineCellSeparator();
|
||||||
|
if (!cellSep.isEmpty())
|
||||||
|
{
|
||||||
|
m_cellSeparator = mapCellSeparator(cellSep);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<QString> columnNames;
|
||||||
|
if (parser->parseColumnNames(parseOptions().cellSeparator, &columnNames))
|
||||||
|
{
|
||||||
|
for (const QString& columnName : columnNames)
|
||||||
|
{
|
||||||
|
options.push_back(caf::PdmOptionItemInfo(columnName, columnName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnNames.size() > 0)
|
||||||
|
{
|
||||||
|
m_timeSeriesColumnName = columnNames.front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete parser;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -39,6 +39,7 @@ public:
|
|||||||
QString dateFormat;
|
QString dateFormat;
|
||||||
QString timeFormat;
|
QString timeFormat;
|
||||||
QString cellSeparator;
|
QString cellSeparator;
|
||||||
|
QString timeSeriesColumnName;
|
||||||
|
|
||||||
RimPlotCurve::LineStyleEnum curveLineStyle;
|
RimPlotCurve::LineStyleEnum curveLineStyle;
|
||||||
RimPlotCurve::PointSymbolEnum curveSymbol;
|
RimPlotCurve::PointSymbolEnum curveSymbol;
|
||||||
@ -56,6 +57,12 @@ class RicPasteAsciiDataToSummaryPlotFeatureUi : public caf::PdmObject
|
|||||||
CAF_PDM_HEADER_INIT;
|
CAF_PDM_HEADER_INIT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum UiMode
|
||||||
|
{
|
||||||
|
UI_MODE_IMPORT,
|
||||||
|
UI_MODE_PASTE
|
||||||
|
};
|
||||||
|
|
||||||
enum DecimalSeparator
|
enum DecimalSeparator
|
||||||
{
|
{
|
||||||
DECIMAL_COMMA,
|
DECIMAL_COMMA,
|
||||||
@ -93,15 +100,20 @@ public:
|
|||||||
public:
|
public:
|
||||||
RicPasteAsciiDataToSummaryPlotFeatureUi();
|
RicPasteAsciiDataToSummaryPlotFeatureUi();
|
||||||
|
|
||||||
|
void setUiModeImport(const QString& fileName);
|
||||||
|
void setUiModePasteText(const QString& text);
|
||||||
|
|
||||||
const AsciiDataParseOptions parseOptions() const;
|
const AsciiDataParseOptions parseOptions() const;
|
||||||
void createNewPlot();
|
void createNewPlot();
|
||||||
void setPreviewText(const QString& text);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||||
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override;
|
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
|
||||||
|
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
UiMode m_uiMode;
|
||||||
|
|
||||||
caf::PdmField<QString> m_plotTitle;
|
caf::PdmField<QString> m_plotTitle;
|
||||||
caf::PdmField<QString> m_curvePrefix;
|
caf::PdmField<QString> m_curvePrefix;
|
||||||
caf::PdmField<DecimalSeparatorEnum> m_decimalSeparator;
|
caf::PdmField<DecimalSeparatorEnum> m_decimalSeparator;
|
||||||
@ -110,6 +122,7 @@ private:
|
|||||||
caf::PdmField<bool> m_useCustomDateFormat;
|
caf::PdmField<bool> m_useCustomDateFormat;
|
||||||
caf::PdmField<QString> m_customDateFormat;
|
caf::PdmField<QString> m_customDateFormat;
|
||||||
caf::PdmField<CellSeparatorEnum> m_cellSeparator;
|
caf::PdmField<CellSeparatorEnum> m_cellSeparator;
|
||||||
|
caf::PdmField<QString> m_timeSeriesColumnName;
|
||||||
|
|
||||||
caf::PdmField<caf::AppEnum<RimPlotCurve::LineStyleEnum>> m_curveLineStyle;
|
caf::PdmField<caf::AppEnum<RimPlotCurve::LineStyleEnum>> m_curveLineStyle;
|
||||||
caf::PdmField<caf::AppEnum<RimPlotCurve::PointSymbolEnum>> m_curveSymbol;
|
caf::PdmField<caf::AppEnum<RimPlotCurve::PointSymbolEnum>> m_curveSymbol;
|
||||||
@ -117,4 +130,8 @@ private:
|
|||||||
|
|
||||||
bool m_createNewPlot;
|
bool m_createNewPlot;
|
||||||
caf::PdmField<QString> m_previewText;
|
caf::PdmField<QString> m_previewText;
|
||||||
|
|
||||||
|
// Data source
|
||||||
|
QString m_fileName;
|
||||||
|
QString m_pastedText;
|
||||||
};
|
};
|
||||||
|
@ -58,8 +58,8 @@ bool RifCsvUserData::parse(const QString& fileName, const AsciiDataParseOptions&
|
|||||||
m_mapFromAddressToTimeStepIndex.clear();
|
m_mapFromAddressToTimeStepIndex.clear();
|
||||||
m_mapFromAddressToResultIndex.clear();
|
m_mapFromAddressToResultIndex.clear();
|
||||||
|
|
||||||
m_parser = std::unique_ptr<RifCsvUserDataParser>(new RifCsvUserDataParser(errorText));
|
m_parser = std::unique_ptr<RifCsvUserDataFileParser>(new RifCsvUserDataFileParser(fileName, errorText));
|
||||||
m_parser->parse(fileName, parseOptions);
|
m_parser->parse(parseOptions);
|
||||||
if (!m_parser)
|
if (!m_parser)
|
||||||
{
|
{
|
||||||
RiaLogging::error(QString("Failed to parse file"));
|
RiaLogging::error(QString("Failed to parse file"));
|
||||||
|
@ -35,8 +35,8 @@
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RifCsvUserDataParser::RifCsvUserDataParser(QString* errorText)
|
RifCsvUserDataParser::RifCsvUserDataParser(QString* errorText) :
|
||||||
: m_errorText(errorText)
|
m_errorText(errorText)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,9 +44,16 @@ RifCsvUserDataParser::RifCsvUserDataParser(QString* errorText)
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RifCsvUserDataParser::parse(const QString& fileName, const AsciiDataParseOptions& parseOptions)
|
RifCsvUserDataParser::~RifCsvUserDataParser()
|
||||||
{
|
{
|
||||||
return parseData(fileName, parseOptions);
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RifCsvUserDataParser::parse(const AsciiDataParseOptions& parseOptions)
|
||||||
|
{
|
||||||
|
return parseData(parseOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -71,43 +78,116 @@ const ColumnInfo* RifCsvUserDataParser::columnInfo(size_t columnIndex) const
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RifCsvUserDataParser::parseData(const QString& fileName, const AsciiDataParseOptions& parseOptions)
|
bool RifCsvUserDataParser::parseColumnNames(const QString& cellSeparator,
|
||||||
|
std::vector<QString>* columnNames)
|
||||||
|
{
|
||||||
|
if (!columnNames) return false;
|
||||||
|
|
||||||
|
columnNames->clear();
|
||||||
|
|
||||||
|
QTextStream* dataStream = openDataStream();
|
||||||
|
bool result = parseColumnHeader(dataStream, cellSeparator, columnNames);
|
||||||
|
|
||||||
|
closeDataStream();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QString RifCsvUserDataParser::previewText()
|
||||||
|
{
|
||||||
|
QTextStream *stream = openDataStream();
|
||||||
|
|
||||||
|
if (!stream) return "";
|
||||||
|
|
||||||
|
QString preview;
|
||||||
|
QTextStream outStream(&preview);
|
||||||
|
int iLine = 0;
|
||||||
|
|
||||||
|
while (iLine < 30 + 1 && !stream->atEnd())
|
||||||
|
{
|
||||||
|
QString line = stream->readLine();
|
||||||
|
|
||||||
|
if (line.isEmpty()) continue;
|
||||||
|
|
||||||
|
outStream << line;
|
||||||
|
outStream << "\n";
|
||||||
|
iLine++;
|
||||||
|
}
|
||||||
|
closeDataStream();
|
||||||
|
return columnifyText(preview);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RifCsvUserDataParser::parseColumnHeader(QTextStream* dataStream, const QString& cellSeparator, std::vector<QString>* columnNames)
|
||||||
|
{
|
||||||
|
if (!columnNames) return false;
|
||||||
|
|
||||||
|
columnNames->clear();
|
||||||
|
|
||||||
|
bool headerFound = false;
|
||||||
|
while (!headerFound)
|
||||||
|
{
|
||||||
|
QString line = dataStream->readLine();
|
||||||
|
if (line.trimmed().isEmpty()) continue;
|
||||||
|
|
||||||
|
QStringList lineColumns = splitLineAndTrim(line, cellSeparator);
|
||||||
|
|
||||||
|
int colCount = lineColumns.size();
|
||||||
|
|
||||||
|
for (int iCol = 0; iCol < colCount; iCol++)
|
||||||
|
{
|
||||||
|
columnNames->push_back(lineColumns[iCol]);
|
||||||
|
}
|
||||||
|
headerFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions)
|
||||||
{
|
{
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
enum { HEADER_ROW, FIRST_DATA_ROW, DATA_ROW } parseState = HEADER_ROW;
|
enum { FIRST_DATA_ROW, DATA_ROW } parseState = FIRST_DATA_ROW;
|
||||||
int colCount = -1;
|
int colCount;
|
||||||
std::vector<ColumnInfo> cols;
|
std::vector<ColumnInfo> cols;
|
||||||
|
|
||||||
QFile file(fileName);
|
QTextStream* dataStream = openDataStream();
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
|
||||||
|
// Parse header
|
||||||
|
std::vector<QString> columnNames;
|
||||||
|
if (parseColumnHeader(dataStream, parseOptions.cellSeparator, &columnNames))
|
||||||
{
|
{
|
||||||
RiaLogging::error(QString("Failed to open %1").arg(fileName));
|
colCount = (int)columnNames.size();
|
||||||
|
|
||||||
|
for (int iCol = 0; iCol < colCount; iCol++)
|
||||||
|
{
|
||||||
|
std::string colName = columnNames[iCol].toStdString();
|
||||||
|
RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::importedAddress(colName);
|
||||||
|
ColumnInfo col = ColumnInfo::createColumnInfoFromCsvData(addr, "");
|
||||||
|
cols.push_back(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_errorText->append("Failed to parse column headers");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream dataStream(&file);
|
while (!dataStream->atEnd())
|
||||||
while (!dataStream.atEnd())
|
|
||||||
{
|
{
|
||||||
QString line = dataStream.readLine();
|
QString line = dataStream->readLine();
|
||||||
if(line.trimmed().isEmpty()) continue;
|
if(line.trimmed().isEmpty()) continue;
|
||||||
|
|
||||||
QStringList lineColumns = splitLineAndTrim(line, parseOptions.cellSeparator);
|
QStringList lineColumns = splitLineAndTrim(line, parseOptions.cellSeparator);
|
||||||
|
|
||||||
if (parseState == HEADER_ROW)
|
if(lineColumns.size() != colCount)
|
||||||
{
|
|
||||||
colCount = lineColumns.size();
|
|
||||||
|
|
||||||
for (int iCol = 0; iCol < colCount; iCol++)
|
|
||||||
{
|
|
||||||
std::string colName = lineColumns[iCol].toStdString();
|
|
||||||
RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::importedAddress(colName);
|
|
||||||
ColumnInfo col = ColumnInfo::createColumnInfoFromCsvData(addr, "");
|
|
||||||
cols.push_back(col);
|
|
||||||
}
|
|
||||||
|
|
||||||
parseState = FIRST_DATA_ROW;
|
|
||||||
}
|
|
||||||
else if(lineColumns.size() != colCount)
|
|
||||||
{
|
{
|
||||||
m_errorText->append("CSV file has invalid content (Column count mismatch)");
|
m_errorText->append("CSV file has invalid content (Column count mismatch)");
|
||||||
errors = true;
|
errors = true;
|
||||||
@ -177,7 +257,7 @@ bool RifCsvUserDataParser::parseData(const QString& fileName, const AsciiDataPar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
closeDataStream();
|
||||||
|
|
||||||
if (!errors)
|
if (!errors)
|
||||||
{
|
{
|
||||||
@ -187,6 +267,25 @@ bool RifCsvUserDataParser::parseData(const QString& fileName, const AsciiDataPar
|
|||||||
return !errors;
|
return !errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QString RifCsvUserDataParser::columnifyText(const QString& text)
|
||||||
|
{
|
||||||
|
QString pretty = text;
|
||||||
|
|
||||||
|
QString cellSep = tryDetermineCellSeparator();
|
||||||
|
if (!cellSep.isEmpty())
|
||||||
|
{
|
||||||
|
if (cellSep == ";" || cellSep == ",")
|
||||||
|
{
|
||||||
|
pretty = pretty.replace(cellSep, QString("\t") + cellSep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pretty;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -207,3 +306,172 @@ QDateTime RifCsvUserDataParser::tryParseDateTime(const std::string& colData, con
|
|||||||
{
|
{
|
||||||
return RiaQDateTimeTools::fromString(QString::fromStdString(colData), format);
|
return RiaQDateTimeTools::fromString(QString::fromStdString(colData), format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QString RifCsvUserDataParser::tryDetermineCellSeparator()
|
||||||
|
{
|
||||||
|
QTextStream* dataStream = openDataStream();
|
||||||
|
std::vector<QString> lines;
|
||||||
|
int iLine = 0;
|
||||||
|
|
||||||
|
while(iLine < 10 && !dataStream->atEnd())
|
||||||
|
{
|
||||||
|
QString line = dataStream->readLine();
|
||||||
|
if(line.isEmpty()) continue;
|
||||||
|
|
||||||
|
lines.push_back(line);
|
||||||
|
iLine++;
|
||||||
|
}
|
||||||
|
closeDataStream();
|
||||||
|
|
||||||
|
// Try different cell separators
|
||||||
|
int totColumnCountTab = 0;
|
||||||
|
int totColumnCountSemicolon = 0;
|
||||||
|
int totColumnCountComma = 0;
|
||||||
|
|
||||||
|
for (const QString& line : lines)
|
||||||
|
{
|
||||||
|
totColumnCountTab += splitLineAndTrim(line, "\t").size();
|
||||||
|
totColumnCountSemicolon += splitLineAndTrim(line, ";").size();
|
||||||
|
totColumnCountComma += splitLineAndTrim(line, ",").size();
|
||||||
|
}
|
||||||
|
|
||||||
|
double avgColumnCountTab = (double)totColumnCountTab / lines.size();
|
||||||
|
double avgColumnCountSemicolon = (double)totColumnCountSemicolon / lines.size();
|
||||||
|
double avgColumnCountComma = (double)totColumnCountComma / lines.size();
|
||||||
|
|
||||||
|
// Select the one having highest average
|
||||||
|
double maxAvg = std::max(std::max(avgColumnCountTab, avgColumnCountSemicolon), avgColumnCountComma);
|
||||||
|
|
||||||
|
if (maxAvg == avgColumnCountTab) return "\t";
|
||||||
|
if (maxAvg == avgColumnCountSemicolon) return ";";
|
||||||
|
if (maxAvg == avgColumnCountComma) return ",";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RifCsvUserDataFileParser::RifCsvUserDataFileParser(const QString& fileName, QString* errorText) :
|
||||||
|
RifCsvUserDataParser(errorText)
|
||||||
|
{
|
||||||
|
m_fileName = fileName;
|
||||||
|
m_file = nullptr;
|
||||||
|
m_textStream = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RifCsvUserDataFileParser::~RifCsvUserDataFileParser()
|
||||||
|
{
|
||||||
|
if (m_textStream)
|
||||||
|
{
|
||||||
|
delete m_textStream;
|
||||||
|
}
|
||||||
|
closeFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QTextStream* RifCsvUserDataFileParser::openDataStream()
|
||||||
|
{
|
||||||
|
if (!openFile()) return nullptr;
|
||||||
|
|
||||||
|
m_textStream = new QTextStream(m_file);
|
||||||
|
return m_textStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RifCsvUserDataFileParser::closeDataStream()
|
||||||
|
{
|
||||||
|
if (m_textStream)
|
||||||
|
{
|
||||||
|
delete m_textStream;
|
||||||
|
m_textStream = nullptr;
|
||||||
|
}
|
||||||
|
closeFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RifCsvUserDataFileParser::openFile()
|
||||||
|
{
|
||||||
|
if (!m_file)
|
||||||
|
{
|
||||||
|
m_file = new QFile(m_fileName);
|
||||||
|
if (!m_file->open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
|
{
|
||||||
|
RiaLogging::error(QString("Failed to open %1").arg(m_fileName));
|
||||||
|
|
||||||
|
delete m_file;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RifCsvUserDataFileParser::closeFile()
|
||||||
|
{
|
||||||
|
if (m_file)
|
||||||
|
{
|
||||||
|
m_file->close();
|
||||||
|
delete m_file;
|
||||||
|
m_file = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RifCsvUserDataPastedTextParser::RifCsvUserDataPastedTextParser(const QString& text, QString* errorText):
|
||||||
|
RifCsvUserDataParser(errorText)
|
||||||
|
{
|
||||||
|
m_text = text;
|
||||||
|
m_textStream = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RifCsvUserDataPastedTextParser::~RifCsvUserDataPastedTextParser()
|
||||||
|
{
|
||||||
|
if (m_textStream)
|
||||||
|
{
|
||||||
|
delete m_textStream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QTextStream* RifCsvUserDataPastedTextParser::openDataStream()
|
||||||
|
{
|
||||||
|
if (m_textStream)
|
||||||
|
{
|
||||||
|
delete m_textStream;
|
||||||
|
}
|
||||||
|
m_textStream = new QTextStream(&m_text);
|
||||||
|
return m_textStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RifCsvUserDataPastedTextParser::closeDataStream()
|
||||||
|
{
|
||||||
|
if (m_textStream)
|
||||||
|
{
|
||||||
|
delete m_textStream;
|
||||||
|
m_textStream = nullptr;
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,8 @@
|
|||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -39,19 +41,75 @@ class RifCsvUserDataParser
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RifCsvUserDataParser(QString* errorText = nullptr);
|
RifCsvUserDataParser(QString* errorText = nullptr);
|
||||||
|
virtual ~RifCsvUserDataParser();
|
||||||
|
|
||||||
|
bool parse(const AsciiDataParseOptions& parseOptions);
|
||||||
bool parse(const QString& fileName, const AsciiDataParseOptions& parseOptions);
|
|
||||||
const TableData& tableData() const;
|
const TableData& tableData() const;
|
||||||
|
|
||||||
const ColumnInfo* columnInfo(size_t columnIndex) const;
|
const ColumnInfo* columnInfo(size_t columnIndex) const;
|
||||||
|
|
||||||
|
bool parseColumnNames(const QString& cellSeparator,
|
||||||
|
std::vector<QString>* columnNames);
|
||||||
|
QString previewText();
|
||||||
|
|
||||||
|
QString tryDetermineCellSeparator();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QTextStream* openDataStream() = 0;
|
||||||
|
virtual void closeDataStream() = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool parseData(const QString& fileName, const AsciiDataParseOptions& parseOptions);
|
bool parseColumnHeader(QTextStream* dataStream,
|
||||||
QStringList splitLineAndTrim(const QString& list, const QString& separator);
|
const QString& cellSeparator,
|
||||||
QDateTime tryParseDateTime(const std::string& colData, const QString& format);
|
std::vector<QString>* columnNames);
|
||||||
|
bool parseData(const AsciiDataParseOptions& parseOptions);
|
||||||
|
QString columnifyText(const QString& text);
|
||||||
|
static QStringList splitLineAndTrim(const QString& line, const QString& separator);
|
||||||
|
static QDateTime tryParseDateTime(const std::string& colData, const QString& format);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TableData m_tableData;
|
TableData m_tableData;
|
||||||
QString* m_errorText;
|
QString* m_errorText;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
///
|
||||||
|
//==================================================================================================
|
||||||
|
class RifCsvUserDataFileParser : public RifCsvUserDataParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RifCsvUserDataFileParser(const QString& fileName, QString* errorText = nullptr);
|
||||||
|
virtual ~RifCsvUserDataFileParser();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QTextStream* openDataStream() override;
|
||||||
|
virtual void closeDataStream() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool openFile();
|
||||||
|
void closeFile();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_fileName;
|
||||||
|
QFile* m_file;
|
||||||
|
QTextStream* m_textStream;
|
||||||
|
};
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
///
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
|
class RifCsvUserDataPastedTextParser : public RifCsvUserDataParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RifCsvUserDataPastedTextParser(const QString& text, QString* errorText = nullptr);
|
||||||
|
virtual ~RifCsvUserDataPastedTextParser();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QTextStream* openDataStream() override;
|
||||||
|
virtual void closeDataStream() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_text;
|
||||||
|
QTextStream* m_textStream;
|
||||||
|
};
|
||||||
|
@ -165,22 +165,9 @@ RimObservedData* RimObservedDataCollection::createAndAddRsmObservedDataFromFile(
|
|||||||
RimObservedData* RimObservedDataCollection::createAndAddCvsObservedDataFromFile(const QString& fileName, QString* errorText /*= nullptr*/)
|
RimObservedData* RimObservedDataCollection::createAndAddCvsObservedDataFromFile(const QString& fileName, QString* errorText /*= nullptr*/)
|
||||||
{
|
{
|
||||||
RimObservedData* observedData = nullptr;
|
RimObservedData* observedData = nullptr;
|
||||||
QString fileContents;
|
|
||||||
|
|
||||||
{
|
|
||||||
QFile file(fileName);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
|
||||||
{
|
|
||||||
RiaLogging::error(QString("Failed to open %1").arg(fileName));
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileContents = file.readAll();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
RicPasteAsciiDataToSummaryPlotFeatureUi parseOptionsUi;
|
RicPasteAsciiDataToSummaryPlotFeatureUi parseOptionsUi;
|
||||||
parseOptionsUi.setPreviewText(fileContents);
|
parseOptionsUi.setUiModeImport(fileName);
|
||||||
caf::PdmSettings::readFieldsFromApplicationStore(&parseOptionsUi);
|
caf::PdmSettings::readFieldsFromApplicationStore(&parseOptionsUi);
|
||||||
|
|
||||||
caf::PdmUiPropertyViewDialog propertyDialog(NULL, &parseOptionsUi, "CSV Import Options", "");
|
caf::PdmUiPropertyViewDialog propertyDialog(NULL, &parseOptionsUi, "CSV Import Options", "");
|
||||||
|
Loading…
Reference in New Issue
Block a user