playlistitem.cpp

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

CPP
1,153
字号
{    const QRect r = listView()->itemRect( this );    if( !r.isValid() )        return;    listView()->viewport()->update( listView()->header()->sectionPos( column ) - listView()->contentsX() + 1,                                    r.y() + 1,                                    listView()->header()->sectionSize( column ) - 2, height() - 2 );}boolPlaylistItem::operator== ( const PlaylistItem & item ) const{    return item.url() == this->url();}boolPlaylistItem::operator< ( const PlaylistItem & item ) const{    return item.url() < this->url();}PlaylistItem*PlaylistItem::nextInAlbum() const{    if( !m_album )        return 0;    const int index = m_album->tracks.findRef( this );    if( index == int(m_album->tracks.count() - 1) )        return 0;    if( index != -1 )        return m_album->tracks.at( index + 1 );    if( track() )        for( int i = 0, n = m_album->tracks.count(); i < n; ++i )	  if( m_album->tracks.at( i )->discNumber() > discNumber() || 	      ( m_album->tracks.at( i )->discNumber() == discNumber() && m_album->tracks.at( i )->track() > track() ) )                return m_album->tracks.at( i );    else        for( QListViewItemIterator it( const_cast<PlaylistItem*>(this), QListViewItemIterator::Visible ); *it; ++it )            #define pit static_cast<PlaylistItem*>( *it )            if( pit != this && pit->m_album == m_album && !pit->track() )                return pit;            #undef pit    return 0;}PlaylistItem*PlaylistItem::prevInAlbum() const{    if( !m_album )        return 0;    const int index = m_album->tracks.findRef( this );    if( index == 0 )        return 0;    if( index != -1 )        return m_album->tracks.at( index - 1 );    if( track() )        for( int i = m_album->tracks.count() - 1; i >= 0; --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() ) ) )                return m_album->tracks.at( i );    else        for( QListViewItemIterator it( const_cast<PlaylistItem*>(this), QListViewItemIterator::Visible ); *it; --it )            #define pit static_cast<PlaylistItem*>( *it )            if( pit != this && pit->m_album == m_album && !pit->track() )                return pit;            #undef pit    return 0;}/////////////////////////////////////////////////////////////////////////////////////// PRIVATE METHODS/////////////////////////////////////////////////////////////////////////////////////intPlaylistItem::compare( QListViewItem *i, int col, bool ascending ) const{    #define i static_cast<PlaylistItem*>(i)    if( Playlist::instance()->dynamicMode() && (isEnabled() != i->isEnabled()) )        return isEnabled() ? 1 : -1;    //damn C++ and its lack of operator<=>    #define cmp(a,b) ( (a < b ) ? -1 : ( a > b ) ? 1 : 0 )    switch( col )    {        case Track:      return cmp( track(),     i->track() );        case Score:      return cmp( score(),     i->score() );        case Rating:     return cmp( rating(),    i->rating() );        case Length:     return cmp( length(),    i->length() );        case PlayCount:  return cmp( playCount(), i->playCount() );        case LastPlayed: return cmp( lastPlay(),  i->lastPlay() );        case Bitrate:    return cmp( bitrate(),   i->bitrate() );        case Bpm:        return cmp( bpm(),       i->bpm() );        case Filesize:   return cmp( filesize(),  i->filesize() );        case Mood:            return cmp( moodbar_const().hueSort(), i->moodbar_const().hueSort() );        case Year:            if( year() == i->year() )                return compare( i, Artist, ascending );            return cmp( year(), i->year() );        case DiscNumber:            if( discNumber() == i->discNumber() )                return compare( i, Track, true ) * (ascending ? 1 : -1);            return cmp( discNumber(), i->discNumber() );    }    #undef cmp    #undef i    QString a =    text( col ).lower();    QString b = i->text( col ).lower();    switch( col )    {        case Type:            a = a.rightJustify( b.length(), '0' );            b = b.rightJustify( a.length(), '0' );            break;        case Artist:            if( a == b ) //if same artist, try to sort by album                return compare( i, Album, ascending );            else            {                if( a.startsWith( "the ", false ) )                    a = a.mid( 4 );                if( b.startsWith( "the ", false ) )                    b = b.mid( 4 );            }            break;        case Album:            if( a == b ) //if same album, try to sort by track                //TODO only sort in ascending order?                return compare( i, DiscNumber, true ) * (ascending ? 1 : -1);            break;    }    return QString::localeAwareCompare( a, b );}void PlaylistItem::paintCell( QPainter *painter, const QColorGroup &cg, int column, int width, int align ){    //TODO add spacing on either side of items    //p->translate( 2, 0 ); width -= 3;    // Don't try to draw if width or height is 0, as this crashes Qt    if( !painter || !listView() || width <= 0 || height() == 0 )        return;    static const QImage currentTrackLeft  = locate( "data", "amarok/images/currenttrack_bar_left.png" );    static const QImage currentTrackMid   = locate( "data", "amarok/images/currenttrack_bar_mid.png" );    static const QImage currentTrackRight = locate( "data", "amarok/images/currenttrack_bar_right.png" );    if( column == Mood  &&  !moodbar().dataExists() )      moodbar().load();  // Only has an effect the first time    // The moodbar column can have text in it, like "Calculating".    // moodbarType is 0 if column != Mood, 1 if we're displaying    // a moodbar, and 2 if we're displaying text    const int moodbarType =        column != Mood ? 0 : moodbar().state() == Moodbar::Loaded ? 1 : 2;    const QString colText = text( column );    const bool isCurrent = this == listView()->currentTrack();    QPixmap buf( width, height() );    QPainter p( &buf, true );    if( isCurrent )    {        static paintCacheItem paintCache[NUM_COLUMNS];        // Convert intensity to string, so we can use it as a key        const QString colorKey = QString::number( glowIntensity );        const bool cacheValid =            paintCache[column].width == width &&            paintCache[column].height == height() &&            paintCache[column].text == colText &&            paintCache[column].font == painter->font() &&            paintCache[column].color == glowBase &&            paintCache[column].selected == isSelected() &&            !s_pixmapChanged;            // If any parameter changed, we must regenerate all pixmaps            if ( !cacheValid )            {                for( int i = 0; i < NUM_COLUMNS; ++i)                    paintCache[i].map.clear();                s_pixmapChanged = false;            }            // Determine if we need to repaint the pixmap, or paint from cache            if ( paintCache[column].map.find( colorKey ) == paintCache[column].map.end() )            {                // Update painting cache                paintCache[column].width = width;                paintCache[column].height = height();                paintCache[column].text = colText;                paintCache[column].font = painter->font();                paintCache[column].color = glowBase;                paintCache[column].selected = isSelected();                QColor bg;                if( isSelected() )                    bg = listView()->colorGroup().highlight();                else                    bg = isAlternate() ? listView()->alternateBackground() :                                        listView()->viewport()->backgroundColor();                buf.fill( bg );                // Draw column divider line                p.setPen( listView()->viewport()->colorGroup().mid() );                p.drawLine( width - 1, 0, width - 1, height() - 1 );                // Here we draw the background bar graphics for the current track:                //                // Illustration of design, L = Left, M = Middle, R = Right:                // <LMMMMMMMMMMMMMMMR>                int leftOffset  = 0;                int rightOffset = 0;                int margin      = listView()->itemMargin();                const float  colorize  = 0.8;                const double intensity = 1.0 - glowIntensity * 0.021;                // Left part                if( column == listView()->m_firstColumn ) {                    QImage tmpImage = currentTrackLeft.smoothScale( 1, height(), QImage::ScaleMax );                    KIconEffect::colorize( tmpImage, glowBase, colorize );                    imageTransparency( tmpImage, intensity );                    p.drawImage( 0, 0, tmpImage, 0, 0, tmpImage.width() - 1 ); //HACK                    leftOffset = tmpImage.width() - 1; //HACK Subtracting 1, to work around the black line bug                    margin += 6;                }                // Right part                else                if( column == Playlist::instance()->mapToLogicalColumn( Playlist::instance()->numVisibleColumns() - 1 ) )                {                    QImage tmpImage = currentTrackRight.smoothScale( 1, height(), QImage::ScaleMax );                    KIconEffect::colorize( tmpImage, glowBase, colorize );                    imageTransparency( tmpImage, intensity );                    p.drawImage( width - tmpImage.width(), 0, tmpImage );                    rightOffset = tmpImage.width();                    margin += 6;                }                // Middle part                // Here we scale the one pixel wide middel image to stretch to the full column width.                QImage tmpImage = currentTrackMid.copy();                KIconEffect::colorize( tmpImage, glowBase, colorize );                imageTransparency( tmpImage, intensity );                tmpImage = tmpImage.smoothScale( width - leftOffset - rightOffset, height() );                p.drawImage( leftOffset, 0, tmpImage );                // Draw the pixmap, if present                int leftMargin = margin;                if ( pixmap( column ) ) {                    p.drawPixmap( leftMargin, height() / 2 - pixmap( column )->height() / 2, *pixmap( column ) );                    leftMargin += pixmap( column )->width() + 2;                }                if( align != Qt::AlignCenter )                align |= Qt::AlignVCenter;                if( column != Rating  &&                    moodbarType != 1 )                {                    // Draw the text                    static QFont font;                    static int minbearing = 1337 + 666;                    if( minbearing == 2003 || font != painter->font() )                    {                        font = painter->font();                        minbearing = painter->fontMetrics().minLeftBearing()                                    + painter->fontMetrics().minRightBearing();                    }                    const bool italic = font.italic();                    int state = EngineController::engine()->state();                    if( state == Engine::Playing || state == Engine::Paused )                        font.setItalic( !italic );                    p.setFont( font );                    p.setPen( cg.highlightedText() );//                  paint.setPen( glowText );                    const int _width = width - leftMargin - margin + minbearing - 1; // -1 seems to be necessary                    const QString _text = KStringHandler::rPixelSqueeze( colText, painter->fontMetrics(), _width );                    p.drawText( leftMargin, 0, _width, height(), align, _text );                    font.setItalic( italic );                    p.setFont( font );                }                paintCache[column].map[colorKey] = buf;            }            else                p.drawPixmap( 0, 0, paintCache[column].map[colorKey] );            if( column == Rating )                drawRating( &p );            if( moodbarType == 1 )                drawMood( &p, width, height() );        }    else    {        const QColorGroup _cg = ( !exists() || !isEnabled() )                                ? listView()->palette().disabled()                                : listView()->palette().active();        QColor bg = isSelected()  ? _cg.highlight()                    : isAlternate() ? listView()->alternateBackground()                    : listView()->viewport()->backgroundColor();        #if KDE_IS_VERSION( 3, 3, 91 )        if( listView()->shadeSortColumn() && !isSelected() && listView()->columnSorted() == column )        {            /* from klistview.cpp                Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org>                Copyright (C) 2000,2003 Charles Samuels <charles@kde.org>                Copyright (C) 2000 Peter Putzer */            if ( bg == Qt::black )                bg = QColor(55, 55, 55);  // dark gray            else            {                int h,s,v;                bg.hsv(&h, &s, &v);                if ( v > 175 )                    bg = bg.dark(104);                else                    bg = bg.light(120);            }        }        #endif        const QColor textc = isSelected() ? _cg.highlightedText() : _cg.text();        buf.fill( bg );        // Draw column divider line        if( !isSelected() )        {            p.setPen( listView()->viewport()->colorGroup().mid() );            p.drawLine( width - 1, 0, width - 1, height() - 1 );        }        // Draw the pixmap, if present        int margin = listView()->itemMargin(), leftMargin = margin;        if ( pixmap( column ) ) {            p.drawPixmap( leftMargin, height() / 2 - pixmap( column )->height() / 2, *pixmap( column ) );            leftMargin += pixmap( column )->width();        }        if( align != Qt::AlignCenter )            align |= Qt::AlignVCenter;        if( column == Rating )            drawRating( &p );        else if( moodbarType == 1 )            drawMood( &p, width, height() );        else        {            // Draw the text            static QFont font;            static int minbearing = 1337 + 666; //can be 0 or negative, 2003 is less likely            if( minbearing == 2003 || font != painter->font() )            {                font = painter->font(); //getting your bearings can be expensive, so we cache them                minbearing = painter->fontMetrics().minLeftBearing()                                + painter->fontMetrics().minRightBearing();            }            p.setFont( font );            p.setPen( ( m_isNew && isEnabled() && !isSelected() ) ? AmarokConfig::newPlaylistItemsColor() : textc );                        const int _width = width - leftMargin - margin + minbearing - 1; // -1 seems to be necessary            const QString _text = KStringHandler::rPixelSqueeze( colText, painter->fontMetrics(), _width );            p.drawText( leftMargin, 0, _width, height(), align, _text );        }    }    /// Track action symbols    const int  queue       = listView()->m_nextTracks.findRef( this ) + 1;    const bool stop        = ( this == listView()->m_stopAfterTrack );    const bool repeat      = Amarok::repeatTrack() && isCurrent;    const uint num = ( queue ? 1 : 0 ) + ( stop ? 1 : 0 ) + ( repeat ? 1 : 0 );

⌨️ 快捷键说明

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