qlabel.cpp

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

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9