Changeset 1506


Ignore:
Timestamp:
Feb 23, 2007, 6:18:45 AM (15 years ago)
Author:
joshe
Message:

Add a window to view a torrent's files.

Location:
trunk/gtk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/dialogs.c

    r1504 r1506  
    3939
    4040#define PREFNAME                "transmission-dialog-pref-name"
     41#define FILESWIND_EXTRA_INDENT  4
     42
     43#define STRIPROOT( path )                                                     \
     44    ( g_path_is_absolute( (path) ) ? g_path_skip_root( (path) ) : (path) )
    4145
    4246struct addcb {
     
    6367};
    6468
     69struct fileswind
     70{
     71    TrTorrent    * tor;
     72    GtkTreeModel * model;
     73};
     74
    6575static void
    6676autoclick(GtkWidget *widget, gpointer gdata);
     
    7383static void
    7484quitresp( GtkWidget * widget, gint resp, gpointer data );
     85static void
     86parsepath( GtkTreeStore * store, GtkTreeIter * ret,
     87           const char * path, int index, uint64_t size );
     88static void
     89setscroll( void * arg );
     90static void
     91fileswindresp( GtkWidget * widget, gint resp SHUTUP, gpointer data );
    7592
    7693void
     
    373390    gtk_widget_destroy( widget );
    374391}
     392
     393enum filescols { FC_INDEX = 0, FC_LABEL, FC_KEY, FC_STOCK, FC__COUNT };
     394
     395void
     396makefileswind( GtkWindow * parent, TrTorrent * tor )
     397{
     398    GType cols[] = { G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING };
     399    tr_info_t         * inf;
     400    GtkTreeStore      * store;
     401    int                 ii;
     402    GtkWidget         * view, * scroll, * frame, * wind;
     403    GtkCellRenderer   * rend;
     404    GtkTreeViewColumn * col;
     405    GtkTreeSelection  * sel;
     406    char              * label;
     407    struct fileswind  * fw;
     408
     409    g_assert( ALEN( cols ) == FC__COUNT );
     410
     411    /* set up the model */
     412    inf   = tr_torrent_info( tor );
     413    store = gtk_tree_store_newv( FC__COUNT, cols );
     414    for( ii = 0; ii < inf->fileCount; ii++ )
     415    {
     416        parsepath( store, NULL, STRIPROOT( inf->files[ii].name ),
     417                   ii, inf->files[ii].length );
     418    }
     419    gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
     420                                          FC_KEY, GTK_SORT_ASCENDING );
     421
     422    /* create the view */
     423    view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
     424    col = gtk_tree_view_column_new();
     425    gtk_tree_view_column_set_title( col, _("File") );
     426    /* add icon renderer */
     427    rend = gtk_cell_renderer_pixbuf_new();
     428    gtk_tree_view_column_pack_start( col, rend, FALSE );
     429    gtk_tree_view_column_add_attribute( col, rend, "stock-id", FC_STOCK );
     430    /* add text renderer */
     431    rend = gtk_cell_renderer_text_new();
     432    gtk_tree_view_column_pack_start( col, rend, TRUE );
     433    gtk_tree_view_column_add_attribute( col, rend, "markup", FC_LABEL );
     434    gtk_tree_view_append_column( GTK_TREE_VIEW( view ), col );
     435    /* set up view */
     436    sel = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) );
     437    gtk_tree_selection_set_mode( sel, GTK_SELECTION_NONE );
     438    gtk_tree_view_expand_all( GTK_TREE_VIEW( view ) );
     439    gtk_tree_view_set_search_column( GTK_TREE_VIEW( view ), FC_LABEL );
     440    gtk_widget_show( view );
     441
     442    /* create the scrolled window and stick the view in it */
     443    scroll = gtk_scrolled_window_new( NULL, NULL );
     444    gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scroll ),
     445                                    GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
     446    gtk_container_add( GTK_CONTAINER( scroll ), view );
     447    gtk_widget_show( scroll );
     448
     449    /* create a frame around the scroll to make it look a little better */
     450    frame = gtk_frame_new( NULL );
     451    gtk_frame_set_shadow_type( GTK_FRAME( frame ), GTK_SHADOW_IN );
     452    gtk_container_add( GTK_CONTAINER( frame ), scroll );
     453    gtk_widget_show( frame );
     454
     455    /* create the window */
     456    label = g_strdup_printf( _("Files for %s"), inf->name );
     457    wind = gtk_dialog_new_with_buttons( label, parent,
     458                                        GTK_DIALOG_DESTROY_WITH_PARENT |
     459                                        GTK_DIALOG_NO_SEPARATOR,
     460                                        GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
     461                                        NULL );
     462    g_free( label );
     463    gtk_dialog_set_default_response( GTK_DIALOG( wind ), GTK_RESPONSE_ACCEPT );
     464    gtk_window_set_resizable( GTK_WINDOW( wind ), TRUE );
     465    gtk_box_pack_start_defaults( GTK_BOX( GTK_DIALOG( wind )->vbox ), frame );
     466
     467    /* set up the callback data */
     468    fw        = g_new0( struct fileswind, 1 );
     469    fw->tor   = tor;
     470    fw->model = GTK_TREE_MODEL( store );
     471    g_object_add_weak_pointer( G_OBJECT( tor ), ( gpointer * )&fw->tor );
     472    g_signal_connect( wind, "response", G_CALLBACK( fileswindresp ), fw );
     473
     474    /* show the window with a nice initial size */
     475    windowsizehack( wind, scroll, view, setscroll, scroll );
     476}
     477
     478static void
     479parsepath( GtkTreeStore * store, GtkTreeIter * ret,
     480           const char * path, int index, uint64_t size )
     481{
     482    GtkTreeModel * model;
     483    GtkTreeIter  * parent, start, iter;
     484    char         * file, * dir, * mykey, * modelkey, * label, * sizestr;
     485    const char   * stock;
     486
     487    model  = GTK_TREE_MODEL( store );
     488    parent = NULL;
     489    file   = g_path_get_basename( path );
     490    if( 0 != strcmp( file, path ) )
     491    {
     492        dir = g_path_get_dirname( path );
     493        parsepath( store, &start, dir, index, size );
     494        g_free( dir );
     495        parent = &start;
     496    }
     497
     498    mykey = g_utf8_collate_key( file, -1 );
     499    if( gtk_tree_model_iter_children( model, &iter, parent ) )
     500    {
     501        do
     502        {
     503            gtk_tree_model_get( model, &iter, FC_KEY, &modelkey, -1 );
     504            if( NULL != modelkey && 0 == strcmp( mykey, modelkey ) )
     505            {
     506                goto done;
     507            }
     508        }
     509        while( gtk_tree_model_iter_next( model, &iter ) );
     510    }
     511
     512    gtk_tree_store_append( store, &iter, parent );
     513    if( NULL == ret )
     514    {
     515        sizestr = readablesize( size );
     516        label = g_markup_printf_escaped( _("<small>%s (%s)</small>"),
     517                                         file, sizestr );
     518        g_free( sizestr );
     519        stock = GTK_STOCK_FILE;
     520    }
     521    else
     522    {
     523        label = g_markup_printf_escaped( _("<small>%s</small>"), file );
     524        stock = GTK_STOCK_DIRECTORY;
     525    }
     526    gtk_tree_store_set( store, &iter, FC_INDEX, index, FC_LABEL, label,
     527                        FC_KEY, mykey, FC_STOCK, stock, -1 );
     528    g_free( label );
     529  done:
     530    g_free( mykey );
     531    g_free( file );
     532    if( NULL != ret )
     533    {
     534        memcpy( ret, &iter, sizeof( iter ) );
     535    }
     536}
     537
     538static void
     539setscroll( void * arg )
     540{
     541    gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( arg ),
     542        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
     543}
     544
     545static void
     546fileswindresp( GtkWidget * widget, gint resp SHUTUP, gpointer data )
     547{
     548    struct fileswind * fw;
     549
     550    fw = data;
     551
     552    g_object_unref( fw->model );
     553    g_object_remove_weak_pointer( G_OBJECT( fw->tor ),
     554                                  ( gpointer * )&fw->tor );
     555    g_free( fw );
     556    gtk_widget_destroy( widget );
     557}
  • trunk/gtk/dialogs.h

    r1504 r1506  
    5454askquit( GtkWindow * parent, callbackfunc_t func, void * cbdata );
    5555
     56/* create a window listing a torrent's files */
     57void
     58makefileswind( GtkWindow * parent, TrTorrent * tor );
     59
    5660#endif /* TG_PREFS_H */
  • trunk/gtk/main.c

    r1504 r1506  
    8989    ACT_DELETE,
    9090    ACT_INFO,
     91    ACT_FILES,
    9192    ACT_PREF,
    9293    ACT_DEBUG,
     
    114115    { N_("Properties"),  GTK_STOCK_PROPERTIES,  ACTF_WHEREVER | ACTF_WHATEVER,
    115116      N_("Show additional information about a torrent") },
     117    { N_("Files"),       NULL,                  ACTF_MENU     | ACTF_WHATEVER,
     118      N_("Show a list of the files in a torrent"), },
    116119    { N_("Preferences"), GTK_STOCK_PREFERENCES, ACTF_WHEREVER | ACTF_ALWAYS,
    117120      N_("Customize application behavior") },
     
    915918      case ACT_DELETE:
    916919      case ACT_INFO:
     920      case ACT_FILES:
    917921      case ACTION_COUNT:
    918922          break;
     
    956960                  makeinfowind( data->wind, tor );
    957961                  break;
     962              case ACT_FILES:
     963                  makefileswind( data->wind, tor );
     964                  break;
    958965              case ACT_OPEN:
    959966              case ACT_PREF:
  • trunk/gtk/tr_window.c

    r1494 r1506  
    387387}
    388388
     389static void
     390setelip( void * arg )
     391{
     392    g_object_set( arg, "ellipsize", TRUE, NULL );
     393}
     394
    389395void
    390396tr_window_size_hack( TrWindow * self )
    391397{
    392     GtkRequisition req;
    393     gint           width, height;
    394     GdkScreen    * screen;
    395 
    396398    TR_IS_WINDOW( self );
    397399
    398     gtk_widget_realize( GTK_WIDGET( self ) );
    399     gtk_widget_size_request( GTK_WIDGET( self->view ), &req );
    400     height = req.height;
    401     gtk_widget_size_request( GTK_WIDGET( self->scroll ), &req );
    402     height -= req.height;
    403     gtk_widget_size_request( GTK_WIDGET( self ), &req );
    404     height += req.height;
    405     screen  = gtk_widget_get_screen( GTK_WIDGET( self ) );
    406     width   = MIN( req.width, gdk_screen_get_width( screen  ) / 2 );
    407     height  = MIN( height,    gdk_screen_get_height( screen ) / 5 * 4 );
    408     if( height > req.width )
    409     {
    410         height = MIN( height, width * 8 / 5 );
    411     }
    412     else
    413     {
    414         height = MAX( height, width * 5 / 8 );
    415     }
    416     if( height > req.width )
    417     {
    418         height = MIN( height, width * 8 / 5 );
    419     }
    420     else
    421     {
    422         height = MAX( height, width * 5 / 8 );
    423     }
    424     g_object_set( self, "ellipsize", TRUE, NULL );
    425     gtk_widget_show_now( GTK_WIDGET( self ) );
    426     gtk_window_resize( GTK_WINDOW( self ), width, height );
     400    windowsizehack( GTK_WIDGET( self ), GTK_WIDGET( self->scroll ),
     401                    GTK_WIDGET( self->view ), setelip, self );
    427402}
    428403
  • trunk/gtk/util.c

    r1504 r1506  
    334334
    335335void
     336windowsizehack( GtkWidget * wind, GtkWidget * scroll, GtkWidget * view,
     337                callbackfunc_t func, void * arg )
     338{
     339    GtkRequisition req;
     340    gint           width, height;
     341    GdkScreen    * screen;
     342
     343    gtk_widget_realize( wind );
     344    gtk_widget_size_request( view, &req );
     345    height = req.height;
     346    gtk_widget_size_request( scroll, &req );
     347    height -= req.height;
     348    gtk_widget_size_request( wind, &req );
     349    height += req.height;
     350    screen  = gtk_widget_get_screen( wind );
     351    width   = MIN( req.width, gdk_screen_get_width( screen  ) / 2 );
     352    height  = MIN( height,    gdk_screen_get_height( screen ) / 5 * 4 );
     353    if( height > req.width )
     354    {
     355        height = MIN( height, width * 8 / 5 );
     356    }
     357    else
     358    {
     359        height = MAX( height, width * 5 / 8 );
     360    }
     361    if( height > req.width )
     362    {
     363        height = MIN( height, width * 8 / 5 );
     364    }
     365    else
     366    {
     367        height = MAX( height, width * 5 / 8 );
     368    }
     369    if( NULL != func )
     370    {
     371        func( arg );
     372    }
     373    gtk_widget_show_now( wind  );
     374    gtk_window_resize( GTK_WINDOW( wind ), width, height );
     375}
     376
     377void
    336378errmsg( GtkWindow * wind, const char * format, ... )
    337379{
  • trunk/gtk/util.h

    r1504 r1506  
    131131#ifdef GTK_MAJOR_VERSION
    132132
     133/* here there be dragons */
     134void
     135windowsizehack( GtkWidget * wind, GtkWidget * scroll, GtkWidget * view,
     136                callbackfunc_t func, void * arg );
     137
    133138/* create an error dialog, if wind is NULL or mapped then show dialog now,
    134139   otherwise show it when wind becomes mapped */
Note: See TracChangeset for help on using the changeset viewer.