diff --git a/GUI/coregui/DataLoaders/AbstractDataLoader.cpp b/GUI/coregui/DataLoaders/AbstractDataLoader.cpp
index cc59ee25f091591b17a6875910d0eb13bf8e6a4a..e5ca3caa0519f994cde30bd28d0077aaab59ef60 100644
--- a/GUI/coregui/DataLoaders/AbstractDataLoader.cpp
+++ b/GUI/coregui/DataLoaders/AbstractDataLoader.cpp
@@ -39,3 +39,8 @@ QByteArray AbstractDataLoader::defaultProperties() const
     cloned->initWithDefaultProperties();
     return cloned->serialize();
 }
+
+bool AbstractDataLoader::fillImportDetailsTable(QTableWidget*, bool, bool, bool) const
+{
+    return false;
+}
diff --git a/GUI/coregui/DataLoaders/AbstractDataLoader.h b/GUI/coregui/DataLoaders/AbstractDataLoader.h
index 6e85c39f9506ac85bdfa23b563cae6beee1a09e8..b06dd2b74bb416ead25b6324109e194592493361 100644
--- a/GUI/coregui/DataLoaders/AbstractDataLoader.h
+++ b/GUI/coregui/DataLoaders/AbstractDataLoader.h
@@ -19,6 +19,8 @@ class QString;
 class QByteArray;
 class QGroupBox;
 class QCustomPlot;
+class QTableWidget;
+class RealDataItem;
 
 #include <QtCore>
 
@@ -49,7 +51,7 @@ public:
     //! Returns every internal setting so it can be restored completely
     virtual QByteArray serialize() const;
 
-    //! #TODO: how to deliver errors? VersionException...?
+    //! #baTODO: how to deliver errors? VersionException...?
     virtual void deserialize(const QByteArray& data);
 
     virtual QByteArray defaultProperties() const;
@@ -57,6 +59,14 @@ public:
     //! Returns a Qt rich text formatted preview
     virtual QString preview(const QString& filepath, QCustomPlot* plotWidget) const = 0;
 
+    virtual void importFile(const QString& filename, RealDataItem* item, QStringList* errors,
+                            QStringList* warnings) const = 0;
+
+    //! Fill the import details table with information from the last call to importFile
+    //! return false if not supported.
+    //! This base implementation returns false.
+    virtual bool fillImportDetailsTable(QTableWidget* table, bool fileContent, bool rawContent,
+                                        bool processedContent) const;
 signals:
     void propertiesChanged();
 };
diff --git a/GUI/coregui/DataLoaders/AbstractDataLoader1D.h b/GUI/coregui/DataLoaders/AbstractDataLoader1D.h
index d91e37ccaa2e698da7459b8f02fec5ca9d8708a2..fd7f60c6ab8dbc4d3534821d7167a0279f2cefff 100644
--- a/GUI/coregui/DataLoaders/AbstractDataLoader1D.h
+++ b/GUI/coregui/DataLoaders/AbstractDataLoader1D.h
@@ -16,7 +16,6 @@
 #define BORNAGAIN_GUI_COREGUI_DATALOADERS_ABSTRACTDATALOADER1D_H
 
 #include "GUI/coregui/DataLoaders/AbstractDataLoader.h"
-#include <QVector>
 
 class AbstractDataLoader1D : public AbstractDataLoader {
 };
diff --git a/GUI/coregui/DataLoaders/AutomaticDataLoader1D.cpp b/GUI/coregui/DataLoaders/AutomaticDataLoader1D.cpp
index 0b14d45eb4eb1b3656da22bdaa5fbc04bd359c1e..8a9fd297ca43d43cd76e5d64212e0ae52cd0b007 100644
--- a/GUI/coregui/DataLoaders/AutomaticDataLoader1D.cpp
+++ b/GUI/coregui/DataLoaders/AutomaticDataLoader1D.cpp
@@ -15,6 +15,7 @@
 #include "GUI/coregui/DataLoaders/AutomaticDataLoader1D.h"
 #include "Base/Axis/PointwiseAxis.h"
 #include "Device/Data/OutputData.h"
+#include "Device/Histo/IntensityDataIOFactory.h"
 #include "Device/InputOutput/DataFormatUtils.h"
 #include "qcustomplot.h"
 #include <QFile>
@@ -161,6 +162,16 @@ AbstractDataLoader* AutomaticDataLoader1D::clone() const
     return loader;
 }
 
