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

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