Changeset 11217


Ignore:
Timestamp:
Sep 17, 2010, 1:23:20 PM (11 years ago)
Author:
charles
Message:

(trunk gtk) #3529 "slow priority-sorting in file list" -- fixed

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/file-list.c

    r10995 r11217  
    4949{
    5050    TrCore        * core;
    51     tr_torrent    * tor;
    5251    GtkWidget     * top;
    5352    GtkWidget     * view;
    5453    GtkTreeModel  * model; /* same object as store, but recast */
    5554    GtkTreeStore  * store; /* same object as model, but recast */
    56     tr_file_stat  * refresh_file_stat;
    5755    int             torrentId;
    5856    guint           timeout_tag;
     
    8179****
    8280***/
     81
     82struct RefreshData
     83{
     84    int sort_column_id;
     85    gboolean resort_needed;
     86
     87    tr_file_stat  * refresh_file_stat;
     88    tr_torrent * tor;
     89
     90    FileData * file_data;
     91};
    8392
    8493static gboolean
     
    8897                     gpointer       gdata )
    8998{
    90     FileData * data = gdata;
     99    struct RefreshData * refresh_data = gdata;
     100    FileData * data = refresh_data->file_data;
    91101    unsigned int index;
    92102    uint64_t size;
     
    107117    if( is_file )
    108118    {
    109         tr_torrent * tor = data->tor;
     119        tr_torrent * tor = refresh_data->tor;
    110120        const tr_info * inf = tr_torrentInfo( tor );
    111121        const int enabled = !inf->files[index].dnd;
    112122        const int priority = inf->files[index].priority;
    113         const uint64_t have = data->refresh_file_stat[index].bytesCompleted;
     123        const uint64_t have = refresh_data->refresh_file_stat[index].bytesCompleted;
    114124        const int prog = size ? (int)((100.0*have)/size) : 1;
    115125
    116126        if( (priority!=old_priority) || (enabled!=old_enabled) || (have!=old_have) || (prog!=old_prog) )
     127        {
     128            /* Changing a value in the sort column can trigger a resort
     129             * which breaks this foreach() call.  (See #3529)
     130             * As a workaround: if that's about to happen, temporarily disable
     131             * sorting until we finish walking the tree. */
     132            if( !refresh_data->resort_needed )
     133            {
     134                if(( refresh_data->resort_needed =
     135                    (( refresh_data->sort_column_id==FC_PRIORITY ) && ( priority!=old_priority )) ||
     136                    (( refresh_data->sort_column_id==FC_ENABLED ) && ( enabled!=old_enabled ))))
     137                {
     138                    refresh_data->resort_needed = TRUE;
     139                    gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( data->model ),
     140                                                          GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
     141                                                          GTK_SORT_ASCENDING );
     142                }
     143            }
     144
    117145            gtk_tree_store_set( data->store, iter, FC_PRIORITY, priority,
    118146                                                   FC_ENABLED, enabled,
     
    120148                                                   FC_PROG, prog,
    121149                                                   -1 );
     150        }
    122151    }
    123152    else
     
    217246    else
    218247    {
     248        GtkSortType order;
     249        int sort_column_id;
    219250        tr_file_index_t fileCount;
    220         data->tor = tr_torrentFindFromId( session, data->torrentId );
    221         data->refresh_file_stat = tr_torrentFiles( tor, &fileCount );
    222 
    223         gtr_tree_model_foreach_postorder( data->model, refreshFilesForeach, data );
    224 
    225         tr_torrentFilesFree( data->refresh_file_stat, fileCount );
    226         data->refresh_file_stat = NULL;
    227         data->tor = NULL;
     251        struct RefreshData refresh_data;
     252        GtkTreeSortable * sortable = GTK_TREE_SORTABLE( data->model );
     253        gtk_tree_sortable_get_sort_column_id( sortable, &sort_column_id, &order );
     254
     255        refresh_data.sort_column_id = sort_column_id;
     256        refresh_data.resort_needed = FALSE;
     257        refresh_data.refresh_file_stat = tr_torrentFiles( tor, &fileCount );
     258        refresh_data.tor = tr_torrentFindFromId( session, data->torrentId );
     259        refresh_data.file_data = data;
     260
     261        gtr_tree_model_foreach_postorder( data->model, refreshFilesForeach, &refresh_data );
     262
     263        if( refresh_data.resort_needed )
     264            gtk_tree_sortable_set_sort_column_id( sortable, sort_column_id, order );
     265
     266        tr_torrentFilesFree( refresh_data.refresh_file_stat, fileCount );
    228267    }
    229268}
Note: See TracChangeset for help on using the changeset viewer.