]> granicus.if.org Git - transmission/commitdiff
(trunk gtk, qt) #3770 "GTK and Qt clients should sort-by-progress as the Mac client...
authorCharles Kerr <charles@transmissionbt.com>
Wed, 1 Dec 2010 05:41:58 +0000 (05:41 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Wed, 1 Dec 2010 05:41:58 +0000 (05:41 +0000)
gtk/tr-core.c
qt/torrent-filter.cc
qt/torrent.cc
qt/torrent.h

index fd552863a0adac39b01afc2b376b9cf90ecc18d7..9278fc41e9a17f42d09e59d5438babcb18810ffd 100644 (file)
@@ -285,6 +285,22 @@ compareDouble( double a, double b )
     return 0;
 }
 
+static int
+compareUint64( uint64_t a, uint64_t b )
+{
+    if( a < b ) return -1;
+    if( a > b ) return 1;
+    return 0;
+}
+
+static int
+compareInt_( int a, int b )
+{
+    if( a < b ) return -1;
+    if( a > b ) return 1;
+    return 0;
+}
+
 static int
 compareRatio( double a, double b )
 {
@@ -303,157 +319,148 @@ compareTime( time_t a, time_t b )
 }
 
 static int
-compareByRatio( GtkTreeModel  * model,
-                GtkTreeIter   * a,
-                GtkTreeIter   * b,
-                gpointer        user_data UNUSED )
+compareByName( GtkTreeModel * m, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data UNUSED )
 {
-    tr_torrent *ta, *tb;
-    const tr_stat *sa, *sb;
+    int ret = 0;
 
-    gtk_tree_model_get( model, a, MC_TORRENT_RAW, &ta, -1 );
-    gtk_tree_model_get( model, b, MC_TORRENT_RAW, &tb, -1 );
+    if( !ret ) {
+        char *ca, *cb;
+        gtk_tree_model_get( m, a, MC_NAME_COLLATED, &ca, -1 );
+        gtk_tree_model_get( m, b, MC_NAME_COLLATED, &cb, -1 );
+        ret = gtr_strcmp0( ca, cb );
+        g_free( cb );
+        g_free( ca );
+    }
 
-    sa = tr_torrentStatCached( ta );
-    sb = tr_torrentStatCached( tb );
+    if( !ret ) {
+        tr_torrent * t;
+        const tr_info *ia, *ib;
+        gtk_tree_model_get( m, a, MC_TORRENT_RAW, &t, -1 );
+        ia = tr_torrentInfo( t );
+        gtk_tree_model_get( m, b, MC_TORRENT_RAW, &t, -1 );
+        ib = tr_torrentInfo( t );
+        ret = memcmp( ia->hash, ib->hash, SHA_DIGEST_LENGTH );
+    }
 
-    return compareRatio( sa->ratio, sb->ratio );
+    return ret;
 }
 
 static int
-compareByActivity( GtkTreeModel * model,
-                   GtkTreeIter  * a,
-                   GtkTreeIter  * b,
-                   gpointer       user_data UNUSED )
+compareByRatio( GtkTreeModel* m, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data )
 {
-    int i;
+    int ret = 0;
     tr_torrent *ta, *tb;
     const tr_stat *sa, *sb;
-    double aUp, aDown, bUp, bDown;
-
-    gtk_tree_model_get( model, a, MC_SPEED_UP, &aUp,
-                                  MC_SPEED_DOWN, &aDown,
-                                  MC_TORRENT_RAW, &ta,
-                                  -1 );
-    gtk_tree_model_get( model, b, MC_SPEED_UP, &bUp,
-                                  MC_SPEED_DOWN, &bDown,
-                                  MC_TORRENT_RAW, &tb,
-                                  -1 );
-
-    if(( i = compareDouble( aUp+aDown, bUp+bDown )))
-        return i;
 
+    gtk_tree_model_get( m, a, MC_TORRENT_RAW, &ta, -1 );
     sa = tr_torrentStatCached( ta );
+    gtk_tree_model_get( m, b, MC_TORRENT_RAW, &tb, -1 );
     sb = tr_torrentStatCached( tb );
-    if( sa->uploadedEver != sb->uploadedEver )
-        return sa->uploadedEver < sa->uploadedEver ? -1 : 1;
 
-    return 0;
+    if( !ret ) ret = compareRatio( sa->ratio, sb->ratio );
+    if( !ret ) ret = compareByName( m, a, b, user_data );
+    return ret;
 }
 
 static int
