453a9f8a55c39063e078072db0dbfad66cf88d55
[quassel.git] / src / contrib / libqxt-2007-10-24 / src / gui / qxtlabel.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) Qxt Foundation. Some rights reserved.
4 **
5 ** This file is part of the QxtGui module of the Qt eXTension library
6 **
7 ** This library is free software; you can redistribute it and/or modify it
8 ** under the terms of th Common Public License, version 1.0, as published by
9 ** IBM.
10 **
11 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
12 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
13 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
14 ** FITNESS FOR A PARTICULAR PURPOSE.
15 **
16 ** You should have received a copy of the CPL along with this file.
17 ** See the LICENSE file and the cpl1.0.txt file included with the source
18 ** distribution for more information. If you did not receive a copy of the
19 ** license, contact the Qxt Foundation.
20 **
21 ** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
22 **
23 ****************************************************************************/
24 #include "qxtlabel.h"
25 #include <QTime>
26 #include <QEvent>
27 #include <QPainter>
28 #include <QFontMetrics>
29 #include <QApplication>
30 #if QT_VERSION < 0x040200
31 #include <QAbstractItemDelegate>
32 #endif // QT_VERSION
33
34 static const int Vertical_Mask = 0x02;
35
36 class QxtLabelPrivate : public QxtPrivate<QxtLabel>
37 {
38 public:
39     QXT_DECLARE_PUBLIC(QxtLabel);
40
41     void init(const QString& txt = QString());
42     void updateLabel();
43
44     QTime time;
45     QString text;
46     Qt::Alignment align;
47     Qt::TextElideMode mode;
48     Qxt::Rotation rot;
49 };
50
51 void QxtLabelPrivate::init(const QString& txt)
52 {
53     text = txt;
54     align = Qt::AlignCenter;
55     mode = Qt::ElideMiddle;
56     rot = Qxt::NoRotation;
57 }
58
59 void QxtLabelPrivate::updateLabel()
60 {
61     qxt_p().updateGeometry();
62     qxt_p().update();
63 }
64
65 /*!
66     \class QxtLabel QxtLabel
67     \ingroup QxtGui
68     \brief A label which is able to show elided and rotated plain text.
69
70     QxtLabel is a label which is able to show elided and rotated plain text.
71     In addition, QxtLabel provides a signal for clicking.
72
73     \image html qxtlabel.png "QxtLabel in action."
74  */
75
76 /*!
77     \fn QxtLabel::clicked()
78
79     This signal is emitted whenever the label has been clicked.
80
81     \note A combination of mouse button press and release in shorter
82     time than \b QApplication::doubleClickInterval is considered
83     as a click.
84
85     \sa QApplication::doubleClickInterval
86  */
87
88 /*!
89     Constructs a new QxtLabel with \a parent and \a flags.
90  */
91 QxtLabel::QxtLabel(QWidget* parent, Qt::WindowFlags flags) : QFrame(parent, flags)
92 {
93     QXT_INIT_PRIVATE(QxtLabel);
94     qxt_d().init();
95 }
96
97 /*!
98     Constructs a new QxtLabel with \a text, \a parent and \a flags.
99  */
100 QxtLabel::QxtLabel(const QString& text, QWidget* parent, Qt::WindowFlags flags) : QFrame(parent, flags)
101 {
102     QXT_INIT_PRIVATE(QxtLabel);
103     qxt_d().init(text);
104 }
105
106 /*!
107     Destructs the label.
108  */
109 QxtLabel::~QxtLabel()
110 {}
111
112 /*!
113     \property QxtLabel::text
114     \brief This property holds the text of the label
115  */
116 QString QxtLabel::text() const
117 {
118     return qxt_d().text;
119 }
120
121 void QxtLabel::setText(const QString& text)
122 {
123     if (qxt_d().text != text)
124     {
125         qxt_d().text = text;
126         qxt_d().updateLabel();
127         emit textChanged(text);
128     }
129 }
130
131 /*!
132     \property QxtLabel::alignment
133     \brief This property holds the alignment of the text
134
135     The text is aligned according to this property.
136     The default value is \b Qt::AlignCenter.
137
138     \sa text, Qt::Alignment
139  */
140 Qt::Alignment QxtLabel::alignment() const
141 {
142     return qxt_d().align;
143 }
144
145 void QxtLabel::setAlignment(Qt::Alignment alignment)
146 {
147     if (qxt_d().align != alignment)
148     {
149         qxt_d().align = alignment;
150         update(); // no geometry change, repaint is sufficient
151     }
152 }
153
154 /*!
155     \property QxtLabel::elideMode
156     \brief This property holds the elide mode of the text
157
158     The text is elided according to this property.
159     The default value is \b Qt::ElideMiddle.
160
161     \sa text, Qt::TextElideMode
162  */
163 Qt::TextElideMode QxtLabel::elideMode() const
164 {
165     return qxt_d().mode;
166 }
167
168 void QxtLabel::setElideMode(Qt::TextElideMode mode)
169 {
170     if (qxt_d().mode != mode)
171     {
172         qxt_d().mode = mode;
173         qxt_d().updateLabel();
174     }
175 }
176
177 /*!
178     \property QxtLabel::rotation
179     \brief This property holds the rotation of the label
180
181     The label is rotated according to this property.
182     The default value is \b Qxt::NoRotation.
183
184     \sa Qxt::Rotation
185  */
186 Qxt::Rotation QxtLabel::rotation() const
187 {
188     return qxt_d().rot;
189 }
190
191 void QxtLabel::setRotation(Qxt::Rotation rotation)
192 {
193     if (qxt_d().rot != rotation)
194     {
195         Qxt::Rotation prev = qxt_d().rot;
196         qxt_d().rot = rotation;
197         switch (rotation)
198         {
199         case Qxt::NoRotation:
200         case Qxt::UpsideDown:
201             if (prev & Vertical_Mask)
202             {
203                 updateGeometry();
204             }
205             break;
206
207         case Qxt::Clockwise:
208         case Qxt::CounterClockwise:
209             if ((prev & Vertical_Mask) == 0)
210             {
211                 updateGeometry();
212             }
213             break;
214         default:
215             // nothing to do
216             break;
217         }
218     }
219     update();
220 }
221
222 QSize QxtLabel::sizeHint() const
223 {
224     const QFontMetrics& fm = fontMetrics();
225     QSize size(fm.width(qxt_d().text), fm.height());
226     if (qxt_d().rot & Vertical_Mask)
227         size.transpose();
228     return size;
229 }
230
231 QSize QxtLabel::minimumSizeHint() const
232 {
233     switch (qxt_d().mode)
234     {
235 #if QT_VERSION >= 0x040200
236     case Qt::ElideNone:
237         return sizeHint();
238 #endif // QT_VERSION
239     default:
240     {
241         const QFontMetrics& fm = fontMetrics();
242         QSize size(fm.width("..."), fm.height());
243         if (qxt_d().rot & Vertical_Mask)
244             size.transpose();
245         return size;
246     }
247     }
248 }
249
250 void QxtLabel::paintEvent(QPaintEvent* event)
251 {
252     QFrame::paintEvent(event);
253     QPainter p(this);
254     p.rotate(qxt_d().rot);
255     QRect r = contentsRect();
256     switch (qxt_d().rot)
257     {
258     case Qxt::UpsideDown:
259         p.translate(-r.width(), -r.height());
260         break;
261
262     case Qxt::Clockwise:
263         p.translate(0, -r.width());
264         break;
265
266     case Qxt::CounterClockwise:
267         p.translate(-r.height(), 0);
268         break;
269
270     default:
271         // nothing to do
272         break;
273     }
274
275     if (qxt_d().rot & Vertical_Mask)
276     {
277         QSize s = r.size();
278         s.transpose();
279         r = QRect(r.topLeft(), s);
280     }
281
282 #if QT_VERSION < 0x040200
283     const QString elidedText = QAbstractItemDelegate::elidedText(fontMetrics(), r.width(), qxt_d().mode, qxt_d().text);
284 #else // QT_VERSION >= 0x040200
285     const QString elidedText = fontMetrics().elidedText(qxt_d().text, qxt_d().mode, r.width());
286 #endif // QT_VERSION
287     p.drawText(r, qxt_d().align, elidedText);
288 }
289
290 void QxtLabel::changeEvent(QEvent* event)
291 {
292     QFrame::changeEvent(event);
293     switch (event->type())
294     {
295     case QEvent::FontChange:
296     case QEvent::ApplicationFontChange:
297         qxt_d().updateLabel();
298         break;
299     default:
300         // nothing to do
301         break;
302     }
303 }
304
305 void QxtLabel::mousePressEvent(QMouseEvent* event)
306 {
307     QFrame::mousePressEvent(event);
308     qxt_d().time.start();
309 }
310
311 void QxtLabel::mouseReleaseEvent(QMouseEvent* event)
312 {
313     QFrame::mouseReleaseEvent(event);
314     if (qxt_d().time.elapsed() < qApp->doubleClickInterval())
315         emit clicked();
316 }