예제 #1
0
void
GridItemDelegate::onPlayClicked( const QPersistentModelIndex& index )
{
    QPoint pos = m_playButton[ index ]->pos();
    clearButtons();

    AnimatedSpinner* spinner = new AnimatedSpinner( m_view );
    spinner->setAutoCenter( false );
    spinner->fadeIn();
    spinner->move( pos );
    spinner->setFocusPolicy( Qt::NoFocus );
    spinner->installEventFilter( this );

    m_spinner[ index ] = spinner;

    PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );

    NewClosure(  AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ),
                const_cast<GridItemDelegate*>(this), SLOT( onPlaybackStarted( QPersistentModelIndex ) ), QPersistentModelIndex( index ) );

    if ( item )
    {
        if ( !item->query().isNull() )
            AudioEngine::instance()->playItem( m_model->playlistInterface(), item->query() );
        else if ( !item->album().isNull() )
            AudioEngine::instance()->playItem( item->album() );
        else if ( !item->artist().isNull() )
            AudioEngine::instance()->playItem( item->artist() );
    }
}
예제 #2
0
void
TreeView::mousePressEvent( QMouseEvent* event )
{
    QTreeView::mousePressEvent( event );

    if ( !m_model || m_proxyModel->style() != PlayableProxyModel::Collection )
        return;

    QModelIndex idx = indexAt( event->pos() );
    if ( event->pos().x() > header()->sectionViewportPosition( idx.column() ) + header()->sectionSize( idx.column() ) - 16 &&
         event->pos().x() < header()->sectionViewportPosition( idx.column() ) + header()->sectionSize( idx.column() ) )
    {
        PlayableItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( idx ) );
        if ( item->query().isNull() )
            return;

        switch ( idx.column() )
        {
            case 0:
            {
                ViewManager::instance()->show( item->query()->displayQuery() );
                break;
            }

            default:
                break;
        }
    }
}
예제 #3
0
bool
PlayableProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const
{
    PlayableItem* pi = itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) );
    if ( !pi )
        return false;

    if ( m_maxVisibleItems >= 0 && sourceRow > m_maxVisibleItems - 1 )
        return false;

    if ( m_hideDupeItems )
    {
        for ( int i = 0; i < sourceRow; i++ )
        {
            PlayableItem* di = itemFromIndex( sourceModel()->index( i, 0, sourceParent ) );
            if ( !di )
                continue;

            bool b = ( pi->query() && pi->query()->equals( di->query() ) ) ||
                     ( pi->album() && pi->album() == di->album() ) ||
                     ( pi->artist() && pi->artist()->name() == di->artist()->name() );

            if ( b && filterAcceptsRow( i, sourceParent ) )
                return false;
        }
    }

    if ( pi->query() )
    {
        const Tomahawk::query_ptr& q = pi->query()->displayQuery();
        if ( q.isNull() ) // uh oh? filter out invalid queries i guess
            return false;

        Tomahawk::result_ptr r;
        if ( q->numResults() )
            r = q->results().first();

        if ( !m_showOfflineResults && ( r.isNull() || !r->isOnline() ) )
            return false;

        if ( filterRegExp().isEmpty() )
            return true;

        QStringList sl = filterRegExp().pattern().split( " ", QString::SkipEmptyParts );
        foreach( QString s, sl )
        {
            s = s.toLower();
            if ( !q->artist().toLower().contains( s ) &&
                    !q->album().toLower().contains( s ) &&
                    !q->track().toLower().contains( s ) )
            {
                return false;
            }
        }
    }