-compareByName( GtkTreeModel *             model,
-               GtkTreeIter *              a,
-               GtkTreeIter *              b,
-               gpointer         user_data UNUSED )
+compareByActivity( GtkTreeModel * m, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data )
 {
-    int   ret;
-    char *ca, *cb;
+    int ret = 0;
+    tr_torrent *ta, *tb;
+    const tr_stat *sa, *sb;
+    double aUp, aDown, bUp, bDown;
 
-    gtk_tree_model_get( model, a, MC_NAME_COLLATED, &ca, -1 );
-    gtk_tree_model_get( model, b, MC_NAME_COLLATED, &cb, -1 );
-    ret = gtr_strcmp0( ca, cb );
+    gtk_tree_model_get( m, a, MC_SPEED_UP, &aUp,
+                              MC_SPEED_DOWN, &aDown,
+                              MC_TORRENT_RAW, &ta,
+                              -1 );
+    gtk_tree_model_get( m, b, MC_SPEED_UP, &bUp,
+                              MC_SPEED_DOWN, &bDown,
+                              MC_TORRENT_RAW, &tb,
+                              -1 );
+    sa = tr_torrentStatCached( ta );
+    sb = tr_torrentStatCached( tb );
 
-    g_free( cb );
-    g_free( ca );
+    if( !ret ) ret = compareDouble( aUp+aDown, bUp+bDown );
+    if( !ret ) ret = compareUint64( sa->uploadedEver, sb->uploadedEver );
+    if( !ret ) ret = compareByName( m, a, b, user_data );
     return ret;
 }
 
 static int
-compareByAge( GtkTreeModel * model,
-              GtkTreeIter  * a,
-              GtkTreeIter  * b,
-              gpointer       user_data UNUSED )
+compareByAge( GtkTreeModel * m, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data )
 {
+    int ret = 0;
     tr_torrent *ta, *tb;
 
-    gtk_tree_model_get( model, a, MC_TORRENT_RAW, &ta, -1 );
-    gtk_tree_model_get( model, b, MC_TORRENT_RAW, &tb, -1 );
-    return compareTime( tr_torrentStatCached( ta )->addedDate,
-                        tr_torrentStatCached( tb )->addedDate );
+    gtk_tree_model_get( m, a, MC_TORRENT_RAW, &ta, -1 );
+    gtk_tree_model_get( m, b, MC_TORRENT_RAW, &tb, -1 );
+
+    if( !ret ) ret = compareTime( tr_torrentStatCached( ta )->addedDate, tr_torrentStatCached( tb )->addedDate );
+    if( !ret ) ret = compareByName( m, a, b, user_data );
+    return ret;
 }
 
 static int
-compareBySize( GtkTreeModel * model,
-               GtkTreeIter  * a,
-               GtkTreeIter  * b,
-               gpointer       user_data UNUSED )
+compareBySize( GtkTreeModel * m, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data )
 {
+    int ret = 0;
     tr_torrent *t;
     const tr_info *ia, *ib;
 
-    gtk_tree_model_get( model, a, MC_TORRENT_RAW, &t, -1 );
+    gtk_tree_model_get( m, a, MC_TORRENT_RAW, &t, -1 );
     ia = tr_torrentInfo( t );
-    gtk_tree_model_get( model, b, MC_TORRENT_RAW, &t, -1 );
+    gtk_tree_model_get( m, b, MC_TORRENT_RAW, &t, -1 );
     ib = tr_torrentInfo( t );
 
-    if( ia->totalSize < ib->totalSize ) return 1;
-    if( ia->totalSize > ib->totalSize ) return -1;
-    return 0;
+    if( !ret ) ret = compareUint64( ia->totalSize, ib->totalSize );
+    if( !ret ) ret = compareByName( m, a, b, user_data );
+    return ret;
 }
 
 static int
