source: trunk/qt/tracker-delegate.cc @ 11092

Last change on this file since 11092 was 11092, checked in by charles, 12 years ago

(trunk qt) synchronize the copyright notices

File size: 8.8 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
9 *
10 * $Id: torrent-delegate.cc 11051 2010-07-24 23:51:02Z charles $
11 */
12
13#include <iostream>
14
15#include <QApplication>
16#include <QBrush>
17#include <QFont>
18#include <QFontMetrics>
19#include <QIcon>
20#include <QModelIndex>
21#include <QPainter>
22#include <QPixmap>
23#include <QPixmapCache>
24#include <QStyleOptionProgressBarV2>
25#include <QTextDocument>
26#include <QUrl>
27
28#include <libtransmission/transmission.h>
29#include <libtransmission/utils.h>
30
31#include "favicon.h"
32#include "formatter.h"
33#include "torrent.h"
34#include "tracker-delegate.h"
35#include "tracker-model.h"
36
37/***
38****
39***/
40
41namespace
42{
43    const int mySpacing = 6;
44    const QSize myMargin( 10, 6 );
45}
46
47QSize
48TrackerDelegate :: margin( const QStyle& style ) const
49{
50    Q_UNUSED( style );
51
52    return myMargin;
53}
54
55/***
56****
57***/
58
59QSize
60TrackerDelegate :: sizeHint( const QStyleOptionViewItem& option, const TrackerInfo& info ) const
61{
62    Q_UNUSED( option );
63
64    QPixmap favicon = info.st.getFavicon( );
65   
66    const QString text = TrackerDelegate :: getText( info );
67    QTextDocument textDoc;
68    textDoc.setHtml( text );
69    const QSize textSize = textDoc.size().toSize();
70
71    return QSize( myMargin.width() + favicon.width() + mySpacing + textSize.width() + myMargin.width(),
72                  myMargin.height() + qMax<int>( favicon.height(), textSize.height() ) + myMargin.height() );
73}
74
75QSize
76TrackerDelegate :: sizeHint( const QStyleOptionViewItem  & option,
77                             const QModelIndex           & index ) const
78{
79    const TrackerInfo trackerInfo = index.data( TrackerModel::TrackerRole ).value<TrackerInfo>();
80    return sizeHint( option, trackerInfo );
81}
82
83void
84TrackerDelegate :: paint( QPainter                    * painter,
85                          const QStyleOptionViewItem  & option,
86                          const QModelIndex           & index) const
87{
88    const TrackerInfo trackerInfo = index.data( TrackerModel::TrackerRole ).value<TrackerInfo>();
89    painter->save( );
90    painter->setClipRect( option.rect );
91    drawBackground( painter, option, index );
92    drawTracker( painter, option, trackerInfo );
93    drawFocus(painter, option, option.rect );
94    painter->restore( );
95}
96
97void
98TrackerDelegate :: drawTracker( QPainter                    * painter,
99                                const QStyleOptionViewItem  & option,
100                                const TrackerInfo           & inf ) const
101{
102    painter->save( );
103
104    QPixmap icon = inf.st.getFavicon( );
105    QRect iconArea( option.rect.x() + myMargin.width(),
106                    option.rect.y() + myMargin.height(),
107                    icon.width(),
108                    icon.height() );
109    painter->drawPixmap( iconArea.x(), iconArea.y()+4, icon );
110
111    const int textWidth = option.rect.width() - myMargin.width()*2 - mySpacing - icon.width();
112    const int textX = myMargin.width() + icon.width() + mySpacing;
113    const QString text = getText( inf );
114    QTextDocument textDoc;
115    textDoc.setHtml( text );
116    const QRect textRect( textX, iconArea.y(), textWidth, option.rect.height() - myMargin.height()*2 );
117    painter->translate( textRect.topLeft( ) );
118    textDoc.drawContents( painter, textRect.translated( -textRect.topLeft( ) ) );
119
120    painter->restore( );
121}
122
123void
124TrackerDelegate :: setShowMore( bool b )
125{
126    myShowMore = b;
127}
128
129namespace
130{
131    QString timeToStringRounded( int seconds )
132    {
133        if( seconds > 60 ) seconds -= ( seconds % 60 );
134        return Formatter::timeToString ( seconds );
135    }
136}
137
138QString
139TrackerDelegate :: getText( const TrackerInfo& inf ) const
140{
141    QString key;
142    QString str;
143    const time_t now( time( 0 ) );
144    const QString err_markup_begin = "<span style=\"color:red\">";
145    const QString err_markup_end = "</span>";
146    const QString timeout_markup_begin = "<span style=\"color:#224466\">";
147    const QString timeout_markup_end = "</span>";
148    const QString success_markup_begin = "<span style=\"color:#008B00\">";
149    const QString success_markup_end = "</span>";
150
151    // hostname
152    str += inf.st.isBackup ? "<i>" : "<b>";
153    char * host = NULL;
154    int port = 0;
155    tr_urlParse( inf.st.announce.toUtf8().constData(), -1, NULL, &host, &port, NULL );
156    str += QString( "%1:%2" ).arg( host ).arg( port );
157    tr_free( host );
158    if( !key.isEmpty( ) ) str += " - " + key;
159    str += inf.st.isBackup ? "</i>" : "</b>";
160
161    // announce & scrape info
162    if( !inf.st.isBackup )
163    {
164        if( inf.st.hasAnnounced )
165        {
166            const QString tstr( timeToStringRounded( now - inf.st.lastAnnounceTime ) );
167            str += "<br/>\n";
168            if( inf.st.lastAnnounceSucceeded )
169            {
170                str += tr( "Got a list of %1%2 peers%3 %4 ago" )
171                           .arg( success_markup_begin )
172                           .arg( inf.st.lastAnnouncePeerCount )
173                           .arg( success_markup_end )
174                           .arg( tstr );
175            }
176            else if( inf.st.lastAnnounceTimedOut )
177            {
178                str += tr( "Peer list request %1timed out%2 %3 ago; will retry" )
179                           .arg( timeout_markup_begin )
180                           .arg( timeout_markup_end )
181                           .arg( tstr );
182            }
183            else
184            {
185                str += tr( "Got an error %1\"%2\"%3 %4 ago" )
186                           .arg( err_markup_begin )
187                           .arg( inf.st.lastAnnounceResult )
188                           .arg( err_markup_end )
189                           .arg( tstr );
190            }
191        }
192
193        switch( inf.st.announceState )
194        {
195            case TR_TRACKER_INACTIVE:
196                if( !inf.st.hasAnnounced ) {
197                    str += "<br/>\n";
198                    str += tr( "No updates scheduled" );
199                }
200                break;
201
202            case TR_TRACKER_WAITING: {
203                const QString tstr( timeToStringRounded( inf.st.nextAnnounceTime - now ) );
204                str += "<br/>\n";
205                str += tr( "Asking for more peers in %1" ).arg( tstr );
206                break;
207            }
208
209            case TR_TRACKER_QUEUED:
210                str += "<br/>\n";
211                str += tr( "Queued to ask for more peers" );
212                break;
213
214            case TR_TRACKER_ACTIVE: {
215                const QString tstr( timeToStringRounded( now - inf.st.lastAnnounceStartTime ) );
216                str += "<br/>\n";
217                str += tr( "Asking for more peers now... <small>%1</small>" ).arg( tstr );
218                break;
219            }
220        }
221
222        if( myShowMore )
223        {
224            if( inf.st.hasScraped )
225            {
226                str += "<br/>\n";
227                const QString tstr( timeToStringRounded( now - inf.st.lastScrapeTime ) );
228                if( inf.st.lastScrapeSucceeded )
229                {
230                    str += tr( "Tracker had %1%2 seeders%3 and %4%5 leechers%6 %7 ago" )
231                               .arg( success_markup_begin )
232                               .arg( inf.st.seederCount )
233                               .arg( success_markup_end )
234                               .arg( success_markup_begin )
235                               .arg( inf.st.leecherCount )
236                               .arg( success_markup_end )
237                               .arg( tstr );
238                }
239                else
240                {
241                    str += tr( "Got a scrape error %1\"%2\"%3 %4 ago" )
242                               .arg( err_markup_begin )
243                               .arg( inf.st.lastScrapeResult )
244                               .arg( err_markup_end )
245                               .arg( tstr );
246                }
247            }
248
249            switch( inf.st.scrapeState )
250            {
251                case TR_TRACKER_INACTIVE:
252                    break;
253
254                case TR_TRACKER_WAITING: {
255                    str += "<br/>\n";
256                    const QString tstr( timeToStringRounded( inf.st.nextScrapeTime - now ) );
257                    str += tr( "Asking for peer counts in %1" ).arg( tstr );
258                    break;
259                }
260
261                case TR_TRACKER_QUEUED: {
262                    str += "<br/>\n";
263                    str += tr( "Queued to ask for peer counts" );
264                    break;
265                }
266
267                case TR_TRACKER_ACTIVE: {
268                    str += "<br/>\n";
269                    const QString tstr( timeToStringRounded( now - inf.st.lastScrapeStartTime ) );
270                    str += tr( "Asking for peer counts now... <small>%1</small>" ).arg( tstr );
271                    break;
272                }
273            }
274        }
275    }
276
277    return str;
278}
Note: See TracBrowser for help on using the repository browser.