Disable clipboardsharing in view only mode.
[kdenetwork.git] / kget / core / transfertreemodel.cpp
blobd58652ef4aebe490459366cfd55b24340a03aa58
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.
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 // Remove index corresponding to when it's created.
74 int remove_index = group->indexOf(transfer);
75 beginRemoveRows(createIndex(m_transferGroups.indexOf(group), 0, group->handler()), remove_index, remove_index);
77 group->remove(transfer);
78 m_changedTransfers.removeAll(transfer->handler());
80 endRemoveRows();
83 void TransferTreeModel::moveTransfer(Transfer * transfer, TransferGroup * destGroup, Transfer * after)
85 if( (after) && (destGroup != after->group()) )
86 return;
88 int removePosition = transfer->group()->indexOf(transfer);
89 int insertPosition = destGroup->size();
90 int groupIndex = m_transferGroups.indexOf(destGroup);
92 beginRemoveRows(createIndex(groupIndex, 0, destGroup->handler()), removePosition, removePosition);
94 beginInsertRows(createIndex(m_transferGroups.indexOf(destGroup), 0, destGroup->handler()), insertPosition, insertPosition);
96 if(destGroup == transfer->group())
98 if(after)
99 destGroup->move(transfer, after);
100 else
101 destGroup->move(transfer, static_cast<Transfer *>(destGroup->last()));
103 else
105 transfer->group()->remove(transfer);
107 if(destGroup->size() != 0)
108 destGroup->insert(transfer, static_cast<Transfer *>(destGroup->last()));
109 else
110 destGroup->append(transfer);
112 transfer->m_jobQueue = destGroup;
115 endInsertRows();
116 endRemoveRows();
118 KGet::selectionModel()->clearSelection();
121 const QList<TransferGroup *> & TransferTreeModel::transferGroups()
123 return m_transferGroups;
126 TransferGroup * TransferTreeModel::findGroup(const QString & groupName)
128 QList<TransferGroup *>::iterator it = m_transferGroups.begin();
129 QList<TransferGroup *>::iterator itEnd = m_transferGroups.end();
131 for(; it!=itEnd ; ++it)
133 if( (*it)->name() == groupName )
135 return *it;
138 return 0;
141 Transfer * TransferTreeModel::findTransfer(const KUrl &src)
143 QList<TransferGroup *>::iterator it = m_transferGroups.begin();
144 QList<TransferGroup *>::iterator itEnd = m_transferGroups.end();
146 Transfer * t;
148 for(; it!=itEnd ; ++it)
150 if( ( t = (*it)->findTransfer(src) ) )
151 return t;
153 return 0;
156 Transfer *TransferTreeModel::findTransferByDestination(const KUrl &dest)
158 QList<TransferGroup *>::iterator it = m_transferGroups.begin();
159 QList<TransferGroup *>::iterator itEnd = m_transferGroups.end();
161 Transfer *t;
162 for(; it!=itEnd; ++it) {
163 if((t = (*it)->findTransferByDestination(dest))) {
164 return t;
168 return 0;
171 bool TransferTreeModel::isTransferGroup(const QModelIndex & index) const
173 // kDebug(5001) << "TransferTreeModel::isTransferGroup()";
175 void * pointer = index.internalPointer();
177 Handler *ph = static_cast<Handler*>(pointer);
178 if (dynamic_cast<TransferGroupHandler*>(ph))
180 return true;
182 return false;
185 void TransferTreeModel::postDataChangedEvent(TransferHandler * transfer)
187 if(m_timerId == -1)
188 m_timerId = startTimer(500);
190 m_changedTransfers.append(transfer);
193 void TransferTreeModel::postDataChangedEvent(TransferGroupHandler * group)
195 if(m_timerId == -1)
196 m_timerId = startTimer(500);
198 m_changedGroups.append(group);
201 QModelIndex TransferTreeModel::createIndex(int row, int column, void * ptr) const
203 static int i = 0;
205 i++;
207 // kDebug(5001) << "TransferTreeModel::createIndex() " << i;
209 return QAbstractItemModel::createIndex(row, column, ptr);
212 int TransferTreeModel::rowCount(const QModelIndex & parent) const{
213 // kDebug(5001) << "TransferTreeModel::rowCount()";
215 if(!parent.isValid())
217 // kDebug(5001) << " (ROOT) -> return " << m_transferGroups.size();
218 return m_transferGroups.size();
221 if(isTransferGroup(parent))
223 void * pointer = parent.internalPointer();
225 TransferGroupHandler * group = static_cast<TransferGroupHandler *>(pointer);
227 // kDebug(5001) << " (GROUP:" << group->name() << ") -> return " << group->size();
229 return group->size();
232 return 0;
235 int TransferTreeModel::columnCount(const QModelIndex & parent) const
237 // kDebug(5001) << "TransferTreeModel::columnCount()";
239 if(!parent.isValid())
241 //Here we should return rootItem->columnCount(); .. but we don't
242 //have a root Item... bah
243 return 6;
246 void * pointer = parent.internalPointer();
248 if(isTransferGroup(parent))
250 //The given index refers to a group object
251 TransferGroupHandler * group = static_cast<TransferGroupHandler *>(pointer);
252 return group->columnCount();
255 //The given index refers to a group object
256 TransferHandler * transfer = static_cast<TransferHandler *>(pointer);
257 return transfer->columnCount();
261 Qt::ItemFlags TransferTreeModel::flags (const QModelIndex & index) const
263 // kDebug(5001) << "TransferTreeModel::flags()";
264 if (!index.isValid())
265 return Qt::ItemIsEnabled;
267 Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
269 if(isTransferGroup(index))
271 if(index.column() == 0)
272 flags |= Qt::ItemIsDropEnabled;
274 else
275 flags |= Qt::ItemIsDragEnabled;
277 //flags |= Qt::ItemIsDropEnabled;
279 // We can edit all the groups but the default one
280 if(index.row() > 0) {
281 flags |= Qt::ItemIsEditable;
284 return flags;
287 QVariant TransferTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
289 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
291 switch (section)
293 case 0:
294 return i18nc("name of download", "Name");
295 case 1:
296 return i18nc("status of download", "Status");
297 case 2:
298 return i18nc("size of download", "Size");
299 case 3:
300 return i18nc("progress of download", "Progress");
301 case 4:
302 return i18nc("speed of download", "Speed");
303 case 5:
304 return i18nc("remaining time of download", "Remaining Time");
305 default:
306 return QVariant();
310 return QVariant();
313 QVariant TransferTreeModel::data(const QModelIndex & index, int role) const
315 // kDebug(5001) << "TransferTreeModel::data()";
317 if (!index.isValid())
319 // kDebug(5001) << " (ROOT)";
320 return QVariant();
323 // KextendableItemDelegate::ShowExtensionIndicatorRole
324 // tells the KExtendableItemDelegate which column contains the extender icon
325 if (role == Qt::UserRole + 200 && !isTransferGroup(index)) {
326 if (index.column () == 0 && Settings::showExpandableTransferDetails()) {
327 return true;
329 else {
330 return false;
334 if (role == Qt::DisplayRole || role == Qt::DecorationRole)
336 void * pointer = index.internalPointer();
338 if(isTransferGroup(index))
340 TransferGroupHandler * group = static_cast<TransferGroupHandler *>(pointer);
341 if (role == Qt::DisplayRole)
343 // kDebug(5001) << " (GROUP)";
344 //The given index refers to a group object
345 return group->data(index.column());
347 else //Qt::DecorationRole -> icon
349 if (index.column() == 0)
350 return group->pixmap();
351 else
352 return QVariant();
356 // kDebug(5001) << " (TRANSFER)";
358 //The given index refers to a transfer object
359 TransferHandler * transfer = static_cast<TransferHandler *>(pointer);
361 if (role == Qt::DisplayRole)
362 return transfer->data(index.column());
363 else //Qt::DecorationRole -> icon
365 switch (index.column())
367 case 0:
368 return KIO::pixmapForUrl(transfer->dest(), 0, KIconLoader::Desktop, 16);
369 case 1:
370 return transfer->statusPixmap();
371 default:
372 return QVariant();
377 if (role == Qt::TextAlignmentRole)
379 if(isTransferGroup(index))
381 switch (index.column())
383 case 0: // name
384 return Qt::AlignVCenter;
385 case 2: // size
386 return Qt::AlignCenter;
387 case 4: // speed
388 return Qt::AlignCenter;
389 case 3: //progress
390 return Qt::AlignCenter;
391 default:
392 return QVariant(Qt::AlignLeft | Qt::AlignBottom);
396 switch (index.column())
398 case 0: // name
399 return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
400 case 2: // size
401 return Qt::AlignCenter;
402 case 4: // speed
403 return Qt::AlignCenter;
404 case 3: //progress
405 return Qt::AlignCenter;
406 default:
407 return Qt::AlignCenter;
411 return QVariant();
414 QModelIndex TransferTreeModel::index(int row, int column, const QModelIndex & parent) const
416 // kDebug(5001) << "TransferTreeModel::index() ( " << row << " , " << column << " )";
418 if(!parent.isValid())
420 // kDebug(5001) << "TransferTreeModel::index() -> group ( " << row << " , " << column << " ) Groups=" << m_transferGroups.size();
421 //Look for the specific group
422 if(row < m_transferGroups.size() && row >= 0)
424 return createIndex(row, column, m_transferGroups[row]->handler());
427 else
428 return QModelIndex();
431 if(isTransferGroup(parent))
433 //The given parent refers to a TransferGroupHandler object
434 void * pointer = parent.internalPointer();
435 TransferGroupHandler * group = static_cast<TransferGroupHandler *>(pointer);
437 //Look for the specific transfer
438 if(row < group->size() && row >= 0)
440 // kDebug(5001) << "aa row=" << row;
441 (*group)[row];
442 // kDebug(5001) << "bb";
443 // return (*group)[row]->index(column);
444 return createIndex(row, column, (*group)[row]);
446 else
447 return QModelIndex();
450 //If here, the given parent is a Transfer object which hasn't any child
451 return QModelIndex();
454 QModelIndex TransferTreeModel::parent(const QModelIndex & index ) const
456 // kDebug(5001) << "TransferTreeModel::parent()";
458 if(!index.isValid())
459 return QModelIndex();
461 if(!isTransferGroup(index))
463 //The given index refers to a Transfer item
464 void * pointer = index.internalPointer();
465 TransferGroupHandler * group = static_cast<TransferHandler *>(pointer)->group();
466 return createIndex(m_transferGroups.indexOf(group->m_group), 0, group);
469 return QModelIndex();
472 Qt::DropActions TransferTreeModel::supportedDropActions() const
474 return Qt::CopyAction | Qt::MoveAction;
477 QStringList TransferTreeModel::mimeTypes() const
479 QStringList types;
480 types << "application/vnd.text.list";
481 return types;
484 QMimeData * TransferTreeModel::mimeData(const QModelIndexList &indexes) const
486 QMimeData * mimeData = new QMimeData();
487 QByteArray encodedData;
489 QDataStream stream(&encodedData, QIODevice::WriteOnly);
491 foreach (const QModelIndex &index, indexes)
493 if (index.isValid())
495 if(index.column() == 0 && index.parent().isValid())
497 stream << data(index.parent(), Qt::DisplayRole).toString();
498 stream << QString::number((qulonglong) index.internalPointer(),16);
503 mimeData->setData("application/vnd.text.list", encodedData);
504 return mimeData;
507 bool TransferTreeModel::dropMimeData(const QMimeData * mdata, Qt::DropAction action, int row, int column, const QModelIndex &parent)
509 if (action == Qt::IgnoreAction)
510 return true;
512 if (!mdata->hasFormat("application/vnd.text.list"))
513 return false;
515 if (column > 0)
516 return false;
518 if (parent.isValid())
519 kDebug(5001) << "TransferTreeModel::dropMimeData" << " " << row << " "
520 << column << endl;
522 QByteArray encodedData = mdata->data("application/vnd.text.list");
523 QDataStream stream(&encodedData, QIODevice::ReadOnly);
524 QStringList stringList;
525 int rows = 0;
527 while (!stream.atEnd())
529 QString text;
530 stream >> text;
531 stringList << text;
532 ++rows;
535 kDebug(5001) << "TransferTreeModel::dropMimeData DATA:";
536 kDebug(5001) << stringList;
539 for(int i=0; i < rows; i++)
541 // TransferGroup * group = findGroup(stringList[i]);
543 // TransferGroup * destGroup = static_cast<TransferGroup *>(index(row, column, parent).internalPointer());
545 TransferGroup * destGroup = findGroup(data(parent, Qt::DisplayRole).toString());
547 TransferHandler * transferHandler = (TransferHandler *) stringList[++i].toInt(0, 16);
549 if(destGroup)
550 moveTransfer(transferHandler->m_transfer, destGroup);
552 return true;
555 QString TransferTreeModel::columnName(int column)
557 switch(column) {
558 case TransferTreeModel::Name:
559 return i18n("Name");
560 case TransferTreeModel::Status:
561 return i18n("Status");
562 case TransferTreeModel::Size:
563 return i18n("Size");
564 case TransferTreeModel::Progress:
565 return i18n("Progress");
566 case TransferTreeModel::Speed:
567 return i18n("Speed");
568 case TransferTreeModel::RemainingTime:
569 return i18n("Remaining Time");
570 default:
571 return QString();
575 void TransferTreeModel::timerEvent(QTimerEvent *event)
577 Q_UNUSED(event);
578 // kDebug(5001) << "TransferTreeModel::timerEvent";
580 QList<TransferHandler *> updatedTransfers;
581 QList<TransferGroupHandler *> updatedGroups;
583 foreach(TransferHandler * transfer, m_changedTransfers)
585 if(!updatedTransfers.contains(transfer))
587 TransferGroupHandler * group = transfer->group();
588 Transfer::ChangesFlags changesFlags = transfer->changesFlags(0);
590 for(int i=0; i<8; i++)//Check the 8 most right bits of the flag
592 if (((changesFlags >> i) & 0x00000001))//remove the ith bit(s) from the right and check if the rest is 0x00000001...
594 QModelIndex index = createIndex(group->indexOf(transfer), i, transfer);
595 emit dataChanged(index,index);
599 transfer->resetChangesFlags(0);
600 updatedTransfers.append(transfer);
604 foreach(TransferGroupHandler * group, m_changedGroups)
606 if(!updatedGroups.contains(group))
608 TransferGroup::ChangesFlags changesFlags = group->changesFlags(0);
610 for(int i=0; i<8; i++)
612 if(((changesFlags >> i) & 0x00000001))
614 QModelIndex index = createIndex(m_transferGroups.indexOf(group->m_group), i, group);
615 emit dataChanged(index,index);
619 group->resetChangesFlags(0);
620 updatedGroups.append(group);
624 m_changedTransfers.clear();
625 m_changedGroups.clear();
627 killTimer(m_timerId);
628 m_timerId = -1;
631 #include "transfertreemodel.moc"