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

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

(qt) small speedup when rebuilding the activity combobox's counts: walk the torrent model just once, rather than once per activity

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