Changeset 9685


Ignore:
Timestamp:
Dec 8, 2009, 8:34:46 PM (12 years ago)
Author:
charles
Message:

(trunk gtk) #2500 "Torrent details window should be single-instance per torrent" -- implemented for 1.80

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/main.c

    r9682 r9685  
    8989};
    9090
     91/**
     92***
     93**/
     94
     95static int
     96compareInts( const void * a, const void * b )
     97{
     98    return *(int*)a - *(int*)b;
     99}
     100
     101static char*
     102getDetailsDialogKey( GSList * id_list )
     103{
     104    int i;
     105    int n;
     106    int * ids;
     107    GSList * l;
     108    GString * gstr = g_string_new( NULL );
     109
     110    n = g_slist_length( id_list );
     111    ids = g_new( int, n );
     112    i = 0;
     113    for( l=id_list; l!=NULL; l=l->next )
     114        ids[i++] = GPOINTER_TO_INT( l->data );
     115    g_assert( i == n );
     116    qsort( ids, n, sizeof(int), compareInts );
     117
     118    for( i=0; i<n; ++i )
     119        g_string_append_printf( gstr, "%d ", ids[i] );
     120
     121    g_free( ids );
     122    return g_string_free( gstr, FALSE );
     123}
     124
     125struct DetailsDialogHandle
     126{
     127    char * key;
     128    GtkWidget * dialog;
     129};
     130
     131static GSList*
     132getSelectedTorrentIds( struct cbdata * data )
     133{
     134    GtkTreeSelection * s;
     135    GtkTreeModel * model;
     136    GSList * ids = NULL;
     137    GList * selrows = NULL;
     138    GList * l;
     139
     140    /* build a list of the selected torrents' ids */
     141    s = tr_window_get_selection( data->wind );
     142    for( selrows=l=gtk_tree_selection_get_selected_rows(s,&model); l; l=l->next ) {
     143        GtkTreeIter iter;
     144        if( gtk_tree_model_get_iter( model, &iter, l->data ) ) {
     145            tr_torrent * tor;
     146            gtk_tree_model_get( model, &iter, MC_TORRENT_RAW, &tor, -1 );
     147            ids = g_slist_append( ids, GINT_TO_POINTER( tr_torrentId( tor ) ) );
     148        }
     149    }
     150
     151    return ids;
     152}
     153
     154static struct DetailsDialogHandle*
     155findDetailsDialogFromIds( struct cbdata * cbdata, GSList * ids )
     156{
     157    GSList * l;
     158    struct DetailsDialogHandle * ret = NULL;
     159    char * key = getDetailsDialogKey( ids );
     160
     161    for( l=cbdata->details; l!=NULL && ret==NULL; l=l->next ) {
     162        struct DetailsDialogHandle * h = l->data;
     163        if( !strcmp( h->key, key ) )
     164            ret = h;
     165    }
     166
     167    g_free( key );
     168    return ret;
     169}
     170
     171static struct DetailsDialogHandle*
     172findDetailsDialogFromWidget( struct cbdata * cbdata, gpointer w )
     173{
     174    GSList * l;
     175    struct DetailsDialogHandle * ret = NULL;
     176
     177    for( l=cbdata->details; l!=NULL && ret==NULL; l=l->next ) {
     178        struct DetailsDialogHandle * h = l->data;
     179        if( h->dialog == w )
     180            ret = h;
     181    }
     182
     183    return ret;
     184}
     185
     186/***
     187****
     188***/
     189
    91190static void           appsetup( TrWindow * wind,
    92191                                GSList *   args,
     
    246345        action_sensitize( "start-all-torrents", active != total );
    247346    }
    248 }
    249 
    250 static void
    251 refreshDetailsDialog( struct cbdata * data, GtkWidget * details )
    252 {
    253     GtkTreeSelection * s;
    254     GtkTreeModel * model;
    255     GSList * ids = NULL;
    256     GList * selrows = NULL;
    257     GList * l;
    258 
    259     /* build a list of the selected torrents' ids */
    260     s = tr_window_get_selection( data->wind );
    261     for( selrows=l=gtk_tree_selection_get_selected_rows(s,&model); l; l=l->next ) {
    262         GtkTreeIter iter;
    263         if( gtk_tree_model_get_iter( model, &iter, l->data ) ) {
    264             tr_torrent * tor;
    265             gtk_tree_model_get( model, &iter, MC_TORRENT_RAW, &tor, -1 );
    266             ids = g_slist_append( ids, GINT_TO_POINTER( tr_torrentId( tor ) ) );
    267         }
    268     }
    269 
    270     torrent_inspector_set_torrents( details, ids );
    271 
    272     /* cleanup */
    273     g_slist_free( ids );
    274     g_list_foreach( selrows, (GFunc)gtk_tree_path_free, NULL );
    275     g_list_free( selrows );
    276347}
    277348
     
    708779
    709780    /* shutdown the gui */
    710     if( cbdata->details ) {
    711         g_slist_foreach( cbdata->details, (GFunc)gtk_widget_destroy, NULL );
     781    if( cbdata->details != NULL )
     782    {
     783        GSList * l;
     784        for( l=cbdata->details; l!=NULL; l=l->next )
     785        {
     786            struct DetailsDialogHandle * h = l->data;
     787            gtk_widget_destroy( h->dialog );
     788            g_free( h->key );
     789            g_free( h );
     790        }
    712791        g_slist_free( cbdata->details );
    713     }
     792        cbdata->details = NULL;
     793    }
     794
    714795    if( cbdata->prefs )
    715796        gtk_widget_destroy( GTK_WIDGET( cbdata->prefs ) );
     
    14001481{
    14011482    struct cbdata * data = gdata;
    1402     data->details = g_slist_remove( data->details, dead );
     1483    struct DetailsDialogHandle * h = findDetailsDialogFromWidget( data, dead );
     1484
     1485    if( h != NULL )
     1486    {
     1487        data->details = g_slist_remove( data->details, h );
     1488        g_free( h->key );
     1489        g_free( h );
     1490    }
    14031491}
    14041492
     
    14891577    else if( !strcmp( action_name, "show-torrent-properties" ) )
    14901578    {
    1491         GtkWidget * w = torrent_inspector_new( GTK_WINDOW( data->wind ), data->core );
    1492         data->details = g_slist_prepend( data->details, w );
    1493         g_object_weak_ref( G_OBJECT( w ), detailsClosed, data );
    1494         refreshDetailsDialog( data, w );
    1495         gtk_widget_show( w );
     1579        GtkWidget * w;
     1580        GSList * ids = getSelectedTorrentIds( data );
     1581        struct DetailsDialogHandle * h = findDetailsDialogFromIds( data, ids );
     1582        if( h != NULL )
     1583            w = h->dialog;
     1584        else {
     1585            h = g_new( struct DetailsDialogHandle, 1 );
     1586            h->key = getDetailsDialogKey( ids );
     1587            h->dialog = w = torrent_inspector_new( GTK_WINDOW( data->wind ), data->core );
     1588            torrent_inspector_set_torrents( w, ids );
     1589            data->details = g_slist_append( data->details, h );
     1590            g_object_weak_ref( G_OBJECT( w ), detailsClosed, data );
     1591        }
     1592        gtk_window_present( GTK_WINDOW( w ) );
    14961593    }
    14971594    else if( !strcmp( action_name, "update-tracker" ) )
Note: See TracChangeset for help on using the changeset viewer.