~ubuntu-branches/ubuntu/maverick/transmission/maverick

« back to all changes in this revision

Viewing changes to gtk/torrent-cell-renderer.c

  • Committer: Bazaar Package Importer
  • Author(s): Krzysztof Klimonda
  • Date: 2009-05-22 21:57:30 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (2.1.18 sid) (1.3.8 upstream)
  • mto: This revision was merged to the branch mainline in revision 36.
  • Revision ID: james.westby@ubuntu.com-20090522215730-ly5kgv5aw9ig2u82
Tags: upstream-1.61
ImportĀ upstreamĀ versionĀ 1.61

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 * This exemption does not extend to derived works not owned by
8
8
 * the Transmission project.
9
9
 *
10
 
 * $Id: torrent-cell-renderer.c 7664 2009-01-11 17:46:51Z charles $
 
10
 * $Id: torrent-cell-renderer.c 8004 2009-03-03 19:43:23Z charles $
11
11
 */
12
12
 
13
13
#include "assert.h"
 
14
#include <string.h> /* strcmp */
14
15
#include <gtk/gtk.h>
15
16
#include <glib/gi18n.h>
16
17
#include <libtransmission/transmission.h>
17
18
#include "hig.h"
 
19
#include "icons.h"
18
20
#include "torrent-cell-renderer.h"
19
21
#include "tr-torrent.h"
20
22
#include "util.h"
29
31
};
30
32
 
31
33
#define DEFAULT_BAR_HEIGHT 12
 
34
#define SMALL_SCALE 0.9
 
35
#define MINIMAL_ICON_SIZE GTK_ICON_SIZE_MENU
 
36
#define FULL_ICON_SIZE GTK_ICON_SIZE_DND
32
37
 
33
38
/***
34
39
****
35
40
***/
36
41
 
37
42
static char*
38
 
getProgressString( const tr_info * info,
39
 
                   const tr_stat * torStat )
 
43
getProgressString( const tr_torrent * tor,
 
44
                   const tr_info    * info,
 
45
                   const tr_stat    * torStat )
