Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | QLabelPrivate::QLabelPrivate() | - |
8 | : QFramePrivate(), | - |
9 | sh(), | - |
10 | msh(), | - |
11 | text(), | - |
12 | pixmap(nullptr), | - |
13 | scaledpixmap(nullptr), | - |
14 | cachedimage(nullptr), | - |
15 | | - |
16 | picture(nullptr), | - |
17 | | - |
18 | | - |
19 | movie(), | - |
20 | | - |
21 | control(nullptr), | - |
22 | shortcutCursor(), | - |
23 | | - |
24 | cursor(), | - |
25 | | - |
26 | | - |
27 | buddy(), | - |
28 | shortcutId(0), | - |
29 | | - |
30 | textformat(Qt::AutoText), | - |
31 | textInteractionFlags(Qt::LinksAccessibleByMouse), | - |
32 | sizePolicy(), | - |
33 | margin(0), | - |
34 | align(Qt::AlignLeft | Qt::AlignVCenter | Qt::TextExpandTabs), | - |
35 | indent(-1), | - |
36 | valid_hints(false), | - |
37 | scaledcontents(false), | - |
38 | textLayoutDirty(false), | - |
39 | textDirty(false), | - |
40 | isRichText(false), | - |
41 | isTextLabel(false), | - |
42 | hasShortcut( ), | - |
43 | | - |
44 | validCursor(false), | - |
45 | onAnchor(false), | - |
46 | | - |
47 | openExternalLinks(false) | - |
48 | { | - |
49 | } | - |
50 | | - |
51 | QLabelPrivate::~QLabelPrivate() | - |
52 | { | - |
53 | } | - |
54 | const QPicture *QLabel::picture() const | - |
55 | { | - |
56 | const QLabelPrivate * const d = d_func(); | - |
57 | return d->picture; | - |
58 | } | - |
59 | QLabel::QLabel(QWidget *parent, Qt::WindowFlags f) | - |
60 | : QFrame(*new QLabelPrivate(), parent, f) | - |
61 | { | - |
62 | QLabelPrivate * const d = d_func(); | - |
63 | d->init(); | - |
64 | } | - |
65 | QLabel::QLabel(const QString &text, QWidget *parent, Qt::WindowFlags f) | - |
66 | : QFrame(*new QLabelPrivate(), parent, f) | - |
67 | { | - |
68 | QLabelPrivate * const d = d_func(); | - |
69 | d->init(); | - |
70 | setText(text); | - |
71 | } | - |
72 | | - |
73 | | - |
74 | | - |
75 | | - |
76 | | - |
77 | | - |
78 | | - |
79 | QLabel::~QLabel() | - |
80 | { | - |
81 | QLabelPrivate * const d = d_func(); | - |
82 | d->clearContents(); | - |
83 | } | - |
84 | | - |
85 | void QLabelPrivate::init() | - |
86 | { | - |
87 | QLabel * const q = q_func(); | - |
88 | | - |
89 | q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, | - |
90 | QSizePolicy::Label)); | - |
91 | setLayoutItemMargins(QStyle::SE_LabelLayoutItem); | - |
92 | } | - |
93 | void QLabel::setText(const QString &text) | - |
94 | { | - |
95 | QLabelPrivate * const d = d_func(); | - |
96 | if (d->text == text) | - |
97 | return; | - |
98 | | - |
99 | QWidgetTextControl *oldControl = d->control; | - |
100 | d->control = 0; | - |
101 | | - |
102 | d->clearContents(); | - |
103 | d->text = text; | - |
104 | d->isTextLabel = true; | - |
105 | d->textDirty = true; | - |
106 | d->isRichText = d->textformat == Qt::RichText | - |
107 | || (d->textformat == Qt::AutoText && Qt::mightBeRichText(d->text)); | - |
108 | | - |
109 | d->control = oldControl; | - |
110 | | - |
111 | if (d->needTextControl()) { | - |
112 | d->ensureTextControl(); | - |
113 | } else { | - |
114 | delete d->control; | - |
115 | d->control = 0; | - |
116 | } | - |
117 | | - |
118 | if (d->isRichText) { | - |
119 | setMouseTracking(true); | - |
120 | } else { | - |
121 | | - |
122 | } | - |
123 | | - |
124 | | - |
125 | if (d->buddy) | - |
126 | d->updateShortcut(); | - |
127 | | - |
128 | | - |
129 | d->updateLabel(); | - |
130 | | - |
131 | | - |
132 | if (accessibleName().isEmpty()) { | - |
133 | QAccessibleEvent event(this, QAccessible::NameChanged); | - |
134 | QAccessible::updateAccessibility(&event); | - |
135 | } | - |
136 | | - |
137 | } | - |
138 | | - |
139 | QString QLabel::text() const | - |
140 | { | - |
141 | const QLabelPrivate * const d = d_func(); | - |
142 | return d->text; | - |
143 | } | - |
144 | | - |
145 | | - |
146 | | - |
147 | | - |
148 | | - |
149 | void QLabel::clear() | - |
150 | { | - |
151 | QLabelPrivate * const d = d_func(); | - |
152 | d->clearContents(); | - |
153 | d->updateLabel(); | - |
154 | } | - |
155 | void QLabel::setPixmap(const QPixmap &pixmap) | - |
156 | { | - |
157 | QLabelPrivate * const d = d_func(); | - |
158 | if (!d->pixmap || d->pixmap->cacheKey() != pixmap.cacheKey()) { | - |
159 | d->clearContents(); | - |
160 | d->pixmap = new QPixmap(pixmap); | - |
161 | } | - |
162 | | - |
163 | if (d->pixmap->depth() == 1 && !d->pixmap->mask()) | - |
164 | d->pixmap->setMask(*((QBitmap *)d->pixmap)); | - |
165 | | - |
166 | d->updateLabel(); | - |
167 | } | - |
168 | | - |
169 | const QPixmap *QLabel::pixmap() const | - |
170 | { | - |
171 | const QLabelPrivate * const d = d_func(); | - |
172 | return d->pixmap; | - |
173 | } | - |
174 | void QLabel::setPicture(const QPicture &picture) | - |
175 | { | - |
176 | QLabelPrivate * const d = d_func(); | - |
177 | d->clearContents(); | - |
178 | d->picture = new QPicture(picture); | - |
179 | | - |
180 | d->updateLabel(); | - |
181 | } | - |
182 | void QLabel::setNum(int num) | - |
183 | { | - |
184 | QString str; | - |
185 | str.setNum(num); | - |
186 | setText(str); | - |
187 | } | - |
188 | void QLabel::setNum(double num) | - |
189 | { | - |
190 | QString str; | - |
191 | str.setNum(num); | - |
192 | setText(str); | - |
193 | } | - |
194 | void QLabel::setAlignment(Qt::Alignment alignment) | - |
195 | { | - |
196 | QLabelPrivate * const d = d_func(); | - |
197 | if (alignment == (d->align & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask))) | - |
198 | return; | - |
199 | d->align = (d->align & ~(Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask)) | - |
200 | | (alignment & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask)); | - |
201 | | - |
202 | d->updateLabel(); | - |
203 | } | - |
204 | | - |
205 | | - |
206 | Qt::Alignment QLabel::alignment() const | - |
207 | { | - |
208 | const QLabelPrivate * const d = d_func(); | - |
209 | return QFlag(d->align & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask)); | - |
210 | } | - |
211 | void QLabel::setWordWrap(bool on) | - |
212 | { | - |
213 | QLabelPrivate * const d = d_func(); | - |
214 | if (on) | - |
215 | d->align |= Qt::TextWordWrap; | - |
216 | else | - |
217 | d->align &= ~Qt::TextWordWrap; | - |
218 | | - |
219 | d->updateLabel(); | - |
220 | } | - |
221 | | - |
222 | bool QLabel::wordWrap() const | - |
223 | { | - |
224 | const QLabelPrivate * const d = d_func(); | - |
225 | return d->align & Qt::TextWordWrap; | - |
226 | } | - |
227 | void QLabel::setIndent(int indent) | - |
228 | { | - |
229 | QLabelPrivate * const d = d_func(); | - |
230 | d->indent = indent; | - |
231 | d->updateLabel(); | - |
232 | } | - |
233 | | - |
234 | int QLabel::indent() const | - |
235 | { | - |
236 | const QLabelPrivate * const d = d_func(); | - |
237 | return d->indent; | - |
238 | } | - |
239 | int QLabel::margin() const | - |
240 | { | - |
241 | const QLabelPrivate * const d = d_func(); | - |
242 | return d->margin; | - |
243 | } | - |
244 | | - |
245 | void QLabel::setMargin(int margin) | - |
246 | { | - |
247 | QLabelPrivate * const d = d_func(); | - |
248 | if (d->margin == margin) | - |
249 | return; | - |
250 | d->margin = margin; | - |
251 | d->updateLabel(); | - |
252 | } | - |
253 | | - |
254 | | - |
255 | | - |
256 | | - |
257 | | - |
258 | QSize QLabelPrivate::sizeForWidth(int w) const | - |
259 | { | - |
260 | const QLabel * const q = q_func(); | - |
261 | if(q->minimumWidth() > 0) | - |
262 | w = qMax(w, q->minimumWidth()); | - |
263 | QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin); | - |
264 | | - |
265 | QRect br; | - |
266 | | - |
267 | int hextra = 2 * margin; | - |
268 | int vextra = hextra; | - |
269 | QFontMetrics fm = q->fontMetrics(); | - |
270 | | - |
271 | if (pixmap && !pixmap->isNull()) { | - |
272 | br = pixmap->rect(); | - |
273 | br.setSize(br.size() / pixmap->devicePixelRatio()); | - |
274 | | - |
275 | } else if (picture && !picture->isNull()) { | - |
276 | br = picture->boundingRect(); | - |
277 | | - |
278 | | - |
279 | } else if (movie && !movie->currentPixmap().isNull()) { | - |
280 | br = movie->currentPixmap().rect(); | - |
281 | br.setSize(br.size() / movie->currentPixmap().devicePixelRatio()); | - |
282 | | - |
283 | } else if (isTextLabel) { | - |
284 | int align = QStyle::visualAlignment(textDirection(), QFlag(this->align)); | - |
285 | | - |
286 | int m = indent; | - |
287 | | - |
288 | if (m < 0 && q->frameWidth()) | - |
289 | m = fm.width(QLatin1Char('x')) - margin*2; | - |
290 | if (m > 0) { | - |
291 | if ((align & Qt::AlignLeft) || (align & Qt::AlignRight)) | - |
292 | hextra += m; | - |
293 | if ((align & Qt::AlignTop) || (align & Qt::AlignBottom)) | - |
294 | vextra += m; | - |
295 | } | - |
296 | | - |
297 | if (control) { | - |
298 | ensureTextLayouted(); | - |
299 | const qreal oldTextWidth = control->textWidth(); | - |
300 | | - |
301 | if (align & Qt::TextWordWrap) { | - |
302 | if (w >= 0) { | - |
303 | w = qMax(w-hextra-contentsMargin.width(), 0); | - |
304 | control->setTextWidth(w); | - |
305 | } else { | - |
306 | control->adjustSize(); | - |
307 | } | - |
308 | } else { | - |
309 | control->setTextWidth(-1); | - |
310 | } | - |
311 | | - |
312 | QSizeF controlSize = control->size(); | - |
313 | br = QRect(QPoint(0, 0), QSize(qCeil(controlSize.width()), qCeil(controlSize.height()))); | - |
314 | | - |
315 | | - |
316 | control->setTextWidth(oldTextWidth); | - |
317 | } else { | - |
318 | | - |
319 | | - |
320 | int flags = align & ~(Qt::AlignVCenter | Qt::AlignHCenter); | - |
321 | if (hasShortcut) { | - |
322 | flags |= Qt::TextShowMnemonic; | - |
323 | QStyleOption opt; | - |
324 | opt.initFrom(q); | - |
325 | if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q)) | - |
326 | flags |= Qt::TextHideMnemonic; | - |
327 | } | - |
328 | | - |
329 | bool tryWidth = (w < 0) && (align & Qt::TextWordWrap); | - |
330 | if (tryWidth) | - |
331 | w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width()); | - |
332 | else if (w < 0) | - |
333 | w = 2000; | - |
334 | w -= (hextra + contentsMargin.width()); | - |
335 | br = fm.boundingRect(0, 0, w ,2000, flags, text); | - |
336 | if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2) | - |
337 | br = fm.boundingRect(0, 0, w/2, 2000, flags, text); | - |
338 | if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4) | - |
339 | br = fm.boundingRect(0, 0, w/4, 2000, flags, text); | - |
340 | } | - |
341 | } else { | - |
342 | br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing())); | - |
343 | } | - |
344 | | - |
345 | const QSize contentsSize(br.width() + hextra, br.height() + vextra); | - |
346 | return (contentsSize + contentsMargin).expandedTo(q->minimumSize()); | - |
347 | } | - |
348 | | - |
349 | | - |
350 | | - |
351 | | - |
352 | | - |
353 | | - |
354 | int QLabel::heightForWidth(int w) const | - |
355 | { | - |
356 | const QLabelPrivate * const d = d_func(); | - |
357 | if (d->isTextLabel) | - |
358 | return d->sizeForWidth(w).height(); | - |
359 | return QWidget::heightForWidth(w); | - |
360 | } | - |
361 | bool QLabel::openExternalLinks() const | - |
362 | { | - |
363 | const QLabelPrivate * const d = d_func(); | - |
364 | return d->openExternalLinks; | - |
365 | } | - |
366 | | - |
367 | void QLabel::setOpenExternalLinks(bool open) | - |
368 | { | - |
369 | QLabelPrivate * const d = d_func(); | - |
370 | d->openExternalLinks = open; | - |
371 | if (d->control) | - |
372 | d->control->setOpenExternalLinks(open); | - |
373 | } | - |
374 | void QLabel::setTextInteractionFlags(Qt::TextInteractionFlags flags) | - |
375 | { | - |
376 | QLabelPrivate * const d = d_func(); | - |
377 | if (d->textInteractionFlags == flags) | - |
378 | return; | - |
379 | d->textInteractionFlags = flags; | - |
380 | if (flags & Qt::LinksAccessibleByKeyboard) | - |
381 | setFocusPolicy(Qt::StrongFocus); | - |
382 | else if (flags & (Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse)) | - |
383 | setFocusPolicy(Qt::ClickFocus); | - |
384 | else | - |
385 | setFocusPolicy(Qt::NoFocus); | - |
386 | | - |
387 | if (d->needTextControl()) { | - |
388 | d->ensureTextControl(); | - |
389 | } else { | - |
390 | delete d->control; | - |
391 | d->control = 0; | - |
392 | } | - |
393 | | - |
394 | if (d->control) | - |
395 | d->control->setTextInteractionFlags(d->textInteractionFlags); | - |
396 | } | - |
397 | | - |
398 | Qt::TextInteractionFlags QLabel::textInteractionFlags() const | - |
399 | { | - |
400 | const QLabelPrivate * const d = d_func(); | - |
401 | return d->textInteractionFlags; | - |
402 | } | - |
403 | void QLabel::setSelection(int start, int length) | - |
404 | { | - |
405 | QLabelPrivate * const d = d_func(); | - |
406 | if (d->control) { | - |
407 | d->ensureTextPopulated(); | - |
408 | QTextCursor cursor = d->control->textCursor(); | - |
409 | cursor.setPosition(start); | - |
410 | cursor.setPosition(start + length, QTextCursor::KeepAnchor); | - |
411 | d->control->setTextCursor(cursor); | - |
412 | } | - |
413 | } | - |
414 | bool QLabel::hasSelectedText() const | - |
415 | { | - |
416 | const QLabelPrivate * const d = d_func(); | - |
417 | if (d->control) | - |
418 | return d->control->textCursor().hasSelection(); | - |
419 | return false; | - |
420 | } | - |
421 | QString QLabel::selectedText() const | - |
422 | { | - |
423 | const QLabelPrivate * const d = d_func(); | - |
424 | if (d->control) | - |
425 | return d->control->textCursor().selectedText(); | - |
426 | return QString(); | - |
427 | } | - |
428 | int QLabel::selectionStart() const | - |
429 | { | - |
430 | const QLabelPrivate * const d = d_func(); | - |
431 | if (d->control && d->control->textCursor().hasSelection()) | - |
432 | return d->control->textCursor().selectionStart(); | - |
433 | return -1; | - |
434 | } | - |
435 | | - |
436 | | - |
437 | | - |
438 | QSize QLabel::sizeHint() const | - |
439 | { | - |
440 | const QLabelPrivate * const d = d_func(); | - |
441 | if (!d->valid_hints) | - |
442 | (void) QLabel::minimumSizeHint(); | - |
443 | return d->sh; | - |
444 | } | - |
445 | | - |
446 | | - |
447 | | - |
448 | | - |
449 | QSize QLabel::minimumSizeHint() const | - |
450 | { | - |
451 | const QLabelPrivate * const d = d_func(); | - |
452 | if (d->valid_hints) { | - |
453 | if (d->sizePolicy == sizePolicy()) | - |
454 | return d->msh; | - |
455 | } | - |
456 | | - |
457 | ensurePolished(); | - |
458 | d->valid_hints = true; | - |
459 | d->sh = d->sizeForWidth(-1); | - |
460 | QSize msh(-1, -1); | - |
461 | | - |
462 | if (!d->isTextLabel) { | - |
463 | msh = d->sh; | - |
464 | } else { | - |
465 | msh.rheight() = d->sizeForWidth(((1<<24)-1)).height(); | - |
466 | msh.rwidth() = d->sizeForWidth(0).width(); | - |
467 | if (d->sh.height() < msh.height()) | - |
468 | msh.rheight() = d->sh.height(); | - |
469 | } | - |
470 | d->msh = msh; | - |
471 | d->sizePolicy = sizePolicy(); | - |
472 | return msh; | - |
473 | } | - |
474 | | - |
475 | | - |
476 | | - |
477 | void QLabel::mousePressEvent(QMouseEvent *ev) | - |
478 | { | - |
479 | QLabelPrivate * const d = d_func(); | - |
480 | d->sendControlEvent(ev); | - |
481 | } | - |
482 | | - |
483 | | - |
484 | | - |
485 | void QLabel::mouseMoveEvent(QMouseEvent *ev) | - |
486 | { | - |
487 | QLabelPrivate * const d = d_func(); | - |
488 | d->sendControlEvent(ev); | - |
489 | } | - |
490 | | - |
491 | | - |
492 | | - |
493 | void QLabel::mouseReleaseEvent(QMouseEvent *ev) | - |
494 | { | - |
495 | QLabelPrivate * const d = d_func(); | - |
496 | d->sendControlEvent(ev); | - |
497 | } | - |
498 | | - |
499 | | - |
500 | | - |
501 | | - |
502 | void QLabel::contextMenuEvent(QContextMenuEvent *ev) | - |
503 | { | - |
504 | QLabelPrivate * const d = d_func(); | - |
505 | if (!d->isTextLabelTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
506 | ev->ignore(); | - |
507 | return; never executed: return; | 0 |
508 | } | - |
509 | QMenu *menu = d->createStandardContextMenu(ev->pos()); | - |
510 | if (!menuTRUE | never evaluated | FALSE | never evaluated |
) { | 0 |
511 | ev->ignore(); | - |
512 | return; never executed: return; | 0 |
513 | } | - |
514 | ev->accept(); | - |
515 | menu->setAttribute(Qt::WA_DeleteOnClose); | - |
516 | menu->popup(ev->globalPos()); | - |
517 | } never executed: end of block | 0 |
518 | | - |
519 | | - |
520 | | - |
521 | | - |
522 | | - |
523 | void QLabel::focusInEvent(QFocusEvent *ev) | - |
524 | { | - |
525 | QLabelPrivate * const d = d_func(); | - |
526 | if (d->isTextLabel) { | - |
527 | d->ensureTextControl(); | - |
528 | d->sendControlEvent(ev); | - |
529 | } | - |
530 | QFrame::focusInEvent(ev); | - |
531 | } | - |
532 | | - |
533 | | - |
534 | | - |
535 | | - |
536 | void QLabel::focusOutEvent(QFocusEvent *ev) | - |
537 | { | - |
538 | QLabelPrivate * const d = d_func(); | - |
539 | if (d->control) { | - |
540 | d->sendControlEvent(ev); | - |
541 | QTextCursor cursor = d->control->textCursor(); | - |
542 | Qt::FocusReason reason = ev->reason(); | - |
543 | if (reason != Qt::ActiveWindowFocusReason | - |
544 | && reason != Qt::PopupFocusReason | - |
545 | && cursor.hasSelection()) { | - |
546 | cursor.clearSelection(); | - |
547 | d->control->setTextCursor(cursor); | - |
548 | } | - |
549 | } | - |
550 | | - |
551 | QFrame::focusOutEvent(ev); | - |
552 | } | - |
553 | | - |
554 | | - |
555 | | - |
556 | bool QLabel::focusNextPrevChild(bool next) | - |
557 | { | - |
558 | QLabelPrivate * const d = d_func(); | - |
559 | if (d->control && d->control->setFocusToNextOrPreviousAnchor(next)) | - |
560 | return true; | - |
561 | return QFrame::focusNextPrevChild(next); | - |
562 | } | - |
563 | | - |
564 | | - |
565 | | - |
566 | void QLabel::keyPressEvent(QKeyEvent *ev) | - |
567 | { | - |
568 | QLabelPrivate * const d = d_func(); | - |
569 | d->sendControlEvent(ev); | - |
570 | } | - |
571 | | - |
572 | | - |
573 | | - |
574 | bool QLabel::event(QEvent *e) | - |
575 | { | - |
576 | QLabelPrivate * const d = d_func(); | - |
577 | QEvent::Type type = e->type(); | - |
578 | | - |
579 | | - |
580 | if (type == QEvent::Shortcut) { | - |
581 | QShortcutEvent *se = static_cast<QShortcutEvent *>(e); | - |
582 | if (se->shortcutId() == d->shortcutId) { | - |
583 | QWidget * w = d->buddy; | - |
584 | QAbstractButton *button = qobject_cast<QAbstractButton *>(w); | - |
585 | if (w->focusPolicy() != Qt::NoFocus) | - |
586 | w->setFocus(Qt::ShortcutFocusReason); | - |
587 | if (button && !se->isAmbiguous()) | - |
588 | button->animateClick(); | - |
589 | else | - |
590 | window()->setAttribute(Qt::WA_KeyboardFocusChange); | - |
591 | return true; | - |
592 | } | - |
593 | } else | - |
594 | | - |
595 | if (type == QEvent::Resize) { | - |
596 | if (d->control) | - |
597 | d->textLayoutDirty = true; | - |
598 | } else if (e->type() == QEvent::StyleChange | - |
599 | | - |
600 | | - |
601 | | - |
602 | ) { | - |
603 | d->setLayoutItemMargins(QStyle::SE_LabelLayoutItem); | - |
604 | d->updateLabel(); | - |
605 | } | - |
606 | | - |
607 | return QFrame::event(e); | - |
608 | } | - |
609 | | - |
610 | | - |
611 | | - |
612 | void QLabel::paintEvent(QPaintEvent *) | - |
613 | { | - |
614 | QLabelPrivate * const d = d_func(); | - |
615 | QStyle *style = QWidget::style(); | - |
616 | QPainter painter(this); | - |
617 | drawFrame(&painter); | - |
618 | QRect cr = contentsRect(); | - |
619 | cr.adjust(d->margin, d->margin, -d->margin, -d->margin); | - |
620 | int align = QStyle::visualAlignment(d->isTextLabel ? d->textDirection() | - |
621 | : layoutDirection(), QFlag(d->align)); | - |
622 | | - |
623 | | - |
624 | if (d->movie) { | - |
625 | if (d->scaledcontents) | - |
626 | style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap().scaled(cr.size())); | - |
627 | else | - |
628 | style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap()); | - |
629 | } | - |
630 | else | - |
631 | | - |
632 | if (d->isTextLabel) { | - |
633 | QRectF lr = d->layoutRect().toAlignedRect(); | - |
634 | QStyleOption opt; | - |
635 | opt.initFrom(this); | - |
636 | | - |
637 | if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) { | - |
638 | cssStyle->styleSheetPalette(this, &opt, &opt.palette); | - |
639 | } | - |
640 | | - |
641 | if (d->control) { | - |
642 | | - |
643 | const bool underline = (bool)style->styleHint(QStyle::SH_UnderlineShortcut, 0, this, 0); | - |
644 | if (d->shortcutId != 0 | - |
645 | && underline != d->shortcutCursor.charFormat().fontUnderline()) { | - |
646 | QTextCharFormat fmt; | - |
647 | fmt.setFontUnderline(underline); | - |
648 | d->shortcutCursor.mergeCharFormat(fmt); | - |
649 | } | - |
650 | | - |
651 | d->ensureTextLayouted(); | - |
652 | | - |
653 | QAbstractTextDocumentLayout::PaintContext context; | - |
654 | | - |
655 | context.palette = opt.palette; | - |
656 | | - |
657 | if (foregroundRole() != QPalette::Text && isEnabled()) | - |
658 | context.palette.setColor(QPalette::Text, context.palette.color(foregroundRole())); | - |
659 | | - |
660 | painter.save(); | - |
661 | painter.translate(lr.topLeft()); | - |
662 | painter.setClipRect(lr.translated(-lr.x(), -lr.y())); | - |
663 | d->control->setPalette(context.palette); | - |
664 | d->control->drawContents(&painter, QRectF(), this); | - |
665 | painter.restore(); | - |
666 | } else { | - |
667 | int flags = align | (d->textDirection() == Qt::LeftToRight ? Qt::TextForceLeftToRight | - |
668 | : Qt::TextForceRightToLeft); | - |
669 | if (d->hasShortcut) { | - |
670 | flags |= Qt::TextShowMnemonic; | - |
671 | if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt, this)) | - |
672 | flags |= Qt::TextHideMnemonic; | - |
673 | } | - |
674 | style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole()); | - |
675 | } | - |
676 | } else | - |
677 | | - |
678 | if (d->picture) { | - |
679 | QRect br = d->picture->boundingRect(); | - |
680 | int rw = br.width(); | - |
681 | int rh = br.height(); | - |
682 | if (d->scaledcontents) { | - |
683 | painter.save(); | - |
684 | painter.translate(cr.x(), cr.y()); | - |
685 | painter.scale((double)cr.width()/rw, (double)cr.height()/rh); | - |
686 | painter.drawPicture(-br.x(), -br.y(), *d->picture); | - |
687 | painter.restore(); | - |
688 | } else { | - |
689 | int xo = 0; | - |
690 | int yo = 0; | - |
691 | if (align & Qt::AlignVCenter) | - |
692 | yo = (cr.height()-rh)/2; | - |
693 | else if (align & Qt::AlignBottom) | - |
694 | yo = cr.height()-rh; | - |
695 | if (align & Qt::AlignRight) | - |
696 | xo = cr.width()-rw; | - |
697 | else if (align & Qt::AlignHCenter) | - |
698 | xo = (cr.width()-rw)/2; | - |
699 | painter.drawPicture(cr.x()+xo-br.x(), cr.y()+yo-br.y(), *d->picture); | - |
700 | } | - |
701 | } else | - |
702 | | - |
703 | if (d->pixmap && !d->pixmap->isNull()) { | - |
704 | QPixmap pix; | - |
705 | if (d->scaledcontents) { | - |
706 | QSize scaledSize = cr.size() * devicePixelRatioF(); | - |
707 | if (!d->scaledpixmap || d->scaledpixmap->size() != scaledSize) { | - |
708 | if (!d->cachedimage) | - |
709 | d->cachedimage = new QImage(d->pixmap->toImage()); | - |
710 | delete d->scaledpixmap; | - |
711 | QImage scaledImage = | - |
712 | d->cachedimage->scaled(scaledSize, | - |
713 | Qt::IgnoreAspectRatio, Qt::SmoothTransformation); | - |
714 | d->scaledpixmap = new QPixmap(QPixmap::fromImage(scaledImage)); | - |
715 | d->scaledpixmap->setDevicePixelRatio(devicePixelRatioF()); | - |
716 | } | - |
717 | pix = *d->scaledpixmap; | - |
718 | } else | - |
719 | pix = *d->pixmap; | - |
720 | QStyleOption opt; | - |
721 | opt.initFrom(this); | - |
722 | if (!isEnabled()) | - |
723 | pix = style->generatedIconPixmap(QIcon::Disabled, pix, &opt); | - |
724 | style->drawItemPixmap(&painter, cr, align, pix); | - |
725 | } | - |
726 | } | - |
727 | | - |
728 | | - |
729 | | - |
730 | | - |
731 | | - |
732 | | - |
733 | void QLabelPrivate::updateLabel() | - |
734 | { | - |
735 | QLabel * const q = q_func(); | - |
736 | valid_hints = false; | - |
737 | | - |
738 | if (isTextLabel) { | - |
739 | QSizePolicy policy = q->sizePolicy(); | - |
740 | const bool wrap = align & Qt::TextWordWrap; | - |
741 | policy.setHeightForWidth(wrap); | - |
742 | if (policy != q->sizePolicy()) | - |
743 | q->setSizePolicy(policy); | - |
744 | textLayoutDirty = true; | - |
745 | } | - |
746 | q->updateGeometry(); | - |
747 | q->update(q->contentsRect()); | - |
748 | } | - |
749 | void QLabel::setBuddy(QWidget *buddy) | - |
750 | { | - |
751 | QLabelPrivate * const d = d_func(); | - |
752 | d->buddy = buddy; | - |
753 | if (d->isTextLabel) { | - |
754 | if (d->shortcutId) | - |
755 | releaseShortcut(d->shortcutId); | - |
756 | d->shortcutId = 0; | - |
757 | d->textDirty = true; | - |
758 | if (buddy) | - |
759 | d->updateShortcut(); | - |
760 | d->updateLabel(); | - |
761 | } | - |
762 | } | - |
763 | QWidget * QLabel::buddy() const | - |
764 | { | - |
765 | const QLabelPrivate * const d = d_func(); | - |
766 | return d->buddy; | - |
767 | } | - |
768 | | - |
769 | void QLabelPrivate::updateShortcut() | - |
770 | { | - |
771 | QLabel * const q = q_func(); | - |
772 | ((!(shortcutId == 0)) ? qt_assert("shortcutId == 0",__FILE__,11981202) : qt_noop()); | - |
773 | | - |
774 | | - |
775 | | - |
776 | | - |
777 | hasShortcut = false; | - |
778 | | - |
779 | if (!text.contains(QLatin1Char('&'))) | - |
780 | return; | - |
781 | hasShortcut = true; | - |
782 | shortcutId = q->grabShortcut(QKeySequence::mnemonic(text)); | - |
783 | } | - |
784 | | - |
785 | | - |
786 | | - |
787 | | - |
788 | void QLabelPrivate::_q_movieUpdated(const QRect& rect) | - |
789 | { | - |
790 | QLabel * const q = q_func(); | - |
791 | if (movie && movie->isValid()) { | - |
792 | QRect r; | - |
793 | if (scaledcontents) { | - |
794 | QRect cr = q->contentsRect(); | - |
795 | QRect pixmapRect(cr.topLeft(), movie->currentPixmap().size()); | - |
796 | if (pixmapRect.isEmpty()) | - |
797 | return; | - |
798 | r.setRect(cr.left(), cr.top(), | - |
799 | (rect.width() * cr.width()) / pixmapRect.width(), | - |
800 | (rect.height() * cr.height()) / pixmapRect.height()); | - |
801 | } else { | - |
802 | r = q->style()->itemPixmapRect(q->contentsRect(), align, movie->currentPixmap()); | - |
803 | r.translate(rect.x(), rect.y()); | - |
804 | r.setWidth(qMin(r.width(), rect.width())); | - |
805 | r.setHeight(qMin(r.height(), rect.height())); | - |
806 | } | - |
807 | q->update(r); | - |
808 | } | - |
809 | } | - |
810 | | - |
811 | void QLabelPrivate::_q_movieResized(const QSize& size) | - |
812 | { | - |
813 | QLabel * const q = q_func(); | - |
814 | q->update(); | - |
815 | valid_hints = false; | - |
816 | _q_movieUpdated(QRect(QPoint(0,0), size)); | - |
817 | q->updateGeometry(); | - |
818 | } | - |
819 | void QLabel::setMovie(QMovie *movie) | - |
820 | { | - |
821 | QLabelPrivate * const d = d_func(); | - |
822 | d->clearContents(); | - |
823 | | - |
824 | if (!movie) | - |
825 | return; | - |
826 | | - |
827 | d->movie = movie; | - |
828 | connect(movie, qFlagLocation("2""resized(QSize)" "\0" __FILE__ ":" "1264""1268"), this, qFlagLocation("1""_q_movieResized(QSize)" "\0" __FILE__ ":" "1264""1268")); | - |
829 | connect(movie, qFlagLocation("2""updated(QRect)" "\0" __FILE__ ":" "1265""1269"), this, qFlagLocation("1""_q_movieUpdated(QRect)" "\0" __FILE__ ":" "1265""1269")); | - |
830 | | - |
831 | | - |
832 | | - |
833 | if (movie->state() != QMovie::Running) | - |
834 | d->updateLabel(); | - |
835 | } | - |
836 | void QLabelPrivate::clearContents() | - |
837 | { | - |
838 | delete control; | - |
839 | control = 0; | - |
840 | isTextLabel = false; | - |
841 | hasShortcut = false; | - |
842 | | - |
843 | | - |
844 | delete picture; | - |
845 | picture = 0; | - |
846 | | - |
847 | delete scaledpixmap; | - |
848 | scaledpixmap = 0; | - |
849 | delete cachedimage; | - |
850 | cachedimage = 0; | - |
851 | delete pixmap; | - |
852 | pixmap = 0; | - |
853 | | - |
854 | text.clear(); | - |
855 | QLabel * const q = q_func(); | - |
856 | | - |
857 | if (shortcutId) | - |
858 | q->releaseShortcut(shortcutId); | - |
859 | shortcutId = 0; | - |
860 | | - |
861 | | - |
862 | if (movie) { | - |
863 | QObject::disconnect(movie, qFlagLocation("2""resized(QSize)" "\0" __FILE__ ":" "1308""1312"), q, qFlagLocation("1""_q_movieResized(QSize)" "\0" __FILE__ ":" "1308""1312")); | - |
864 | QObject::disconnect(movie, qFlagLocation("2""updated(QRect)" "\0" __FILE__ ":" "1309""1313"), q, qFlagLocation("1""_q_movieUpdated(QRect)" "\0" __FILE__ ":" "1309""1313")); | - |
865 | } | - |
866 | movie = 0; | - |
867 | | - |
868 | | - |
869 | if (onAnchor) { | - |
870 | if (validCursor) | - |
871 | q->setCursor(cursor); | - |
872 | else | - |
873 | q->unsetCursor(); | - |
874 | } | - |
875 | validCursor = false; | - |
876 | onAnchor = false; | - |
877 | | - |
878 | } | - |
879 | QMovie *QLabel::movie() const | - |
880 | { | - |
881 | const QLabelPrivate * const d = d_func(); | - |
882 | return d->movie; | - |
883 | } | - |
884 | Qt::TextFormat QLabel::textFormat() const | - |
885 | { | - |
886 | const QLabelPrivate * const d = d_func(); | - |
887 | return d->textformat; | - |
888 | } | - |
889 | | - |
890 | void QLabel::setTextFormat(Qt::TextFormat format) | - |
891 | { | - |
892 | QLabelPrivate * const d = d_func(); | - |
893 | if (format != d->textformat) { | - |
894 | d->textformat = format; | - |
895 | QString t = d->text; | - |
896 | if (!t.isNull()) { | - |
897 | d->text.clear(); | - |
898 | setText(t); | - |
899 | } | - |
900 | } | - |
901 | } | - |
902 | | - |
903 | | - |
904 | | - |
905 | | - |
906 | void QLabel::changeEvent(QEvent *ev) | - |
907 | { | - |
908 | QLabelPrivate * const d = d_func(); | - |
909 | if(ev->type() == QEvent::FontChange || ev->type() == QEvent::ApplicationFontChange) { | - |
910 | if (d->isTextLabel) { | - |
911 | if (d->control) | - |
912 | d->control->document()->setDefaultFont(font()); | - |
913 | d->updateLabel(); | - |
914 | } | - |
915 | } else if (ev->type() == QEvent::PaletteChange && d->control) { | - |
916 | d->control->setPalette(palette()); | - |
917 | } else if (ev->type() == QEvent::ContentsRectChange) { | - |
918 | d->updateLabel(); | - |
919 | } | - |
920 | QFrame::changeEvent(ev); | - |
921 | } | - |
922 | bool QLabel::hasScaledContents() const | - |
923 | { | - |
924 | const QLabelPrivate * const d = d_func(); | - |
925 | return d->scaledcontents; | - |
926 | } | - |
927 | | - |
928 | void QLabel::setScaledContents(bool enable) | - |
929 | { | - |
930 | QLabelPrivate * const d = d_func(); | - |
931 | if ((bool)d->scaledcontents == enable) | - |
932 | return; | - |
933 | d->scaledcontents = enable; | - |
934 | if (!enable) { | - |
935 | delete d->scaledpixmap; | - |
936 | d->scaledpixmap = 0; | - |
937 | delete d->cachedimage; | - |
938 | d->cachedimage = 0; | - |
939 | } | - |
940 | update(contentsRect()); | - |
941 | } | - |
942 | | - |
943 | Qt::LayoutDirection QLabelPrivate::textDirection() const | - |
944 | { | - |
945 | if (control) { | - |
946 | QTextOption opt = control->document()->defaultTextOption(); | - |
947 | return opt.textDirection(); | - |
948 | } | - |
949 | | - |
950 | return text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; | - |
951 | } | - |
952 | | - |
953 | | - |
954 | | - |
955 | QRect QLabelPrivate::documentRect() const | - |
956 | { | - |
957 | const QLabel * const q = q_func(); | - |
958 | ((!(isTextLabel)) ? qt_assert_x("documentRect", "document rect called for label that is not a text label!",__FILE__,14401444) : qt_noop()); | - |
959 | QRect cr = q->contentsRect(); | - |
960 | cr.adjust(margin, margin, -margin, -margin); | - |
961 | const int align = QStyle::visualAlignment(isTextLabel ? textDirection() | - |
962 | : q->layoutDirection(), QFlag(this->align)); | - |
963 | int m = indent; | - |
964 | if (m < 0 && q->frameWidth()) | - |
965 | m = q->fontMetrics().width(QLatin1Char('x')) / 2 - margin; | - |
966 | if (m > 0) { | - |
967 | if (align & Qt::AlignLeft) | - |
968 | cr.setLeft(cr.left() + m); | - |
969 | if (align & Qt::AlignRight) | - |
970 | cr.setRight(cr.right() - m); | - |
971 | if (align & Qt::AlignTop) | - |
972 | cr.setTop(cr.top() + m); | - |
973 | if (align & Qt::AlignBottom) | - |
974 | cr.setBottom(cr.bottom() - m); | - |
975 | } | - |
976 | return cr; | - |
977 | } | - |
978 | | - |
979 | void QLabelPrivate::ensureTextPopulated() const | - |
980 | { | - |
981 | if (!textDirty) | - |
982 | return; | - |
983 | if (control) { | - |
984 | QTextDocument *doc = control->document(); | - |
985 | if (textDirty) { | - |
986 | | - |
987 | if (isRichText) | - |
988 | doc->setHtml(text); | - |
989 | else | - |
990 | doc->setPlainText(text); | - |
991 | | - |
992 | | - |
993 | | - |
994 | doc->setUndoRedoEnabled(false); | - |
995 | | - |
996 | | - |
997 | if (hasShortcut) { | - |
998 | | - |
999 | int from = 0; | - |
1000 | bool found = false; | - |
1001 | QTextCursor cursor; | - |
1002 | while (!(cursor = control->document()->find((QLatin1String("&")), from)).isNull()) { | - |
1003 | cursor.deleteChar(); | - |
1004 | cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); | - |
1005 | from = cursor.position(); | - |
1006 | if (!found && cursor.selectedText() != QLatin1String("&")) { | - |
1007 | found = true; | - |
1008 | shortcutCursor = cursor; | - |
1009 | } | - |
1010 | } | - |
1011 | } | - |
1012 | | - |
1013 | } | - |
1014 | } | - |
1015 | textDirty = false; | - |
1016 | } | - |
1017 | | - |
1018 | void QLabelPrivate::ensureTextLayouted() const | - |
1019 | { | - |
1020 | if (!textLayoutDirty) | - |
1021 | return; | - |
1022 | ensureTextPopulated(); | - |
1023 | if (control) { | - |
1024 | QTextDocument *doc = control->document(); | - |
1025 | QTextOption opt = doc->defaultTextOption(); | - |
1026 | | - |
1027 | opt.setAlignment(QFlag(this->align)); | - |
1028 | | - |
1029 | if (this->align & Qt::TextWordWrap) | - |
1030 | opt.setWrapMode(QTextOption::WordWrap); | - |
1031 | else | - |
1032 | opt.setWrapMode(QTextOption::ManualWrap); | - |
1033 | | - |
1034 | doc->setDefaultTextOption(opt); | - |
1035 | | - |
1036 | QTextFrameFormat fmt = doc->rootFrame()->frameFormat(); | - |
1037 | fmt.setMargin(0); | - |
1038 | doc->rootFrame()->setFrameFormat(fmt); | - |
1039 | doc->setTextWidth(documentRect().width()); | - |
1040 | } | - |
1041 | textLayoutDirty = false; | - |
1042 | } | - |
1043 | | - |
1044 | void QLabelPrivate::ensureTextControl() const | - |
1045 | { | - |
1046 | const QLabel * const q = q_func(); | - |
1047 | if (!isTextLabel) | - |
1048 | return; | - |
1049 | if (!control) { | - |
1050 | control = new QWidgetTextControl(const_cast<QLabel *>(q)); | - |
1051 | control->document()->setUndoRedoEnabled(false); | - |
1052 | control->document()->setDefaultFont(q->font()); | - |
1053 | control->setTextInteractionFlags(textInteractionFlags); | - |
1054 | control->setOpenExternalLinks(openExternalLinks); | - |
1055 | control->setPalette(q->palette()); | - |
1056 | control->setFocus(q->hasFocus()); | - |
1057 | QObject::connect(control, qFlagLocation("2""updateRequest(QRectF)" "\0" __FILE__ ":" "1539""1543"), | - |
1058 | q, qFlagLocation("1""update()" "\0" __FILE__ ":" "1540""1544")); | - |
1059 | QObject::connect(control, qFlagLocation("2""linkHovered(QString)" "\0" __FILE__ ":" "1541""1545"), | - |
1060 | q, qFlagLocation("1""_q_linkHovered(QString)" "\0" __FILE__ ":" "1542""1546")); | - |
1061 | QObject::connect(control, qFlagLocation("2""linkActivated(QString)" "\0" __FILE__ ":" "1543""1547"), | - |
1062 | q, qFlagLocation("2""linkActivated(QString)" "\0" __FILE__ ":" "1544""1548")); | - |
1063 | textLayoutDirty = true; | - |
1064 | textDirty = true; | - |
1065 | } | - |
1066 | } | - |
1067 | | - |
1068 | void QLabelPrivate::sendControlEvent(QEvent *e) | - |
1069 | { | - |
1070 | QLabel * const q = q_func(); | - |
1071 | if (!isTextLabel || !control || textInteractionFlags == Qt::NoTextInteraction) { | - |
1072 | e->ignore(); | - |
1073 | return; | - |
1074 | } | - |
1075 | control->processEvent(e, -layoutRect().topLeft(), q); | - |
1076 | } | - |
1077 | | - |
1078 | void QLabelPrivate::_q_linkHovered(const QString &anchor) | - |
1079 | { | - |
1080 | QLabel * const q = q_func(); | - |
1081 | | - |
1082 | if (anchor.isEmpty()) { | - |
1083 | if (validCursor) | - |
1084 | q->setCursor(cursor); | - |
1085 | else | - |
1086 | q->unsetCursor(); | - |
1087 | onAnchor = false; | - |
1088 | } else if (!onAnchor) { | - |
1089 | validCursor = q->testAttribute(Qt::WA_SetCursor); | - |
1090 | if (validCursor) { | - |
1091 | cursor = q->cursor(); | - |
1092 | } | - |
1093 | q->setCursor(Qt::PointingHandCursor); | - |
1094 | onAnchor = true; | - |
1095 | } | - |
1096 | | - |
1097 | q->linkHovered(anchor); | - |
1098 | } | - |
1099 | | - |
1100 | | - |
1101 | | - |
1102 | | - |
1103 | QRectF QLabelPrivate::layoutRect() const | - |
1104 | { | - |
1105 | QRectF cr = documentRect(); | - |
1106 | if (!control) | - |
1107 | return cr; | - |
1108 | ensureTextLayouted(); | - |
1109 | | - |
1110 | qreal rh = control->document()->documentLayout()->documentSize().height(); | - |
1111 | qreal yo = 0; | - |
1112 | if (align & Qt::AlignVCenter) | - |
1113 | yo = qMax((cr.height()-rh)/2, qreal(0)); | - |
1114 | else if (align & Qt::AlignBottom) | - |
1115 | yo = qMax(cr.height()-rh, qreal(0)); | - |
1116 | return QRectF(cr.x(), yo + cr.y(), cr.width(), cr.height()); | - |
1117 | } | - |
1118 | | - |
1119 | | - |
1120 | QPoint QLabelPrivate::layoutPoint(const QPoint& p) const | - |
1121 | { | - |
1122 | QRect lr = layoutRect().toRect(); | - |
1123 | return p - lr.topLeft(); | - |
1124 | } | - |
1125 | | - |
1126 | | - |
1127 | QMenu *QLabelPrivate::createStandardContextMenu(const QPoint &pos) | - |
1128 | { | - |
1129 | QString linkToCopy; | - |
1130 | QPoint p; | - |
1131 | if (control && isRichText) { | - |
1132 | p = layoutPoint(pos); | - |
1133 | linkToCopy = control->document()->documentLayout()->anchorAt(p); | - |
1134 | } | - |
1135 | | - |
1136 | if (linkToCopy.isEmpty() && !control) | - |
1137 | return 0; | - |
1138 | | - |
1139 | return control->createStandardContextMenu(p, q_func()); | - |
1140 | } | - |
1141 | | - |
1142 | | - |
| | |