/* * Copyright (C) 2016 Enrico Mariotti * Copyright (C) 2017 KeePassXC Team * * This program 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 2 or (at your option) * version 3 of the License. * * This program 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "CsvParserModel.h" #include "core/Tools.h" #include "format/CsvParser.h" #include CsvParserModel::CsvParserModel(QObject* parent) : QAbstractTableModel(parent) , m_parser(new CsvParser()) , m_skipped(0) { } CsvParserModel::~CsvParserModel() { } CsvParser* CsvParserModel::parser() { return m_parser; } void CsvParserModel::setFilename(const QString& filename) { m_filename = filename; } QString CsvParserModel::getFileInfo() { return QString("%1, %2, %3") .arg(Tools::humanReadableFileSize(m_parser->getFileSize()), tr("%n row(s)", "CSV row count", m_parser->getCsvRows()), tr("%n column(s)", "CSV column count", qMax(0, m_parser->getCsvCols() - 1))); } bool CsvParserModel::parse() { bool r; beginResetModel(); m_columnMap.clear(); if (m_parser->isFileLoaded()) { r = m_parser->reparse(); } else { QFile csv(m_filename); r = m_parser->parse(&csv); } for (int i = 0; i < columnCount(); ++i) { m_columnMap.insert(i, 0); } endResetModel(); return r; } void CsvParserModel::mapColumns(int csvColumn, int dbColumn) { if (dbColumn < 0 || dbColumn >= m_columnMap.size()) { return; } beginResetModel(); if (csvColumn < 0 || csvColumn >= m_parser->getCsvCols()) { // This indicates a blank cell m_columnMap[dbColumn] = -1; } else { m_columnMap[dbColumn] = csvColumn; } endResetModel(); } void CsvParserModel::setSkippedRows(int skipped) { m_skipped = skipped; QModelIndex topLeft = createIndex(skipped, 0); QModelIndex bottomRight = createIndex(m_skipped + rowCount(), columnCount()); emit dataChanged(topLeft, bottomRight); emit layoutChanged(); } int CsvParserModel::skippedRows() const { return m_skipped; } void CsvParserModel::setHeaderLabels(const QStringList& labels) { m_columnHeader = labels; } int CsvParserModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { return 0; } return m_parser->getCsvRows(); } int CsvParserModel::columnCount(const QModelIndex& parent) const { if (parent.isValid()) { return 0; } return m_columnHeader.size(); } QVariant CsvParserModel::data(const QModelIndex& index, int role) const { if (index.column() >= m_columnHeader.size() || index.row() + m_skipped >= rowCount() || !index.isValid()) { return {}; } if (role == Qt::DisplayRole) { auto column = m_columnMap[index.column()]; if (column >= 0) { return m_parser->getCsvTable().at(index.row() + m_skipped).at(column); } } return QVariant(); } QVariant CsvParserModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole) { if (orientation == Qt::Horizontal) { if (section >= 0 && section < m_columnHeader.size()) { return m_columnHeader.at(section); } } else if (orientation == Qt::Vertical) { if (section + m_skipped < rowCount()) { return QString::number(section + 1); } } } return QVariant(); }