1 | /* This file is part of the KDE project |
2 | Copyright (C) 2007, 2012 Dag Andersen <danders@get2net.dk> |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2 of the License, or (at your option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public 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 |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | * Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #include "kptdocumentmodel.h" |
21 | |
22 | #include "kptdocuments.h" |
23 | #include "kptglobal.h" |
24 | #include "kptcommonstrings.h" |
25 | #include "kptdebug.h" |
26 | |
27 | #include <QMimeData> |
28 | |
29 | |
30 | class KoDocument; |
31 | |
32 | namespace KPlato |
33 | { |
34 | |
35 | QVariant DocumentModel::url( const Document *doc, int role ) const |
36 | { |
37 | switch ( role ) { |
38 | case Qt::DisplayRole: |
39 | case Qt::EditRole: |
40 | case Qt::ToolTipRole: |
41 | return doc->url().url(); |
42 | case Qt::StatusTipRole: |
43 | case Qt::WhatsThisRole: |
44 | return QVariant(); |
45 | } |
46 | return QVariant(); |
47 | } |
48 | |
49 | QVariant DocumentModel::name( const Document *doc, int role ) const |
50 | { |
51 | switch ( role ) { |
52 | case Qt::DisplayRole: |
53 | case Qt::EditRole: |
54 | case Qt::ToolTipRole: |
55 | return doc->name(); |
56 | case Qt::StatusTipRole: |
57 | case Qt::WhatsThisRole: |
58 | return QVariant(); |
59 | } |
60 | return QVariant(); |
61 | } |
62 | |
63 | bool DocumentModel::setName( Document *doc, const QVariant &value, int role ) |
64 | { |
65 | switch ( role ) { |
66 | case Qt::EditRole: |
67 | doc->setName( value.toString() ); |
68 | return true; |
69 | default: |
70 | break; |
71 | } |
72 | return false; |
73 | } |
74 | |
75 | QVariant DocumentModel::type( const Document *doc, int role ) const |
76 | { |
77 | switch ( role ) { |
78 | case Qt::DisplayRole: |
79 | case Qt::ToolTipRole: |
80 | return Document::typeToString( doc->type(), true ); |
81 | case Role::EnumList: |
82 | return Document::typeList( true ); |
83 | case Qt::EditRole: |
84 | case Role::EnumListValue: |
85 | return (int)doc->type(); |
86 | case Qt::TextAlignmentRole: |
87 | return Qt::AlignCenter; |
88 | case Qt::StatusTipRole: |
89 | case Qt::WhatsThisRole: |
90 | return QVariant(); |
91 | default: |
92 | break; |
93 | } |
94 | return QVariant(); |
95 | } |
96 | |
97 | bool DocumentModel::setType( Document *doc, const QVariant &value, int role ) |
98 | { |
99 | switch ( role ) { |
100 | case Qt::EditRole: |
101 | doc->setType( static_cast<Document::Type>( value.toInt() ) ); |
102 | return true; |
103 | default: |
104 | break; |
105 | } |
106 | return false; |
107 | } |
108 | |
109 | QVariant DocumentModel::status( const Document *doc, int role ) const |
110 | { |
111 | switch ( role ) { |
112 | case Qt::DisplayRole: |
113 | case Qt::EditRole: |
114 | case Qt::ToolTipRole: { |
115 | return doc->status(); |
116 | } |
117 | case Qt::StatusTipRole: |
118 | case Qt::WhatsThisRole: |
119 | return QVariant(); |
120 | } |
121 | return QVariant(); |
122 | } |
123 | |
124 | QVariant DocumentModel::sendAs( const Document *doc, int role ) const |
125 | { |
126 | switch ( role ) { |
127 | case Qt::DisplayRole: |
128 | case Qt::ToolTipRole: |
129 | return Document::sendAsToString( doc->sendAs(), true ); |
130 | case Role::EnumList: |
131 | return Document::sendAsList( true ); |
132 | case Qt::EditRole: |
133 | case Role::EnumListValue: |
134 | return (int)doc->sendAs(); |
135 | case Qt::TextAlignmentRole: |
136 | return Qt::AlignCenter; |
137 | case Qt::StatusTipRole: |
138 | case Qt::WhatsThisRole: |
139 | return QVariant(); |
140 | default: |
141 | break; |
142 | } |
143 | return QVariant(); |
144 | } |
145 | |
146 | bool DocumentModel::setSendAs( Document *doc, const QVariant &value, int role ) |
147 | { |
148 | switch ( role ) { |
149 | case Qt::EditRole: |
150 | doc->setSendAs( static_cast<Document::SendAs>( value.toInt() ) ); |
151 | return true; |
152 | default: |
153 | break; |
154 | } |
155 | return false; |
156 | } |
157 | |
158 | QVariant DocumentModel::data( const Document *doc, int property, int role ) const |
159 | { |
160 | QVariant result; |
161 | switch ( property ) { |
162 | case Property_Url: result = url( doc, role ); break; |
163 | case Property_Name: result = name( doc, role ); break; |
164 | case Property_Type: result = type( doc, role ); break; |
165 | case Property_SendAs: result = sendAs( doc, role ); break; |
166 | case Property_Status: result = status( doc, role ); break; |
167 | default: |
168 | //kDebug(planDbg())<<"Invalid property number: "<<property; |
169 | return result; |
170 | } |
171 | return result; |
172 | } |
173 | |
174 | int DocumentModel::propertyCount() |
175 | { |
176 | return 5; |
177 | } |
178 | |
179 | bool DocumentModel::setData( Document *doc, int property, const QVariant & /*value*/, int role ) |
180 | { |
181 | Q_UNUSED(doc); |
182 | Q_UNUSED(property); |
183 | Q_UNUSED(role); |
184 | switch ( property ) { |
185 | //case 0: result = url( doc, role ); break; |
186 | //case 1: return setType( doc, value, role ); |
187 | //case 2: result = status( doc, role ); break; |
188 | default: |
189 | //kDebug(planDbg())<<"Invalid property number: "<<property; |
190 | break; |
191 | } |
192 | return false; |
193 | } |
194 | |
195 | QVariant DocumentModel::( int section, int role ) |
196 | { |
197 | if ( role == Qt::DisplayRole ) { |
198 | switch ( section ) { |
199 | case Property_Url: return i18n( "Url" ); |
200 | case Property_Name: return i18n( "Name" ); |
201 | case Property_Type: return i18n( "Type" ); |
202 | case Property_SendAs: return i18n( "Send As" ); |
203 | case Property_Status: return i18n( "Status" ); |
204 | |
205 | default: return QVariant(); |
206 | } |
207 | } |
208 | if ( role == Qt::ToolTipRole ) { |
209 | switch ( section ) { |
210 | case Property_Url: return ToolTip::documentUrl(); |
211 | case Property_Name: return QVariant(); //TODO |
212 | case Property_Type: return ToolTip::documentType(); |
213 | case Property_SendAs: return ToolTip::documentSendAs(); |
214 | case Property_Status: return ToolTip::documentStatus(); |
215 | |
216 | default: return QVariant(); |
217 | } |
218 | } |
219 | return QVariant(); |
220 | } |
221 | |
222 | //---------------------------- |
223 | DocumentItemModel::DocumentItemModel( QObject *parent ) |
224 | : ItemModelBase( parent ), |
225 | m_documents( 0 ) |
226 | { |
227 | } |
228 | |
229 | DocumentItemModel::~DocumentItemModel() |
230 | { |
231 | } |
232 | |
233 | void DocumentItemModel::slotDocumentToBeInserted( Documents *parent, int row ) |
234 | { |
235 | if ( parent == m_documents ) { |
236 | beginInsertRows( QModelIndex(), row, row ); |
237 | } |
238 | } |
239 | |
240 | void DocumentItemModel::slotDocumentInserted( Document *doc ) |
241 | { |
242 | if ( m_documents->contains( doc ) ) { |
243 | endInsertRows(); |
244 | } |
245 | } |
246 | |
247 | void DocumentItemModel::slotDocumentToBeRemoved( Document *doc ) |
248 | { |
249 | if ( m_documents->contains( doc ) ) { |
250 | int row = m_documents->indexOf( doc ); |
251 | beginRemoveRows( QModelIndex(), row, row ); |
252 | } |
253 | } |
254 | |
255 | void DocumentItemModel::slotDocumentRemoved( Document *doc ) |
256 | { |
257 | Q_UNUSED(doc); |
258 | //FIXME |
259 | endRemoveRows(); |
260 | } |
261 | |
262 | void DocumentItemModel::setDocuments( Documents *docs ) |
263 | { |
264 | //kDebug(planDbg())<<m_documents<<docs; |
265 | if ( m_documents ) { |
266 | } |
267 | m_documents = docs; |
268 | if ( m_documents ) { |
269 | } |
270 | reset(); |
271 | } |
272 | |
273 | Documents *DocumentItemModel::documents() const |
274 | { |
275 | return m_documents; |
276 | } |
277 | |
278 | Qt::ItemFlags DocumentItemModel::flags( const QModelIndex &index ) const |
279 | { |
280 | Qt::ItemFlags flags = QAbstractItemModel::flags( index ); |
281 | if ( !index.isValid() ) { |
282 | if ( m_readWrite ) { |
283 | flags |= Qt::ItemIsDropEnabled; |
284 | } |
285 | return flags; |
286 | } |
287 | //kDebug(planDbg())<<index<<m_readWrite; |
288 | if ( m_readWrite ) { |
289 | flags |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; |
290 | switch ( index.column() ) { |
291 | case DocumentModel::Property_Url: // url |
292 | flags &= ~Qt::ItemIsEditable; // wee need a full path |
293 | break; |
294 | case DocumentModel::Property_Name: // name |
295 | flags |= Qt::ItemIsEditable; |
296 | break; |
297 | case DocumentModel::Property_Type: // type |
298 | flags |= Qt::ItemIsEditable; |
299 | break; |
300 | case DocumentModel::Property_SendAs: // sendAs |
301 | flags |= Qt::ItemIsEditable; |
302 | break; |
303 | case DocumentModel::Property_Status: // status |
304 | flags &= ~Qt::ItemIsEditable; |
305 | break; |
306 | default: |
307 | flags &= ~Qt::ItemIsEditable; |
308 | } |
309 | } |
310 | return flags; |
311 | } |
312 | |
313 | QModelIndex DocumentItemModel::parent( const QModelIndex &/*index*/ ) const |
314 | { |
315 | return QModelIndex(); |
316 | } |
317 | |
318 | QModelIndex DocumentItemModel::index( int row, int column, const QModelIndex &parent ) const |
319 | { |
320 | if ( parent.isValid() ) { |
321 | return QModelIndex(); |
322 | } |
323 | if ( m_documents == 0 || column < 0 || column >= columnCount() || row < 0 ) { |
324 | //kDebug(planDbg())<<"No index for"<<row<<","<<column; |
325 | return QModelIndex(); |
326 | } |
327 | if ( row >= m_documents->count() ) { |
328 | return QModelIndex(); |
329 | } |
330 | return createIndex(row, column ); |
331 | } |
332 | |
333 | QModelIndex DocumentItemModel::index( const Document *doc ) const |
334 | { |
335 | if ( m_documents == 0 || ! doc->isValid() ) { |
336 | return QModelIndex(); |
337 | } |
338 | if ( ! m_documents->contains( doc ) ) { |
339 | return QModelIndex(); |
340 | } |
341 | return createIndex( m_documents->indexOf( doc ), 0 ); |
342 | } |
343 | |
344 | bool DocumentItemModel::setUrl( Document *doc, const QVariant &value, int role ) |
345 | { |
346 | switch ( role ) { |
347 | case Qt::EditRole: |
348 | if ( KUrl( value.toString() ) == doc->url() ) { |
349 | return false; |
350 | } |
351 | //m_part->addCommand( new DocumentModifyUrlCmd( *doc, value.toString(), "Modify Document Url" ) ); |
352 | return true; |
353 | } |
354 | return false; |
355 | } |
356 | |
357 | bool DocumentItemModel::setName( Document *doc, const QVariant &value, int role ) |
358 | { |
359 | switch ( role ) { |
360 | case Qt::EditRole: |
361 | //m_part->addCommand( new DocumentModifyTypeCmd( *doc, value.toString(), "Modify Document Type" ) ); |
362 | return m_model.setName( doc, value, role ); |
363 | } |
364 | return false; |
365 | } |
366 | |
367 | bool DocumentItemModel::setType( Document *doc, const QVariant &value, int role ) |
368 | { |
369 | switch ( role ) { |
370 | case Qt::EditRole: |
371 | if ( value.toInt() == doc->type() ) { |
372 | return false; |
373 | } |
374 | m_model.setType( doc, value, role ); |
375 | //m_part->addCommand( new DocumentModifyTypeCmd( *doc, value.toString(), "Modify Document Type" ) ); |
376 | return true; |
377 | } |
378 | return false; |
379 | } |
380 | |
381 | bool DocumentItemModel::setSendAs( Document *doc, const QVariant &value, int role ) |
382 | { |
383 | switch ( role ) { |
384 | case Qt::EditRole: |
385 | if ( value.toInt() == doc->sendAs() ) { |
386 | return false; |
387 | } |
388 | m_model.setSendAs( doc, value, role ); |
389 | //m_part->addCommand( new DocumentModifyTypeCmd( *doc, value.toString(), "Modify Document Type" ) ); |
390 | return true; |
391 | } |
392 | return false; |
393 | } |
394 | |
395 | |
396 | QVariant DocumentItemModel::data( const QModelIndex &index, int role ) const |
397 | { |
398 | QVariant result; |
399 | const Document *doc = document( index ); |
400 | if ( doc ) { |
401 | result = m_model.data( doc, index.column(), role ); |
402 | } |
403 | if ( result.isValid() ) { |
404 | if ( role == Qt::DisplayRole && result.type() == QVariant::String && result.toString().isEmpty()) { |
405 | // HACK to show focus in empty cells |
406 | result = ' '; |
407 | } |
408 | return result; |
409 | } |
410 | return result; |
411 | } |
412 | |
413 | bool DocumentItemModel::setData( const QModelIndex &index, const QVariant &value, int role ) |
414 | { |
415 | if ( ! index.isValid() ) { |
416 | return ItemModelBase::setData( index, value, role ); |
417 | } |
418 | if ( ( flags(index) & Qt::ItemIsEditable ) == 0 || role != Qt::EditRole ) { |
419 | return false; |
420 | } |
421 | bool result = false; |
422 | Document *doc = document( index ); |
423 | switch (index.column()) { |
424 | case DocumentModel::Property_Url: |
425 | result = setUrl( doc, value, role ); |
426 | break; |
427 | case DocumentModel::Property_Name: |
428 | result = setName( doc, value, role ); |
429 | break; |
430 | case DocumentModel::Property_Type: |
431 | result = setType( doc, value, role ); |
432 | break; |
433 | case DocumentModel::Property_SendAs: |
434 | result = setSendAs( doc, value, role ); |
435 | break; |
436 | default: |
437 | qWarning("data: invalid display value column %d" , index.column()); |
438 | break; |
439 | } |
440 | if ( result ) { |
441 | emit dataChanged( index, index ); |
442 | } |
443 | return result; |
444 | } |
445 | |
446 | QVariant DocumentItemModel::( int section, Qt::Orientation orientation, int role ) const |
447 | { |
448 | if ( orientation == Qt::Horizontal ) { |
449 | if ( role == Qt::DisplayRole ) { |
450 | return m_model.headerData( section, role ); |
451 | } else if ( role == Qt::TextAlignmentRole ) { |
452 | switch (section) { |
453 | case DocumentModel::Property_Type: return Qt::AlignCenter; |
454 | case DocumentModel::Property_SendAs: return Qt::AlignCenter; |
455 | default: return QVariant(); |
456 | } |
457 | } |
458 | } |
459 | if ( role == Qt::ToolTipRole ) { |
460 | return DocumentModel::headerData( section, role ); |
461 | } |
462 | return ItemModelBase::headerData(section, orientation, role); |
463 | } |
464 | |
465 | QAbstractItemDelegate *DocumentItemModel::createDelegate( int column, QWidget *parent ) const |
466 | { |
467 | switch ( column ) { |
468 | //case 0: return new KUrlDelegate( parent ); //??????? |
469 | case DocumentModel::Property_Type: { kDebug(planDbg())<< column; return new EnumDelegate( parent ); } |
470 | case DocumentModel::Property_SendAs: { kDebug(planDbg())<< column; return new EnumDelegate( parent ); } |
471 | default: break; |
472 | } |
473 | return 0; |
474 | } |
475 | |
476 | int DocumentItemModel::columnCount( const QModelIndex &/*parent*/ ) const |
477 | { |
478 | //kDebug(planDbg())<<m_model.propertyCount(); |
479 | return m_model.propertyCount(); |
480 | } |
481 | |
482 | int DocumentItemModel::rowCount( const QModelIndex &parent ) const |
483 | { |
484 | if ( m_documents == 0 || parent.isValid() ) { |
485 | //kDebug(planDbg())<<parent; |
486 | return 0; |
487 | } |
488 | //kDebug(planDbg())<<parent<<": "<<m_documents->count(); |
489 | return m_documents->count(); |
490 | } |
491 | |
492 | Qt::DropActions DocumentItemModel::supportedDropActions() const |
493 | { |
494 | return Qt::CopyAction | Qt::MoveAction; |
495 | } |
496 | |
497 | |
498 | QStringList DocumentItemModel::mimeTypes() const |
499 | { |
500 | return QStringList() << "application/x-vnd.kde.plan.documentitemmodel.internal" ; |
501 | } |
502 | |
503 | QMimeData *DocumentItemModel::mimeData( const QModelIndexList & indexes ) const |
504 | { |
505 | QMimeData *m = new QMimeData(); |
506 | QByteArray encodedData; |
507 | //QDataStream stream(&encodedData, QIODevice::WriteOnly); |
508 | //QList<int> rows; |
509 | foreach (const QModelIndex &index, indexes) { |
510 | Q_UNUSED(index); |
511 | m->setData("application/x-vnd.kde.plan.documentitemmodel.internal" , encodedData); |
512 | } |
513 | return m; |
514 | } |
515 | |
516 | bool DocumentItemModel::dropAllowed( const QModelIndex &index, int dropIndicatorPosition, const QMimeData *data ) |
517 | { |
518 | Q_UNUSED(index); |
519 | Q_UNUSED(dropIndicatorPosition); |
520 | Q_UNUSED(data); |
521 | //kDebug(planDbg()); |
522 | return true; |
523 | } |
524 | |
525 | bool DocumentItemModel::dropAllowed( Document *on, const QMimeData *data ) |
526 | { |
527 | Q_UNUSED(on) |
528 | if ( !data->hasFormat("application/x-vnd.kde.plan.documentitemmodel.internal" ) ) { |
529 | return false; |
530 | } |
531 | return true; |
532 | } |
533 | |
534 | bool DocumentItemModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int /*column*/, const QModelIndex &parent ) |
535 | { |
536 | Q_UNUSED(row); |
537 | Q_UNUSED(parent); |
538 | //kDebug(planDbg())<<action; |
539 | if (action == Qt::IgnoreAction) { |
540 | return true; |
541 | } |
542 | if ( !data->hasFormat( "application/x-vnd.kde.plan.documentitemmodel.internal" ) ) { |
543 | return false; |
544 | } |
545 | return false; |
546 | } |
547 | |
548 | Document *DocumentItemModel::document( const QModelIndex &index ) const |
549 | { |
550 | if ( m_documents == 0 ) { |
551 | return 0; |
552 | } |
553 | return m_documents->value( index.row() ); |
554 | } |
555 | |
556 | void DocumentItemModel::slotDocumentChanged( Document *doc ) |
557 | { |
558 | if ( m_documents == 0 ) { |
559 | return; |
560 | } |
561 | int row = m_documents->indexOf( doc ); |
562 | if ( row == -1 ) { |
563 | return; |
564 | } |
565 | emit dataChanged( createIndex( row, 0 ), createIndex( row, columnCount() - 1 ) ); |
566 | } |
567 | |
568 | QModelIndex DocumentItemModel::insertDocument( Document *doc, Document *after ) |
569 | { |
570 | Q_UNUSED(after); |
571 | // m_part->addCommand( new DocumentAddCmd( doc, after, kundo2_i18n( "Add Document") ) ); |
572 | int row = m_documents->indexOf( doc ); |
573 | if ( row == -1 ) { |
574 | return QModelIndex(); |
575 | } |
576 | return createIndex( row, 0 ); |
577 | } |
578 | |
579 | } //namespace KPlato |
580 | |
581 | #include "kptdocumentmodel.moc" |
582 | |