void HTMLLinkElement::process() { if (!inDocument()) return; String type = m_type.lower(); // IE extension: location of small icon for locationbar / bookmarks // We'll record this URL per document, even if we later only use it in top level frames if (m_isIcon && m_url.isValid() && !m_url.isEmpty()) document()->setIconURL(m_url.string(), type); if (m_isDNSPrefetch && m_url.isValid() && !m_url.isEmpty()) ResourceHandle::prepareForURL(m_url); bool acceptIfTypeContainsTextCSS = document()->page() && document()->page()->settings() && document()->page()->settings()->treatsAnyTextCSSLinkAsStylesheet(); // Stylesheet // This was buggy and would incorrectly match <link rel="alternate">, which has a different specified meaning. -dwh if (m_disabledState != 2 && (m_isStyleSheet || (acceptIfTypeContainsTextCSS && type.contains("text/css"))) && document()->frame() && m_url.isValid()) { // also, don't load style sheets for standalone documents String charset = getAttribute(charsetAttr); if (charset.isEmpty() && document()->frame()) charset = document()->frame()->loader()->encoding(); if (m_cachedSheet) { if (m_loading) document()->removePendingSheet(); m_cachedSheet->removeClient(this); m_cachedSheet = 0; } if (!dispatchBeforeLoadEvent(m_url)) return; m_loading = true; // Add ourselves as a pending sheet, but only if we aren't an alternate // stylesheet. Alternate stylesheets don't hold up render tree construction. if (!isAlternate()) document()->addPendingSheet(); m_cachedSheet = document()->docLoader()->requestCSSStyleSheet(m_url, charset); if (m_cachedSheet) m_cachedSheet->addClient(this); else { // The request may have been denied if (for example) the stylesheet is local and the document is remote. m_loading = false; if (!isAlternate()) document()->removePendingSheet(); } } else if (m_sheet) { // we no longer contain a stylesheet, e.g. perhaps rel or type was changed m_sheet = 0; document()->updateStyleSelector(); } }
void K2sendPlayListItem::paintCell (QPainter * p, const QColorGroup & cg, int column, int width, int alignment) { QColorGroup _cg (cg); QColor c = _cg.text (); if (_playing) { _cg.setColor (QColorGroup::Text, _color); //_cg.setColor( QColorGroup::Base, Qt::white ); QListViewItem::paintCell (p, _cg, column, width, alignment); } if (isAlternate ()) _cg.setColor (QColorGroup::Base, KGlobalSettings::alternateBackgroundColor ()); QListViewItem::paintCell (p, _cg, column, width, alignment); }
void KInvestmentListItem::paintCell(QPainter * p, const QColorGroup & cg, int column, int width, int align) { bool bPaintRed = false; if((column == COLUMN_RAWGAIN_INDEX && bColumn5Negative) || (column == COLUMN_1WEEKGAIN_INDEX && bColumn6Negative) || (column == COLUMN_4WEEKGAIN_INDEX && bColumn7Negative) || (column == COLUMN_3MONGAIN_INDEX && bColumn8Negative) || (column == COLUMN_YTDGAIN_INDEX && bColumn9Negative)) { bPaintRed = true; } p->save(); QColorGroup cg2(cg); if(isAlternate()) cg2.setColor(QColorGroup::Base, KMyMoneyGlobalSettings::listColor()); else cg2.setColor(QColorGroup::Base, KMyMoneyGlobalSettings::listBGColor()); #ifndef KMM_DESIGNER QFont font = KMyMoneyGlobalSettings::listCellFont(); // strike out closed accounts if(m_account.isClosed()) font.setStrikeOut(true); p->setFont(font); #endif if(bPaintRed) { QColorGroup _cg( cg2); QColor c = _cg.text(); _cg.setColor(QColorGroup::Text, Qt::red); QListViewItem::paintCell(p, _cg, column, width, align); _cg.setColor(QColorGroup::Text, c); } else { QListViewItem::paintCell(p, cg2, column, width, align); } p->restore(); }
void HTMLLinkElement::process() { if (!inDocument() || m_isInShadowTree) { ASSERT(!m_sheet); return; } String type = m_type.lower(); if (!m_linkLoader.loadLink(m_relAttribute, type, m_sizes->toString(), m_url, document())) return; bool acceptIfTypeContainsTextCSS = document()->page() && document()->page()->settings() && document()->page()->settings()->treatsAnyTextCSSLinkAsStylesheet(); if (m_disabledState != Disabled && (m_relAttribute.m_isStyleSheet || (acceptIfTypeContainsTextCSS && type.contains("text/css"))) && document()->frame() && m_url.isValid()) { String charset = getAttribute(charsetAttr); if (charset.isEmpty() && document()->frame()) charset = document()->charset(); if (m_cachedSheet) { removePendingSheet(); m_cachedSheet->removeClient(this); m_cachedSheet = 0; } if (!shouldLoadLink()) return; m_loading = true; bool mediaQueryMatches = true; if (!m_media.isEmpty()) { RefPtr<RenderStyle> documentStyle = CSSStyleSelector::styleForDocument(document()); RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media); MediaQueryEvaluator evaluator(document()->frame()->view()->mediaType(), document()->frame(), documentStyle.get()); mediaQueryMatches = evaluator.eval(media.get()); } // Don't hold up render tree construction and script execution on stylesheets // that are not needed for the rendering at the moment. bool blocking = mediaQueryMatches && !isAlternate(); addPendingSheet(blocking ? Blocking : NonBlocking); // Load stylesheets that are not needed for the rendering immediately with low priority. ResourceLoadPriority priority = blocking ? ResourceLoadPriorityUnresolved : ResourceLoadPriorityVeryLow; ResourceRequest request(document()->completeURL(m_url)); m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(request, charset, priority); if (m_cachedSheet) m_cachedSheet->addClient(this); else { // The request may have been denied if (for example) the stylesheet is local and the document is remote. m_loading = false; removePendingSheet(); } } else if (m_sheet) { // we no longer contain a stylesheet, e.g. perhaps rel or type was changed m_sheet = 0; document()->styleSelectorChanged(DeferRecalcStyle); } }
void HTMLLinkElement::process() { if (!inDocument() || m_isInShadowTree) { ASSERT(!m_sheet); return; } String type = m_type.lower(); // IE extension: location of small icon for locationbar / bookmarks // We'll record this URL per document, even if we later only use it in top level frames if (m_relAttribute.m_isIcon && m_url.isValid() && !m_url.isEmpty()) { if (!checkBeforeLoadEvent()) return; document()->setIconURL(m_url.string(), type); } #ifdef ANDROID_APPLE_TOUCH_ICON if ((m_relAttribute.m_isTouchIcon || m_relAttribute.m_isPrecomposedTouchIcon) && m_url.isValid() && !m_url.isEmpty() && document()->frame()) document()->frame()->loader()->client() ->dispatchDidReceiveTouchIconURL(m_url.string(), m_relAttribute.m_isPrecomposedTouchIcon); #endif if (m_relAttribute.m_isDNSPrefetch) { Settings* settings = document()->settings(); // FIXME: The href attribute of the link element can be in "//hostname" form, and we shouldn't attempt // to complete that as URL <https://bugs.webkit.org/show_bug.cgi?id=48857>. if (settings && settings->dnsPrefetchingEnabled() && m_url.isValid() && !m_url.isEmpty()) ResourceHandle::prepareForURL(m_url); } #if ENABLE(LINK_PREFETCH) if ((m_relAttribute.m_isLinkPrefetch || m_relAttribute.m_isLinkPrerender || m_relAttribute.m_isLinkSubresource) && m_url.isValid() && document()->frame()) { if (!checkBeforeLoadEvent()) return; ResourceLoadPriority priority = ResourceLoadPriorityUnresolved; CachedResource::Type type = CachedResource::LinkPrefetch; // We only make one request to the cachedresourcelodaer if multiple rel types are // specified. if (m_relAttribute.m_isLinkSubresource) { priority = ResourceLoadPriorityLow; type = CachedResource::LinkSubresource; } else if (m_relAttribute.m_isLinkPrerender) type = CachedResource::LinkPrerender; ResourceRequest linkRequest(document()->completeURL(m_url)); m_cachedLinkResource = document()->cachedResourceLoader()->requestLinkResource(type, linkRequest, priority); if (m_cachedLinkResource) m_cachedLinkResource->addClient(this); } #endif bool acceptIfTypeContainsTextCSS = document()->page() && document()->page()->settings() && document()->page()->settings()->treatsAnyTextCSSLinkAsStylesheet(); if (m_disabledState != Disabled && (m_relAttribute.m_isStyleSheet || (acceptIfTypeContainsTextCSS && type.contains("text/css"))) && document()->frame() && m_url.isValid()) { String charset = getAttribute(charsetAttr); if (charset.isEmpty() && document()->frame()) charset = document()->charset(); if (m_cachedSheet) { removePendingSheet(); m_cachedSheet->removeClient(this); m_cachedSheet = 0; } if (!checkBeforeLoadEvent()) return; m_loading = true; bool mediaQueryMatches = true; if (!m_media.isEmpty()) { RefPtr<RenderStyle> documentStyle = CSSStyleSelector::styleForDocument(document()); RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media); MediaQueryEvaluator evaluator(document()->frame()->view()->mediaType(), document()->frame(), documentStyle.get()); mediaQueryMatches = evaluator.eval(media.get()); } // Don't hold up render tree construction and script execution on stylesheets // that are not needed for the rendering at the moment. bool blocking = mediaQueryMatches && !isAlternate(); addPendingSheet(blocking ? Blocking : NonBlocking); // Load stylesheets that are not needed for the rendering immediately with low priority. ResourceLoadPriority priority = blocking ? ResourceLoadPriorityUnresolved : ResourceLoadPriorityVeryLow; ResourceRequest request(document()->completeURL(m_url)); m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(request, charset, priority); if (m_cachedSheet) m_cachedSheet->addClient(this); else { // The request may have been denied if (for example) the stylesheet is local and the document is remote. m_loading = false; removePendingSheet(); } } else if (m_sheet) { // we no longer contain a stylesheet, e.g. perhaps rel or type was changed m_sheet = 0; document()->styleSelectorChanged(DeferRecalcStyle); } }
void HTMLLinkElement::process() { if (!inDocument()) { ASSERT(!m_sheet); return; } String type = m_type.lower(); // IE extension: location of small icon for locationbar / bookmarks // We'll record this URL per document, even if we later only use it in top level frames if (m_relAttribute.m_isIcon && m_url.isValid() && !m_url.isEmpty()) document()->setIconURL(m_url.string(), type); if (m_relAttribute.m_isDNSPrefetch) { Settings* settings = document()->settings(); // FIXME: The href attribute of the link element can be in "//hostname" form, and we shouldn't attempt // to complete that as URL <https://bugs.webkit.org/show_bug.cgi?id=48857>. if (settings && settings->dnsPrefetchingEnabled() && m_url.isValid() && !m_url.isEmpty()) ResourceHandle::prepareForURL(m_url); } #if ENABLE(LINK_PREFETCH) if (m_relAttribute.m_isLinkPrefetch && m_url.isValid() && document()->frame()) document()->cachedResourceLoader()->requestLinkPrefetch(m_url); #endif bool acceptIfTypeContainsTextCSS = document()->page() && document()->page()->settings() && document()->page()->settings()->treatsAnyTextCSSLinkAsStylesheet(); // Stylesheet // This was buggy and would incorrectly match <link rel="alternate">, which has a different specified meaning. -dwh if (m_disabledState != Disabled && (m_relAttribute.m_isStyleSheet || (acceptIfTypeContainsTextCSS && type.contains("text/css"))) && document()->frame() && m_url.isValid()) { // also, don't load style sheets for standalone documents String charset = getAttribute(charsetAttr); if (charset.isEmpty() && document()->frame()) charset = document()->frame()->loader()->writer()->encoding(); if (m_cachedSheet) { if (m_loading) document()->removePendingSheet(); m_cachedSheet->removeClient(this); m_cachedSheet = 0; } if (!dispatchBeforeLoadEvent(m_url)) return; m_loading = true; // Add ourselves as a pending sheet, but only if we aren't an alternate // stylesheet. Alternate stylesheets don't hold up render tree construction. if (!isAlternate()) document()->addPendingSheet(); m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(m_url, charset); if (m_cachedSheet) m_cachedSheet->addClient(this); else { // The request may have been denied if (for example) the stylesheet is local and the document is remote. m_loading = false; if (!isAlternate()) document()->removePendingSheet(); } } else if (m_sheet) { // we no longer contain a stylesheet, e.g. perhaps rel or type was changed m_sheet = 0; document()->styleSelectorChanged(DeferRecalcStyle); } }
void ChannelListItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ) { QPixmap back( width, height() ); QPainter paint( &back ); //KListViewItem::paintCell( &paint, cg, column, width, align ); // PASTED FROM KLISTVIEWITEM: // set the alternate cell background colour if necessary QColorGroup _cg = cg; if (isAlternate()) if (listView()->viewport()->backgroundMode()==Qt::FixedColor) _cg.setColor(QColorGroup::Background, static_cast< KListView* >(listView())->alternateBackground()); else _cg.setColor(QColorGroup::Base, static_cast< KListView* >(listView())->alternateBackground()); // PASTED FROM QLISTVIEWITEM { QPainter *p = &paint; QListView *lv = listView(); if ( !lv ) return; QFontMetrics fm( p->fontMetrics() ); // any text we render is done by the Components, not by this class, so make sure we've nothing to write QString t; // removed text truncating code from Qt - we do that differently, further on int marg = lv->itemMargin(); int r = marg; // const QPixmap * icon = pixmap( column ); const BackgroundMode bgmode = lv->viewport()->backgroundMode(); const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode ); if ( _cg.brush( crole ) != lv->colorGroup().brush( crole ) ) p->fillRect( 0, 0, width, height(), _cg.brush( crole ) ); else { // all copied from QListView::paintEmptyArea //lv->paintEmptyArea( p, QRect( 0, 0, width, height() ) ); QStyleOption opt( lv->sortColumn(), 0 ); // ### hack; in 3.1, add a property in QListView and QHeader QStyle::SFlags how = QStyle::Style_Default; if ( lv->isEnabled() ) how |= QStyle::Style_Enabled; lv->style().drawComplexControl( QStyle::CC_ListView, p, lv, QRect( 0, 0, width, height() ), lv->colorGroup(), how, QStyle::SC_ListView, QStyle::SC_None, opt ); } if ( isSelected() && (column == 0 || lv->allColumnsShowFocus()) ) { p->fillRect( r - marg, 0, width - r + marg, height(), _cg.brush( QColorGroup::Highlight ) ); // removed text pen setting code from Qt } // removed icon drawing code from Qt // draw the tree gubbins if ( multiLinesEnabled() && column == 0 && isOpen() && childCount() ) { int textheight = fm.size( align, t ).height() + 2 * lv->itemMargin(); textheight = QMAX( textheight, QApplication::globalStrut().height() ); if ( textheight % 2 > 0 ) textheight++; if ( textheight < height() ) { int w = lv->treeStepSize() / 2; lv->style().drawComplexControl( QStyle::CC_ListView, p, lv, QRect( 0, textheight, w + 1, height() - textheight + 1 ), _cg, lv->isEnabled() ? QStyle::Style_Enabled : QStyle::Style_Default, QStyle::SC_ListViewExpand, (uint)QStyle::SC_All, QStyleOption( this ) ); } } } // END OF PASTE //do you see a better way to tell the TextComponent we are selected ? - Olivier 2004-09-02 if ( isSelected() ) _cg.setColor(QColorGroup::Text , _cg.highlightedText() ); QSimpleRichText myrichtext( text(column), paint.font() ); myrichtext.draw( &paint, 0, 0, paint.window(), _cg ); paint.end(); p->drawPixmap( 0, 0, back ); }
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 <*****@*****.**> Copyright (C) 2000,2003 Charles Samuels <*****@*****.**> 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 ); 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 ); }