1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation (qt-info@nokia.com)
|
---|
6 | **
|
---|
7 | ** This file is part of the QtGui module of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at qt-info@nokia.com.
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #include "qpainter.h"
|
---|
43 | #include "qevent.h"
|
---|
44 | #include "qdrawutil.h"
|
---|
45 | #include "qapplication.h"
|
---|
46 | #include "qabstractbutton.h"
|
---|
47 | #include "qstyle.h"
|
---|
48 | #include "qstyleoption.h"
|
---|
49 | #include <limits.h>
|
---|
50 | #include "qaction.h"
|
---|
51 | #include "qclipboard.h"
|
---|
52 | #include <qdebug.h>
|
---|
53 | #include <qurl.h>
|
---|
54 | #include "qlabel_p.h"
|
---|
55 | #include "private/qstylesheetstyle_p.h"
|
---|
56 |
|
---|
57 | QT_BEGIN_NAMESPACE
|
---|
58 |
|
---|
59 | /*!
|
---|
60 | \class QLabel
|
---|
61 | \brief The QLabel widget provides a text or image display.
|
---|
62 |
|
---|
63 | \ingroup basicwidgets
|
---|
64 |
|
---|
65 | QLabel is used for displaying text or an image. No user
|
---|
66 | interaction functionality is provided. The visual appearance of
|
---|
67 | the label can be configured in various ways, and it can be used
|
---|
68 | for specifying a focus mnemonic key for another widget.
|
---|
69 |
|
---|
70 | A QLabel can contain any of the following content types:
|
---|
71 |
|
---|
72 | \table
|
---|
73 | \header \o Content \o Setting
|
---|
74 | \row \o Plain text
|
---|
75 | \o Pass a QString to setText().
|
---|
76 | \row \o Rich text
|
---|
77 | \o Pass a QString that contains rich text to setText().
|
---|
78 | \row \o A pixmap
|
---|
79 | \o Pass a QPixmap to setPixmap().
|
---|
80 | \row \o A movie
|
---|
81 | \o Pass a QMovie to setMovie().
|
---|
82 | \row \o A number
|
---|
83 | \o Pass an \e int or a \e double to setNum(), which converts
|
---|
84 | the number to plain text.
|
---|
85 | \row \o Nothing
|
---|
86 | \o The same as an empty plain text. This is the default. Set
|
---|
87 | by clear().
|
---|
88 | \endtable
|
---|
89 |
|
---|
90 | When the content is changed using any of these functions, any
|
---|
91 | previous content is cleared.
|
---|
92 |
|
---|
93 | By default, labels display \l{alignment}{left-aligned, vertically-centered}
|
---|
94 | text and images, where any tabs in the text to be displayed are
|
---|
95 | \l{Qt::TextExpandTabs}{automatically expanded}. However, the look
|
---|
96 | of a QLabel can be adjusted and fine-tuned in several ways.
|
---|
97 |
|
---|
98 | The positioning of the content within the QLabel widget area can
|
---|
99 | be tuned with setAlignment() and setIndent(). Text content can
|
---|
100 | also wrap lines along word boundaries with setWordWrap(). For
|
---|
101 | example, this code sets up a sunken panel with a two-line text in
|
---|
102 | the bottom right corner (both lines being flush with the right
|
---|
103 | side of the label):
|
---|
104 |
|
---|
105 | \snippet doc/src/snippets/code/src_gui_widgets_qlabel.cpp 0
|
---|
106 |
|
---|
107 | The properties and functions QLabel inherits from QFrame can also
|
---|
108 | be used to specify the widget frame to be used for any given label.
|
---|
109 |
|
---|
110 | A QLabel is often used as a label for an interactive widget. For
|
---|
111 | this use QLabel provides a useful mechanism for adding an
|
---|
112 | mnemonic (see QKeySequence) that will set the keyboard focus to
|
---|
113 | the other widget (called the QLabel's "buddy"). For example:
|
---|
114 |
|
---|
115 | \snippet doc/src/snippets/code/src_gui_widgets_qlabel.cpp 1
|
---|
116 |
|
---|
117 | In this example, keyboard focus is transferred to the label's
|
---|
118 | buddy (the QLineEdit) when the user presses Alt+P. If the buddy
|
---|
119 | was a button (inheriting from QAbstractButton), triggering the
|
---|
120 | mnemonic would emulate a button click.
|
---|
121 |
|
---|
122 | \table 100%
|
---|
123 | \row
|
---|
124 | \o \inlineimage macintosh-label.png Screenshot of a Macintosh style label
|
---|
125 | \o A label shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
|
---|
126 | \row
|
---|
127 | \o \inlineimage plastique-label.png Screenshot of a Plastique style label
|
---|
128 | \o A label shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
|
---|
129 | \row
|
---|
130 | \o \inlineimage windowsxp-label.png Screenshot of a Windows XP style label
|
---|
131 | \o A label shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
|
---|
132 | \endtable
|
---|
133 |
|
---|
134 | \sa QLineEdit, QTextEdit, QPixmap, QMovie,
|
---|
135 | {fowler}{GUI Design Handbook: Label}
|
---|
136 | */
|
---|
137 |
|
---|
138 | #ifndef QT_NO_PICTURE
|
---|
139 | /*!
|
---|
140 | Returns the label's picture or 0 if the label doesn't have a
|
---|
141 | picture.
|
---|
142 | */
|
---|
143 |
|
---|
144 | const QPicture *QLabel::picture() const
|
---|
145 | {
|
---|
146 | Q_D(const QLabel);
|
---|
147 | return d->picture;
|
---|
148 | }
|
---|
149 | #endif
|
---|
150 |
|
---|
151 |
|
---|
152 | /*!
|
---|
153 | Constructs an empty label.
|
---|
154 |
|
---|
155 | The \a parent and widget flag \a f, arguments are passed
|
---|
156 | to the QFrame constructor.
|
---|
157 |
|
---|
158 | \sa setAlignment(), setFrameStyle(), setIndent()
|
---|
159 | */
|
---|
160 | QLabel::QLabel(QWidget *parent, Qt::WindowFlags f)
|
---|
161 | : QFrame(*new QLabelPrivate(), parent, f)
|
---|
162 | {
|
---|
163 | Q_D(QLabel);
|
---|
164 | d->init();
|
---|
165 | }
|
---|
166 |
|
---|
167 | /*!
|
---|
168 | Constructs a label that displays the text, \a text.
|
---|
169 |
|
---|
170 | The \a parent and widget flag \a f, arguments are passed
|
---|
171 | to the QFrame constructor.
|
---|
172 |
|
---|
173 | \sa setText(), setAlignment(), setFrameStyle(), setIndent()
|
---|
174 | */
|
---|
175 | QLabel::QLabel(const QString &text, QWidget *parent, Qt::WindowFlags f)
|
---|
176 | : QFrame(*new QLabelPrivate(), parent, f)
|
---|
177 | {
|
---|
178 | Q_D(QLabel);
|
---|
179 | d->init();
|
---|
180 | setText(text);
|
---|
181 | }
|
---|
182 |
|
---|
183 |
|
---|
184 | #ifdef QT3_SUPPORT
|
---|
185 | /*! \obsolete
|
---|
186 | Constructs an empty label.
|
---|
187 |
|
---|
188 | The \a parent, \a name and widget flag \a f, arguments are passed
|
---|
189 | to the QFrame constructor.
|
---|
190 |
|
---|
191 | \sa setAlignment(), setFrameStyle(), setIndent()
|
---|
192 | */
|
---|
193 |
|
---|
194 | QLabel::QLabel(QWidget *parent, const char *name, Qt::WindowFlags f)
|
---|
195 | : QFrame(*new QLabelPrivate(), parent, f)
|
---|
196 | {
|
---|
197 | Q_D(QLabel);
|
---|
198 | if (name)
|
---|
199 | setObjectName(QString::fromAscii(name));
|
---|
200 | d->init();
|
---|
201 | }
|
---|
202 |
|
---|
203 |
|
---|
204 | /*! \obsolete
|
---|
205 | Constructs a label that displays the text, \a text.
|
---|
206 |
|
---|
207 | The \a parent, \a name and widget flag \a f, arguments are passed
|
---|
208 | to the QFrame constructor.
|
---|
209 |
|
---|
210 | \sa setText(), setAlignment(), setFrameStyle(), setIndent()
|
---|
211 | */
|
---|
212 |
|
---|
213 | QLabel::QLabel(const QString &text, QWidget *parent, const char *name,
|
---|
214 | Qt::WindowFlags f)
|
---|
215 | : QFrame(*new QLabelPrivate(), parent, f)
|
---|
216 | {
|
---|
217 | Q_D(QLabel);
|
---|
218 | if (name)
|
---|
219 | setObjectName(QString::fromAscii(name));
|
---|
220 | d->init();
|
---|
221 | setText(text);
|
---|
222 | }
|
---|
223 |
|
---|
224 |
|
---|
225 | /*! \obsolete
|
---|
226 | Constructs a label that displays the text \a text. The label has a
|
---|
227 | buddy widget, \a buddy.
|
---|
228 |
|
---|
229 | If the \a text contains an underlined letter (a letter preceded by
|
---|
230 | an ampersand, \&), when the user presses Alt+ the underlined letter,
|
---|
231 | focus is passed to the buddy widget.
|
---|
232 |
|
---|
233 | The \a parent, \a name and widget flag, \a f, arguments are passed
|
---|
234 | to the QFrame constructor.
|
---|
235 |
|
---|
236 | \sa setText(), setBuddy(), setAlignment(), setFrameStyle(),
|
---|
237 | setIndent()
|
---|
238 | */
|
---|
239 | QLabel::QLabel(QWidget *buddy, const QString &text,
|
---|
240 | QWidget *parent, const char *name, Qt::WindowFlags f)
|
---|
241 | : QFrame(*new QLabelPrivate(), parent, f)
|
---|
242 | {
|
---|
243 | Q_D(QLabel);
|
---|
244 | if (name)
|
---|
245 | setObjectName(QString::fromAscii(name));
|
---|
246 | d->init();
|
---|
247 | #ifndef QT_NO_SHORTCUT
|
---|
248 | setBuddy(buddy);
|
---|
249 | #endif
|
---|
250 | setText(text);
|
---|
251 | }
|
---|
252 | #endif //QT3_SUPPORT
|
---|
253 |
|
---|
254 | /*!
|
---|
255 | Destroys the label.
|
---|
256 | */
|
---|
257 |
|
---|
258 | QLabel::~QLabel()
|
---|
259 | {
|
---|
260 | Q_D(QLabel);
|
---|
261 | d->clearContents();
|
---|
262 | }
|
---|
263 |
|
---|
264 | void QLabelPrivate::init()
|
---|
265 | {
|
---|
266 | Q_Q(QLabel);
|
---|
267 |
|
---|
268 | valid_hints = false;
|
---|
269 | margin = 0;
|
---|
270 | #ifndef QT_NO_MOVIE
|
---|
271 | movie = 0;
|
---|
272 | #endif
|
---|
273 | #ifndef QT_NO_SHORTCUT
|
---|
274 | shortcutId = 0;
|
---|
275 | #endif
|
---|
276 | pixmap = 0;
|
---|
277 | scaledpixmap = 0;
|
---|
278 | cachedimage = 0;
|
---|
279 | #ifndef QT_NO_PICTURE
|
---|
280 | picture = 0;
|
---|
281 | #endif
|
---|
282 | align = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextExpandTabs;
|
---|
283 | indent = -1;
|
---|
284 | scaledcontents = false;
|
---|
285 | textLayoutDirty = false;
|
---|
286 | textDirty = false;
|
---|
287 | textformat = Qt::AutoText;
|
---|
288 | control = 0;
|
---|
289 | textInteractionFlags = Qt::LinksAccessibleByMouse;
|
---|
290 | isRichText = false;
|
---|
291 | isTextLabel = false;
|
---|
292 |
|
---|
293 | q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred,
|
---|
294 | QSizePolicy::Label));
|
---|
295 |
|
---|
296 | #ifndef QT_NO_CURSOR
|
---|
297 | validCursor = false;
|
---|
298 | onAnchor = false;
|
---|
299 | #endif
|
---|
300 |
|
---|
301 | openExternalLinks = false;
|
---|
302 |
|
---|
303 | setLayoutItemMargins(QStyle::SE_LabelLayoutItem);
|
---|
304 | }
|
---|
305 |
|
---|
306 |
|
---|
307 | /*!
|
---|
308 | \property QLabel::text
|
---|
309 | \brief the label's text
|
---|
310 |
|
---|
311 | If no text has been set this will return an empty string. Setting
|
---|
312 | the text clears any previous content.
|
---|
313 |
|
---|
314 | The text will be interpreted either as plain text or as rich
|
---|
315 | text, depending on the text format setting; see setTextFormat().
|
---|
316 | The default setting is Qt::AutoText; i.e. QLabel will try to
|
---|
317 | auto-detect the format of the text set.
|
---|
318 |
|
---|
319 | If a buddy has been set, the buddy mnemonic key is updated
|
---|
320 | from the new text.
|
---|
321 |
|
---|
322 | Note that QLabel is well-suited to display small rich text
|
---|
323 | documents, such as small documents that get their document
|
---|
324 | specific settings (font, text color, link color) from the label's
|
---|
325 | palette and font properties. For large documents, use QTextEdit
|
---|
326 | in read-only mode instead. QTextEdit can also provide a scroll bar
|
---|
327 | when necessary.
|
---|
328 |
|
---|
329 | \note This function enables mouse tracking if \a text contains rich
|
---|
330 | text.
|
---|
331 |
|
---|
332 | \sa setTextFormat(), setBuddy(), alignment
|
---|
333 | */
|
---|
334 |
|
---|
335 | void QLabel::setText(const QString &text)
|
---|
336 | {
|
---|
337 | Q_D(QLabel);
|
---|
338 | if (d->text == text)
|
---|
339 | return;
|
---|
340 |
|
---|
341 | QTextControl *oldControl = d->control;
|
---|
342 | d->control = 0;
|
---|
343 |
|
---|
344 | d->clearContents();
|
---|
345 | d->text = text;
|
---|
346 | d->isTextLabel = true;
|
---|
347 | d->textDirty = true;
|
---|
348 | d->isRichText = d->textformat == Qt::RichText
|
---|
349 | || (d->textformat == Qt::AutoText && Qt::mightBeRichText(d->text));
|
---|
350 |
|
---|
351 | d->control = oldControl;
|
---|
352 |
|
---|
353 | if (d->needTextControl()) {
|
---|
354 | d->ensureTextControl();
|
---|
355 | } else {
|
---|
356 | delete d->control;
|
---|
357 | d->control = 0;
|
---|
358 | }
|
---|
359 |
|
---|
360 | if (d->isRichText) {
|
---|
361 | setMouseTracking(true);
|
---|
362 | } else {
|
---|
363 | // Note: mouse tracking not disabled intentionally
|
---|
364 | }
|
---|
365 |
|
---|
366 | #ifndef QT_NO_SHORTCUT
|
---|
367 | if (d->buddy)
|
---|
368 | d->updateShortcut();
|
---|
369 | #endif
|
---|
370 |
|
---|
371 | d->updateLabel();
|
---|
372 | }
|
---|
373 |
|
---|
374 | QString QLabel::text() const
|
---|
375 | {
|
---|
376 | Q_D(const QLabel);
|
---|
377 | return d->text;
|
---|
378 | }
|
---|
379 |
|
---|
380 | /*!
|
---|
381 | Clears any label contents.
|
---|
382 | */
|
---|
383 |
|
---|
384 | void QLabel::clear()
|
---|
385 | {
|
---|
386 | Q_D(QLabel);
|
---|
387 | d->clearContents();
|
---|
388 | d->updateLabel();
|
---|
389 | }
|
---|
390 |
|
---|
391 | /*!
|
---|
392 | \property QLabel::pixmap
|
---|
393 | \brief the label's pixmap
|
---|
394 |
|
---|
395 | If no pixmap has been set this will return 0.
|
---|
396 |
|
---|
397 | Setting the pixmap clears any previous content. The buddy
|
---|
398 | shortcut, if any, is disabled.
|
---|
399 | */
|
---|
400 | void QLabel::setPixmap(const QPixmap &pixmap)
|
---|
401 | {
|
---|
402 | Q_D(QLabel);
|
---|
403 | if (!d->pixmap || d->pixmap->cacheKey() != pixmap.cacheKey()) {
|
---|
404 | d->clearContents();
|
---|
405 | d->pixmap = new QPixmap(pixmap);
|
---|
406 | }
|
---|
407 |
|
---|
408 | if (d->pixmap->depth() == 1 && !d->pixmap->mask())
|
---|
409 | d->pixmap->setMask(*((QBitmap *)d->pixmap));
|
---|
410 |
|
---|
411 | d->updateLabel();
|
---|
412 | }
|
---|
413 |
|
---|
414 | const QPixmap *QLabel::pixmap() const
|
---|
415 | {
|
---|
416 | Q_D(const QLabel);
|
---|
417 | return d->pixmap;
|
---|
418 | }
|
---|
419 |
|
---|
420 | #ifndef QT_NO_PICTURE
|
---|
421 | /*!
|
---|
422 | Sets the label contents to \a picture. Any previous content is
|
---|
423 | cleared.
|
---|
424 |
|
---|
425 | The buddy shortcut, if any, is disabled.
|
---|
426 |
|
---|
427 | \sa picture(), setBuddy()
|
---|
428 | */
|
---|
429 |
|
---|
430 | void QLabel::setPicture(const QPicture &picture)
|
---|
431 | {
|
---|
432 | Q_D(QLabel);
|
---|
433 | d->clearContents();
|
---|
434 | d->picture = new QPicture(picture);
|
---|
435 |
|
---|
436 | d->updateLabel();
|
---|
437 | }
|
---|
438 | #endif // QT_NO_PICTURE
|
---|
439 |
|
---|
440 | /*!
|
---|
441 | Sets the label contents to plain text containing the textual
|
---|
442 | representation of integer \a num. Any previous content is cleared.
|
---|
443 | Does nothing if the integer's string representation is the same as
|
---|
444 | the current contents of the label.
|
---|
445 |
|
---|
446 | The buddy shortcut, if any, is disabled.
|
---|
447 |
|
---|
448 | \sa setText(), QString::setNum(), setBuddy()
|
---|
449 | */
|
---|
450 |
|
---|
451 | void QLabel::setNum(int num)
|
---|
452 | {
|
---|
453 | QString str;
|
---|
454 | str.setNum(num);
|
---|
455 | setText(str);
|
---|
456 | }
|
---|
457 |
|
---|
458 | /*!
|
---|
459 | \overload
|
---|
460 |
|
---|
461 | Sets the label contents to plain text containing the textual
|
---|
462 | representation of double \a num. Any previous content is cleared.
|
---|
463 | Does nothing if the double's string representation is the same as
|
---|
464 | the current contents of the label.
|
---|
465 |
|
---|
466 | The buddy shortcut, if any, is disabled.
|
---|
467 |
|
---|
468 | \sa setText(), QString::setNum(), setBuddy()
|
---|
469 | */
|
---|
470 |
|
---|
471 | void QLabel::setNum(double num)
|
---|
472 | {
|
---|
473 | QString str;
|
---|
474 | str.setNum(num);
|
---|
475 | setText(str);
|
---|
476 | }
|
---|
477 |
|
---|
478 | /*!
|
---|
479 | \property QLabel::alignment
|
---|
480 | \brief the alignment of the label's contents
|
---|
481 |
|
---|
482 | By default, the contents of the label are left-aligned and vertically-centered.
|
---|
483 |
|
---|
484 | \sa text
|
---|
485 | */
|
---|
486 |
|
---|
487 | void QLabel::setAlignment(Qt::Alignment alignment)
|
---|
488 | {
|
---|
489 | Q_D(QLabel);
|
---|
490 | if (alignment == (d->align & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask)))
|
---|
491 | return;
|
---|
492 | d->align = (d->align & ~(Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask))
|
---|
493 | | (alignment & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask));
|
---|
494 |
|
---|
495 | d->updateLabel();
|
---|
496 | }
|
---|
497 |
|
---|
498 | #ifdef QT3_SUPPORT
|
---|
499 | /*!
|
---|
500 | Use setAlignment(Qt::Alignment) instead.
|
---|
501 |
|
---|
502 | If \a alignment specifies text flags as well, use setTextFormat()
|
---|
503 | to set those.
|
---|
504 | */
|
---|
505 | void QLabel::setAlignment(int alignment)
|
---|
506 | {
|
---|
507 | Q_D(QLabel);
|
---|
508 | d->align = alignment & ~(Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask|Qt::TextWordWrap);
|
---|
509 | setAlignment(Qt::Alignment(QFlag(alignment)));
|
---|
510 | }
|
---|
511 | #endif
|
---|
512 |
|
---|
513 | Qt::Alignment QLabel::alignment() const
|
---|
514 | {
|
---|
515 | Q_D(const QLabel);
|
---|
516 | return QFlag(d->align & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask));
|
---|
517 | }
|
---|
518 |
|
---|
519 |
|
---|
520 | /*!
|
---|
521 | \property QLabel::wordWrap
|
---|
522 | \brief the label's word-wrapping policy
|
---|
523 |
|
---|
524 | If this property is true then label text is wrapped where
|
---|
525 | necessary at word-breaks; otherwise it is not wrapped at all.
|
---|
526 |
|
---|
527 | By default, word wrap is disabled.
|
---|
528 |
|
---|
529 | \sa text
|
---|
530 | */
|
---|
531 | void QLabel::setWordWrap(bool on)
|
---|
532 | {
|
---|
533 | Q_D(QLabel);
|
---|
534 | if (on)
|
---|
535 | d->align |= Qt::TextWordWrap;
|
---|
536 | else
|
---|
537 | d->align &= ~Qt::TextWordWrap;
|
---|
538 |
|
---|
539 | d->updateLabel();
|
---|
540 | }
|
---|
541 |
|
---|
542 | bool QLabel::wordWrap() const
|
---|
543 | {
|
---|
544 | Q_D(const QLabel);
|
---|
545 | return d->align & Qt::TextWordWrap;
|
---|
546 | }
|
---|
547 |
|
---|
548 | /*!
|
---|
549 | \property QLabel::indent
|
---|
550 | \brief the label's text indent in pixels
|
---|
551 |
|
---|
552 | If a label displays text, the indent applies to the left edge if
|
---|
553 | alignment() is Qt::AlignLeft, to the right edge if alignment() is
|
---|
554 | Qt::AlignRight, to the top edge if alignment() is Qt::AlignTop, and
|
---|
555 | to to the bottom edge if alignment() is Qt::AlignBottom.
|
---|
556 |
|
---|
557 | If indent is negative, or if no indent has been set, the label
|
---|
558 | computes the effective indent as follows: If frameWidth() is 0,
|
---|
559 | the effective indent becomes 0. If frameWidth() is greater than 0,
|
---|
560 | the effective indent becomes half the width of the "x" character
|
---|
561 | of the widget's current font().
|
---|
562 |
|
---|
563 | By default, the indent is -1, meaning that an effective indent is
|
---|
564 | calculating in the manner described above.
|
---|
565 |
|
---|
566 | \sa alignment, margin, frameWidth(), font()
|
---|
567 | */
|
---|
568 |
|
---|
569 | void QLabel::setIndent(int indent)
|
---|
570 | {
|
---|
571 | Q_D(QLabel);
|
---|
572 | d->indent = indent;
|
---|
573 | d->updateLabel();
|
---|
574 | }
|
---|
575 |
|
---|
576 | int QLabel::indent() const
|
---|
577 | {
|
---|
578 | Q_D(const QLabel);
|
---|
579 | return d->indent;
|
---|
580 | }
|
---|
581 |
|
---|
582 |
|
---|
583 | /*!
|
---|
584 | \property QLabel::margin
|
---|
585 | \brief the width of the margin
|
---|
586 |
|
---|
587 | The margin is the distance between the innermost pixel of the
|
---|
588 | frame and the outermost pixel of contents.
|
---|
589 |
|
---|
590 | The default margin is 0.
|
---|
591 |
|
---|
592 | \sa indent
|
---|
593 | */
|
---|
594 | int QLabel::margin() const
|
---|
595 | {
|
---|
596 | Q_D(const QLabel);
|
---|
597 | return d->margin;
|
---|
598 | }
|
---|
599 |
|
---|
600 | void QLabel::setMargin(int margin)
|
---|
601 | {
|
---|
602 | Q_D(QLabel);
|
---|
603 | if (d->margin == margin)
|
---|
604 | return;
|
---|
605 | d->margin = margin;
|
---|
606 | d->updateLabel();
|
---|
607 | }
|
---|
608 |
|
---|
609 | /*!
|
---|
610 | Returns the size that will be used if the width of the label is \a
|
---|
611 | w. If \a w is -1, the sizeHint() is returned. If \a w is 0 minimumSizeHint() is returned
|
---|
612 | */
|
---|
613 | QSize QLabelPrivate::sizeForWidth(int w) const
|
---|
614 | {
|
---|
615 | Q_Q(const QLabel);
|
---|
616 | if(q->minimumWidth() > 0)
|
---|
617 | w = qMax(w, q->minimumWidth());
|
---|
618 | QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin);
|
---|
619 |
|
---|
620 | QRect br;
|
---|
621 |
|
---|
622 | int hextra = 2 * margin;
|
---|
623 | int vextra = hextra;
|
---|
624 | QFontMetrics fm = q->fontMetrics();
|
---|
625 |
|
---|
626 | if (pixmap && !pixmap->isNull())
|
---|
627 | br = pixmap->rect();
|
---|
628 | #ifndef QT_NO_PICTURE
|
---|
629 | else if (picture && !picture->isNull())
|
---|
630 | br = picture->boundingRect();
|
---|
631 | #endif
|
---|
632 | #ifndef QT_NO_MOVIE
|
---|
633 | else if (movie && !movie->currentPixmap().isNull())
|
---|
634 | br = movie->currentPixmap().rect();
|
---|
635 | #endif
|
---|
636 | else if (isTextLabel) {
|
---|
637 | int align = QStyle::visualAlignment(q->layoutDirection(), QFlag(this->align));
|
---|
638 | // Add indentation
|
---|
639 | int m = indent;
|
---|
640 |
|
---|
641 | if (m < 0 && q->frameWidth()) // no indent, but we do have a frame
|
---|
642 | m = fm.width(QLatin1Char('x')) - margin*2;
|
---|
643 | if (m > 0) {
|
---|
644 | if ((align & Qt::AlignLeft) || (align & Qt::AlignRight))
|
---|
645 | hextra += m;
|
---|
646 | if ((align & Qt::AlignTop) || (align & Qt::AlignBottom))
|
---|
647 | vextra += m;
|
---|
648 | }
|
---|
649 |
|
---|
650 | if (control) {
|
---|
651 | ensureTextLayouted();
|
---|
652 | const qreal oldTextWidth = control->textWidth();
|
---|
653 | // Calculate the length of document if w is the width
|
---|
654 | if (align & Qt::TextWordWrap) {
|
---|
655 | if (w >= 0) {
|
---|
656 | w = qMax(w-hextra-contentsMargin.width(), 0); // strip margin and indent
|
---|
657 | control->setTextWidth(w);
|
---|
658 | } else {
|
---|
659 | control->adjustSize();
|
---|
660 | }
|
---|
661 | } else {
|
---|
662 | control->setTextWidth(-1);
|
---|
663 | }
|
---|
664 | br = QRect(QPoint(0, 0), control->size().toSize());
|
---|
665 |
|
---|
666 | // restore state
|
---|
667 | control->setTextWidth(oldTextWidth);
|
---|
668 | } else {
|
---|
669 | // Turn off center alignment in order to avoid rounding errors for centering,
|
---|
670 | // since centering involves a division by 2. At the end, all we want is the size.
|
---|
671 | int flags = align & ~(Qt::AlignVCenter | Qt::AlignHCenter);
|
---|
672 | if (hasShortcut) {
|
---|
673 | flags |= Qt::TextShowMnemonic;
|
---|
674 | QStyleOption opt;
|
---|
675 | opt.initFrom(q);
|
---|
676 | if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q))
|
---|
677 | flags |= Qt::TextHideMnemonic;
|
---|
678 | }
|
---|
679 |
|
---|
680 | bool tryWidth = (w < 0) && (align & Qt::TextWordWrap);
|
---|
681 | if (tryWidth)
|
---|
682 | w = fm.averageCharWidth() * 80;
|
---|
683 | else if (w < 0)
|
---|
684 | w = 2000;
|
---|
685 | w -= (hextra + contentsMargin.width());
|
---|
686 | br = fm.boundingRect(0, 0, w ,2000, flags, text);
|
---|
687 | if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2)
|
---|
688 | br = fm.boundingRect(0, 0, w/2, 2000, flags, text);
|
---|
689 | if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4)
|
---|
690 | br = fm.boundingRect(0, 0, w/4, 2000, flags, text);
|
---|
691 | }
|
---|
692 | } else {
|
---|
693 | br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing()));
|
---|
694 | }
|
---|
695 |
|
---|
696 | const QSize contentsSize(br.width() + hextra, br.height() + vextra);
|
---|
697 | return (contentsSize + contentsMargin).expandedTo(q->minimumSize());
|
---|
698 | }
|
---|
699 |
|
---|
700 |
|
---|
701 | /*!
|
---|
702 | \reimp
|
---|
703 | */
|
---|
704 |
|
---|
705 | int QLabel::heightForWidth(int w) const
|
---|
706 | {
|
---|
707 | Q_D(const QLabel);
|
---|
708 | if (d->isTextLabel)
|
---|
709 | return d->sizeForWidth(w).height();
|
---|
710 | return QWidget::heightForWidth(w);
|
---|
711 | }
|
---|
712 |
|
---|
713 | /*!
|
---|
714 | \property QLabel::openExternalLinks
|
---|
715 | \since 4.2
|
---|
716 |
|
---|
717 | Specifies whether QLabel should automatically open links using
|
---|
718 | QDesktopServices::openUrl() instead of emitting the
|
---|
719 | linkActivated() signal.
|
---|
720 |
|
---|
721 | \bold{Note:} The textInteractionFlags set on the label need to include
|
---|
722 | either LinksAccessibleByMouse or LinksAccessibleByKeyboard.
|
---|
723 |
|
---|
724 | The default value is false.
|
---|
725 |
|
---|
726 | \sa textInteractionFlags()
|
---|
727 | */
|
---|
728 | bool QLabel::openExternalLinks() const
|
---|
729 | {
|
---|
730 | Q_D(const QLabel);
|
---|
731 | return d->openExternalLinks;
|
---|
732 | }
|
---|
733 |
|
---|
734 | void QLabel::setOpenExternalLinks(bool open)
|
---|
735 | {
|
---|
736 | Q_D(QLabel);
|
---|
737 | d->openExternalLinks = open;
|
---|
738 | if (d->control)
|
---|
739 | d->control->setOpenExternalLinks(open);
|
---|
740 | }
|
---|
741 |
|
---|
742 | /*!
|
---|
743 | \property QLabel::textInteractionFlags
|
---|
744 | \since 4.2
|
---|
745 |
|
---|
746 | Specifies how the label should interact with user input if it displays text.
|
---|
747 |
|
---|
748 | If the flags contain Qt::LinksAccessibleByKeyboard the focus policy is also
|
---|
749 | automatically set to Qt::StrongFocus. If Qt::TextSelectableByKeyboard is set
|
---|
750 | then the focus policy is set to Qt::ClickFocus.
|
---|
751 |
|
---|
752 | The default value is Qt::LinksAccessibleByMouse.
|
---|
753 | */
|
---|
754 | void QLabel::setTextInteractionFlags(Qt::TextInteractionFlags flags)
|
---|
755 | {
|
---|
756 | Q_D(QLabel);
|
---|
757 | if (d->textInteractionFlags == flags)
|
---|
758 | return;
|
---|
759 | d->textInteractionFlags = flags;
|
---|
760 | if (flags & Qt::LinksAccessibleByKeyboard)
|
---|
761 | setFocusPolicy(Qt::StrongFocus);
|
---|
762 | else if (flags & (Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse))
|
---|
763 | setFocusPolicy(Qt::ClickFocus);
|
---|
764 | else
|
---|
765 | setFocusPolicy(Qt::NoFocus);
|
---|
766 |
|
---|
767 | if (d->needTextControl()) {
|
---|
768 | d->ensureTextControl();
|
---|
769 | } else {
|
---|
770 | delete d->control;
|
---|
771 | d->control = 0;
|
---|
772 | }
|
---|
773 |
|
---|
774 | if (d->control)
|
---|
775 | d->control->setTextInteractionFlags(d->textInteractionFlags);
|
---|
776 | }
|
---|
777 |
|
---|
778 | Qt::TextInteractionFlags QLabel::textInteractionFlags() const
|
---|
779 | {
|
---|
780 | Q_D(const QLabel);
|
---|
781 | return d->textInteractionFlags;
|
---|
782 | }
|
---|
783 |
|
---|
784 | /*!\reimp
|
---|
785 | */
|
---|
786 | QSize QLabel::sizeHint() const
|
---|
787 | {
|
---|
788 | Q_D(const QLabel);
|
---|
789 | if (!d->valid_hints)
|
---|
790 | (void) QLabel::minimumSizeHint();
|
---|
791 | return d->sh;
|
---|
792 | }
|
---|
793 |
|
---|
794 | /*!
|
---|
795 | \reimp
|
---|
796 | */
|
---|
797 | QSize QLabel::minimumSizeHint() const
|
---|
798 | {
|
---|
799 | Q_D(const QLabel);
|
---|
800 | if (d->valid_hints) {
|
---|
801 | if (d->sizePolicy == sizePolicy())
|
---|
802 | return d->msh;
|
---|
803 | }
|
---|
804 |
|
---|
805 | ensurePolished();
|
---|
806 | d->valid_hints = true;
|
---|
807 | d->sh = d->sizeForWidth(-1); // wrap ? golden ratio : min doc size
|
---|
808 | QSize msh(-1, -1);
|
---|
809 |
|
---|
810 | if (!d->isTextLabel) {
|
---|
811 | msh = d->sh;
|
---|
812 | } else {
|
---|
813 | msh.rheight() = d->sizeForWidth(QWIDGETSIZE_MAX).height(); // height for one line
|
---|
814 | msh.rwidth() = d->sizeForWidth(0).width(); // wrap ? size of biggest word : min doc size
|
---|
815 | if (d->sh.height() < msh.height())
|
---|
816 | msh.rheight() = d->sh.height();
|
---|
817 | }
|
---|
818 | d->msh = msh;
|
---|
819 | d->sizePolicy = sizePolicy();
|
---|
820 | return msh;
|
---|
821 | }
|
---|
822 |
|
---|
823 | /*!\reimp
|
---|
824 | */
|
---|
825 | void QLabel::mousePressEvent(QMouseEvent *ev)
|
---|
826 | {
|
---|
827 | Q_D(QLabel);
|
---|
828 | d->sendControlEvent(ev);
|
---|
829 | }
|
---|
830 |
|
---|
831 | /*!\reimp
|
---|
832 | */
|
---|
833 | void QLabel::mouseMoveEvent(QMouseEvent *ev)
|
---|
834 | {
|
---|
835 | Q_D(QLabel);
|
---|
836 | d->sendControlEvent(ev);
|
---|
837 | }
|
---|
838 |
|
---|
839 | /*!\reimp
|
---|
840 | */
|
---|
841 | void QLabel::mouseReleaseEvent(QMouseEvent *ev)
|
---|
842 | {
|
---|
843 | Q_D(QLabel);
|
---|
844 | d->sendControlEvent(ev);
|
---|
845 | }
|
---|
846 |
|
---|
847 | /*!\reimp
|
---|
848 | */
|
---|
849 | void QLabel::contextMenuEvent(QContextMenuEvent *ev)
|
---|
850 | {
|
---|
851 | #ifdef QT_NO_CONTEXTMENU
|
---|
852 | Q_UNUSED(ev);
|
---|
853 | #else
|
---|
854 | Q_D(QLabel);
|
---|
855 | if (!d->isTextLabel) {
|
---|
856 | ev->ignore();
|
---|
857 | return;
|
---|
858 | }
|
---|
859 | QMenu *menu = d->createStandardContextMenu(ev->pos());
|
---|
860 | if (!menu) {
|
---|
861 | ev->ignore();
|
---|
862 | return;
|
---|
863 | }
|
---|
864 | ev->accept();
|
---|
865 | menu->exec(ev->globalPos());
|
---|
866 | delete menu;
|
---|
867 | #endif
|
---|
868 | }
|
---|
869 |
|
---|
870 | /*!
|
---|
871 | \reimp
|
---|
872 | */
|
---|
873 | void QLabel::focusInEvent(QFocusEvent *ev)
|
---|
874 | {
|
---|
875 | Q_D(QLabel);
|
---|
876 | if (d->isTextLabel) {
|
---|
877 | d->ensureTextControl();
|
---|
878 | d->sendControlEvent(ev);
|
---|
879 | }
|
---|
880 | QFrame::focusInEvent(ev);
|
---|
881 | }
|
---|
882 |
|
---|
883 | /*!
|
---|
884 | \reimp
|
---|
885 | */
|
---|
886 | void QLabel::focusOutEvent(QFocusEvent *ev)
|
---|
887 | {
|
---|
888 | Q_D(QLabel);
|
---|
889 | if (d->control) {
|
---|
890 | d->sendControlEvent(ev);
|
---|
891 | QTextCursor cursor = d->control->textCursor();
|
---|
892 | Qt::FocusReason reason = ev->reason();
|
---|
893 | if (reason != Qt::ActiveWindowFocusReason
|
---|
894 | && reason != Qt::PopupFocusReason
|
---|
895 | && cursor.hasSelection()) {
|
---|
896 | cursor.clearSelection();
|
---|
897 | d->control->setTextCursor(cursor);
|
---|
898 | }
|
---|
899 | }
|
---|
900 |
|
---|
901 | QFrame::focusOutEvent(ev);
|
---|
902 | }
|
---|
903 |
|
---|
904 | /*!\reimp
|
---|
905 | */
|
---|
906 | bool QLabel::focusNextPrevChild(bool next)
|
---|
907 | {
|
---|
908 | Q_D(QLabel);
|
---|
909 | if (d->control && d->control->setFocusToNextOrPreviousAnchor(next))
|
---|
910 | return true;
|
---|
911 | return QFrame::focusNextPrevChild(next);
|
---|
912 | }
|
---|
913 |
|
---|
914 | /*!\reimp
|
---|
915 | */
|
---|
916 | void QLabel::keyPressEvent(QKeyEvent *ev)
|
---|
917 | {
|
---|
918 | Q_D(QLabel);
|
---|
919 | d->sendControlEvent(ev);
|
---|
920 | }
|
---|
921 |
|
---|
922 | /*!\reimp
|
---|
923 | */
|
---|
924 | bool QLabel::event(QEvent *e)
|
---|
925 | {
|
---|
926 | Q_D(QLabel);
|
---|
927 | QEvent::Type type = e->type();
|
---|
928 |
|
---|
929 | #ifndef QT_NO_SHORTCUT
|
---|
930 | if (type == QEvent::Shortcut) {
|
---|
931 | QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
|
---|
932 | if (se->shortcutId() == d->shortcutId) {
|
---|
933 | QWidget * w = d->buddy;
|
---|
934 | QAbstractButton *button = qobject_cast<QAbstractButton *>(w);
|
---|
935 | if (w->focusPolicy() != Qt::NoFocus)
|
---|
936 | w->setFocus(Qt::ShortcutFocusReason);
|
---|
937 | if (button && !se->isAmbiguous())
|
---|
938 | button->animateClick();
|
---|
939 | else
|
---|
940 | window()->setAttribute(Qt::WA_KeyboardFocusChange);
|
---|
941 | return true;
|
---|
942 | }
|
---|
943 | } else
|
---|
944 | #endif
|
---|
945 | if (type == QEvent::Resize) {
|
---|
946 | if (d->control)
|
---|
947 | d->textLayoutDirty = true;
|
---|
948 | } else if (e->type() == QEvent::StyleChange
|
---|
949 | #ifdef Q_WS_MAC
|
---|
950 | || e->type() == QEvent::MacSizeChange
|
---|
951 | #endif
|
---|
952 | ) {
|
---|
953 | d->setLayoutItemMargins(QStyle::SE_LabelLayoutItem);
|
---|
954 | d->updateLabel();
|
---|
955 | }
|
---|
956 |
|
---|
957 | return QFrame::event(e);
|
---|
958 | }
|
---|
959 |
|
---|
960 | /*!\reimp
|
---|
961 | */
|
---|
962 | void QLabel::paintEvent(QPaintEvent *)
|
---|
963 | {
|
---|
964 | Q_D(QLabel);
|
---|
965 | QStyle *style = QWidget::style();
|
---|
966 | QPainter painter(this);
|
---|
967 | drawFrame(&painter);
|
---|
968 | QRect cr = contentsRect();
|
---|
969 | cr.adjust(d->margin, d->margin, -d->margin, -d->margin);
|
---|
970 | int align = QStyle::visualAlignment(layoutDirection(), QFlag(d->align));
|
---|
971 |
|
---|
972 | #ifndef QT_NO_MOVIE
|
---|
973 | if (d->movie) {
|
---|
974 | if (d->scaledcontents)
|
---|
975 | style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap().scaled(cr.size()));
|
---|
976 | else
|
---|
977 | style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap());
|
---|
978 | }
|
---|
979 | else
|
---|
980 | #endif
|
---|
981 | if (d->isTextLabel) {
|
---|
982 | QRectF lr = d->layoutRect();
|
---|
983 | QStyleOption opt;
|
---|
984 | opt.initFrom(this);
|
---|
985 | #ifndef QT_NO_STYLE_STYLESHEET
|
---|
986 | if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
|
---|
987 | cssStyle->styleSheetPalette(this, &opt, &opt.palette);
|
---|
988 | }
|
---|
989 | #endif
|
---|
990 | if (d->control) {
|
---|
991 | #ifndef QT_NO_SHORTCUT
|
---|
992 | const bool underline = (bool)style->styleHint(QStyle::SH_UnderlineShortcut, 0, this, 0);
|
---|
993 | if (d->shortcutId != 0
|
---|
994 | && underline != d->shortcutCursor.charFormat().fontUnderline()) {
|
---|
995 | QTextCharFormat fmt;
|
---|
996 | fmt.setFontUnderline(underline);
|
---|
997 | d->shortcutCursor.mergeCharFormat(fmt);
|
---|
998 | }
|
---|
999 | #endif
|
---|
1000 | d->ensureTextLayouted();
|
---|
1001 |
|
---|
1002 | QAbstractTextDocumentLayout::PaintContext context;
|
---|
1003 | if (!isEnabled() && !d->control &&
|
---|
1004 | // We cannot support etched for rich text controls because custom
|
---|
1005 | // colors and links will override the light palette
|
---|
1006 | style->styleHint(QStyle::SH_EtchDisabledText, &opt, this)) {
|
---|
1007 | context.palette = opt.palette;
|
---|
1008 | context.palette.setColor(QPalette::Text, context.palette.light().color());
|
---|
1009 | painter.save();
|
---|
1010 | painter.translate(lr.x() + 1, lr.y() + 1);
|
---|
1011 | painter.setClipRect(lr.translated(-lr.x() - 1, -lr.y() - 1));
|
---|
1012 | QAbstractTextDocumentLayout *layout = d->control->document()->documentLayout();
|
---|
1013 | layout->draw(&painter, context);
|
---|
1014 | painter.restore();
|
---|
1015 | }
|
---|
1016 |
|
---|
1017 | // Adjust the palette
|
---|
1018 | context.palette = opt.palette;
|
---|
1019 |
|
---|
1020 | if (foregroundRole() != QPalette::Text && isEnabled())
|
---|
1021 | context.palette.setColor(QPalette::Text, context.palette.color(foregroundRole()));
|
---|
1022 |
|
---|
1023 | painter.save();
|
---|
1024 | painter.translate(lr.topLeft());
|
---|
1025 | painter.setClipRect(lr.translated(-lr.x(), -lr.y()));
|
---|
1026 | d->control->setPalette(context.palette);
|
---|
1027 | d->control->drawContents(&painter, QRectF(), this);
|
---|
1028 | painter.restore();
|
---|
1029 | } else {
|
---|
1030 | int flags = align;
|
---|
1031 | if (d->hasShortcut) {
|
---|
1032 | flags |= Qt::TextShowMnemonic;
|
---|
1033 | if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt, this))
|
---|
1034 | flags |= Qt::TextHideMnemonic;
|
---|
1035 | }
|
---|
1036 | style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole());
|
---|
1037 | }
|
---|
1038 | } else
|
---|
1039 | #ifndef QT_NO_PICTURE
|
---|
1040 | if (d->picture) {
|
---|
1041 | QRect br = d->picture->boundingRect();
|
---|
1042 | int rw = br.width();
|
---|
1043 | int rh = br.height();
|
---|
1044 | if (d->scaledcontents) {
|
---|
1045 | painter.save();
|
---|
1046 | painter.translate(cr.x(), cr.y());
|
---|
1047 | painter.scale((double)cr.width()/rw, (double)cr.height()/rh);
|
---|
1048 | painter.drawPicture(-br.x(), -br.y(), *d->picture);
|
---|
1049 | painter.restore();
|
---|
1050 | } else {
|
---|
1051 | int xo = 0;
|
---|
1052 | int yo = 0;
|
---|
1053 | if (align & Qt::AlignVCenter)
|
---|
1054 | yo = (cr.height()-rh)/2;
|
---|
1055 | else if (align & Qt::AlignBottom)
|
---|
1056 | yo = cr.height()-rh;
|
---|
1057 | if (align & Qt::AlignRight)
|
---|
1058 | xo = cr.width()-rw;
|
---|
1059 | else if (align & Qt::AlignHCenter)
|
---|
1060 | xo = (cr.width()-rw)/2;
|
---|
1061 | painter.drawPicture(cr.x()+xo-br.x(), cr.y()+yo-br.y(), *d->picture);
|
---|
1062 | }
|
---|
1063 | } else
|
---|
1064 | #endif
|
---|
1065 | if (d->pixmap && !d->pixmap->isNull()) {
|
---|
1066 | QPixmap pix;
|
---|
1067 | if (d->scaledcontents) {
|
---|
1068 | if (!d->scaledpixmap || d->scaledpixmap->size() != cr.size()) {
|
---|
1069 | if (!d->cachedimage)
|
---|
1070 | d->cachedimage = new QImage(d->pixmap->toImage());
|
---|
1071 | delete d->scaledpixmap;
|
---|
1072 | d->scaledpixmap = new QPixmap(QPixmap::fromImage(d->cachedimage->scaled(cr.size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)));
|
---|
1073 | }
|
---|
1074 | pix = *d->scaledpixmap;
|
---|
1075 | } else
|
---|
1076 | pix = *d->pixmap;
|
---|
1077 | QStyleOption opt;
|
---|
1078 | opt.initFrom(this);
|
---|
1079 | if (!isEnabled())
|
---|
1080 | pix = style->generatedIconPixmap(QIcon::Disabled, pix, &opt);
|
---|
1081 | style->drawItemPixmap(&painter, cr, align, pix);
|
---|
1082 | }
|
---|
1083 | }
|
---|
1084 |
|
---|
1085 |
|
---|
1086 | /*!
|
---|
1087 | Updates the label, but not the frame.
|
---|
1088 | */
|
---|
1089 |
|
---|
1090 | void QLabelPrivate::updateLabel()
|
---|
1091 | {
|
---|
1092 | Q_Q(QLabel);
|
---|
1093 | valid_hints = false;
|
---|
1094 |
|
---|
1095 | if (isTextLabel) {
|
---|
1096 | QSizePolicy policy = q->sizePolicy();
|
---|
1097 | const bool wrap = align & Qt::TextWordWrap;
|
---|
1098 | policy.setHeightForWidth(wrap);
|
---|
1099 | if (policy != q->sizePolicy()) // ### should be replaced by WA_WState_OwnSizePolicy idiom
|
---|
1100 | q->setSizePolicy(policy);
|
---|
1101 | textLayoutDirty = true;
|
---|
1102 | }
|
---|
1103 | q->updateGeometry();
|
---|
1104 | q->update(q->contentsRect());
|
---|
1105 | }
|
---|
1106 |
|
---|
1107 | #ifndef QT_NO_SHORTCUT
|
---|
1108 | /*!
|
---|
1109 | Sets this label's buddy to \a buddy.
|
---|
1110 |
|
---|
1111 | When the user presses the shortcut key indicated by this label,
|
---|
1112 | the keyboard focus is transferred to the label's buddy widget.
|
---|
1113 |
|
---|
1114 | The buddy mechanism is only available for QLabels that contain
|
---|
1115 | text in which one character is prefixed with an ampersand, '&'.
|
---|
1116 | This character is set as the shortcut key. See the \l
|
---|
1117 | QKeySequence::mnemonic() documentation for details (to display an
|
---|
1118 | actual ampersand, use '&&').
|
---|
1119 |
|
---|
1120 | In a dialog, you might create two data entry widgets and a label
|
---|
1121 | for each, and set up the geometry layout so each label is just to
|
---|
1122 | the left of its data entry widget (its "buddy"), for example:
|
---|
1123 | \snippet doc/src/snippets/code/src_gui_widgets_qlabel.cpp 2
|
---|
1124 |
|
---|
1125 | With the code above, the focus jumps to the Name field when the
|
---|
1126 | user presses Alt+N, and to the Phone field when the user presses
|
---|
1127 | Alt+P.
|
---|
1128 |
|
---|
1129 | To unset a previously set buddy, call this function with \a buddy
|
---|
1130 | set to 0.
|
---|
1131 |
|
---|
1132 | \sa buddy(), setText(), QShortcut, setAlignment()
|
---|
1133 | */
|
---|
1134 |
|
---|
1135 | void QLabel::setBuddy(QWidget *buddy)
|
---|
1136 | {
|
---|
1137 | Q_D(QLabel);
|
---|
1138 | d->buddy = buddy;
|
---|
1139 | if (d->isTextLabel) {
|
---|
1140 | if (d->shortcutId)
|
---|
1141 | releaseShortcut(d->shortcutId);
|
---|
1142 | d->shortcutId = 0;
|
---|
1143 | d->textDirty = true;
|
---|
1144 | if (buddy)
|
---|
1145 | d->updateShortcut(); // grab new shortcut
|
---|
1146 | d->updateLabel();
|
---|
1147 | }
|
---|
1148 | }
|
---|
1149 |
|
---|
1150 |
|
---|
1151 | /*!
|
---|
1152 | Returns this label's buddy, or 0 if no buddy is currently set.
|
---|
1153 |
|
---|
1154 | \sa setBuddy()
|
---|
1155 | */
|
---|
1156 |
|
---|
1157 | QWidget * QLabel::buddy() const
|
---|
1158 | {
|
---|
1159 | Q_D(const QLabel);
|
---|
1160 | return d->buddy;
|
---|
1161 | }
|
---|
1162 |
|
---|
1163 | void QLabelPrivate::updateShortcut()
|
---|
1164 | {
|
---|
1165 | Q_Q(QLabel);
|
---|
1166 | Q_ASSERT(shortcutId == 0);
|
---|
1167 | // Introduce an extra boolean to indicate the presence of a shortcut in the
|
---|
1168 | // text. We cannot use the shortcutId itself because on the mac mnemonics are
|
---|
1169 | // off by default, so QKeySequence::mnemonic always returns an empty sequence.
|
---|
1170 | // But then we do want to hide the ampersands, so we can't use shortcutId.
|
---|
1171 | hasShortcut = false;
|
---|
1172 |
|
---|
1173 | if (!text.contains(QLatin1Char('&')))
|
---|
1174 | return;
|
---|
1175 | hasShortcut = true;
|
---|
1176 | shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
|
---|
1177 | }
|
---|
1178 |
|
---|
1179 | #endif // QT_NO_SHORTCUT
|
---|
1180 |
|
---|
1181 | #ifndef QT_NO_MOVIE
|
---|
1182 | void QLabelPrivate::_q_movieUpdated(const QRect& rect)
|
---|
1183 | {
|
---|
1184 | Q_Q(QLabel);
|
---|
1185 | if (movie && movie->isValid()) {
|
---|
1186 | QRect r;
|
---|
1187 | if (scaledcontents) {
|
---|
1188 | QRect cr = q->contentsRect();
|
---|
1189 | QRect pixmapRect(cr.topLeft(), movie->currentPixmap().size());
|
---|
1190 | if (pixmapRect.isEmpty())
|
---|
1191 | return;
|
---|
1192 | r.setRect(cr.left(), cr.top(),
|
---|
1193 | (rect.width() * cr.width()) / pixmapRect.width(),
|
---|
1194 | (rect.height() * cr.height()) / pixmapRect.height());
|
---|
1195 | } else {
|
---|
1196 | r = q->style()->itemPixmapRect(q->contentsRect(), align, movie->currentPixmap());
|
---|
1197 | r.translate(rect.x(), rect.y());
|
---|
1198 | r.setWidth(qMin(r.width(), rect.width()));
|
---|
1199 | r.setHeight(qMin(r.height(), rect.height()));
|
---|
1200 | }
|
---|
1201 | q->update(r);
|
---|
1202 | }
|
---|
1203 | }
|
---|
1204 |
|
---|
1205 | void QLabelPrivate::_q_movieResized(const QSize& size)
|
---|
1206 | {
|
---|
1207 | Q_Q(QLabel);
|
---|
1208 | q->update(); //we need to refresh the whole background in case the new size is smaler
|
---|
1209 | valid_hints = false;
|
---|
1210 | _q_movieUpdated(QRect(QPoint(0,0), size));
|
---|
1211 | q->updateGeometry();
|
---|
1212 | }
|
---|
1213 |
|
---|
1214 | /*!
|
---|
1215 | Sets the label contents to \a movie. Any previous content is
|
---|
1216 | cleared. The label does NOT take ownership of the movie.
|
---|
1217 |
|
---|
1218 | The buddy shortcut, if any, is disabled.
|
---|
1219 |
|
---|
1220 | \sa movie(), setBuddy()
|
---|
1221 | */
|
---|
1222 |
|
---|
1223 | void QLabel::setMovie(QMovie *movie)
|
---|
1224 | {
|
---|
1225 | Q_D(QLabel);
|
---|
1226 | d->clearContents();
|
---|
1227 |
|
---|
1228 | if (!movie)
|
---|
1229 | return;
|
---|
1230 |
|
---|
1231 | d->movie = movie;
|
---|
1232 | connect(movie, SIGNAL(resized(QSize)), this, SLOT(_q_movieResized(QSize)));
|
---|
1233 | connect(movie, SIGNAL(updated(QRect)), this, SLOT(_q_movieUpdated(QRect)));
|
---|
1234 |
|
---|
1235 | // Assume that if the movie is running,
|
---|
1236 | // resize/update signals will come soon enough
|
---|
1237 | if (movie->state() != QMovie::Running)
|
---|
1238 | d->updateLabel();
|
---|
1239 | }
|
---|
1240 |
|
---|
1241 | #endif // QT_NO_MOVIE
|
---|
1242 |
|
---|
1243 | /*!
|
---|
1244 | \internal
|
---|
1245 |
|
---|
1246 | Clears any contents, without updating/repainting the label.
|
---|
1247 | */
|
---|
1248 |
|
---|
1249 | void QLabelPrivate::clearContents()
|
---|
1250 | {
|
---|
1251 | delete control;
|
---|
1252 | control = 0;
|
---|
1253 | isTextLabel = false;
|
---|
1254 | hasShortcut = false;
|
---|
1255 |
|
---|
1256 | #ifndef QT_NO_PICTURE
|
---|
1257 | delete picture;
|
---|
1258 | picture = 0;
|
---|
1259 | #endif
|
---|
1260 | delete scaledpixmap;
|
---|
1261 | scaledpixmap = 0;
|
---|
1262 | delete cachedimage;
|
---|
1263 | cachedimage = 0;
|
---|
1264 | delete pixmap;
|
---|
1265 | pixmap = 0;
|
---|
1266 |
|
---|
1267 | text.clear();
|
---|
1268 | Q_Q(QLabel);
|
---|
1269 | #ifndef QT_NO_SHORTCUT
|
---|
1270 | if (shortcutId)
|
---|
1271 | q->releaseShortcut(shortcutId);
|
---|
1272 | shortcutId = 0;
|
---|
1273 | #endif
|
---|
1274 | #ifndef QT_NO_MOVIE
|
---|
1275 | if (movie) {
|
---|
1276 | QObject::disconnect(movie, SIGNAL(resized(QSize)), q, SLOT(_q_movieResized(QSize)));
|
---|
1277 | QObject::disconnect(movie, SIGNAL(updated(QRect)), q, SLOT(_q_movieUpdated(QRect)));
|
---|
1278 | }
|
---|
1279 | movie = 0;
|
---|
1280 | #endif
|
---|
1281 | #ifndef QT_NO_CURSOR
|
---|
1282 | if (onAnchor) {
|
---|
1283 | if (validCursor)
|
---|
1284 | q->setCursor(cursor);
|
---|
1285 | else
|
---|
1286 | q->unsetCursor();
|
---|
1287 | }
|
---|
1288 | validCursor = false;
|
---|
1289 | onAnchor = false;
|
---|
1290 | #endif
|
---|
1291 | }
|
---|
1292 |
|
---|
1293 |
|
---|
1294 | #ifndef QT_NO_MOVIE
|
---|
1295 |
|
---|
1296 | /*!
|
---|
1297 | Returns a pointer to the label's movie, or 0 if no movie has been
|
---|
1298 | set.
|
---|
1299 |
|
---|
1300 | \sa setMovie()
|
---|
1301 | */
|
---|
1302 |
|
---|
1303 | QMovie *QLabel::movie() const
|
---|
1304 | {
|
---|
1305 | Q_D(const QLabel);
|
---|
1306 | return d->movie;
|
---|
1307 | }
|
---|
1308 |
|
---|
1309 | #endif // QT_NO_MOVIE
|
---|
1310 |
|
---|
1311 | /*!
|
---|
1312 | \property QLabel::textFormat
|
---|
1313 | \brief the label's text format
|
---|
1314 |
|
---|
1315 | See the Qt::TextFormat enum for an explanation of the possible
|
---|
1316 | options.
|
---|
1317 |
|
---|
1318 | The default format is Qt::AutoText.
|
---|
1319 |
|
---|
1320 | \sa text()
|
---|
1321 | */
|
---|
1322 |
|
---|
1323 | Qt::TextFormat QLabel::textFormat() const
|
---|
1324 | {
|
---|
1325 | Q_D(const QLabel);
|
---|
1326 | return d->textformat;
|
---|
1327 | }
|
---|
1328 |
|
---|
1329 | void QLabel::setTextFormat(Qt::TextFormat format)
|
---|
1330 | {
|
---|
1331 | Q_D(QLabel);
|
---|
1332 | if (format != d->textformat) {
|
---|
1333 | d->textformat = format;
|
---|
1334 | QString t = d->text;
|
---|
1335 | if (!t.isNull()) {
|
---|
1336 | d->text.clear();
|
---|
1337 | setText(t);
|
---|
1338 | }
|
---|
1339 | }
|
---|
1340 | }
|
---|
1341 |
|
---|
1342 | /*!
|
---|
1343 | \reimp
|
---|
1344 | */
|
---|
1345 | void QLabel::changeEvent(QEvent *ev)
|
---|
1346 | {
|
---|
1347 | Q_D(QLabel);
|
---|
1348 | if(ev->type() == QEvent::FontChange || ev->type() == QEvent::ApplicationFontChange) {
|
---|
1349 | if (d->isTextLabel) {
|
---|
1350 | if (d->control)
|
---|
1351 | d->control->document()->setDefaultFont(font());
|
---|
1352 | d->updateLabel();
|
---|
1353 | }
|
---|
1354 | } else if (ev->type() == QEvent::PaletteChange && d->control) {
|
---|
1355 | d->control->setPalette(palette());
|
---|
1356 | } else if (ev->type() == QEvent::ContentsRectChange) {
|
---|
1357 | d->updateLabel();
|
---|
1358 | } else if (ev->type() == QEvent::LayoutDirectionChange) {
|
---|
1359 | if (d->isTextLabel && d->control) {
|
---|
1360 | d->sendControlEvent(ev);
|
---|
1361 | }
|
---|
1362 | }
|
---|
1363 | QFrame::changeEvent(ev);
|
---|
1364 | }
|
---|
1365 |
|
---|
1366 | /*!
|
---|
1367 | \property QLabel::scaledContents
|
---|
1368 | \brief whether the label will scale its contents to fill all
|
---|
1369 | available space.
|
---|
1370 |
|
---|
1371 | When enabled and the label shows a pixmap, it will scale the
|
---|
1372 | pixmap to fill the available space.
|
---|
1373 |
|
---|
1374 | This property's default is false.
|
---|
1375 | */
|
---|
1376 | bool QLabel::hasScaledContents() const
|
---|
1377 | {
|
---|
1378 | Q_D(const QLabel);
|
---|
1379 | return d->scaledcontents;
|
---|
1380 | }
|
---|
1381 |
|
---|
1382 | void QLabel::setScaledContents(bool enable)
|
---|
1383 | {
|
---|
1384 | Q_D(QLabel);
|
---|
1385 | if ((bool)d->scaledcontents == enable)
|
---|
1386 | return;
|
---|
1387 | d->scaledcontents = enable;
|
---|
1388 | if (!enable) {
|
---|
1389 | delete d->scaledpixmap;
|
---|
1390 | d->scaledpixmap = 0;
|
---|
1391 | delete d->cachedimage;
|
---|
1392 | d->cachedimage = 0;
|
---|
1393 | }
|
---|
1394 | update(contentsRect());
|
---|
1395 | }
|
---|
1396 |
|
---|
1397 |
|
---|
1398 | /*!
|
---|
1399 | \fn void QLabel::setAlignment(Qt::AlignmentFlag flag)
|
---|
1400 | \internal
|
---|
1401 |
|
---|
1402 | Without this function, a call to e.g. setAlignment(Qt::AlignTop)
|
---|
1403 | results in the \c QT3_SUPPORT function setAlignment(int) being called,
|
---|
1404 | rather than setAlignment(Qt::Alignment).
|
---|
1405 | */
|
---|
1406 |
|
---|
1407 | // Returns the rect that is available for us to draw the document
|
---|
1408 | QRect QLabelPrivate::documentRect() const
|
---|
1409 | {
|
---|
1410 | Q_Q(const QLabel);
|
---|
1411 | Q_ASSERT_X(isTextLabel, "documentRect", "document rect called for label that is not a text label!");
|
---|
1412 | QRect cr = q->contentsRect();
|
---|
1413 | cr.adjust(margin, margin, -margin, -margin);
|
---|
1414 | const int align = QStyle::visualAlignment(q->layoutDirection(), QFlag(this->align));
|
---|
1415 | int m = indent;
|
---|
1416 | if (m < 0 && q->frameWidth()) // no indent, but we do have a frame
|
---|
1417 | m = q->fontMetrics().width(QLatin1Char('x')) / 2 - margin;
|
---|
1418 | if (m > 0) {
|
---|
1419 | if (align & Qt::AlignLeft)
|
---|
1420 | cr.setLeft(cr.left() + m);
|
---|
1421 | if (align & Qt::AlignRight)
|
---|
1422 | cr.setRight(cr.right() - m);
|
---|
1423 | if (align & Qt::AlignTop)
|
---|
1424 | cr.setTop(cr.top() + m);
|
---|
1425 | if (align & Qt::AlignBottom)
|
---|
1426 | cr.setBottom(cr.bottom() - m);
|
---|
1427 | }
|
---|
1428 | return cr;
|
---|
1429 | }
|
---|
1430 |
|
---|
1431 | void QLabelPrivate::ensureTextPopulated() const
|
---|
1432 | {
|
---|
1433 | if (!textDirty)
|
---|
1434 | return;
|
---|
1435 | if (control) {
|
---|
1436 | QTextDocument *doc = control->document();
|
---|
1437 | if (textDirty) {
|
---|
1438 | #ifndef QT_NO_TEXTHTMLPARSER
|
---|
1439 | if (isRichText)
|
---|
1440 | doc->setHtml(text);
|
---|
1441 | else
|
---|
1442 | doc->setPlainText(text);
|
---|
1443 | #else
|
---|
1444 | doc->setPlainText(text);
|
---|
1445 | #endif
|
---|
1446 | doc->setUndoRedoEnabled(false);
|
---|
1447 |
|
---|
1448 | #ifndef QT_NO_SHORTCUT
|
---|
1449 | if (hasShortcut) {
|
---|
1450 | // Underline the first character that follows an ampersand (and remove the others ampersands)
|
---|
1451 | int from = 0;
|
---|
1452 | bool found = false;
|
---|
1453 | QTextCursor cursor;
|
---|
1454 | while (!(cursor = control->document()->find((QLatin1String("&")), from)).isNull()) {
|
---|
1455 | cursor.deleteChar(); // remove the ampersand
|
---|
1456 | cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
|
---|
1457 | from = cursor.position();
|
---|
1458 | if (!found && cursor.selectedText() != QLatin1String("&")) { //not a second &
|
---|
1459 | found = true;
|
---|
1460 | shortcutCursor = cursor;
|
---|
1461 | }
|
---|
1462 | }
|
---|
1463 | }
|
---|
1464 | #endif
|
---|
1465 | }
|
---|
1466 | }
|
---|
1467 | textDirty = false;
|
---|
1468 | }
|
---|
1469 |
|
---|
1470 | void QLabelPrivate::ensureTextLayouted() const
|
---|
1471 | {
|
---|
1472 | if (!textLayoutDirty)
|
---|
1473 | return;
|
---|
1474 | ensureTextPopulated();
|
---|
1475 | Q_Q(const QLabel);
|
---|
1476 | if (control) {
|
---|
1477 | QTextDocument *doc = control->document();
|
---|
1478 | QTextOption opt = doc->defaultTextOption();
|
---|
1479 |
|
---|
1480 | opt.setAlignment(QFlag(this->align));
|
---|
1481 |
|
---|
1482 | if (this->align & Qt::TextWordWrap)
|
---|
1483 | opt.setWrapMode(QTextOption::WordWrap);
|
---|
1484 | else
|
---|
1485 | opt.setWrapMode(QTextOption::ManualWrap);
|
---|
1486 |
|
---|
1487 | opt.setTextDirection(q->layoutDirection());
|
---|
1488 |
|
---|
1489 | doc->setDefaultTextOption(opt);
|
---|
1490 |
|
---|
1491 | QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
|
---|
1492 | fmt.setMargin(0);
|
---|
1493 | doc->rootFrame()->setFrameFormat(fmt);
|
---|
1494 | doc->setTextWidth(documentRect().width());
|
---|
1495 | }
|
---|
1496 | textLayoutDirty = false;
|
---|
1497 | }
|
---|
1498 |
|
---|
1499 | void QLabelPrivate::ensureTextControl() const
|
---|
1500 | {
|
---|
1501 | Q_Q(const QLabel);
|
---|
1502 | if (!isTextLabel)
|
---|
1503 | return;
|
---|
1504 | if (!control) {
|
---|
1505 | control = new QTextControl(const_cast<QLabel *>(q));
|
---|
1506 | control->document()->setUndoRedoEnabled(false);
|
---|
1507 | control->document()->setDefaultFont(q->font());
|
---|
1508 | control->setTextInteractionFlags(textInteractionFlags);
|
---|
1509 | control->setOpenExternalLinks(openExternalLinks);
|
---|
1510 | control->setPalette(q->palette());
|
---|
1511 | control->setFocus(q->hasFocus());
|
---|
1512 | QObject::connect(control, SIGNAL(updateRequest(QRectF)),
|
---|
1513 | q, SLOT(update()));
|
---|
1514 | QObject::connect(control, SIGNAL(linkHovered(QString)),
|
---|
1515 | q, SLOT(_q_linkHovered(QString)));
|
---|
1516 | QObject::connect(control, SIGNAL(linkActivated(QString)),
|
---|
1517 | q, SIGNAL(linkActivated(QString)));
|
---|
1518 | textLayoutDirty = true;
|
---|
1519 | textDirty = true;
|
---|
1520 | }
|
---|
1521 | }
|
---|
1522 |
|
---|
1523 | void QLabelPrivate::sendControlEvent(QEvent *e)
|
---|
1524 | {
|
---|
1525 | Q_Q(QLabel);
|
---|
1526 | if (!isTextLabel || !control || textInteractionFlags == Qt::NoTextInteraction) {
|
---|
1527 | e->ignore();
|
---|
1528 | return;
|
---|
1529 | }
|
---|
1530 | control->processEvent(e, -layoutRect().topLeft(), q);
|
---|
1531 | }
|
---|
1532 |
|
---|
1533 | void QLabelPrivate::_q_linkHovered(const QString &anchor)
|
---|
1534 | {
|
---|
1535 | Q_Q(QLabel);
|
---|
1536 | #ifndef QT_NO_CURSOR
|
---|
1537 | if (anchor.isEmpty()) { // restore cursor
|
---|
1538 | if (validCursor)
|
---|
1539 | q->setCursor(cursor);
|
---|
1540 | else
|
---|
1541 | q->unsetCursor();
|
---|
1542 | onAnchor = false;
|
---|
1543 | } else if (!onAnchor) {
|
---|
1544 | validCursor = q->testAttribute(Qt::WA_SetCursor);
|
---|
1545 | if (validCursor) {
|
---|
1546 | cursor = q->cursor();
|
---|
1547 | }
|
---|
1548 | q->setCursor(Qt::PointingHandCursor);
|
---|
1549 | onAnchor = true;
|
---|
1550 | }
|
---|
1551 | #endif
|
---|
1552 | emit q->linkHovered(anchor);
|
---|
1553 | }
|
---|
1554 |
|
---|
1555 | // Return the layout rect - this is the rect that is given to the layout painting code
|
---|
1556 | // This may be different from the document rect since vertical alignment is not
|
---|
1557 | // done by the text layout code
|
---|
1558 | QRectF QLabelPrivate::layoutRect() const
|
---|
1559 | {
|
---|
1560 | QRectF cr = documentRect();
|
---|
1561 | if (!control)
|
---|
1562 | return cr;
|
---|
1563 | ensureTextLayouted();
|
---|
1564 | // Caculate y position manually
|
---|
1565 | qreal rh = control->document()->documentLayout()->documentSize().height();
|
---|
1566 | qreal yo = 0;
|
---|
1567 | if (align & Qt::AlignVCenter)
|
---|
1568 | yo = qMax((cr.height()-rh)/2, qreal(0));
|
---|
1569 | else if (align & Qt::AlignBottom)
|
---|
1570 | yo = qMax(cr.height()-rh, qreal(0));
|
---|
1571 | return QRectF(cr.x(), yo + cr.y(), cr.width(), cr.height());
|
---|
1572 | }
|
---|
1573 |
|
---|
1574 | // Returns the point in the document rect adjusted with p
|
---|
1575 | QPoint QLabelPrivate::layoutPoint(const QPoint& p) const
|
---|
1576 | {
|
---|
1577 | QRect lr = layoutRect().toRect();
|
---|
1578 | return p - lr.topLeft();
|
---|
1579 | }
|
---|
1580 |
|
---|
1581 | #ifndef QT_NO_CONTEXTMENU
|
---|
1582 | QMenu *QLabelPrivate::createStandardContextMenu(const QPoint &pos)
|
---|
1583 | {
|
---|
1584 | QString linkToCopy;
|
---|
1585 | QPoint p;
|
---|
1586 | if (control && isRichText) {
|
---|
1587 | p = layoutPoint(pos);
|
---|
1588 | linkToCopy = control->document()->documentLayout()->anchorAt(p);
|
---|
1589 | }
|
---|
1590 |
|
---|
1591 | if (linkToCopy.isEmpty() && !control)
|
---|
1592 | return 0;
|
---|
1593 |
|
---|
1594 | return control->createStandardContextMenu(p, q_func());
|
---|
1595 | }
|
---|
1596 | #endif
|
---|
1597 |
|
---|
1598 | /*!
|
---|
1599 | \fn void QLabel::linkHovered(const QString &link)
|
---|
1600 | \since 4.2
|
---|
1601 |
|
---|
1602 | This signal is emitted when the user hovers over a link. The URL
|
---|
1603 | referred to by the anchor is passed in \a link.
|
---|
1604 |
|
---|
1605 | \sa linkActivated()
|
---|
1606 | */
|
---|
1607 |
|
---|
1608 |
|
---|
1609 | /*!
|
---|
1610 | \fn void QLabel::linkActivated(const QString &link)
|
---|
1611 | \since 4.2
|
---|
1612 |
|
---|
1613 | This signal is emitted when the user clicks a link. The URL
|
---|
1614 | referred to by the anchor is passed in \a link.
|
---|
1615 |
|
---|
1616 | \sa linkHovered()
|
---|
1617 | */
|
---|
1618 |
|
---|
1619 | QT_END_NAMESPACE
|
---|
1620 |
|
---|
1621 | #include "moc_qlabel.cpp"
|
---|