File indexing completed on 2023-10-01 08:39:31
0001 /* This file is part of the KDE project 0002 0003 Copyright (C) 2006 Dario Massarin <nekkar@libero.it> 0004 Copyright (C) 2009 Lukas Appelhans <l.appelhans@gmx.de> 0005 Copyright (C) 2010 Matthias Fuchs <mat69@gmx.net> 0006 0007 This program is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 */ 0012 0013 #include "core/transfertreemodel.h" 0014 0015 #include "core/kget.h" 0016 #include "core/transfergrouphandler.h" 0017 #include "core/transferhandler.h" 0018 #include "core/transfertreeselectionmodel.h" 0019 #include "dbus/dbustransferwrapper.h" 0020 #include "kget_debug.h" 0021 #include "settings.h" 0022 #include "transferadaptor.h" 0023 #include "transfergroupscheduler.h" 0024 0025 #include <algorithm> 0026 0027 #include <QDebug> 0028 0029 #include <KIO/Global> 0030 #include <KLocalizedString> 0031 0032 ItemMimeData::ItemMimeData() 0033 : QMimeData() 0034 { 0035 } 0036 0037 ItemMimeData::~ItemMimeData() 0038 { 0039 } 0040 0041 void ItemMimeData::appendTransfer(const QPointer<TransferHandler> &transfer) 0042 { 0043 m_transfers.append(transfer); 0044 } 0045 0046 QList<QPointer<TransferHandler>> ItemMimeData::transfers() const 0047 { 0048 return m_transfers; 0049 } 0050 0051 ModelItem::ModelItem(Handler *handler) 0052 : QStandardItem() 0053 , m_handler(handler) 0054 { 0055 } 0056 0057 ModelItem::~ModelItem() 0058 { 0059 } 0060 0061 void ModelItem::emitDataChanged() 0062 { 0063 QStandardItem::emitDataChanged(); 0064 } 0065 0066 Handler *ModelItem::handler() 0067 { 0068 return m_handler; 0069 } 0070 0071 bool ModelItem::isGroup() 0072 { 0073 return false; 0074 } 0075 0076 GroupModelItem *ModelItem::asGroup() 0077 { 0078 return dynamic_cast<GroupModelItem *>(this); 0079 } 0080 0081 TransferModelItem *ModelItem::asTransfer() 0082 { 0083 return dynamic_cast<TransferModelItem *>(this); 0084 } 0085 0086 TransferModelItem::TransferModelItem(TransferHandler *handler) 0087 : ModelItem(handler) 0088 , m_transferHandler(handler) 0089 { 0090 } 0091 0092 TransferModelItem::~TransferModelItem() 0093 { 0094 } 0095 0096 QVariant TransferModelItem::data(int role) const 0097 { 0098 if (role == Qt::DisplayRole) 0099 return m_transferHandler->data(column()); 0100 else if (role == Qt::DecorationRole) { 0101 switch (column()) { 0102 case 0: { 0103 // store the icon for speed improvements, KIconLoader should make sure, that 0104 // the icon data gets shared 0105 if (m_mimeType.isNull()) { 0106 m_mimeType = QIcon::fromTheme(KIO::iconNameForUrl(m_transferHandler->dest())); 0107 } 0108 0109 return m_mimeType; 0110 } 0111 case 1: 0112 return QIcon::fromTheme(m_transferHandler->statusIconName()); 0113 } 0114 } 0115 if (role == Qt::TextAlignmentRole) { 0116 switch (column()) { 0117 case 0: // name 0118 return QVariant(Qt::AlignLeft | Qt::AlignVCenter); 0119 default: 0120 return Qt::AlignCenter; 0121 } 0122 } 0123 // KextendableItemDelegate::ShowExtensionIndicatorRole 0124 // tells the KExtendableItemDelegate which column contains the extender icon 0125 if (role == Qt::UserRole + 200) { 0126 if (column() == 0) 0127 return true; 0128 else 0129 return false; 0130 } 0131 return QVariant(); 0132 } 0133 0134 TransferHandler *TransferModelItem::transferHandler() 0135 { 0136 return m_transferHandler; 0137 } 0138 0139 GroupModelItem::GroupModelItem(TransferGroupHandler *handler) 0140 : ModelItem(handler) 0141 , m_groupHandler(handler) 0142 { 0143 } 0144 0145 GroupModelItem::~GroupModelItem() 0146 { 0147 } 0148 0149 QVariant GroupModelItem::data(int role) const 0150 { 0151 if (role == Qt::DisplayRole) { 0152 return m_groupHandler->data(column()); 0153 } 0154 if (role == Qt::TextAlignmentRole) { 0155 switch (column()) { 0156 case 0: // name 0157 return Qt::AlignVCenter; 0158 case 2: // size 0159 case 3: // speed 0160 case 4: // progress 0161 return Qt::AlignCenter; 0162 default: 0163 return QVariant(Qt::AlignLeft | Qt::AlignBottom); 0164 } 0165 } 0166 if (role == Qt::DecorationRole && column() == 0) 0167 return m_groupHandler->pixmap(); 0168 return QVariant(); 0169 } 0170 0171 TransferGroupHandler *GroupModelItem::groupHandler() 0172 { 0173 // qDebug() << m_groupHandler->name(); 0174 return m_groupHandler; 0175 } 0176 0177 bool GroupModelItem::isGroup() 0178 { 0179 return true; 0180 } 0181 0182 TransferTreeModel::TransferTreeModel(Scheduler *scheduler) 0183 : QStandardItemModel() 0184 , m_scheduler(scheduler) 0185 , m_timerId(-1) 0186 { 0187 m_transferGroups.clear(); 0188 m_transfers.clear(); 0189 } 0190 0191 TransferTreeModel::~TransferTreeModel() 0192 { 0193 } 0194 0195 void TransferTreeModel::addGroup(TransferGroup *group) 0196 { 0197 QList<QStandardItem *> items; 0198 for (int i = 0; i != group->handler()->columnCount(); i++) 0199 items << new GroupModelItem(group->handler()); 0200 0201 appendRow(items); 0202 0203 m_transferGroups.append(static_cast<GroupModelItem *>(items.first())); 0204 0205 Q_EMIT groupAddedEvent(group->handler()); 0206 0207 KGet::m_scheduler->addQueue(group); 0208 } 0209 0210 void TransferTreeModel::delGroup(TransferGroup *group) 0211 { 0212 if (m_transferGroups.count() <= 1) // If there is only one group left, we should not remove it 0213 return; 0214 GroupModelItem *item = itemFromTransferGroupHandler(group->handler()); 0215 if (!item) { 0216 return; 0217 } 0218 0219 QList<Transfer *> transfers; 0220 JobQueue::iterator it; 0221 JobQueue::iterator itEnd = group->end(); 0222 for (it = group->begin(); it != itEnd; ++it) { 0223 transfers << static_cast<Transfer *>(*it); 0224 } 0225 delTransfers(transfers); 0226 0227 m_transferGroups.removeAll(item); 0228 removeRow(item->row()); 0229 0230 m_changedGroups.removeAll(group->handler()); 0231 0232 Q_EMIT groupRemovedEvent(group->handler()); 0233 0234 KGet::m_scheduler->delQueue(group); 0235 } 0236 0237 void TransferTreeModel::addTransfers(const QList<Transfer *> &transfers, TransferGroup *group) 0238 { 0239 ModelItem *parentItem = itemFromTransferGroupHandler(group->handler()); 0240 beginInsertRows(parentItem->index(), parentItem->rowCount(), parentItem->rowCount() + transfers.count() - 1); 0241 0242 // HACK blocks all signals from the model when adding multiple items, 0243 // that way rowsInserted gets only emitted once, and not constantly when doing appendRow 0244 // change this once there is a better way to append many transfers at once 0245 blockSignals(true); 0246 0247 // now create and add the new items 0248 QList<TransferHandler *> handlers; 0249 group->append(transfers); 0250 foreach (Transfer *transfer, transfers) { 0251 TransferHandler *handler = transfer->handler(); 0252 handlers << handler; 0253 0254 QList<QStandardItem *> items; 0255 for (int i = 0; i != handler->columnCount(); ++i) { 0256 items << new TransferModelItem(handler); 0257 } 0258 0259 parentItem->appendRow(items); 0260 0261 m_transfers.append(static_cast<TransferModelItem *>(items.first())); 0262 0263 auto *wrapper = new DBusTransferWrapper(handler); 0264 new TransferAdaptor(wrapper); 0265 QDBusConnection::sessionBus().registerObject(handler->dBusObjectPath(), wrapper); 0266 } 0267 0268 // notify the rest of the changes 0269 blockSignals(false); 0270 endInsertRows(); 0271 Q_EMIT transfersAddedEvent(handlers); 0272 } 0273 0274 void TransferTreeModel::delTransfers(const QList<Transfer *> &t) 0275 { 0276 QList<Transfer *> transfers = t; 0277 QList<TransferHandler *> handlers; 0278 0279 // find all valid items and sort them according to their groups 0280 QHash<TransferGroup *, QList<TransferModelItem *>> groups; 0281 QHash<TransferGroup *, QList<Transfer *>> groupsTransfer; 0282 { 0283 QList<Transfer *>::iterator it; 0284 QList<Transfer *>::iterator itEnd = transfers.end(); 0285 for (it = transfers.begin(); it != itEnd;) { 0286 TransferModelItem *item = itemFromTransferHandler((*it)->handler()); 0287 if (item) { 0288 handlers << (*it)->handler(); 0289 groups[(*it)->group()] << item; 0290 groupsTransfer[(*it)->group()] << *it; 0291 ++it; 0292 } else { 0293 it = transfers.erase(it); 0294 } 0295 } 0296 } 0297 0298 Q_EMIT transfersAboutToBeRemovedEvent(handlers); 0299 0300 // remove the items from the model 0301 { 0302 QHash<TransferGroup *, QList<TransferModelItem *>>::iterator it; 0303 QHash<TransferGroup *, QList<TransferModelItem *>>::iterator itEnd = groups.end(); 0304 for (it = groups.begin(); it != itEnd; ++it) { 0305 const int numItems = (*it).count(); 0306 QStandardItem *parentItem = (*it).first()->parent(); 0307 QModelIndex parentIndex = parentItem->index(); 0308 if (numItems == parentItem->rowCount()) { 0309 for (int i = 0; i < numItems; ++i) { 0310 m_transfers.removeAll((*it)[i]); 0311 } 0312 removeRows(0, numItems, parentIndex); 0313 continue; 0314 } 0315 0316 int rowStart = (*it).first()->row(); 0317 int numRows = 1; 0318 m_transfers.removeAll((*it).first()); 0319 for (int i = 1; i < numItems; ++i) { 0320 // previous item is neighbour 0321 if (rowStart + numRows == (*it)[i]->row()) { 0322 ++numRows; 0323 // no neighbour, so start again 0324 } else { 0325 removeRows(rowStart, numRows, parentIndex); 0326 rowStart = (*it)[i]->row(); 0327 numRows = 1; 0328 } 0329 m_transfers.removeAll((*it)[i]); 0330 } 0331 // remove last items 0332 removeRows(rowStart, numRows, parentIndex); 0333 } 0334 } 0335 0336 foreach (Transfer *transfer, transfers) { 0337 QDBusConnection::sessionBus().unregisterObject(transfer->handler()->dBusObjectPath()); 0338 m_changedTransfers.removeAll(transfer->handler()); 0339 } 0340 0341 { 0342 QHash<TransferGroup *, QList<Transfer *>>::iterator it; 0343 QHash<TransferGroup *, QList<Transfer *>>::iterator itEnd = groupsTransfer.end(); 0344 for (it = groupsTransfer.begin(); it != itEnd; ++it) { 0345 it.key()->remove(it.value()); 0346 } 0347 } 0348 0349 Q_EMIT transfersRemovedEvent(handlers); 0350 } 0351 0352 TransferModelItem *TransferTreeModel::itemFromTransferHandler(TransferHandler *handler) 0353 { 0354 foreach (TransferModelItem *item, m_transfers) { 0355 if (handler == item->transferHandler()) 0356 return item; 0357 } 0358 return nullptr; 0359 } 0360 0361 GroupModelItem *TransferTreeModel::itemFromTransferGroupHandler(TransferGroupHandler *handler) 0362 { 0363 foreach (GroupModelItem *item, m_transferGroups) { 0364 if (handler == item->groupHandler()) 0365 return item; 0366 } 0367 return nullptr; 0368 } 0369 0370 ModelItem *TransferTreeModel::itemFromHandler(Handler *handler) 0371 { 0372 auto *transfer = qobject_cast<TransferHandler *>(handler); 0373 if (transfer) { 0374 return itemFromTransferHandler(transfer); 0375 } 0376 return itemFromTransferGroupHandler(qobject_cast<TransferGroupHandler *>(handler)); 0377 } 0378 0379 ModelItem *TransferTreeModel::itemFromIndex(const QModelIndex &index) const 0380 { 0381 QStandardItem *item = QStandardItemModel::itemFromIndex(index); 0382 if (item) 0383 return dynamic_cast<ModelItem *>(item); 0384 return nullptr; 0385 } 0386 0387 void TransferTreeModel::moveTransfer(Transfer *transfer, TransferGroup *destGroup, Transfer *after) 0388 { 0389 if ((after) && (destGroup != after->group())) 0390 return; 0391 0392 int position = transfer->group()->indexOf(transfer); 0393 0394 TransferGroup *oldGroup = transfer->group(); 0395 0396 bool sameGroup = false; 0397 0398 if (destGroup == transfer->group()) { 0399 sameGroup = true; 0400 if (after) 0401 destGroup->move(transfer, after); 0402 else 0403 destGroup->move(transfer, nullptr); 0404 } else { 0405 transfer->group()->remove(transfer); 0406 0407 if (after) 0408 destGroup->insert(transfer, after); 0409 else 0410 destGroup->prepend(transfer); 0411 0412 transfer->m_jobQueue = destGroup; 0413 } 0414 QList<QStandardItem *> items = itemFromHandler(oldGroup->handler())->takeRow(position); 0415 itemFromHandler(destGroup->handler())->insertRow(destGroup->indexOf(transfer), items); 0416 0417 if (!sameGroup) 0418 Q_EMIT transferMovedEvent(transfer->handler(), destGroup->handler()); 0419 0420 KGet::selectionModel()->clearSelection(); 0421 } 0422 0423 void TransferTreeModel::moveTransfer(TransferHandler *transfer, TransferGroupHandler *destGroup, TransferHandler *after) 0424 { 0425 Transfer *afterTransfer = nullptr; 0426 if (after) { 0427 afterTransfer = after->m_transfer; 0428 } 0429 moveTransfer(transfer->m_transfer, destGroup->m_group, afterTransfer); 0430 } 0431 0432 QList<TransferGroup *> TransferTreeModel::transferGroups() 0433 { 0434 QList<TransferGroup *> transferGroups; 0435 foreach (GroupModelItem *item, m_transferGroups) { 0436 transferGroups << item->groupHandler()->m_group; 0437 } 0438 0439 return transferGroups; 0440 } 0441 0442 TransferGroup *TransferTreeModel::findGroup(const QString &groupName) 0443 { 0444 foreach (GroupModelItem *group, m_transferGroups) { 0445 if (group->groupHandler()->name() == groupName) 0446 return group->groupHandler()->m_group; 0447 } 0448 return nullptr; 0449 } 0450 0451 Transfer *TransferTreeModel::findTransfer(const QUrl &src) 0452 { 0453 /*foreach (TransferGroup * group, transferGroups()) 0454 { 0455 Transfer * t = group->findTransfer(src); 0456 if (t) 0457 return t; 0458 }*/ 0459 foreach (TransferModelItem *transfer, m_transfers) { 0460 if (transfer->transferHandler()->source() == src) 0461 return transfer->transferHandler()->m_transfer; 0462 } 0463 return nullptr; 0464 } 0465 0466 Transfer *TransferTreeModel::findTransferByDestination(const QUrl &dest) 0467 { 0468 /*foreach (TransferGroup * group, transferGroups()) 0469 { 0470 Transfer * t = group->findTransferByDestination(dest); 0471 if (t) 0472 return t; 0473 }*/ 0474 foreach (TransferModelItem *transfer, m_transfers) { 0475 if (transfer->transferHandler()->dest() == dest) 0476 return transfer->transferHandler()->m_transfer; 0477 } 0478 return nullptr; 0479 } 0480 0481 Transfer *TransferTreeModel::findTransferByDBusObjectPath(const QString &dbusObjectPath) 0482 { 0483 foreach (TransferModelItem *transfer, m_transfers) { 0484 if (transfer->transferHandler()->dBusObjectPath() == dbusObjectPath) 0485 return transfer->transferHandler()->m_transfer; 0486 } 0487 return nullptr; 0488 } 0489 0490 void TransferTreeModel::postDataChangedEvent(TransferHandler *transfer) 0491 { 0492 if (m_timerId == -1) 0493 m_timerId = startTimer(500); 0494 0495 m_changedTransfers.append(transfer); 0496 } 0497 0498 void TransferTreeModel::postDataChangedEvent(TransferGroupHandler *group) 0499 { 0500 if (m_timerId == -1) 0501 m_timerId = startTimer(500); 0502 0503 m_changedGroups.append(group); 0504 } 0505 0506 Qt::ItemFlags TransferTreeModel::flags(const QModelIndex &index) const 0507 { 0508 // qCDebug(KGET_DEBUG) << "TransferTreeModel::flags()"; 0509 if (!index.isValid()) 0510 return Qt::ItemIsEnabled; 0511 0512 Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; 0513 0514 if (!index.parent().isValid()) { 0515 if (index.column() == 0) 0516 flags |= Qt::ItemIsDropEnabled; 0517 } else 0518 flags |= Qt::ItemIsDragEnabled; 0519 0520 // flags |= Qt::ItemIsDropEnabled; 0521 0522 // We can edit all the groups but the default one 0523 if (index.row() > 0) { 0524 flags |= Qt::ItemIsEditable; 0525 } 0526 0527 return flags; 0528 } 0529 0530 QVariant TransferTreeModel::headerData(int section, Qt::Orientation orientation, int role) const 0531 { 0532 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { 0533 return columnName(section); 0534 } 0535 0536 return QVariant(); 0537 } 0538 0539 Qt::DropActions TransferTreeModel::supportedDropActions() const 0540 { 0541 return Qt::CopyAction | Qt::MoveAction; 0542 } 0543 0544 QStringList TransferTreeModel::mimeTypes() const 0545 { 0546 QStringList types; 0547 types << "kget/transfer_pointer"; 0548 return types; 0549 } 0550 0551 QMimeData *TransferTreeModel::mimeData(const QModelIndexList &indexes) const 0552 { 0553 auto *mimeData = new ItemMimeData(); 0554 0555 QModelIndexList sortedIndexes = indexes; 0556 std::sort(sortedIndexes.begin(), sortedIndexes.end(), [](const QModelIndex &a, const QModelIndex &b) { 0557 return b < a; 0558 }); 0559 foreach (const QModelIndex &index, sortedIndexes) { 0560 if (index.isValid() && index.column() == 0 && index.parent().isValid()) { 0561 ModelItem *item = itemFromIndex(index); 0562 if (!item->isGroup()) { 0563 mimeData->appendTransfer(QPointer<TransferHandler>(item->asTransfer()->transferHandler())); 0564 } 0565 } 0566 } 0567 0568 mimeData->setData("kget/transfer_pointer", QByteArray()); 0569 return mimeData; 0570 } 0571 0572 bool TransferTreeModel::dropMimeData(const QMimeData *mdata, Qt::DropAction action, int row, int column, const QModelIndex &parent) 0573 { 0574 if (action == Qt::IgnoreAction) 0575 return true; 0576 0577 const auto *itemData = qobject_cast<const ItemMimeData *>(mdata); 0578 if (!itemData) { 0579 qCWarning(KGET_DEBUG) << "Unsupported mime data dropped."; 0580 return false; 0581 } 0582 0583 TransferGroup *destGroup = findGroup(data(parent, Qt::DisplayRole).toString()); 0584 if (!destGroup) { 0585 qCWarning(KGET_DEBUG) << "No group could be found where the transfers should be inserted to."; 0586 return false; 0587 } 0588 0589 if (parent.isValid()) 0590 qCDebug(KGET_DEBUG) << "TransferTreeModel::dropMimeData" 0591 << " " << row << " " << column; 0592 0593 QList<QPointer<TransferHandler>> transfers = itemData->transfers(); 0594 qCDebug(KGET_DEBUG) << "TransferTreeModel::dropMimeData:" << transfers.count() << "transfers."; 0595 0596 const bool droppedInsideGroup = parent.isValid(); 0597 Transfer *after = nullptr; 0598 for (int i = 0; i < transfers.count(); ++i) { 0599 bool b = destGroup->size() > row && row - 1 >= 0; 0600 if (b) 0601 qCDebug(KGET_DEBUG) << "TRANSFER AFTER:" << destGroup->operator[](row - 1)->source(); 0602 else 0603 qCDebug(KGET_DEBUG) << "TRANSFER AFTER NOT EXISTING"; 0604 0605 if (!after) { 0606 bool rowValid = (row - 1 >= 0) && (destGroup->size() >= row); 0607 if (droppedInsideGroup && rowValid) { 0608 after = destGroup->operator[](row - 1); // insert at the correct position 0609 } 0610 } 0611 0612 if (transfers[i].isNull()) { 0613 qWarning() << "The moved transfer has been deleted inbetween."; 0614 } else { 0615 moveTransfer(transfers[i].data()->m_transfer, destGroup, after); 0616 } 0617 } 0618 return true; 0619 } 0620 0621 QString TransferTreeModel::columnName(int column) 0622 { 0623 switch (column) { 0624 case 0: 0625 return i18nc("name of download", "Name"); 0626 case 1: 0627 return i18nc("status of download", "Status"); 0628 case 2: 0629 return i18nc("size of download", "Size"); 0630 case 3: 0631 return i18nc("progress of download", "Progress"); 0632 case 4: 0633 return i18nc("speed of download", "Speed"); 0634 case 5: 0635 return i18nc("remaining time of download", "Remaining Time"); 0636 } 0637 return QString(); 0638 } 0639 0640 int TransferTreeModel::column(Transfer::TransferChange flag) 0641 { 0642 switch (flag) { 0643 case Transfer::Tc_FileName: 0644 return 0; 0645 case Transfer::Tc_Status: 0646 return 1; 0647 case Transfer::Tc_TotalSize: 0648 return 2; 0649 case Transfer::Tc_Percent: 0650 return 3; 0651 case Transfer::Tc_DownloadSpeed: 0652 return 4; 0653 case Transfer::Tc_RemainingTime: 0654 return 5; 0655 default: 0656 return -1; 0657 } 0658 return -1; 0659 } 0660 0661 int TransferTreeModel::column(TransferGroup::GroupChange flag) 0662 { 0663 switch (flag) { 0664 case TransferGroup::Gc_GroupName: 0665 return 0; 0666 case TransferGroup::Gc_Status: 0667 return 1; 0668 case TransferGroup::Gc_TotalSize: 0669 return 2; 0670 case TransferGroup::Gc_Percent: 0671 return 3; 0672 case TransferGroup::Gc_DownloadSpeed: 0673 return 4; 0674 default: 0675 return -1; 0676 } 0677 return -1; 0678 } 0679 0680 void TransferTreeModel::timerEvent(QTimerEvent *event) 0681 { 0682 Q_UNUSED(event) 0683 // qCDebug(KGET_DEBUG) << "TransferTreeModel::timerEvent"; 0684 0685 QMap<TransferHandler *, Transfer::ChangesFlags> updatedTransfers; 0686 QMap<TransferGroupHandler *, TransferGroup::ChangesFlags> updatedGroups; 0687 0688 foreach (TransferHandler *transfer, m_changedTransfers) { 0689 if (!updatedTransfers.contains(transfer)) { 0690 TransferGroupHandler *group = transfer->group(); 0691 ModelItem *item = itemFromHandler(group); 0692 Transfer::ChangesFlags changesFlags = transfer->changesFlags(); 0693 0694 Q_EMIT transfer->transferChangedEvent(transfer, changesFlags); 0695 0696 int row = group->indexOf(transfer); 0697 0698 // qCDebug(KGET_DEBUG) << "CHILD = " << item->child(row, column(Transfer::Tc_FileName)); 0699 0700 // Now, check that model child items already exist (there are some cases when the transfer 0701 // can notify for changes before the gui has been correctly initialized) 0702 if (item->child(row, 0)) { 0703 if (changesFlags & Transfer::Tc_FileName) 0704 static_cast<ModelItem *>(item->child(row, column(Transfer::Tc_FileName)))->emitDataChanged(); 0705 if (changesFlags & Transfer::Tc_Status) 0706 static_cast<ModelItem *>(item->child(row, column(Transfer::Tc_Status)))->emitDataChanged(); 0707 if (changesFlags & Transfer::Tc_TotalSize) 0708 static_cast<ModelItem *>(item->child(row, column(Transfer::Tc_TotalSize)))->emitDataChanged(); 0709 if (changesFlags & Transfer::Tc_Percent) 0710 static_cast<ModelItem *>(item->child(row, column(Transfer::Tc_Percent)))->emitDataChanged(); 0711 if (changesFlags & Transfer::Tc_DownloadSpeed) 0712 static_cast<ModelItem *>(item->child(row, column(Transfer::Tc_DownloadSpeed)))->emitDataChanged(); 0713 if (changesFlags & Transfer::Tc_RemainingTime) 0714 static_cast<ModelItem *>(item->child(row, column(Transfer::Tc_RemainingTime)))->emitDataChanged(); 0715 0716 transfer->resetChangesFlags(); 0717 updatedTransfers.insert(transfer, changesFlags); 0718 } 0719 } 0720 } 0721 0722 if (!updatedTransfers.isEmpty()) 0723 Q_EMIT transfersChangedEvent(updatedTransfers); 0724 0725 foreach (TransferGroupHandler *group, m_changedGroups) { 0726 if (!updatedGroups.contains(group)) { 0727 TransferGroup::ChangesFlags changesFlags = group->changesFlags(); 0728 0729 Q_EMIT group->groupChangedEvent(group, changesFlags); 0730 0731 int row = itemFromHandler(group)->row(); 0732 0733 if (changesFlags & TransferGroup::Gc_GroupName) 0734 static_cast<ModelItem *>(item(row, column(TransferGroup::Gc_GroupName)))->emitDataChanged(); 0735 if (changesFlags & TransferGroup::Gc_Status) 0736 static_cast<ModelItem *>(item(row, column(TransferGroup::Gc_Status)))->emitDataChanged(); 0737 if (changesFlags & TransferGroup::Gc_TotalSize) 0738 static_cast<ModelItem *>(item(row, column(TransferGroup::Gc_TotalSize)))->emitDataChanged(); 0739 if (changesFlags & TransferGroup::Gc_Percent) 0740 static_cast<ModelItem *>(item(row, column(TransferGroup::Gc_Percent)))->emitDataChanged(); 0741 if (changesFlags & TransferGroup::Gc_DownloadSpeed) 0742 static_cast<ModelItem *>(item(row, column(TransferGroup::Gc_DownloadSpeed)))->emitDataChanged(); 0743 0744 /*for(int i=0; i<8; i++) 0745 { 0746 if(((changesFlags >> i) & 0x00000001)) 0747 { 0748 QStandardItem *groupItem = itemFromHandler(group); 0749 dynamic_cast<ModelItem*>(invisibleRootItem()->child(groupItem->row(), i))->emitDataChanged(); 0750 //QModelIndex index = createIndex(m_transferGroups.indexOf(group->m_group), i, group); 0751 //Q_EMIT dataChanged(index,index); 0752 } 0753 }*/ 0754 0755 group->resetChangesFlags(); 0756 updatedGroups.insert(group, changesFlags); 0757 } 0758 } 0759 0760 if (!updatedGroups.isEmpty()) 0761 Q_EMIT groupsChangedEvent(updatedGroups); 0762 0763 m_changedTransfers.clear(); 0764 m_changedGroups.clear(); 0765 0766 killTimer(m_timerId); 0767 m_timerId = -1; 0768 } 0769 0770 #include "moc_transfertreemodel.cpp"