40
46
{
41
47
    const int      isDone = torStat->leftUntilDone == 0;
42
48
    const uint64_t haveTotal = torStat->haveUnchecked + torStat->haveValid;
43
49
    const int      isSeed = torStat->haveValid >= info->totalSize;
44
50
    char           buf1[32], buf2[32], buf3[32], buf4[32];
45
51
    char *         str;
 
52
    double         seedRatio; 
 
53
    gboolean       hasSeedRatio;
46
54
 
47
55
    if( !isDone )
 
56
    {
48
57
        str = g_strdup_printf(
49
58
            /* %1$s is how much we've got,
50
59
               %2$s is how much we'll have when done,
53
62
            tr_strlsize( buf1, haveTotal, sizeof( buf1 ) ),
54
63
            tr_strlsize( buf2, torStat->sizeWhenDone, sizeof( buf2 ) ),
55
64
            torStat->percentDone * 100.0 );
 
65
    }
56
66
    else if( !isSeed )
 
67
    {
57
68
        str = g_strdup_printf(
58
69
            /* %1$s is how much we've got,
59
70
               %2$s is the torrent's total size,
66
77
            torStat->percentComplete * 100.0,
67
78
            tr_strlsize( buf3, torStat->uploadedEver, sizeof( buf3 ) ),
68
79
            tr_strlratio( buf4, torStat->ratio, sizeof( buf4 ) ) );
69
 
    else
 
80
    }
 
81
    else if(( hasSeedRatio = tr_torrentGetSeedRatio( tor, &seedRatio )))
 
82
    {
 
83
        str = g_strdup_printf(
 
84
            /* %1$s is the torrent's total size,
 
85
               %2$s is how much we've uploaded,
 
86
               %3$s is our upload-to-download ratio,
 
87
               $4$s is the ratio we want to reach before we stop uploading */
 
88
            _( "%1$s, uploaded %2$s (Ratio: %3$s Goal: %4$s)" ),
 
89
            tr_strlsize( buf1, info->totalSize, sizeof( buf1 ) ),
 
90
            tr_strlsize( buf2, torStat->uploadedEver, sizeof( buf2 ) ),
 
91
            tr_strlratio( buf3, torStat->ratio, sizeof( buf3 ) ),
 
92
            tr_strlratio( buf4, seedRatio, sizeof( buf4 ) ) );
 
93
    }
 
94
    else /* seeding w/o a ratio */
 
95
    {
70
96
        str = g_strdup_printf(
71
97
            /* %1$s is the torrent's total size,
72
98
               %2$s is how much we've uploaded,
75
101
            tr_strlsize( buf1, info->totalSize, sizeof( buf1 ) ),
76
102
            tr_strlsize( buf2, torStat->uploadedEver, sizeof( buf2 ) ),
77
103
            tr_strlratio( buf3, torStat->ratio, sizeof( buf3 ) ) );
 
104
    }
78
105
 
79
106
    /* add time when downloading */
80
 
    if( torStat->activity == TR_STATUS_DOWNLOAD )
 
107
    if( hasSeedRatio || ( torStat->activity == TR_STATUS_DOWNLOAD ) )
81
108
    {
82
109
        const int eta = torStat->eta;
83
110
        GString * gstr = g_string_new( str );
239
266
 
240
267
struct TorrentCellRendererPrivate
241
268
{
242
 
    tr_torrent *       tor;
243
 
    GtkCellRenderer *  text_renderer;
244
 
    GtkCellRenderer *  text_renderer_err;
245
 
    GtkCellRenderer *  progress_renderer;
 
269
    tr_torrent       * tor;
 
270
    GtkCellRenderer  * text_renderer;
 
271
    GtkCellRenderer  * text_renderer_err;
 
272
    GtkCellRenderer  * progress_renderer;
 
273
    GtkCellRenderer  * icon_renderer;
246
274
    int                bar_height;
247
275
    gboolean           minimal;
248
276
};
249
277
 
250
 
static void
251
 
torrent_cell_renderer_get_size( GtkCellRenderer * cell,
252
 
                                GtkWidget *       widget,
253
 
                                GdkRectangle *    cell_area,
254
 
                                gint *            x_offset,
255
 
                                gint *            y_offset,
256
 
                                gint *            width,
257
 
                                gint *            height )
 
278
/***
 
279
****
 
280
***/
 
281
 
 
282
static GdkPixbuf*
 
283
get_icon( const tr_torrent * tor, GtkIconSize icon_size, GtkWidget * for_widget )
 
284
{
 
285
    const char * mime_type;
 
286
    const tr_info * info = tr_torrentInfo( tor );
 
287
 
 
288
    if( info->fileCount > 1 )
 
289
        mime_type = DIRECTORY_MIME_TYPE;
 
290
    else
 
291
        mime_type = get_mime_type_from_filename( info->files[0].name );
 
292
 
 
293
    return get_mime_type_icon( mime_type, icon_size, for_widget );
 
294
}
 
295
 
 
296
static GtkCellRenderer*
 
297
get_text_renderer( const tr_stat * st, TorrentCellRenderer * r )
 
298
{
 
299
    return st->error ? r->priv->text_renderer_err : r->priv->text_renderer;
 
300
}
 
301
 
 
302
/***
 
303
****
 
304
***/
 
305
 
 
306
static void
 
307
get_size_minimal( TorrentCellRenderer * cell,
 
308
                  GtkWidget           * widget,
 
309
                  gint                * width,
 
310
                  gint                * height )
 
311
{
 
312
    int w, h;
 
313
    GdkRectangle icon_area;
 
314
    GdkRectangle name_area;
 
315
    GdkRectangle stat_area;
 
316
    const char * name;
 
317
    char * status;
 
318
    GdkPixbuf * icon;
 
319
    GtkCellRenderer * text_renderer;
 
320
 
 
321
    struct TorrentCellRendererPrivate * p = cell->priv;
 
322
    const tr_torrent * tor = p->tor;
 
323
    const tr_stat * st = tr_torrentStatCached( (tr_torrent*)tor );
 
324
 
 
325
    icon = get_icon( tor, MINIMAL_ICON_SIZE, widget );
 
326
    name = tr_torrentInfo( tor )->name;
 
327
    status = getShortStatusString( st );
 
328
 
 
329
    /* get the idealized cell dimensions */
 
330
    g_object_set( p->icon_renderer, "pixbuf", icon, NULL );
 
331
    gtk_cell_renderer_get_size( p->icon_renderer, widget, NULL, NULL, NULL, &w, &h );
 
332
    icon_area.width = w;
 
333
    icon_area.height = h;
 
334
    text_renderer = get_text_renderer( st, cell );
 
335
    g_object_set( text_renderer, "text", name, "ellipsize", PANGO_ELLIPSIZE_NONE,  "scale", 1.0, NULL );
 
336
    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
 
337
    name_area.width = w;
 
338
    name_area.height = h;
 
339
    g_object_set( text_renderer, "text", status, "scale", SMALL_SCALE, NULL );
 
340
    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
 
341
    stat_area.width = w;
 
342
    stat_area.height = h;
 
343
    
 
344
    /**
 
345
    *** LAYOUT
 
346
    **/
 
347
 
 
348
    if( width != NULL )
 
349
        *width = cell->parent.xpad * 2 + icon_area.width + GUI_PAD + name_area.width + GUI_PAD + stat_area.width;
 
350
    if( height != NULL )
 
351
        *height = cell->parent.ypad * 2 + name_area.height + p->bar_height;
 
352
 
 
353
    /* cleanup */
 
354
    g_free( status );
 
355
    g_object_unref( icon );
 
356
}
 
357
 
 
358
#define MAX3(a,b,c) MAX(a,MAX(b,c))
 
359
 
 
360
static void
 
361
get_size_full( TorrentCellRenderer * cell,
 
362
               GtkWidget           * widget,
 
363
               gint                * width,
 
364
               gint                * height )
 
365
{
 
366
    int w, h;
 
367
    GdkRectangle icon_area;
 
368
    GdkRectangle name_area;
 
369
    GdkRectangle stat_area;
 
370
    GdkRectangle prog_area;
 
371
    const char * name;
 
372
    char * status;
 
373
    char * progress;
 
374
    GdkPixbuf * icon;
 
375
    GtkCellRenderer * text_renderer;
 
376
 
 
377
    struct TorrentCellRendererPrivate * p = cell->priv;
 
378
    const tr_torrent * tor = p->tor;
 
379
    const tr_stat * st = tr_torrentStatCached( (tr_torrent*)tor );
 
380
    const tr_info * inf = tr_torrentInfo( tor );
 
381
 
 
382
    icon = get_icon( tor, FULL_ICON_SIZE, widget );
 
383
    name = inf->name;
 
384
    status = getStatusString( st );
 
385
    progress = getProgressString( tor, inf, st );
 
386
 
 
387
    /* get the idealized cell dimensions */
 
388
    g_object_set( p->icon_renderer, "pixbuf", icon, NULL );
 
389
    gtk_cell_renderer_get_size( p->icon_renderer, widget, NULL, NULL, NULL, &w, &h );
 
390
    icon_area.width = w;
 
391
    icon_area.height = h;
 
392
    text_renderer = get_text_renderer( st, cell );
 
393
    g_object_set( text_renderer, "text", name, "weight", PANGO_WEIGHT_BOLD, "scale", 1.0, "ellipsize", PANGO_ELLIPSIZE_NONE, NULL );
 
394
    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
 
395
    name_area.width = w;
 
396
    name_area.height = h;
 
397
    g_object_set( text_renderer, "text", progress, "weight", PANGO_WEIGHT_NORMAL, "scale", SMALL_SCALE, NULL );
 
398
    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
 
399
    prog_area.width = w;
 
400
    prog_area.height = h;
 
401
    g_object_set( text_renderer, "text", status, NULL );
 
402
    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
 
403
    stat_area.width = w;
 
404
    stat_area.height = h;
 
405
    
 
406
    /**
 
407
    *** LAYOUT
 
408
    **/
 
409
 
 
410
    if( width != NULL )
 
411
        *width = cell->parent.xpad * 2 + icon_area.width + GUI_PAD + MAX3( name_area.width, prog_area.width, stat_area.width );
 
412
    if( height != NULL )
 
413
        *height = cell->parent.ypad * 2 + name_area.height + prog_area.height + GUI_PAD_SMALL + p->bar_height + GUI_PAD_SMALL + stat_area.height;
 
414
 
 
415
    /* cleanup */
 
416
    g_free( status );
 
417
    g_free( progress );
 
418
    g_object_unref( icon );
 
419
}
 
420
 
 
421
 
 
422
static void
 
423
torrent_cell_renderer_get_size( GtkCellRenderer  * cell,
 
424
                                GtkWidget        * widget,
 
425
                                GdkRectangle     * cell_area,
 
426
                                gint             * x_offset,
 
427
                                gint             * y_offset,
 
428
                                gint             * width,
 
429
                                gint             * height )
258
430
{
259
431
    TorrentCellRenderer * self = TORRENT_CELL_RENDERER( cell );
260
432
 
261
433
    if( self && self->priv->tor )
262
434
    {
263
 
        const tr_torrent *                  tor = self->priv->tor;
264
 
        const tr_info *                     info = tr_torrentInfo( tor );
265
 
        const char *                        name = info->name;
266
 
        const tr_stat *                     torStat =
267
 
            tr_torrentStatCached( (tr_torrent*)tor );
268
 
        char *                              str;
269
 
        int                                 w = 0, h = 0;
270
435
        struct TorrentCellRendererPrivate * p = self->priv;
271
 
        GtkCellRenderer *                   text_renderer =
272
 
            torStat->error != 0
273
 
            ? p->
274
 
            text_renderer_err
275
 
            : p->
276
 
            text_renderer;
277
 
 
278
 
        g_object_set( text_renderer, "ellipsize", PANGO_ELLIPSIZE_NONE,
279
 
                      NULL );
280
 
 
281
 
        /* above the progressbar */
 
436
        int w, h;
 
437
 
282
438
        if( p->minimal )
283
 
        {
284
 
            int    w1, w2, h1, h2;
285
 
            char * shortStatus = getShortStatusString( torStat );
286
 
            g_object_set( text_renderer, "text", name, NULL );
287
 
            gtk_cell_renderer_get_size( text_renderer,
288
 
                                        widget, NULL, NULL, NULL, &w1, &h1 );
289
 
            str = g_markup_printf_escaped( "<small>%s</small>", shortStatus );
290
 
            g_object_set( text_renderer, "markup", str, NULL );
291
 
            gtk_cell_renderer_get_size( text_renderer,
292
 
                                        widget, NULL, NULL, NULL, &w2, &h2 );
293
 
            h += MAX( h1, h2 );
294
 
            w = MAX( w, w1 + GUI_PAD_BIG + w2 );
295
 
            g_free( str );
296
 
            g_free( shortStatus );
297
 
        }
 
439
            get_size_minimal( TORRENT_CELL_RENDERER( cell ), widget, &w, &h );
298
440
        else
299
 
        {
300
 
            int    w1, h1;
301
 
            char * progressString = getProgressString( info, torStat );
302
 
            str = g_markup_printf_escaped( "<b>%s</b>\n<small>%s</small>",
303
 
                                           name, progressString );
304
 
            g_object_set( text_renderer, "markup", str, NULL );
305
 
            gtk_cell_renderer_get_size( text_renderer,
306
 
                                        widget, NULL, NULL, NULL, &w1, &h1 );
307
 
            h += h1;
308
 
            w = MAX( w, w1 );
309
 
            g_free( str );
310
 
            g_free( progressString );
311
 
        }
312
 
 
313
 
        /* below the progressbar */
314
 
        if( !p->minimal )
315
 
        {
316
 
            int    w1, h1;
317
 
            char * statusString = getStatusString( torStat );
318
 
            str = g_markup_printf_escaped( "<small>%s</small>",
319
 
                                           statusString );
320
 
            g_object_set( text_renderer, "markup", str, NULL );
321
 
            gtk_cell_renderer_get_size( text_renderer,
322
 
                                        widget, NULL, NULL, NULL, &w1, &h1 );
323
 
            h += h1;
324
 
            w = MAX( w, w1 );
325
 
            g_free( str );
326
 
            g_free( statusString );
327
 
        }
328
 
 
329
 
        h += p->bar_height;
330
 
 
331
 
        if( cell_area )
332
 
        {
 
441
            get_size_full( TORRENT_CELL_RENDERER( cell ), widget, &w, &h );
 
442
 
 
443
        if( width )
 
444
            *width = w;
 
445
 
 
446
        if( height )
 
447
            *height = h;
 
448
 
 
449
        if( cell_area ) {
333
450
            if( x_offset ) *x_offset = 0;
334
 
            if( y_offset )
335
 
            {
336
 
                *y_offset = 0.5 *
337
 
                            ( cell_area->height - ( h + ( 2 * cell->ypad ) ) );
 
451
            if( y_offset ) {
 
452
                *y_offset = 0.5 * ( cell_area->height - ( h + ( 2 * cell->ypad ) ) );
338
453
                *y_offset = MAX( *y_offset, 0 );
339
454
            }
340
455
        }
341
 
 
342
 
        *width = w + cell->xpad * 2;
343
 
        *height = h + cell->ypad * 2;
344
456
    }
345
457
}
346
458
 
347
459
static void
348
 
torrent_cell_renderer_render(
349
 
    GtkCellRenderer *                  cell,
350
 
    GdkDrawable *                      window,
351
 
    GtkWidget *                        widget,
352
 
    GdkRectangle *
353
 
                                       background_area,
354
 
    GdkRectangle         * cell_area   UNUSED,
355
 
    GdkRectangle         * expose_area UNUSED,
356
 
    GtkCellRendererState               flags )
 
460
render_minimal( TorrentCellRenderer   * cell,
 
461
                GdkDrawable           * window,
 
462
                GtkWidget             * widget,
 
463
                GdkRectangle          * background_area,
 
464
                GdkRectangle          * cell_area UNUSED,
 
465
                GdkRectangle          * expose_area UNUSED,
 
466
                GtkCellRendererState    flags )
 
467
{
 
468
    int w, h;
 
469
    GdkRectangle icon_area;
 
470
    GdkRectangle name_area;
 
471
    GdkRectangle stat_area;
 
472
    GdkRectangle prog_area;
 
473
    GdkRectangle fill_area;
 
474
    const char * name;
 
475
    char * status;
 
476
    GdkPixbuf * icon;
 
477
    GtkCellRenderer * text_renderer;
 
478
 
 
479
    struct TorrentCellRendererPrivate * p = cell->priv;
 
480
    const tr_torrent * tor = p->tor;
 
481
    const tr_stat * st = tr_torrentStatCached( (tr_torrent*)tor );
 
482
    const gboolean active = st->activity != TR_STATUS_STOPPED;
 
483
    const double percentDone = MAX( 0.0, st->percentDone );
 
484
 
 
485
    icon = get_icon( tor, MINIMAL_ICON_SIZE, widget );
 
486
    name = tr_torrentInfo( tor )->name;
 
487
    status = getShortStatusString( st );
 
488
 
 
489
    /* get the cell dimensions */
 
490
    g_object_set( p->icon_renderer, "pixbuf", icon, NULL );
 
491
    gtk_cell_renderer_get_size( p->icon_renderer, widget, NULL, NULL, NULL, &w, &h );
 
492
    icon_area.width = w;
 
493
    icon_area.height = h;
 
494
    text_renderer = get_text_renderer( st, cell );
 
495
    g_object_set( text_renderer, "text", name, "ellipsize", PANGO_ELLIPSIZE_NONE, "scale", 1.0, NULL );
 
496
    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
 
497
    name_area.width = w;
 
498
    name_area.height = h;
 
499
    g_object_set( text_renderer, "text", status, "scale", SMALL_SCALE, NULL );
 
500
    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
 
501
    stat_area.width = w;
 
502
    stat_area.height = h;
 
503
 
 
504
    /**
 
505
    *** LAYOUT
 
506
    **/
 
507
 
 
508
    fill_area = *background_area;
 
509
    fill_area.x += cell->parent.xpad;
 
510
    fill_area.y += cell->parent.ypad;
 
511
    fill_area.width -= cell->parent.xpad * 2;
 
512
    fill_area.height -= cell->parent.ypad * 2;
 
513
 
 
514
    /* icon */
 
515
    icon_area.x = fill_area.x;
 
516
    icon_area.y = fill_area.y + ( fill_area.height - icon_area.height ) / 2;
 
517
 
 
518
    /* short status (right justified) */
 
519
    stat_area.x = fill_area.x + fill_area.width - stat_area.width;
 
520
    stat_area.y = fill_area.y + ( name_area.height - stat_area.height ) / 2;
 
521
 
 
522
    /* name */
 
523
    name_area.x = icon_area.x + icon_area.width + GUI_PAD;
 
524
    name_area.y = fill_area.y;
 
525
    name_area.width = stat_area.x - GUI_PAD - name_area.x;
 
526
 
 
527
    /* progressbar */
 
528
    prog_area.x = name_area.x;
 
529
    prog_area.y = name_area.y + name_area.height;
 
530
    prog_area.width = name_area.width + GUI_PAD + stat_area.width;
 
531
    prog_area.height = p->bar_height;
 
532
 
 
533
    /**
 
534
    *** RENDER
 
535
    **/
 
536
   
 
537
    g_object_set( p->icon_renderer, "pixbuf", icon, "sensitive", active, NULL );
 
538
    gtk_cell_renderer_render( p->icon_renderer, window, widget, &icon_area, &icon_area, &icon_area, flags );
 
539
    g_object_set( text_renderer, "text", status, "scale", SMALL_SCALE, "sensitive", active, "ellipsize", PANGO_ELLIPSIZE_END, NULL );
 
540
    gtk_cell_renderer_render( text_renderer, window, widget, &stat_area, &stat_area, &stat_area, flags );
 
541
    g_object_set( text_renderer, "text", name, "scale", 1.0, NULL );
 
542
    gtk_cell_renderer_render( text_renderer, window, widget, &name_area, &name_area, &name_area, flags );
 
543
    g_object_set( p->progress_renderer, "value", (int)(percentDone*100.0), "text", "", "sensitive", active, NULL );
 
544
    gtk_cell_renderer_render( p->progress_renderer, window, widget, &prog_area, &prog_area, &prog_area, flags );
 
545
 
 
546
    /* cleanup */
 
547
    g_free( status );
 
548
    g_object_unref( icon );
 
549
}
 
550
 
 
551
static void
 
552
render_full( TorrentCellRenderer   * cell,
 
553
             GdkDrawable           * window,
 
554
             GtkWidget             * widget,
 
555
             GdkRectangle          * background_area,
 
556
             GdkRectangle          * cell_area UNUSED,
 
557
             GdkRectangle          * expose_area UNUSED,
 
558
             GtkCellRendererState    flags )
 
559
{
 
560
    int w, h;
 
561
    GdkRectangle fill_area;
 
562
    GdkRectangle icon_area;
 
563
    GdkRectangle name_area;
 
564
    GdkRectangle stat_area;
 
565
    GdkRectangle prog_area;
 
566
    GdkRectangle prct_area;
 
567
    const char * name;
 
568
    char * status;
 
569
    char * progress;
 
570
    GdkPixbuf * icon;
 
571
    GtkCellRenderer * text_renderer;
 
572
 
 
573
    struct TorrentCellRendererPrivate * p = cell->priv;
 
574
    const tr_torrent * tor = p->tor;
 
575
    const tr_stat * st = tr_torrentStatCached( (tr_torrent*)tor );
 
576
    const tr_info * inf = tr_torrentInfo( tor );
 
577
    const gboolean active = st->activity != TR_STATUS_STOPPED;
 
578
    const double percentDone = MAX( 0.0, st->percentDone );
 
579
 
 
580
    icon = get_icon( tor, FULL_ICON_SIZE, widget );
 
581
    name = inf->name;
 
582
    status = getStatusString( st );
 
583
    progress = getProgressString( tor, inf, st );
 
584
 
 
585
    /* get the idealized cell dimensions */
 
586
    g_object_set( p->icon_renderer, "pixbuf", icon, NULL );
 
587
    gtk_cell_renderer_get_size( p->icon_renderer, widget, NULL, NULL, NULL, &w, &h );
 
588
    icon_area.width = w;
 
589
    icon_area.height = h;
 
590
    text_renderer = get_text_renderer( st, cell );
 
591
    g_object_set( text_renderer, "text", name, "weight", PANGO_WEIGHT_BOLD, "ellipsize", PANGO_ELLIPSIZE_NONE, "scale", 1.0, NULL );
 
592
    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
 
593
    name_area.width = w;
 
594
    name_area.height = h;
 
595
    g_object_set( text_renderer, "text", progress, "weight", PANGO_WEIGHT_NORMAL, "scale", SMALL_SCALE, NULL );
 
596
    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
 
597
    prog_area.width = w;
 
598
    prog_area.height = h;
 
599
    g_object_set( text_renderer, "text", status, NULL );
 
600
    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
 
601
    stat_area.width = w;
 
602
    stat_area.height = h;
 
603
    
 
604
    /**
 
605
    *** LAYOUT
 
606
    **/
 
607
 
 
608
    fill_area = *background_area;
 
609
    fill_area.x += cell->parent.xpad;
 
610
    fill_area.y += cell->parent.ypad;
 
611
    fill_area.width -= cell->parent.xpad * 2;
 
612
    fill_area.height -= cell->parent.ypad * 2;
 
613
 
 
614
    /* icon */
 
615
    icon_area.x = fill_area.x;
 
616
    icon_area.y = fill_area.y + ( fill_area.height - icon_area.height ) / 2;
 
617
 
 
618
    /* name */
 
619
    name_area.x = icon_area.x + icon_area.width + GUI_PAD;
 
620
    name_area.y = fill_area.y;
 
621
    name_area.width = fill_area.width - GUI_PAD - icon_area.width - GUI_PAD_SMALL;
 
622
 
 
623
    /* prog */
 
624
    prog_area.x = name_area.x;
 
625
    prog_area.y = name_area.y + name_area.height;
 
626
    prog_area.width = name_area.width;
 
627
 
 
628
    /* progressbar */
 
629
    prct_area.x = prog_area.x;
 
630
    prct_area.y = prog_area.y + prog_area.height + GUI_PAD_SMALL;
 
631
    prct_area.width = prog_area.width;
 
632
    prct_area.height = p->bar_height;
 
633
 
 
634
    /* status */
 
635
    stat_area.x = prct_area.x;
 
636
    stat_area.y = prct_area.y + prct_area.height + GUI_PAD_SMALL;
 
637
    stat_area.width = prct_area.width;
 
638
 
 
639
    /**
 
640
    *** RENDER
 
641
    **/
 
642
   
 
643
    g_object_set( p->icon_renderer, "pixbuf", icon, "sensitive", active, NULL );
 
644
    gtk_cell_renderer_render( p->icon_renderer, window, widget, &icon_area, &icon_area, &icon_area, flags );
 
645
    g_object_set( text_renderer, "text", name, "scale", 1.0, "sensitive", active, "ellipsize", PANGO_ELLIPSIZE_END, "weight", PANGO_WEIGHT_BOLD, NULL );
 
646
    gtk_cell_renderer_render( text_renderer, window, widget, &name_area, &name_area, &name_area, flags );
 
647
    g_object_set( text_renderer, "text", progress, "scale", SMALL_SCALE, "weight", PANGO_WEIGHT_NORMAL, NULL );
 
648
    gtk_cell_renderer_render( text_renderer, window, widget, &prog_area, &prog_area, &prog_area, flags );
 
649
    g_object_set( p->progress_renderer, "value", (int)(percentDone*100.0), "text", "", "sensitive", active, NULL );
 
650
    gtk_cell_renderer_render( p->progress_renderer, window, widget, &prct_area, &prct_area, &prct_area, flags );
 
651
    g_object_set( text_renderer, "text", status, NULL );
 
652
    gtk_cell_renderer_render( text_renderer, window, widget, &stat_area, &stat_area, &stat_area, flags );
 
653
 
 
654
    /* cleanup */
 
655
    g_free( status );
 
656
    g_free( progress );
 
657
    g_object_unref( icon );
 
658
}
 
659
 
 
660
static void
 
661
torrent_cell_renderer_render( GtkCellRenderer       * cell,
 
662
                              GdkDrawable           * window,
 
663
                              GtkWidget             * widget,
 
664
                              GdkRectangle          * background_area,
 
665
                              GdkRectangle          * cell_area,
 
666
                              GdkRectangle          * expose_area,
 
667
                              GtkCellRendererState    flags )
357
668
{
358
669
    TorrentCellRenderer * self = TORRENT_CELL_RENDERER( cell );
359
670
 
364
675
 
365
676
    if( self && self->priv->tor )
366
677
    {
367
 
        const tr_torrent *                  tor = self->priv->tor;
368
 
        const tr_info *                     info = tr_torrentInfo( tor );
369
 
        const char *                        name = info->name;
370
 
        const tr_stat *                     torStat =
371
 
            tr_torrentStatCached( (tr_torrent*)tor );
372
 
        GdkRectangle                        my_bg;
373
 
        GdkRectangle                        my_cell;
374
 
        GdkRectangle                        my_expose;
375
 
        int                                 w, h;
376
678
        struct TorrentCellRendererPrivate * p = self->priv;
377
 
        GtkCellRenderer * text_renderer = torStat->error != 0
378
 
                                        ? p->text_renderer_err
379
 
                                        : p->text_renderer;
380
 
        const gboolean isActive = torStat->activity != TR_STATUS_STOPPED;
381
 
 
382
 
        my_bg = *background_area;
383
 
        my_bg.x += cell->xpad;
384
 
        my_bg.y += cell->ypad;
385
 
        my_bg.width -= cell->xpad * 2;
386
 
        my_cell = my_expose = my_bg;
387
 
 
388
 
        g_object_set( text_renderer, "sensitive", isActive, NULL );
389
 
        g_object_set( p->progress_renderer, "sensitive", isActive, NULL );
390
 
 
391
 
        /* above the progressbar */
392
 
        if( !p->minimal )
393
 
        {
394
 
            char * progressString = getProgressString( info, torStat );
395
 
            char * str = g_markup_printf_escaped(
396
 
                "<b>%s</b>\n<small>%s</small>",
397
 
                name, progressString );
398
 
            g_object_set( text_renderer, "markup", str,
399
 
                          "ellipsize", PANGO_ELLIPSIZE_NONE,
400
 
                          NULL );
401
 
            gtk_cell_renderer_get_size( text_renderer,
402
 
                                        widget, NULL, NULL, NULL, &w, &h );
403
 
            my_bg.height     =
404
 
                my_cell.height   =
405
 
                    my_expose.height = h;
406
 
            g_object_set( text_renderer, "ellipsize", PANGO_ELLIPSIZE_END,
407
 
                          NULL );
408
 
            gtk_cell_renderer_render( text_renderer,
409
 
                                      window, widget,
410
 
                                      &my_bg, &my_cell, &my_expose, flags );
411
 
            my_bg.y += h;
412
 
            my_cell.y += h;
413
 
            my_expose.y += h;
414
 
 
415
 
            g_free( str );
416
 
            g_free( progressString );
417
 
        }
 
679
        if( p->minimal )
 
680
            render_minimal( self, window, widget, background_area, cell_area, expose_area, flags );
418
681
        else
419
 
        {
420
 
            char *       statusStr = getShortStatusString( torStat );
421
 
            char *       str = g_markup_printf_escaped( "<small>%s</small>",
422
 
                                                        statusStr );
423
 
            int          w1, w2, h1, h2, tmp_h;
424
 
            GdkRectangle tmp_bg, tmp_cell, tmp_expose;
425
 
 
426
 
            /* get the dimensions for the name */
427
 
            g_object_set( text_renderer, "text", name,
428
 
                          "ellipsize", PANGO_ELLIPSIZE_NONE,
429
 
                          NULL );
430
 
            gtk_cell_renderer_get_size( text_renderer,
431
 
                                        widget, NULL, NULL, NULL, &w1, &h1 );
432
 
 
433
 
            /* get the dimensions for the short status string */
434
 
            g_object_set( text_renderer, "markup", str,
435
 
                          "ellipsize", PANGO_ELLIPSIZE_NONE,
436
 
                          NULL );
437
 
            gtk_cell_renderer_get_size( text_renderer,
438
 
                                        widget, NULL, NULL, NULL, &w2, &h2 );
439
 
 
440
 
            tmp_h = MAX( h1, h2 );
441
 
 
442
 
            /* short status */
443
 
            tmp_bg.x = my_bg.width - w2;
444
 
            tmp_bg.y = my_bg.y + ( h2 - h1 ) / 2;
445
 
            tmp_bg.width = w2;
446
 
            tmp_bg.height = tmp_h;
447
 
            tmp_expose = tmp_cell = tmp_bg;
448
 
            g_object_set( text_renderer, "markup", str,
449
 
                          "ellipsize", PANGO_ELLIPSIZE_END,
450
 
                          NULL );
451
 
            gtk_cell_renderer_render( text_renderer,
452
 
                                      window, widget,
453
 
                                      &tmp_bg, &tmp_cell, &tmp_expose,
454
 
                                      flags );
455
 
 
456
 
            /* name */
457
 
            tmp_bg.x = my_bg.x;
458
 
            tmp_bg.width = my_bg.width - w2 - GUI_PAD_BIG;
459
 
            tmp_expose = tmp_cell = tmp_bg;
460
 
            g_object_set( text_renderer, "text", name,
461
 
                          "ellipsize", PANGO_ELLIPSIZE_END,
462
 
                          NULL );
463
 
            gtk_cell_renderer_render( text_renderer,
464
 
                                      window, widget,
465
 
                                      &tmp_bg, &tmp_cell, &tmp_expose,
466
 
                                      flags );
467
 
 
468
 
            my_bg.y = tmp_bg.y + tmp_bg.height;
469
 
            my_cell.y = tmp_cell.y + tmp_cell.height;
470
 
            my_expose.y = tmp_expose.y + tmp_cell.height;
471
 
 
472
 
            g_free( str );
473
 
            g_free( statusStr );
474
 
        }
475
 
 
476
 
        /* the progressbar */
477
 
        my_cell.height = p->bar_height;
478
 
        if( 1 )
479
 
        {
480
 
            const double percent = MAX( 0.0, torStat->percentDone );
481
 
            g_object_set( p->progress_renderer, "value",
482
 
                          (int)( percent * 100.0 ),
483
 
                          "text", "",
484
 
                          NULL );
485
 
            gtk_cell_renderer_render( p->progress_renderer,
486
 
                                      window, widget,
487
 
                                      &my_cell, &my_cell, &my_cell, flags );
488
 
        }
489
 
        my_bg.y     += my_cell.height;
490
 
        my_cell.y   += my_cell.height;
491
 
        my_expose.y += my_cell.height;
492
 
 
493
 
        /* below progressbar */
494
 
        if( !p->minimal )
495
 
        {
496
 
            char * statusString = getStatusString( torStat );
497
 
            char * str = g_markup_printf_escaped( "<small>%s</small>",
498
 
                                                  statusString );
499
 
            g_object_set( text_renderer, "markup", str,
500
 
                          "ellipsize", PANGO_ELLIPSIZE_END,
501
 
                          NULL );
502
 
            gtk_cell_renderer_get_size( text_renderer,
503
 
                                        widget, NULL, NULL, NULL, &w, &h );
504
 
            my_bg.height      =
505
 
                my_cell.height    =
506
 
                    my_expose.height  = h;
507
 
            gtk_cell_renderer_render( text_renderer,
508
 
                                      window, widget,
509
 
                                      &my_bg, &my_cell, &my_expose, flags );
510
 
 
511
 
            g_free( str );
512
 
            g_free( statusString );
513
 
        }
 
682
            render_full( self, window, widget, background_area, cell_area, expose_area, flags );
514
683
    }
515
684
 
516
685
#ifdef TEST_RTL
583
752
        g_object_unref( G_OBJECT( r->priv->text_renderer ) );
584
753
        g_object_unref( G_OBJECT( r->priv->text_renderer_err ) );
585
754
        g_object_unref( G_OBJECT( r->priv->progress_renderer ) );
 
755
        g_object_unref( G_OBJECT( r->priv->icon_renderer ) );
586
756
        r->priv = NULL;
587
757
    }
588
758
 
642
812
 
643
813
    p->tor = NULL;
644
814
    p->text_renderer = gtk_cell_renderer_text_new( );
 
815
    g_object_set( p->text_renderer, "xpad", 0, "ypad", 0, NULL );
645
816
    p->text_renderer_err = gtk_cell_renderer_text_new(  );
 
817
    g_object_set( p->text_renderer_err, "xpad", 0, "ypad", 0, NULL );
646
818
    p->progress_renderer = gtk_cell_renderer_progress_new(  );
 
819
    p->icon_renderer = gtk_cell_renderer_pixbuf_new(  );
647
820
    g_object_set( p->text_renderer_err, "foreground", "red", NULL );
648
821
    tr_object_ref_sink( p->text_renderer );
649
822
    tr_object_ref_sink( p->text_renderer_err );
650
823
    tr_object_ref_sink( p->progress_renderer );
 
824
    tr_object_ref_sink( p->icon_renderer );
651
825
 
652
826
    p->bar_height = DEFAULT_BAR_HEIGHT;
653
827
}