-compareByProgress( GtkTreeModel *             model,
-                   GtkTreeIter *              a,
-                   GtkTreeIter *              b,
-                   gpointer         user_data UNUSED )
+compareByProgress( GtkTreeModel * m, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data )
 {
-    int ret;
+    int ret = 0;
     tr_torrent * t;
     const tr_stat *sa, *sb;
 
-    gtk_tree_model_get( model, a, MC_TORRENT_RAW, &t, -1 );
+    gtk_tree_model_get( m, a, MC_TORRENT_RAW, &t, -1 );
     sa = tr_torrentStatCached( t );
-    gtk_tree_model_get( model, b, MC_TORRENT_RAW, &t, -1 );
+    gtk_tree_model_get( m, b, MC_TORRENT_RAW, &t, -1 );
     sb = tr_torrentStatCached( t );
-    ret = compareDouble( sa->percentDone, sb->percentDone );
-    if( !ret )
-        ret = compareRatio( sa->ratio, sb->ratio );
+
+    if( !ret ) ret = compareDouble( sa->percentComplete, sb->percentComplete );
+    if( !ret ) ret = compareDouble( sa->seedRatioPercentDone, sb->seedRatioPercentDone );
+    if( !ret ) ret = compareByRatio( m, a, b, user_data );
     return ret;
 }
 
 static int
-compareByETA( GtkTreeModel * model,
-              GtkTreeIter  * a,
-              GtkTreeIter  * b,
-              gpointer       user_data UNUSED )
+compareByETA( GtkTreeModel * m, GtkTreeIter  * a, GtkTreeIter  * b, gpointer user_data )
 {
+    int ret = 0;
     tr_torrent *ta, *tb;
 
-    gtk_tree_model_get( model, a, MC_TORRENT_RAW, &ta, -1 );
-    gtk_tree_model_get( model, b, MC_TORRENT_RAW, &tb, -1 );
+    gtk_tree_model_get( m, a, MC_TORRENT_RAW, &ta, -1 );
+    gtk_tree_model_get( m, b, MC_TORRENT_RAW, &tb, -1 );
 
-    return compareETA( tr_torrentStatCached( ta )->eta,
-                       tr_torrentStatCached( tb )->eta );
+    if( !ret ) ret = compareETA( tr_torrentStatCached( ta )->eta, tr_torrentStatCached( tb )->eta );
+    if( !ret ) ret = compareByName( m, a, b, user_data );
+    return ret;
 }
 
 static int
-compareByState( GtkTreeModel * model,
-                GtkTreeIter *  a,
-                GtkTreeIter *  b,
-                gpointer       user_data )
+compareByState( GtkTreeModel * m, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data )
 {
-    int sa, sb, ret;
-
-    /* first by state */
-    gtk_tree_model_get( model, a, MC_ACTIVITY, &sa, -1 );
-    gtk_tree_model_get( model, b, MC_ACTIVITY, &sb, -1 );
-    ret = sa - sb;
+    int ret = 0;
+    int sa, sb;
 
-    /* second by progress */
-    if( !ret )
-        ret = compareByProgress( model, a, b, user_data );
+    gtk_tree_model_get( m, a, MC_ACTIVITY, &sa, -1 );
+    gtk_tree_model_get( m, b, MC_ACTIVITY, &sb, -1 );
 
+    if( !ret ) ret = compareInt_( sa, sb );
+    if( !ret ) ret = compareByProgress( m, a, b, user_data );
     return ret;
 }
 
