demos/browser/urllineedit.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the demonstration applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "urllineedit.h"
       
    43 
       
    44 #include "browserapplication.h"
       
    45 #include "searchlineedit.h"
       
    46 #include "webview.h"
       
    47 
       
    48 #include <QtCore/QEvent>
       
    49 
       
    50 #include <QtGui/QApplication>
       
    51 #include <QtGui/QCompleter>
       
    52 #include <QtGui/QFocusEvent>
       
    53 #include <QtGui/QHBoxLayout>
       
    54 #include <QtGui/QLabel>
       
    55 #include <QtGui/QLineEdit>
       
    56 #include <QtGui/QPainter>
       
    57 #include <QtGui/QStyle>
       
    58 #include <QtGui/QStyleOptionFrameV2>
       
    59 
       
    60 #include <QtCore/QDebug>
       
    61 
       
    62 ExLineEdit::ExLineEdit(QWidget *parent)
       
    63     : QWidget(parent)
       
    64     , m_leftWidget(0)
       
    65     , m_lineEdit(new QLineEdit(this))
       
    66     , m_clearButton(0)
       
    67 {
       
    68     setFocusPolicy(m_lineEdit->focusPolicy());
       
    69     setAttribute(Qt::WA_InputMethodEnabled);
       
    70     setSizePolicy(m_lineEdit->sizePolicy());
       
    71     setBackgroundRole(m_lineEdit->backgroundRole());
       
    72     setMouseTracking(true);
       
    73     setAcceptDrops(true);
       
    74     setAttribute(Qt::WA_MacShowFocusRect, true);
       
    75     QPalette p = m_lineEdit->palette();
       
    76     setPalette(p);
       
    77 
       
    78     // line edit
       
    79     m_lineEdit->setFrame(false);
       
    80     m_lineEdit->setFocusProxy(this);
       
    81     m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
       
    82     QPalette clearPalette = m_lineEdit->palette();
       
    83     clearPalette.setBrush(QPalette::Base, QBrush(Qt::transparent));
       
    84     m_lineEdit->setPalette(clearPalette);
       
    85 
       
    86     // clearButton
       
    87     m_clearButton = new ClearButton(this);
       
    88     connect(m_clearButton, SIGNAL(clicked()),
       
    89             m_lineEdit, SLOT(clear()));
       
    90     connect(m_lineEdit, SIGNAL(textChanged(const QString&)),
       
    91             m_clearButton, SLOT(textChanged(const QString&)));
       
    92 }
       
    93 
       
    94 void ExLineEdit::setLeftWidget(QWidget *widget)
       
    95 {
       
    96     m_leftWidget = widget;
       
    97 }
       
    98 
       
    99 QWidget *ExLineEdit::leftWidget() const
       
   100 {
       
   101     return m_leftWidget;
       
   102 }
       
   103 
       
   104 void ExLineEdit::resizeEvent(QResizeEvent *event)
       
   105 {
       
   106     Q_ASSERT(m_leftWidget);
       
   107     updateGeometries();
       
   108     QWidget::resizeEvent(event);
       
   109 }
       
   110 
       
   111 void ExLineEdit::updateGeometries()
       
   112 {
       
   113     QStyleOptionFrameV2 panel;
       
   114     initStyleOption(&panel);
       
   115     QRect rect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
       
   116 
       
   117     int height = rect.height();
       
   118     int width = rect.width();
       
   119 
       
   120     int m_leftWidgetHeight = m_leftWidget->height();
       
   121     m_leftWidget->setGeometry(rect.x() + 2,          rect.y() + (height - m_leftWidgetHeight)/2,
       
   122                               m_leftWidget->width(), m_leftWidget->height());
       
   123 
       
   124     int clearButtonWidth = this->height();
       
   125     m_lineEdit->setGeometry(m_leftWidget->x() + m_leftWidget->width(),        0,
       
   126                             width - clearButtonWidth - m_leftWidget->width(), this->height());
       
   127 
       
   128     m_clearButton->setGeometry(this->width() - clearButtonWidth, 0,
       
   129                                clearButtonWidth, this->height());
       
   130 }
       
   131 
       
   132 void ExLineEdit::initStyleOption(QStyleOptionFrameV2 *option) const
       
   133 {
       
   134     option->initFrom(this);
       
   135     option->rect = contentsRect();
       
   136     option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this);
       
   137     option->midLineWidth = 0;
       
   138     option->state |= QStyle::State_Sunken;
       
   139     if (m_lineEdit->isReadOnly())
       
   140         option->state |= QStyle::State_ReadOnly;
       
   141 #ifdef QT_KEYPAD_NAVIGATION
       
   142     if (hasEditFocus())
       
   143         option->state |= QStyle::State_HasEditFocus;
       
   144 #endif
       
   145     option->features = QStyleOptionFrameV2::None;
       
   146 }
       
   147 
       
   148 QSize ExLineEdit::sizeHint() const
       
   149 {
       
   150     m_lineEdit->setFrame(true);
       
   151     QSize size = m_lineEdit->sizeHint();
       
   152     m_lineEdit->setFrame(false);
       
   153     return size;
       
   154 }
       
   155 
       
   156 void ExLineEdit::focusInEvent(QFocusEvent *event)
       
   157 {
       
   158     m_lineEdit->event(event);
       
   159     QWidget::focusInEvent(event);
       
   160 }
       
   161 
       
   162 void ExLineEdit::focusOutEvent(QFocusEvent *event)
       
   163 {
       
   164     m_lineEdit->event(event);
       
   165 
       
   166     if (m_lineEdit->completer()) {
       
   167         connect(m_lineEdit->completer(), SIGNAL(activated(QString)),
       
   168                          m_lineEdit, SLOT(setText(QString)));
       
   169         connect(m_lineEdit->completer(), SIGNAL(highlighted(QString)),
       
   170                          m_lineEdit, SLOT(_q_completionHighlighted(QString)));
       
   171     }
       
   172     QWidget::focusOutEvent(event);
       
   173 }
       
   174 
       
   175 void ExLineEdit::keyPressEvent(QKeyEvent *event)
       
   176 {
       
   177     m_lineEdit->event(event);
       
   178 }
       
   179 
       
   180 bool ExLineEdit::event(QEvent *event)
       
   181 {
       
   182     if (event->type() == QEvent::ShortcutOverride)
       
   183         return m_lineEdit->event(event);
       
   184     return QWidget::event(event);
       
   185 }
       
   186 
       
   187 void ExLineEdit::paintEvent(QPaintEvent *)
       
   188 {
       
   189     QPainter p(this);
       
   190     QStyleOptionFrameV2 panel;
       
   191     initStyleOption(&panel);
       
   192     style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
       
   193 }
       
   194 
       
   195 QVariant ExLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
       
   196 {
       
   197     return m_lineEdit->inputMethodQuery(property);
       
   198 }
       
   199 
       
   200 void ExLineEdit::inputMethodEvent(QInputMethodEvent *e)
       
   201 {
       
   202     m_lineEdit->event(e);
       
   203 }
       
   204 
       
   205 
       
   206 class UrlIconLabel : public QLabel
       
   207 {
       
   208 
       
   209 public:
       
   210     UrlIconLabel(QWidget *parent);
       
   211 
       
   212     WebView *m_webView;
       
   213 
       
   214 protected:
       
   215     void mousePressEvent(QMouseEvent *event);
       
   216     void mouseMoveEvent(QMouseEvent *event);
       
   217 
       
   218 private:
       
   219     QPoint m_dragStartPos;
       
   220 
       
   221 };
       
   222 
       
   223 UrlIconLabel::UrlIconLabel(QWidget *parent)
       
   224     : QLabel(parent)
       
   225     , m_webView(0)
       
   226 {
       
   227     setMinimumWidth(16);
       
   228     setMinimumHeight(16);
       
   229 }
       
   230 
       
   231 void UrlIconLabel::mousePressEvent(QMouseEvent *event)
       
   232 {
       
   233     if (event->button() == Qt::LeftButton)
       
   234         m_dragStartPos = event->pos();
       
   235     QLabel::mousePressEvent(event);
       
   236 }
       
   237 
       
   238 void UrlIconLabel::mouseMoveEvent(QMouseEvent *event)
       
   239 {
       
   240     if (event->buttons() == Qt::LeftButton
       
   241         && (event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance()
       
   242          && m_webView) {
       
   243         QDrag *drag = new QDrag(this);
       
   244         QMimeData *mimeData = new QMimeData;
       
   245         mimeData->setText(QString::fromUtf8(m_webView->url().toEncoded()));
       
   246         QList<QUrl> urls;
       
   247         urls.append(m_webView->url());
       
   248         mimeData->setUrls(urls);
       
   249         drag->setMimeData(mimeData);
       
   250         drag->exec();
       
   251     }
       
   252 }
       
   253 
       
   254 UrlLineEdit::UrlLineEdit(QWidget *parent)
       
   255     : ExLineEdit(parent)
       
   256     , m_webView(0)
       
   257     , m_iconLabel(0)
       
   258 {
       
   259     // icon
       
   260     m_iconLabel = new UrlIconLabel(this);
       
   261     m_iconLabel->resize(16, 16);
       
   262     setLeftWidget(m_iconLabel);
       
   263     m_defaultBaseColor = palette().color(QPalette::Base);
       
   264 
       
   265     webViewIconChanged();
       
   266 }
       
   267 
       
   268 void UrlLineEdit::setWebView(WebView *webView)
       
   269 {
       
   270     Q_ASSERT(!m_webView);
       
   271     m_webView = webView;
       
   272     m_iconLabel->m_webView = webView;
       
   273     connect(webView, SIGNAL(urlChanged(const QUrl &)),
       
   274         this, SLOT(webViewUrlChanged(const QUrl &)));
       
   275     connect(webView, SIGNAL(loadFinished(bool)),
       
   276         this, SLOT(webViewIconChanged()));
       
   277     connect(webView, SIGNAL(iconChanged()),
       
   278         this, SLOT(webViewIconChanged()));
       
   279     connect(webView, SIGNAL(loadProgress(int)),
       
   280         this, SLOT(update()));
       
   281 }
       
   282 
       
   283 void UrlLineEdit::webViewUrlChanged(const QUrl &url)
       
   284 {
       
   285     m_lineEdit->setText(QString::fromUtf8(url.toEncoded()));
       
   286     m_lineEdit->setCursorPosition(0);
       
   287 }
       
   288 
       
   289 void UrlLineEdit::webViewIconChanged()
       
   290 {
       
   291     QUrl url = (m_webView)  ? m_webView->url() : QUrl();
       
   292     QIcon icon = BrowserApplication::instance()->icon(url);
       
   293     QPixmap pixmap(icon.pixmap(16, 16));
       
   294     m_iconLabel->setPixmap(pixmap);
       
   295 }
       
   296 
       
   297 QLinearGradient UrlLineEdit::generateGradient(const QColor &color) const
       
   298 {
       
   299     QLinearGradient gradient(0, 0, 0, height());
       
   300     gradient.setColorAt(0, m_defaultBaseColor);
       
   301     gradient.setColorAt(0.15, color.lighter(120));
       
   302     gradient.setColorAt(0.5, color);
       
   303     gradient.setColorAt(0.85, color.lighter(120));
       
   304     gradient.setColorAt(1, m_defaultBaseColor);
       
   305     return gradient;
       
   306 }
       
   307 
       
   308 void UrlLineEdit::focusOutEvent(QFocusEvent *event)
       
   309 {
       
   310     if (m_lineEdit->text().isEmpty() && m_webView)
       
   311         m_lineEdit->setText(QString::fromUtf8(m_webView->url().toEncoded()));
       
   312     ExLineEdit::focusOutEvent(event);
       
   313 }
       
   314 
       
   315 void UrlLineEdit::paintEvent(QPaintEvent *event)
       
   316 {
       
   317     QPalette p = palette();
       
   318     if (m_webView && m_webView->url().scheme() == QLatin1String("https")) {
       
   319         QColor lightYellow(248, 248, 210);
       
   320         p.setBrush(QPalette::Base, generateGradient(lightYellow));
       
   321     } else {
       
   322         p.setBrush(QPalette::Base, m_defaultBaseColor);
       
   323     }
       
   324     setPalette(p);
       
   325     ExLineEdit::paintEvent(event);
       
   326 
       
   327     QPainter painter(this);
       
   328     QStyleOptionFrameV2 panel;
       
   329     initStyleOption(&panel);
       
   330     QRect backgroundRect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
       
   331     if (m_webView && !hasFocus()) {
       
   332         int progress = m_webView->progress();
       
   333         QColor loadingColor = QColor(116, 192, 250);
       
   334         painter.setBrush(generateGradient(loadingColor));
       
   335         painter.setPen(Qt::transparent);
       
   336         int mid = backgroundRect.width() / 100 * progress;
       
   337         QRect progressRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height());
       
   338         painter.drawRect(progressRect);
       
   339     }
       
   340 }