mirror of https://github.com/qt/qtdoc.git
117 lines
3.5 KiB
C++
117 lines
3.5 KiB
C++
// Copyright (C) 2025 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
#include "datamodel.h"
|
|
#include "internal/common.hpp"
|
|
#include <csv.hpp>
|
|
#include <QFileInfo>
|
|
#include <QtQml>
|
|
#include <qlogging.h>
|
|
#include <sstream>
|
|
#include <charconv>
|
|
#include <string_view>
|
|
|
|
DataModel::DataModel(QObject *parent) : QAbstractTableModel(parent) { }
|
|
|
|
DataModel::~DataModel() { }
|
|
|
|
int DataModel::columnCount(const QModelIndex &parent) const
|
|
{
|
|
return m_csvData.count() ? m_csvData.at(0).count() : 0;
|
|
}
|
|
|
|
|
|
QVariant DataModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (role == Qt::DisplayRole) {
|
|
if (index.row() < rowCount() && index.column() < columnCount())
|
|
return m_csvData.at(index.row()).at(index.column());
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
QVariant DataModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
{
|
|
if (role == Qt::DisplayRole) {
|
|
if (orientation == Qt::Horizontal) {
|
|
if (section < columnCount())
|
|
return m_csvData.at(0).at(section);
|
|
}
|
|
else if (orientation == Qt::Vertical) {
|
|
if (section < rowCount() && columnCount() > 0)
|
|
return m_csvData.at(section).at(0);
|
|
}
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
QHash<int, QByteArray> DataModel::roleNames() const
|
|
{
|
|
QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
|
|
roles[CustomRoles::Background] = "background";
|
|
return roles;
|
|
}
|
|
|
|
static int tryConvertToInt(std::string_view team, std::string_view fieldName, std::string field)
|
|
{
|
|
int value = -1;
|
|
auto [ptr, ec] = std::from_chars(field.data(), field.data() + field.size(), value);
|
|
if (value == -1)
|
|
qWarning("%s: error in %s field", team.data(), fieldName.data());
|
|
|
|
return value;
|
|
};
|
|
|
|
void DataModel::readCsv(const QUrl &csvFile)
|
|
{
|
|
QAbstractItemModel::beginResetModel();
|
|
|
|
const auto context = qmlContext(this);
|
|
const auto resolvedUrl = context ? context->resolvedUrl(csvFile) : csvFile;
|
|
|
|
QFile file(QQmlFile::urlToLocalFileOrQrc(resolvedUrl));
|
|
|
|
if (!file.open(QIODeviceBase::ReadOnly)) {
|
|
qWarning("Could not open %s for reading", qUtf8Printable(csvFile.toString()));
|
|
return;
|
|
}
|
|
|
|
m_csvData.clear();
|
|
std::stringstream ss(file.readAll().toStdString());
|
|
|
|
csv::CSVReader reader(ss);
|
|
auto headers = reader.get_col_names();
|
|
QList<QVariant> headersList;
|
|
headersList.resize(headers.size());
|
|
auto hIt = headersList.begin();
|
|
auto it = headers.begin();
|
|
while (it != headers.end()) {
|
|
*hIt = QString::fromStdString(*it);
|
|
++hIt;
|
|
++it;
|
|
}
|
|
|
|
if (headersList.count() > 0)
|
|
m_csvData.push_back(headersList);
|
|
|
|
for (const csv::CSVRow &csvRow : reader) {
|
|
csv::CSVField teamField = csvRow[headers.at(0)];
|
|
csv::CSVField goldField = csvRow[headers.at(1)];
|
|
csv::CSVField silverField = csvRow[headers.at(2)];
|
|
csv::CSVField bronzeField = csvRow[headers.at(3)];
|
|
csv::CSVField totalField = csvRow[headers.at(4)];
|
|
|
|
QList<QVariant> row;
|
|
row.resize(5);
|
|
auto team = teamField.get();
|
|
row[0] = QString::fromStdString(teamField.get());
|
|
row[1] = tryConvertToInt(team, headers.at(1), goldField.get());
|
|
row[2] = tryConvertToInt(team, headers.at(2), silverField.get());
|
|
row[3] = tryConvertToInt(team, headers.at(3), bronzeField.get());
|
|
row[4] = tryConvertToInt(team, headers.at(4), totalField.get());
|
|
m_csvData.push_back(row);
|
|
}
|
|
|
|
QAbstractItemModel::endResetModel();
|
|
}
|