source: trunk/qt/torrent-filter.cc @ 14225

Last change on this file since 14225 was 14225, checked in by jordan, 9 years ago

Licensing changes:

  1. add the option the code to be used under GPLv2 or GPLv3; previously only GPLv2 was allowed
  1. add the "proxy option" as described in GPLv3 so we can add future licenses without having to bulk-edit everything again :)
  1. remove the awkward "exception for MIT code in Mac client" clause; it was unnecessary and confusing.
  • Property svn:keywords set to Date Rev Author Id
File size: 6.6 KB
Line 
1/*
2 * This file Copyright (C) 2009-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU Public License v2 or v3 licenses,
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: torrent-filter.cc 14225 2014-01-19 01:09:44Z jordan $
8 */
9
10#include <algorithm>
11#include <iostream>
12
13#include "filters.h"
14#include "hig.h"
15#include "prefs.h"
16#include "torrent.h"
17#include "torrent-filter.h"
18#include "torrent-model.h"
19#include "utils.h"
20
21TorrentFilter :: TorrentFilter (Prefs& prefs):
22  myPrefs (prefs)
23{
24  // listen for changes to the preferences to know when to refilter / resort
25  connect (&myPrefs, SIGNAL(changed(int)), this, SLOT(refreshPref(int)));
26
27  setDynamicSortFilter (true);
28
29  // initialize our state from the current prefs
30  QList<int> initKeys;
31  initKeys << Prefs :: SORT_MODE
32           << Prefs :: FILTER_MODE
33           << Prefs :: FILTER_TRACKERS
34           << Prefs :: FILTER_TEXT;
35  foreach (int key, initKeys)
36    refreshPref (key);
37}
38
39TorrentFilter :: ~TorrentFilter ()
40{
41}
42
43void
44TorrentFilter :: refreshPref (int key)
45{
46  switch (key)
47    {
48      case Prefs :: FILTER_TEXT:
49      case Prefs :: FILTER_MODE:
50      case Prefs :: FILTER_TRACKERS:
51        invalidateFilter ();
52        /* force a re-sort */
53        sort (0, !myPrefs.getBool(Prefs::SORT_REVERSED) ? Qt::AscendingOrder : Qt::DescendingOrder);
54
55      case Prefs :: SORT_MODE:
56      case Prefs :: SORT_REVERSED:
57        sort (0, myPrefs.getBool(Prefs::SORT_REVERSED) ? Qt::AscendingOrder : Qt::DescendingOrder);
58        invalidate ();
59        break;
60    }
61}
62
63/***
64****
65***/
66
67namespace
68{
69  template <typename T> int compare (const T a, const T b)
70    {
71      if (a < b)
72        return -1;
73
74      if (b < a)
75        return 1;
76
77      return 0;
78    }
79}
80
81bool
82TorrentFilter :: lessThan (const QModelIndex& left, const QModelIndex& right) const
83{
84  int val = 0;
85  const Torrent * a = sourceModel()->data (left, TorrentModel::TorrentRole).value<const Torrent*>();
86  const Torrent * b = sourceModel()->data (right, TorrentModel::TorrentRole).value<const Torrent*>();
87
88  switch (myPrefs.get<SortMode>(Prefs::SORT_MODE).mode())
89    {
90      case SortMode :: SORT_BY_QUEUE:
91        if (!val)
92          val = -compare (a->queuePosition(), b->queuePosition());
93        break;
94
95      case SortMode :: SORT_BY_SIZE:
96        if (!val)
97          val = compare (a->sizeWhenDone(), b->sizeWhenDone());
98        break;
99
100      case SortMode :: SORT_BY_AGE:
101        val = compare (a->dateAdded().toTime_t(), b->dateAdded().toTime_t());
102        break;
103
104      case SortMode :: SORT_BY_ID:
105        if (!val)
106          val = compare (a->id(), b->id());
107        break;
108
109      case SortMode :: SORT_BY_ACTIVITY:
110        if (!val)
111          val = compare (a->downloadSpeed() + a->uploadSpeed(), b->downloadSpeed() + b->uploadSpeed());
112        if (!val)
113          val = compare (a->peersWeAreUploadingTo() + a->webseedsWeAreDownloadingFrom(),
114                         b->peersWeAreUploadingTo() + b->webseedsWeAreDownloadingFrom());
115        // fall through
116
117      case SortMode :: SORT_BY_STATE:
118        if (!val)
119          val = -compare (a->isPaused(), b->isPaused());
120        if (!val)
121          val = compare (a->getActivity(), b->getActivity());
122        if (!val)
123          val = -compare (a->queuePosition(), b->queuePosition());
124        if (!val)
125          val = compare (a->hasError(), b->hasError());
126        // fall through
127
128      case SortMode :: SORT_BY_PROGRESS:
129        if (!val)
130          val = compare (a->percentComplete(), b->percentComplete());
131        if (!val)
132          val = a->compareSeedRatio (*b);
133        if (!val)
134          val = -compare (a->queuePosition(), b->queuePosition());
135
136      case SortMode :: SORT_BY_RATIO:
137        if (!val)
138          val = a->compareRatio (*b);
139        break;
140
141      case SortMode :: SORT_BY_ETA:
142        if (!val)
143          val = a->compareETA (*b);
144        break;
145
146      default:
147        break;
148    }
149
150  if (val == 0)
151    val = -a->name().compare (b->name(), Qt::CaseInsensitive);
152
153  if (val == 0)
154    val = compare (a->hashString(), b->hashString());
155
156  return val < 0;
157}
158
159
160/***
161****
162***/
163
164bool
165TorrentFilter :: trackerFilterAcceptsTorrent (const Torrent * tor, const QString& tracker) const
166{
167  return tracker.isEmpty() || tor->hasTrackerSubstring (tracker);
168}
169
170bool
171TorrentFilter :: activityFilterAcceptsTorrent (const Torrent * tor, const FilterMode& m) const
172{
173  bool accepts;
174
175  switch (m.mode ())
176    {
177      case FilterMode::SHOW_ACTIVE:
178        accepts = tor->peersWeAreUploadingTo () > 0 || tor->peersWeAreDownloadingFrom () > 0 || tor->isVerifying ();
179        break;
180
181      case FilterMode::SHOW_DOWNLOADING:
182        accepts = tor->isDownloading () || tor->isWaitingToDownload ();
183        break;
184
185      case FilterMode::SHOW_SEEDING:
186        accepts = tor->isSeeding () || tor->isWaitingToSeed ();
187        break;
188
189      case FilterMode::SHOW_PAUSED:
190        accepts = tor->isPaused ();
191        break;
192
193      case FilterMode::SHOW_FINISHED:
194        accepts = tor->isFinished ();
195        break;
196
197      case FilterMode::SHOW_VERIFYING:
198        accepts = tor->isVerifying () || tor->isWaitingToVerify ();
199        break;
200
201      case FilterMode::SHOW_ERROR:
202        accepts = tor->hasError ();
203        break;
204
205      default: // FilterMode::SHOW_ALL
206        accepts = true;
207        break;
208    }
209
210  return accepts;
211}
212
213bool
214TorrentFilter :: filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const
215{
216  QModelIndex childIndex = sourceModel()->index (sourceRow, 0, sourceParent);
217  const Torrent * tor = childIndex.model()->data (childIndex, TorrentModel::TorrentRole).value<const Torrent*>();
218  bool accepts = true;
219
220  if (accepts)
221    {
222      const FilterMode m = myPrefs.get<FilterMode>(Prefs::FILTER_MODE);
223      accepts = activityFilterAcceptsTorrent (tor, m);
224    }
225
226  if (accepts)
227    {
228      const QString trackers = myPrefs.getString(Prefs::FILTER_TRACKERS);
229      accepts = trackerFilterAcceptsTorrent (tor, trackers);
230    }
231
232  if (accepts)
233    {
234      const QString text = myPrefs.getString (Prefs::FILTER_TEXT);
235      if (!text.isEmpty ())
236        accepts = tor->name().contains (text, Qt::CaseInsensitive);
237    }
238
239  return accepts;
240}
241
242int
243TorrentFilter :: hiddenRowCount () const
244{
245  return sourceModel()->rowCount () - rowCount ();
246}
247
248void
249TorrentFilter :: countTorrentsPerMode (int * setmeCounts) const
250{
251  std::fill_n (setmeCounts, static_cast<std::size_t>(FilterMode::NUM_MODES), 0);
252
253  for (int row(0); ; ++row)
254    { 
255      QModelIndex index (sourceModel()->index(row, 0));
256      if (!index.isValid())
257        break;
258
259      const Torrent * tor (index.data (TorrentModel::TorrentRole).value<const Torrent*>());
260      for (int mode(0); mode<FilterMode::NUM_MODES; ++mode)
261        if (activityFilterAcceptsTorrent (tor, mode))
262          ++setmeCounts[mode];
263    }
264}
265
Note: See TracBrowser for help on using the repository browser.