(trunk qt) #3459 "Qt client's filterbar should be updated to match the GTK+ client's" -- fixed
This commit is contained in:
parent
f63d475d13
commit
e41281a997
|
@ -0,0 +1,539 @@
|
|||
/*
|
||||
* This file Copyright (C) 2010 Mnemosyne LLC
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <QString>
|
||||
#include <QtGui>
|
||||
|
||||
#include "app.h"
|
||||
#include "favicon.h"
|
||||
#include "filters.h"
|
||||
#include "filterbar.h"
|
||||
#include "prefs.h"
|
||||
#include "qticonloader.h"
|
||||
#include "torrent-filter.h"
|
||||
#include "torrent-model.h"
|
||||
#include "utils.h"
|
||||
|
||||
/****
|
||||
*****
|
||||
***** DELEGATE
|
||||
*****
|
||||
****/
|
||||
|
||||
enum
|
||||
{
|
||||
TorrentCountRole = Qt::UserRole + 1,
|
||||
ActivityRole,
|
||||
TrackerRole
|
||||
};
|
||||
|
||||
FilterBarComboBoxDelegate :: FilterBarComboBoxDelegate( QObject * parent, QComboBox * combo ):
|
||||
QItemDelegate( parent ),
|
||||
myCombo( combo )
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
FilterBarComboBoxDelegate :: isSeparator( const QModelIndex &index )
|
||||
{
|
||||
return index.data(Qt::AccessibleDescriptionRole).toString() == QLatin1String("separator");
|
||||
}
|
||||
void
|
||||
FilterBarComboBoxDelegate :: setSeparator( QAbstractItemModel * model, const QModelIndex& index )
|
||||
{
|
||||
model->setData( index, QString::fromLatin1("separator"), Qt::AccessibleDescriptionRole );
|
||||
|
||||
if( QStandardItemModel *m = qobject_cast<QStandardItemModel*>(model) )
|
||||
if (QStandardItem *item = m->itemFromIndex(index))
|
||||
item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
|
||||
}
|
||||
|
||||
void
|
||||
FilterBarComboBoxDelegate :: paint( QPainter * painter,
|
||||
const QStyleOptionViewItem & option,
|
||||
const QModelIndex & index ) const
|
||||
{
|
||||
if( isSeparator( index ) )
|
||||
{
|
||||
QRect rect = option.rect;
|
||||
if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3*>(&option))
|
||||
if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(v3->widget))
|
||||
rect.setWidth(view->viewport()->width());
|
||||
QStyleOption opt;
|
||||
opt.rect = rect;
|
||||
myCombo->style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, painter, myCombo);
|
||||
}
|
||||
else
|
||||
{
|
||||
QStyleOptionViewItem disabledOption = option;
|
||||
disabledOption.state &= ~( QStyle::State_Enabled | QStyle::State_Selected );
|
||||
QRect boundingBox = option.rect;
|
||||
|
||||
const int hmargin = myCombo->style()->pixelMetric( QStyle::PM_LayoutHorizontalSpacing, 0, myCombo );
|
||||
boundingBox.setLeft( boundingBox.left() + hmargin );
|
||||
boundingBox.setRight( boundingBox.right() - hmargin );
|
||||
|
||||
QRect decorationRect = rect( option, index, Qt::DecorationRole );
|
||||
decorationRect.moveLeft( decorationRect.left( ) );
|
||||
decorationRect.setSize( myCombo->iconSize( ) );
|
||||
decorationRect = QStyle::alignedRect( Qt::LeftToRight,
|
||||
Qt::AlignLeft|Qt::AlignVCenter,
|
||||
decorationRect.size(), boundingBox );
|
||||
boundingBox.setLeft( decorationRect.right() + hmargin );
|
||||
|
||||
QRect countRect = rect( option, index, TorrentCountRole );
|
||||
countRect = QStyle::alignedRect( Qt::LeftToRight,
|
||||
Qt::AlignRight|Qt::AlignVCenter,
|
||||
countRect.size(), boundingBox );
|
||||
boundingBox.setRight( countRect.left() - hmargin );
|
||||
const QRect displayRect = boundingBox;
|
||||
|
||||
drawBackground( painter, option, index );
|
||||
QStyleOptionViewItem option2 = option;
|
||||
option2.decorationSize = myCombo->iconSize( );
|
||||
drawDecoration( painter, option, decorationRect, decoration(option2,index.data(Qt::DecorationRole)) );
|
||||
drawDisplay( painter, option, displayRect, index.data(Qt::DisplayRole).toString() );
|
||||
drawDisplay( painter, disabledOption, countRect, index.data(TorrentCountRole).toString() );
|
||||
drawFocus( painter, option, displayRect|countRect );
|
||||
}
|
||||
}
|
||||
|
||||
QSize
|
||||
FilterBarComboBoxDelegate :: sizeHint( const QStyleOptionViewItem & option,
|
||||
const QModelIndex & index ) const
|
||||
{
|
||||
if( isSeparator( index ) )
|
||||
{
|
||||
const int pm = myCombo->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, myCombo);
|
||||
return QSize( pm, pm + 10 );
|
||||
}
|
||||
else
|
||||
{
|
||||
QStyle * s = myCombo->style( );
|
||||
const int hmargin = s->pixelMetric( QStyle::PM_LayoutHorizontalSpacing, 0, myCombo );
|
||||
|
||||
|
||||
QSize size = QItemDelegate::sizeHint( option, index );
|
||||
size.setHeight( qMax( size.height(), myCombo->iconSize().height() + 6 ) );
|
||||
size.rwidth() += s->pixelMetric( QStyle::PM_FocusFrameHMargin, 0, myCombo );
|
||||
size.rwidth() += rect(option,index,TorrentCountRole).width();
|
||||
size.rwidth() += hmargin * 4;
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
***
|
||||
**/
|
||||
|
||||
FilterBarComboBox :: FilterBarComboBox( QWidget * parent ):
|
||||
QComboBox( parent )
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
FilterBarComboBox :: paintEvent( QPaintEvent * e )
|
||||
{
|
||||
Q_UNUSED( e );
|
||||
|
||||
QStylePainter painter(this);
|
||||
painter.setPen(palette().color(QPalette::Text));
|
||||
|
||||
// draw the combobox frame, focusrect and selected etc.
|
||||
QStyleOptionComboBox opt;
|
||||
initStyleOption(&opt);
|
||||
painter.drawComplexControl(QStyle::CC_ComboBox, opt);
|
||||
|
||||
// draw the icon and text
|
||||
const QModelIndex modelIndex = model()->index( currentIndex(), 0, rootModelIndex() );
|
||||
if( modelIndex.isValid( ) )
|
||||
{
|
||||
QStyle * s = style();
|
||||
QRect rect = s->subControlRect( QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this );
|
||||
const int hmargin = s->pixelMetric( QStyle::PM_LayoutHorizontalSpacing, 0, this );
|
||||
rect.setRight( rect.right() - hmargin );
|
||||
|
||||
// draw the icon
|
||||
QPixmap pixmap;
|
||||
QVariant variant = modelIndex.data( Qt::DecorationRole );
|
||||
switch( variant.type( ) ) {
|
||||
case QVariant::Pixmap: pixmap = qvariant_cast<QPixmap>(variant); break;
|
||||
case QVariant::Icon: pixmap = qvariant_cast<QIcon>(variant).pixmap(iconSize()); break;
|
||||
default: break;
|
||||
}
|
||||
if( !pixmap.isNull() ) {
|
||||
s->drawItemPixmap( &painter, rect, Qt::AlignLeft|Qt::AlignVCenter, pixmap );
|
||||
rect.setLeft( rect.left() + pixmap.width() + hmargin );
|
||||
}
|
||||
|
||||
// draw the count
|
||||
const int count = modelIndex.data( TorrentCountRole ).toInt();
|
||||
if( count >= 0 ) {
|
||||
const QString text = QString::number( count);
|
||||
const QPen pen = painter.pen( );
|
||||
painter.setPen( opt.palette.color( QPalette::Disabled, QPalette::Text ) );
|
||||
QRect r = s->itemTextRect( painter.fontMetrics(), rect, Qt::AlignRight|Qt::AlignVCenter, false, text );
|
||||
painter.drawText( r, 0, text );
|
||||
rect.setRight( r.left() - hmargin );
|
||||
painter.setPen( pen );
|
||||
}
|
||||
|
||||
// draw the text
|
||||
QString text = modelIndex.data( Qt::DisplayRole ).toString();
|
||||
text = painter.fontMetrics().elidedText ( text, Qt::ElideRight, rect.width() );
|
||||
s->drawItemText( &painter, rect, Qt::AlignLeft|Qt::AlignVCenter, opt.palette, true, text );
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
*****
|
||||
***** ACTIVITY
|
||||
*****
|
||||
****/
|
||||
|
||||
QComboBox*
|
||||
FilterBar :: createActivityCombo( )
|
||||
{
|
||||
QComboBox * c = new FilterBarComboBox( this );
|
||||
FilterBarComboBoxDelegate * delegate = new FilterBarComboBoxDelegate( 0, c );
|
||||
c->setItemDelegate( delegate );
|
||||
|
||||
QPixmap blankPixmap( c->iconSize( ) );
|
||||
blankPixmap.fill( Qt::transparent );
|
||||
QIcon blankIcon( blankPixmap );
|
||||
|
||||
QStandardItemModel * model = new QStandardItemModel;
|
||||
|
||||
QStandardItem * row = new QStandardItem( tr( "All" ) );
|
||||
row->setData( FilterMode::SHOW_ALL, ActivityRole );
|
||||
model->appendRow( row );
|
||||
|
||||
model->appendRow( new QStandardItem ); // separator
|
||||
delegate->setSeparator( model, model->index( 1, 0 ) );
|
||||
|
||||
row = new QStandardItem( QtIconLoader::icon( "system-run" ), tr( "Active" ) );
|
||||
row->setData( FilterMode::SHOW_ACTIVE, ActivityRole );
|
||||
model->appendRow( row );
|
||||
|
||||
row = new QStandardItem( QtIconLoader::icon( "go-down" ), tr( "Downloading" ) );
|
||||
row->setData( FilterMode::SHOW_DOWNLOADING, ActivityRole );
|
||||
model->appendRow( row );
|
||||
|
||||
row = new QStandardItem( QtIconLoader::icon( "go-up" ), tr( "Seeding" ) );
|
||||
row->setData( FilterMode::SHOW_SEEDING, ActivityRole );
|
||||
model->appendRow( row );
|
||||
|
||||
row = new QStandardItem( QtIconLoader::icon( "media-playback-pause", blankIcon ), tr( "Paused" ) );
|
||||
row->setData( FilterMode::SHOW_PAUSED, ActivityRole );
|
||||
model->appendRow( row );
|
||||
|
||||
row = new QStandardItem( blankIcon, tr( "Queued" ) );
|
||||
row->setData( FilterMode::SHOW_QUEUED, ActivityRole );
|
||||
model->appendRow( row );
|
||||
|
||||
row = new QStandardItem( QtIconLoader::icon( "view-refresh", blankIcon ), tr( "Verifying" ) );
|
||||
row->setData( FilterMode::SHOW_VERIFYING, ActivityRole );
|
||||
model->appendRow( row );
|
||||
|
||||
row = new QStandardItem( QtIconLoader::icon( "dialog-error", blankIcon ), tr( "Error" ) );
|
||||
row->setData( FilterMode::SHOW_ERROR, ActivityRole );
|
||||
model->appendRow( row );
|
||||
|
||||
c->setModel( model );
|
||||
return c;
|
||||
}
|
||||
|
||||
/****
|
||||
*****
|
||||
*****
|
||||
*****
|
||||
****/
|
||||
|
||||
namespace
|
||||
{
|
||||
QString readableHostName( const QString host )
|
||||
{
|
||||
// get the readable name...
|
||||
QString name = host;
|
||||
const int pos = name.lastIndexOf( '.' );
|
||||
if( pos >= 0 )
|
||||
name.truncate( pos );
|
||||
if( !name.isEmpty( ) )
|
||||
name[0] = name[0].toUpper( );
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FilterBar :: refreshTrackers( )
|
||||
{
|
||||
Favicons& favicons = dynamic_cast<MyApp*>(QApplication::instance())->favicons;
|
||||
const int firstTrackerRow = 2; // skip over the "All" and separator...
|
||||
|
||||
// pull info from the tracker model...
|
||||
QSet<QString> oldHosts;
|
||||
for( int row=firstTrackerRow; ; ++row ) {
|
||||
QModelIndex index = myTrackerModel->index( row, 0 );
|
||||
if( !index.isValid( ) )
|
||||
break;
|
||||
oldHosts << index.data(TrackerRole).toString();
|
||||
}
|
||||
|
||||
// pull the new stats from the torrent model...
|
||||
QSet<QString> newHosts;
|
||||
QMap<QString,int> torrentsPerHost;
|
||||
for( int row=0; ; ++row )
|
||||
{
|
||||
QModelIndex index = myTorrents.index( row, 0 );
|
||||
if( !index.isValid( ) )
|
||||
break;
|
||||
const Torrent * tor = index.data( TorrentModel::TorrentRole ).value<const Torrent*>();
|
||||
const QStringList trackers = tor->trackers( );
|
||||
QSet<QString> torrentHosts;
|
||||
foreach( QString tracker, trackers )
|
||||
torrentHosts.insert( Favicons::getHost( QUrl( tracker ) ) );
|
||||
foreach( QString host, torrentHosts ) {
|
||||
newHosts.insert( host );
|
||||
++torrentsPerHost[host];
|
||||
}
|
||||
}
|
||||
|
||||
// update the "All" row
|
||||
myTrackerModel->setData( myTrackerModel->index(0,0), myTorrents.rowCount(), TorrentCountRole );
|
||||
|
||||
// rows to update
|
||||
foreach( QString host, oldHosts & newHosts )
|
||||
{
|
||||
const QString name = readableHostName( host );
|
||||
QStandardItem * row = myTrackerModel->findItems(name).front();
|
||||
row->setData( torrentsPerHost[host], TorrentCountRole );
|
||||
row->setData( favicons.findFromHost(host), Qt::DecorationRole );
|
||||
}
|
||||
|
||||
// rows to remove
|
||||
foreach( QString host, oldHosts - newHosts ) {
|
||||
const QString name = readableHostName( host );
|
||||
QStandardItem * item = myTrackerModel->findItems(name).front();
|
||||
if( !item->data(TrackerRole).toString().isEmpty() ) // don't remove "All"
|
||||
myTrackerModel->removeRows( item->row(), 1 );
|
||||
}
|
||||
|
||||
// rows to add
|
||||
bool anyAdded = false;
|
||||
foreach( QString host, newHosts - oldHosts )
|
||||
{
|
||||
const QString name = readableHostName( host );
|
||||
|
||||
// find the sorted position to add this row
|
||||
int i = firstTrackerRow;
|
||||
for( int n=myTrackerModel->rowCount(); i<n; ++i )
|
||||
if( myTrackerModel->index(i,0).data(Qt::DisplayRole).toString() > name )
|
||||
break;
|
||||
|
||||
// add the row
|
||||
QStandardItem * row = new QStandardItem( favicons.findFromHost( host ), readableHostName( host ) );
|
||||
row->setData( torrentsPerHost[host], TorrentCountRole );
|
||||
row->setData( favicons.findFromHost(host), Qt::DecorationRole );
|
||||
row->setData( host, TrackerRole );
|
||||
myTrackerModel->insertRow( i, row );
|
||||
anyAdded = true;
|
||||
}
|
||||
|
||||
if( anyAdded ) // the one added might match our filter...
|
||||
refreshPref( Prefs::FILTER_TRACKERS );
|
||||
}
|
||||
|
||||
|
||||
QComboBox*
|
||||
FilterBar :: createTrackerCombo( QStandardItemModel * model )
|
||||
{
|
||||
QComboBox * c = new FilterBarComboBox( this );
|
||||
FilterBarComboBoxDelegate * delegate = new FilterBarComboBoxDelegate( 0, c );
|
||||
c->setItemDelegate( delegate );
|
||||
|
||||
QStandardItem * row = new QStandardItem( tr( "All" ) );
|
||||
row->setData( "", TrackerRole );
|
||||
row->setData( myTorrents.rowCount(), TorrentCountRole );
|
||||
model->appendRow( row );
|
||||
|
||||
model->appendRow( new QStandardItem ); // separator
|
||||
delegate->setSeparator( model, model->index( 1, 0 ) );
|
||||
|
||||
c->setModel( model );
|
||||
return c;
|
||||
}
|
||||
|
||||
/****
|
||||
*****
|
||||
*****
|
||||
*****
|
||||
****/
|
||||
|
||||
FilterBar :: FilterBar( Prefs& prefs, TorrentModel& torrents, TorrentFilter& filter, QWidget * parent ):
|
||||
QWidget( parent ),
|
||||
myPrefs( prefs ),
|
||||
myTorrents( torrents ),
|
||||
myFilter( filter ),
|
||||
myRecountTimer( new QTimer( this ) ),
|
||||
myIsBootstrapping( true )
|
||||
{
|
||||
QHBoxLayout * h = new QHBoxLayout( this );
|
||||
int hmargin = style()->pixelMetric( QStyle::PM_LayoutHorizontalSpacing );
|
||||
|
||||
h->setSpacing( 0 );
|
||||
h->setContentsMargins( 2, 2, 2, 2 );
|
||||
h->addWidget( new QLabel( tr( "Show:" ), this ) );
|
||||
h->addSpacing( hmargin );
|
||||
|
||||
myActivityCombo = createActivityCombo( );
|
||||
h->addWidget( myActivityCombo, 1 );
|
||||
h->addSpacing( hmargin );
|
||||
|
||||
myTrackerModel = new QStandardItemModel;
|
||||
myTrackerCombo = createTrackerCombo( myTrackerModel );
|
||||
h->addWidget( myTrackerCombo, 1 );
|
||||
h->addSpacing( hmargin*2 );
|
||||
|
||||
myLineEdit = new QLineEdit( this );
|
||||
h->addWidget( myLineEdit );
|
||||
connect( myLineEdit, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString)));
|
||||
|
||||
QPushButton * p = new QPushButton;
|
||||
QIcon icon = QtIconLoader::icon( "edit-clear" );
|
||||
if( icon.isNull( ) )
|
||||
icon = style()->standardIcon( QStyle::SP_DialogCloseButton );
|
||||
int iconSize = style()->pixelMetric( QStyle::PM_SmallIconSize );
|
||||
p->setIconSize( QSize( iconSize, iconSize ) );
|
||||
p->setIcon( icon );
|
||||
p->setFlat( true );
|
||||
h->addWidget( p );
|
||||
connect( p, SIGNAL(clicked(bool)), myLineEdit, SLOT(clear()));
|
||||
|
||||
// listen for changes from the other players
|
||||
connect( &myPrefs, SIGNAL(changed(int)), this, SLOT(refreshPref(int)));
|
||||
connect( myActivityCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onActivityIndexChanged(int)));
|
||||
connect( myTrackerCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onTrackerIndexChanged(int)));
|
||||
connect( &myTorrents, SIGNAL(modelReset()), this, SLOT(onTorrentModelReset()));
|
||||
connect( &myTorrents, SIGNAL(rowsInserted(const QModelIndex&,int,int)), this, SLOT(onTorrentModelRowsInserted(const QModelIndex&,int,int)));
|
||||
connect( &myTorrents, SIGNAL(rowsRemoved(const QModelIndex&,int,int)), this, SLOT(onTorrentModelRowsRemoved(const QModelIndex&,int,int)));
|
||||
connect( &myTorrents, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&)), this, SLOT(onTorrentModelDataChanged(const QModelIndex&,const QModelIndex&)));
|
||||
connect( myRecountTimer, SIGNAL(timeout()), this, SLOT(recount()) );
|
||||
|
||||
recountSoon( );
|
||||
refreshTrackers( );
|
||||
myIsBootstrapping = false;
|
||||
|
||||
// initialize our state
|
||||
QList<int> initKeys;
|
||||
initKeys << Prefs :: FILTER_MODE
|
||||
<< Prefs :: FILTER_TRACKERS;
|
||||
foreach( int key, initKeys )
|
||||
refreshPref( key );
|
||||
}
|
||||
|
||||
FilterBar :: ~FilterBar( )
|
||||
{
|
||||
delete myRecountTimer;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
void
|
||||
FilterBar :: refreshPref( int key )
|
||||
{
|
||||
switch( key )
|
||||
{
|
||||
case Prefs :: FILTER_MODE: {
|
||||
const FilterMode m = myPrefs.get<FilterMode>( key );
|
||||
QAbstractItemModel * model = myActivityCombo->model( );
|
||||
QModelIndexList indices = model->match( model->index(0,0), ActivityRole, m.mode(), -1 );
|
||||
myActivityCombo->setCurrentIndex( indices.isEmpty() ? 0 : indices.first().row( ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case Prefs :: FILTER_TRACKERS: {
|
||||
const QString tracker = myPrefs.getString( key );
|
||||
QList<QStandardItem*> rows = myTrackerModel->findItems( tracker );
|
||||
if( !rows.isEmpty( ) )
|
||||
myTrackerCombo->setCurrentIndex( rows.first()->row() );
|
||||
else if( myTorrents.rowCount( ) > 0 ) // uh-oh... we don't have this tracker anymore. best use "show all" as a fallback
|
||||
myPrefs.set( key, "" );
|
||||
break;
|
||||
}
|
||||
|
||||
case Prefs :: FILTER_TEXT:
|
||||
myLineEdit->setText( myPrefs.getString( key ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FilterBar :: onTextChanged( const QString& str )
|
||||
{
|
||||
if( !myIsBootstrapping )
|
||||
myPrefs.set( Prefs::FILTER_TEXT, str.trimmed( ) );
|
||||
}
|
||||
|
||||
void
|
||||
FilterBar :: onTrackerIndexChanged( int i )
|
||||
{
|
||||
if( !myIsBootstrapping )
|
||||
myPrefs.set( Prefs::FILTER_TRACKERS, myTrackerCombo->itemData( i, Qt::DisplayRole ).toString( ) );
|
||||
}
|
||||
|
||||
void
|
||||
FilterBar :: onActivityIndexChanged( int i )
|
||||
{
|
||||
if( !myIsBootstrapping )
|
||||
{
|
||||
const FilterMode mode = myActivityCombo->itemData( i, ActivityRole ).toInt( );
|
||||
myPrefs.set( Prefs::FILTER_MODE, mode );
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
void FilterBar :: onTorrentModelReset( ) { recountSoon( ); }
|
||||
void FilterBar :: onTorrentModelRowsInserted( const QModelIndex&, int, int ) { recountSoon( ); }
|
||||
void FilterBar :: onTorrentModelRowsRemoved( const QModelIndex&, int, int ) { recountSoon( ); }
|
||||
void FilterBar :: onTorrentModelDataChanged( const QModelIndex&, const QModelIndex& ) { recountSoon( ); }
|
||||
|
||||
void
|
||||
FilterBar :: recountSoon( )
|
||||
{
|
||||
if( !myRecountTimer->isActive( ) )
|
||||
{
|
||||
myRecountTimer->setSingleShot( true );
|
||||
myRecountTimer->start( 500 );
|
||||
}
|
||||
}
|
||||
void
|
||||
FilterBar :: recount ( )
|
||||
{
|
||||
// recount the activity combobox...
|
||||
for( int i=0, n=FilterMode::NUM_MODES; i<n; ++i )
|
||||
{
|
||||
const FilterMode m( i );
|
||||
QAbstractItemModel * model = myActivityCombo->model( );
|
||||
QModelIndexList indices = model->match( model->index(0,0), ActivityRole, m.mode(), -1 );
|
||||
if( !indices.isEmpty( ) ) {
|
||||
const int count = myFilter.count( m );
|
||||
model->setData( indices.first(), count, TorrentCountRole );
|
||||
}
|
||||
}
|
||||
|
||||
refreshTrackers( );
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* This file Copyright (C) 2010 Mnemosyne LLC
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef QTR_FILTERBAR_H
|
||||
#define QTR_FILTERBAR_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QItemDelegate>
|
||||
#include <QWidget>
|
||||
|
||||
class QLineEdit;
|
||||
class QPaintEvent;
|
||||
class QStandardItemModel;
|
||||
class QTimer;
|
||||
|
||||
class Prefs;
|
||||
class TorrentFilter;
|
||||
class TorrentModel;
|
||||
|
||||
class FilterBarComboBoxDelegate: public QItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FilterBarComboBoxDelegate( QObject * parent, QComboBox * combo );
|
||||
|
||||
public:
|
||||
static bool isSeparator( const QModelIndex &index );
|
||||
static void setSeparator( QAbstractItemModel * model, const QModelIndex& index );
|
||||
|
||||
protected:
|
||||
virtual void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const;
|
||||
virtual QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const;
|
||||
|
||||
private:
|
||||
QComboBox * myCombo;
|
||||
|
||||
};
|
||||
|
||||
class FilterBarComboBox: public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FilterBarComboBox( QWidget * parent = 0 );
|
||||
|
||||
protected:
|
||||
virtual void paintEvent( QPaintEvent * e );
|
||||
};
|
||||
|
||||
|
||||
class FilterBar: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FilterBar( Prefs& prefs, TorrentModel& torrents, TorrentFilter& filter, QWidget * parent = 0 );
|
||||
~FilterBar( );
|
||||
|
||||
private:
|
||||
QComboBox * createTrackerCombo( QStandardItemModel * );
|
||||
QComboBox * createActivityCombo( );
|
||||
void recountSoon( );
|
||||
void refreshTrackers( );
|
||||
|
||||
private:
|
||||
Prefs& myPrefs;
|
||||
TorrentModel& myTorrents;
|
||||
TorrentFilter& myFilter;
|
||||
QComboBox * myActivityCombo;
|
||||
QComboBox * myTrackerCombo;
|
||||
QStandardItemModel * myTrackerModel;
|
||||
QTimer * myRecountTimer;
|
||||
bool myIsBootstrapping;
|
||||
QLineEdit * myLineEdit;
|
||||
|
||||
private slots:
|
||||
void recount( );
|
||||
void refreshPref( int key );
|
||||
void onActivityIndexChanged( int index );
|
||||
void onTrackerIndexChanged( int index );
|
||||
void onTorrentModelReset( );
|
||||
void onTorrentModelRowsInserted( const QModelIndex&, int, int );
|
||||
void onTorrentModelRowsRemoved( const QModelIndex&, int, int );
|
||||
void onTorrentModelDataChanged( const QModelIndex&, const QModelIndex& );
|
||||
void onTextChanged( const QString& );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -12,12 +12,16 @@
|
|||
|
||||
#include "filters.h"
|
||||
|
||||
const QString FilterMode::names[NUM_MODES] = {
|
||||
const QString FilterMode::names[NUM_MODES] =
|
||||
{
|
||||
"show-all",
|
||||
"show-active",
|
||||
"show-downloading",
|
||||
"show-seeding",
|
||||
"show-paused"
|
||||
"show-paused",
|
||||
"show-queued",
|
||||
"show-verifying",
|
||||
"show-error",
|
||||
};
|
||||
|
||||
int
|
||||
|
|
|
@ -25,7 +25,8 @@ class FilterMode
|
|||
FilterMode( int mode=SHOW_ALL ): myMode(mode) { }
|
||||
FilterMode( const QString& name ): myMode(modeFromName(name)) { }
|
||||
static const QString names[];
|
||||
enum { SHOW_ALL, SHOW_ACTIVE, SHOW_DOWNLOADING, SHOW_SEEDING, SHOW_PAUSED, NUM_MODES };
|
||||
enum { SHOW_ALL, SHOW_ACTIVE, SHOW_DOWNLOADING, SHOW_SEEDING, SHOW_PAUSED,
|
||||
SHOW_QUEUED, SHOW_VERIFYING, SHOW_ERROR, NUM_MODES };
|
||||
static int modeFromName( const QString& name );
|
||||
static const QString& nameFromMode( int mode ) { return names[mode]; }
|
||||
int mode() const { return myMode; }
|
||||
|
|
110
qt/mainwin.cc
110
qt/mainwin.cc
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "about.h"
|
||||
#include "details.h"
|
||||
#include "filterbar.h"
|
||||
#include "filters.h"
|
||||
#include "formatter.h"
|
||||
#include "hig.h"
|
||||
|
@ -246,14 +247,13 @@ TrMainWindow :: TrMainWindow( Session& session, Prefs& prefs, TorrentModel& mode
|
|||
ui.action_TrayIcon->setChecked( minimized || prefs.getBool( Prefs::SHOW_TRAY_ICON ) );
|
||||
|
||||
ui.verticalLayout->addWidget( createStatusBar( ) );
|
||||
ui.verticalLayout->insertWidget( 0, createFilterBar( ) );
|
||||
ui.verticalLayout->insertWidget( 0, myFilterBar = new FilterBar( myPrefs, myModel, myFilterModel ) );
|
||||
|
||||
QList<int> initKeys;
|
||||
initKeys << Prefs :: MAIN_WINDOW_X
|
||||
<< Prefs :: SHOW_TRAY_ICON
|
||||
<< Prefs :: SORT_REVERSED
|
||||
<< Prefs :: SORT_MODE
|
||||
<< Prefs :: FILTER_MODE
|
||||
<< Prefs :: FILTERBAR
|
||||
<< Prefs :: STATUSBAR
|
||||
<< Prefs :: STATUSBAR_STATS
|
||||
|
@ -352,88 +352,6 @@ TrMainWindow :: onSetPrefs( bool isChecked )
|
|||
|
||||
#define SHOW_KEY "show-mode"
|
||||
|
||||
void
|
||||
TrMainWindow :: onShowModeClicked( )
|
||||
{
|
||||
setShowMode( sender()->property(SHOW_KEY).toInt() );
|
||||
}
|
||||
|
||||
QWidget *
|
||||
TrMainWindow :: createFilterBar( )
|
||||
{
|
||||
int i;
|
||||
QMenu * m;
|
||||
QLineEdit * e;
|
||||
QPushButton * p;
|
||||
QHBoxLayout * h;
|
||||
QActionGroup * a;
|
||||
const int smallSize = style( )->pixelMetric( QStyle::PM_SmallIconSize, 0, this );
|
||||
const QSize smallIconSize( smallSize, smallSize );
|
||||
|
||||
QWidget * top = myFilterBar = new QWidget;
|
||||
h = new QHBoxLayout( top );
|
||||
h->setContentsMargins( HIG::PAD_SMALL, HIG::PAD_SMALL, HIG::PAD_SMALL, HIG::PAD_SMALL );
|
||||
h->setSpacing( HIG::PAD_SMALL );
|
||||
#ifdef Q_OS_MAC
|
||||
top->setStyleSheet( "QPushButton{ "
|
||||
" border-radius: 10px; "
|
||||
" padding: 0 5px; "
|
||||
" border: 1px none; "
|
||||
"} "
|
||||
"QPushButton:pressed, QPushButton:checked{ "
|
||||
" border-width: 1px; "
|
||||
" border-style: solid; "
|
||||
" border-color: #5f5f5f #979797 #979797; "
|
||||
" background-color: #979797; "
|
||||
" color: white; "
|
||||
"} ");
|
||||
#endif
|
||||
|
||||
QList<QString> titles;
|
||||
titles << tr( "A&ll" ) << tr( "&Active" ) << tr( "&Downloading" ) << tr( "&Seeding" ) << tr( "&Paused" );
|
||||
for( i=0; i<titles.size(); ++i ) {
|
||||
p = myFilterButtons[i] = new QPushButton( titles[i] );
|
||||
p->setProperty( SHOW_KEY, i );
|
||||
p->setFlat( true );
|
||||
p->setCheckable( true );
|
||||
p->setMaximumSize( calculateTextButtonSizeHint( p ) );
|
||||
connect( p, SIGNAL(clicked()), this, SLOT(onShowModeClicked()));
|
||||
h->addWidget( p );
|
||||
}
|
||||
|
||||
h->addStretch( 1 );
|
||||
|
||||
a = new QActionGroup( this );
|
||||
a->addAction( ui.action_FilterByName );
|
||||
a->addAction( ui.action_FilterByFiles );
|
||||
a->addAction( ui.action_FilterByTracker );
|
||||
m = new QMenu( );
|
||||
m->addAction( ui.action_FilterByName );
|
||||
m->addAction( ui.action_FilterByFiles );
|
||||
m->addAction( ui.action_FilterByTracker );
|
||||
connect( ui.action_FilterByName, SIGNAL(triggered()), this, SLOT(filterByName()));
|
||||
connect( ui.action_FilterByFiles, SIGNAL(triggered()), this, SLOT(filterByFiles()));
|
||||
connect( ui.action_FilterByTracker, SIGNAL(triggered()), this, SLOT(filterByTracker()));
|
||||
ui.action_FilterByName->setChecked( true );
|
||||
p = myFilterTextButton = new TrIconPushButton;
|
||||
p->setIcon( getStockIcon( "edit-find", QStyle::SP_ArrowForward ) );
|
||||
p->setFlat( true );
|
||||
p->setMenu( m );
|
||||
h->addWidget( p );
|
||||
|
||||
e = myFilterTextLineEdit = new QLineEdit;
|
||||
connect( e, SIGNAL(textChanged(QString)), &myFilterModel, SLOT(setText(QString)));
|
||||
h->addWidget( e );
|
||||
|
||||
p = myFilterTextButton = new TrIconPushButton;
|
||||
p->setIcon( getStockIcon( "edit-clear", QStyle::SP_DialogCloseButton ) );
|
||||
p->setFlat( true );
|
||||
connect( p, SIGNAL(clicked()), myFilterTextLineEdit, SLOT(clear()));
|
||||
h->addWidget( p );
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
QWidget *
|
||||
TrMainWindow :: createStatusBar( )
|
||||
{
|
||||
|
@ -835,7 +753,7 @@ TrMainWindow :: getSelectedTorrents( ) const
|
|||
|
||||
foreach( QModelIndex index, ui.listView->selectionModel( )->selectedRows( ) )
|
||||
{
|
||||
const Torrent * tor( index.model()->data( index, TorrentModel::TorrentRole ).value<const Torrent*>( ) );
|
||||
const Torrent * tor( index.data( TorrentModel::TorrentRole ).value<const Torrent*>( ) );
|
||||
ids.insert( tor->id( ) );
|
||||
}
|
||||
|
||||
|
@ -887,17 +805,6 @@ TrMainWindow :: reannounceSelected( )
|
|||
***
|
||||
**/
|
||||
|
||||
void TrMainWindow :: setShowMode ( int i ) { myPrefs.set( Prefs::FILTER_MODE, FilterMode( i ) ); }
|
||||
void TrMainWindow :: showAll ( ) { setShowMode( FilterMode :: SHOW_ALL ); }
|
||||
void TrMainWindow :: showActive ( ) { setShowMode( FilterMode :: SHOW_ACTIVE ); }
|
||||
void TrMainWindow :: showDownloading ( ) { setShowMode( FilterMode :: SHOW_DOWNLOADING ); }
|
||||
void TrMainWindow :: showSeeding ( ) { setShowMode( FilterMode :: SHOW_SEEDING ); }
|
||||
void TrMainWindow :: showPaused ( ) { setShowMode( FilterMode :: SHOW_PAUSED ); }
|
||||
|
||||
void TrMainWindow :: filterByName ( ) { myFilterModel.setTextMode( TorrentFilter :: FILTER_BY_NAME ); }
|
||||
void TrMainWindow :: filterByTracker ( ) { myFilterModel.setTextMode( TorrentFilter :: FILTER_BY_TRACKER ); }
|
||||
void TrMainWindow :: filterByFiles ( ) { myFilterModel.setTextMode( TorrentFilter :: FILTER_BY_FILES ); }
|
||||
|
||||
void TrMainWindow :: showTotalRatio ( ) { myPrefs.set( Prefs::STATUSBAR_STATS, "total-ratio"); }
|
||||
void TrMainWindow :: showTotalTransfer ( ) { myPrefs.set( Prefs::STATUSBAR_STATS, "total-transfer"); }
|
||||
void TrMainWindow :: showSessionRatio ( ) { myPrefs.set( Prefs::STATUSBAR_STATS, "session-ratio"); }
|
||||
|
@ -953,8 +860,9 @@ TrMainWindow :: toggleWindows( bool doShow )
|
|||
{
|
||||
if ( !isVisible( ) ) show( );
|
||||
if ( isMinimized( ) ) showNormal( );
|
||||
activateWindow( );
|
||||
//activateWindow( );
|
||||
raise( );
|
||||
QApplication::setActiveWindow( this );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1030,12 +938,6 @@ TrMainWindow :: refreshPref( int key )
|
|||
myRatioOnAction->setText( tr( "Stop at Ratio (%1)" ).arg( Formatter::ratioToString( myPrefs.get<double>(key) ) ) );
|
||||
break;
|
||||
|
||||
case Prefs::FILTER_MODE:
|
||||
i = myPrefs.get<FilterMode>(key).mode( );
|
||||
for( int j=0; j<FilterMode::NUM_MODES; ++j )
|
||||
myFilterButtons[j]->setChecked( i==j );
|
||||
break;
|
||||
|
||||
case Prefs::FILTERBAR:
|
||||
b = myPrefs.getBool( key );
|
||||
myFilterBar->setVisible( b );
|
||||
|
@ -1183,7 +1085,7 @@ TrMainWindow :: removeTorrents( const bool deleteFiles )
|
|||
|
||||
foreach( QModelIndex index, ui.listView->selectionModel( )->selectedRows( ) )
|
||||
{
|
||||
const Torrent * tor( index.model()->data( index, TorrentModel::TorrentRole ).value<const Torrent*>( ) );
|
||||
const Torrent * tor( index.data( TorrentModel::TorrentRole ).value<const Torrent*>( ) );
|
||||
ids.insert( tor->id( ) );
|
||||
if( tor->connectedPeers( ) )
|
||||
++connected;
|
||||
|
|
15
qt/mainwin.h
15
qt/mainwin.h
|
@ -45,6 +45,7 @@ class QLabel;
|
|||
class QMenu;
|
||||
class QModelIndex;
|
||||
class QSortFilterProxyModel;
|
||||
class Filterbar;
|
||||
|
||||
class TrMainWindow: public QMainWindow
|
||||
{
|
||||
|
@ -85,7 +86,6 @@ class TrMainWindow: public QMainWindow
|
|||
QIcon getStockIcon( const QString&, int fallback=-1 );
|
||||
|
||||
private:
|
||||
void setShowMode( int );
|
||||
QSet<int> getSelectedTorrents( ) const;
|
||||
void updateNetworkIcon( );
|
||||
QWidgetList myHidden;
|
||||
|
@ -97,15 +97,6 @@ class TrMainWindow: public QMainWindow
|
|||
void onPrefsDestroyed( );
|
||||
void openPreferences( );
|
||||
void onDetailsDestroyed( );
|
||||
void onShowModeClicked( );
|
||||
void showAll( );
|
||||
void showActive( );
|
||||
void showDownloading( );
|
||||
void showSeeding( );
|
||||
void showPaused( );
|
||||
void filterByName( );
|
||||
void filterByFiles( );
|
||||
void filterByTracker( );
|
||||
void showTotalRatio( );
|
||||
void showTotalTransfer( );
|
||||
void showSessionRatio( );
|
||||
|
@ -148,11 +139,7 @@ class TrMainWindow: public QMainWindow
|
|||
void onSortByTrackerToggled ( bool );
|
||||
|
||||
private:
|
||||
QWidget * createFilterBar( void );
|
||||
QWidget * myFilterBar;
|
||||
QPushButton * myFilterButtons[FilterMode::NUM_MODES];
|
||||
QPushButton * myFilterTextButton;
|
||||
QLineEdit * myFilterTextLineEdit;
|
||||
|
||||
private:
|
||||
QMenu * createOptionsMenu( void );
|
||||
|
|
16
qt/prefs.cc
16
qt/prefs.cc
|
@ -56,6 +56,8 @@ Prefs::PrefItem Prefs::myItems[] =
|
|||
{ MAIN_WINDOW_X, "main-window-x", QVariant::Int },
|
||||
{ MAIN_WINDOW_Y, "main-window-y", QVariant::Int },
|
||||
{ FILTER_MODE, "filter-mode", TrTypes::FilterModeType },
|
||||
{ FILTER_TRACKERS, "filter-trackers", QVariant::String },
|
||||
{ FILTER_TEXT, "filter-text", QVariant::String },
|
||||
{ SESSION_IS_REMOTE, "remote-session-enabled", QVariant::Bool },
|
||||
{ SESSION_REMOTE_HOST, "remote-session-host", QVariant::String },
|
||||
{ SESSION_REMOTE_PORT, "remote-session-port", QVariant::Int },
|
||||
|
@ -133,6 +135,10 @@ Prefs :: Prefs( const char * configDir ):
|
|||
for( int i=0; i<PREFS_COUNT; ++i )
|
||||
assert( myItems[i].id == i );
|
||||
|
||||
// these are the prefs that don't get saved to settings.json
|
||||
// when the application exits.
|
||||
myTemporaryPrefs << FILTER_TEXT;
|
||||
|
||||
tr_benc top;
|
||||
tr_bencInitDict( &top, 0 );
|
||||
initDefaults( &top );
|
||||
|
@ -197,10 +203,16 @@ Prefs :: ~Prefs( )
|
|||
tr_bencInitDict( &top, PREFS_COUNT );
|
||||
|
||||
/* merge our own settings with the ones already in the file */
|
||||
for( int i=0; i<PREFS_COUNT; ++i ) {
|
||||
for( int i=0; i<PREFS_COUNT; ++i )
|
||||
{
|
||||
if( myTemporaryPrefs.contains( i ) )
|
||||
continue;
|
||||
|
||||
const char * key = myItems[i].key;
|
||||
const QVariant& val = myValues[i];
|
||||
switch( myItems[i].type ) {
|
||||
|
||||
switch( myItems[i].type )
|
||||
{
|
||||
case QVariant::Int:
|
||||
tr_bencDictAddInt( &top, key, val.toInt() );
|
||||
break;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
|
@ -59,6 +60,8 @@ class Prefs: public QObject
|
|||
MAIN_WINDOW_X,
|
||||
MAIN_WINDOW_Y,
|
||||
FILTER_MODE,
|
||||
FILTER_TRACKERS,
|
||||
FILTER_TEXT,
|
||||
SESSION_IS_REMOTE,
|
||||
SESSION_REMOTE_HOST,
|
||||
SESSION_REMOTE_PORT,
|
||||
|
@ -140,6 +143,7 @@ class Prefs: public QObject
|
|||
static PrefItem myItems[];
|
||||
|
||||
private:
|
||||
QSet<int> myTemporaryPrefs;
|
||||
QString myConfigDir;
|
||||
QVariant myValues[PREFS_COUNT];
|
||||
void initDefaults( struct tr_benc* );
|
||||
|
|
|
@ -31,7 +31,7 @@ TRANSLATIONS += transmission_en.ts transmission_ru.ts
|
|||
FORMS += mainwin.ui
|
||||
RESOURCES += application.qrc
|
||||
SOURCES += about.cc app.cc dbus-adaptor.cc details.cc favicon.cc file-tree.cc \
|
||||
filters.cc formatter.cc hig.cc license.cc mainwin.cc \
|
||||
filterbar.cc filters.cc formatter.cc hig.cc license.cc mainwin.cc \
|
||||
make-dialog.cc options.cc prefs.cc prefs-dialog.cc qticonloader.cc \
|
||||
relocate.cc session.cc session-dialog.cc squeezelabel.cc \
|
||||
stats-dialog.cc torrent.cc torrent-delegate.cc \
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
#include <QMetaType>
|
||||
#include <QVariant>
|
||||
|
||||
class QString;
|
||||
class QWidget;
|
||||
|
||||
struct Prefs;
|
||||
struct QString;
|
||||
class FilterMode;
|
||||
class Prefs;
|
||||
class Torrent;
|
||||
|
||||
class TorrentFilter: public QSortFilterProxyModel
|
||||
{
|
||||
|
@ -31,13 +34,8 @@ class TorrentFilter: public QSortFilterProxyModel
|
|||
|
||||
public:
|
||||
enum TextMode { FILTER_BY_NAME, FILTER_BY_FILES, FILTER_BY_TRACKER };
|
||||
TextMode getTextMode( ) const { return myTextMode; }
|
||||
int hiddenRowCount( ) const;
|
||||
|
||||
public slots:
|
||||
void setTextMode( int textMode );
|
||||
void setText( QString );
|
||||
|
||||
private slots:
|
||||
void refreshPref( int key );
|
||||
|
||||
|
@ -45,10 +43,15 @@ class TorrentFilter: public QSortFilterProxyModel
|
|||
virtual bool filterAcceptsRow( int, const QModelIndex& ) const;
|
||||
virtual bool lessThan( const QModelIndex&, const QModelIndex& ) const;
|
||||
|
||||
private:
|
||||
bool activityFilterAcceptsTorrent( const Torrent * tor, const FilterMode& mode ) const;
|
||||
bool trackerFilterAcceptsTorrent( const Torrent * tor, const QString& tracker ) const;
|
||||
|
||||
public:
|
||||
int count( const FilterMode& ) const;
|
||||
|
||||
private:
|
||||
Prefs& myPrefs;
|
||||
TextMode myTextMode;
|
||||
QString myText;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -119,7 +119,7 @@ TorrentModel :: onTorrentChanged( int torrentId )
|
|||
const int row( myIdToRow.value( torrentId, -1 ) );
|
||||
if( row >= 0 ) {
|
||||
QModelIndex qmi( index( row, 0 ) );
|
||||
dataChanged( qmi, qmi );
|
||||
emit dataChanged( qmi, qmi );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -299,6 +299,7 @@ class Torrent: public QObject
|
|||
int seedIdleLimit( ) const { return getInt( SEED_IDLE_LIMIT ); }
|
||||
tr_idlelimit seedIdleMode( ) const { return (tr_idlelimit) getInt( SEED_IDLE_MODE ); }
|
||||
TrackerStatsList trackerStats( ) const{ return myValues[TRACKERSTATS].value<TrackerStatsList>(); }
|
||||
QStringList trackers() const { return myValues[TRACKERS].value<QStringList>(); }
|
||||
PeerList peers( ) const{ return myValues[PEERS].value<PeerList>(); }
|
||||
const FileList& files( ) const { return myFiles; }
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ QSize
|
|||
TrackerDelegate :: sizeHint( const QStyleOptionViewItem & option,
|
||||
const QModelIndex & index ) const
|
||||
{
|
||||
const TrackerInfo trackerInfo = index.model()->data( index, TrackerModel::TrackerRole ).value<TrackerInfo>();
|
||||
const TrackerInfo trackerInfo = index.data( TrackerModel::TrackerRole ).value<TrackerInfo>();
|
||||
return sizeHint( option, trackerInfo );
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ TrackerDelegate :: paint( QPainter * painter,
|
|||
const QStyleOptionViewItem & option,
|
||||
const QModelIndex & index) const
|
||||
{
|
||||
const TrackerInfo trackerInfo = index.model()->data( index, TrackerModel::TrackerRole ).value<TrackerInfo>();
|
||||
const TrackerInfo trackerInfo = index.data( TrackerModel::TrackerRole ).value<TrackerInfo>();
|
||||
painter->save( );
|
||||
painter->setClipRect( option.rect );
|
||||
drawBackground( painter, option, index );
|
||||
|
|
Loading…
Reference in New Issue