⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qtextbrowser.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qtextbrowser.h"#include "qtextedit_p.h"#ifndef QT_NO_TEXTBROWSER#include <qstack.h>#include <qapplication.h>#include <qevent.h>#include <qdesktopwidget.h>#include <qdebug.h>#include <qabstracttextdocumentlayout.h>#include "private/qtextdocumentlayout_p.h"#include <qtextcodec.h>#include <qpainter.h>#include <qdir.h>#include <qwhatsthis.h>#include <qtextobject.h>#include <qdesktopservices.h>class QTextBrowserPrivate : public QTextEditPrivate{    Q_DECLARE_PUBLIC(QTextBrowser)public:    inline QTextBrowserPrivate()        : textOrSourceChanged(false), forceLoadOnSourceChange(false), openExternalLinks(false),          openLinks(true)#ifdef QT_KEYPAD_NAVIGATION        , lastKeypadScrollValue(-1)#endif    {}    void init();    struct HistoryEntry {        inline HistoryEntry()            : hpos(0), vpos(0), focusIndicatorPosition(-1),              focusIndicatorAnchor(-1) {}        QUrl url;        int hpos;        int vpos;        int focusIndicatorPosition, focusIndicatorAnchor;    };    HistoryEntry createHistoryEntry() const;    void restoreHistoryEntry(const HistoryEntry entry);    QStack<HistoryEntry> stack;    QStack<HistoryEntry> forwardStack;    QUrl home;    QUrl currentURL;    QStringList searchPaths;    /*flag necessary to give the linkClicked() signal some meaningful      semantics when somebody connected to it calls setText() or      setSource() */    bool textOrSourceChanged;    bool forceLoadOnSourceChange;    bool openExternalLinks;    bool openLinks;#ifndef QT_NO_CURSOR    QCursor oldCursor;#endif    QString findFile(const QUrl &name) const;    inline void _q_documentModified()    {        textOrSourceChanged = true;        forceLoadOnSourceChange = !currentURL.path().isEmpty();    }    void _q_activateAnchor(const QString &href);    void _q_highlightLink(const QString &href);    void setSource(const QUrl &url);    QUrl resolveUrl(const QUrl &url) const;#ifdef QT_KEYPAD_NAVIGATION    void keypadMove(bool next);    QTextCursor prevFocus;    int lastKeypadScrollValue;#endif};static bool isAbsoluteFileName(const QString &name){    return !name.isEmpty()           && (name[0] == QLatin1Char('/')#if defined(Q_WS_WIN)               || (name[0].isLetter() && name[1] == QLatin1Char(':')) || name.startsWith(QLatin1String("\\\\"))#endif               || (name[0]  == QLatin1Char(':') && name[1] == QLatin1Char('/'))              );}QString QTextBrowserPrivate::findFile(const QUrl &name) const{    QString fileName;    if (name.scheme() == QLatin1String("qrc"))        fileName = QLatin1String(":/") + name.path();    else        fileName = name.toLocalFile();    if (isAbsoluteFileName(fileName))        return fileName;    foreach (QString path, searchPaths) {        if (!path.endsWith(QLatin1Char('/')))            path.append(QLatin1Char('/'));        path.append(fileName);        if (QFileInfo(path).isReadable())            return path;    }    return fileName;}QUrl QTextBrowserPrivate::resolveUrl(const QUrl &url) const{    if (!url.isRelative())        return url;    // For the second case QUrl can merge "#someanchor" with "foo.html"    // correctly to "foo.html#someanchor"    if (!(currentURL.isRelative()          || (currentURL.scheme() == QLatin1String("file")              && !isAbsoluteFileName(currentURL.toLocalFile())))          || (url.hasFragment() && url.path().isEmpty())) {        return currentURL.resolved(url);    }    // this is our last resort when current url and new url are both relative    // we try to resolve against the current working directory in the local    // file system.    QFileInfo fi(currentURL.toLocalFile());    if (fi.exists()) {        return QUrl::fromLocalFile(fi.absolutePath() + QDir::separator()).resolved(url);    }    return url;}void QTextBrowserPrivate::_q_activateAnchor(const QString &href){    if (href.isEmpty())        return;    Q_Q(QTextBrowser);#ifndef QT_NO_CURSOR    viewport->setCursor(oldCursor);#endif    const QUrl url = resolveUrl(href);    if (!openLinks) {        emit q->anchorClicked(url);        return;    }    textOrSourceChanged = false;#ifndef QT_NO_DESKTOPSERVICES    if (openExternalLinks        && url.scheme() != QLatin1String("file")        && url.scheme() != QLatin1String("qrc")) {        QDesktopServices::openUrl(url);        return;    }#endif    emit q->anchorClicked(url);    if (textOrSourceChanged)        return;    q->setSource(url);}void QTextBrowserPrivate::_q_highlightLink(const QString &anchor){    Q_Q(QTextBrowser);    if (anchor.isEmpty()) {#ifndef QT_NO_CURSOR        if (viewport->cursor().shape() != Qt::PointingHandCursor)            oldCursor = viewport->cursor();        viewport->setCursor(oldCursor);#endif        emit q->highlighted(QUrl());        emit q->highlighted(QString());    } else {#ifndef QT_NO_CURSOR        viewport->setCursor(Qt::PointingHandCursor);#endif        const QUrl url = resolveUrl(anchor);        emit q->highlighted(url);        // convenience to ease connecting to QStatusBar::showMessage(const QString &)        emit q->highlighted(url.toString());    }}void QTextBrowserPrivate::setSource(const QUrl &url){    Q_Q(QTextBrowser);#ifndef QT_NO_CURSOR    if (q->isVisible())        qApp->setOverrideCursor(Qt::WaitCursor);#endif    textOrSourceChanged = true;    QString txt;    bool doSetText = false;    QUrl currentUrlWithoutFragment = currentURL;    currentUrlWithoutFragment.setFragment(QString());    QUrl newUrlWithoutFragment = currentURL.resolved(url);    newUrlWithoutFragment.setFragment(QString());    if (url.isValid()        && (newUrlWithoutFragment != currentUrlWithoutFragment || forceLoadOnSourceChange)) {        QVariant data = q->loadResource(QTextDocument::HtmlResource, resolveUrl(url));        if (data.type() == QVariant::String) {            txt = data.toString();        } else if (data.type() == QVariant::ByteArray) {#ifndef QT_NO_TEXTCODEC            QByteArray ba = data.toByteArray();            QTextCodec *codec = Qt::codecForHtml(ba);            txt = codec->toUnicode(ba);#else	    txt = data.toString();#endif        }        if (txt.isEmpty())            qWarning("QTextBrowser: No document for %s", url.toString().toLatin1().constData());        if (q->isVisible()) {            QString firstTag = txt.left(txt.indexOf(QLatin1Char('>')) + 1);            if (firstTag.left(3) == QLatin1String("<qt") && firstTag.contains(QLatin1String("type")) && firstTag.contains(QLatin1String("detail"))) {#ifndef QT_NO_CURSOR                qApp->restoreOverrideCursor();#endif#ifndef QT_NO_WHATSTHIS                QWhatsThis::showText(QCursor::pos(), txt, q);#endif                return;            }        }        currentURL = resolveUrl(url);        doSetText = true;    }    if (!home.isValid())        home = url;    if (doSetText) {        q->QTextEdit::setHtml(txt);#ifdef QT_KEYPAD_NAVIGATION        prevFocus.movePosition(QTextCursor::Start);#endif    }    forceLoadOnSourceChange = false;    if (!url.fragment().isEmpty()) {        q->scrollToAnchor(url.fragment());    } else {        hbar->setValue(0);        vbar->setValue(0);    }#ifdef QT_KEYPAD_NAVIGATION     lastKeypadScrollValue = vbar->value(); #endif #ifndef QT_NO_CURSOR    if (q->isVisible())        qApp->restoreOverrideCursor();#endif    emit q->sourceChanged(url);}#ifdef QT_KEYPAD_NAVIGATIONvoid QTextBrowserPrivate::keypadMove(bool next){    Q_Q(QTextBrowser);    const int height = viewport->height();    const int overlap = qBound(20, height / 5, 40); // XXX arbitrary, but a good balance    const int visibleLinkAmount = overlap; // consistent, but maybe not the best choice (?)    int yOffset = vbar->value();    int scrollYOffset = qBound(0, next ? yOffset + height - overlap : yOffset - height + overlap, vbar->maximum());    bool foundNextAnchor = false;    bool focusIt = false;    int focusedPos = -1;    QTextCursor anchorToFocus;    QRectF viewRect = QRectF(0, yOffset, control->size().width(), height);    QRectF newViewRect = QRectF(0, scrollYOffset, control->size().width(), height);    QRectF bothViewRects = viewRect.united(newViewRect);    // If we don't have a previous anchor, pretend that we had the first/last character    // on the screen selected.    if (prevFocus.isNull()) {        if (next)            prevFocus = control->cursorForPosition(QPointF(0, yOffset));        else            prevFocus = control->cursorForPosition(QPointF(control->size().width(), yOffset + height));    }    // First, check to see if someone has moved the scroll bars independently    if (lastKeypadScrollValue != yOffset) {        // Someone (user or programmatically) has moved us, so we might        // need to start looking from the current position instead of prevFocus        bool findOnScreen = true;        // If prevFocus is on screen at all, we just use it.        if (prevFocus.hasSelection()) {            QRectF prevRect = control->selectionRect(prevFocus);            if (viewRect.intersects(prevRect))                findOnScreen = false;        }        // Otherwise, we find a new anchor that's on screen.        // Basically, create a cursor with the last/first character        // on screen        if (findOnScreen) {            if (next)                prevFocus = control->cursorForPosition(QPointF(0, yOffset));            else                prevFocus = control->cursorForPosition(QPointF(control->size().width(), yOffset + height));        }        foundNextAnchor = control->findNextPrevAnchor(prevFocus, next, anchorToFocus);    } else if (prevFocus.hasSelection()) {        // Check the pathological case that the current anchor is higher        // than the screen, and just scroll through it in that case        QRectF prevRect = control->selectionRect(prevFocus);        if ((next && prevRect.bottom() > (yOffset + height)) ||                (!next && prevRect.top() < yOffset)) {            anchorToFocus = prevFocus;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -