--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) Qxt Foundation. Some rights reserved.
+**
+** This file is part of the QxtGui module of the Qt eXTension library
+**
+** This library is free software; you can redistribute it and/or modify it
+** under the terms of th Common Public License, version 1.0, as published by
+** IBM.
+**
+** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
+** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
+** FITNESS FOR A PARTICULAR PURPOSE.
+**
+** You should have received a copy of the CPL along with this file.
+** See the LICENSE file and the cpl1.0.txt file included with the source
+** distribution for more information. If you did not receive a copy of the
+** license, contact the Qxt Foundation.
+**
+** <http://libqxt.sourceforge.net> <foundation@libqxt.org>
+**
+****************************************************************************/
+#include "qxtlabel.h"
+#include <QTime>
+#include <QEvent>
+#include <QPainter>
+#include <QFontMetrics>
+#include <QApplication>
+#if QT_VERSION < 0x040200
+#include <QAbstractItemDelegate>
+#endif // QT_VERSION
+
+static const int Vertical_Mask = 0x02;
+
+class QxtLabelPrivate : public QxtPrivate<QxtLabel>
+{
+public:
+ QXT_DECLARE_PUBLIC(QxtLabel);
+
+ void init(const QString& txt = QString());
+ void updateLabel();
+
+ QTime time;
+ QString text;
+ Qt::Alignment align;
+ Qt::TextElideMode mode;
+ Qxt::Rotation rot;
+};
+
+void QxtLabelPrivate::init(const QString& txt)
+{
+ text = txt;
+ align = Qt::AlignCenter;
+ mode = Qt::ElideMiddle;
+ rot = Qxt::NoRotation;
+}
+
+void QxtLabelPrivate::updateLabel()
+{
+ qxt_p().updateGeometry();
+ qxt_p().update();
+}
+
+/*!
+ \class QxtLabel QxtLabel
+ \ingroup QxtGui
+ \brief A label which is able to show elided and rotated plain text.
+
+ QxtLabel is a label which is able to show elided and rotated plain text.
+ In addition, QxtLabel provides a signal for clicking.
+
+ \image html qxtlabel.png "QxtLabel in action."
+ */
+
+/*!
+ \fn QxtLabel::clicked()
+
+ This signal is emitted whenever the label has been clicked.
+
+ \note A combination of mouse button press and release in shorter
+ time than \b QApplication::doubleClickInterval is considered
+ as a click.
+
+ \sa QApplication::doubleClickInterval
+ */
+
+/*!
+ Constructs a new QxtLabel with \a parent and \a flags.
+ */
+QxtLabel::QxtLabel(QWidget* parent, Qt::WindowFlags flags) : QFrame(parent, flags)
+{
+ QXT_INIT_PRIVATE(QxtLabel);
+ qxt_d().init();
+}
+
+/*!
+ Constructs a new QxtLabel with \a text, \a parent and \a flags.
+ */
+QxtLabel::QxtLabel(const QString& text, QWidget* parent, Qt::WindowFlags flags) : QFrame(parent, flags)
+{
+ QXT_INIT_PRIVATE(QxtLabel);
+ qxt_d().init(text);
+}
+
+/*!
+ Destructs the label.
+ */
+QxtLabel::~QxtLabel()
+{}
+
+/*!
+ \property QxtLabel::text
+ \brief This property holds the text of the label
+ */
+QString QxtLabel::text() const
+{
+ return qxt_d().text;
+}
+
+void QxtLabel::setText(const QString& text)
+{
+ if (qxt_d().text != text)
+ {
+ qxt_d().text = text;
+ qxt_d().updateLabel();
+ emit textChanged(text);
+ }
+}
+
+/*!
+ \property QxtLabel::alignment
+ \brief This property holds the alignment of the text
+
+ The text is aligned according to this property.
+ The default value is \b Qt::AlignCenter.
+
+ \sa text, Qt::Alignment
+ */
+Qt::Alignment QxtLabel::alignment() const
+{
+ return qxt_d().align;
+}
+
+void QxtLabel::setAlignment(Qt::Alignment alignment)
+{
+ if (qxt_d().align != alignment)
+ {
+ qxt_d().align = alignment;
+ update(); // no geometry change, repaint is sufficient
+ }
+}
+
+/*!
+ \property QxtLabel::elideMode
+ \brief This property holds the elide mode of the text
+
+ The text is elided according to this property.
+ The default value is \b Qt::ElideMiddle.
+
+ \sa text, Qt::TextElideMode
+ */
+Qt::TextElideMode QxtLabel::elideMode() const
+{
+ return qxt_d().mode;
+}
+
+void QxtLabel::setElideMode(Qt::TextElideMode mode)
+{
+ if (qxt_d().mode != mode)
+ {
+ qxt_d().mode = mode;
+ qxt_d().updateLabel();
+ }
+}
+
+/*!
+ \property QxtLabel::rotation
+ \brief This property holds the rotation of the label
+
+ The label is rotated according to this property.
+ The default value is \b Qxt::NoRotation.
+
+ \sa Qxt::Rotation
+ */
+Qxt::Rotation QxtLabel::rotation() const
+{
+ return qxt_d().rot;
+}
+
+void QxtLabel::setRotation(Qxt::Rotation rotation)
+{
+ if (qxt_d().rot != rotation)
+ {
+ Qxt::Rotation prev = qxt_d().rot;
+ qxt_d().rot = rotation;
+ switch (rotation)
+ {
+ case Qxt::NoRotation:
+ case Qxt::UpsideDown:
+ if (prev & Vertical_Mask)
+ {
+ updateGeometry();
+ }
+ break;
+
+ case Qxt::Clockwise:
+ case Qxt::CounterClockwise:
+ if ((prev & Vertical_Mask) == 0)
+ {
+ updateGeometry();
+ }
+ break;
+ default:
+ // nothing to do
+ break;
+ }
+ }
+ update();
+}
+
+QSize QxtLabel::sizeHint() const
+{
+ const QFontMetrics& fm = fontMetrics();
+ QSize size(fm.width(qxt_d().text), fm.height());
+ if (qxt_d().rot & Vertical_Mask)
+ size.transpose();
+ return size;
+}
+
+QSize QxtLabel::minimumSizeHint() const
+{
+ switch (qxt_d().mode)
+ {
+#if QT_VERSION >= 0x040200
+ case Qt::ElideNone:
+ return sizeHint();
+#endif // QT_VERSION
+ default:
+ {
+ const QFontMetrics& fm = fontMetrics();
+ QSize size(fm.width("..."), fm.height());
+ if (qxt_d().rot & Vertical_Mask)
+ size.transpose();
+ return size;
+ }
+ }
+}
+
+void QxtLabel::paintEvent(QPaintEvent* event)
+{
+ QFrame::paintEvent(event);
+ QPainter p(this);
+ p.rotate(qxt_d().rot);
+ QRect r = contentsRect();
+ switch (qxt_d().rot)
+ {
+ case Qxt::UpsideDown:
+ p.translate(-r.width(), -r.height());
+ break;
+
+ case Qxt::Clockwise:
+ p.translate(0, -r.width());
+ break;
+
+ case Qxt::CounterClockwise:
+ p.translate(-r.height(), 0);
+ break;
+
+ default:
+ // nothing to do
+ break;
+ }
+
+ if (qxt_d().rot & Vertical_Mask)
+ {
+ QSize s = r.size();
+ s.transpose();
+ r = QRect(r.topLeft(), s);
+ }
+
+#if QT_VERSION < 0x040200
+ const QString elidedText = QAbstractItemDelegate::elidedText(fontMetrics(), r.width(), qxt_d().mode, qxt_d().text);
+#else // QT_VERSION >= 0x040200
+ const QString elidedText = fontMetrics().elidedText(qxt_d().text, qxt_d().mode, r.width());
+#endif // QT_VERSION
+ p.drawText(r, qxt_d().align, elidedText);
+}
+
+void QxtLabel::changeEvent(QEvent* event)
+{
+ QFrame::changeEvent(event);
+ switch (event->type())
+ {
+ case QEvent::FontChange:
+ case QEvent::ApplicationFontChange:
+ qxt_d().updateLabel();
+ break;
+ default:
+ // nothing to do
+ break;
+ }
+}
+
+void QxtLabel::mousePressEvent(QMouseEvent* event)
+{
+ QFrame::mousePressEvent(event);
+ qxt_d().time.start();
+}
+
+void QxtLabel::mouseReleaseEvent(QMouseEvent* event)
+{
+ QFrame::mouseReleaseEvent(event);
+ if (qxt_d().time.elapsed() < qApp->doubleClickInterval())
+ emit clicked();
+}