/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** 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 Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/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. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt 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 #include #include #include #include #include #include #include #include #include #include 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 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); webViewIconChanged(); } 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(loadFinished(bool)), this, SLOT(webViewIconChanged())); 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() { QUrl url = (m_webView) ? m_webView->url() : QUrl(); QIcon icon = BrowserApplication::instance()->icon(url); QPixmap pixmap(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); } }