* Paint a styled progressbar instead of our home-brown one.
[kdenetwork.git] / kget / core / transfertreemodel.cpp
blobcb9b7851143742566f59174839da16355fd38faf
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; version 2
8 of the License.
9 */
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"
19 #include "settings.h"
21 #include <kdebug.h>
22 #include <klocale.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),
31 m_timerId(-1)
36 TransferTreeModel::~TransferTreeModel()
41 void TransferTreeModel::addGroup(TransferGroup * group)
43 beginInsertRows(QModelIndex(), m_transferGroups.size(), m_transferGroups.size());
45 m_transferGroups.append(group);
47 endInsertRows();
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());
57 endRemoveRows();
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);
66 endInsertRows();
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());
78 endRemoveRows();
81 void TransferTreeModel::moveTransfer(Transfer * transfer, TransferGroup * destGroup, Transfer * after)
83 if( (after) && (destGroup != after->group()) )
84 return;
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())
96 if(after)
97 destGroup->move(transfer, after);
98 else
99 destGroup->move(transfer, static_cast<Transfer *>(destGroup->last()));
101 else
103 transfer->group()->remove(transfer);
105 if(destGroup->size() != 0)
106 destGroup->insert(transfer, static_cast<Transfer *>(destGroup->last()));
107 else
108 destGroup->append(transfer);
110 transfer->m_jobQueue = destGroup;
113 endInsertRows();
114 endRemoveRows();
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 )
133 return *it;
136 return 0;
139 Transfer * TransferTreeModel::findTransfer(const KUrl &src)
141 QList<TransferGroup *>::iterator it = m_transferGroups.begin();
142 QList<TransferGroup *>::iterator itEnd = m_transferGroups.end();
144 Transfer * t;
146 for(; it!=itEnd ; ++it)
148 if( ( t = (*it)->findTransfer(src) ) )
149 return t;
151 return 0;
154 Transfer *TransferTreeModel::findTransferByDestination(const KUrl &dest)
156 QList<TransferGroup *>::iterator it = m_transferGroups.begin();
157 QList<TransferGroup *>::iterator itEnd = m_transferGroups.end();
159 Transfer *t;
160 for(; it!=itEnd; ++it) {
161 if((t = (*it)->findTransferByDestination(dest))) {
162 return t;
166 return 0;
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)
179 return true;
183 return false;
186 void TransferTreeModel::postDataChangedEvent(TransferHandler * transfer)
188 if(m_timerId == -1)
189 m_timerId = startTimer(200);
191 m_changedTransfers.append(transfer);
194 void TransferTreeModel::postDataChangedEvent(TransferGroupHandler * group)
196 if(m_timerId == -1)
197 m_timerId = startTimer(200);
199 m_changedGroups.append(group);
202 QModelIndex TransferTreeModel::createIndex(int row, int column, void * ptr) const
204 static int i = 0;
206 i++;
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();
233 return 0;
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
244 return 5;
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;
275 else
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;
285 return flags;
288 QVariant TransferTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
290 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
292 switch (section)
294 case 0:
295 return i18n("Name");
296 case 1:
297 return i18n("Status");
298 case 2:
299 return i18n("Size");
300 case 3:
301 return i18n("Progress");
302 case 4:
303 return i18n("Speed");
304 default:
305 return QVariant();
309 return QVariant();
312 QVariant TransferTreeModel::data(const QModelIndex & index, int role) const
314 // kDebug(5001) << "TransferTreeModel::data()";
316 if (!index.isValid())
318 // kDebug(5001) << " (ROOT)";
319 return QVariant();
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()) {
326 return true;
328 else {
329 return false;
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);
350 else
351 return QVariant();
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())
366 case 0:
367 return KIO::pixmapForUrl(transfer->dest(), 0, KIconLoader::Desktop, 16);
368 case 1:
369 return transfer->statusPixmap();
370 default:
371 return QVariant();
376 if (role == Qt::TextAlignmentRole)
378 if(isTransferGroup(index))
380 switch (index.column())
382 case 0: // name
383 return Qt::AlignVCenter;
384 case 2: // size
385 return Qt::AlignCenter;
386 case 4: // speed
387 return Qt::AlignCenter;
388 case 3: //progress
389 return Qt::AlignCenter;
390 default:
391 return QVariant(Qt::AlignLeft | Qt::AlignBottom);
395 switch (index.column())
397 case 0: // name
398 return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
399 case 2: // size
400 return Qt::AlignCenter;
401 case 4: // speed
402 return Qt::AlignCenter;
403 case 3: //progress
404 return Qt::AlignCenter;
405 default:
406 return Qt::AlignCenter;
410 return QVariant();
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());
426 else
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;
440 (*group)[row];
441 // kDebug(5001) << "bb";
442 // return (*group)[row]->index(column);
443 return createIndex(row, column, (*group)[row]);
445 else
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()";
457 if(!index.isValid())
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
478 QStringList types;
479 types << "application/vnd.text.list";
480 return types;
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)
492 if (index.isValid())
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);
503 return mimeData;
506 bool TransferTreeModel::dropMimeData(const QMimeData * mdata, Qt::DropAction action, int row, int column, const QModelIndex &parent)
508 if (action == Qt::IgnoreAction)
509 return true;
511 if (!mdata->hasFormat("application/vnd.text.list"))
512 return false;
514 if (column > 0)
515 return false;
517 if (parent.isValid())
518 kDebug(5001) << "TransferTreeModel::dropMimeData" << " " << row << " "
519 << column << endl;
521 QByteArray encodedData = mdata->data("application/vnd.text.list");
522 QDataStream stream(&encodedData, QIODevice::ReadOnly);
523 QStringList stringList;
524 int rows = 0;
526 while (!stream.atEnd())
528 QString text;
529 stream >> text;
530 stringList << text;
531 ++rows;
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);
550 return true;
553 void TransferTreeModel::timerEvent(QTimerEvent *event)
555 Q_UNUSED(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);
589 m_timerId = -1;
592 #include "transfertreemodel.moc"