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

0001 /***************************************************************************
0002  *   Copyright (C) 2008 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 "trackermodel.h"
0022 
0023 #include <KLocalizedString>
0024 
0025 #include <interfaces/torrentinterface.h>
0026 
0027 namespace kt
0028 {
0029 
0030 TrackerModel::TrackerModel(QObject *parent)
0031     : QAbstractTableModel(parent)
0032     , tc(nullptr)
0033 {
0034     running = false;
0035 }
0036 
0037 TrackerModel::~TrackerModel()
0038 {
0039     qDeleteAll(trackers);
0040 }
0041 
0042 void TrackerModel::changeTC(bt::TorrentInterface *tc)
0043 {
0044     beginResetModel();
0045     qDeleteAll(trackers);
0046     trackers.clear();
0047     this->tc = tc;
0048     if (tc) {
0049         QList<bt::TrackerInterface *> tracker_list = tc->getTrackersList()->getTrackers();
0050         foreach (bt::TrackerInterface *trk, tracker_list) {
0051             trackers.append(new Item(trk));
0052         }
0053     }
0054 
0055     endResetModel();
0056 }
0057 
0058 void TrackerModel::update()
0059 {
0060     if (!tc)
0061         return;
0062 
0063     int idx = 0;
0064     foreach (Item *t, trackers) {
0065         if (t->update())
0066             Q_EMIT dataChanged(index(idx, 1), index(idx, 5));
0067         idx++;
0068     }
0069 
0070     running = tc->getStats().running;
0071 }
0072 
0073 int TrackerModel::rowCount(const QModelIndex &parent) const
0074 {
0075     if (parent.isValid() || !tc)
0076         return 0;
0077     else
0078         return trackers.count();
0079 }
0080 
0081 int TrackerModel::columnCount(const QModelIndex &parent) const
0082 {
0083     if (parent.isValid())
0084         return 0;
0085     else
0086         return 6;
0087 }
0088 
0089 QVariant TrackerModel::data(const QModelIndex &index, int role) const
0090 {
0091     if (!tc || !index.isValid() || index.row() < 0 || index.row() >= trackers.count())
0092         return QVariant();
0093 
0094     Item *item = (Item *)index.internalPointer();
0095     if (!item)
0096         return QVariant();
0097 
0098     bt::TrackerInterface *trk = item->trk;
0099 
0100     if (role == Qt::CheckStateRole && index.column() == 0) {
0101         return trk->isEnabled() ? Qt::Checked : Qt::Unchecked;
0102     } else if (role == Qt::DisplayRole) {
0103         return item->displayData(index.column());
0104     } else if (role == Qt::UserRole) {
0105         return item->sortData(index.column());
0106     } else if (role == Qt::ForegroundRole && index.column() == 1 && trk->trackerStatus() == bt::TRACKER_ERROR) {
0107         return QVariant::fromValue(Qt::red);
0108     }
0109 
0110     return QVariant();
0111 }
0112 
0113 bool TrackerModel::setData(const QModelIndex &index, const QVariant &value, int role)
0114 {
0115     if (!tc || !index.isValid() || index.row() < 0 || index.row() >= trackers.count())
0116         return false;
0117 
0118     if (role == Qt::CheckStateRole) {
0119         QUrl url = trackers.at(index.row())->trk->trackerURL();
0120         tc->getTrackersList()->setTrackerEnabled(url, (Qt::CheckState)value.toUInt() == Qt::Checked);
0121         return true;
0122     }
0123     return false;
0124 }
0125 
0126 QVariant TrackerModel::headerData(int section, Qt::Orientation orientation, int role) const
0127 {
0128     if (orientation != Qt::Horizontal)
0129         return QVariant();
0130 
0131     if (role == Qt::DisplayRole) {
0132         switch (section) {
0133         case 0:
0134             return i18n("Url");
0135         case 1:
0136             return i18n("Status");
0137         case 2:
0138             return i18n("Seeders");
0139         case 3:
0140             return i18n("Leechers");
0141         case 4:
0142             return i18n("Times Downloaded");
0143         case 5:
0144             return i18n("Next Update");
0145         }
0146     }
0147     return QVariant();
0148 }
0149 
0150 bool TrackerModel::insertRows(int row, int count, const QModelIndex &parent)
0151 {
0152     Q_UNUSED(parent)
0153     beginInsertRows(QModelIndex(), row, row + count - 1);
0154     if (tc) {
0155         QList<bt::TrackerInterface *> tracker_list = tc->getTrackersList()->getTrackers();
0156         QList<Item *>::iterator i = trackers.begin();
0157         foreach (bt::TrackerInterface *trk, tracker_list) {
0158             if (i != trackers.end()) {
0159                 Item *item = *i;
0160                 item->trk = trk;
0161             } else
0162                 trackers.append(new Item(trk));
0163             i++;
0164         }
0165     }
0166     endInsertRows();
0167     return true;
0168 }
0169 
0170 bool TrackerModel::removeRows(int row, int count, const QModelIndex &parent)
0171 {
0172     Q_UNUSED(parent)
0173     beginRemoveRows(QModelIndex(), row, row + count - 1);
0174     if (tc) {
0175         for (int i = 0; i < count; i++) {
0176             Item *item = trackers.takeAt(row);
0177             QUrl url = item->trk->trackerURL();
0178             tc->getTrackersList()->removeTracker(url);
0179             delete item;
0180         }
0181     }
0182     endRemoveRows();
0183     return true;
0184 }
0185 
0186 Qt::ItemFlags TrackerModel::flags(const QModelIndex &index) const
0187 {
0188     if (!tc || !index.isValid() || index.row() >= trackers.count() || index.row() < 0 || index.column() != 0)
0189         return QAbstractItemModel::flags(index);
0190     else
0191         return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
0192 }
0193 
0194 QModelIndex TrackerModel::index(int row, int column, const QModelIndex &parent) const
0195 {
0196     if (parent.isValid() || row < 0 || row >= trackers.count() || column < 0 || column >= 6)
0197         return QModelIndex();
0198     else
0199         return createIndex(row, column, trackers.at(row));
0200 }
0201 
0202 QUrl TrackerModel::trackerUrl(const QModelIndex &index)
0203 {
0204     if (!tc || !index.isValid() || index.row() < 0 || index.row() >= trackers.count())
0205         return QUrl();
0206 
0207     return ((Item *)index.internalPointer())->trk->trackerURL();
0208 }
0209 
0210 bt::TrackerInterface *TrackerModel::tracker(const QModelIndex &index)
0211 {
0212     if (!tc || !index.isValid() || index.row() < 0 || index.row() >= trackers.count())
0213         return nullptr;
0214 
0215     return ((Item *)index.internalPointer())->trk;
0216 }
0217 
0218 //////////////////////////////////////////
0219 
0220 TrackerModel::Item::Item(bt::TrackerInterface *tracker)
0221     : trk(tracker)
0222 {
0223     seeders = leechers = -1;
0224     times_downloaded = -1;
0225     time_to_next_update = 0;
0226     status = tracker->trackerStatus();
0227 }
0228 
0229 bool TrackerModel::Item::update()
0230 {
0231     bool ret = false;
0232     if (status != trk->trackerStatus()) {
0233         status = trk->trackerStatus();
0234         ret = true;
0235     }
0236 
0237     if (seeders != trk->getNumSeeders()) {
0238         seeders = trk->getNumSeeders();
0239         ret = true;
0240     }
0241 
0242     if (leechers != trk->getNumLeechers()) {
0243         leechers = trk->getNumLeechers();
0244         ret = true;
0245     }
0246 
0247     if (times_downloaded != trk->getTotalTimesDownloaded()) {
0248         times_downloaded = trk->getTotalTimesDownloaded();
0249         ret = true;
0250     }
0251 
0252     if (static_cast<bt::Uint32>(time_to_next_update) != trk->timeToNextUpdate()) {
0253         time_to_next_update = trk->timeToNextUpdate();
0254         ret = true;
0255     }
0256 
0257     return ret;
0258 }
0259 
0260 QVariant TrackerModel::Item::displayData(int column) const
0261 {
0262     switch (column) {
0263     case 0:
0264         return trk->trackerURL().toDisplayString();
0265     case 1:
0266         return trk->trackerStatusString();
0267     case 2:
0268         return seeders >= 0 ? seeders : QVariant();
0269     case 3:
0270         return leechers >= 0 ? leechers : QVariant();
0271     case 4:
0272         return times_downloaded >= 0 ? times_downloaded : QVariant();
0273     case 5: {
0274         int secs = time_to_next_update;
0275         if (secs)
0276             return QTime().addSecs(secs).toString("mm:ss");
0277         else
0278             return QVariant();
0279     }
0280     default:
0281         return QVariant();
0282     }
0283 }
0284 
0285 QVariant TrackerModel::Item::sortData(int column) const
0286 {
0287     switch (column) {
0288     case 0:
0289         return trk->trackerURL().toDisplayString();
0290     case 1:
0291         return status;
0292     case 2:
0293         return seeders;
0294     case 3:
0295         return leechers;
0296     case 4:
0297         return times_downloaded;
0298     case 5:
0299         return time_to_next_update;
0300     default:
0301         return QVariant();
0302     }
0303 }
0304 }
0305 
0306 #include "moc_trackermodel.cpp"