• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kaddressbook

  • sources
  • kde-4.12
  • kdepim
  • kaddressbook
  • xxport
  • csv
qcsvmodel.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "qcsvmodel.h"
21 #include "qcsvmodel_p.h"
22 #include "qcsvreader.h"
23 
24 #include <QtCore/QMap>
25 #include <QtCore/QPair>
26 #include <QtCore/QStringList>
27 #include <QtCore/QVector>
28 
29 CsvParser::CsvParser( QObject *parent )
30  : QThread( parent ), mDevice( 0 ), mRowCount( 0 ), mColumnCount( 0 ), mCacheCounter( 0 )
31 {
32  mReader = new QCsvReader( this );
33 }
34 
35 CsvParser::~CsvParser()
36 {
37  delete mReader;
38 }
39 
40 void CsvParser::load( QIODevice *device )
41 {
42  mDevice = device;
43 
44  start();
45 }
46 
47 void CsvParser::begin()
48 {
49  mCacheCounter = 0;
50  mRowCount = 0;
51  mColumnCount = 0;
52 }
53 
54 void CsvParser::beginLine()
55 {
56  mRowCount++;
57 }
58 
59 void CsvParser::field( const QString &data, uint row, uint column )
60 {
61  const int tmp = qMax( mColumnCount, (int)column + 1 );
62  if ( tmp != mColumnCount ) {
63  mColumnCount = tmp;
64  emit columnCountChanged( tmp );
65  }
66 
67  emit dataChanged( data, row, column );
68 }
69 
70 void CsvParser::endLine()
71 {
72  mCacheCounter++;
73  if ( mCacheCounter == 50 ) {
74  emit rowCountChanged( mRowCount );
75  mCacheCounter = 0;
76  }
77 }
78 
79 void CsvParser::end()
80 {
81  emit rowCountChanged( mRowCount );
82  emit ended();
83 }
84 
85 void CsvParser::error( const QString & )
86 {
87 }
88 
89 void CsvParser::run()
90 {
91  if ( !mDevice->isOpen() ) {
92  mDevice->open( QIODevice::ReadOnly );
93  }
94 
95  mDevice->reset();
96  mReader->read( mDevice );
97 }
98 
99 class QCsvModel::Private
100 {
101  public:
102  Private( QCsvModel *model )
103  : mParent( model ), mParser( 0 ),
104  mDevice( 0 ), mRowCount( 0 ), mColumnCount( 0 )
105  {
106  }
107 
108  void columnCountChanged( int columns );
109  void rowCountChanged( int rows );
110  void fieldChanged( const QString &data, int row, int column );
111  void finishedLoading();
112 
113  QCsvModel *mParent;
114  CsvParser *mParser;
115  QVector<QString> mFieldIdentifiers;
116  QMap< QPair<int, int>, QString> mFields;
117  QIODevice *mDevice;
118 
119  int mRowCount;
120  int mColumnCount;
121 };
122 
123 void QCsvModel::Private::columnCountChanged( int columns )
124 {
125  mColumnCount = columns;
126  mFieldIdentifiers.resize( columns );
127  mFieldIdentifiers[ columns - 1 ] = QLatin1String( "0" );
128  emit mParent->layoutChanged();
129 }
130 
131 void QCsvModel::Private::rowCountChanged( int rows )
132 {
133  mRowCount = rows;
134  emit mParent->layoutChanged();
135 }
136 
137 void QCsvModel::Private::fieldChanged( const QString &data, int row, int column )
138 {
139  mFields.insert( QPair<int, int>( row, column ), data );
140 }
141 
142 void QCsvModel::Private::finishedLoading()
143 {
144  emit mParent->finishedLoading();
145 }
146 
147 QCsvModel::QCsvModel( QObject *parent )
148  : QAbstractTableModel( parent ), d( new Private( this ) )
149 {
150  d->mParser = new CsvParser( this );
151 
152  connect( d->mParser, SIGNAL(columnCountChanged(int)),
153  this, SLOT(columnCountChanged(int)), Qt::QueuedConnection );
154  connect( d->mParser, SIGNAL(rowCountChanged(int)),
155  this, SLOT(rowCountChanged(int)), Qt::QueuedConnection );
156  connect( d->mParser, SIGNAL(dataChanged(QString,int,int)),
157  this, SLOT(fieldChanged(QString,int,int)), Qt::QueuedConnection );
158  connect( d->mParser, SIGNAL(ended()), this, SLOT(finishedLoading()) );
159 }
160 
161 QCsvModel::~QCsvModel()
162 {
163  delete d;
164 }
165 
166 bool QCsvModel::load( QIODevice *device )
167 {
168  d->mDevice = device;
169  d->mRowCount = 0;
170  d->mColumnCount = 0;
171 
172  emit layoutChanged();
173 
174  d->mParser->load( device );
175 
176  return true;
177 }
178 
179 void QCsvModel::setTextQuote( const QChar &textQuote )
180 {
181  const bool isRunning = d->mParser->isRunning();
182 
183  if ( isRunning ) {
184  d->mParser->reader()->terminate();
185  d->mParser->wait();
186  }
187 
188  d->mParser->reader()->setTextQuote( textQuote );
189 
190  if ( isRunning ) {
191  load( d->mDevice );
192  }
193 }
194 
195 QChar QCsvModel::textQuote() const
196 {
197  return d->mParser->reader()->textQuote();
198 }
199 
200 void QCsvModel::setDelimiter( const QChar &delimiter )
201 {
202  const bool isRunning = d->mParser->isRunning();
203 
204  if ( isRunning ) {
205  d->mParser->reader()->terminate();
206  d->mParser->wait();
207  }
208 
209  d->mParser->reader()->setDelimiter( delimiter );
210 
211  if ( isRunning ) {
212  load( d->mDevice );
213  }
214 }
215 
216 QChar QCsvModel::delimiter() const
217 {
218  return d->mParser->reader()->delimiter();
219 }
220 
221 void QCsvModel::setStartRow( uint startRow )
222 {
223  const bool isRunning = d->mParser->isRunning();
224 
225  if ( isRunning ) {
226  d->mParser->reader()->terminate();
227  d->mParser->wait();
228  }
229 
230  d->mParser->reader()->setStartRow( startRow );
231 
232  if ( isRunning ) {
233  load( d->mDevice );
234  }
235 }
236 
237 uint QCsvModel::startRow() const
238 {
239  return d->mParser->reader()->startRow();
240 }
241 
242 void QCsvModel::setTextCodec( QTextCodec *textCodec )
243 {
244  const bool isRunning = d->mParser->isRunning();
245 
246  if ( isRunning ) {
247  d->mParser->reader()->terminate();
248  d->mParser->wait();
249  }
250 
251  d->mParser->reader()->setTextCodec( textCodec );
252 
253  if ( isRunning ) {
254  load( d->mDevice );
255  }
256 }
257 
258 QTextCodec *QCsvModel::textCodec() const
259 {
260  return d->mParser->reader()->textCodec();
261 }
262 
263 int QCsvModel::columnCount( const QModelIndex &parent ) const
264 {
265  if ( !parent.isValid() ) {
266  return d->mColumnCount;
267  } else {
268  return 0;
269  }
270 }
271 
272 int QCsvModel::rowCount( const QModelIndex &parent ) const
273 {
274  if ( !parent.isValid() ) {
275  return d->mRowCount + 1; // +1 for the header row
276  } else {
277  return 0;
278  }
279 }
280 
281 QVariant QCsvModel::data( const QModelIndex &index, int role ) const
282 {
283  if ( !index.isValid() ) {
284  return QVariant();
285  }
286 
287  if ( index.row() == 0 ) {
288  if ( index.column() >= d->mFieldIdentifiers.count() ) {
289  return QVariant();
290  }
291 
292  if ( role == Qt::DisplayRole || role == Qt::EditRole ) {
293  return d->mFieldIdentifiers.at( index.column() );
294  }
295 
296  return QVariant();
297  }
298 
299  const QPair<int, int> pair( index.row() - 1, index.column() );
300  if ( !d->mFields.contains( pair ) ) {
301  return QVariant();
302  }
303 
304  const QString data = d->mFields.value( pair );
305 
306  if ( role == Qt::DisplayRole ) {
307  return data;
308  } else {
309  return QVariant();
310  }
311 }
312 
313 bool QCsvModel::setData( const QModelIndex &index, const QVariant &data, int role )
314 {
315  if ( role == Qt::EditRole && index.row() == 0 &&
316  index.column() <= d->mFieldIdentifiers.count() ) {
317  d->mFieldIdentifiers[ index.column() ] = data.toString();
318 
319  emit dataChanged( index, index );
320  return true;
321  }
322 
323  return false;
324 }
325 
326 Qt::ItemFlags QCsvModel::flags( const QModelIndex &index ) const
327 {
328  Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
329  if ( index.row() == 0 ) {
330  flags |= Qt::ItemIsEditable;
331  }
332 
333  return flags;
334 }
335 
336 #include "qcsvmodel.moc"
337 #include "qcsvmodel_p.moc"
QCsvModel::delimiter
QChar delimiter() const
Returns the delimiter that is used as delimiter for fields.
Definition: qcsvmodel.cpp:216
QCsvModel::setTextCodec
void setTextCodec(QTextCodec *textCodec)
Sets the text codec that shall be used for parsing the csv list.
Definition: qcsvmodel.cpp:242
CsvParser::load
void load(QIODevice *device)
Definition: qcsvmodel.cpp:40
CsvParser::run
virtual void run()
Definition: qcsvmodel.cpp:89
QCsvModel::rowCount
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Inherited from QAbstractTableModel.
Definition: qcsvmodel.cpp:272
QCsvModel::setStartRow
void setStartRow(uint startRow)
Sets the row from where the parsing shall be started.
Definition: qcsvmodel.cpp:221
QCsvModel::setDelimiter
void setDelimiter(const QChar &delimiter)
Sets the character that is used as delimiter for fields.
Definition: qcsvmodel.cpp:200
CsvParser::rowCountChanged
void rowCountChanged(int rows)
QCsvModel::finishedLoading
void finishedLoading()
This signal is emitted whenever the model has loaded all data.
QCsvModel::data
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Inherited from QAbstractTableModel.
Definition: qcsvmodel.cpp:281
QCsvReader
A parser for comma separated value data.
Definition: qcsvreader.h:91
QObject
QCsvModel::load
bool load(QIODevice *device)
Loads the data from the device into the model.
Definition: qcsvmodel.cpp:166
QCsvModel::startRow
uint startRow() const
Returns the start row.
Definition: qcsvmodel.cpp:237
QCsvModel::~QCsvModel
~QCsvModel()
Destroys the csv model.
Definition: qcsvmodel.cpp:161
CsvParser::beginLine
void beginLine()
This method is called whenever a new line starts.
Definition: qcsvmodel.cpp:54
QCsvModel::flags
virtual Qt::ItemFlags flags(const QModelIndex &index) const
Inherited from QAbstractTableModel.
Definition: qcsvmodel.cpp:326
CsvParser::error
void error(const QString &errorMsg)
This method is called whenever an error occurs during parsing.
Definition: qcsvmodel.cpp:85
CsvParser::ended
void ended()
CsvParser::columnCountChanged
void columnCountChanged(int columns)
CsvParser::~CsvParser
~CsvParser()
Definition: qcsvmodel.cpp:35
QCsvModel::columnCount
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const
Inherited from QAbstractTableModel.
Definition: qcsvmodel.cpp:263
QCsvModel::QCsvModel
QCsvModel(QObject *parent)
Creates a new csv model.
Definition: qcsvmodel.cpp:147
qcsvreader.h
QCsvReader::read
bool read(QIODevice *device)
Parses the csv data from device.
Definition: qcsvreader.cpp:89
QCsvModel::textQuote
QChar textQuote() const
Returns the character that is used for quoting.
Definition: qcsvmodel.cpp:195
CsvParser::begin
void begin()
This method is called on start of the parsing.
Definition: qcsvmodel.cpp:47
CsvParser::field
void field(const QString &data, uint row, uint column)
This method is called for every parsed field.
Definition: qcsvmodel.cpp:59
CsvParser::CsvParser
CsvParser(QObject *parent)
Definition: qcsvmodel.cpp:29
QCsvModel::setTextQuote
void setTextQuote(const QChar &textQuote)
Sets the character that is used for quoting.
Definition: qcsvmodel.cpp:179
qcsvmodel_p.h
CsvParser::endLine
void endLine()
This method is called whenever a line ends.
Definition: qcsvmodel.cpp:70
CsvParser::end
void end()
This method is called at the end of parsing.
Definition: qcsvmodel.cpp:79
CsvParser
Definition: qcsvmodel_p.h:27
QCsvModel::setData
virtual bool setData(const QModelIndex &index, const QVariant &data, int role=Qt::EditRole)
Inherited from QAbstractTableModel.
Definition: qcsvmodel.cpp:313
QThread
qcsvmodel.h
QCsvModel::textCodec
QTextCodec * textCodec() const
Returns the text codec that is used for parsing the csv list.
Definition: qcsvmodel.cpp:258
QCsvModel
Definition: qcsvmodel.h:25
CsvParser::dataChanged
void dataChanged(const QString &data, int row, int column)
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:55:51 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kaddressbook

Skip menu "kaddressbook"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal