qtextbrowser.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/widgets/qtextbrowser.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtWidgets module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
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 http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://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 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qtextbrowser.h"-
35#include "qtextedit_p.h"-
36-
37#ifndef QT_NO_TEXTBROWSER-
38-
39#include <qstack.h>-
40#include <qapplication.h>-
41#include <qevent.h>-
42#include <qdesktopwidget.h>-
43#include <qdebug.h>-
44#include <qabstracttextdocumentlayout.h>-
45#include "private/qtextdocumentlayout_p.h"-
46#include <qtextcodec.h>-
47#include <qpainter.h>-
48#include <qdir.h>-
49#include <qwhatsthis.h>-
50#include <qtextobject.h>-
51#include <qdesktopservices.h>-
52-
53QT_BEGIN_NAMESPACE-
54-
55class QTextBrowserPrivate : public QTextEditPrivate-
56{-
57 Q_DECLARE_PUBLIC(QTextBrowser)-
58public:-
59 inline QTextBrowserPrivate()-
60 : textOrSourceChanged(false), forceLoadOnSourceChange(false), openExternalLinks(false),-
61 openLinks(true)-
62#ifdef QT_KEYPAD_NAVIGATION-
63 , lastKeypadScrollValue(-1)-
64#endif-
65 {}
never executed: end of block
0
66-
67 void init();-
68-
69 struct HistoryEntry {-
70 inline HistoryEntry()-
71 : hpos(0), vpos(0), focusIndicatorPosition(-1),-
72 focusIndicatorAnchor(-1) {}
never executed: end of block
0
73 QUrl url;-
74 QString title;-
75 int hpos;-
76 int vpos;-
77 int focusIndicatorPosition, focusIndicatorAnchor;-
78 };-
79-
80 HistoryEntry history(int i) const-
81 {-
82 if (i <= 0)
i <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
83 if (-i < stack.count())
-i < stack.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
84 return stack[stack.count()+i-1];
never executed: return stack[stack.count()+i-1];
0
85 else-
86 return HistoryEntry();
never executed: return HistoryEntry();
0
87 else-
88 if (i <= forwardStack.count())
i <= forwardStack.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
89 return forwardStack[forwardStack.count()-i];
never executed: return forwardStack[forwardStack.count()-i];
0
90 else-
91 return HistoryEntry();
never executed: return HistoryEntry();
0
92 }-
93-
94-
95 HistoryEntry createHistoryEntry() const;-
96 void restoreHistoryEntry(const HistoryEntry entry);-
97-
98 QStack<HistoryEntry> stack;-
99 QStack<HistoryEntry> forwardStack;-
100 QUrl home;-
101 QUrl currentURL;-
102-
103 QStringList searchPaths;-
104-
105 /*flag necessary to give the linkClicked() signal some meaningful-
106 semantics when somebody connected to it calls setText() or-
107 setSource() */-
108 bool textOrSourceChanged;-
109 bool forceLoadOnSourceChange;-
110-
111 bool openExternalLinks;-
112 bool openLinks;-
113-
114#ifndef QT_NO_CURSOR-
115 QCursor oldCursor;-
116#endif-
117-
118 QString findFile(const QUrl &name) const;-
119-
120 inline void _q_documentModified()-
121 {-
122 textOrSourceChanged = true;-
123 forceLoadOnSourceChange = !currentURL.path().isEmpty();-
124 }
never executed: end of block
0
125-
126 void _q_activateAnchor(const QString &href);-
127 void _q_highlightLink(const QString &href);-
128-
129 void setSource(const QUrl &url);-
130-
131 // re-imlemented from QTextEditPrivate-
132 virtual QUrl resolveUrl(const QUrl &url) const Q_DECL_OVERRIDE;-
133 inline QUrl resolveUrl(const QString &url) const-
134 { return resolveUrl(QUrl(url)); }
never executed: return resolveUrl(QUrl(url));
0
135-
136#ifdef QT_KEYPAD_NAVIGATION-
137 void keypadMove(bool next);-
138 QTextCursor prevFocus;-
139 int lastKeypadScrollValue;-
140#endif-
141};-
142Q_DECLARE_TYPEINFO(QTextBrowserPrivate::HistoryEntry, Q_MOVABLE_TYPE);-
143-
144QString QTextBrowserPrivate::findFile(const QUrl &name) const-
145{-
146 QString fileName;-
147 if (name.scheme() == QLatin1String("qrc")) {
name.scheme() ...1String("qrc")Description
TRUEnever evaluated
FALSEnever evaluated
0
148 fileName = QLatin1String(":/") + name.path();-
149 } else if (name.scheme().isEmpty()) {
never executed: end of block
name.scheme().isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
150 fileName = name.path();-
151 } else {
never executed: end of block
0
152#if defined(Q_OS_ANDROID)-
153 if (name.scheme() == QLatin1String("assets"))-
154 fileName = QLatin1String("assets:") + name.path();-
155 else-
156#endif-
157 fileName = name.toLocalFile();-
158 }
never executed: end of block
0
159-
160 if (QFileInfo(fileName).isAbsolute())
QFileInfo(file...).isAbsolute()Description
TRUEnever evaluated
FALSEnever evaluated
0
161 return fileName;
never executed: return fileName;
0
162-
163 foreach (QString path, searchPaths) {-
164 if (!path.endsWith(QLatin1Char('/')))
!path.endsWith...tin1Char('/'))Description
TRUEnever evaluated
FALSEnever evaluated
0
165 path.append(QLatin1Char('/'));
never executed: path.append(QLatin1Char('/'));
0
166 path.append(fileName);-
167 if (QFileInfo(path).isReadable())
QFileInfo(path).isReadable()Description
TRUEnever evaluated
FALSEnever evaluated
0
168 return path;
never executed: return path;
0
169 }
never executed: end of block
0
170-
171 return fileName;
never executed: return fileName;
0
172}-
173-
174QUrl QTextBrowserPrivate::resolveUrl(const QUrl &url) const-
175{-
176 if (!url.isRelative())
!url.isRelative()Description
TRUEnever evaluated
FALSEnever evaluated
0
177 return url;
never executed: return url;
0
178-
179 // For the second case QUrl can merge "#someanchor" with "foo.html"-
180 // correctly to "foo.html#someanchor"-
181 if (!(currentURL.isRelative()
currentURL.isRelative()Description
TRUEnever evaluated
FALSEnever evaluated
0
182 || (currentURL.scheme() == QLatin1String("file")
currentURL.sch...String("file")Description
TRUEnever evaluated
FALSEnever evaluated
0
183 && !QFileInfo(currentURL.toLocalFile()).isAbsolute()))
!QFileInfo(cur...).isAbsolute()Description
TRUEnever evaluated
FALSEnever evaluated
0
184 || (url.hasFragment() && url.path().isEmpty())) {
url.hasFragment()Description
TRUEnever evaluated
FALSEnever evaluated
url.path().isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
185 return currentURL.resolved(url);
never executed: return currentURL.resolved(url);
0
186 }-
187-
188 // this is our last resort when current url and new url are both relative-
189 // we try to resolve against the current working directory in the local-
190 // file system.-
191 QFileInfo fi(currentURL.toLocalFile());-
192 if (fi.exists()) {
fi.exists()Description
TRUEnever evaluated
FALSEnever evaluated
0
193 return QUrl::fromLocalFile(fi.absolutePath() + QDir::separator()).resolved(url);
never executed: return QUrl::fromLocalFile(fi.absolutePath() + QDir::separator()).resolved(url);
0
194 }-
195-
196 return url;
never executed: return url;
0
197}-
198-
199void QTextBrowserPrivate::_q_activateAnchor(const QString &href)-
200{-
201 if (href.isEmpty())
href.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
202 return;
never executed: return;
0
203 Q_Q(QTextBrowser);-
204-
205#ifndef QT_NO_CURSOR-
206 viewport->setCursor(oldCursor);-
207#endif-
208-
209 const QUrl url = resolveUrl(href);-
210-
211 if (!openLinks) {
!openLinksDescription
TRUEnever evaluated
FALSEnever evaluated
0
212 emit q->anchorClicked(url);-
213 return;
never executed: return;
0
214 }-
215-
216 textOrSourceChanged = false;-
217-
218#ifndef QT_NO_DESKTOPSERVICES-
219 bool isFileScheme =-
220 url.scheme() == QLatin1String("file")
url.scheme() =...String("file")Description
TRUEnever evaluated
FALSEnever evaluated
0
221#if defined(Q_OS_ANDROID)-
222 || url.scheme() == QLatin1String("assets")-
223#endif-
224 || url.scheme() == QLatin1String("qrc");
url.scheme() =...1String("qrc")Description
TRUEnever evaluated
FALSEnever evaluated
0
225 if ((openExternalLinks && !isFileScheme && !url.isRelative())
openExternalLinksDescription
TRUEnever evaluated
FALSEnever evaluated
!isFileSchemeDescription
TRUEnever evaluated
FALSEnever evaluated
!url.isRelative()Description
TRUEnever evaluated
FALSEnever evaluated
0
226 || (url.isRelative() && !currentURL.isRelative() && !isFileScheme)) {
url.isRelative()Description
TRUEnever evaluated
FALSEnever evaluated
!currentURL.isRelative()Description
TRUEnever evaluated
FALSEnever evaluated
!isFileSchemeDescription
TRUEnever evaluated
FALSEnever evaluated
0
227 QDesktopServices::openUrl(url);-
228 return;
never executed: return;
0
229 }-
230#endif-
231-
232 emit q->anchorClicked(url);-
233-
234 if (textOrSourceChanged)
textOrSourceChangedDescription
TRUEnever evaluated
FALSEnever evaluated
0
235 return;
never executed: return;
0
236-
237 q->setSource(url);-
238}
never executed: end of block
0
239-
240void QTextBrowserPrivate::_q_highlightLink(const QString &anchor)-
241{-
242 Q_Q(QTextBrowser);-
243 if (anchor.isEmpty()) {
anchor.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
244#ifndef QT_NO_CURSOR-
245 if (viewport->cursor().shape() != Qt::PointingHandCursor)
viewport->curs...tingHandCursorDescription
TRUEnever evaluated
FALSEnever evaluated
0
246 oldCursor = viewport->cursor();
never executed: oldCursor = viewport->cursor();
0
247 viewport->setCursor(oldCursor);-
248#endif-
249 emit q->highlighted(QUrl());-
250 emit q->highlighted(QString());-
251 } else {
never executed: end of block
0
252#ifndef QT_NO_CURSOR-
253 viewport->setCursor(Qt::PointingHandCursor);-
254#endif-
255-
256 const QUrl url = resolveUrl(anchor);-
257 emit q->highlighted(url);-
258 // convenience to ease connecting to QStatusBar::showMessage(const QString &)-
259 emit q->highlighted(url.toString());-
260 }
never executed: end of block
0
261}-
262-
263void QTextBrowserPrivate::setSource(const QUrl &url)-
264{-
265 Q_Q(QTextBrowser);-
266#ifndef QT_NO_CURSOR-
267 if (q->isVisible())
q->isVisible()Description
TRUEnever evaluated
FALSEnever evaluated
0
268 QApplication::setOverrideCursor(Qt::WaitCursor);
never executed: QApplication::setOverrideCursor(Qt::WaitCursor);
0
269#endif-
270 textOrSourceChanged = true;-
271-
272 QString txt;-
273-
274 bool doSetText = false;-
275-
276 QUrl currentUrlWithoutFragment = currentURL;-
277 currentUrlWithoutFragment.setFragment(QString());-
278 QUrl newUrlWithoutFragment = currentURL.resolved(url);-
279 newUrlWithoutFragment.setFragment(QString());-
280-
281 if (url.isValid()
url.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
282 && (newUrlWithoutFragment != currentUrlWithoutFragment || forceLoadOnSourceChange)) {
newUrlWithoutF...ithoutFragmentDescription
TRUEnever evaluated
FALSEnever evaluated
forceLoadOnSourceChangeDescription
TRUEnever evaluated
FALSEnever evaluated
0
283 QVariant data = q->loadResource(QTextDocument::HtmlResource, resolveUrl(url));-
284 if (data.type() == QVariant::String) {
data.type() ==...ariant::StringDescription
TRUEnever evaluated
FALSEnever evaluated
0
285 txt = data.toString();-
286 } else if (data.type() == QVariant::ByteArray) {
never executed: end of block
data.type() ==...ant::ByteArrayDescription
TRUEnever evaluated
FALSEnever evaluated
0
287#ifndef QT_NO_TEXTCODEC-
288 QByteArray ba = data.toByteArray();-
289 QTextCodec *codec = Qt::codecForHtml(ba);-
290 txt = codec->toUnicode(ba);-
291#else-
292 txt = data.toString();-
293#endif-
294 }
never executed: end of block
0
295 if (txt.isEmpty())
txt.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
296 qWarning("QTextBrowser: No document for %s", url.toString().toLatin1().constData());
never executed: QMessageLogger(__FILE__, 296, __PRETTY_FUNCTION__).warning("QTextBrowser: No document for %s", url.toString().toLatin1().constData());
0
297-
298 if (q->isVisible()) {
q->isVisible()Description
TRUEnever evaluated
FALSEnever evaluated
0
299 QString firstTag = txt.left(txt.indexOf(QLatin1Char('>')) + 1);-
300 if (firstTag.startsWith(QLatin1String("<qt")) && firstTag.contains(QLatin1String("type")) && firstTag.contains(QLatin1String("detail"))) {
firstTag.start...String("<qt"))Description
TRUEnever evaluated
FALSEnever evaluated
firstTag.conta...tring("type"))Description
TRUEnever evaluated
FALSEnever evaluated
firstTag.conta...ing("detail"))Description
TRUEnever evaluated
FALSEnever evaluated
0
301#ifndef QT_NO_CURSOR-
302 QApplication::restoreOverrideCursor();-
303#endif-
304#ifndef QT_NO_WHATSTHIS-
305 QWhatsThis::showText(QCursor::pos(), txt, q);-
306#endif-
307 return;
never executed: return;
0
308 }-
309 }
never executed: end of block
0
310-
311 currentURL = resolveUrl(url);-
312 doSetText = true;-
313 }
never executed: end of block
0
314-
315 if (!home.isValid())
!home.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
316 home = url;
never executed: home = url;
0
317-
318 if (doSetText) {
doSetTextDescription
TRUEnever evaluated
FALSEnever evaluated
0
319#ifndef QT_NO_TEXTHTMLPARSER-
320 q->QTextEdit::setHtml(txt);-
321 q->document()->setMetaInformation(QTextDocument::DocumentUrl, currentURL.toString());-
322#else-
323 q->QTextEdit::setPlainText(txt);-
324#endif-
325-
326#ifdef QT_KEYPAD_NAVIGATION-
327 prevFocus.movePosition(QTextCursor::Start);-
328#endif-
329 }
never executed: end of block
0
330-
331 forceLoadOnSourceChange = false;-
332-
333 if (!url.fragment().isEmpty()) {
!url.fragment().isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
334 q->scrollToAnchor(url.fragment());-
335 } else {
never executed: end of block
0
336 hbar->setValue(0);-
337 vbar->setValue(0);-
338 }
never executed: end of block
0
339#ifdef QT_KEYPAD_NAVIGATION-
340 lastKeypadScrollValue = vbar->value();-
341 emit q->highlighted(QUrl());-
342 emit q->highlighted(QString());-
343#endif-
344-
345#ifndef QT_NO_CURSOR-
346 if (q->isVisible())
q->isVisible()Description
TRUEnever evaluated
FALSEnever evaluated
0
347 QApplication::restoreOverrideCursor();
never executed: QApplication::restoreOverrideCursor();
0
348#endif-
349 emit q->sourceChanged(url);-
350}
never executed: end of block
0
351-
352#ifdef QT_KEYPAD_NAVIGATION-
353void QTextBrowserPrivate::keypadMove(bool next)-
354{-
355 Q_Q(QTextBrowser);-
356-
357 const int height = viewport->height();-
358 const int overlap = qBound(20, height / 5, 40); // XXX arbitrary, but a good balance-
359 const int visibleLinkAmount = overlap; // consistent, but maybe not the best choice (?)-
360 int yOffset = vbar->value();-
361 int scrollYOffset = qBound(0, next ? yOffset + height - overlap : yOffset - height + overlap, vbar->maximum());-
362-
363 bool foundNextAnchor = false;-
364 bool focusIt = false;-
365 int focusedPos = -1;-
366-
367 QTextCursor anchorToFocus;-
368-
369 QRectF viewRect = QRectF(0, yOffset, control->size().width(), height);-
370 QRectF newViewRect = QRectF(0, scrollYOffset, control->size().width(), height);-
371 QRectF bothViewRects = viewRect.united(newViewRect);-
372-
373 // If we don't have a previous anchor, pretend that we had the first/last character-
374 // on the screen selected.-
375 if (prevFocus.isNull()) {-
376 if (next)-
377 prevFocus = control->cursorForPosition(QPointF(0, yOffset));-
378 else-
379 prevFocus = control->cursorForPosition(QPointF(control->size().width(), yOffset + height));-
380 }-
381-
382 // First, check to see if someone has moved the scroll bars independently-
383 if (lastKeypadScrollValue != yOffset) {-
384 // Someone (user or programmatically) has moved us, so we might-
385 // need to start looking from the current position instead of prevFocus-
386-
387 bool findOnScreen = true;-
388-
389 // If prevFocus is on screen at all, we just use it.-
390 if (prevFocus.hasSelection()) {-
391 QRectF prevRect = control->selectionRect(prevFocus);-
392 if (viewRect.intersects(prevRect))-
393 findOnScreen = false;-
394 }-
395-
396 // Otherwise, we find a new anchor that's on screen.-
397 // Basically, create a cursor with the last/first character-
398 // on screen-
399 if (findOnScreen) {-
400 if (next)-
401 prevFocus = control->cursorForPosition(QPointF(0, yOffset));-
402 else-
403 prevFocus = control->cursorForPosition(QPointF(control->size().width(), yOffset + height));-
404 }-
405 foundNextAnchor = control->findNextPrevAnchor(prevFocus, next, anchorToFocus);-
406 } else if (prevFocus.hasSelection()) {-
407 // Check the pathological case that the current anchor is higher-
408 // than the screen, and just scroll through it in that case-
409 QRectF prevRect = control->selectionRect(prevFocus);-
410 if ((next && prevRect.bottom() > (yOffset + height)) ||-
411 (!next && prevRect.top() < yOffset)) {-
412 anchorToFocus = prevFocus;-
413 focusedPos = scrollYOffset;-
414 focusIt = true;-
415 } else {-
416 // This is the "normal" case - no scroll bar adjustments, no large anchors,-
417 // and no wrapping.-
418 foundNextAnchor = control->findNextPrevAnchor(prevFocus, next, anchorToFocus);-
419 }-
420 }-
421-
422 // If not found yet, see if we need to wrap-
423 if (!focusIt && !foundNextAnchor) {-
424 if (next) {-
425 if (yOffset == vbar->maximum()) {-
426 prevFocus.movePosition(QTextCursor::Start);-
427 yOffset = scrollYOffset = 0;-
428-
429 // Refresh the rectangles-
430 viewRect = QRectF(0, yOffset, control->size().width(), height);-
431 newViewRect = QRectF(0, scrollYOffset, control->size().width(), height);-
432 bothViewRects = viewRect.united(newViewRect);-
433 }-
434 } else {-
435 if (yOffset == 0) {-
436 prevFocus.movePosition(QTextCursor::End);-
437 yOffset = scrollYOffset = vbar->maximum();-
438-
439 // Refresh the rectangles-
440 viewRect = QRectF(0, yOffset, control->size().width(), height);-
441 newViewRect = QRectF(0, scrollYOffset, control->size().width(), height);-
442 bothViewRects = viewRect.united(newViewRect);-
443 }-
444 }-
445-
446 // Try looking now-
447 foundNextAnchor = control->findNextPrevAnchor(prevFocus, next, anchorToFocus);-
448 }-
449-
450 // If we did actually find an anchor to use...-
451 if (foundNextAnchor) {-
452 QRectF desiredRect = control->selectionRect(anchorToFocus);-
453-
454 // XXX This is an arbitrary heuristic-
455 // Decide to focus an anchor if it will be at least be-
456 // in the middle region of the screen after a scroll.-
457 // This can result in partial anchors with focus, but-
458 // insisting on links being completely visible before-
459 // selecting them causes disparities between links that-
460 // take up 90% of the screen height and those that take-
461 // up e.g. 110%-
462 // Obviously if a link is entirely visible, we still-
463 // focus it.-
464 if(bothViewRects.contains(desiredRect)-
465 || bothViewRects.adjusted(0, visibleLinkAmount, 0, -visibleLinkAmount).intersects(desiredRect)) {-
466 focusIt = true;-
467-
468 // We aim to put the new link in the middle of the screen,-
469 // unless the link is larger than the screen (we just move to-
470 // display the first page of the link)-
471 if (desiredRect.height() > height) {-
472 if (next)-
473 focusedPos = (int) desiredRect.top();-
474 else-
475 focusedPos = (int) desiredRect.bottom() - height;-
476 } else-
477 focusedPos = (int) ((desiredRect.top() + desiredRect.bottom()) / 2 - (height / 2));-
478-
479 // and clamp it to make sure we don't skip content.-
480 if (next)-
481 focusedPos = qBound(yOffset, focusedPos, scrollYOffset);-
482 else-
483 focusedPos = qBound(scrollYOffset, focusedPos, yOffset);-
484 }-
485 }-
486-
487 // If we didn't get a new anchor, check if the old one is still on screen when we scroll-
488 // Note that big (larger than screen height) anchors also have some handling at the-
489 // start of this function.-
490 if (!focusIt && prevFocus.hasSelection()) {-
491 QRectF desiredRect = control->selectionRect(prevFocus);-
492 // XXX this may be better off also using the visibleLinkAmount value-
493 if(newViewRect.intersects(desiredRect)) {-
494 focusedPos = scrollYOffset;-
495 focusIt = true;-
496 anchorToFocus = prevFocus;-
497 }-
498 }-
499-
500 // setTextCursor ensures that the cursor is visible. save & restore-
501 // the scroll bar values therefore-
502 const int savedXOffset = hbar->value();-
503-
504 // Now actually process our decision-
505 if (focusIt && control->setFocusToAnchor(anchorToFocus)) {-
506 // Save the focus for next time-
507 prevFocus = control->textCursor();-
508-
509 // Scroll-
510 vbar->setValue(focusedPos);-
511 lastKeypadScrollValue = focusedPos;-
512 hbar->setValue(savedXOffset);-
513-
514 // Ensure that the new selection is highlighted.-
515 const QString href = control->anchorAtCursor();-
516 QUrl url = resolveUrl(href);-
517 emit q->highlighted(url);-
518 emit q->highlighted(url.toString());-
519 } else {-
520 // Scroll-
521 vbar->setValue(scrollYOffset);-
522 lastKeypadScrollValue = scrollYOffset;-
523-
524 // now make sure we don't have a focused anchor-
525 QTextCursor cursor = control->textCursor();-
526 cursor.clearSelection();-
527-
528 control->setTextCursor(cursor);-
529-
530 hbar->setValue(savedXOffset);-
531 vbar->setValue(scrollYOffset);-
532-
533 emit q->highlighted(QUrl());-
534 emit q->highlighted(QString());-
535 }-
536}-
537#endif-
538-
539QTextBrowserPrivate::HistoryEntry QTextBrowserPrivate::createHistoryEntry() const-
540{-
541 HistoryEntry entry;-
542 entry.url = q_func()->source();-
543 entry.title = q_func()->documentTitle();-
544 entry.hpos = hbar->value();-
545 entry.vpos = vbar->value();-
546-
547 const QTextCursor cursor = control->textCursor();-
548 if (control->cursorIsFocusIndicator()
control->curso...cusIndicator()Description
TRUEnever evaluated
FALSEnever evaluated
0
549 && cursor.hasSelection()) {
cursor.hasSelection()Description
TRUEnever evaluated
FALSEnever evaluated
0
550-
551 entry.focusIndicatorPosition = cursor.position();-
552 entry.focusIndicatorAnchor = cursor.anchor();-
553 }
never executed: end of block
0
554 return entry;
never executed: return entry;
0
555}-
556-
557void QTextBrowserPrivate::restoreHistoryEntry(const HistoryEntry entry)-
558{-
559 setSource(entry.url);-
560 hbar->setValue(entry.hpos);-
561 vbar->setValue(entry.vpos);-
562 if (entry.focusIndicatorAnchor != -1 && entry.focusIndicatorPosition != -1) {
entry.focusInd...orAnchor != -1Description
TRUEnever evaluated
FALSEnever evaluated
entry.focusInd...Position != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
563 QTextCursor cursor(control->document());-
564 cursor.setPosition(entry.focusIndicatorAnchor);-
565 cursor.setPosition(entry.focusIndicatorPosition, QTextCursor::KeepAnchor);-
566 control->setTextCursor(cursor);-
567 control->setCursorIsFocusIndicator(true);-
568 }
never executed: end of block
0
569#ifdef QT_KEYPAD_NAVIGATION-
570 lastKeypadScrollValue = vbar->value();-
571 prevFocus = control->textCursor();-
572-
573 Q_Q(QTextBrowser);-
574 const QString href = prevFocus.charFormat().anchorHref();-
575 QUrl url = resolveUrl(href);-
576 emit q->highlighted(url);-
577 emit q->highlighted(url.toString());-
578#endif-
579}
never executed: end of block
0
580-
581/*!-
582 \class QTextBrowser-
583 \brief The QTextBrowser class provides a rich text browser with hypertext navigation.-
584-
585 \ingroup richtext-processing-
586 \inmodule QtWidgets-
587-
588 This class extends QTextEdit (in read-only mode), adding some navigation-
589 functionality so that users can follow links in hypertext documents.-
590-
591 If you want to provide your users with an editable rich text editor,-
592 use QTextEdit. If you want a text browser without hypertext navigation-
593 use QTextEdit, and use QTextEdit::setReadOnly() to disable-
594 editing. If you just need to display a small piece of rich text-
595 use QLabel.-
596-
597 \section1 Document Source and Contents-
598-
599 The contents of QTextEdit are set with setHtml() or setPlainText(),-
600 but QTextBrowser also implements the setSource() function, making it-
601 possible to use a named document as the source text. The name is looked-
602 up in a list of search paths and in the directory of the current document-
603 factory.-
604-
605 If a document name ends with-
606 an anchor (for example, "\c #anchor"), the text browser automatically-
607 scrolls to that position (using scrollToAnchor()). When the user clicks-
608 on a hyperlink, the browser will call setSource() itself with the link's-
609 \c href value as argument. You can track the current source by connecting-
610 to the sourceChanged() signal.-
611-
612 \section1 Navigation-
613-
614 QTextBrowser provides backward() and forward() slots which you can-
615 use to implement Back and Forward buttons. The home() slot sets-
616 the text to the very first document displayed. The anchorClicked()-
617 signal is emitted when the user clicks an anchor. To override the-
618 default navigation behavior of the browser, call the setSource()-
619 function to supply new document text in a slot connected to this-
620 signal.-
621-
622 If you want to load documents stored in the Qt resource system use-
623 \c{qrc} as the scheme in the URL to load. For example, for the document-
624 resource path \c{:/docs/index.html} use \c{qrc:/docs/index.html} as-
625 the URL with setSource().-
626-
627 \sa QTextEdit, QTextDocument-
628*/-
629-
630/*!-
631 \property QTextBrowser::modified-
632 \brief whether the contents of the text browser have been modified-
633*/-
634-
635/*!-
636 \property QTextBrowser::readOnly-
637 \brief whether the text browser is read-only-
638-
639 By default, this property is \c true.-
640*/-
641-
642/*!-
643 \property QTextBrowser::undoRedoEnabled-
644 \brief whether the text browser supports undo/redo operations-
645-
646 By default, this property is \c false.-
647*/-
648-
649void QTextBrowserPrivate::init()-
650{-
651 Q_Q(QTextBrowser);-
652 control->setTextInteractionFlags(Qt::TextBrowserInteraction);-
653#ifndef QT_NO_CURSOR-
654 viewport->setCursor(oldCursor);-
655#endif-
656 q->setAttribute(Qt::WA_InputMethodEnabled, !q->isReadOnly());-
657 q->setUndoRedoEnabled(false);-
658 viewport->setMouseTracking(true);-
659 QObject::connect(q->document(), SIGNAL(contentsChanged()), q, SLOT(_q_documentModified()));-
660 QObject::connect(control, SIGNAL(linkActivated(QString)),-
661 q, SLOT(_q_activateAnchor(QString)));-
662 QObject::connect(control, SIGNAL(linkHovered(QString)),-
663 q, SLOT(_q_highlightLink(QString)));-
664}
never executed: end of block
0
665-
666/*!-
667 Constructs an empty QTextBrowser with parent \a parent.-
668*/-
669QTextBrowser::QTextBrowser(QWidget *parent)-
670 : QTextEdit(*new QTextBrowserPrivate, parent)-
671{-
672 Q_D(QTextBrowser);-
673 d->init();-
674}
never executed: end of block
0
675-
676-
677/*!-
678 \internal-
679*/-
680QTextBrowser::~QTextBrowser()-
681{-
682}-
683-
684/*!-
685 \property QTextBrowser::source-
686 \brief the name of the displayed document.-
687-
688 This is a an invalid url if no document is displayed or if the-
689 source is unknown.-
690-
691 When setting this property QTextBrowser tries to find a document-
692 with the specified name in the paths of the searchPaths property-
693 and directory of the current source, unless the value is an absolute-
694 file path. It also checks for optional anchors and scrolls the document-
695 accordingly-
696-
697 If the first tag in the document is \c{<qt type=detail>}, the-
698 document is displayed as a popup rather than as new document in-
699 the browser window itself. Otherwise, the document is displayed-
700 normally in the text browser with the text set to the contents of-
701 the named document with setHtml().-
702-
703 By default, this property contains an empty URL.-
704*/-
705QUrl QTextBrowser::source() const-
706{-
707 Q_D(const QTextBrowser);-
708 if (d->stack.isEmpty())
d->stack.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
709 return QUrl();
never executed: return QUrl();
0
710 else-
711 return d->stack.top().url;
never executed: return d->stack.top().url;
0
712}-
713-
714/*!-
715 \property QTextBrowser::searchPaths-
716 \brief the search paths used by the text browser to find supporting-
717 content-
718-
719 QTextBrowser uses this list to locate images and documents.-
720-
721 By default, this property contains an empty string list.-
722*/-
723-
724QStringList QTextBrowser::searchPaths() const-
725{-
726 Q_D(const QTextBrowser);-
727 return d->searchPaths;
never executed: return d->searchPaths;
0
728}-
729-
730void QTextBrowser::setSearchPaths(const QStringList &paths)-
731{-
732 Q_D(QTextBrowser);-
733 d->searchPaths = paths;-
734}
never executed: end of block
0
735-
736/*!-
737 Reloads the current set source.-
738*/-
739void QTextBrowser::reload()-
740{-
741 Q_D(QTextBrowser);-
742 QUrl s = d->currentURL;-
743 d->currentURL = QUrl();-
744 setSource(s);-
745}
never executed: end of block
0
746-
747void QTextBrowser::setSource(const QUrl &url)-
748{-
749 Q_D(QTextBrowser);-
750-
751 const QTextBrowserPrivate::HistoryEntry historyEntry = d->createHistoryEntry();-
752-
753 d->setSource(url);-
754-
755 if (!url.isValid())
!url.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
756 return;
never executed: return;
0
757-
758 // the same url you are already watching?-
759 if (!d->stack.isEmpty() && d->stack.top().url == url)
!d->stack.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
d->stack.top().url == urlDescription
TRUEnever evaluated
FALSEnever evaluated
0
760 return;
never executed: return;
0
761-
762 if (!d->stack.isEmpty())
!d->stack.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
763 d->stack.top() = historyEntry;
never executed: d->stack.top() = historyEntry;
0
764-
765 QTextBrowserPrivate::HistoryEntry entry;-
766 entry.url = url;-
767 entry.title = documentTitle();-
768 entry.hpos = 0;-
769 entry.vpos = 0;-
770 d->stack.push(entry);-
771-
772 emit backwardAvailable(d->stack.count() > 1);-
773-
774 if (!d->forwardStack.isEmpty() && d->forwardStack.top().url == url) {
!d->forwardStack.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
d->forwardStac...p().url == urlDescription
TRUEnever evaluated
FALSEnever evaluated
0
775 d->forwardStack.pop();-
776 emit forwardAvailable(d->forwardStack.count() > 0);-
777 } else {
never executed: end of block
0
778 d->forwardStack.clear();-
779 emit forwardAvailable(false);-
780 }
never executed: end of block
0
781-
782 emit historyChanged();-
783}
never executed: end of block
0
784-
785/*!-
786 \fn void QTextBrowser::backwardAvailable(bool available)-
787-
788 This signal is emitted when the availability of backward()-
789 changes. \a available is false when the user is at home();-
790 otherwise it is true.-
791*/-
792-
793/*!-
794 \fn void QTextBrowser::forwardAvailable(bool available)-
795-
796 This signal is emitted when the availability of forward() changes.-
797 \a available is true after the user navigates backward() and false-
798 when the user navigates or goes forward().-
799*/-
800-
801/*!-
802 \fn void QTextBrowser::historyChanged()-
803 \since 4.4-
804-
805 This signal is emitted when the history changes.-
806-
807 \sa historyTitle(), historyUrl()-
808*/-
809-
810/*!-
811 \fn void QTextBrowser::sourceChanged(const QUrl &src)-
812-
813 This signal is emitted when the source has changed, \a src-
814 being the new source.-
815-
816 Source changes happen both programmatically when calling-
817 setSource(), forward(), backword() or home() or when the user-
818 clicks on links or presses the equivalent key sequences.-
819*/-
820-
821/*! \fn void QTextBrowser::highlighted(const QUrl &link)-
822-
823 This signal is emitted when the user has selected but not-
824 activated an anchor in the document. The URL referred to by the-
825 anchor is passed in \a link.-
826*/-
827-
828/*! \fn void QTextBrowser::highlighted(const QString &link)-
829 \overload-
830-
831 Convenience signal that allows connecting to a slot-
832 that takes just a QString, like for example QStatusBar's-
833 message().-
834*/-
835-
836-
837/*!-
838 \fn void QTextBrowser::anchorClicked(const QUrl &link)-
839-
840 This signal is emitted when the user clicks an anchor. The-
841 URL referred to by the anchor is passed in \a link.-
842-
843 Note that the browser will automatically handle navigation to the-
844 location specified by \a link unless the openLinks property-
845 is set to false or you call setSource() in a slot connected.-
846 This mechanism is used to override the default navigation features of the browser.-
847*/-
848-
849/*!-
850 Changes the document displayed to the previous document in the-
851 list of documents built by navigating links. Does nothing if there-
852 is no previous document.-
853-
854 \sa forward(), backwardAvailable()-
855*/-
856void QTextBrowser::backward()-
857{-
858 Q_D(QTextBrowser);-
859 if (d->stack.count() <= 1)
d->stack.count() <= 1Description
TRUEnever evaluated
FALSEnever evaluated
0
860 return;
never executed: return;
0
861-
862 // Update the history entry-
863 d->forwardStack.push(d->createHistoryEntry());-
864 d->stack.pop(); // throw away the old version of the current entry-
865 d->restoreHistoryEntry(d->stack.top()); // previous entry-
866 emit backwardAvailable(d->stack.count() > 1);-
867 emit forwardAvailable(true);-
868 emit historyChanged();-
869}
never executed: end of block
0
870-
871/*!-
872 Changes the document displayed to the next document in the list of-
873 documents built by navigating links. Does nothing if there is no-
874 next document.-
875-
876 \sa backward(), forwardAvailable()-
877*/-
878void QTextBrowser::forward()-
879{-
880 Q_D(QTextBrowser);-
881 if (d->forwardStack.isEmpty())
d->forwardStack.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
882 return;
never executed: return;
0
883 if (!d->stack.isEmpty()) {
!d->stack.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
884 // Update the history entry-
885 d->stack.top() = d->createHistoryEntry();-
886 }
never executed: end of block
0
887 d->stack.push(d->forwardStack.pop());-
888 d->restoreHistoryEntry(d->stack.top());-
889 emit backwardAvailable(true);-
890 emit forwardAvailable(!d->forwardStack.isEmpty());-
891 emit historyChanged();-
892}
never executed: end of block
0
893-
894/*!-
895 Changes the document displayed to be the first document from-
896 the history.-
897*/-
898void QTextBrowser::home()-
899{-
900 Q_D(QTextBrowser);-
901 if (d->home.isValid())
d->home.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
902 setSource(d->home);
never executed: setSource(d->home);
0
903}
never executed: end of block
0
904-
905/*!-
906 The event \a ev is used to provide the following keyboard shortcuts:-
907 \table-
908 \header \li Keypress \li Action-
909 \row \li Alt+Left Arrow \li \l backward()-
910 \row \li Alt+Right Arrow \li \l forward()-
911 \row \li Alt+Up Arrow \li \l home()-
912 \endtable-
913*/-
914void QTextBrowser::keyPressEvent(QKeyEvent *ev)-
915{-
916#ifdef QT_KEYPAD_NAVIGATION-
917 Q_D(QTextBrowser);-
918 switch (ev->key()) {-
919 case Qt::Key_Select:-
920 if (QApplication::keypadNavigationEnabled()) {-
921 if (!hasEditFocus()) {-
922 setEditFocus(true);-
923 return;-
924 } else {-
925 QTextCursor cursor = d->control->textCursor();-
926 QTextCharFormat charFmt = cursor.charFormat();-
927 if (!cursor.hasSelection() || charFmt.anchorHref().isEmpty()) {-
928 ev->accept();-
929 return;-
930 }-
931 }-
932 }-
933 break;-
934 case Qt::Key_Back:-
935 if (QApplication::keypadNavigationEnabled()) {-
936 if (hasEditFocus()) {-
937 setEditFocus(false);-
938 ev->accept();-
939 return;-
940 }-
941 }-
942 QTextEdit::keyPressEvent(ev);-
943 return;-
944 default:-
945 if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {-
946 ev->ignore();-
947 return;-
948 }-
949 }-
950#endif-
951-
952 if (ev->modifiers() & Qt::AltModifier) {
ev->modifiers(...t::AltModifierDescription
TRUEnever evaluated
FALSEnever evaluated
0
953 switch (ev->key()) {-
954 case Qt::Key_Right:
never executed: case Qt::Key_Right:
0
955 forward();-
956 ev->accept();-
957 return;
never executed: return;
0
958 case Qt::Key_Left:
never executed: case Qt::Key_Left:
0
959 backward();-
960 ev->accept();-
961 return;
never executed: return;
0
962 case Qt::Key_Up:
never executed: case Qt::Key_Up:
0
963 home();-
964 ev->accept();-
965 return;
never executed: return;
0
966 }-
967 }
never executed: end of block
0
968#ifdef QT_KEYPAD_NAVIGATION-
969 else {-
970 if (ev->key() == Qt::Key_Up) {-
971 d->keypadMove(false);-
972 return;-
973 } else if (ev->key() == Qt::Key_Down) {-
974 d->keypadMove(true);-
975 return;-
976 }-
977 }-
978#endif-
979 QTextEdit::keyPressEvent(ev);-
980}
never executed: end of block
0
981-
982/*!-
983 \reimp-
984*/-
985void QTextBrowser::mouseMoveEvent(QMouseEvent *e)-
986{-
987 QTextEdit::mouseMoveEvent(e);-
988}
never executed: end of block
0
989-
990/*!-
991 \reimp-
992*/-
993void QTextBrowser::mousePressEvent(QMouseEvent *e)-
994{-
995 QTextEdit::mousePressEvent(e);-
996}
never executed: end of block
0
997-
998/*!-
999 \reimp-
1000*/-
1001void QTextBrowser::mouseReleaseEvent(QMouseEvent *e)-
1002{-
1003 QTextEdit::mouseReleaseEvent(e);-
1004}
never executed: end of block
0
1005-
1006/*!-
1007 \reimp-
1008*/-
1009void QTextBrowser::focusOutEvent(QFocusEvent *ev)-
1010{-
1011#ifndef QT_NO_CURSOR-
1012 Q_D(QTextBrowser);-
1013 d->viewport->setCursor((!(d->control->textInteractionFlags() & Qt::TextEditable)) ? d->oldCursor : Qt::IBeamCursor);-
1014#endif-
1015 QTextEdit::focusOutEvent(ev);-
1016}
never executed: end of block
0
1017-
1018/*!-
1019 \reimp-
1020*/-
1021bool QTextBrowser::focusNextPrevChild(bool next)-
1022{-
1023 Q_D(QTextBrowser);-
1024 if (d->control->setFocusToNextOrPreviousAnchor(next)) {
d->control->se...usAnchor(next)Description
TRUEnever evaluated
FALSEnever evaluated
0
1025#ifdef QT_KEYPAD_NAVIGATION-
1026 // Might need to synthesize a highlight event.-
1027 if (d->prevFocus != d->control->textCursor() && d->control->textCursor().hasSelection()) {-
1028 const QString href = d->control->anchorAtCursor();-
1029 QUrl url = d->resolveUrl(href);-
1030 emit highlighted(url);-
1031 emit highlighted(url.toString());-
1032 }-
1033 d->prevFocus = d->control->textCursor();-
1034#endif-
1035 return true;
never executed: return true;
0
1036 } else {-
1037#ifdef QT_KEYPAD_NAVIGATION-
1038 // We assume we have no highlight now.-
1039 emit highlighted(QUrl());-
1040 emit highlighted(QString());-
1041#endif-
1042 }
never executed: end of block
0
1043 return QTextEdit::focusNextPrevChild(next);
never executed: return QTextEdit::focusNextPrevChild(next);
0
1044}-
1045-
1046/*!-
1047 \reimp-
1048*/-
1049void QTextBrowser::paintEvent(QPaintEvent *e)-
1050{-
1051 Q_D(QTextBrowser);-
1052 QPainter p(d->viewport);-
1053 d->paint(&p, e);-
1054}
never executed: end of block
0
1055-
1056/*!-
1057 This function is called when the document is loaded and for-
1058 each image in the document. The \a type indicates the type of resource-
1059 to be loaded. An invalid QVariant is returned if the resource cannot be-
1060 loaded.-
1061-
1062 The default implementation ignores \a type and tries to locate-
1063 the resources by interpreting \a name as a file name. If it is-
1064 not an absolute path it tries to find the file in the paths of-
1065 the \l searchPaths property and in the same directory as the-
1066 current source. On success, the result is a QVariant that stores-
1067 a QByteArray with the contents of the file.-
1068-
1069 If you reimplement this function, you can return other QVariant-
1070 types. The table below shows which variant types are supported-
1071 depending on the resource type:-
1072-
1073 \table-
1074 \header \li ResourceType \li QVariant::Type-
1075 \row \li QTextDocument::HtmlResource \li QString or QByteArray-
1076 \row \li QTextDocument::ImageResource \li QImage, QPixmap or QByteArray-
1077 \row \li QTextDocument::StyleSheetResource \li QString or QByteArray-
1078 \endtable-
1079*/-
1080QVariant QTextBrowser::loadResource(int /*type*/, const QUrl &name)-
1081{-
1082 Q_D(QTextBrowser);-
1083-
1084 QByteArray data;-
1085 QString fileName = d->findFile(d->resolveUrl(name));-
1086 QFile f(fileName);-
1087 if (f.open(QFile::ReadOnly)) {
f.open(QFile::ReadOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
1088 data = f.readAll();-
1089 f.close();-
1090 } else {
never executed: end of block
0
1091 return QVariant();
never executed: return QVariant();
0
1092 }-
1093-
1094 return data;
never executed: return data;
0
1095}-
1096-
1097/*!-
1098 \since 4.2-
1099-
1100 Returns \c true if the text browser can go backward in the document history-
1101 using backward().-
1102-
1103 \sa backwardAvailable(), backward()-
1104*/-
1105bool QTextBrowser::isBackwardAvailable() const-
1106{-
1107 Q_D(const QTextBrowser);-
1108 return d->stack.count() > 1;
never executed: return d->stack.count() > 1;
0
1109}-
1110-
1111/*!-
1112 \since 4.2-
1113-
1114 Returns \c true if the text browser can go forward in the document history-
1115 using forward().-
1116-
1117 \sa forwardAvailable(), forward()-
1118*/-
1119bool QTextBrowser::isForwardAvailable() const-
1120{-
1121 Q_D(const QTextBrowser);-
1122 return !d->forwardStack.isEmpty();
never executed: return !d->forwardStack.isEmpty();
0
1123}-
1124-
1125/*!-
1126 \since 4.2-
1127-
1128 Clears the history of visited documents and disables the forward and-
1129 backward navigation.-
1130-
1131 \sa backward(), forward()-
1132*/-
1133void QTextBrowser::clearHistory()-
1134{-
1135 Q_D(QTextBrowser);-
1136 d->forwardStack.clear();-
1137 if (!d->stack.isEmpty()) {
!d->stack.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1138 QTextBrowserPrivate::HistoryEntry historyEntry = d->stack.top();-
1139 d->stack.resize(0);-
1140 d->stack.push(historyEntry);-
1141 d->home = historyEntry.url;-
1142 }
never executed: end of block
0
1143 emit forwardAvailable(false);-
1144 emit backwardAvailable(false);-
1145 emit historyChanged();-
1146}
never executed: end of block
0
1147-
1148/*!-
1149 Returns the url of the HistoryItem.-
1150-
1151 \table-
1152 \header \li Input \li Return-
1153 \row \li \a{i} < 0 \li \l backward() history-
1154 \row \li\a{i} == 0 \li current, see QTextBrowser::source()-
1155 \row \li \a{i} > 0 \li \l forward() history-
1156 \endtable-
1157-
1158 \since 4.4-
1159*/-
1160QUrl QTextBrowser::historyUrl(int i) const-
1161{-
1162 Q_D(const QTextBrowser);-
1163 return d->history(i).url;
never executed: return d->history(i).url;
0
1164}-
1165-
1166/*!-
1167 Returns the documentTitle() of the HistoryItem.-
1168-
1169 \table-
1170 \header \li Input \li Return-
1171 \row \li \a{i} < 0 \li \l backward() history-
1172 \row \li \a{i} == 0 \li current, see QTextBrowser::source()-
1173 \row \li \a{i} > 0 \li \l forward() history-
1174 \endtable-
1175-
1176 \snippet code/src_gui_widgets_qtextbrowser.cpp 0-
1177-
1178 \since 4.4-
1179*/-
1180QString QTextBrowser::historyTitle(int i) const-
1181{-
1182 Q_D(const QTextBrowser);-
1183 return d->history(i).title;
never executed: return d->history(i).title;
0
1184}-
1185-
1186-
1187/*!-
1188 Returns the number of locations forward in the history.-
1189-
1190 \since 4.4-
1191*/-
1192int QTextBrowser::forwardHistoryCount() const-
1193{-
1194 Q_D(const QTextBrowser);-
1195 return d->forwardStack.count();
never executed: return d->forwardStack.count();
0
1196}-
1197-
1198/*!-
1199 Returns the number of locations backward in the history.-
1200-
1201 \since 4.4-
1202*/-
1203int QTextBrowser::backwardHistoryCount() const-
1204{-
1205 Q_D(const QTextBrowser);-
1206 return d->stack.count()-1;
never executed: return d->stack.count()-1;
0
1207}-
1208-
1209/*!-
1210 \property QTextBrowser::openExternalLinks-
1211 \since 4.2-
1212-
1213 Specifies whether QTextBrowser should automatically open links to external-
1214 sources using QDesktopServices::openUrl() instead of emitting the-
1215 anchorClicked signal. Links are considered external if their scheme is-
1216 neither file or qrc.-
1217-
1218 The default value is false.-
1219*/-
1220bool QTextBrowser::openExternalLinks() const-
1221{-
1222 Q_D(const QTextBrowser);-
1223 return d->openExternalLinks;
never executed: return d->openExternalLinks;
0
1224}-
1225-
1226void QTextBrowser::setOpenExternalLinks(bool open)-
1227{-
1228 Q_D(QTextBrowser);-
1229 d->openExternalLinks = open;-
1230}
never executed: end of block
0
1231-
1232/*!-
1233 \property QTextBrowser::openLinks-
1234 \since 4.3-
1235-
1236 This property specifies whether QTextBrowser should automatically open links the user tries to-
1237 activate by mouse or keyboard.-
1238-
1239 Regardless of the value of this property the anchorClicked signal is always emitted.-
1240-
1241 The default value is true.-
1242*/-
1243-
1244bool QTextBrowser::openLinks() const-
1245{-
1246 Q_D(const QTextBrowser);-
1247 return d->openLinks;
never executed: return d->openLinks;
0
1248}-
1249-
1250void QTextBrowser::setOpenLinks(bool open)-
1251{-
1252 Q_D(QTextBrowser);-
1253 d->openLinks = open;-
1254}
never executed: end of block
0
1255-
1256/*! \reimp */-
1257bool QTextBrowser::event(QEvent *e)-
1258{-
1259 return QTextEdit::event(e);
never executed: return QTextEdit::event(e);
0
1260}-
1261-
1262QT_END_NAMESPACE-
1263-
1264#include "moc_qtextbrowser.cpp"-
1265-
1266#endif // QT_NO_TEXTBROWSER-
Source codeSwitch to Preprocessed file

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