/*************************************************************************** gradientelidelabel.cpp - adds a gradient-like elide to long labels ------------------- begin : Thursday May 14 2009 copyright : (C) 2009 by Adam Goossens email : fontknocker@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "gradientelidelabel.h" #include <QApplication> #include <QPainter> #include <QFontMetrics> #include <QLinearGradient> #include <QRegExp> #include "utils/kmessshared.h" GradientElideLabel::GradientElideLabel( QWidget *parent ) : QLabel(parent) { } GradientElideLabel::GradientElideLabel( const QString &text, QWidget *parent ) : QLabel( text, parent) { setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed) ); setText(text); } GradientElideLabel::~GradientElideLabel() { } void GradientElideLabel::setText( const QString &text ) { QLabel::setText( text ); cleanText = text; // strip out any HTML tags and replace HTML entities. // at this point "cleanText" should *roughly* resemble the // actual formatted string in width (excusing bold face and what not). cleanText.replace(QRegExp("</?\\w+\\s*[^>]*>"), ""); cleanText = KMessShared::htmlUnescape(cleanText); } void GradientElideLabel::paintEvent(QPaintEvent *event) { QFontMetrics fm(font()); if (fm.width(cleanText) <= contentsRect().width()) { QLabel::paintEvent(event); return; } // if we get here we believe that the text will be too long for the label // so apply the fade. // first, create a pixmap and have QLabel paint itself onto it. // this handles the display of rich text. QPixmap label = QPixmap(width(), height()); label.fill(Qt::transparent); // force the label to draw itself to the pixmap. // we'll then fade out the pixmap and draw it where it should really go. QPainter::setRedirected(this, &label); QLabel::paintEvent(event); QPainter::restoreRedirected(this); // create a painter to paint on the pixmap. QPainter p(&label); p.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing, true ); // create a linear gradient, white to transparent. QLinearGradient gradient(contentsRect().topLeft(), contentsRect().topRight()); if( QApplication::isLeftToRight() ) { gradient.setColorAt( 0.75, Qt::white ); gradient.setColorAt( 1.00, Qt::transparent ); } else { gradient.setColorAt( 0.25, Qt::white ); gradient.setColorAt( 0.00, Qt::transparent ); } // now composite the gradient and the pixmap. p.setCompositionMode(QPainter::CompositionMode_DestinationIn); p.fillRect(rect(), QBrush(gradient)); // now paint that pixmap onto ourselves. QPainter pUs(this); pUs.drawPixmap(rect(), label); }