Tomahawk::query_ptr
PlayableProxyModelPlaylistInterface::queryAt( qint64 index ) const
{
    if ( m_proxyModel.isNull() )
        return query_ptr();

    PlayableItem* item = reinterpret_cast<PlayableItem*>( (void*)index );
    if ( item && item->query() )
        return item->query();

    return query_ptr();
}
Tomahawk::result_ptr
PlayableProxyModelPlaylistInterface::currentItem() const
{
    if ( m_proxyModel.isNull() )
        return Tomahawk::result_ptr();

    PlayableProxyModel* proxyModel = m_proxyModel.data();

    PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->currentIndex() ) );
    if ( item && !item->query().isNull() && item->query()->playable() )
        return item->query()->results().at( 0 );
    return Tomahawk::result_ptr();
}
예제 #6
0
void
TrackView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
{
    QTreeView::currentChanged( current, previous );

    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) );
    if ( item && item->query() )
    {
        emit querySelected( item->query() );
    }
    else
    {
        emit querySelected( query_ptr() );
    }
}
예제 #7
0
void
TrackView::startAutoPlay( const QModelIndex& index )
{
    if ( tryToPlayItem( index ) )
        return;

    // item isn't playable but still resolving
    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
    if ( item && !item->query().isNull() && !item->query()->resolvingFinished() )
    {
        m_autoPlaying = item->query(); // So we can kill it if user starts autoplaying this playlist again
        NewClosure( item->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( autoPlayResolveFinished( Tomahawk::query_ptr, int ) ),
                    item->query(), index.row() );
        return;
    }
예제 #8
0
QSize
TreeItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    QSize size = QStyledItemDelegate::sizeHint( option, index );

    if ( index.isValid() )
    {
        PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
        if ( item )
        {
            if ( item->album() )
            {
                size.setHeight( option.fontMetrics.height() * 3 );
                return size;
            }
            else if ( item->query() || item->result() )
            {
                size.setHeight( option.fontMetrics.height() * 1.6 );
                return size;
            }
        }
    }
    
    // artist per default
    size.setHeight( option.fontMetrics.height() * 4 );
    return size;
}
예제 #9
0
void
QueueProxyModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
{
    for ( int i = 0; i < rowCount(); i++ )
    {
        QModelIndex idx = index( i, 0 );
        PlayableItem* item = itemFromIndex( mapToSource( idx ) );
        if ( item && item->query() && ( item->query()->results().contains( result ) ||
                                        item->query()->track()->equals( result->track() ) ) )
        {
            removeIndex( idx );
            if ( !rowCount() )
                ViewManager::instance()->hideQueue();
        }
    }
}
예제 #10
0
void
TreeView::updateHoverIndex( const QPoint& pos )
{
    QModelIndex idx = indexAt( pos );

    if ( idx != m_hoveredIndex )
    {
        m_hoveredIndex = idx;
        repaint();
    }

    if ( !m_model || m_proxyModel->style() != PlayableProxyModel::Collection )
        return;

    PlayableItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( idx ) );
    if ( idx.column() == 0 && !item->query().isNull() )
    {
        if ( pos.x() > header()->sectionViewportPosition( idx.column() ) + header()->sectionSize( idx.column() ) - 16 &&
             pos.x() < header()->sectionViewportPosition( idx.column() ) + header()->sectionSize( idx.column() ) )
        {
            setCursor( Qt::PointingHandCursor );
            return;
        }
    }

    if ( cursor().shape() != Qt::ArrowCursor )
        setCursor( Qt::ArrowCursor );
}
예제 #11
0
void
ColumnView::onCustomContextMenu( const QPoint& pos )
{
    m_contextMenu->clear();

    QModelIndex idx = indexAt( pos );
    idx = idx.sibling( idx.row(), 0 );
    m_contextMenuIndex = idx;

    if ( !idx.isValid() )
        return;

    QList<query_ptr> queries;
    QList<artist_ptr> artists;
    QList<album_ptr> albums;

    QModelIndexList indexes = selectedIndexes();
    if ( !indexes.contains( idx ) )
    {
        indexes.clear();
        indexes << idx;
    }

    foreach ( const QModelIndex& index, indexes )
    {
        if ( index.column() || indexes.contains( index.parent() ) )
            continue;

        PlayableItem* item = m_proxyModel->itemFromIndex( m_proxyModel->mapToSource( index ) );

        if ( item && !item->result().isNull() )
            queries << item->result()->toQuery();
        else if ( item && !item->query().isNull() )
            queries << item->query();
        if ( item && !item->artist().isNull() )
            artists << item->artist();
        if ( item && !item->album().isNull() )
            albums << item->album();
    }

    m_contextMenu->setQueries( queries );
    m_contextMenu->setArtists( artists );
    m_contextMenu->setAlbums( albums );
    m_contextMenu->setPlaylistInterface( proxyModel()->playlistInterface() );

    m_contextMenu->exec( viewport()->mapToGlobal( pos ) );
}
예제 #12
0
void
ContextView::onDownloadAll()
{
    for ( int i = 0; i < m_trackView->proxyModel()->rowCount( QModelIndex() ); i++ )
    {
        PlayableItem* item = m_trackView->proxyModel()->itemFromIndex( m_trackView->proxyModel()->mapToSource( m_trackView->proxyModel()->index( i, 0, QModelIndex() ) ) );
        if ( !item || !item->query() || !item->query()->results().count() )
            continue;
        if ( !item->query()->results().first()->downloadFormats().count() )
            continue;

        if ( !DownloadManager::instance()->localFileForDownload( item->query()->results().first()->downloadFormats().first().url.toString() ).isEmpty() )
            continue;
        if ( !item->result()->downloadFormats().isEmpty() )
            DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().first() ) );
    }
}
예제 #13
0
void
GridView::onItemActivated( const QModelIndex& index )
{
    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
    if ( item )
    {
//        qDebug() << "Result activated:" << item->album()->tracks().first()->toString() << item->album()->tracks().first()->results().first()->url();
//        APP->audioEngine()->playItem( item->album().data(), item->album()->tracks().first()->results().first() );

        if ( !item->album().isNull() )
            ViewManager::instance()->show( item->album() );
        else if ( !item->artist().isNull() )
            ViewManager::instance()->show( item->artist() );
        else if ( !item->query().isNull() )
            ViewManager::instance()->show( item->query() );
    }
}
예제 #14
0
void
GridItemDelegate::onPlayClicked( const QPersistentModelIndex& index )
{
    QPoint pos = m_playButton[ index ]->pos();
    foreach ( ImageButton* button, m_playButton )
        button->deleteLater();
    m_playButton.clear();

    AnimatedSpinner* spinner = new AnimatedSpinner( m_view );
    spinner->setAutoCenter( false );
    spinner->fadeIn();
    spinner->move( pos );
    spinner->setFocusPolicy( Qt::NoFocus );
    spinner->installEventFilter( this );

    m_spinner[ index ] = spinner;

    PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
    if ( item )
    {
        NewClosure( AudioEngine::instance(), SIGNAL( loading( Tomahawk::result_ptr ) ),
                    const_cast<GridItemDelegate*>(this), SLOT( onPlaybackStarted( QPersistentModelIndex ) ), QPersistentModelIndex( index ) );

        m_closures.remove( index );

        m_closures.insertMulti( index, NewClosure( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ),
                                const_cast<GridItemDelegate*>(this), SLOT( onPlaylistChanged( QPersistentModelIndex ) ), QPersistentModelIndex( index ) ) );
        m_closures.insertMulti( index, NewClosure( AudioEngine::instance(), SIGNAL( stopped() ),
                                const_cast<GridItemDelegate*>(this), SLOT( onPlaylistChanged( QPersistentModelIndex ) ), QPersistentModelIndex( index ) ) );

        foreach ( _detail::Closure* closure, m_closures.values( index ) )
            closure->setAutoDelete( false );

        connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackFinished() ) );

        if ( !item->query().isNull() )
            AudioEngine::instance()->playItem( Tomahawk::playlistinterface_ptr(), item->query() );
        else if ( !item->album().isNull() )
            AudioEngine::instance()->playItem( item->album() );
        else if ( !item->artist().isNull() )
            AudioEngine::instance()->playItem( item->artist() );
    }
}
예제 #15
0
void
TreeView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
{
    QTreeView::currentChanged( current, previous );

    if ( !m_updateContextView )
        return;

    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) );
    if ( item )
    {
        if ( !item->result().isNull() )
            ViewManager::instance()->context()->setQuery( item->result()->toQuery() );
        else if ( !item->artist().isNull() )
            ViewManager::instance()->context()->setArtist( item->artist() );
        else if ( !item->album().isNull() )
            ViewManager::instance()->context()->setAlbum( item->album() );
        else if ( !item->query().isNull() )
            ViewManager::instance()->context()->setQuery( item->query() );
    }
}
예제 #16
0
void
PlayableProxyModel::updateDetailedInfo( const QModelIndex& index )
{
    PlayableItem* item = itemFromIndex( mapToSource( index ) );

    if ( item->album() )
    {
        item->album()->cover( QSize( 0, 0 ) );
    }
    else if ( item->artist() )
    {
        item->artist()->cover( QSize( 0, 0 ) );
    }
    else if ( item->query() )
    {
        item->query()->track()->cover( QSize( 0, 0 ) );

/*        if ( style() == PlayableProxyModel::Fancy )
        {
            item->query()->track()->loadSocialActions();
        }*/
    }
}
예제 #17
0
void
TrackView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
{
    QTreeView::currentChanged( current, previous );

    if ( !m_updateContextView )
        return;

    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) );
    if ( item )
    {
        ViewManager::instance()->context()->setQuery( item->query() );
    }
}
예제 #18
0
void
TreeView::onItemActivated( const QModelIndex& index )
{
    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
    if ( item )
    {
        if ( !item->artist().isNull() )
        {
            ViewManager::instance()->show( item->artist() );
        }
        else if ( !item->album().isNull() )
        {
            ViewManager::instance()->show( item->album() );
        }
        else if ( !item->result().isNull() && item->result()->isOnline() )
        {
            AudioEngine::instance()->playItem( m_proxyModel->playlistInterface(), item->result() );
        }
        else if ( !item->query().isNull() )
        {
            AudioEngine::instance()->playItem( m_proxyModel->playlistInterface(), item->query() );
        }
    }
}
QList< Tomahawk::query_ptr >
PlayableProxyModelPlaylistInterface::tracks()
{
    if ( m_proxyModel.isNull() )
        return QList< Tomahawk::query_ptr >();

    PlayableProxyModel* proxyModel = m_proxyModel.data();
    QList<Tomahawk::query_ptr> queries;

    for ( int i = 0; i < proxyModel->rowCount( QModelIndex() ); i++ )
    {
        PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->index( i, 0 ) ) );
        if ( item )
            queries << item->query();
    }

    return queries;
}
예제 #20
0
void
QueueProxyModel::onIndexChanged( const QModelIndex& index )
{
    PlayableItem* item = itemFromIndex( mapToSource( index ) );
    if ( item && item->query() )
    {
        tDebug() << item->query()->toString() << item->query()->resolvingFinished() << item->query()->playable();
    }
    if ( !item || !item->query() || ( item->query()->resolvingFinished() && !item->query()->playable() ) )
    {
        removeIndex( index );
    }
}
예제 #21
0
bool
PlayableProxyModel::dupeFilterAcceptsRow( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent, PlayableProxyModelFilterMemo& memo ) const
{
    if ( !m_hideDupeItems )
        return true;

    for ( int i = 0; i < sourceRow; i++ )
    {
        PlayableItem* di = itemFromIndex( sourceModel()->index( i, 0, sourceParent ) );
        if ( !di )
            continue;

        bool b = ( pi->query() && pi->query()->equals( di->query() ) ) ||
                 ( pi->album() && pi->album() == di->album() ) ||
                 ( pi->artist() && pi->artist()->name() == di->artist()->name() );

        if ( b && filterAcceptsRowInternal( i, di, sourceParent, memo ) )
            return false;
    }

    return true;
}
예제 #22
0
void
CollectionViewPage::onDownloadAll()
{
    if ( DownloadManager::instance()->state() == DownloadManager::Running )
    {
        DownloadManager::instance()->cancelAll();
    }
    else
    {
        for ( int i = 0; i < m_trackView->proxyModel()->rowCount( QModelIndex() ); i++ )
        {
            PlayableItem* item = m_trackView->proxyModel()->itemFromIndex( m_trackView->proxyModel()->mapToSource( m_trackView->proxyModel()->index( i, 0, QModelIndex() ) ) );
            if ( !item )
                continue;

            QList< DownloadFormat > formats = item->query()->results().first()->downloadFormats();
            if ( formats.isEmpty() || !DownloadManager::instance()->localFileForDownload( formats.first().url.toString() ).isEmpty() )
                continue;

            if ( !item->result()->downloadFormats().isEmpty() )
                DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().first() ) );
        }
    }
}
예제 #23
0
void
PlaylistChartItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
    Q_ASSERT( item );

    QStyleOptionViewItemV4 opt = option;
    prepareStyleOption( &opt, index, item );
    opt.text.clear();

    qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter );

    if ( m_view->header()->visualIndex( index.column() ) > 0 )
        return;

    const query_ptr q = item->query()->displayQuery();
    unsigned int duration = q->duration();
    QString artist = q->artist();
    QString track = q->track();
    QPixmap avatar;
    QString upperText, lowerText;

    painter->save();
    {
        QRect r = opt.rect.adjusted( 4, 6, 0, -6 );
        
        // Paint Now Playing Speaker Icon
        if ( item->isPlaying() )
        {
            const int pixMargin = 4;
            const int pixHeight = r.height() - pixMargin * 2;
            QRect npr = r.adjusted( pixMargin, pixMargin + 1, pixHeight - r.width() + pixMargin, -pixMargin + 1 );
            painter->drawPixmap( npr, TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker, TomahawkUtils::Original, npr.size() ) );
            r.adjust( pixHeight + 8, 0, 0, 0 );
        }

        QFont figureFont = opt.font;
        figureFont.setPointSize( TomahawkUtils::defaultFontSize() + 6 );
        figureFont.setWeight( 99 );

        QFont boldFont = opt.font;
        boldFont.setPointSize( TomahawkUtils::defaultFontSize() + 1 );
        boldFont.setWeight( 99 );

        QFont smallBoldFont = opt.font;
        smallBoldFont.setPointSize( TomahawkUtils::defaultFontSize() );
        smallBoldFont.setWeight( 60 );

        QFont durationFont = opt.font;
        durationFont.setPointSize( TomahawkUtils::defaultFontSize() );
        durationFont.setWeight( 80 );
        QFontMetrics durationFontMetrics( durationFont );

        if ( index.row() == 0 )
        {
            figureFont.setPointSize( TomahawkUtils::defaultFontSize() + 33 );
            boldFont.setPointSize( TomahawkUtils::defaultFontSize() + 13 );
            smallBoldFont.setPointSize( TomahawkUtils::defaultFontSize() + 9 );
        }
        else if ( index.row() == 1 )
        {
            figureFont.setPointSize( TomahawkUtils::defaultFontSize() + 17 );
            boldFont.setPointSize( TomahawkUtils::defaultFontSize() + 9 );
            smallBoldFont.setPointSize( TomahawkUtils::defaultFontSize() + 4 );
        }
        else if ( index.row() == 2 )
        {
            figureFont.setPointSize( TomahawkUtils::defaultFontSize() + 9 );
            boldFont.setPointSize( TomahawkUtils::defaultFontSize() + 4 );
            smallBoldFont.setPointSize( TomahawkUtils::defaultFontSize() + 2 );
        }
        else if ( index.row() >= 10 )
        {
            boldFont.setPointSize( TomahawkUtils::defaultFontSize() );
            smallBoldFont.setPointSize( TomahawkUtils::defaultFontSize() - 1 );
        }

        QRect figureRect = r.adjusted( 0, 0, -option.rect.width() + 60 - 6 + r.left(), 0 );
        painter->setFont( figureFont );
        painter->setPen( option.palette.text().color().lighter( 450 ) );
        painter->drawText( figureRect, QString::number( index.row() + 1 ), m_centerOption );
        painter->setPen( opt.palette.text().color() );

        QRect pixmapRect = r.adjusted( figureRect.width() + 6, 0, -option.rect.width() + figureRect.width() + option.rect.height() - 6 + r.left(), 0 );

        if ( !m_pixmaps.contains( index ) )
        {
            m_pixmaps.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->query(), pixmapRect.size(), TomahawkUtils::Original, false ) ) );
            _detail::Closure* closure = NewClosure( m_pixmaps[ index ], SIGNAL( repaintRequest() ), const_cast<PlaylistChartItemDelegate*>(this), SLOT( doUpdateIndex( const QPersistentModelIndex& ) ), QPersistentModelIndex( index ) );
            closure->setAutoDelete( false );
        }

        const QPixmap pixmap = m_pixmaps[ index ]->currentPixmap();
        painter->drawPixmap( pixmapRect, pixmap );

        r.adjust( pixmapRect.width() + figureRect.width() + 18, 1, -28, 0 );
        QRect leftRect = r.adjusted( 0, 0, -durationFontMetrics.width( TomahawkUtils::timeToString( duration ) ) - 8, 0 );

        painter->setFont( boldFont );
        QString text = painter->fontMetrics().elidedText( track, Qt::ElideRight, leftRect.width() );
        painter->drawText( leftRect, text, m_topOption );

        painter->setFont( smallBoldFont );
        text = painter->fontMetrics().elidedText( artist, Qt::ElideRight, leftRect.width() );
        painter->drawText( index.row() >= 10 ? leftRect : leftRect.adjusted( 0, painter->fontMetrics().height() + 6, 0, 0 ), text, index.row() >= 10 ? m_bottomOption : m_topOption );

        if ( duration > 0 )
        {
            painter->setFont( durationFont );
            QRect rightRect = r.adjusted( r.width() - durationFontMetrics.width( TomahawkUtils::timeToString( duration ) ), 0, 0, 0 );
            text = painter->fontMetrics().elidedText( TomahawkUtils::timeToString( duration ), Qt::ElideRight, rightRect.width() );
            painter->drawText( rightRect, text, m_centerRightOption );
        }
    }
