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

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

(trunk qt) minor cleanup in the delegate code

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