summaryrefslogtreecommitdiffstats
path: root/src/widgets/qlabel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/qlabel.cpp')
-rw-r--r--src/widgets/qlabel.cpp1190
1 files changed, 1190 insertions, 0 deletions
diff --git a/src/widgets/qlabel.cpp b/src/widgets/qlabel.cpp
new file mode 100644
index 0000000..40f2b38
--- /dev/null
+++ b/src/widgets/qlabel.cpp
@@ -0,0 +1,1190 @@
+/**********************************************************************
+**
+** Implementation of QLabel widget class
+**
+** Created : 941215
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the Qt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at [email protected].
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "qlabel.h"
+#ifndef QT_NO_LABEL
+#include "qpainter.h"
+#include "qdrawutil.h"
+#include "qaccel.h"
+#include "qmovie.h"
+#include "qimage.h"
+#include "qbitmap.h"
+#include "qpicture.h"
+#include "qapplication.h"
+#include "qsimplerichtext.h"
+#include "qstylesheet.h"
+#include "qstyle.h"
+
+class QLabelPrivate
+{
+public:
+ QLabelPrivate()
+ :img(0), pix(0), valid_hints( -1 )
+ {}
+ QImage* img; // for scaled contents
+ QPixmap* pix; // for scaled contents
+ QSize sh;
+ QSize msh;
+ int valid_hints; // stores the frameWidth() for the stored size hint, -1 otherwise
+};
+
+
+/*!
+ \class QLabel qlabel.h
+ \brief The QLabel widget provides a text or image display.
+
+ \ingroup basic
+ \ingroup text
+ \mainclass
+
+ QLabel is used for displaying text or an image. No user
+ interaction functionality is provided. The visual appearance of
+ the label can be configured in various ways, and it can be used
+ for specifying a focus accelerator key for another widget.
+
+ A QLabel can contain any of the following content types:
+ \table
+ \header \i Content \i Setting
+ \row \i Plain text
+ \i Pass a QString to setText().
+ \row \i Rich text
+ \i Pass a QString that contains rich text to setText().
+ \row \i A pixmap
+ \i Pass a QPixmap to setPixmap().
+ \row \i A movie
+ \i Pass a QMovie to setMovie().
+ \row \i A number
+ \i Pass an \e int or a \e double to setNum(), which converts
+ the number to plain text.
+ \row \i Nothing
+ \i The same as an empty plain text. This is the default. Set
+ by clear().
+ \endtable
+
+ When the content is changed using any of these functions, any
+ previous content is cleared.
+
+ The look of a QLabel can be tuned in several ways. All the
+ settings of QFrame are available for specifying a widget frame.
+ The positioning of the content within the QLabel widget area can
+ be tuned with setAlignment() and setIndent(). For example, this
+ code sets up a sunken panel with a two-line text in the bottom
+ right corner (both lines being flush with the right side of the
+ label):
+ \code
+ QLabel *label = new QLabel( this );
+ label->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ label->setText( "first line\nsecond line" );
+ label->setAlignment( AlignBottom | AlignRight );
+ \endcode
+
+ A QLabel is often used as a label for an interactive widget. For
+ this use QLabel provides a useful mechanism for adding an
+ accelerator key (see QAccel) that will set the keyboard focus to
+ the other widget (called the QLabel's "buddy"). For example:
+ \code
+ QLineEdit* phoneEdit = new QLineEdit( this, "phoneEdit" );
+ QLabel* phoneLabel = new QLabel( phoneEdit, "&Phone:", this, "phoneLabel" );
+ \endcode
+
+ In this example, keyboard focus is transferred to the label's
+ buddy (the QLineEdit) when the user presses Alt+P. You can
+ also use the setBuddy() function to accomplish the same thing.
+
+ <img src=qlabel-m.png> <img src=qlabel-w.png>
+
+ \sa QLineEdit, QTextEdit, QPixmap, QMovie,
+ \link guibooks.html#fowler GUI Design Handbook: Label\endlink
+*/
+
+/*!
+ \fn QPicture * QLabel::picture() const
+
+ Returns the label's picture or 0 if the label doesn't have a
+ picture.
+*/
+
+
+/*!
+ Constructs an empty label.
+
+ The \a parent, \a name and widget flag \a f, arguments are passed
+ to the QFrame constructor.
+
+ \sa setAlignment(), setFrameStyle(), setIndent()
+*/
+
+QLabel::QLabel( QWidget *parent, const char *name, WFlags f )
+ : QFrame( parent, name, f | WMouseNoMask )
+{
+ init();
+}
+
+
+/*!
+ Constructs a label that displays the text, \a text.
+
+ The \a parent, \a name and widget flag \a f, arguments are passed
+ to the QFrame constructor.
+
+ \sa setText(), setAlignment(), setFrameStyle(), setIndent()
+*/
+
+QLabel::QLabel( const QString &text, QWidget *parent, const char *name,
+ WFlags f )
+ : QFrame( parent, name, f | WMouseNoMask )
+{
+ init();
+ setText( text );
+}
+
+
+/*!
+ Constructs a label that displays the text \a text. The label has a
+ buddy widget, \a buddy.
+
+ If the \a text contains an underlined letter (a letter preceded by
+ an ampersand, \&), and the text is in plain text format, when the
+ user presses Alt+ the underlined letter, focus is passed to the
+ buddy widget.
+
+ The \a parent, \a name and widget flag, \a f, arguments are passed
+ to the QFrame constructor.
+
+ \sa setText(), setBuddy(), setAlignment(), setFrameStyle(),
+ setIndent()
+*/
+QLabel::QLabel( QWidget *buddy, const QString &text,
+ QWidget *parent, const char *name, WFlags f )
+ : QFrame( parent, name, f | WMouseNoMask )
+{
+ init();
+#ifndef QT_NO_ACCEL
+ setBuddy( buddy );
+#endif
+ setText( text );
+}
+
+/*!
+ Destroys the label.
+*/
+
+QLabel::~QLabel()
+{
+ clearContents();
+ delete d;
+}
+
+
+void QLabel::init()
+{
+ lpixmap = 0;
+#ifndef QT_NO_MOVIE
+ lmovie = 0;
+#endif
+#ifndef QT_NO_ACCEL
+ lbuddy = 0;
+ accel = 0;
+#endif
+ lpixmap = 0;
+#ifndef QT_NO_PICTURE
+ lpicture = 0;
+#endif
+ align = AlignAuto | AlignVCenter | ExpandTabs;
+ extraMargin = -1;
+ autoresize = FALSE;
+ scaledcontents = FALSE;
+ textformat = Qt::AutoText;
+#ifndef QT_NO_RICHTEXT
+ doc = 0;
+#endif
+
+ setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) );
+ d = new QLabelPrivate;
+}
+
+
+/*!
+ \property QLabel::text
+ \brief the label's text
+
+ If no text has been set this will return an empty string. Setting
+ the text clears any previous content, unless they are the same.
+
+ The text will be interpreted either as a plain text or as a rich
+ text, depending on the text format setting; see setTextFormat().
+ The default setting is \c AutoText, i.e. QLabel will try to
+ auto-detect the format of the text set.
+
+ If the text is interpreted as a plain text and a buddy has been
+ set, the buddy accelerator key is updated from the new text.
+
+ The label resizes itself if auto-resizing is enabled.
+
+ Note that Qlabel is well-suited to display small rich text
+ documents, i.e. those small documents that get their document
+ specific settings (font, text color, link color) from the label's
+ palette and font properties. For large documents, use QTextEdit
+ in read-only mode instead. QTextEdit will flicker less on resize
+ and can also provide a scrollbar when necessary.
+
+ \sa text, setTextFormat(), setBuddy(), alignment
+*/
+
+void QLabel::setText( const QString &text )
+{
+ if ( ltext == text )
+ return;
+ QSize osh = sizeHint();
+#ifndef QT_NO_RICHTEXT
+ bool hadRichtext = doc != 0;
+#endif
+ clearContents();
+ ltext = text;
+#ifndef QT_NO_RICHTEXT
+ bool useRichText = (textformat == RichText ||
+ ( ( textformat == AutoText ) && QStyleSheet::mightBeRichText(ltext) ) );
+#else
+ bool useRichText = TRUE;
+#endif
+#ifndef QT_NO_ACCEL
+ // ### Setting accelerators for rich text labels will not work.
+ // Eg. <b>&gt;Hello</b> will return ALT+G which is clearly
+ // not intended.
+ if ( !useRichText ) {
+ int p = QAccel::shortcutKey( ltext );
+ if ( p ) {
+ if ( !accel )
+ accel = new QAccel( this, "accel label accel" );
+ accel->connectItem( accel->insertItem( p ),
+ this, SLOT(acceleratorSlot()) );
+ }
+ }
+#endif
+#ifndef QT_NO_RICHTEXT
+ if ( useRichText ) {
+ if ( !hadRichtext )
+ align |= WordBreak;
+ QString t = ltext;
+ if ( align & AlignRight )
+ t.prepend( "<div align=\"right\">");
+ else if ( align & AlignHCenter )
+ t.prepend( "<div align=\"center\">");
+ if ( (align & WordBreak) == 0 )
+ t.prepend( "<nobr>" );
+ doc = new QSimpleRichText( t, font() );
+ }
+#endif
+
+ updateLabel( osh );
+}
+
+
+/*!
+ Clears any label contents. Equivalent to setText( "" ).
+*/
+
+void QLabel::clear()
+{
+ setText( QString::fromLatin1("") );
+}
+
+/*!
+ \property QLabel::pixmap
+ \brief the label's pixmap
+
+ If no pixmap has been set this will return an invalid pixmap.
+
+ Setting the pixmap clears any previous content, and resizes the
+ label if \l QLabel::autoResize() is TRUE. The buddy accelerator,
+ if any, is disabled.
+*/
+void QLabel::setPixmap( const QPixmap &pixmap )
+{
+ QSize osh = sizeHint();
+
+ if ( !lpixmap || lpixmap->serialNumber() != pixmap.serialNumber() ) {
+ clearContents();
+ lpixmap = new QPixmap( pixmap );
+ }
+
+ if ( lpixmap->depth() == 1 && !lpixmap->mask() )
+ lpixmap->setMask( *((QBitmap *)lpixmap) );
+
+ updateLabel( osh );
+}
+
+#ifndef QT_NO_PICTURE
+/*!
+ Sets the label contents to \a picture. Any previous content is
+ cleared.
+
+ The buddy accelerator, if any, is disabled.
+
+ \sa picture(), setBuddy()
+*/
+
+void QLabel::setPicture( const QPicture &picture )
+{
+ QSize osh = sizeHint();
+ clearContents();
+ lpicture = new QPicture( picture );
+
+ updateLabel( osh );
+}
+#endif // QT_NO_PICTURE
+
+/*!
+ Sets the label contents to plain text containing the textual
+ representation of integer \a num. Any previous content is cleared.
+ Does nothing if the integer's string representation is the same as
+ the current contents of the label.
+
+ The buddy accelerator, if any, is disabled.
+
+ The label resizes itself if auto-resizing is enabled.
+
+ \sa setText(), QString::setNum(), setBuddy()
+*/
+
+void QLabel::setNum( int num )
+{
+ QString str;
+ str.setNum( num );
+ setText( str );
+}
+
+/*!
+ \overload
+
+ Sets the label contents to plain text containing the textual
+ representation of double \a num. Any previous content is cleared.
+ Does nothing if the double's string representation is the same as
+ the current contents of the label.
+
+ The buddy accelerator, if any, is disabled.
+
+ The label resizes itself if auto-resizing is enabled.
+
+ \sa setText(), QString::setNum(), setBuddy()
+*/
+
+void QLabel::setNum( double num )
+{
+ QString str;
+ str.setNum( num );
+ setText( str );
+}
+
+/*!
+ \property QLabel::alignment
+ \brief the alignment of the label's contents
+
+ The alignment is a bitwise OR of \c Qt::AlignmentFlags and \c
+ Qt::TextFlags values. The \c ExpandTabs, \c SingleLine and \c
+ ShowPrefix flags apply only if the label contains plain text;
+ otherwise they are ignored. The \c DontClip flag is always
+ ignored. \c WordBreak applies to both rich text and plain text
+ labels. The \c BreakAnywhere flag is not supported in QLabel.
+
+ If the label has a buddy, the \c ShowPrefix flag is forced to
+ TRUE.
+
+ The default alignment is \c{AlignAuto | AlignVCenter | ExpandTabs}
+ if the label doesn't have a buddy and \c{AlignAuto | AlignVCenter
+ | ExpandTabs | ShowPrefix} if the label has a buddy. If the label
+ contains rich text, additionally \c WordBreak is turned on.
+
+ \sa Qt::AlignmentFlags, alignment, setBuddy(), text
+*/
+
+void QLabel::setAlignment( int alignment )
+{
+ if ( alignment == align )
+ return;
+ QSize osh = sizeHint();
+#ifndef QT_NO_ACCEL
+ if ( lbuddy )
+ align = alignment | ShowPrefix;
+ else
+#endif
+ align = alignment;
+
+#ifndef QT_NO_RICHTEXT
+ QString t = ltext;
+ if ( !t.isNull() ) {
+ ltext = QString::null;
+ setText( t );
+ }
+#endif
+
+ updateLabel( osh );
+}
+
+
+/*!
+ \property QLabel::indent
+ \brief the label's text indent in pixels
+
+ If a label displays text, the indent applies to the left edge if
+ alignment() is \c AlignLeft, to the right edge if alignment() is
+ \c AlignRight, to the top edge if alignment() is \c AlignTop, and
+ to to the bottom edge if alignment() is \c AlignBottom.
+
+ If indent is negative, or if no indent has been set, the label
+ computes the effective indent as follows: If frameWidth() is 0,
+ the effective indent becomes 0. If frameWidth() is greater than 0,
+ the effective indent becomes half the width of the "x" character
+ of the widget's current font().
+
+ \sa alignment, frameWidth(), font()
+*/
+
+void QLabel::setIndent( int indent )
+{
+ extraMargin = indent;
+ updateLabel( QSize( -1, -1 ) );
+}
+
+
+/*!
+ \fn bool QLabel::autoResize() const
+
+ \obsolete
+
+ Returns TRUE if auto-resizing is enabled, or FALSE if auto-resizing
+ is disabled.
+
+ Auto-resizing is disabled by default.
+
+ \sa setAutoResize()
+*/
+
+/*! \obsolete
+ Enables auto-resizing if \a enable is TRUE, or disables it if \a
+ enable is FALSE.
+
+ When auto-resizing is enabled the label will resize itself to fit
+ the contents whenever the contents change. The top-left corner is
+ not moved. This is useful for QLabel widgets that are not managed by
+ a QLayout (e.g., top-level widgets).
+
+ Auto-resizing is disabled by default.
+
+ \sa autoResize(), adjustSize(), sizeHint()
+*/
+
+void QLabel::setAutoResize( bool enable )
+{
+ if ( (bool)autoresize != enable ) {
+ autoresize = enable;
+ if ( autoresize )
+ adjustSize(); // calls resize which repaints
+ }
+}
+
+
+
+/*!
+ Returns the size that will be used if the width of the label is \a
+ w. If \a w is -1, the sizeHint() is returned.
+*/
+
+QSize QLabel::sizeForWidth( int w ) const
+{
+ QRect br;
+ QPixmap *pix = pixmap();
+#ifndef QT_NO_PICTURE
+ QPicture *pic = picture();
+#else
+ const int pic = 0;
+#endif
+#ifndef QT_NO_MOVIE
+ QMovie *mov = movie();
+#else
+ const int mov = 0;
+#endif
+ int hextra = 2 * frameWidth();
+ int vextra = hextra;
+ QFontMetrics fm( fontMetrics() );
+ int xw = fm.width( 'x' );
+ if ( !mov && !pix && !pic ) {
+ int m = indent();
+ if ( m < 0 && hextra ) // no indent, but we do have a frame
+ m = xw / 2 - margin();
+ if ( m >= 0 ) {
+ int horizAlign = QApplication::horizontalAlignment( align );
+ if ( (horizAlign & AlignLeft) || (horizAlign & AlignRight ) )
+ hextra += m;
+ if ( (align & AlignTop) || (align & AlignBottom ) )
+ vextra += m;
+ }
+ }
+
+ if ( pix )
+ br = pix->rect();
+#ifndef QT_NO_PICTURE
+ else if ( pic )
+ br = pic->boundingRect();
+#endif
+#ifndef QT_NO_MOVIE
+ else if ( mov )
+ br = mov->framePixmap().rect();
+#endif
+#ifndef QT_NO_RICHTEXT
+ else if ( doc ) {
+ int oldW = doc->width();
+ if ( align & WordBreak ) {
+ if ( w < 0 )
+ doc->adjustSize();
+ else
+ doc->setWidth( w-hextra );
+ }
+ br = QRect( 0, 0, doc->widthUsed(), doc->height() );
+ doc->setWidth( oldW );
+ }
+#endif
+ else {
+ bool tryWidth = (w < 0) && (align & WordBreak);
+ if ( tryWidth )
+ w = xw * 80;
+ else if ( w < 0 )
+ w = 2000;
+ w -= hextra;
+ br = fm.boundingRect( 0, 0, w ,2000, alignment(), text() );
+ if ( tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2 )
+ br = fm.boundingRect( 0, 0, w/2, 2000, alignment(), text() );
+ if ( tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4 )
+ br = fm.boundingRect( 0, 0, w/4, 2000, alignment(), text() );
+ }
+ int wid = br.width() + hextra;
+ int hei = br.height() + vextra;
+
+ return QSize( wid, hei );
+}
+
+
+/*!
+ \reimp
+*/
+
+int QLabel::heightForWidth( int w ) const
+{
+ if (
+#ifndef QT_NO_RICHTEXT
+ doc ||
+#endif
+ (align & WordBreak) )
+ return sizeForWidth( w ).height();
+ return QWidget::heightForWidth( w );
+}
+
+
+
+/*!\reimp
+*/
+QSize QLabel::sizeHint() const
+{
+ if ( d->valid_hints != frameWidth() )
+ (void) QLabel::minimumSizeHint();
+ return d->sh;
+}
+
+/*!
+ \reimp
+*/
+
+QSize QLabel::minimumSizeHint() const
+{
+ if ( d->valid_hints == frameWidth() )
+ return d->msh;
+
+ constPolish();
+ d->valid_hints = frameWidth();
+ d->sh = sizeForWidth( -1 );
+ QSize sz( -1, -1 );
+
+ if (
+#ifndef QT_NO_RICHTEXT
+ !doc &&
+#endif
+ (align & WordBreak) == 0 ) {
+ sz = d->sh;
+ } else {
+ // think about caching these for performance
+ sz.rwidth() = sizeForWidth( 0 ).width();
+ sz.rheight() = sizeForWidth(QWIDGETSIZE_MAX).height();
+ if ( d->sh.height() < sz.height() )
+ sz.rheight() = d->sh.height();
+ }
+ if ( sizePolicy().horData() == QSizePolicy::Ignored )
+ sz.rwidth() = -1;
+ if ( sizePolicy().verData() == QSizePolicy::Ignored )
+ sz.rheight() = -1;
+ d->msh = sz;
+ return sz;
+}
+
+/*!
+ \reimp
+*/
+void QLabel::resizeEvent( QResizeEvent* e )
+{
+ QFrame::resizeEvent( e );
+
+#ifdef QT_NO_RICHTEXT
+ static const bool doc = FALSE;
+#endif
+
+ // optimize for standard labels
+ if ( frameShape() == NoFrame && (align & WordBreak) == 0 && !doc &&
+ ( e->oldSize().width() >= e->size().width() && (align & AlignLeft ) == AlignLeft )
+ && ( e->oldSize().height() >= e->size().height() && (align & AlignTop ) == AlignTop ) ) {
+ setWFlags( WResizeNoErase );
+ return;
+ }
+
+ clearWFlags( WResizeNoErase );
+ QRect cr = contentsRect();
+ if ( !lpixmap || !cr.isValid() ||
+ // masked pixmaps can only reduce flicker when being top/left
+ // aligned and when we do not perform scaled contents
+ ( lpixmap->hasAlpha() && ( scaledcontents || ( ( align & (AlignLeft|AlignTop) ) != (AlignLeft|AlignTop) ) ) ) )
+ return;
+
+ setWFlags( WResizeNoErase );
+
+ if ( !scaledcontents ) {
+ // don't we all love QFrame? Reduce pixmap flicker
+ QRegion reg = QRect( QPoint(0, 0), e->size() );
+ reg = reg.subtract( cr );
+ int x = cr.x();
+ int y = cr.y();
+ int w = lpixmap->width();
+ int h = lpixmap->height();
+ if ( (align & Qt::AlignVCenter) == Qt::AlignVCenter )
+ y += cr.height()/2 - h/2;
+ else if ( (align & Qt::AlignBottom) == Qt::AlignBottom)
+ y += cr.height() - h;
+ if ( (align & Qt::AlignRight) == Qt::AlignRight )
+ x += cr.width() - w;
+ else if ( (align & Qt::AlignHCenter) == Qt::AlignHCenter )
+ x += cr.width()/2 - w/2;
+ if ( x > cr.x() )
+ reg = reg.unite( QRect( cr.x(), cr.y(), x - cr.x(), cr.height() ) );
+ if ( y > cr.y() )
+ reg = reg.unite( QRect( cr.x(), cr.y(), cr.width(), y - cr.y() ) );
+
+ if ( x + w < cr.right() )
+ reg = reg.unite( QRect( x + w, cr.y(), cr.right() - x - w, cr.height() ) );
+ if ( y + h < cr.bottom() )
+ reg = reg.unite( QRect( cr.x(), y + h, cr.width(), cr.bottom() - y - h ) );
+
+ erase( reg );
+ }
+}
+
+
+/*!
+ Draws the label contents using the painter \a p.
+*/
+
+void QLabel::drawContents( QPainter *p )
+{
+ QRect cr = contentsRect();
+
+ QPixmap *pix = pixmap();
+#ifndef QT_NO_PICTURE
+ QPicture *pic = picture();
+#else
+ const int pic = 0;
+#endif
+#ifndef QT_NO_MOVIE
+ QMovie *mov = movie();
+#else
+ const int mov = 0;
+#endif
+
+ if ( !mov && !pix && !pic ) {
+ int m = indent();
+ if ( m < 0 && frameWidth() ) // no indent, but we do have a frame
+ m = fontMetrics().width('x') / 2 - margin();
+ if ( m > 0 ) {
+ int hAlign = QApplication::horizontalAlignment( align );
+ if ( hAlign & AlignLeft )
+ cr.setLeft( cr.left() + m );
+ if ( hAlign & AlignRight )
+ cr.setRight( cr.right() - m );
+ if ( align & AlignTop )
+ cr.setTop( cr.top() + m );
+ if ( align & AlignBottom )
+ cr.setBottom( cr.bottom() - m );
+ }
+ }
+
+#ifndef QT_NO_MOVIE
+ if ( mov ) {
+ // ### should add movie to qDrawItem
+ QRect r = style().itemRect( p, cr, align, isEnabled(), &(mov->framePixmap()),
+ QString::null );
+ // ### could resize movie frame at this point
+ p->drawPixmap(r.x(), r.y(), mov->framePixmap() );
+ }
+ else
+#endif
+#ifndef QT_NO_RICHTEXT
+ if ( doc ) {
+ doc->setWidth(p, cr.width() );
+ int rh = doc->height();
+ int yo = 0;
+ if ( align & AlignVCenter )
+ yo = (cr.height()-rh)/2;
+ else if ( align & AlignBottom )
+ yo = cr.height()-rh;
+ if (! isEnabled() &&
+ style().styleHint(QStyle::SH_EtchDisabledText, this)) {
+ QColorGroup cg = colorGroup();
+ cg.setColor( QColorGroup::Text, cg.light() );
+ doc->draw(p, cr.x()+1, cr.y()+yo+1, cr, cg, 0);
+ }
+
+ // QSimpleRichText always draws with QColorGroup::Text as with
+ // background mode PaletteBase. QLabel typically has
+ // background mode PaletteBackground, so we create a temporary
+ // color group with the text color adjusted.
+ QColorGroup cg = colorGroup();
+ if ( backgroundMode() != PaletteBase && isEnabled() )
+ cg.setColor( QColorGroup::Text, paletteForegroundColor() );
+
+ doc->draw(p, cr.x(), cr.y()+yo, cr, cg, 0);
+ } else
+#endif
+#ifndef QT_NO_PICTURE
+ if ( pic ) {
+ QRect br = pic->boundingRect();
+ int rw = br.width();
+ int rh = br.height();
+ if ( scaledcontents ) {
+ p->save();
+ p->translate( cr.x(), cr.y() );
+#ifndef QT_NO_TRANSFORMATIONS
+ p->scale( (double)cr.width()/rw, (double)cr.height()/rh );
+#endif
+ p->drawPicture( -br.x(), -br.y(), *pic );
+ p->restore();
+ } else {
+ int xo = 0;
+ int yo = 0;
+ if ( align & AlignVCenter )
+ yo = (cr.height()-rh)/2;
+ else if ( align & AlignBottom )
+ yo = cr.height()-rh;
+ if ( align & AlignRight )
+ xo = cr.width()-rw;
+ else if ( align & AlignHCenter )
+ xo = (cr.width()-rw)/2;
+ p->drawPicture( cr.x()+xo-br.x(), cr.y()+yo-br.y(), *pic );
+ }
+ } else
+#endif
+ {
+#ifndef QT_NO_IMAGE_SMOOTHSCALE
+ if ( scaledcontents && pix ) {
+ if ( !d->img )
+ d->img = new QImage( lpixmap->convertToImage() );
+
+ if ( !d->pix )
+ d->pix = new QPixmap;
+ if ( d->pix->size() != cr.size() )
+ d->pix->convertFromImage( d->img->smoothScale( cr.width(), cr.height() ) );
+ pix = d->pix;
+ }
+#endif
+ int alignment = align;
+ if ((align & ShowPrefix) && !style().styleHint(QStyle::SH_UnderlineAccelerator, this))
+ alignment |= NoAccel;
+ // ordinary text or pixmap label
+ style().drawItem( p, cr, alignment, colorGroup(), isEnabled(),
+ pix, ltext );
+ }
+}
+
+
+/*!
+ Updates the label, but not the frame.
+*/
+
+void QLabel::updateLabel( QSize oldSizeHint )
+{
+ d->valid_hints = -1;
+ QSizePolicy policy = sizePolicy();
+ bool wordBreak = align & WordBreak;
+ policy.setHeightForWidth( wordBreak );
+ if ( policy != sizePolicy() )
+ setSizePolicy( policy );
+ if ( sizeHint() != oldSizeHint )
+ updateGeometry();
+ if ( autoresize ) {
+ adjustSize();
+ update( contentsRect() );
+ } else {
+ update( contentsRect() );
+ }
+}
+
+
+/*!
+ \internal
+
+ Internal slot, used to set focus for accelerator labels.
+*/
+#ifndef QT_NO_ACCEL
+void QLabel::acceleratorSlot()
+{
+ if ( !lbuddy )
+ return;
+ QWidget * w = lbuddy;
+ while ( w->focusProxy() )
+ w = w->focusProxy();
+ if ( !w->hasFocus() &&
+ w->isEnabled() &&
+ w->isVisible() &&
+ w->focusPolicy() != NoFocus ) {
+ QFocusEvent::setReason( QFocusEvent::Shortcut );
+ w->setFocus();
+ QFocusEvent::resetReason();
+ }
+}
+#endif
+
+/*!
+ \internal
+
+ Internal slot, used to clean up if the buddy widget dies.
+*/
+#ifndef QT_NO_ACCEL
+void QLabel::buddyDied() // I can't remember if I cried.
+{
+ lbuddy = 0;
+}
+
+/*!
+ Sets this label's buddy to \a buddy.
+
+ When the user presses the accelerator key indicated by this label,
+ the keyboard focus is transferred to the label's buddy widget.
+
+ The buddy mechanism is only available for QLabels that contain
+ plain text in which one letter is prefixed with an ampersand, \&.
+ This letter is set as the accelerator key. The letter is displayed
+ underlined, and the '\&' is not displayed (i.e. the \c ShowPrefix
+ alignment flag is turned on; see setAlignment()).
+
+ In a dialog, you might create two data entry widgets and a label
+ for each, and set up the geometry layout so each label is just to
+ the left of its data entry widget (its "buddy"), for example:
+ \code
+ QLineEdit *nameEd = new QLineEdit( this );
+ QLabel *nameLb = new QLabel( "&Name:", this );
+ nameLb->setBuddy( nameEd );
+ QLineEdit *phoneEd = new QLineEdit( this );
+ QLabel *phoneLb = new QLabel( "&Phone:", this );
+ phoneLb->setBuddy( phoneEd );
+ // ( layout setup not shown )
+ \endcode
+
+ With the code above, the focus jumps to the Name field when the
+ user presses Alt+N, and to the Phone field when the user presses
+ Alt+P.
+
+ To unset a previously set buddy, call this function with \a buddy
+ set to 0.
+
+ \sa buddy(), setText(), QAccel, setAlignment()
+*/
+
+void QLabel::setBuddy( QWidget *buddy )
+{
+ if ( buddy )
+ setAlignment( alignment() | ShowPrefix );
+ else
+ setAlignment( alignment() & ~ShowPrefix );
+
+ if ( lbuddy )
+ disconnect( lbuddy, SIGNAL(destroyed()), this, SLOT(buddyDied()) );
+
+ lbuddy = buddy;
+
+ if ( !lbuddy )
+ return;
+#ifndef QT_NO_RICHTEXT
+ if ( !( textformat == RichText || (textformat == AutoText &&
+ QStyleSheet::mightBeRichText(ltext) ) ) )
+#endif
+ {
+ int p = QAccel::shortcutKey( ltext );
+ if ( p ) {
+ if ( !accel )
+ accel = new QAccel( this, "accel label accel" );
+ accel->connectItem( accel->insertItem( p ),
+ this, SLOT(acceleratorSlot()) );
+ }
+ }
+
+ connect( lbuddy, SIGNAL(destroyed()), this, SLOT(buddyDied()) );
+}
+
+
+/*!
+ Returns this label's buddy, or 0 if no buddy is currently set.
+
+ \sa setBuddy()
+*/
+
+QWidget * QLabel::buddy() const
+{
+ return lbuddy;
+}
+#endif //QT_NO_ACCEL
+
+
+#ifndef QT_NO_MOVIE
+void QLabel::movieUpdated(const QRect& rect)
+{
+ QMovie *mov = movie();
+ if ( mov && !mov->isNull() ) {
+ QRect r = contentsRect();
+ r = style().itemRect( 0, r, align, isEnabled(), &(mov->framePixmap()),
+ QString::null );
+ r.moveBy(rect.x(), rect.y());
+ r.setWidth(QMIN(r.width(), rect.width()));
+ r.setHeight(QMIN(r.height(), rect.height()));
+ repaint( r, mov->framePixmap().mask() != 0 );
+ }
+}
+
+void QLabel::movieResized( const QSize& size )
+{
+ d->valid_hints = -1;
+ if ( autoresize )
+ adjustSize();
+ movieUpdated( QRect( QPoint(0,0), size ) );
+ updateGeometry();
+}
+
+/*!
+ Sets the label contents to \a movie. Any previous content is
+ cleared.
+
+ The buddy accelerator, if any, is disabled.
+
+ The label resizes itself if auto-resizing is enabled.
+
+ \sa movie(), setBuddy()
+*/
+
+void QLabel::setMovie( const QMovie& movie )
+{
+ QSize osh = sizeHint();
+ clearContents();
+
+ lmovie = new QMovie( movie );
+ lmovie->connectResize(this, SLOT(movieResized(const QSize&)));
+ lmovie->connectUpdate(this, SLOT(movieUpdated(const QRect&)));
+
+ if ( !lmovie->running() ) // Assume that if the movie is running,
+ updateLabel( osh ); // resize/update signals will come soon enough
+}
+
+#endif // QT_NO_MOVIE
+
+/*!
+ \internal
+
+ Clears any contents, without updating/repainting the label.
+*/
+
+void QLabel::clearContents()
+{
+#ifndef QT_NO_RICHTEXT
+ delete doc;
+ doc = 0;
+#endif
+
+ delete lpixmap;
+ lpixmap = 0;
+#ifndef QT_NO_PICTURE
+ delete lpicture;
+ lpicture = 0;
+#endif
+ delete d->img;
+ d->img = 0;
+ delete d->pix;
+ d->pix = 0;
+
+ ltext = QString::null;
+#ifndef QT_NO_ACCEL
+ if ( accel )
+ accel->clear();
+#endif
+#ifndef QT_NO_MOVIE
+ if ( lmovie ) {
+ lmovie->disconnectResize(this, SLOT(movieResized(const QSize&)));
+ lmovie->disconnectUpdate(this, SLOT(movieUpdated(const QRect&)));
+ delete lmovie;
+ lmovie = 0;
+ }
+#endif
+}
+
+
+#ifndef QT_NO_MOVIE
+
+/*!
+ Returns a pointer to the label's movie, or 0 if no movie has been
+ set.
+
+ \sa setMovie()
+*/
+
+QMovie* QLabel::movie() const
+{
+ return lmovie;
+}
+
+#endif // QT_NO_MOVIE
+
+/*!
+ \property QLabel::backgroundMode
+ \brief the label's background mode
+
+ Get this property with backgroundMode().
+
+ \sa QWidget::setBackgroundMode()
+*/
+
+/*!
+ \property QLabel::textFormat
+ \brief the label's text format
+
+ See the \c Qt::TextFormat enum for an explanation of the possible
+ options.
+
+ The default format is \c AutoText.
+
+ \sa text
+*/
+
+Qt::TextFormat QLabel::textFormat() const
+{
+ return textformat;
+}
+
+void QLabel::setTextFormat( Qt::TextFormat format )
+{
+ if ( format != textformat ) {
+ textformat = format;
+ QString t = ltext;
+ if ( !t.isNull() ) {
+ ltext = QString::null;
+ setText( t );
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void QLabel::fontChange( const QFont & )
+{
+ if ( !ltext.isEmpty() ) {
+#ifndef QT_NO_RICHTEXT
+ if ( doc )
+ doc->setDefaultFont( font() );
+#endif
+ updateLabel( QSize( -1, -1 ) );
+ }
+}
+
+#ifndef QT_NO_IMAGE_SMOOTHSCALE
+/*!
+ \property QLabel::scaledContents
+ \brief whether the label will scale its contents to fill all
+ available space.
+
+ When enabled and the label shows a pixmap, it will scale the
+ pixmap to fill the available space.
+
+ This property's default is FALSE.
+
+ \sa setScaledContents()
+*/
+bool QLabel::hasScaledContents() const
+{
+ return scaledcontents;
+}
+
+void QLabel::setScaledContents( bool enable )
+{
+ if ( (bool)scaledcontents == enable )
+ return;
+ scaledcontents = enable;
+ if ( !enable ) {
+ delete d->img;
+ d->img = 0;
+ delete d->pix;
+ d->pix = 0;
+ }
+ update( contentsRect() );
+}
+
+#endif // QT_NO_IMAGE_SMOOTHSCALE
+
+/*!
+ Sets the font used on the QLabel to font \a f.
+*/
+
+void QLabel::setFont( const QFont &f )
+{
+ QFrame::setFont( f );
+}
+
+#endif // QT_NO_LABEL