예제 #24
0
void
GridItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
    if ( !item || !index.isValid() )
        return;

    QStyleOptionViewItemV4 opt = option;
    initStyleOption( &opt, QModelIndex() );
    qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter );

    QRect r = option.rect;
    QString top, bottom;
    if ( !item->album().isNull() )
    {
        top = item->album()->name();

        if ( !item->album()->artist().isNull() )
            bottom = item->album()->artist()->name();
    }
    else if ( !item->artist().isNull() )
    {
        top = item->artist()->name();
    }
    else if ( !item->query().isNull() )
    {
        top = item->query()->track()->track();
        bottom = item->query()->track()->artist();
    }
    else
    {
        return;
    }

    painter->save();
    painter->setRenderHint( QPainter::Antialiasing );

    if ( !m_covers.contains( index ) )
    {
        if ( !item->album().isNull() )
        {
            m_covers.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->album(), r.size(), TomahawkUtils::Grid ) ) );
        }
        else if ( !item->artist().isNull() )
        {
            m_covers.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->artist(), r.size(), TomahawkUtils::Grid ) ) );
        }
        else
        {
            m_covers.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->query(), r.size(), TomahawkUtils::Grid ) ) );
        }

        NewClosure( m_covers[ index ], SIGNAL( repaintRequest() ),
                    const_cast<GridItemDelegate*>(this), SLOT( doUpdateIndex( QPersistentModelIndex ) ), QPersistentModelIndex( index ) )->setAutoDelete( false );
    }

    QSharedPointer< Tomahawk::PixmapDelegateFader > fader = m_covers[ index ];
    if ( fader->size() != r.size() )
        fader->setSize( r.size() );

    const QPixmap cover = fader->currentPixmap();
    painter->drawPixmap( r, cover );

    qreal opacity = -1.;
    if ( m_hoverFaders.contains( index ) )
    {
        const qreal pct = ( m_hoverFaders[ index ]->currentFrame() / 100.0 );
        opacity = 0.35 - pct * 0.35;
    }
    else if ( m_hoverIndex == index )
    {
        opacity = 0.35;
    }

    if ( opacity > -1.0 )
    {
        painter->save();

        painter->setPen( TomahawkStyle::HOVER_GLOW );
        painter->setBrush( TomahawkStyle::HOVER_GLOW );
        painter->setOpacity( opacity );
        painter->drawRect( r );

        painter->restore();
    }

    QTextOption to;
    to.setWrapMode( QTextOption::NoWrap );

    QString text;
    QFont font = opt.font;
    font.setPointSize( TomahawkUtils::defaultFontSize() );
    QFont boldFont = font;
    boldFont.setBold( true );
    boldFont.setPointSize( TomahawkUtils::defaultFontSize() + 1 );

    int bottomHeight = QFontMetrics( font ).boundingRect( bottom ).height();
    int topHeight = QFontMetrics( boldFont ).boundingRect( top ).height();
    int frameHeight = bottomHeight + topHeight + 10;

    QColor c1;
    c1.setRgb( 0, 0, 0 );
    c1.setAlphaF( 0.00 );
    QColor c2;
    c2.setRgb( 0, 0, 0 );
    c2.setAlphaF( 0.88 );

    QRect gradientRect = r.adjusted( 0, r.height() - frameHeight * 2, 0, 0 );
    QLinearGradient gradient( QPointF( 0, 0 ), QPointF( 0, 1 ) );
    gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
    gradient.setColorAt( 0.0, c1 );
    gradient.setColorAt( 0.6, c2 );
    gradient.setColorAt( 1.0, c2 );

    painter->save();
    painter->setPen( Qt::transparent );
    painter->setBrush( gradient );
    painter->drawRect( gradientRect );
    painter->restore();

    painter->setPen( TomahawkStyle::SELECTION_FOREGROUND );

    QRect textRect = option.rect.adjusted( 6, option.rect.height() - frameHeight, -6, -6 );
    bool oneLiner = false;
    if ( bottom.isEmpty() )
        oneLiner = true;

    painter->setFont( boldFont );
    if ( oneLiner )
    {
        to.setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
        text = painter->fontMetrics().elidedText( top, Qt::ElideRight, textRect.width() - 3 );
        painter->drawText( textRect, text, to );
    }
    else
    {
        to.setAlignment( Qt::AlignHCenter | Qt::AlignTop );
        text = painter->fontMetrics().elidedText( top, Qt::ElideRight, textRect.width() - 3 );
        painter->drawText( textRect, text, to );

        painter->setFont( font );
        // If the user is hovering over an artist rect, draw a background so she knows it's clickable
        QRect r = textRect;
        r.setTop( r.bottom() - painter->fontMetrics().height() );
        r.adjust( 4, 0, -4, -1 );
        if ( m_hoveringOver == index )
        {
            TomahawkUtils::drawQueryBackground( painter, r );
            painter->setPen( TomahawkStyle::SELECTION_FOREGROUND );
        }

        to.setAlignment( Qt::AlignHCenter | Qt::AlignBottom );
        text = painter->fontMetrics().elidedText( bottom, Qt::ElideRight, textRect.width() - 10 );
        painter->drawText( textRect.adjusted( 5, -1, -5, -1 ), text, to );

        // Calculate rect of artist on-hover button click area
        m_artistNameRects[ index ] = r;
    }

    painter->restore();
}
예제 #25
0
void
PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
    Q_ASSERT( item );

    QStyleOptionViewItemV4 opt = option;
    prepareStyleOption( &opt, index, item );
    opt.text.clear();

    qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter );

    if ( m_view->header()->visualIndex( index.column() ) > 0 )
        return;

    const track_ptr track = item->query()->track();
    QPixmap pixmap;
    QString upperLeftText, upperRightText, lowerText;

    if ( !item->playbackLog().source )
    {
        upperLeftText = track->track();
        lowerText = track->artist();
    }
    else
    {
        upperLeftText = track->track();
        upperRightText = QString( " - %2" ).arg( track->artist() );
        QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->playbackLog().timestamp ), true );

        if ( item->playbackLog().source->isLocal() )
            lowerText = QString( tr( "played %1 by you" ) ).arg( playtime );
        else
            lowerText = QString( tr( "played %1 by %2" ) ).arg( playtime ).arg( item->playbackLog().source->friendlyName() );
    }

    painter->save();
    {
        QRect r = opt.rect.adjusted( 3, 6, 0, -6 );

        // Paint Now Playing Speaker Icon
        if ( item->isPlaying() )
        {
            const int pixMargin = 2;
            const int pixHeight = r.height() - pixMargin * 2;
            const QRect npr = r.adjusted( pixMargin, pixMargin + 1, pixHeight - r.width() + pixMargin, -pixMargin + 1 );
            painter->drawPixmap( npr, TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker, TomahawkUtils::Original, npr.size() ) );
            r.adjust( pixHeight + 8, 0, 0, 0 );
        }

        painter->setPen( opt.palette.text().color() );

        QRect ir = r.adjusted( 4, 0, -option.rect.width() + option.rect.height() - 8 + r.left(), 0 );
        pixmap = item->query()->track()->cover( ir.size(), true );

        if ( pixmap.isNull() )
        {
            pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::RoundedCorners, ir.size() );
        }

        painter->drawPixmap( ir, pixmap );

        r.adjust( ir.width() + 12, 0, -12, 0 );
        painter->setFont( m_boldFont );
        QFontMetrics fm = painter->fontMetrics();
        QString elided = fm.elidedText( upperLeftText, Qt::ElideRight, r.width() );
        if ( fm.width( elided ) != fm.width( upperLeftText ) ) //if we had to elide the track title
        {                                                      //we just paint that and we're done
            painter->drawText( r.adjusted( 0, 1, 0, 0 ), elided, m_topOption );
        }
        else
        {
            int remainingSpace = r.width() - fm.width( upperLeftText );
            elided = fm.elidedText( upperRightText, Qt::ElideRight, remainingSpace );
            painter->drawText( r.adjusted( 0, 1, -remainingSpace, 0 ), upperLeftText, m_topOption );

            if ( item->query()->numResults() > 0 && item->query()->results().first()->isOnline() )
                painter->setPen( opt.palette.text().color().lighter( 220 ) );

            painter->drawText( r.adjusted( r.width() - remainingSpace, 1, 0, 0 ), elided, m_topOption );
        }

        painter->setFont( opt.font );
        if ( !( option.state & QStyle::State_Selected || item->isPlaying() ) )
            painter->setPen( Qt::gray );

        elided = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, r.width() );
        painter->drawText( r.adjusted( 0, 1, 0, 0 ), elided, m_bottomOption );
    }

    painter->restore();
}
예제 #26
0
void
GridItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
    if ( !item || !index.isValid() )
        return;

    QStyleOptionViewItemV4 opt = option;
    initStyleOption( &opt, QModelIndex() );