index c97ee15a8a05715863530c392d3ad8a6f0700869..558deb0aca450677310ba5b0346265fdc6abcd29 100644 (file)
@@ -79,51 +79,47 @@ namespace
 bool
 TorrentFilter :: lessThan( const QModelIndex& left, const QModelIndex& right ) const
 {
+    int val = 0;
     const Torrent * a = sourceModel()->data( left, TorrentModel::TorrentRole ).value<const Torrent*>();
     const Torrent * b = sourceModel()->data( right, TorrentModel::TorrentRole ).value<const Torrent*>();
-    int less = 0;
 
     switch( myPrefs.get<SortMode>(Prefs::SORT_MODE).mode() )
     {
         case SortMode :: SORT_BY_SIZE:
-            less = compare( a->sizeWhenDone(), b->sizeWhenDone() );
+            if( !val ) val = compare( a->sizeWhenDone(), b->sizeWhenDone() );
             break;
         case SortMode :: SORT_BY_ACTIVITY:
-            less = compare( a->downloadSpeed() + a->uploadSpeed(), b->downloadSpeed() + b->uploadSpeed() );
-            if( !less )
-                less = compare( a->uploadedEver(), b->uploadedEver() );
+            if( !val ) val = compare( a->downloadSpeed() + a->uploadSpeed(), b->downloadSpeed() + b->uploadSpeed() );
+            if( !val ) val = compare( a->uploadedEver(), b->uploadedEver() );
             break;
         case SortMode :: SORT_BY_AGE:
-            less = compare( a->dateAdded().toTime_t(), b->dateAdded().toTime_t() );
+            val = compare( a->dateAdded().toTime_t(), b->dateAdded().toTime_t() );
             break;
         case SortMode :: SORT_BY_ID:
-            less = compare( a->id(), b->id() );
+            if( !val ) val = compare( a->id(), b->id() );
             break;
         case SortMode :: SORT_BY_STATE:
-            if( a->hasError() != b->hasError() )
-                less = a->hasError();
-            else
-                less = compare( a->getActivity(), b->getActivity() );
-            if( less )
-                break;
+            if( !val ) val = compare( a->hasError(), b->hasError() );
+            if( !val ) val = compare( a->getActivity(), b->getActivity() );
+            // fall through
         case SortMode :: SORT_BY_PROGRESS:
-            less = compare( a->percentDone(), b->percentDone() );
-            if( less )
-                break;
+            if( !val ) val = compare( a->percentComplete(), b->percentComplete() );
+            if( !val ) val = a->compareSeedRatio( *b );
+            // fall through
         case SortMode :: SORT_BY_RATIO:
-            less = a->compareRatio( *b );
+            if( !val ) val = a->compareRatio( *b );
             break;
         case SortMode :: SORT_BY_ETA:
-            less = a->compareETA( *b );
+            if( !val ) val = a->compareETA( *b );
             break;
         default:
             break;
     }
-    if( less == 0 )
-        less = -a->name().compare( b->name(), Qt::CaseInsensitive );
-    if( less == 0 )
-        less = compare( a->hashString(), b->hashString() );
-    return less < 0;
+    if( val == 0 )
+        val = -a->name().compare( b->name(), Qt::CaseInsensitive );
+    if( val == 0 )
+        val = compare( a->hashString(), b->hashString() );
+    return val < 0;
 }
 
 
index f8884d4d40c5b2543045022062922e5fffc951e4..4a3f26cc38add184ce0deb31c7b31fd62ba8b40b 100644 (file)
@@ -368,6 +368,20 @@ Torrent :: hasTrackerSubstring( const QString& substr ) const
     return false;
 }
 
+int
+Torrent :: compareSeedRatio( const Torrent& that ) const
+{
+    double a;
+    double b;
+    const bool has_a = getSeedRatio( a );
+    const bool has_b = that.getSeedRatio( b );
+    if( !has_a && !has_b ) return 0;
+    if( !has_a || !has_b ) return has_a ? -1 : 1;
+    if( a < b ) return -1;
+    if( a > b ) return 1;
+    return 0;
+}
+
 int
 Torrent :: compareRatio( const Torrent& that ) const
 {
index 211f94910d84f1e04a2bc613e49cad47acebf716..7cd484babf3c1296e7a277aa27871248eb13ea0e 100644 (file)
@@ -268,6 +268,7 @@ class Torrent: public QObject
         uint64_t uploadedEver( ) const { return getSize( UPLOADED_EVER ); }
         uint64_t failedEver( ) const { return getSize( FAILED_EVER ); }
         int compareTracker( const Torrent& ) const;
+        int compareSeedRatio( const Torrent& ) const;
         int compareRatio( const Torrent& ) const;
         int compareETA( const Torrent& ) const;
         bool hasETA( ) const { return getETA( ) >= 0; }