playlistitem.cpp

来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 1,153 行 · 第 1/3 页

CPP
1,153
字号
    static const QPixmap pixstop   = Amarok::getPNG(  "currenttrack_stop_small"  ),                         pixrepeat = Amarok::getPNG( "currenttrack_repeat_small" );    //figure out if we are in the actual physical first column    if( column == listView()->m_firstColumn && num )    {        //margin, height        const uint m = 2, h = height() - m;        const QString str = QString::number( queue );        const uint qw = painter->fontMetrics().width( str ), sw = pixstop.width(),  rw = pixrepeat.width(),                   qh = painter->fontMetrics().height(),     sh = pixstop.height(), rh = pixrepeat.height();        //maxwidth        const uint mw = kMax( qw, kMax( rw, sw ) );        //width of first & second column of pixmaps        const uint w1 = ( num == 3 ) ? kMax( qw, rw )                      : ( num == 2 && isCurrent ) ? kMax( repeat ? rw : 0, kMax( stop ? sw : 0, queue ? qw : 0 ) )                      : ( num == 2 ) ? qw                      : queue ? qw : repeat ? rw : stop ? sw : 0,                   w2 = ( num == 3 ) ? sw                      : ( num == 2 && !isCurrent ) ? sw                      : 0; //phew        //ellipse width, total width        const uint ew = 16, tw = w1 + w2 + m * ( w2 ? 2 : 1 );        p.setBrush( cg.highlight() );        p.setPen( cg.highlight().dark() ); //TODO blend with background color        p.drawEllipse( width - tw - ew/2, m / 2, ew, h );        p.drawRect( width - tw, m / 2, tw, h );        p.setPen( cg.highlight() );        p.drawLine( width - tw, m/2 + 1, width - tw, h - m/2 );        int x = width - m - mw, y = height() / 2, tmp = 0;        const bool multi = ( isCurrent && num >= 2 );        if( queue )        {            //draw the shadowed inner text            //NOTE we can't set an arbituary font size or family, these settings are already optional            //and user defaults should also take presidence if no playlist font has been selected            //const QFont smallFont( "Arial", (playNext > 9) ? 9 : 12 );            //p->setFont( smallFont );            //TODO the shadow is hard to do well when using a dark font color            //TODO it also looks cluttered for small font sizes            //p->setPen( cg.highlightedText().dark() );            //p->drawText( width - w + 2, 3, w, h-1, Qt::AlignCenter, str );            if( !multi )                tmp = -(qh / 2);            y += tmp;            p.setPen( cg.highlightedText() );            p.drawText( x, y, -x + width, multi ? h/2 : qh, Qt::AlignCenter, str );            y -= tmp;            if( isCurrent )                y -= height() / 2;            else                x -= m + w2;        }        if( repeat )        {            if( multi )                tmp = (h/2 - rh)/2 + ( num == 2 && stop ? 0 : 1 );            else                tmp = -(rh / 2);            y += tmp;            p.drawPixmap( x, y, pixrepeat );            y -= tmp;            if( num == 3 )            {                x -= m + w2 + 2;                y = height() / 2;            }            else                y -= height() / 2;        }        if( stop )        {            if( multi && num != 3 )                tmp = m + (h/2 - sh)/2;            else                tmp = -(sh / 2);            y += tmp;            p.drawPixmap( x, y, pixstop );            y -= tmp;        }    }    if( this != listView()->currentTrack() && !isSelected() )    {        p.setPen( QPen( cg.mid(), 0, Qt::SolidLine ) );        p.drawLine( width - 1, 0, width - 1, height() - 1 );    }    p.end();    painter->drawPixmap( 0, 0, buf );}void PlaylistItem::drawRating( QPainter *p ){    int gray = 0;    if( this == listView()->m_hoveredRating || ( isSelected() && listView()->m_selCount > 1 &&        listView()->m_hoveredRating && listView()->m_hoveredRating->isSelected() ) )    {        const int pos = listView()->viewportToContents( listView()->viewport()->mapFromGlobal( QCursor::pos() ) ).x();        gray = ratingAtPoint( pos );    }    drawRating( p, ( rating() + 1 ) / 2, gray / 2, rating() % 2 );}void PlaylistItem::drawRating( QPainter *p, int stars, int greystars, bool half ){    int i = 1, x = 1;    const int y = height() / 2 - StarManager::instance()->getGreyStar()->height() / 2;    if( half )        i++;    //We use multiple pre-colored stars instead of coloring here to keep things speedy    for(; i <= stars; ++i )    {        bitBlt( p->device(), x, y, StarManager::instance()->getStar( stars ) );        x += StarManager::instance()->getGreyStar()->width() + listView()->itemMargin();    }    if( half )    {        bitBlt( p->device(), x, y, StarManager::instance()->getHalfStar( stars ) );        x += StarManager::instance()->getGreyStar()->width() + listView()->itemMargin();    }    for(; i <= greystars; ++i )    {        bitBlt( p->device(), x, y, StarManager::instance()->getGreyStar() );        x += StarManager::instance()->getGreyStar()->width() + listView()->itemMargin();    }}#define MOODBAR_SPACING 2  // The distance from the moodbar pixmap to each sidevoid PlaylistItem::drawMood( QPainter *p, int width, int height ){    // In theory, if AmarokConfig::showMoodbar() == false, then the    // moodbar column should be hidden and we shouldn't be here.    if( !AmarokConfig::showMoodbar() )      return;    // Due to the logic of the calling code, this should always return true    if( moodbar().dataExists() )      {        QPixmap mood = moodbar().draw( width - MOODBAR_SPACING*2,                                       height - MOODBAR_SPACING*2 );        p->drawPixmap( MOODBAR_SPACING, MOODBAR_SPACING, mood );      }    else      moodbar().load();  // This only has any effect the first time it's run    // We don't have to listen for the jobEvent() signal since we    // inherit MetaBundle, and the moodbar lets the MetaBundle know    // about new data directly via moodbarJobEvent() below.}// This is run when a job starts or finishesvoid PlaylistItem::moodbarJobEvent( int newState ){    (void) newState;  // want to redraw nomatter what the new state is    if( AmarokConfig::showMoodbar() )      repaint();    // Don't automatically resort because it's annoying}void PlaylistItem::setup(){    KListViewItem::setup();    // We make the current track item a bit taller than ordinary items    if( this == listView()->currentTrack() )        setHeight( int( float( listView()->fontMetrics().height() ) * 1.53 ) );}void PlaylistItem::paintFocus( QPainter* p, const QColorGroup& cg, const QRect& r ){    if( this != listView()->currentTrack() )        KListViewItem::paintFocus( p, cg, r );}const QString &PlaylistItem::editingText(){    static const QString text = i18n( "Writing tag..." );    return text;}/** * Changes the transparency (alpha component) of an image. * @param image Image to be manipulated. Must be true color (8 bit per channel). * @param factor > 1.0 == more transparency, < 1.0 == less transparency. */void PlaylistItem::imageTransparency( QImage& image, float factor ) //static{    uint *data = reinterpret_cast<unsigned int *>( image.bits() );    const int pixels = image.width() * image.height();    uint table[256];    register int c;    // Precalculate lookup table    for( int i = 0; i < 256; ++i ) {        c = int( double( i ) * factor );        if( c > 255 ) c = 255;        table[i] = c;    }    // Process all pixels. Highly optimized.    for( int i = 0; i < pixels; ++i ) {        c = data[i]; // Memory access is slow, so do it only once        data[i] = qRgba( qRed( c ), qGreen( c ), qBlue( c ), table[qAlpha( c )] );    }}AtomicString PlaylistItem::artist_album() const{    static const AtomicString various_artist = QString( "Various Artists (INTERNAL) [ASDF!]" );    if( compilation() == CompilationYes )        return various_artist;    else        return artist();}void PlaylistItem::refAlbum(){    if( Amarok::entireAlbums() )    {        if( listView()->m_albums[artist_album()].find( album() ) == listView()->m_albums[artist_album()].end() )            listView()->m_albums[artist_album()][album()] = new PlaylistAlbum;        m_album = listView()->m_albums[artist_album()][album()];        m_album->refcount++;    }}void PlaylistItem::derefAlbum(){    if( Amarok::entireAlbums() && m_album )    {        m_album->refcount--;        if( !m_album->refcount )        {            if (!listView()->m_prevAlbums.removeRef( m_album ))		warning() << "Unable to remove album reference from "		          << "listView.m_prevAlbums" << endl;            listView()->m_albums[artist_album()].remove( album() );            if( listView()->m_albums[artist_album()].isEmpty() )                listView()->m_albums.remove( artist_album() );            delete m_album;        }    }}void PlaylistItem::incrementTotals(){    if( Amarok::entireAlbums() && m_album )    {        const uint prevCount = m_album->tracks.count();        // Multiple tracks with same track number are possible;         // e.g. with "various_artist" albums or albums with multiple disks.        // We are trying to keep m_album->tracks sorted first by discNumber() and then by track().        // It seems that the following assumption is made for the following:         // ``Either all the tracks in an album have their track()'s set (to nonzero) or none of them have.''        if( !track() || !m_album->tracks.count() ||	    ( m_album->tracks.getLast()->track() &&	      ( ( m_album->tracks.getLast()->discNumber() < discNumber() ) || 		( m_album->tracks.getLast()->discNumber() == discNumber() && m_album->tracks.getLast()->track() < track() ) ) ) )            m_album->tracks.append( this );        else            for( int i = 0, n = m_album->tracks.count(); i < n; ++i )                if(!m_album->tracks.at(i)->track() || m_album->tracks.at(i)->discNumber() > discNumber() ||		   ( m_album->tracks.at(i)->discNumber() == discNumber() && m_album->tracks.at(i)->track() > track() ) )                {                    m_album->tracks.insert( i, this );                    break;                }        const Q_INT64 prevTotal = m_album->total;        Q_INT64 total = m_album->total * prevCount;        total += totalIncrementAmount();        m_album->total = Q_INT64( double( total + 0.5 ) / m_album->tracks.count() );        if( listView()->m_prevAlbums.findRef( m_album ) == -1 )            listView()->m_total = listView()->m_total - prevTotal + m_album->total;    }    else if( listView()->m_prevTracks.findRef( this ) == -1 )        listView()->m_total += totalIncrementAmount();}void PlaylistItem::decrementTotals(){    if( Amarok::entireAlbums() && m_album )    {        const Q_INT64 prevTotal = m_album->total;        Q_INT64 total = m_album->total * m_album->tracks.count();        if (!m_album->tracks.removeRef( this ))	    warning() << "Unable to remove myself from m_album" << endl;        total -= totalIncrementAmount();        m_album->total = Q_INT64( double( total + 0.5 ) / m_album->tracks.count() );        if( listView()->m_prevAlbums.findRef( m_album ) == -1 )            listView()->m_total = listView()->m_total - prevTotal + m_album->total;    }    else if( listView()->m_prevTracks.findRef( this ) == -1 )        listView()->m_total -= totalIncrementAmount();}int PlaylistItem::totalIncrementAmount() const{    switch( AmarokConfig::favorTracks() )    {        case AmarokConfig::EnumFavorTracks::Off: return 0;        case AmarokConfig::EnumFavorTracks::HigherScores: return score() > 0.f ? static_cast<int>( score() ) : 50;        case AmarokConfig::EnumFavorTracks::HigherRatings: return rating() ? rating() : 5; // 2.5        case AmarokConfig::EnumFavorTracks::LessRecentlyPlayed:        {            if( lastPlay() )                return listView()->m_startupTime_t - lastPlay();            else if( listView()->m_oldestTime_t )                return ( listView()->m_startupTime_t - listView()->m_oldestTime_t ) * 2;            else                return listView()->m_startupTime_t - 1058652000; //july 20, 2003, when Amarok was first released.        }        default: return 0;    }}void PlaylistItem::incrementCounts(){    listView()->m_totalCount++;    if( isSelected() )    {        listView()->m_selCount++;    }    if( isVisible() )    {        listView()->m_visCount++;        incrementTotals();    }}void PlaylistItem::decrementCounts(){    listView()->m_totalCount--;    if( isSelected() )    {        listView()->m_selCount--;    }    if( isVisible() )    {        listView()->m_visCount--;        decrementTotals();    }}void PlaylistItem::incrementLengths(){    listView()->m_totalLength += length();    if( isSelected() )    {        listView()->m_selLength += length();    }    if( isVisible() )    {        listView()->m_visLength += length();    }}void PlaylistItem::decrementLengths(){    listView()->m_totalLength -= length();    if( isSelected() )    {        listView()->m_selLength -= length();    }    if( isVisible() )    {        listView()->m_visLength -= length();    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?