File indexing completed on 2024-05-05 04:59:13

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 "torrentfilelistmodel.h"
0022 
0023 #include <QIcon>
0024 #include <QMimeDatabase>
0025 #include <QMimeType>
0026 #include <QTreeView>
0027 
0028 #include <KLocalizedString>
0029 
0030 #include <interfaces/torrentfileinterface.h>
0031 #include <interfaces/torrentinterface.h>
0032 #include <util/functions.h>
0033 
0034 using namespace bt;
0035 
0036 namespace kt
0037 {
0038 
0039 TorrentFileListModel::TorrentFileListModel(bt::TorrentInterface *tc, DeselectMode mode, QObject *parent)
0040     : TorrentFileModel(tc, mode, parent)
0041 {
0042 }
0043 
0044 TorrentFileListModel::~TorrentFileListModel()
0045 {
0046 }
0047 
0048 int TorrentFileListModel::rowCount(const QModelIndex &parent) const
0049 {
0050     if (!parent.isValid())
0051         return tc->getStats().multi_file_torrent ? tc->getNumFiles() : 1;
0052     else
0053         return 0;
0054 }
0055 
0056 int TorrentFileListModel::columnCount(const QModelIndex &parent) const
0057 {
0058     if (!parent.isValid())
0059         return 2;
0060     else
0061         return 0;
0062 }
0063 
0064 QVariant TorrentFileListModel::headerData(int section, Qt::Orientation orientation, int role) const
0065 {
0066     if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
0067         return QVariant();
0068 
0069     switch (section) {
0070     case 0:
0071         return i18n("File");
0072     case 1:
0073         return i18n("Size");
0074     default:
0075         return QVariant();
0076     }
0077 }
0078 
0079 QVariant TorrentFileListModel::data(const QModelIndex &index, int role) const
0080 {
0081     if (!index.isValid())
0082         return QVariant();
0083 
0084     int r = index.row();
0085     int nfiles = rowCount(QModelIndex());
0086     bool multi = tc->getStats().multi_file_torrent;
0087     if (r < 0 || r >= nfiles)
0088         return QVariant();
0089 
0090     const TorrentStats &s = tc->getStats();
0091     if (role == Qt::DisplayRole || role == Qt::EditRole) {
0092         switch (index.column()) {
0093         case 0:
0094             if (multi)
0095                 return tc->getTorrentFile(r).getUserModifiedPath();
0096             else
0097                 return tc->getUserModifiedFileName();
0098         case 1:
0099             if (multi)
0100                 return BytesToString(tc->getTorrentFile(r).getSize());
0101             else
0102                 return BytesToString(s.total_bytes);
0103         default:
0104             return QVariant();
0105         }
0106     } else if (role == Qt::UserRole) // sorting
0107     {
0108         switch (index.column()) {
0109         case 0:
0110             if (multi)
0111                 return tc->getTorrentFile(r).getUserModifiedPath();
0112             else
0113                 return tc->getUserModifiedFileName();
0114         case 1:
0115             if (multi)
0116                 return tc->getTorrentFile(r).getSize();
0117             else
0118                 return s.total_bytes;
0119         default:
0120             return QVariant();
0121         }
0122     } else if (role == Qt::DecorationRole && index.column() == 0) {
0123         // if this is an empty folder then we are in the single file case
0124         QMimeDatabase db;
0125         if (multi)
0126             return QIcon::fromTheme(db.mimeTypeForFile(tc->getTorrentFile(r).getPath()).iconName());
0127         else
0128             return QIcon::fromTheme(db.mimeTypeForFile(s.torrent_name).iconName());
0129     } else if (role == Qt::CheckStateRole && index.column() == 0) {
0130         if (multi)
0131             return tc->getTorrentFile(r).doNotDownload() ? Qt::Unchecked : Qt::Checked;
0132         ;
0133     }
0134 
0135     return QVariant();
0136 }
0137 
0138 QModelIndex TorrentFileListModel::parent(const QModelIndex &index) const
0139 {
0140     Q_UNUSED(index)
0141     return QModelIndex();
0142 }
0143 
0144 QModelIndex TorrentFileListModel::index(int row, int column, const QModelIndex &parent) const
0145 {
0146     if (!hasIndex(row, column, parent))
0147         return QModelIndex();
0148     else {
0149         bt::TorrentFileInterface *f = &tc->getTorrentFile(row);
0150         return createIndex(row, column, f);
0151     }
0152 }
0153 
0154 bool TorrentFileListModel::setData(const QModelIndex &index, const QVariant &value, int role)
0155 {
0156     if (!index.isValid())
0157         return false;
0158 
0159     if (role == Qt::CheckStateRole) {
0160         auto newState = static_cast<Qt::CheckState>(value.toInt());
0161         bt::TorrentFileInterface &file = tc->getTorrentFile(index.row());
0162         if (newState == Qt::Checked) {
0163             if (file.getPriority() == ONLY_SEED_PRIORITY)
0164                 file.setPriority(NORMAL_PRIORITY);
0165             else
0166                 file.setDoNotDownload(false);
0167         } else {
0168             if (mode == KEEP_FILES)
0169                 file.setPriority(ONLY_SEED_PRIORITY);
0170             else
0171                 file.setDoNotDownload(true);
0172         }
0173         dataChanged(createIndex(index.row(), 0), createIndex(index.row(), columnCount(index) - 1));
0174         checkStateChanged();
0175         return true;
0176     } else if (role == Qt::EditRole) {
0177         QString path = value.toString();
0178         if (path.isEmpty())
0179             return false;
0180 
0181         if (tc->getStats().multi_file_torrent) {
0182             bt::TorrentFileInterface &file = tc->getTorrentFile(index.row());
0183             // keep track of modified paths
0184             file.setUserModifiedPath(path);
0185         } else {
0186             // change the name of the file or toplevel directory
0187             tc->setUserModifiedFileName(path);
0188         }
0189         dataChanged(createIndex(index.row(), 0), createIndex(index.row(), columnCount(index) - 1));
0190         return true;
0191     }
0192 
0193     return false;
0194 }
0195 
0196 void TorrentFileListModel::checkAll()
0197 {
0198     if (tc->getStats().multi_file_torrent) {
0199         for (Uint32 i = 0; i < tc->getNumFiles(); ++i)
0200             setData(index(i, 0, QModelIndex()), Qt::Checked, Qt::CheckStateRole);
0201     }
0202 }
0203 
0204 void TorrentFileListModel::uncheckAll()
0205 {
0206     if (tc->getStats().multi_file_torrent) {
0207         for (Uint32 i = 0; i < tc->getNumFiles(); ++i)
0208             setData(index(i, 0, QModelIndex()), Qt::Unchecked, Qt::CheckStateRole);
0209     }
0210 }
0211 
0212 void TorrentFileListModel::invertCheck()
0213 {
0214     if (!tc->getStats().multi_file_torrent)
0215         return;
0216 
0217     for (Uint32 i = 0; i < tc->getNumFiles(); ++i)
0218         invertCheck(index(i, 0, QModelIndex()));
0219 }
0220 
0221 void TorrentFileListModel::invertCheck(const QModelIndex &idx)
0222 {
0223     if (tc->getTorrentFile(idx.row()).doNotDownload())
0224         setData(idx, Qt::Checked, Qt::CheckStateRole);
0225     else
0226         setData(idx, Qt::Unchecked, Qt::CheckStateRole);
0227 }
0228 
0229 bt::Uint64 TorrentFileListModel::bytesToDownload()
0230 {
0231     if (tc->getStats().multi_file_torrent) {
0232         bt::Uint64 ret = 0;
0233         for (Uint32 i = 0; i < tc->getNumFiles(); ++i) {
0234             const bt::TorrentFileInterface &file = tc->getTorrentFile(i);
0235             if (!file.doNotDownload())
0236                 ret += file.getSize();
0237         }
0238         return ret;
0239     } else
0240         return tc->getStats().total_bytes;
0241 }
0242 
0243 bt::TorrentFileInterface *TorrentFileListModel::indexToFile(const QModelIndex &idx)
0244 {
0245     if (!idx.isValid())
0246         return nullptr;
0247 
0248     int r = idx.row();
0249     if (r < 0 || r >= rowCount(QModelIndex()))
0250         return nullptr;
0251     else
0252         return &tc->getTorrentFile(r);
0253 }
0254 
0255 QString TorrentFileListModel::dirPath(const QModelIndex &idx)
0256 {
0257     if (!idx.isValid())
0258         return QString();
0259 
0260     int r = idx.row();
0261     if (r < 0 || r >= rowCount(QModelIndex()))
0262         return QString();
0263     else
0264         return tc->getTorrentFile(r).getPath();
0265 }
0266 
0267 void TorrentFileListModel::changePriority(const QModelIndexList &indexes, bt::Priority newpriority)
0268 {
0269     foreach (const QModelIndex &idx, indexes) {
0270         setData(idx, newpriority, Qt::UserRole);
0271     }
0272 }
0273 }
0274 
0275 #include "moc_torrentfilelistmodel.cpp"