- Qt 5.5
- Qt WebEngine Widgets
- WebEngine Tab Browser Example
- urllineedit.cpp Example File
- Qt 5.5.1 Reference Documentation

# urllineedit.cpp Example File

browser/urllineedit.cpp

    /****************************************************************************
    **
    ** Copyright (C) 2015 The Qt Company Ltd.
    ** Contact: http://www.qt.io/licensing/
    **
    ** This file is part of the demonstration applications of the Qt Toolkit.
    **
    ** $QT_BEGIN_LICENSE:LGPL$
    ** Commercial License Usage
    ** Licensees holding valid commercial Qt licenses may use this file in
    ** accordance with the commercial license agreement provided with the
    ** Software or, alternatively, in accordance with the terms contained in
    ** a written agreement between you and The Qt Company. For licensing terms
    ** and conditions see http://www.qt.io/terms-conditions. For further
    ** information use the contact form at http://www.qt.io/contact-us.
    **
    ** GNU Lesser General Public License Usage
    ** Alternatively, this file may be used under the terms of the GNU Lesser
    ** General Public License version 2.1 as published by the Free Software
    ** Foundation and appearing in the file LICENSE.LGPL included in the
    ** packaging of this file. Please review the following information to
    ** ensure the GNU Lesser General Public License version 2.1 requirements
    ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    **
    ** As a special exception, The Qt Company gives you certain additional
    ** rights. These rights are described in The Qt Company LGPL Exception
    ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    **
    ** GNU General Public License Usage
    ** Alternatively, this file may be used under the terms of the GNU
    ** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be
    ** met: http://www.gnu.org/copyleft/gpl.html.
    **
    **
    ** $QT_END_LICENSE$
    **
    ****************************************************************************/

    #include "urllineedit.h"

    #include "browserapplication.h"
    #include "searchlineedit.h"
    #include "webview.h"

    #include <QtCore/QEvent>
    #include <QtCore/QMimeData>

    #include <QtWidgets/QApplication>
    #include <QtWidgets/QCompleter>
    #include <QtGui/QFocusEvent>
    #include <QtWidgets/QHBoxLayout>
    #include <QtWidgets/QLabel>
    #include <QtWidgets/QLineEdit>
    #include <QtGui/QDrag>
    #include <QtGui/QPainter>
    #include <QtWidgets/QStyle>
    #include <QtWidgets/QStyleOptionFrameV2>

    #include <QtCore/QDebug>

    ExLineEdit::ExLineEdit(QWidget *parent)
        : QWidget(parent)
        , m_leftWidget(0)
        , m_lineEdit(new QLineEdit(this))
        , m_clearButton(0)
    {
        setFocusPolicy(m_lineEdit->focusPolicy());
        setAttribute(Qt::WA_InputMethodEnabled);
        setSizePolicy(m_lineEdit->sizePolicy());
        setBackgroundRole(m_lineEdit->backgroundRole());
        setMouseTracking(true);
        setAcceptDrops(true);
        setAttribute(Qt::WA_MacShowFocusRect, true);
        QPalette p = m_lineEdit->palette();
        setPalette(p);

        // line edit
        m_lineEdit->setFrame(false);
        m_lineEdit->setFocusProxy(this);
        m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
        QPalette clearPalette = m_lineEdit->palette();
        clearPalette.setBrush(QPalette::Base, QBrush(Qt::transparent));
        m_lineEdit->setPalette(clearPalette);

        // clearButton
        m_clearButton = new ClearButton(this);
        connect(m_clearButton, SIGNAL(clicked()),
                m_lineEdit, SLOT(clear()));
        connect(m_lineEdit, SIGNAL(textChanged(QString)),
                m_clearButton, SLOT(textChanged(QString)));
    }

    void ExLineEdit::setLeftWidget(QWidget *widget)
    {
        m_leftWidget = widget;
    }

    QWidget *ExLineEdit::leftWidget() const
    {
        return m_leftWidget;
    }

    void ExLineEdit::resizeEvent(QResizeEvent *event)
    {
        Q_ASSERT(m_leftWidget);
        updateGeometries();
        QWidget::resizeEvent(event);
    }

    void ExLineEdit::updateGeometries()
    {
        QStyleOptionFrameV2 panel;
        initStyleOption(&panel);
        QRect rect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);

        int height = rect.height();
        int width = rect.width();

        int m_leftWidgetHeight = m_leftWidget->height();
        m_leftWidget->setGeometry(rect.x() + 2,          rect.y() + (height - m_leftWidgetHeight)/2,
                                  m_leftWidget->width(), m_leftWidget->height());

        int clearButtonWidth = this->height();
        m_lineEdit->setGeometry(m_leftWidget->x() + m_leftWidget->width(),        0,
                                width - clearButtonWidth - m_leftWidget->width(), this->height());

        m_clearButton->setGeometry(this->width() - clearButtonWidth, 0,
                                   clearButtonWidth, this->height());
    }

    void ExLineEdit::initStyleOption(QStyleOptionFrameV2 *option) const
    {
        option->initFrom(this);
        option->rect = contentsRect();
        option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this);
        option->midLineWidth = 0;
        option->state |= QStyle::State_Sunken;
        if (m_lineEdit->isReadOnly())
            option->state |= QStyle::State_ReadOnly;
    #ifdef QT_KEYPAD_NAVIGATION
        if (hasEditFocus())
            option->state |= QStyle::State_HasEditFocus;
    #endif
        option->features = QStyleOptionFrameV2::None;
    }

    QSize ExLineEdit::sizeHint() const
    {
        m_lineEdit->setFrame(true);
        QSize size = m_lineEdit->sizeHint();
        m_lineEdit->setFrame(false);
        return size;
    }

    void ExLineEdit::focusInEvent(QFocusEvent *event)
    {
        m_lineEdit->event(event);
        QWidget::focusInEvent(event);
    }

    void ExLineEdit::focusOutEvent(QFocusEvent *event)
    {
        m_lineEdit->event(event);

        if (m_lineEdit->completer()) {
            connect(m_lineEdit->completer(), SIGNAL(activated(QString)),
                             m_lineEdit, SLOT(setText(QString)));
            connect(m_lineEdit->completer(), SIGNAL(highlighted(QString)),
                             m_lineEdit, SLOT(_q_completionHighlighted(QString)));
        }
        QWidget::focusOutEvent(event);
    }

    void ExLineEdit::keyPressEvent(QKeyEvent *event)
    {
        m_lineEdit->event(event);
    }

    bool ExLineEdit::event(QEvent *event)
    {
        if (event->type() == QEvent::ShortcutOverride)
            return m_lineEdit->event(event);
        return QWidget::event(event);
    }

    void ExLineEdit::paintEvent(QPaintEvent *)
    {
        QPainter p(this);
        QStyleOptionFrameV2 panel;
        initStyleOption(&panel);
        style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
    }

    QVariant ExLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
    {
        return m_lineEdit->inputMethodQuery(property);
    }

    void ExLineEdit::inputMethodEvent(QInputMethodEvent *e)
    {
        m_lineEdit->event(e);
    }

    class UrlIconLabel : public QLabel
    {

    public:
        UrlIconLabel(QWidget *parent);

        WebView *m_webView;

    protected:
        void mousePressEvent(QMouseEvent *event);
        void mouseMoveEvent(QMouseEvent *event);

    private:
        QPoint m_dragStartPos;

    };

    UrlIconLabel::UrlIconLabel(QWidget *parent)
        : QLabel(parent)
        , m_webView(0)
    {
        setMinimumWidth(16);
        setMinimumHeight(16);
    }

    void UrlIconLabel::mousePressEvent(QMouseEvent *event)
    {
        if (event->button() == Qt::LeftButton)
            m_dragStartPos = event->pos();
        QLabel::mousePressEvent(event);
    }

    void UrlIconLabel::mouseMoveEvent(QMouseEvent *event)
    {
        if (event->buttons() == Qt::LeftButton
            && (event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance()
             && m_webView) {
            QDrag *drag = new QDrag(this);
            QMimeData *mimeData = new QMimeData;
            mimeData->setText(QString::fromUtf8(m_webView->url().toEncoded()));
            QList<QUrl> urls;
            urls.append(m_webView->url());
            mimeData->setUrls(urls);
            drag->setMimeData(mimeData);
            drag->exec();
        }
    }

    UrlLineEdit::UrlLineEdit(QWidget *parent)
        : ExLineEdit(parent)
        , m_webView(0)
        , m_iconLabel(0)
    {
        // icon
        m_iconLabel = new UrlIconLabel(this);
        m_iconLabel->resize(16, 16);
        setLeftWidget(m_iconLabel);
        m_defaultBaseColor = palette().color(QPalette::Base);
    }

    void UrlLineEdit::setWebView(WebView *webView)
    {
        Q_ASSERT(!m_webView);
        m_webView = webView;
        m_iconLabel->m_webView = webView;
        connect(webView, SIGNAL(urlChanged(QUrl)),
            this, SLOT(webViewUrlChanged(QUrl)));
        connect(webView, SIGNAL(iconChanged()),
            this, SLOT(webViewIconChanged()));
        connect(webView, SIGNAL(loadProgress(int)),
            this, SLOT(update()));
    }

    void UrlLineEdit::webViewUrlChanged(const QUrl &url)
    {
        m_lineEdit->setText(QString::fromUtf8(url.toEncoded()));
        m_lineEdit->setCursorPosition(0);
    }

    void UrlLineEdit::webViewIconChanged()
    {
        Q_ASSERT(m_webView);
        QPixmap pixmap = m_webView->icon().pixmap(16, 16);
        m_iconLabel->setPixmap(pixmap);
    }

    QLinearGradient UrlLineEdit::generateGradient(const QColor &color) const
    {
        QLinearGradient gradient(0, 0, 0, height());
        gradient.setColorAt(0, m_defaultBaseColor);
        gradient.setColorAt(0.15, color.lighter(120));
        gradient.setColorAt(0.5, color);
        gradient.setColorAt(0.85, color.lighter(120));
        gradient.setColorAt(1, m_defaultBaseColor);
        return gradient;
    }

    void UrlLineEdit::focusOutEvent(QFocusEvent *event)
    {
        if (m_lineEdit->text().isEmpty() && m_webView)
            m_lineEdit->setText(QString::fromUtf8(m_webView->url().toEncoded()));
        ExLineEdit::focusOutEvent(event);
    }

    void UrlLineEdit::paintEvent(QPaintEvent *event)
    {
        QPalette p = palette();
        if (m_webView && m_webView->url().scheme() == QLatin1String("https")) {
            QColor lightYellow(248, 248, 210);
            p.setBrush(QPalette::Base, generateGradient(lightYellow));
        } else {
            p.setBrush(QPalette::Base, m_defaultBaseColor);
        }
        setPalette(p);
        ExLineEdit::paintEvent(event);

        QPainter painter(this);
        QStyleOptionFrameV2 panel;
        initStyleOption(&panel);
        QRect backgroundRect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
        if (m_webView && !hasFocus()) {
            int progress = m_webView->progress();
            QColor loadingColor = QColor(116, 192, 250);
            painter.setBrush(generateGradient(loadingColor));
            painter.setPen(Qt::transparent);
            int mid = backgroundRect.width() / 100 * progress;
            QRect progressRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height());
            painter.drawRect(progressRect);
        }
    }