# HG changeset patch # User Andre Heinecke # Date 1427124806 -3600 # Node ID 7a2637c3eb839d446c9d315ca8eb572b3356210b # Parent 147b08bc7d64f5f9269bf74b98d4076fca3efcce Add csv parser from libqxt diff -r 147b08bc7d64 -r 7a2637c3eb83 src/CMakeLists.txt --- a/src/CMakeLists.txt Mon Mar 23 12:41:52 2015 +0100 +++ b/src/CMakeLists.txt Mon Mar 23 16:33:26 2015 +0100 @@ -7,6 +7,7 @@ include_directories(${Qt5Widgets_INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(libqxt) add_definitions(${Qt5Widgets_DEFINITIONS}) @@ -72,6 +73,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/l10n/main_de_DE.ts) endif() +add_subdirectory(libqxt) + add_executable(${PROJECT_NAME} ${_add_executable_params} # ${IMG_SRC} @@ -83,7 +86,9 @@ target_link_libraries(${PROJECT_NAME} Qt5::Widgets - ${EXTRA_STATIC_LIBS}) + ${EXTRA_STATIC_LIBS} + ${PROJECT_NAME}_libqxt +) if (WIN32) set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-municode") diff -r 147b08bc7d64 -r 7a2637c3eb83 src/libqxt/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libqxt/CMakeLists.txt Mon Mar 23 16:33:26 2015 +0100 @@ -0,0 +1,13 @@ +# Copyright (C) 2014 by Intevation GmbH +# +# This file is Free Software under the GNU GPL (v>=2) +# and comes with ABSOLUTELY NO WARRANTY! +# See LICENSE.txt for details. + +# Minimal CVS parser code from libqxt to avoid a big +# library dependency. +set (LIBQXT_SRC + qxtcsvmodel.cpp +) + +add_library(${PROJECT_NAME}_libqxt STATIC ${LIBQXT_SRC}) diff -r 147b08bc7d64 -r 7a2637c3eb83 src/libqxt/COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libqxt/COPYING Mon Mar 23 16:33:26 2015 +0100 @@ -0,0 +1,33 @@ +Code in this directory was taken from the libqxt project: + http://dev.libqxt.org/ +And is available under the following license: + +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** +*****************************************************************************/ diff -r 147b08bc7d64 -r 7a2637c3eb83 src/libqxt/qxtcsvmodel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libqxt/qxtcsvmodel.cpp Mon Mar 23 16:33:26 2015 +0100 @@ -0,0 +1,553 @@ + +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** +*****************************************************************************/ + +/*! +\class QxtCsvModel +\inmodule QxtCore +\brief The QxtCsvModel class provides a QAbstractTableModel for CSV Files + */ + + + +#include "qxtcsvmodel.h" +#include +#include +#include + +class QxtCsvModelPrivate : public QxtPrivate +{ +public: + QxtCsvModelPrivate() : csvData(), header(), maxColumn(0), quoteMode(QxtCsvModel::DefaultQuoteMode) + {} + QXT_DECLARE_PUBLIC(QxtCsvModel) + + QList csvData; + QStringList header; + int maxColumn; + QxtCsvModel::QuoteMode quoteMode; +}; + +/*! + Creates an empty QxtCsvModel with parent \a parent. + */ +QxtCsvModel::QxtCsvModel(QObject *parent) : QAbstractTableModel(parent) +{ + QXT_INIT_PRIVATE(QxtCsvModel); +} + +/*! + Creates a QxtCsvModel with the parent \a parent and content loaded from \a file. + + See \a setSource for information on the \a withHeader and \a separator properties, or + if you need control over the quoting method or codec used to parse the file. + + \sa setSource + */ +QxtCsvModel::QxtCsvModel(QIODevice *file, QObject *parent, bool withHeader, QChar separator) : QAbstractTableModel(parent) +{ + QXT_INIT_PRIVATE(QxtCsvModel); + setSource(file, withHeader, separator); +} + +/*! + \overload + + Creates a QxtCsvModel with the parent \a parent and content loaded from \a file. + + See \a setSource for information on the \a withHeader and \a separator properties, or + if you need control over the quoting method or codec used to parse the file. + + \sa setSource + */ +QxtCsvModel::QxtCsvModel(const QString filename, QObject *parent, bool withHeader, QChar separator) : QAbstractTableModel(parent) +{ + QXT_INIT_PRIVATE(QxtCsvModel); + QFile src(filename); + setSource(&src, withHeader, separator); +} + +QxtCsvModel::~QxtCsvModel() +{} + +/*! + \reimp + */ +int QxtCsvModel::rowCount(const QModelIndex& parent) const +{ + if (parent.row() != -1 && parent.column() != -1) return 0; + return qxt_d().csvData.count(); +} + +/*! + \reimp + */ +int QxtCsvModel::columnCount(const QModelIndex& parent) const +{ + if (parent.row() != -1 && parent.column() != -1) return 0; + return qxt_d().maxColumn; +} + +/*! + \reimp + */ +QVariant QxtCsvModel::data(const QModelIndex& index, int role) const +{ + if(index.parent() != QModelIndex()) return QVariant(); + if(role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) { + if(index.row() < 0 || index.column() < 0 || index.row() >= rowCount()) + return QVariant(); + const QStringList& row = qxt_d().csvData[index.row()]; + if(index.column() >= row.length()) + return QVariant(); + return row[index.column()]; + } + return QVariant(); +} + +/*! + \reimp + */ +QVariant QxtCsvModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(section < qxt_d().header.count() && orientation == Qt::Horizontal && (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole)) + return qxt_d().header[section]; + else + return QAbstractTableModel::headerData(section, orientation, role); +} + +/*! + \overload + + Reads in a CSV file from the provided \a file using \a codec. + */ +void QxtCsvModel::setSource(const QString filename, bool withHeader, QChar separator, QTextCodec* codec) +{ + QFile src(filename); + setSource(&src, withHeader, separator, codec); +} + +/*! + Reads in a CSV file from the provided \a file using \a codec. + + The value of \a separator will be used to delimit fields, subject to the specified \a quoteMode. + If \a withHeader is set to true, the first line of the file will be used to populate the model's + horizontal header. + + \sa quoteMode + */ +void QxtCsvModel::setSource(QIODevice *file, bool withHeader, QChar separator, QTextCodec* codec) +{ + QxtCsvModelPrivate* d_ptr = &qxt_d(); + bool headerSet = !withHeader; + if(!file->isOpen()) + file->open(QIODevice::ReadOnly); + if(withHeader) + d_ptr->maxColumn = 0; + else + d_ptr->maxColumn = d_ptr->header.size(); + d_ptr->csvData.clear(); + QStringList row; + QString field; + QChar quote; + QChar ch, buffer(0); + bool readCR = false; + QTextStream stream(file); + if(codec) { + stream.setCodec(codec); + } else { + stream.setAutoDetectUnicode(true); + } + while(!stream.atEnd()) { + if(buffer != QChar(0)) { + ch = buffer; + buffer = QChar(0); + } else { + stream >> ch; + } + if(ch == '\n' && readCR) + continue; + else if(ch == '\r') + readCR = true; + else + readCR = false; + if(ch != separator && (ch.category() == QChar::Separator_Line || ch.category() == QChar::Separator_Paragraph || ch.category() == QChar::Other_Control)) { + row << field; + field.clear(); + if(!row.isEmpty()) { + if(!headerSet) { + d_ptr->header = row; + headerSet = true; + } else { + d_ptr->csvData.append(row); + } + if(row.length() > d_ptr->maxColumn) { + d_ptr->maxColumn = row.length(); + } + } + row.clear(); + } else if((d_ptr->quoteMode & DoubleQuote && ch == '"') || (d_ptr->quoteMode & SingleQuote && ch == '\'')) { + quote = ch; + do { + stream >> ch; + if(ch == '\\' && d_ptr->quoteMode & BackslashEscape) { + stream >> ch; + } else if(ch == quote) { + if(d_ptr->quoteMode & TwoQuoteEscape) { + stream >> buffer; + if(buffer == quote) { + buffer = QChar(0); + field.append(ch); + continue; + } + } + break; + } + field.append(ch); + } while(!stream.atEnd()); + } else if(ch == separator) { + row << field; + field.clear(); + } else { + field.append(ch); + } + } + if(!field.isEmpty()) + row << field; + if(!row.isEmpty()) { + if(!headerSet) + d_ptr->header = row; + else + d_ptr->csvData.append(row); + } + file->close(); +} + +/*! + Sets the horizontal headers of the model to the values provided in \a data. + */ +void QxtCsvModel::setHeaderData(const QStringList& data) +{ + qxt_d().header = data; + emit headerDataChanged(Qt::Horizontal, 0, data.count()); +} + +/*! + \reimp + */ +bool QxtCsvModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role) +{ + if(orientation != Qt::Horizontal) return false; // We don't support the vertical header + if(role != Qt::DisplayRole || role != Qt::EditRole) return false; // We don't support any other roles + if(section < 0) return false; // Bogus input + while(section > qxt_d().header.size()) { + qxt_d().header << QString(); + } + qxt_d().header[section] = value.toString(); + emit headerDataChanged(Qt::Horizontal, section, section); + return true; +} + +/*! + \reimp + */ +bool QxtCsvModel::setData(const QModelIndex& index, const QVariant& data, int role) +{ + if (index.parent() != QModelIndex()) return false; + + 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; + QStringList& row = qxt_d().csvData[index.row()]; + while(row.length() <= index.column()) + row << QString(); + row[index.column()] = data.toString(); + emit dataChanged(index, index); + return true; + } + return false; +} + +/*! + \reimp + */ +bool QxtCsvModel::insertRow(int row, const QModelIndex& parent) +{ + return insertRows(row, 1, parent); +} + +/*! + \reimp + */ +bool QxtCsvModel::insertRows(int row, int count, const QModelIndex& parent) +{ + if (parent != QModelIndex() || row < 0) return false; + emit beginInsertRows(parent, row, row + count); + QxtCsvModelPrivate& d_ptr = qxt_d(); + if(row >= rowCount()) { + for(int i = 0; i < count; i++) d_ptr.csvData << QStringList(); + } else { + for(int i = 0; i < count; i++) d_ptr.csvData.insert(row, QStringList()); + } + emit endInsertRows(); + return true; +} + +/*! + \reimp + */ +bool QxtCsvModel::removeRow(int row, const QModelIndex& parent) +{ + return removeRows(row, 1, parent); +} + +/*! + \reimp + */ +bool QxtCsvModel::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); + QxtCsvModelPrivate& d_ptr = qxt_d(); + for (int i = 0;i < count;i++) + d_ptr.csvData.removeAt(row); + emit endRemoveRows(); + return true; +} + +/*! + \reimp + */ +bool QxtCsvModel::insertColumn(int col, const QModelIndex& parent) +{ + return insertColumns(col, 1, parent); +} + +/*! + \reimp + */ +bool QxtCsvModel::insertColumns(int col, int count, const QModelIndex& parent) +{ + if (parent != QModelIndex() || col < 0) return false; + beginInsertColumns(parent, col, col + count - 1); + QxtCsvModelPrivate& d_ptr = qxt_d(); + for(int i = 0; i < rowCount(); i++) { + QStringList& row = d_ptr.csvData[i]; + while(col >= row.length()) row.append(QString()); + for(int j = 0; j < count; j++) { + row.insert(col, QString()); + } + } + for(int i = 0; i < count ;i++) + d_ptr.header.insert(col, QString()); + d_ptr.maxColumn += count; + endInsertColumns(); + return true; +} + +/*! + \reimp + */ +bool QxtCsvModel::removeColumn(int col, const QModelIndex& parent) +{ + return removeColumns(col, 1, parent); +} + +/*! + \reimp + */ +bool QxtCsvModel::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); + QxtCsvModelPrivate& d_ptr = qxt_d(); + QString before, after; + for(int i = 0; i < rowCount(); i++) { + for(int j = 0; j < count; j++) { + d_ptr.csvData[i].removeAt(col); + } + } + for(int i = 0; i < count; i++) + d_ptr.header.removeAt(col); + emit endRemoveColumns(); + return true; +} + +static QString qxt_addCsvQuotes(QxtCsvModel::QuoteMode mode, QString field) +{ + bool addDoubleQuotes = ((mode & QxtCsvModel::DoubleQuote) && field.contains('"')); + bool addSingleQuotes = ((mode & QxtCsvModel::SingleQuote) && field.contains('\'')); + bool quoteField = (mode & QxtCsvModel::AlwaysQuoteOutput) || addDoubleQuotes || addSingleQuotes; + if(quoteField && !addDoubleQuotes && !addSingleQuotes) { + if(mode & QxtCsvModel::DoubleQuote) + addDoubleQuotes = true; + else if(mode & QxtCsvModel::SingleQuote) + addSingleQuotes = true; + } + if(mode & QxtCsvModel::BackslashEscape) { + if(addDoubleQuotes) + return '"' + field.replace("\\", "\\\\").replace("\"", "\\\"") + '"'; + if(addSingleQuotes) + return '\'' + field.replace("\\", "\\\\").replace("'", "\\'") + '\''; + } else { + if(addDoubleQuotes) + return '"' + field.replace("\"", "\"\"") + '"'; + if(addSingleQuotes) + return '\'' + field.replace("'", "''") + '\''; + } + return field; +} + +/*! + Outputs the content of the model as a CSV file to the device \a dest using \a codec. + + Fields in the output file will be separated by \a separator. Set \a withHeader to true + to output a row of headers at the top of the file. + */ +void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QTextCodec* codec) const +{ + const QxtCsvModelPrivate& d_ptr = qxt_d(); + int row, col, rows, cols; + rows = rowCount(); + cols = columnCount(); + QString data; + if(!dest->isOpen()) dest->open(QIODevice::WriteOnly | QIODevice::Truncate); + QTextStream stream(dest); + if(codec) stream.setCodec(codec); + if(withHeader) { + data = ""; + for(col = 0; col < cols; ++col) { + if(col > 0) data += separator; + data += qxt_addCsvQuotes(d_ptr.quoteMode, d_ptr.header.at(col)); + } + stream << data << endl; + } + for(row = 0; row < rows; ++row) + { + const QStringList& rowData = d_ptr.csvData[row]; + data = ""; + for(col = 0; col < cols; ++col) { + if(col > 0) data += separator; + if(col < rowData.length()) + data += qxt_addCsvQuotes(d_ptr.quoteMode, rowData.at(col)); + else + data += qxt_addCsvQuotes(d_ptr.quoteMode, QString());; + } + stream << data << endl; + } + stream << flush; + dest->close(); +} + +/*! + \overload + + Outputs the content of the model as a CSV file to the file specified by \a filename using \a codec. + + Fields in the output file will be separated by \a separator. Set \a withHeader to true + to output a row of headers at the top of the file. + */ +void QxtCsvModel::toCSV(const QString filename, bool withHeader, QChar separator, QTextCodec* codec) const +{ + QFile dest(filename); + toCSV(&dest, withHeader, separator, codec); +} + +/*! + \reimp + */ +Qt::ItemFlags QxtCsvModel::flags(const QModelIndex& index) const +{ + return Qt::ItemIsEditable | QAbstractTableModel::flags(index); +} + +/*! + * Returns the current quoting mode. + * \sa setQuoteMode + */ +QxtCsvModel::QuoteMode QxtCsvModel::quoteMode() const +{ + return qxt_d().quoteMode; +} + +/*! + * Sets the current quoting mode. The default quoting mode is BothQuotes | BackslashEscape. + * + * The quoting mode determines what kinds of quoting is used for reading and writing CSV files. + * \sa quoteMode + * \sa QuoteOption + */ +void QxtCsvModel::setQuoteMode(QuoteMode mode) +{ + qxt_d().quoteMode = mode; +} + +/*! + Sets the content of the cell at row \a row and column \a column to \a value. + + \sa text + */ +void QxtCsvModel::setText(int row, int column, const QString& value) +{ + setData(index(row, column), value); +} + +/*! + Fetches the content of the cell at row \a row and column \a column. + + \sa setText + */ +QString QxtCsvModel::text(int row, int column) const +{ + return data(index(row, column)).toString(); +} + +/*! + Sets the content of the header for column \a column to \a value. + + \sa headerText + */ +void QxtCsvModel::setHeaderText(int column, const QString& value) +{ + setHeaderData(column, Qt::Horizontal, value); +} + +/*! + Fetches the content of the cell at row \a row and column \a column. + + \sa setText + */ +QString QxtCsvModel::headerText(int column) const +{ + return headerData(column, Qt::Horizontal).toString(); +} diff -r 147b08bc7d64 -r 7a2637c3eb83 src/libqxt/qxtcsvmodel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libqxt/qxtcsvmodel.h Mon Mar 23 16:33:26 2015 +0100 @@ -0,0 +1,96 @@ +#ifndef QXTCSVMODEL_H +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** +*****************************************************************************/ + +#define QXTCSVMODEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +class QTextCodec; + +class QxtCsvModelPrivate; +class QXT_CORE_EXPORT QxtCsvModel : public QAbstractTableModel +{ + Q_OBJECT +public: + QxtCsvModel(QObject *parent = 0); + explicit QxtCsvModel(QIODevice *file, QObject *parent = 0, bool withHeader = false, QChar separator = ','); + explicit QxtCsvModel(const QString filename, QObject *parent = 0, bool withHeader = false, QChar separator = ','); + ~QxtCsvModel(); + + int rowCount(const QModelIndex& parent = QModelIndex()) const; + int columnCount(const QModelIndex& parent = QModelIndex()) const; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex& index, const QVariant& data, int role = Qt::EditRole); + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + bool setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role = Qt::DisplayRole); + void setHeaderData(const QStringList& data); + QString text(int row, int column) const; + void setText(int row, int column, const QString& value); + QString headerText(int column) const; + void setHeaderText(int column, const QString& value); + + + bool insertRow(int row, const QModelIndex& parent = QModelIndex()); + bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()); + bool removeRow(int row, const QModelIndex& parent = QModelIndex()); + bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()); + bool insertColumn(int col, const QModelIndex& parent = QModelIndex()); + bool insertColumns(int col, int count, const QModelIndex& parent = QModelIndex()); + bool removeColumn(int col, const QModelIndex& parent = QModelIndex()); + bool removeColumns(int col, int count, const QModelIndex& parent = QModelIndex()); + + void setSource(QIODevice *file, bool withHeader = false, QChar separator = ',', QTextCodec* codec = 0); + void setSource(const QString filename, bool withHeader = false, QChar separator = ',', QTextCodec* codec = 0); + + void toCSV(QIODevice *file, bool withHeader = false, QChar separator = ',', QTextCodec* codec = 0) const; + void toCSV(const QString filename, bool withHeader = false, QChar separator = ',', QTextCodec* codec = 0) const; + + enum QuoteOption { NoQuotes = 0, SingleQuote = 1, DoubleQuote = 2, BothQuotes = 3, + NoEscape = 0, TwoQuoteEscape = 4, BackslashEscape = 8, + AlwaysQuoteOutput = 16, DefaultQuoteMode = BothQuotes | BackslashEscape | AlwaysQuoteOutput }; + Q_DECLARE_FLAGS(QuoteMode, QuoteOption) + QuoteMode quoteMode() const; + void setQuoteMode(QuoteMode mode); + + Qt::ItemFlags flags(const QModelIndex& index) const; + +private: + QXT_DECLARE_PRIVATE(QxtCsvModel) +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QxtCsvModel::QuoteMode) + +#endif diff -r 147b08bc7d64 -r 7a2637c3eb83 src/libqxt/qxtglobal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libqxt/qxtglobal.h Mon Mar 23 16:33:26 2015 +0100 @@ -0,0 +1,233 @@ + +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** +*****************************************************************************/ + +#ifndef QXTGLOBAL_H +#define QXTGLOBAL_H + +#include + +#define QXT_VERSION 0x000700 +#define QXT_VERSION_STR "0.7.0" + +//--------------------------global macros------------------------------ + +#ifndef QXT_NO_MACROS + +#ifndef _countof +#define _countof(x) (sizeof(x)/sizeof(*x)) +#endif + +#endif // QXT_NO_MACROS + +//--------------------------export macros------------------------------ + +#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE + +#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) +# if defined(BUILD_QXT_CORE) +# define QXT_CORE_EXPORT Q_DECL_EXPORT +# else +# define QXT_CORE_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_CORE_EXPORT +#endif // BUILD_QXT_CORE + +#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) +# if defined(BUILD_QXT_GUI) +# define QXT_GUI_EXPORT Q_DECL_EXPORT +# else +# define QXT_GUI_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_GUI_EXPORT +#endif // BUILD_QXT_GUI + +#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) +# if defined(BUILD_QXT_NETWORK) +# define QXT_NETWORK_EXPORT Q_DECL_EXPORT +# else +# define QXT_NETWORK_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_NETWORK_EXPORT +#endif // BUILD_QXT_NETWORK + +#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) +# if defined(BUILD_QXT_SQL) +# define QXT_SQL_EXPORT Q_DECL_EXPORT +# else +# define QXT_SQL_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_SQL_EXPORT +#endif // BUILD_QXT_SQL + +#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) +# if defined(BUILD_QXT_WEB) +# define QXT_WEB_EXPORT Q_DECL_EXPORT +# else +# define QXT_WEB_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_WEB_EXPORT +#endif // BUILD_QXT_WEB + +#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) +# if defined(BUILD_QXT_BERKELEY) +# define QXT_BERKELEY_EXPORT Q_DECL_EXPORT +# else +# define QXT_BERKELEY_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_BERKELEY_EXPORT +#endif // BUILD_QXT_BERKELEY + +#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) +# if defined(BUILD_QXT_ZEROCONF) +# define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT +# else +# define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_ZEROCONF_EXPORT +#endif // QXT_ZEROCONF_EXPORT + +#if defined(BUILD_QXT_CORE) || defined(BUILD_QXT_GUI) || defined(BUILD_QXT_SQL) || defined(BUILD_QXT_NETWORK) || defined(BUILD_QXT_WEB) || defined(BUILD_QXT_BERKELEY) || defined(BUILD_QXT_ZEROCONF) +# define BUILD_QXT +#endif + +QXT_CORE_EXPORT const char* qxtVersion(); + +#ifndef QT_BEGIN_NAMESPACE +#define QT_BEGIN_NAMESPACE +#endif + +#ifndef QT_END_NAMESPACE +#define QT_END_NAMESPACE +#endif + +#ifndef QT_FORWARD_DECLARE_CLASS +#define QT_FORWARD_DECLARE_CLASS(Class) class Class; +#endif + +/**************************************************************************** +** This file is derived from code bearing the following notice: +** The sole author of this file, Adam Higerd, has explicitly disclaimed all +** copyright interest and protection for the content within. This file has +** been placed in the public domain according to United States copyright +** statute and case law. In jurisdictions where this public domain dedication +** is not legally recognized, anyone who receives a copy of this file is +** permitted to use, modify, duplicate, and redistribute this file, in whole +** or in part, with no restrictions or conditions. In these jurisdictions, +** this file shall be copyright (C) 2006-2008 by Adam Higerd. +****************************************************************************/ + +#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface qxt_d; +#define QXT_DECLARE_PUBLIC(PUB) friend class PUB; +#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this); +#define QXT_D(PUB) PUB##Private& d = qxt_d() +#define QXT_P(PUB) PUB& p = qxt_p() + +template +class QxtPrivate +{ +public: + virtual ~QxtPrivate() + {} + inline void QXT_setPublic(PUB* pub) + { + qxt_p_ptr = pub; + } + +protected: + inline PUB& qxt_p() + { + return *qxt_p_ptr; + } + inline const PUB& qxt_p() const + { + return *qxt_p_ptr; + } + inline PUB* qxt_ptr() + { + return qxt_p_ptr; + } + inline const PUB* qxt_ptr() const + { + return qxt_p_ptr; + } + +private: + PUB* qxt_p_ptr; +}; + +template +class QxtPrivateInterface +{ + friend class QxtPrivate; +public: + QxtPrivateInterface() + { + pvt = new PVT; + } + ~QxtPrivateInterface() + { + delete pvt; + } + + inline void setPublic(PUB* pub) + { + pvt->QXT_setPublic(pub); + } + inline PVT& operator()() + { + return *static_cast(pvt); + } + inline const PVT& operator()() const + { + return *static_cast(pvt); + } + inline PVT * operator->() + { + return static_cast(pvt); + } + inline const PVT * operator->() const + { + return static_cast(pvt); + } +private: + QxtPrivateInterface(const QxtPrivateInterface&) { } + QxtPrivateInterface& operator=(const QxtPrivateInterface&) { } + QxtPrivate* pvt; +}; + +#endif // QXT_GLOBAL