File indexing completed on 2024-05-12 04:59:20
0001 /*************************************************************************** 0002 * Copyright (C) 2007 by Joris Guisson and Ivan Vasic * 0003 * joris.guisson@gmail.com * 0004 * ivasic@gmail.com * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 * This program is distributed in the hope that it will be useful, * 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0014 * GNU General Public License for more details. * 0015 * * 0016 * You should have received a copy of the GNU General Public License * 0017 * along with this program; if not, write to the * 0018 * Free Software Foundation, Inc., * 0019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 0020 ***************************************************************************/ 0021 #include "iwfiletreemodel.h" 0022 0023 #include <KLocalizedString> 0024 #include <cmath> 0025 0026 #include <interfaces/torrentfileinterface.h> 0027 #include <interfaces/torrentinterface.h> 0028 #include <util/functions.h> 0029 0030 using namespace bt; 0031 0032 namespace kt 0033 { 0034 0035 IWFileTreeModel::IWFileTreeModel(bt::TorrentInterface *tc, QObject *parent) 0036 : TorrentFileTreeModel(tc, KEEP_FILES, parent) 0037 { 0038 mmfile = IsMultimediaFile(tc->getStats().output_path); 0039 preview = false; 0040 percentage = 0; 0041 0042 if (root) { 0043 BitSet d = tc->downloadedChunksBitSet(); 0044 d -= tc->onlySeedChunksBitSet(); 0045 root->initPercentage(tc, d); 0046 } 0047 } 0048 0049 IWFileTreeModel::~IWFileTreeModel() 0050 { 0051 } 0052 0053 int IWFileTreeModel::columnCount(const QModelIndex & /*parent*/) const 0054 { 0055 return 5; 0056 } 0057 0058 QVariant IWFileTreeModel::headerData(int section, Qt::Orientation orientation, int role) const 0059 { 0060 if (role != Qt::DisplayRole || orientation != Qt::Horizontal) 0061 return QVariant(); 0062 0063 if (section < 2) 0064 return TorrentFileTreeModel::headerData(section, orientation, role); 0065 0066 switch (section) { 0067 case 2: 0068 return i18n("Priority"); 0069 case 3: 0070 return i18n("Preview"); 0071 // xgettext: no-c-format 0072 case 4: 0073 return i18nc("Percent of File Downloaded", "% Complete"); 0074 default: 0075 return QVariant(); 0076 } 0077 } 0078 0079 static QString PriorityString(const bt::TorrentFileInterface *file) 0080 { 0081 switch (file->getPriority()) { 0082 case FIRST_PREVIEW_PRIORITY: 0083 case FIRST_PRIORITY: 0084 return i18nc("Download first", "First"); 0085 case LAST_PREVIEW_PRIORITY: 0086 case LAST_PRIORITY: 0087 return i18nc("Download last", "Last"); 0088 case ONLY_SEED_PRIORITY: 0089 case EXCLUDED: 0090 return QString(); 0091 case NORMAL_PREVIEW_PRIORITY: 0092 default: 0093 return i18nc("Download normally(not as first or last)", "Normal"); 0094 } 0095 } 0096 0097 QVariant IWFileTreeModel::data(const QModelIndex &index, int role) const 0098 { 0099 Node *n = nullptr; 0100 if (index.column() < 2 && role != Qt::ForegroundRole) 0101 return TorrentFileTreeModel::data(index, role); 0102 0103 if (!index.isValid() || !(n = (Node *)index.internalPointer())) 0104 return QVariant(); 0105 0106 if (role == Qt::ForegroundRole && index.column() == 2 && tc->getStats().multi_file_torrent && n->file) 0107 return QVariant(); 0108 0109 if (role == Qt::DisplayRole) 0110 return displayData(n, index); 0111 else if (role == Qt::UserRole) 0112 return sortData(n, index); 0113 0114 return QVariant(); 0115 } 0116 0117 QVariant IWFileTreeModel::displayData(Node *n, const QModelIndex &index) const 0118 { 0119 if (tc->getStats().multi_file_torrent && n->file) { 0120 const bt::TorrentFileInterface *file = n->file; 0121 switch (index.column()) { 0122 case 2: 0123 return PriorityString(file); 0124 case 3: 0125 if (file->isMultimedia()) { 0126 if (file->isPreviewAvailable()) 0127 return i18nc("preview available", "Available"); 0128 else 0129 return i18nc("Preview pending", "Pending"); 0130 } else 0131 return i18nc("No preview available", "No"); 0132 case 4: 0133 if (file->getPriority() == ONLY_SEED_PRIORITY || file->getPriority() == EXCLUDED) 0134 return QVariant(); 0135 else 0136 return ki18n("%1 %").subs(n->percentage, 0, 'f', 2).toString(); 0137 default: 0138 return QVariant(); 0139 } 0140 } else if (!tc->getStats().multi_file_torrent) { 0141 switch (index.column()) { 0142 case 2: 0143 return QVariant(); 0144 case 3: 0145 if (mmfile) { 0146 if (tc->readyForPreview()) 0147 return i18nc("Preview available", "Available"); 0148 else 0149 return i18nc("Preview pending", "Pending"); 0150 } else 0151 return i18nc("No preview available", "No"); 0152 case 4: 0153 return ki18n("%1 %").subs(bt::Percentage(tc->getStats()), 0, 'f', 2).toString(); 0154 default: 0155 return QVariant(); 0156 } 0157 } else if (tc->getStats().multi_file_torrent && index.column() == 4) { 0158 return ki18n("%1 %").subs(n->percentage, 0, 'f', 2).toString(); 0159 } 0160 0161 return QVariant(); 0162 } 0163 0164 QVariant IWFileTreeModel::sortData(Node *n, const QModelIndex &index) const 0165 { 0166 if (tc->getStats().multi_file_torrent && n->file) { 0167 const bt::TorrentFileInterface *file = n->file; 0168 switch (index.column()) { 0169 case 2: 0170 return (int)file->getPriority(); 0171 case 3: 0172 if (file->isMultimedia()) { 0173 if (file->isPreviewAvailable()) 0174 return 3; 0175 else 0176 return 2; 0177 } else 0178 return 1; 0179 case 4: 0180 return n->percentage; 0181 } 0182 } else if (!tc->getStats().multi_file_torrent) { 0183 switch (index.column()) { 0184 case 2: 0185 return QVariant(); 0186 case 3: 0187 if (mmfile) { 0188 if (tc->readyForPreview()) 0189 return 3; 0190 else 0191 return 2; 0192 } else 0193 return 1; 0194 case 4: 0195 return bt::Percentage(tc->getStats()); 0196 } 0197 } else if (tc->getStats().multi_file_torrent && index.column() == 4) { 0198 return n->percentage; 0199 } 0200 0201 return QVariant(); 0202 } 0203 0204 bool IWFileTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) 0205 { 0206 if (role == Qt::CheckStateRole) 0207 return TorrentFileTreeModel::setData(index, value, role); 0208 0209 if (!index.isValid() || role != Qt::UserRole) 0210 return false; 0211 0212 Node *n = static_cast<Node *>(index.internalPointer()); 0213 if (!n) 0214 return false; 0215 0216 if (!n->file) { 0217 for (int i = 0; i < n->children.count(); i++) { 0218 // recurse down the tree 0219 setData(index.model()->index(i, 0), value, role); 0220 } 0221 } else { 0222 bt::TorrentFileInterface *file = n->file; 0223 auto prio = (bt::Priority)value.toInt(); 0224 Priority old = file->getPriority(); 0225 0226 if (prio != old) { 0227 file->setPriority(prio); 0228 dataChanged(createIndex(index.row(), 0), createIndex(index.row(), 4)); 0229 QModelIndex parent = index.parent(); 0230 if (parent.isValid()) 0231 dataChanged(parent, parent); // parent needs to be updated to 0232 } 0233 } 0234 0235 return true; 0236 } 0237 0238 void IWFileTreeModel::filePercentageChanged(bt::TorrentFileInterface *file, float percentage) 0239 { 0240 Q_UNUSED(percentage) 0241 update(index(0, 0, QModelIndex()), file, 4); 0242 } 0243 0244 void IWFileTreeModel::filePreviewChanged(bt::TorrentFileInterface *file, bool preview) 0245 { 0246 Q_UNUSED(preview) 0247 update(index(0, 0, QModelIndex()), file, 3); 0248 } 0249 0250 void IWFileTreeModel::update(const QModelIndex &idx, bt::TorrentFileInterface *file, int col) 0251 { 0252 Node *n = (Node *)idx.internalPointer(); 0253 if (n->file && n->file == file) { 0254 QModelIndex i = createIndex(idx.row(), col, n); 0255 Q_EMIT dataChanged(i, i); 0256 if (col == 4) { 0257 // update percentages along the tree 0258 // this will go back up the tree and update the percentage of 0259 // all directories involved 0260 BitSet d = tc->downloadedChunksBitSet(); 0261 d -= tc->onlySeedChunksBitSet(); 0262 n->updatePercentage(d); 0263 0264 // Q_EMIT necessary signals 0265 QModelIndex parent = idx.parent(); 0266 while (parent.isValid()) { 0267 Node *nd = (Node *)parent.internalPointer(); 0268 i = createIndex(parent.row(), 4, nd); 0269 Q_EMIT dataChanged(i, i); 0270 parent = parent.parent(); 0271 } 0272 } 0273 } else { 0274 for (int i = 0; i < n->children.count(); i++) { 0275 // recurse down the tree 0276 update(idx.model()->index(i, 0), file, col); 0277 } 0278 } 0279 } 0280 0281 void IWFileTreeModel::update() 0282 { 0283 if (!tc->getStats().multi_file_torrent) { 0284 bool changed = false; 0285 bool np = mmfile && tc->readyForPreview(); 0286 if (preview != np) { 0287 preview = np; 0288 changed = true; 0289 } 0290 0291 double perc = bt::Percentage(tc->getStats()); 0292 if (fabs(perc - percentage) > 0.01) { 0293 percentage = perc; 0294 changed = true; 0295 } 0296 0297 if (changed) 0298 dataChanged(createIndex(0, 2), createIndex(0, 4)); 0299 } 0300 } 0301 } 0302 0303 #include "moc_iwfiletreemodel.cpp"