1 /* This file is part of the KDE project
3 Copyright (C) 2006 Dario Massarin <nekkar@libero.it>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
11 #include "core/transfertreemodel.h"
13 #include "core/kget.h"
14 #include "core/transfertreeselectionmodel.h"
15 #include "core/transfergrouphandler.h"
16 #include "core/transfergroup.h"
17 #include "core/transferhandler.h"
18 #include "core/transfer.h"
23 #include <kio/netaccess.h>
24 #include <kiconloader.h>
26 #include <qmimedata.h>
28 TransferTreeModel::TransferTreeModel(Scheduler
* scheduler
)
29 : QAbstractItemModel(),
30 m_scheduler(scheduler
),
36 TransferTreeModel::~TransferTreeModel()
41 void TransferTreeModel::addGroup(TransferGroup
* group
)
43 beginInsertRows(QModelIndex(), m_transferGroups
.size(), m_transferGroups
.size());
45 m_transferGroups
.append(group
);
50 void TransferTreeModel::delGroup(TransferGroup
* group
)
52 beginRemoveRows(QModelIndex(), m_transferGroups
.indexOf(group
), m_transferGroups
.indexOf(group
));
54 m_transferGroups
.removeAll(group
);
55 m_changedGroups
.removeAll(group
->handler());
60 void TransferTreeModel::addTransfer(Transfer
* transfer
, TransferGroup
* group
)
62 beginInsertRows(createIndex(m_transferGroups
.indexOf(group
), 0, group
->handler()), group
->size(), group
->size());
64 group
->append(transfer
);
69 void TransferTreeModel::delTransfer(Transfer
* transfer
)
71 TransferGroup
* group
= transfer
->group();
73 beginRemoveRows(createIndex(m_transferGroups
.indexOf(group
), 0, group
->handler()), group
->size()-1, group
->size()-1);
75 group
->remove(transfer
);
76 m_changedTransfers
.removeAll(transfer
->handler());
81 void TransferTreeModel::moveTransfer(Transfer
* transfer
, TransferGroup
* destGroup
, Transfer
* after
)
83 if( (after
) && (destGroup
!= after
->group()) )
86 int removePosition
= transfer
->group()->indexOf(transfer
);
87 int insertPosition
= destGroup
->size();
88 int groupIndex
= m_transferGroups
.indexOf(destGroup
);
90 beginRemoveRows(createIndex(groupIndex
, 0, destGroup
->handler()), removePosition
, removePosition
);
92 beginInsertRows(createIndex(m_transferGroups
.indexOf(destGroup
), 0, destGroup
->handler()), insertPosition
, insertPosition
);
94 if(destGroup
== transfer
->group())
97 destGroup
->move(transfer
, after
);
99 destGroup
->move(transfer
, static_cast<Transfer
*>(destGroup
->last()));
103 transfer
->group()->remove(transfer
);
105 if(destGroup
->size() != 0)
106 destGroup
->insert(transfer
, static_cast<Transfer
*>(destGroup
->last()));
108 destGroup
->append(transfer
);
110 transfer
->m_jobQueue
= destGroup
;
116 KGet::selectionModel()->clearSelection();
119 const QList
<TransferGroup
*> & TransferTreeModel::transferGroups()
121 return m_transferGroups
;
124 TransferGroup
* TransferTreeModel::findGroup(const QString
& groupName
)
126 QList
<TransferGroup
*>::iterator it
= m_transferGroups
.begin();
127 QList
<TransferGroup
*>::iterator itEnd
= m_transferGroups
.end();
129 for(; it
!=itEnd
; ++it
)
131 if( (*it
)->name() == groupName
)
139 Transfer
* TransferTreeModel::findTransfer(const KUrl
&src
)
141 QList
<TransferGroup
*>::iterator it
= m_transferGroups
.begin();
142 QList
<TransferGroup
*>::iterator itEnd
= m_transferGroups
.end();
146 for(; it
!=itEnd
; ++it
)
148 if( ( t
= (*it
)->findTransfer(src
) ) )
154 Transfer
*TransferTreeModel::findTransferByDestination(const KUrl
&dest
)
156 QList
<TransferGroup
*>::iterator it
= m_transferGroups
.begin();
157 QList
<TransferGroup
*>::iterator itEnd
= m_transferGroups
.end();
160 for(; it
!=itEnd
; ++it
) {
161 if((t
= (*it
)->findTransferByDestination(dest
))) {
169 bool TransferTreeModel::isTransferGroup(const QModelIndex
& index
) const
171 // kDebug(5001) << "TransferTreeModel::isTransferGroup()";
173 void * pointer
= index
.internalPointer();
175 foreach(TransferGroup
* group
, m_transferGroups
)
177 if(group
->handler() == pointer
)
186 void TransferTreeModel::postDataChangedEvent(TransferHandler
* transfer
)
189 m_timerId
= startTimer(200);
191 m_changedTransfers
.append(transfer
);
194 void TransferTreeModel::postDataChangedEvent(TransferGroupHandler
* group
)
197 m_timerId
= startTimer(200);
199 m_changedGroups
.append(group
);
202 QModelIndex
TransferTreeModel::createIndex(int row
, int column
, void * ptr
) const
208 // kDebug(5001) << "TransferTreeModel::createIndex() " << i;
210 return QAbstractItemModel::createIndex(row
, column
, ptr
);
213 int TransferTreeModel::rowCount(const QModelIndex
& parent
) const{
214 // kDebug(5001) << "TransferTreeModel::rowCount()";
216 if(!parent
.isValid())
218 // kDebug(5001) << " (ROOT) -> return " << m_transferGroups.size();
219 return m_transferGroups
.size();
222 if(isTransferGroup(parent
))
224 void * pointer
= parent
.internalPointer();
226 TransferGroupHandler
* group
= static_cast<TransferGroupHandler
*>(pointer
);
228 // kDebug(5001) << " (GROUP:" << group->name() << ") -> return " << group->size();
230 return group
->size();
236 int TransferTreeModel::columnCount(const QModelIndex
& parent
) const
238 // kDebug(5001) << "TransferTreeModel::columnCount()";
240 if(!parent
.isValid())
242 //Here we should return rootItem->columnCount(); .. but we don't
243 //have a root Item... bah
247 void * pointer
= parent
.internalPointer();
249 if(isTransferGroup(parent
))
251 //The given index refers to a group object
252 TransferGroupHandler
* group
= static_cast<TransferGroupHandler
*>(pointer
);
253 return group
->columnCount();
256 //The given index refers to a group object
257 TransferHandler
* transfer
= static_cast<TransferHandler
*>(pointer
);
258 return transfer
->columnCount();
262 Qt::ItemFlags
TransferTreeModel::flags (const QModelIndex
& index
) const
264 // kDebug(5001) << "TransferTreeModel::flags()";
265 if (!index
.isValid())
266 return Qt::ItemIsEnabled
;
268 Qt::ItemFlags flags
= Qt::ItemIsEnabled
| Qt::ItemIsSelectable
;
270 if(isTransferGroup(index
))
272 if(index
.column() == 0)
273 flags
|= Qt::ItemIsDropEnabled
;
276 flags
|= Qt::ItemIsDragEnabled
;
278 //flags |= Qt::ItemIsDropEnabled;
280 // We can edit all the groups but the default one
281 if(index
.row() > 0) {
282 flags
|= Qt::ItemIsEditable
;
288 QVariant
TransferTreeModel::headerData(int section
, Qt::Orientation orientation
, int role
) const
290 if (orientation
== Qt::Horizontal
&& role
== Qt::DisplayRole
)
295 return i18nc("name of download", "Name");
297 return i18nc("status of download", "Status");
299 return i18nc("size of download", "Size");
301 return i18nc("progress of download", "Progress");
303 return i18nc("speed of download", "Speed");
312 QVariant
TransferTreeModel::data(const QModelIndex
& index
, int role
) const
314 // kDebug(5001) << "TransferTreeModel::data()";
316 if (!index
.isValid())
318 // kDebug(5001) << " (ROOT)";
322 // KextendableItemDelegate::ShowExtensionIndicatorRole
323 // tells the KExtendableItemDelegate which column contains the extender icon
324 if (role
== Qt::UserRole
+ 200 && !isTransferGroup(index
)) {
325 if (index
.column () == 0 && Settings::showExpandableTransferDetails()) {
333 if (role
== Qt::DisplayRole
|| role
== Qt::DecorationRole
)
335 void * pointer
= index
.internalPointer();
337 if(isTransferGroup(index
))
339 if (role
== Qt::DisplayRole
)
341 // kDebug(5001) << " (GROUP)";
342 //The given index refers to a group object
343 TransferGroupHandler
* group
= static_cast<TransferGroupHandler
*>(pointer
);
344 return group
->data(index
.column());
346 else //Qt::DecorationRole -> icon
348 if (index
.column() == 0)
349 return SmallIcon("bookmark-new-list", 32);
355 // kDebug(5001) << " (TRANSFER)";
357 //The given index refers to a transfer object
358 TransferHandler
* transfer
= static_cast<TransferHandler
*>(pointer
);
360 if (role
== Qt::DisplayRole
)
361 return transfer
->data(index
.column());
362 else //Qt::DecorationRole -> icon
364 switch (index
.column())
367 return KIO::pixmapForUrl(transfer
->dest(), 0, KIconLoader::Desktop
, 16);
369 return transfer
->statusPixmap();
376 if (role
== Qt::TextAlignmentRole
)
378 if(isTransferGroup(index
))
380 switch (index
.column())
383 return Qt::AlignVCenter
;
385 return Qt::AlignCenter
;
387 return Qt::AlignCenter
;
389 return Qt::AlignCenter
;
391 return QVariant(Qt::AlignLeft
| Qt::AlignBottom
);
395 switch (index
.column())
398 return QVariant(Qt::AlignLeft
| Qt::AlignVCenter
);
400 return Qt::AlignCenter
;
402 return Qt::AlignCenter
;
404 return Qt::AlignCenter
;
406 return Qt::AlignCenter
;
413 QModelIndex
TransferTreeModel::index(int row
, int column
, const QModelIndex
& parent
) const
415 // kDebug(5001) << "TransferTreeModel::index() ( " << row << " , " << column << " )";
417 if(!parent
.isValid())
419 // kDebug(5001) << "TransferTreeModel::index() -> group ( " << row << " , " << column << " ) Groups=" << m_transferGroups.size();
420 //Look for the specific group
421 if(row
< m_transferGroups
.size() && row
>= 0)
423 return createIndex(row
, column
, m_transferGroups
[row
]->handler());
427 return QModelIndex();
430 if(isTransferGroup(parent
))
432 //The given parent refers to a TransferGroup object
433 void * pointer
= parent
.internalPointer();
434 TransferGroupHandler
* group
= static_cast<TransferGroupHandler
*>(pointer
);
436 //Look for the specific transfer
437 if(row
< group
->size() && row
>= 0)
439 // kDebug(5001) << "aa row=" << row;
441 // kDebug(5001) << "bb";
442 // return (*group)[row]->index(column);
443 return createIndex(row
, column
, (*group
)[row
]);
446 return QModelIndex();
449 //If here, the given parent is a Transfer object which hasn't any child
450 return QModelIndex();
453 QModelIndex
TransferTreeModel::parent(const QModelIndex
& index
) const
455 // kDebug(5001) << "TransferTreeModel::parent()";
458 return QModelIndex();
460 if(!isTransferGroup(index
))
462 //The given index refers to a Transfer item
463 void * pointer
= index
.internalPointer();
464 TransferGroupHandler
* group
= static_cast<TransferHandler
*>(pointer
)->group();
465 return createIndex(m_transferGroups
.indexOf(group
->m_group
), 0, group
);
468 return QModelIndex();
471 Qt::DropActions
TransferTreeModel::supportedDropActions() const
473 return Qt::CopyAction
| Qt::MoveAction
;
476 QStringList
TransferTreeModel::mimeTypes() const
479 types
<< "application/vnd.text.list";
483 QMimeData
* TransferTreeModel::mimeData(const QModelIndexList
&indexes
) const
485 QMimeData
* mimeData
= new QMimeData();
486 QByteArray encodedData
;
488 QDataStream
stream(&encodedData
, QIODevice::WriteOnly
);
490 foreach (QModelIndex index
, indexes
)
494 if(index
.column() == 0 && index
.parent().isValid())
496 stream
<< data(index
.parent(), Qt::DisplayRole
).toString();
497 stream
<< QString::number((qulonglong
) index
.internalPointer(),16);
502 mimeData
->setData("application/vnd.text.list", encodedData
);
506 bool TransferTreeModel::dropMimeData(const QMimeData
* mdata
, Qt::DropAction action
, int row
, int column
, const QModelIndex
&parent
)
508 if (action
== Qt::IgnoreAction
)
511 if (!mdata
->hasFormat("application/vnd.text.list"))
517 if (parent
.isValid())
518 kDebug(5001) << "TransferTreeModel::dropMimeData" << " " << row
<< " "
521 QByteArray encodedData
= mdata
->data("application/vnd.text.list");
522 QDataStream
stream(&encodedData
, QIODevice::ReadOnly
);
523 QStringList stringList
;
526 while (!stream
.atEnd())
534 kDebug(5001) << "TransferTreeModel::dropMimeData DATA:";
535 kDebug(5001) << stringList
;
538 for(int i
=0; i
< rows
; i
++)
540 // TransferGroup * group = findGroup(stringList[i]);
542 // TransferGroup * destGroup = static_cast<TransferGroup *>(index(row, column, parent).internalPointer());
544 TransferGroup
* destGroup
= findGroup(data(parent
, Qt::DisplayRole
).toString());
546 TransferHandler
* transferHandler
= (TransferHandler
*) stringList
[++i
].toInt(0, 16);
548 moveTransfer(transferHandler
->m_transfer
, destGroup
);
553 void TransferTreeModel::timerEvent(QTimerEvent
*event
)
556 // kDebug(5001) << "TransferTreeModel::timerEvent";
558 QList
<TransferHandler
*> updatedTransfers
;
559 QList
<TransferGroupHandler
*> updatedGroups
;
561 foreach(TransferHandler
* transfer
, m_changedTransfers
)
563 if(!updatedTransfers
.contains(transfer
))
565 TransferGroupHandler
* group
= transfer
->group();
567 emit
dataChanged(createIndex(group
->indexOf(transfer
), 0, transfer
),
568 createIndex(group
->indexOf(transfer
), transfer
->columnCount(), transfer
));
570 updatedTransfers
.append(transfer
);
574 foreach(TransferGroupHandler
* group
, m_changedGroups
)
576 if(!updatedGroups
.contains(group
))
578 emit
dataChanged(createIndex(m_transferGroups
.indexOf(group
->m_group
), 0, group
),
579 createIndex(m_transferGroups
.indexOf(group
->m_group
), group
->columnCount(), group
));
581 updatedGroups
.append(group
);
585 m_changedTransfers
.clear();
586 m_changedGroups
.clear();
588 killTimer(m_timerId
);
592 #include "transfertreemodel.moc"