2 * This file Copyright (C) Mnemosyne LLC
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.
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10 * $Id: tracker-delegate.cc 11522 2010-12-12 16:43:19Z charles $
17 #include <QTextDocument>
19 #include <libtransmission/transmission.h>
20 #include <libtransmission/utils.h>
23 #include "formatter.h"
25 #include "tracker-delegate.h"
26 #include "tracker-model.h"
34 const int mySpacing
= 6;
35 const QSize
myMargin( 10, 6 );
39 TrackerDelegate :: margin( const QStyle
& style
) const
51 TrackerDelegate :: sizeHint( const QStyleOptionViewItem
& option
, const TrackerInfo
& info
) const
55 QPixmap favicon
= info
.st
.getFavicon( );
57 const QString text
= TrackerDelegate :: getText( info
);
58 QTextDocument textDoc
;
59 textDoc
.setHtml( text
);
60 const QSize textSize
= textDoc
.size().toSize();
62 return QSize( myMargin
.width() + favicon
.width() + mySpacing
+ textSize
.width() + myMargin
.width(),
63 myMargin
.height() + qMax
<int>( favicon
.height(), textSize
.height() ) + myMargin
.height() );
67 TrackerDelegate :: sizeHint( const QStyleOptionViewItem
& option
,
68 const QModelIndex
& index
) const
70 const TrackerInfo trackerInfo
= index
.data( TrackerModel::TrackerRole
).value
<TrackerInfo
>();
71 return sizeHint( option
, trackerInfo
);
75 TrackerDelegate :: paint( QPainter
* painter
,
76 const QStyleOptionViewItem
& option
,
77 const QModelIndex
& index
) const
79 const TrackerInfo trackerInfo
= index
.data( TrackerModel::TrackerRole
).value
<TrackerInfo
>();
81 painter
->setClipRect( option
.rect
);
82 drawBackground( painter
, option
, index
);
83 drawTracker( painter
, option
, trackerInfo
);
84 drawFocus(painter
, option
, option
.rect
);
89 TrackerDelegate :: drawTracker( QPainter
* painter
,
90 const QStyleOptionViewItem
& option
,
91 const TrackerInfo
& inf
) const
95 QPixmap icon
= inf
.st
.getFavicon( );
96 QRect
iconArea( option
.rect
.x() + myMargin
.width(),
97 option
.rect
.y() + myMargin
.height(),
100 painter
->drawPixmap( iconArea
.x(), iconArea
.y()+4, icon
);
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( ) ) );
115 TrackerDelegate :: setShowMore( bool b
)
122 QString
timeToStringRounded( int seconds
)
124 if( seconds
> 60 ) seconds
-= ( seconds
% 60 );
125 return Formatter::timeToString ( seconds
);
130 TrackerDelegate :: getText( const TrackerInfo
& inf
) const
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>";
143 str
+= inf
.st
.isBackup
? "<i>" : "<b>";
146 tr_urlParse( inf
.st
.announce
.toUtf8().constData(), -1, NULL
, &host
, &port
, NULL
);
147 str
+= QString( "%1:%2" ).arg( host
).arg( port
);
149 if( !key
.isEmpty( ) ) str
+= " - " + key
;
150 str
+= inf
.st
.isBackup
? "</i>" : "</b>";
152 // announce & scrape info
153 if( !inf
.st
.isBackup
)
155 if( inf
.st
.hasAnnounced
&& inf
.st
.announceState
!= TR_TRACKER_INACTIVE
)
157 const QString
tstr( timeToStringRounded( now
- inf
.st
.lastAnnounceTime
) );
159 if( inf
.st
.lastAnnounceSucceeded
)
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
)
167 else if( inf
.st
.lastAnnounceTimedOut
)
169 str
+= tr( "Peer list request %1timed out%2 %3 ago; will retry" )
170 .arg( timeout_markup_begin
)
171 .arg( timeout_markup_end
)
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
)
184 switch( inf
.st
.announceState
)
186 case TR_TRACKER_INACTIVE
:
188 str
+= tr( "No updates scheduled" );
191 case TR_TRACKER_WAITING
: {
192 const QString
tstr( timeToStringRounded( inf
.st
.nextAnnounceTime
- now
) );
194 str
+= tr( "Asking for more peers in %1" ).arg( tstr
);
198 case TR_TRACKER_QUEUED
:
200 str
+= tr( "Queued to ask for more peers" );
203 case TR_TRACKER_ACTIVE
: {
204 const QString
tstr( timeToStringRounded( now
- inf
.st
.lastAnnounceStartTime
) );
206 str
+= tr( "Asking for more peers now... <small>%1</small>" ).arg( tstr
);
213 if( inf
.st
.hasScraped
)
216 const QString
tstr( timeToStringRounded( now
- inf
.st
.lastScrapeTime
) );
217 if( inf
.st
.lastScrapeSucceeded
)
219 str
+= tr( "Tracker had %1%2 seeders%3 and %4%5 leechers%6 %7 ago" )
220 .arg( success_markup_begin
)
221 .arg( inf
.st
.seederCount
)
222 .arg( success_markup_end
)
223 .arg( success_markup_begin
)
224 .arg( inf
.st
.leecherCount
)
225 .arg( success_markup_end
)
230 str
+= tr( "Got a scrape error %1\"%2\"%3 %4 ago" )
231 .arg( err_markup_begin
)
232 .arg( inf
.st
.lastScrapeResult
)
233 .arg( err_markup_end
)
238 switch( inf
.st
.scrapeState
)
240 case TR_TRACKER_INACTIVE
:
243 case TR_TRACKER_WAITING
: {
245 const QString
tstr( timeToStringRounded( inf
.st
.nextScrapeTime
- now
) );
246 str
+= tr( "Asking for peer counts in %1" ).arg( tstr
);
250 case TR_TRACKER_QUEUED
: {
252 str
+= tr( "Queued to ask for peer counts" );
256 case TR_TRACKER_ACTIVE
: {
258 const QString
tstr( timeToStringRounded( now
- inf
.st
.lastScrapeStartTime
) );
259 str
+= tr( "Asking for peer counts now... <small>%1</small>" ).arg( tstr
);