//    qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter );

    QRect r = option.rect;
    r.setHeight( r.width() );

    QString top, bottom;
    if ( !item->album().isNull() )
    {
        top = item->album()->name();

        if ( !item->album()->artist().isNull() )
            bottom = item->album()->artist()->name();
    }
    else if ( !item->artist().isNull() )
    {
        top = item->artist()->name();
    }
    else if ( !item->query().isNull() )
    {
        top = item->query()->track()->track();
        bottom = item->query()->track()->artist();
    }
    else
    {
        return;
    }

    painter->save();
    painter->setRenderHint( QPainter::TextAntialiasing );

    if ( !m_covers.contains( index ) )
    {
        if ( !item->album().isNull() )
        {
            m_covers.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->album(), r.size(), TomahawkUtils::Original, false ) ) );
        }
        else if ( !item->artist().isNull() )
        {
            m_covers.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->artist(), r.size(), TomahawkUtils::Original, false ) ) );
        }
        else
        {
            m_covers.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->query(), r.size(), TomahawkUtils::Original, false ) ) );
        }

        NewClosure( m_covers[ index ], SIGNAL( repaintRequest() ),
                    const_cast<GridItemDelegate*>(this), SLOT( doUpdateIndex( QPersistentModelIndex ) ), QPersistentModelIndex( index ) )->setAutoDelete( false );
    }

    QSharedPointer< Tomahawk::PixmapDelegateFader > fader = m_covers[ index ];
    if ( fader->size() != r.size() )
        fader->setSize( r.size() );
    const QPixmap cover = fader->currentPixmap();

    qreal opacity = -1.0;
    qreal pct = -1.0;
    if ( m_hoverFaders.contains( index ) )
    {
        pct = ( m_hoverFaders[ index ]->currentFrame() / 100.0 );
        opacity = 1.0 - pct * 0.70;
    }
    else if ( m_hoverIndex == index )
    {
        opacity = 0.3;
        pct = 1.0;
    }
    if ( opacity > -1.0 )
    {
        painter->save();

        const int cropIn = pct * ( (qreal)cover.width() * 0.10 );
        const QRect crop = cover.rect().adjusted( cropIn, cropIn, -cropIn, -cropIn );

        painter->drawPixmap( r, cover.copy( crop ).scaled( r.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );

        painter->setOpacity( 1.0 - opacity );
        painter->setPen( Qt::transparent );
        painter->setBrush( Qt::black );
        painter->drawRect( r );

        painter->restore();
    }
    else
    {
        painter->drawPixmap( r, cover );
    }

    QTextOption to;
    to.setWrapMode( QTextOption::NoWrap );

    QString text;
    QRect textRect = option.rect.adjusted( 0, r.height() + m_margin / 4, 0, -m_margin / 2 + m_margin / 8 );
    bool oneLiner = false;
    if ( bottom.isEmpty() )
        oneLiner = true;

    painter->setPen( TomahawkStyle::SELECTION_FOREGROUND );
    painter->setFont( m_font );
    painter->setPen( Qt::black );
    painter->setOpacity( 0.8 );

    if ( m_showPosition )
    {
        painter->save();

        if ( !oneLiner )
        {
            QFont figFont = m_font;
            figFont.setPixelSize( textRect.height() - m_margin / 8 );
            painter->setFont( figFont );
        }

        const QString fig = QString::number( index.row() + 1 );
        painter->drawText( textRect, fig, QTextOption( Qt::AlignLeft | Qt::AlignVCenter ) );

        textRect.adjust( painter->fontMetrics().boundingRect( textRect, Qt::AlignLeft | Qt::AlignVCenter, fig ).width() + m_margin / 4, 0, 0, 0 );
        painter->restore();
    }

    if ( oneLiner )
    {
        // If the user is hovering over an artist rect, draw a background so they knows it's clickable
        if ( m_hoveringOverArtist == index )
        {
            QFont f = painter->font();
            f.setUnderline( true );
            painter->setFont( f );
        }

        to.setAlignment( Qt::AlignLeft | Qt::AlignTop );
        text = painter->fontMetrics().elidedText( top, Qt::ElideRight, textRect.width() - m_margin / 4 );
        painter->drawText( textRect, text, to );

        // Calculate rect of artist on-hover button click area
        m_artistNameRects[ index ] = painter->fontMetrics().boundingRect( textRect, Qt::AlignLeft | Qt::AlignTop, text );
    }
    else
    {
        painter->save();
        // If the user is hovering over an album rect, underline the album name
        if ( m_hoveringOverAlbum == index )
        {
            QFont f = painter->font();
            f.setUnderline( true );
            painter->setFont( f );
        }

        if ( m_showBuyButtons && !item->query().isNull() )
        {
            textRect.adjust( 0, 0, 0, -40 );
        }

        to.setAlignment( Qt::AlignLeft | Qt::AlignTop );
        text = painter->fontMetrics().elidedText( top, Qt::ElideRight, textRect.width() - m_margin / 4 );
        painter->drawText( textRect, text, to );

        if ( item->album() )
        {
            // Calculate rect of album on-hover button click area
            m_albumNameRects[ index ] = painter->fontMetrics().boundingRect( textRect, Qt::AlignLeft | Qt::AlignTop, text );
        }
        painter->restore();

        painter->save();
        painter->setOpacity( 0.6 );
        painter->setFont( m_smallFont );

        // If the user is hovering over an artist rect, underline the artist name
        if ( m_hoveringOverArtist == index )
        {
            QFont f = painter->font();
            f.setUnderline( true );
            painter->setFont( f );
        }

        textRect.adjust( 0, painter->fontMetrics().height() + m_margin / 16, 0, 0 );
        to.setAlignment( Qt::AlignLeft | Qt::AlignBottom );
        text = painter->fontMetrics().elidedText( bottom, Qt::ElideRight, textRect.width() - m_margin / 4 );
        painter->drawText( textRect, text, to );

        // Calculate rect of artist on-hover button click area
        m_artistNameRects[ index ] = painter->fontMetrics().boundingRect( textRect, Qt::AlignLeft | Qt::AlignBottom, text );
        painter->restore();

        if ( m_showBuyButtons && !item->query().isNull() )
        {
            QRect r = textRect;
            r.setY( textRect.y() + textRect.height() + 8 );
            r.setHeight( 32 );
            m_buyButtonRects[ index ] = r;

            QString text;
            bool itemsAvailable = false;
            if ( item->result() &&
               ( ( !item->result()->downloadFormats().isEmpty() && !DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() ) ||
                 ( item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished ) ) )
            {
                text = tr( "View in Finder" );
            }
            else if ( item->query() && item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
            {
                text = tr( "Download %1" ).arg( item->query()->results().first()->downloadFormats().first().extension.toUpper() );
                itemsAvailable = true;
            }
            else if ( item->query()->numResults( true ) && !item->query()->results().first()->purchaseUrl().isEmpty() )
            {
                text = tr( "Buy" );
            }

            if ( !item->result() || !item->result()->downloadJob() || item->result()->downloadJob()->state() == DownloadJob::Finished )
            {
                if ( !text.isEmpty() )
                    DropDownButton::drawPrimitive( painter, r, text, m_hoveringOverBuyButton == index, itemsAvailable );
                else
                    m_buyButtonRects.remove( index );
            }
            else
            {
                painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
                painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
                painter->drawRect( r.adjusted( 2, 2, -2, -2 ) );
                painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
                painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
                QRect fillp = r.adjusted( 3, 3, -3, -3 );
                fillp.setWidth( float(fillp.width()) * ( float(item->result()->downloadJob()->progressPercentage()) / 100.0 ) );
                painter->drawRect( fillp );
            }
        }
    }

    painter->restore();
}
예제 #27
0
bool
TreeProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const
{
    PlayableItem* item = sourceModel()->itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) );
    Q_ASSERT( item );

    //FIXME: m_cache lookup is broken
    if ( /*m_model->mode() == Tomahawk::DatabaseMode &&*/ !item->query().isNull() )
    {
/*        QList< Tomahawk::query_ptr > rl = m_cache.values( sourceParent );
        foreach ( const Tomahawk::query_ptr& cachedQuery, rl )
        {
            if ( cachedQuery.isNull() )
                continue;

            if ( cachedQuery->track()->track() == item->query()->track()->track() &&
               ( cachedQuery->track()->albumpos() == item->query()->track()->albumpos() || cachedQuery->track()->albumpos() == 0 ) )
            {
                return ( cachedQuery.data() == item->query().data() );
            }
        }*/

        for ( int i = 0; i < sourceModel()->rowCount( sourceParent ); i++ )
        {
            if ( i == sourceRow )
                continue;

            PlayableItem* ti = sourceModel()->itemFromIndex( sourceModel()->index( i, 0, sourceParent ) );
            if ( ti && ti->name() == item->name() && !ti->query().isNull() )
            {
                if ( ti->query()->track()->albumpos() == item->query()->track()->albumpos() || ti->query()->track()->albumpos() == 0 || item->query()->track()->albumpos() == 0 )
                {
                    if ( item->result().isNull() )
                        return false;

                    if ( !ti->result().isNull() )
                    {
                        if ( !item->result()->isOnline() && ti->result()->isOnline() )
                            return false;

                        if ( ( item->result()->resolvedByCollection().isNull() || !item->result()->resolvedByCollection()->isLocal() ) &&
                             !ti->result()->resolvedByCollection().isNull() && ti->result()->resolvedByCollection()->isLocal() )
                        {
                            return false;
                        }
                    }
                }
            }
        }
    }

    bool accepted = false;
    if ( m_filter.isEmpty() )
        accepted = true;
    else if ( !item->artist().isNull() )
        accepted = m_artistsFilter.contains( item->artist() );
    else if ( !item->album().isNull() )
        accepted = m_albumsFilter.contains( item->album() );

    if ( !accepted )
    {
        QStringList sl = m_filter.split( " ", QString::SkipEmptyParts );
        foreach( const QString& s, sl )
        {
            if ( !item->name().contains( s, Qt::CaseInsensitive ) &&
                 !item->albumName().contains( s, Qt::CaseInsensitive ) &&
                 !item->artistName().contains( s, Qt::CaseInsensitive ) )
            {
                return false;
            }
        }
    }
