rendered paste body/*************************************************************************** * Copyright (C) 2005 by Adam Higerd * * ahigerd@stratitec.com * * * * 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 of the License, or * * (at your option) any later version. * * * * 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, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/#include "csvmodel.h"#include <QFile>#include <QDebug>CSVModel::CSVModel(QObject *parent) : QAbstractTableModel(parent){ csvFile = 0; maxColumn = 0;}CSVModel::CSVModel(QIODevice *file, QObject *parent, bool withHeader, QChar separator) : QAbstractTableModel(parent){ setSource(file, withHeader, separator);}CSVModel::CSVModel(const QString filename, QObject *parent, bool withHeader, QChar separator) : QAbstractTableModel(parent){ setSource(new QFile(filename, this), withHeader, separator);}CSVModel::~CSVModel(){}int CSVModel::rowCount(const QModelIndex& parent) const{ if(parent.row()!=-1 && parent.column()!=-1) return 0; return csvData.count();}int CSVModel::columnCount(const QModelIndex& parent) const{ if(parent.row()!=-1 && parent.column()!=-1) return 0; return maxColumn;}QVariant CSVModel::data(const QModelIndex& index, int role) const{ if(index.parent()!=QModelIndex()) return QVariant(); if(role==Qt::DisplayRole || role==Qt::EditRole || role==Qt::UserRole) return csvData[index.row()].section(QChar(1),index.column(),index.column()); else { //QVariant v; return QVariant(); }}QVariant CSVModel::headerData(int section, Qt::Orientation orientation, int role) const{ if(section < header.count() && orientation==Qt::Horizontal && (role==Qt::DisplayRole || role==Qt::EditRole || role==Qt::UserRole)) { if(section >= header.count()) return ""; return header[section]; } else return QAbstractTableModel::headerData(section, orientation, role);}void CSVModel::setSource(const QString filename, bool withHeader, QChar separator){ setSource(new QFile(filename), withHeader, separator);}void CSVModel::setSource(QIODevice *file, bool withHeader, QChar separator){ QString l; int size; bool isQuoted, headerSet = false; file->open(QIODevice::ReadOnly); if(withHeader) maxColumn = 0; else maxColumn = header.size(); csvData.clear(); while(!file->atEnd()) { l = file->readLine(); l.replace(QChar('\n'),""); l.replace(QChar('\r'),""); size = l.length(); isQuoted = false; for(int i=0;i<size;i++) { if(i>0) { if(l[i]=='"' && l[i-1]!='\\') isQuoted=!isQuoted; else if(!isQuoted && l[i]==separator) l[i]=QChar(1); } else { if(l[i]=='"') isQuoted=!isQuoted; else if(!isQuoted && l[i]==separator) l[i]=QChar(1); } } if(l.count(QChar(1))+1 > maxColumn) maxColumn = l.count(QChar(1))+1; if(withHeader && !headerSet) { header = l.split(QChar(1)); headerSet=true; } else csvData.append(l); } file->close();}void CSVModel::setHeaderData(const QStringList data){ header = data; emit headerDataChanged(Qt::Horizontal, 0, data.count());}bool CSVModel::setData(const QModelIndex& index, const QVariant& data, int role){ if(index.parent()!=QModelIndex()) return false; QString before, after; if(role==Qt::DisplayRole || role==Qt::EditRole || role==Qt::UserRole) { if(index.row()>=rowCount() || index.column()>=columnCount() || index.row()<0 || index.column()<0) return false; if(index.column()!=0) before = csvData[index.row()].section(QChar(1),0,index.column()-1) + QChar(1); else before = ""; after = csvData[index.row()].section(QChar(1),index.column()+1); csvData[index.row()] = before + data.toString() + QChar(1) + after; emit dataChanged(index, index); return true; } else { return false; }}bool CSVModel::insertRow(int row, const QModelIndex& parent){ return insertRows(row, 1, parent);}bool CSVModel::insertRows(int row, int count, const QModelIndex& parent){ if(parent!=QModelIndex() || row<0) return false; emit beginInsertRows(parent, row, row+count); if(row>=rowCount()) { for(int i=0;i<count;i++) csvData << ""; } else { for(int i=0;i<count;i++) csvData.insert(row, ""); } emit endInsertRows(); return true;}bool CSVModel::removeRow(int row, const QModelIndex& parent){ return removeRows(row, 1, parent);}bool CSVModel::removeRows(int row, int count, const QModelIndex& parent){ if(parent!=QModelIndex() || row<0) return false; if(row>=rowCount()) return false; if(row+count>=rowCount()) count = rowCount()-row; emit beginRemoveRows(parent, row, row+count); for(int i=0;i<count;i++) csvData.removeAt(row); emit endRemoveRows(); return true;}bool CSVModel::insertColumn(int col, const QModelIndex& parent){ return insertColumns(col, 1, parent);}bool CSVModel::insertColumns(int col, int count, const QModelIndex& parent){ if(parent!=QModelIndex() || col<0) return false; emit beginInsertColumns(parent, col, col+count); if(col<columnCount()) { QString before, after; for(int i=0;i<rowCount();i++) { if(col>0) before = csvData[i].section(QChar(1),0,col-1)+QChar(1); else before = ""; after = csvData[i].section(QChar(1),col); csvData[i] = before + QString(count, QChar(1)) + after; } } for(int i=0;i<count;i++) header.insert(col,""); maxColumn+=count; emit endInsertColumns(); return true;}bool CSVModel::removeColumn(int col, const QModelIndex& parent){ return removeColumns(col, 1, parent);}bool CSVModel::removeColumns(int col, int count, const QModelIndex& parent){ if(parent!=QModelIndex() || col<0) return false; if(col>=columnCount()) return false; if(col+count>=columnCount()) count = columnCount()-col; emit beginRemoveColumns(parent, col, col+count); QString before, after; for(int i=0;i<rowCount();i++) { if(col>0) before = csvData[i].section(QChar(1),0,col-1)+QChar(1); else before = ""; after = csvData[i].section(QChar(1),col+count); csvData[i] = before + after; } for(int i=0;i<count;i++) header.removeAt(col); emit endRemoveColumns(); return true;}void CSVModel::toCSV(QIODevice* dest, bool withHeader, QChar separator){ int row, col, rows, cols; rows = rowCount(); cols = columnCount(); QString data; dest->open(QIODevice::WriteOnly | QIODevice::Truncate); if(withHeader) { data = ""; for(col = 0; col < cols; col++) { data += '"' + header.at(col) + '"'; if(col<cols-1) data += separator; } data += QChar(10); dest->write(data.toLatin1()); } for(row = 0; row < rows; row++) { data = ""; for(col = 0; col < cols; col++) { data += '"' + csvData[row].section(QChar(1),col,col) + '"'; if(col<cols-1) data += separator; } data += QChar(10); dest->write(data.toLatin1()); } dest->close();}void CSVModel::toCSV(const QString filename, bool withHeader, QChar separator){ toCSV(new QFile(filename, this), withHeader, separator);}Qt::ItemFlags CSVModel::flags(const QModelIndex& index) const{ return Qt::ItemIsEditable | QAbstractTableModel::flags(index);}