+void AutomaticDataLoader1D::importFile(const QString& filename, RealDataItem* item,
+                                       QStringList* errors, QStringList* warnings) const
+{
+    // #baimport implement legacy loader
+    /*
+        auto data = IntensityDataIOFactory::readReflectometryData(filename.toStdString());
+        return OutputData<double>(std::move(*data));
+    */
+}
+
 QString AutomaticDataLoader1D::outputDataToTable(const OutputData<double>& outputData) const
 {
     auto size = outputData.axis(0).size();
diff --git a/GUI/coregui/DataLoaders/AutomaticDataLoader1D.h b/GUI/coregui/DataLoaders/AutomaticDataLoader1D.h
index 05215d5fb6cc1a3b3a4c77baf97d654ecd4f72eb..b8e9a89e628553a227a61f08c3427bbf4d008fbd 100644
--- a/GUI/coregui/DataLoaders/AutomaticDataLoader1D.h
+++ b/GUI/coregui/DataLoaders/AutomaticDataLoader1D.h
@@ -26,6 +26,8 @@ public:
     virtual QString persistentClassName() const override;
     virtual QString preview(const QString& filepath, QCustomPlot* plotWidget) const override;
     virtual AbstractDataLoader* clone() const override;
+    virtual void importFile(const QString& filename, RealDataItem* item, QStringList* errors,
+                            QStringList* warnings) const override;
 
 private:
     QString outputDataToTable(const OutputData<double>& outputData) const;
diff --git a/GUI/coregui/DataLoaders/QREDataLoader.cpp b/GUI/coregui/DataLoaders/QREDataLoader.cpp
index 92bf8ce69543973522a717e73cc1fce3d832b623..7d240c18ef8eaf1f88f7f552076e6ae291084b3d 100644
--- a/GUI/coregui/DataLoaders/QREDataLoader.cpp
+++ b/GUI/coregui/DataLoaders/QREDataLoader.cpp
@@ -13,10 +13,18 @@
 //  ************************************************************************************************
 
 #include "GUI/coregui/DataLoaders/QREDataLoader.h"
+#include "../Axis/PointwiseAxis.h"
+#include "Device/Histo/IntensityDataIOFactory.h"
 #include "Device/InputOutput/DataFormatUtils.h"
+#include "Device/Unit/AxisNames.h"
 #include "GUI/coregui/DataLoaders/QREDataLoaderProperties.h"
+#include "Models/DataItem.h"
+#include "Models/JobItemUtils.h"
+#include "Models/RealDataItem.h"
+#include "Models/SpecularDataItem.h"
 #include "qcustomplot.h"
 #include "ui_QREDataLoaderProperties.h"
+#include "utils/ImportDataInfo.h"
 #include <QFile>
 #include <QString>
 #include <QTextStream>
@@ -107,155 +115,42 @@ QString QREDataLoader::persistentClassName() const
 
 QString QREDataLoader::preview(const QString& filepath, QCustomPlot* plotWidget) const
 {
-    /*
-    QFile file(filepath);
-    if (!file.open(QFile::ReadOnly)) {
-        return "File '" + filepath + "' could not be opened";
-    }
-
-    const QStringList headerPrefixes =
-        (m_headerPrefix.trimmed().isEmpty()) ? QStringList() : m_headerPrefix.split(",");
-
-    const auto lineIsHeader = [headerPrefixes](const QString& line) {
-        for (auto prefix : headerPrefixes) {
-            if (line.startsWith(prefix.trimmed()))
-                return true;
-        }
-
-        return false;
-    };
-
-    const auto skippedLines = expandLineNumberPattern(m_linesToSkip);
-    const auto lineShouldBeSkipped = [skippedLines](int lineNr) {
-        for (auto pair : skippedLines) {
-            if (lineNr >= pair.first && lineNr <= pair.second)
-                return true;
-        }
-        return false;
-    };
-
-    // calc map with factors
-    // #TODO: wrong result when more than one dataType points to same column with different factors
-    QMap<int, double> factorsOfColumns;
-    for (auto dataType : m_columnDefinitions.keys()) {
-        const auto& colDef = m_columnDefinitions[dataType];
-        if (colDef.enabled)
-            factorsOfColumns[colDef.column] = colDef.factor;
-    }
-
-    QVector<QVector<double>> entriesAsDouble;
-    QVector<QStringList> entriesAsString;
-    QTextStream in(&file);
-    int lineNr = 0;
-    int lastColumnCount = -1;
-    while (!in.atEnd()) {
-        QString line = in.readLine().trimmed();
-        lineNr++;
-
-        if (lineIsHeader(line) || lineShouldBeSkipped(lineNr) || line.isEmpty())
-            continue;
-
-        QStringList lineEntries = line.split(m_separator);
-
-        if (lastColumnCount == -1)
-            lastColumnCount = lineEntries.count();
-        else if (lastColumnCount != lineEntries.count())
-            return QString(
-                       "Error: number of columns is not constant over all lines (found in line %1)")
-                .arg(lineNr);
-
-        QVector<double> rowEntriesAsDouble;
-        QStringList rowEntriesAsString; // already with factors
-
-        for (int col = 0; col < lineEntries.count(); col++) {
-            bool ok = false;
-            double val = lineEntries[col].toDouble(&ok);
-            if (!ok)
-                val = NAN; // #TODO: review
-            else
-                val *= factorsOfColumns.value(col, 1.0);
-
-            rowEntriesAsDouble << val;
-            rowEntriesAsString << QString::number(val);
-        }
-
-        entriesAsDouble << rowEntriesAsDouble;
-        entriesAsString << rowEntriesAsString;
-    }
-
-    // validate - There is at least one row and at least two columns
-    size_t nrows = entriesAsDouble.size();
-    if (nrows < 1)
-        return "Error: no numerical values found";
-    size_t ncols = entriesAsDouble[0].size();
-    if (ncols < 2)
-        return "Error: Minimum 2 columns required";
-
-    // Assign Q vs R, dR, dQ:
-    QStringList tableEntries;
-
-    QMap<int, QString> typeStr;
-    typeStr[0] = "Q";
-    typeStr[1] = "R";
-    typeStr[2] = "E";
-    typeStr[3] = "ignored";
-
-    for (int col = 0; col < ncols; col++) {
-        QString headerText = typeStr[3];
-        for (auto dataType : m_columnDefinitions.keys()) {
-            if (m_columnDefinitions[dataType].column == col
-                && m_columnDefinitions[dataType].enabled) {
-                headerText = typeStr[(int)dataType];
-                break;
-            }
-        }
-
-        tableEntries << headerText;
-    }
-
-    for (auto line : entriesAsString)
-        tableEntries << line;
-
-    QString s = bold("Data table:");
-
-    s += table((int)ncols, tableEntries, "border=\"1\" cellpadding=\"10\" cellspacing=\"0\"", true);
-
     // -- create plot
-    int qCol = m_columnDefinitions[DataType::Q].column;
-    int rCol = m_columnDefinitions[DataType::R].column;
     int dRCol = m_columnDefinitions[DataType::dR].column;
 
     QVector<double> qVec;
     QVector<double> rVec;
-    QVector<double> drVec;
+    QVector<double> eVec;
 
-    const bool addDR = m_columnDefinitions[DataType::dR].enabled && (ncols > dRCol);
+    const bool addError =
+        m_columnDefinitions[DataType::dR].enabled && (m_parsingResult.columnCount > dRCol);
 
-    for (const auto lineAsDoubles : entriesAsDouble) {
-        qVec << lineAsDoubles[qCol];
-        rVec << lineAsDoubles[rCol];
-        if (addDR)
-            drVec << lineAsDoubles[dRCol];
-    }
+    for (const auto d : m_parsingResult.qValues)
+        qVec << d.second;
+
+    for (const auto d : m_parsingResult.rValues)
+        rVec << d.second;
+
+    if (addError)
+        for (const auto d : m_parsingResult.eValues)
+            eVec << d.second;
 
     auto graph = plotWidget->addGraph();
     graph->addData(qVec, rVec);
 
-    if (!drVec.empty()) {
+    if (!eVec.empty()) {
         auto errorBars = new QCPErrorBars(plotWidget->xAxis, plotWidget->yAxis);
 
-        errorBars->setData(drVec);
+        errorBars->setData(eVec);
         errorBars->setDataPlottable(graph);
     }
 
     plotWidget->rescaleAxes();
     plotWidget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
-    plotWidget->xAxis->setLabel("Q [" + m_columnDefinitions[DataType::Q].unit + "]");
+    plotWidget->xAxis->setLabel("Q [1/nm]");
     plotWidget->yAxis->setLabel("R");
 
-    return "<p>" + bold("<h>Information: </h>") + info() + "</p><p>" + s + "</p>";
-    */
-    return "not implemented";
+    return "";
 }
 
 void QREDataLoader::populatePropertiesWidget(QWidget* parent)
@@ -318,6 +213,7 @@ void QREDataLoader::initWithDefaultProperties()
 
 QByteArray QREDataLoader::serialize() const
 {
+    // #badataloader ++ add version
     QByteArray a;
     QDataStream s(&a, QIODevice::WriteOnly);
     s << m_separator;
@@ -366,6 +262,325 @@ AbstractDataLoader* QREDataLoader::clone() const
     return loader;
 }
 
+void QREDataLoader::importFile(const QString& filename, RealDataItem* item, QStringList* errors,
+                               QStringList* warnings) const
+{
+    ASSERT(item != nullptr);
+    ASSERT(item->isSpecularData());
+
+    m_parsingResult.clear();
+
+    if (!parseFile(filename, errors, warnings)) {
+        // #baimport ++ reset item!
+        return;
+    }
+
+    // -- create OutputData
+    std::vector<double> qVec;
+    std::vector<double> rVec;
+
+    for (const auto d : m_parsingResult.qValues)
+        qVec.push_back(d.second);
+
+    for (const auto d : m_parsingResult.rValues)
+        rVec.push_back(d.second);
+
+    // -- make a few checks (mainly for fulfilling PointwiseAxis::sanityCheck())
+    if (qVec.size() < 2) {
+        *errors << "At least two Q coordinates must exist";
+        return;
+    }
+    if (!std::is_sorted(qVec.begin(), qVec.end())) {
+        *errors << "Q coordinates must be sorted in ascending order";
+        return;
+    }
+    if (std::adjacent_find(qVec.begin(), qVec.end()) != qVec.end()) {
+        *errors << "Q coordinates must not contain duplicate values";
+        return;
+    }
+
+    OutputData<double>* oData = new OutputData<double>();
+    oData->addAxis(PointwiseAxis("qVector", qVec));
+    oData->setRawDataVector(rVec);
+
+    try {
+        // -- Replacement of item->setImportData(std::move(data));
+        item->initNativeData();
+
+        QString units_name = JobItemUtils::nameFromAxesUnits(Axes::Units::QSPACE);
+
+        // -- Replacement of specularItem->reset(std::move(data));
+        SpecularDataItem* specularItem = item->specularDataItem();
+        ComboProperty combo = ComboProperty() << units_name;
+
+        specularItem->setItemValue(SpecularDataItem::P_AXES_UNITS, combo.variant());
+        specularItem->getItem(SpecularDataItem::P_AXES_UNITS)->setVisible(true);
+
+        auto label_map = AxisNames::InitSpecAxis();
+        const auto xAxisTitle = QString::fromStdString(label_map[Axes::Units::QSPACE]);
+        const auto yAxisTitle = "Signal [a.u.]"; // taken from ImportDataInfo::axisLabel
+
+        specularItem->setXaxisTitle(xAxisTitle);
+        specularItem->setYaxisTitle(yAxisTitle);
+        specularItem->setOutputData(oData); // takes ownership of odata
+        specularItem->setAxesRangeToData();
+
+        item->setNativeDataUnits(units_name);
+        item->nativeData()->setOutputData(oData->clone()); // takes ownership of odata
+    } catch (...) {
+        *errors << "Import not successful - caught an exception.";
+        // #baimport ++ reset item!
+    }
+}
+
+bool QREDataLoader::fillImportDetailsTable(QTableWidget* table, bool fileContent, bool rawContent,
+                                           bool processedContent) const
+{
+    bool showErrorColumn = m_columnDefinitions[QREDataLoader::DataType::dR].enabled;
+    QString qUnit = " [1/nm]";
+
+    auto t = table;
+    t->clear();
+
+    int colCount = 0;
+    if (fileContent)
+        colCount++;
+
+    if (rawContent)
+        colCount += m_parsingResult.columnCount;
+
+    if (processedContent)
+        colCount += showErrorColumn ? 3 : 2;
+
+    if (!fileContent && !rawContent && !processedContent) {
+        t->setRowCount(0);
+        return true;
+    }
+
+    t->setColumnCount(colCount);
+    t->setRowCount(fileContent ? m_parsingResult.lines.size()
+                               : m_parsingResult.originalEntriesAsDouble.size());
+
+    const auto cell = [t](int row, int col, double s, const QColor& backColor) {
+        auto tableItem = new QTableWidgetItem(QString::number(s));
+        tableItem->setBackgroundColor(backColor);
+        tableItem->setFlags(tableItem->flags() & ~Qt::ItemIsEditable);
+        t->setItem(row, col, tableItem);
+    };
+
+    QColor backgroundColorFileContent(239, 237, 248);
+    QColor backgroundColorRawContent(247, 240, 210);
+    QColor backgroundColorProcessedContent(191, 232, 242);
+
+    int dataCol = 0;
+    if (fileContent) {
+        auto headerItem = new QTableWidgetItem("File content (text)");
+        headerItem->setBackgroundColor(backgroundColorFileContent.darker(150));
+        t->setHorizontalHeaderItem(0, headerItem);
+        int row = 0;
+        for (auto line : m_parsingResult.lines) {
+            const bool skipped = line.first;
+            QString lineContent = line.second;
+            lineContent.replace("\t", " --> ");
+            auto tableItem = new QTableWidgetItem(lineContent);
+            if (skipped)
+                tableItem->setTextColor(Qt::lightGray); // #baimport review
+            tableItem->setBackgroundColor(backgroundColorFileContent);
+            tableItem->setFlags(tableItem->flags() & ~Qt::ItemIsEditable);
+            t->setItem(row++, 0, tableItem);
+        }
+        dataCol = 1;
+    }
+
+    if (rawContent) {
+        for (int col = 0; col < m_parsingResult.columnCount; col++) {
+            t->setHorizontalHeaderItem(dataCol + col,
+                                       new QTableWidgetItem(QString("Column %1 raw").arg(col + 1)));
+        }
+
+        for (auto rowContent : m_parsingResult.originalEntriesAsDouble) {
+            int lineNr = rowContent.first;
+            int dataRow = lineNr - 1; // lineNr is 1-based
+
+            for (auto v : rowContent.second)
+                cell(dataRow, dataCol++, v, backgroundColorRawContent);
+            dataCol -= rowContent.second.size();
+        }
+        dataCol += m_parsingResult.columnCount;
+    }
+
+    if (processedContent) {
+        t->setHorizontalHeaderItem(dataCol, new QTableWidgetItem("Q" + qUnit));
+        t->setHorizontalHeaderItem(dataCol + 1, new QTableWidgetItem("R"));
+        if (showErrorColumn)
+            t->setHorizontalHeaderItem(dataCol + 2, new QTableWidgetItem("E"));
+
+        for (auto rowContent : m_parsingResult.qValues) {
+            int lineNr = rowContent.first;
+            int dataRow = lineNr - 1; // lineNr is 1-based
+            auto v = rowContent.second;
+            cell(dataRow, dataCol + 0, v, backgroundColorProcessedContent);
+        }
+
+        for (auto rowContent : m_parsingResult.rValues) {
+            int lineNr = rowContent.first;
+            int dataRow = lineNr - 1; // lineNr is 1-based
+            auto v = rowContent.second;
+            cell(dataRow, dataCol + 1, v, backgroundColorProcessedContent);
+        }
+
+        if (showErrorColumn) {
+            for (auto rowContent : m_parsingResult.eValues) {
+                int lineNr = rowContent.first;
+                int dataRow = lineNr - 1; // lineNr is 1-based
+                auto v = rowContent.second;
+                cell(dataRow, dataCol + 2, v, backgroundColorProcessedContent);
+            }
+        }
+    }
+
+    t->resizeColumnsToContents();
+
+    return true;
+}
+
+bool QREDataLoader::parseFile(const QString& filename, QStringList* errors,
+                              QStringList* warnings) const
+{
+    // #baimport optimize: check which import settings changed. E.g. if only q-factor changed, only
+    // regenerate qValues
+
+    QFile file(filename);
+    if (!file.open(QFile::ReadOnly)) {
+        *errors << "File '" + filename + "' could not be opened";
+        return false;
+    }
+
+    const QStringList headerPrefixes =
+        (m_headerPrefix.trimmed().isEmpty()) ? QStringList() : m_headerPrefix.split(",");
+
+    const auto lineIsHeader = [headerPrefixes](const QString& line) {
+        for (auto prefix : headerPrefixes) {
+            if (line.startsWith(prefix.trimmed()))
+                return true;
+        }
+
+        return false;
+    };
+
+    const auto skippedLines = expandLineNumberPattern(m_linesToSkip);
+    const auto lineShouldBeSkipped = [skippedLines](int lineNr) {
+        for (auto pair : skippedLines) {
+            if (lineNr >= pair.first && lineNr <= pair.second)
+                return true;
+        }
+        return false;
+    };
+
+    QTextStream in(&file);
+    int lineNr = 0;
+    int lastColumnCount = -1;
+    // if separator is SPACE: e.g. three consecutive SPACEs do not represent 3 columns => delete
+    // empty parts
+    QString::SplitBehavior splitBehavior =
+        m_separator == " " ? QString::SkipEmptyParts : QString::KeepEmptyParts;
+    while (!in.atEnd()) {
+        lineNr++;
+
+        QString line = in.readLine();
+
+        const bool skip =
+            lineIsHeader(line) || lineShouldBeSkipped(lineNr) || line.trimmed().isEmpty();
+
+        m_parsingResult.lines << qMakePair(skip, line);
+        if (skip)
+            continue;
+
+        QStringList lineEntries = line.split(m_separator, splitBehavior);
+
+        if (lastColumnCount == -1)
+            lastColumnCount = lineEntries.count();
+        else if (lastColumnCount != lineEntries.count()) {
+            *errors << QString(
+                           "Number of columns is not constant over all lines (found in line %1)")
+                           .arg(lineNr);
+            return false;
+        }
+
+        QVector<double> rowEntriesAsDouble;
+
+        for (int col = 0; col < lineEntries.count(); col++) {
+            bool ok = false;
+            double val = lineEntries[col].toDouble(&ok);
+            if (!ok)
+                val = std::numeric_limits<double>::quiet_NaN();
+
+            rowEntriesAsDouble << val;
+        }
+
+        m_parsingResult.originalEntriesAsDouble << qMakePair(lineNr, rowEntriesAsDouble);
+    }
+
+    // validate - There is at least one row and at least two columns
+    size_t nrows = m_parsingResult.originalEntriesAsDouble.size();
+    if (nrows < 1) {
+        *errors << "No numerical values found";
+        return false;
+    }
+
+    m_parsingResult.columnCount = m_parsingResult.originalEntriesAsDouble[0].second.size();
+    if (m_parsingResult.columnCount < 2) {
+        *errors << "Minimum 2 columns required";
+        return false;
+    }
+
+    // -- calculate the Q/R/E values (take from specified column, use factor)
+    const bool errorColumnIsEnabled = m_columnDefinitions[DataType::dR].enabled;
+    const double unitFac =
+        (m_columnDefinitions[DataType::Q].unit == UnitInFile::perAngstrom) ? 10.0 : 1.0;
+    const double qFactor = m_columnDefinitions[DataType::Q].factor * unitFac;
+    const double rFactor = m_columnDefinitions[DataType::R].factor;
+    const double eFactor = m_columnDefinitions[DataType::dR].factor;
+
+    const int qCol = m_columnDefinitions[DataType::Q].column;
+    const int rCol = m_columnDefinitions[DataType::R].column;
+    const int eCol = m_columnDefinitions[DataType::dR].column;
+
+    const bool qColIsValid = qCol >= 0 && qCol < m_parsingResult.columnCount;
+    const bool rColIsValid = rCol >= 0 && rCol < m_parsingResult.columnCount;
+    const bool eColIsValid = eCol >= 0 && eCol < m_parsingResult.columnCount;
+
+    QSet<double> foundQValues;
+
+    for (auto rowContent : m_parsingResult.originalEntriesAsDouble) {
+        int lineNr = rowContent.first;
+        const auto& rawValues = rowContent.second;
+
+        const double q =
+            qColIsValid ? rawValues[qCol] * qFactor : std::numeric_limits<double>::quiet_NaN();
+        const double r =
+            rColIsValid ? rawValues[rCol] * rFactor : std::numeric_limits<double>::quiet_NaN();
+        const double e =
+            eColIsValid ? rawValues[eCol] * eFactor : std::numeric_limits<double>::quiet_NaN();
+
+        const bool containsNaN =
+            (std::isnan(q) || std::isnan(r) || (std::isnan(e) && errorColumnIsEnabled));
+
+        const bool isDuplicateQ = foundQValues.contains(q);
+
+        // ignore lines when a resulting value would be NAN or in case of duplicate Q values
+        // #baimport make this dependent from a UI checkbox?
+        if (!containsNaN && !isDuplicateQ) {
+            m_parsingResult.qValues << qMakePair(lineNr, q);
+            m_parsingResult.rValues << qMakePair(lineNr, r);
+            m_parsingResult.eValues << qMakePair(lineNr, e);
+            foundQValues << q;
+        }
+    }
+
+    return true;
+}
+
 void QREDataLoader::applyProperties()
 {
     if (!m_propertiesWidget)
@@ -396,3 +611,13 @@ void QREDataLoader::applyProperties()
     m_columnDefinitions[DataType::dR].enabled =
         m_propertiesWidget->m_ui->enableErrorCheckBox->isChecked();
 }
+
+void QREDataLoader::ParsingResult::clear()
+{
+    lines.clear();
+    originalEntriesAsDouble.clear();
+    qValues.clear();
+    rValues.clear();
+    eValues.clear();
+    columnCount = 0;
+}
diff --git a/GUI/coregui/DataLoaders/QREDataLoader.h b/GUI/coregui/DataLoaders/QREDataLoader.h
index a347c74bbe0b93a220bca3727679f2bfee808b6f..9b175efd1b9a95f3fb4f61e23bced72b45505868 100644
--- a/GUI/coregui/DataLoaders/QREDataLoader.h
+++ b/GUI/coregui/DataLoaders/QREDataLoader.h
@@ -1,63 +1,76 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      GUI/coregui/DataLoaders/QREDataLoader.h
-//! @brief     Defines class QREDataLoader
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2021
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-//  ************************************************************************************************
-
-#ifndef GUI_COREGUI_DATALOADERS_QREDATALOADER_H
-#define GUI_COREGUI_DATALOADERS_QREDATALOADER_H
-
-#include "GUI/coregui/DataLoaders/AbstractDataLoader1D.h"
-#include <QVector>
-
-class QString;
-class QREDataLoaderProperties;
-
-class QREDataLoader : public AbstractDataLoader1D {
-public:
-    QREDataLoader();
-    virtual QString name() const override;
-    virtual QString info() const override;
-    virtual QString persistentClassName() const override;
-    virtual QString preview(const QString& filepath, QCustomPlot* plotWidget) const override;
-    virtual void populatePropertiesWidget(QWidget* parent) override;
-    virtual void initWithDefaultProperties() override;
-    virtual void applyProperties() override;
-    virtual QByteArray serialize() const override;
-    virtual void deserialize(const QByteArray& data) override;
-    virtual AbstractDataLoader* clone() const override;
-
+//  ************************************************************************************************
+//
+//  BornAgain: simulate and fit reflection and scattering
+//
+//! @file      GUI/coregui/DataLoaders/QREDataLoader.h
+//! @brief     Defines class QREDataLoader
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2021
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+//  ************************************************************************************************
+
+#ifndef GUI_COREGUI_DATALOADERS_QREDATALOADER_H
+#define GUI_COREGUI_DATALOADERS_QREDATALOADER_H
+
+#include "GUI/coregui/DataLoaders/AbstractDataLoader1D.h"
+#include <QVector>
+
+class QString;
+class QREDataLoaderProperties;
+
+class QREDataLoader : public AbstractDataLoader1D {
+public:
+    QREDataLoader();
+    virtual QString name() const override;
+    virtual QString info() const override;
+    virtual QString persistentClassName() const override;
+    virtual QString preview(const QString& filepath, QCustomPlot* plotWidget) const override;
+    virtual void populatePropertiesWidget(QWidget* parent) override;
+    virtual void initWithDefaultProperties() override;
+    virtual void applyProperties() override;
+    virtual QByteArray serialize() const override;
+    virtual void deserialize(const QByteArray& data) override;
+    virtual AbstractDataLoader* clone() const override;
+    virtual void importFile(const QString& filename, RealDataItem* item, QStringList* errors,
+                            QStringList* warnings) const override;
+    virtual bool fillImportDetailsTable(QTableWidget* table, bool fileContent, bool rawContent,
+                                        bool processedContent) const override;
+
 private:
-    enum class UnitInFile {
-        none,
-        perNanoMeter,
-        perAngstrom,
-        other
+    bool parseFile(const QString& filename, QStringList* errors, QStringList* warnings) const;
+
+private:
+    enum class UnitInFile { none, perNanoMeter, perAngstrom, other };
+
+    struct ColumnDefinition {
+        bool enabled;
+        int column;
+        UnitInFile unit;
+        double factor;
+    };
+
+    enum class DataType { Q, R, dR };
+
+    QString m_separator;    //!< column separator
+    QString m_headerPrefix; //!< prefix denoting header line
+    QString m_linesToSkip;  //!< pattern denoting line to skip (i.e. '1,10-12,42')
+    QPointer<QREDataLoaderProperties> m_propertiesWidget;
+
+    QMap<DataType, ColumnDefinition> m_columnDefinitions;
+
+    struct ParsingResult {
+        void clear();
+        QVector<QPair<bool, QString>> lines; // bool describes whether line is skipped
+        QVector<QPair<int, QVector<double>>> originalEntriesAsDouble;
+        QVector<QPair<int, double>> qValues;
+        QVector<QPair<int, double>> rValues;
+        QVector<QPair<int, double>> eValues;
+        int columnCount;
     };
-
-    struct ColumnDefinition {
-        bool enabled;
-        int column;
-        UnitInFile unit;
-        double factor;
-    };
-
-    enum class DataType { Q, R, dR };
-
-    QString m_separator;    //!< column separator
-    QString m_headerPrefix; //!< prefix denoting header line
-    QString m_linesToSkip;  //!< pattern denoting line to skip (i.e. '1,10-12,42')
-    QPointer<QREDataLoaderProperties> m_propertiesWidget;
-
-    QMap<DataType, ColumnDefinition> m_columnDefinitions;
-};
-
-#endif // GUI_COREGUI_DATALOADERS_QREDATALOADER_H
+    mutable ParsingResult m_parsingResult;
+};
+
+#endif // GUI_COREGUI_DATALOADERS_QREDATALOADER_H
diff --git a/GUI/coregui/DataLoaders/QREDataLoaderProperties.cpp b/GUI/coregui/DataLoaders/QREDataLoaderProperties.cpp
index de70d251fc3312ed905189ef67a9b1e7ca04fb4a..8c1f43236fdada85538cfb45a13df1d46afcd215 100644
--- a/GUI/coregui/DataLoaders/QREDataLoaderProperties.cpp
+++ b/GUI/coregui/DataLoaders/QREDataLoaderProperties.cpp
@@ -62,27 +62,11 @@ double QREDataLoaderProperties::factor(int dataType) const
     return spinBox->isVisible() ? spinBox->value() : 1.0;
 }
 
-void QREDataLoaderProperties::updateEnabling(int dataType, bool enabled)
-{
-    const int lineInLayout = dataType;
-    for (int col = 1; col < m_ui->gridLayout->columnCount(); col++) {
-        auto layoutItem = m_ui->gridLayout->itemAtPosition(lineInLayout, col);
-        if (layoutItem) {
-            QWidget* w = layoutItem->widget();
-            if (w) {
-                const bool belongsToUnusedCombo =
-                    (dataType != 0) && (col >= 5); // no unit except for Q
-                w->setVisible(enabled && !belongsToUnusedCombo);
-            }
-        }
-    }
-}
-
 void QREDataLoaderProperties::updateErrorEnabling(bool enabled)
 {
     const int lineInLayout = 2;
 
-    for (int col = 1; col < m_ui->gridLayout->columnCount(); col++) {
+    for (int col = 2; col < m_ui->gridLayout->columnCount(); col++) {
         auto layoutItem = m_ui->gridLayout->itemAtPosition(lineInLayout, col);
         if (layoutItem) {
             QWidget* w = layoutItem->widget();
@@ -106,7 +90,8 @@ void QREDataLoaderProperties::onErrorEnablingChanged()
 QSpinBox* QREDataLoaderProperties::columnSpinBox(int dataType) const
 {
     const int lineInLayout = dataType;
-    return dynamic_cast<QSpinBox*>(m_ui->gridLayout->itemAtPosition(lineInLayout, 2)->widget());
+    return dynamic_cast<QSpinBox*>(
+        m_ui->gridLayout->itemAtPosition(lineInLayout, columnColumn)->widget());
 }
 
 QDoubleSpinBox* QREDataLoaderProperties::factorSpinBox(int dataType) const
diff --git a/GUI/coregui/DataLoaders/QREDataLoaderProperties.h b/GUI/coregui/DataLoaders/QREDataLoaderProperties.h
index 471560a466bf03dac8eec21f26875e08e76d613c..68dd2256d1a5ea0b9326e90dae30f7ce187c26b3 100644
--- a/GUI/coregui/DataLoaders/QREDataLoaderProperties.h
+++ b/GUI/coregui/DataLoaders/QREDataLoaderProperties.h
@@ -45,7 +45,6 @@ signals:
     void propertiesChanged();
 
 private:
-    void updateEnabling(int dataType, bool enabled);
     void updateErrorEnabling(bool enabled);
     void onErrorEnablingChanged();
     QLabel* factorLabel(int dataType) const;
@@ -54,7 +53,8 @@ private:
     // they are only deactivated. Call allowFactors(true) to enable them.
     bool m_allowFactors;
 
-    static const int factorLabelColumn = 3;
+    static const int columnColumn = 3;
+    static const int factorLabelColumn = 4;
     static const int factorColumn = factorLabelColumn + 1;
 };
 
diff --git a/GUI/coregui/DataLoaders/QREDataLoaderProperties.ui b/GUI/coregui/DataLoaders/QREDataLoaderProperties.ui
index 68f0538cba995cc733ca7bd15f2adb6fd7ad101c..881462bb4eb1b0af578cf550a020f3115cbe95b1 100644
--- a/GUI/coregui/DataLoaders/QREDataLoaderProperties.ui
+++ b/GUI/coregui/DataLoaders/QREDataLoaderProperties.ui
@@ -150,70 +150,62 @@
       </item>
       <item>
        <layout class="QGridLayout" name="gridLayout">
-        <item row="2" column="0">
-         <widget class="QCheckBox" name="enableErrorCheckBox">
-          <property name="text">
-           <string>Read error</string>
-          </property>
-         </widget>
-        </item>
-        <item row="1" column="4">
-         <widget class="QDoubleSpinBox" name="factorSpinBox4_5">
-          <property name="value">
-           <double>1.000000000000000</double>
-          </property>
-         </widget>
-        </item>
-        <item row="0" column="1">
-         <widget class="QLabel" name="label_5">
-          <property name="text">
-           <string>from column</string>
-          </property>
-         </widget>
-        </item>
-        <item row="1" column="2">
-         <widget class="QSpinBox" name="spinBox_2">
+        <item row="0" column="3">
+         <widget class="QSpinBox" name="spinBox">
           <property name="minimum">
            <number>1</number>
           </property>
          </widget>
         </item>
-        <item row="0" column="2">
-         <widget class="QSpinBox" name="spinBox">
+        <item row="2" column="3">
+         <widget class="QSpinBox" name="spinBox_3">
           <property name="minimum">
            <number>1</number>
           </property>
          </widget>
         </item>
-        <item row="2" column="1">
-         <widget class="QLabel" name="label_10">
+        <item row="0" column="10">
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item row="0" column="1">
+         <widget class="QLabel" name="label">
           <property name="text">
-           <string>from column</string>
+           <string>Read Q</string>
           </property>
          </widget>
         </item>
-        <item row="0" column="5">
-         <widget class="QLabel" name="unitLabel4_2">
+        <item row="0" column="2">
+         <widget class="QLabel" name="label_5">
           <property name="text">
-           <string>given values are in</string>
+           <string>from column</string>
           </property>
          </widget>
         </item>
-        <item row="2" column="3">
+        <item row="2" column="4">
          <widget class="QLabel" name="factorLabel4_8">
           <property name="text">
            <string>multiplied by</string>
           </property>
          </widget>
         </item>
-        <item row="1" column="1">
-         <widget class="QLabel" name="label_6">
-          <property name="text">
-           <string>from column</string>
+        <item row="0" column="5">
+         <widget class="QDoubleSpinBox" name="factorSpinBox4_2">
+          <property name="value">
+           <double>1.000000000000000</double>
           </property>
          </widget>
         </item>
-        <item row="0" column="6">
+        <item row="0" column="7">
          <widget class="QComboBox" name="qUnitCombo">
           <item>
            <property name="text">
@@ -227,65 +219,106 @@
           </item>
          </widget>
         </item>
-        <item row="1" column="3">
-         <widget class="QLabel" name="factorLabel4_7">
-          <property name="text">
-           <string>multiplied by</string>
+        <item row="1" column="5">
+         <widget class="QDoubleSpinBox" name="factorSpinBox4_5">
+          <property name="value">
+           <double>1.000000000000000</double>
           </property>
          </widget>
         </item>
-        <item row="0" column="9">
-         <spacer name="horizontalSpacer_2">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
+        <item row="2" column="2">
+         <widget class="QLabel" name="label_10">
+          <property name="text">
+           <string>from column</string>
           </property>
-         </spacer>
+         </widget>
         </item>
-        <item row="0" column="3">
-         <widget class="QLabel" name="factorLabel4_2">
+        <item row="1" column="4">
+         <widget class="QLabel" name="factorLabel4_7">
           <property name="text">
            <string>multiplied by</string>
           </property>
          </widget>
         </item>
-        <item row="0" column="4">
-         <widget class="QDoubleSpinBox" name="factorSpinBox4_2">
+        <item row="2" column="5">
+         <widget class="QDoubleSpinBox" name="factorSpinBox4_6">
           <property name="value">
            <double>1.000000000000000</double>
           </property>
          </widget>
         </item>
-        <item row="2" column="2">
-         <widget class="QSpinBox" name="spinBox_3">
+        <item row="1" column="3">
+         <widget class="QSpinBox" name="spinBox_2">
           <property name="minimum">
            <number>1</number>
           </property>
          </widget>
         </item>
-        <item row="2" column="4">
-         <widget class="QDoubleSpinBox" name="factorSpinBox4_6">
-          <property name="value">
-           <double>1.000000000000000</double>
+        <item row="0" column="6">
+         <widget class="QLabel" name="unitLabel4_2">
+          <property name="text">
+           <string>given values are in</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1">
+         <widget class="QLabel" name="label_7">
+          <property name="text">
+           <string>Read R</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="4">
+         <widget class="QLabel" name="factorLabel4_2">
+          <property name="text">
+           <string>multiplied by</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="2">
+         <widget class="QLabel" name="label_6">
+          <property name="text">
+           <string>from column</string>
           </property>
          </widget>
         </item>
         <item row="0" column="0">
-         <widget class="QLabel" name="label">
+         <widget class="QCheckBox" name="checkBox">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
           <property name="text">
-           <string>Read Q</string>
+           <string/>
+          </property>
+          <property name="checked">
+           <bool>true</bool>
           </property>
          </widget>
         </item>
         <item row="1" column="0">
-         <widget class="QLabel" name="label_7">
+         <widget class="QCheckBox" name="checkBox_2">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
           <property name="text">
-           <string>Read R</string>
+           <string/>
+          </property>
+          <property name="checked">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="0">
+         <widget class="QCheckBox" name="enableErrorCheckBox">
+          <property name="text">
+           <string/>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1">
+         <widget class="QLabel" name="label_8">
+          <property name="text">
+           <string>Read error</string>
           </property>
          </widget>
         </item>
diff --git a/GUI/coregui/DataLoaders/UserDefinedDataLoader1D.cpp b/GUI/coregui/DataLoaders/UserDefinedDataLoader1D.cpp
index 465365c68c435f2bfd2719672473a875bb78b176..06cfba4109d64e29ad4be13ba5ca6e523cc25c21 100644
--- a/GUI/coregui/DataLoaders/UserDefinedDataLoader1D.cpp
+++ b/GUI/coregui/DataLoaders/UserDefinedDataLoader1D.cpp
@@ -69,3 +69,9 @@ AbstractDataLoader* UserDefinedDataLoader1D::clone() const
     auto loader = new UserDefinedDataLoader1D(cloned, m_name, m_defaultProperties);
     return loader;
 }
+
+void UserDefinedDataLoader1D::importFile(const QString& filename, RealDataItem* item,
+                                         QStringList* errors, QStringList* warnings) const
+{
+    m_wrappedLoader->importFile(filename, item, errors, warnings);
+}
diff --git a/GUI/coregui/DataLoaders/UserDefinedDataLoader1D.h b/GUI/coregui/DataLoaders/UserDefinedDataLoader1D.h
index 5a79013497b3199ca347807186bbd047a24be9ec..ec4f4459b5c9cd8c0007bbec9d32e726a5342af1 100644
--- a/GUI/coregui/DataLoaders/UserDefinedDataLoader1D.h
+++ b/GUI/coregui/DataLoaders/UserDefinedDataLoader1D.h
@@ -31,6 +31,8 @@ public:
     virtual void deserialize(const QByteArray& data) override;
     virtual QString preview(const QString& filepath, QCustomPlot* plotWidget) const override;
     virtual AbstractDataLoader* clone() const override;
+    virtual void importFile(const QString& filename, RealDataItem* item, QStringList* errors,
+                            QStringList* warnings) const override;
 
 private:
     QString m_name;