예제 #28
0
void
GridItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
    if ( !item )
        return;

    QStyleOptionViewItemV4 opt = option;
    initStyleOption( &opt, QModelIndex() );
    qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter );

    painter->save();
    painter->setRenderHint( QPainter::Antialiasing );

    QRect r = option.rect;
    QString top, bottom;
    if ( !item->album().isNull() )
    {
        top = item->album()->name();

        if ( !item->album()->artist().isNull() )
            bottom = item->album()->artist()->name();
    }
    else if ( !item->artist().isNull() )
    {
        top = item->artist()->name();
    }
    else
    {
        top = item->query()->track();
        bottom = item->query()->artist();
    }

    if ( !m_covers.contains( index ) )
    {
        if ( !item->album().isNull() )
        {
            m_covers.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->album(), r.size(), TomahawkUtils::Grid ) ) );
        }
        else if ( !item->artist().isNull() )
        {
            m_covers.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->artist(), r.size(), TomahawkUtils::Grid ) ) );
        }
        else
        {
            m_covers.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->query(), r.size(), TomahawkUtils::Grid ) ) );
        }

        NewClosure( m_covers[ index ], SIGNAL( repaintRequest() ),
                    const_cast<GridItemDelegate*>(this), SLOT( doUpdateIndex( QPersistentModelIndex ) ), QPersistentModelIndex( index ) )->setAutoDelete( false );
    }

    QSharedPointer< Tomahawk::PixmapDelegateFader > fader = m_covers[ index ];
    if ( fader->size() != r.size() )
        fader->setSize( r.size() );

    const QPixmap cover = fader->currentPixmap();
    painter->drawPixmap( r, cover );

    qreal opacity = -1.;
    if ( m_hoverFaders.contains( index ) )
    {
        const qreal pct = ( m_hoverFaders[ index ]->currentFrame() / 100. );
        opacity = 0.35 - pct * 0.35;
    }
    else if ( m_hoverIndex == index )
    {
        opacity = 0.35;
    }

    if ( opacity > -1. )
    {
        painter->save();

        painter->setPen( QColor( 33, 33, 33 ) );
        painter->setBrush( QColor( 33, 33, 33 ) );
        painter->setOpacity( opacity );
        painter->drawRect( r );

        painter->restore();
    }

    painter->save();

    painter->setPen( Qt::black );
    painter->setBrush( Qt::black );
    painter->setOpacity( 0.5 );
    painter->drawRoundedRect( r.adjusted( 4, +r.height() - 36, -4, -4 ), 3, 3 );

    painter->restore();

    painter->setPen( opt.palette.color( QPalette::HighlightedText ) );
    QTextOption to;
    to.setWrapMode( QTextOption::NoWrap );

    QString text;
    QFont font = opt.font;
    font.setPointSize( TomahawkUtils::defaultFontSize() );
    QFont boldFont = font;
    boldFont.setBold( true );
    boldFont.setPointSize( TomahawkUtils::defaultFontSize() + 1 );

    QRect textRect = option.rect.adjusted( 6, option.rect.height() - 36, -4, -6 );
    painter->setFont( font );
    int bottomHeight = painter->fontMetrics().boundingRect( bottom ).height();
    painter->setFont( boldFont );
    int topHeight = painter->fontMetrics().boundingRect( top ).height();

    bool oneLiner = false;
    if ( bottom.isEmpty() )
        oneLiner = true;
    else
        oneLiner = ( textRect.height() < topHeight + bottomHeight );

    if ( oneLiner )
    {
        to.setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
        text = painter->fontMetrics().elidedText( top, Qt::ElideRight, textRect.width() - 3 );
        painter->drawText( textRect, text, to );
    }
    else
    {
        to.setAlignment( Qt::AlignHCenter | Qt::AlignTop );
        text = painter->fontMetrics().elidedText( top, Qt::ElideRight, textRect.width() - 3 );
        painter->drawText( textRect, text, to );

        painter->setFont( font );
        // If the user is hovering over an artist rect, draw a background so she knows it's clickable
        QRect r = textRect;
        r.setTop( r.bottom() - painter->fontMetrics().height() );
        r.adjust( 4, 0, -4, -1 );
        if ( m_hoveringOver == index )
        {
            TomahawkUtils::drawQueryBackground( painter, opt.palette, r, 1.1 );
            painter->setPen( opt.palette.color( QPalette::HighlightedText ) );
        }

        to.setAlignment( Qt::AlignHCenter | Qt::AlignBottom );
        text = painter->fontMetrics().elidedText( bottom, Qt::ElideRight, textRect.width() - 10 );
        painter->drawText( textRect.adjusted( 5, -1, -5, -1 ), text, to );

        // Calculate rect of artist on-hover button click area
        m_artistNameRects[ index ] = r;
    }

    painter->restore();
}
예제 #29
0
void
PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, bool useAvatars ) const
{
    PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
    Q_ASSERT( item );

    QStyleOptionViewItemV4 opt = option;
    prepareStyleOption( &opt, index, item );
    opt.text.clear();

    qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter );

    if ( m_view->header()->visualIndex( index.column() ) > 0 )
        return;

    const query_ptr q = item->query()->displayQuery();
    QString artist = q->artist();
    QString track = q->track();
    QPixmap pixmap;
    QString upperText, lowerText;
    source_ptr source = item->query()->playedBy().first;

    if ( source.isNull() )
    {
        upperText = track;
        lowerText = artist;
    }
    else
    {
        upperText = QString( "%1 - %2" ).arg( artist ).arg( track );
        QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->query()->playedBy().second ), true );

        if ( source == SourceList::instance()->getLocal() )
            lowerText = QString( tr( "played %1 by you" ) ).arg( playtime );
        else
            lowerText = QString( tr( "played %1 by %2" ) ).arg( playtime ).arg( source->friendlyName() );
    }

    painter->save();
    {
        QRect r = opt.rect.adjusted( 3, 6, 0, -6 );

        // Paint Now Playing Speaker Icon
        if ( item->isPlaying() )
        {
            const int pixMargin = 2;
            const int pixHeight = r.height() - pixMargin * 2;
            QRect npr = r.adjusted( pixMargin, pixMargin + 1, pixHeight - r.width() + pixMargin, -pixMargin + 1 );
            painter->drawPixmap( npr, TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker, TomahawkUtils::Original, npr.size() ) );
            r.adjust( pixHeight + 8, 0, 0, 0 );
        }

        painter->setPen( opt.palette.text().color() );

        QRect ir = r.adjusted( 4, 0, -option.rect.width() + option.rect.height() - 8 + r.left(), 0 );

        if ( useAvatars )
        {
            if ( !source.isNull() )
                pixmap = source->avatar( TomahawkUtils::RoundedCorners, ir.size() );
        }
        else
            pixmap = item->query()->cover( ir.size(), false );

        if ( pixmap.isNull() )
        {
            if ( !useAvatars )
                pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::Original, ir.size() );
            else
                pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultSourceAvatar, TomahawkUtils::RoundedCorners, ir.size() );
        }

        painter->drawPixmap( ir, pixmap );

        QFont boldFont = opt.font;
        boldFont.setBold( true );

        r.adjust( ir.width() + 12, 0, -12, 0 );
        painter->setFont( boldFont );
        QString text = painter->fontMetrics().elidedText( upperText, Qt::ElideRight, r.width() );
        painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, m_topOption );

        painter->setFont( opt.font );
        if ( !( option.state & QStyle::State_Selected || item->isPlaying() ) )
            painter->setPen( Qt::gray );

        text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, r.width() );
        painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, m_bottomOption );
    }
    painter->restore();
}
예제 #30
0
void
TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
    if ( !item )
        return;

    QString text;
    if ( !item->artist().isNull() )
    {
        text = item->artist()->name();
    }
    else if ( !item->album().isNull() )
    {
        text = item->album()->name();
    }
    else if ( !item->result().isNull() || !item->query().isNull() )
    {
        float opacity = item->result().isNull() ? 0.0 : item->result()->score();
        opacity = qMax( (float)0.3, opacity );
        QColor textColor = TomahawkUtils::alphaBlend( option.palette.color( QPalette::Foreground ), option.palette.color( QPalette::Background ), opacity );

        {
            QStyleOptionViewItemV4 o = option;
            initStyleOption( &o, QModelIndex() );

            painter->save();
            o.palette.setColor( QPalette::Text, textColor );

            if ( o.state & QStyle::State_Selected && o.state & QStyle::State_Active )
            {
                o.palette.setColor( QPalette::Text, o.palette.color( QPalette::HighlightedText ) );
            }

            if ( item->isPlaying() )
            {
                o.palette.setColor( QPalette::Highlight, o.palette.color( QPalette::Mid ) );
                if ( o.state & QStyle::State_Selected )
                    o.palette.setColor( QPalette::Text, textColor );
                o.state |= QStyle::State_Selected;
            }

            int oldX = 0;
            if ( m_view->header()->visualIndex( index.column() ) == 0 )
            {
                oldX = o.rect.x();
                o.rect.setX( 0 );
            }
            qApp->style()->drawControl( QStyle::CE_ItemViewItem, &o, painter );
            if ( oldX > 0 )
                o.rect.setX( oldX );

            {
                QRect r = o.rect.adjusted( 3, 0, 0, 0 );

                // Paint Now Playing Speaker Icon
                if ( item->isPlaying() && m_view->header()->visualIndex( index.column() ) == 0 )
                {
                    r.adjust( 0, 0, 0, -3 );
                    QRect npr = r.adjusted( 3, 1, 18 - r.width(), 1 );
                    painter->drawPixmap( npr, TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker, TomahawkUtils::Original, npr.size() ) );
                    r.adjust( 25, 0, 0, 3 );
                }

                painter->setPen( o.palette.text().color() );

                QTextOption to( Qt::AlignVCenter );
                QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, r.width() - 3 );
                painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, to );
            }
            painter->restore();
        }

        return;
    }
    else
        return;

    if ( text.trimmed().isEmpty() )
        text = tr( "Unknown" );

    QStyleOptionViewItemV4 opt = option;
    initStyleOption( &opt, QModelIndex() );
    qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter );

    if ( option.state & QStyle::State_Selected )
    {
        opt.palette.setColor( QPalette::Text, opt.palette.color( QPalette::HighlightedText ) );
    }

    if ( index.column() > 0 )
        return;

    painter->save();
    painter->setRenderHint( QPainter::Antialiasing );
    painter->setPen( opt.palette.color( QPalette::Text ) );

    QRect r = option.rect.adjusted( 4, 4, -option.rect.width() + option.rect.height() - 4, -4 );
//    painter->drawPixmap( r, QPixmap( RESPATH "images/cover-shadow.png" ) );

    if ( !m_pixmaps.contains( index ) )
    {
        if ( !item->album().isNull() )
        {
            m_pixmaps.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->album(), r.size(), TomahawkUtils::ScaledCover, false ) ) );
            _detail::Closure* closure = NewClosure( m_pixmaps[ index ], SIGNAL( repaintRequest() ), const_cast<TreeItemDelegate*>(this), SLOT( doUpdateIndex( const QPersistentModelIndex& ) ), QPersistentModelIndex( index ) );
            closure->setAutoDelete( false );
        }
        else if ( !item->artist().isNull() )