WebKit2/UIProcess/API/qt/qwkpage.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
       
     3  *
       
     4  * This library is free software; you can redistribute it and/or
       
     5  * modify it under the terms of the GNU Library General Public
       
     6  * License as published by the Free Software Foundation; either
       
     7  * version 2 of the License, or (at your option) any later version.
       
     8  *
       
     9  * This program is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    12  * Library General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU Library General Public License
       
    15  * along with this program; see the file COPYING.LIB.  If not, write to
       
    16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    17  * Boston, MA 02110-1301, USA.
       
    18  *
       
    19  */
       
    20 
       
    21 #include "qwkpage.h"
       
    22 #include "qwkpage_p.h"
       
    23 
       
    24 #include "ClientImpl.h"
       
    25 #include "LocalizedStrings.h"
       
    26 #include "WebEventFactoryQt.h"
       
    27 #include "WKStringQt.h"
       
    28 #include "WKURLQt.h"
       
    29 #include <QAction>
       
    30 #include <QApplication>
       
    31 #include <QGraphicsSceneMouseEvent>
       
    32 #include <QStyle>
       
    33 #include <QtDebug>
       
    34 #include <WebKit2/WKFrame.h>
       
    35 #include <WebKit2/WKRetainPtr.h>
       
    36 
       
    37 using namespace WebKit;
       
    38 using namespace WebCore;
       
    39 
       
    40 QWKPagePrivate::QWKPagePrivate(QWKPage* qq, WKPageNamespaceRef namespaceRef)
       
    41     : q(qq)
       
    42     , createNewPageFn(0)
       
    43 {
       
    44     memset(actions, 0, sizeof(actions));
       
    45     page = toWK(namespaceRef)->createWebPage();
       
    46     page->setPageClient(this);
       
    47 }
       
    48 
       
    49 QWKPagePrivate::~QWKPagePrivate()
       
    50 {
       
    51     page->close();
       
    52 }
       
    53 
       
    54 void QWKPagePrivate::init(const QSize& viewportSize, DrawingAreaProxy* proxy)
       
    55 {
       
    56     page->initializeWebPage(IntSize(viewportSize), proxy);
       
    57 }
       
    58 
       
    59 void QWKPagePrivate::toolTipChanged(const String&, const String& newTooltip)
       
    60 {
       
    61     emit q->statusBarMessage(QString(newTooltip));
       
    62 }
       
    63 
       
    64 void QWKPagePrivate::paint(QPainter* painter, QRect area)
       
    65 {
       
    66     painter->save();
       
    67 
       
    68     painter->setBrush(Qt::white);
       
    69     painter->drawRect(area);
       
    70 
       
    71     if (page->isValid() && page->drawingArea())
       
    72         page->drawingArea()->paint(IntRect(area), painter);
       
    73 
       
    74     painter->restore();
       
    75 }
       
    76 
       
    77 void QWKPagePrivate::keyPressEvent(QKeyEvent* ev)
       
    78 {
       
    79     WebKeyboardEvent keyboardEvent = WebEventFactory::createWebKeyboardEvent(ev);
       
    80     page->keyEvent(keyboardEvent);
       
    81 }
       
    82 
       
    83 void QWKPagePrivate::keyReleaseEvent(QKeyEvent* ev)
       
    84 {
       
    85     WebKeyboardEvent keyboardEvent = WebEventFactory::createWebKeyboardEvent(ev);
       
    86     page->keyEvent(keyboardEvent);
       
    87 }
       
    88 
       
    89 void QWKPagePrivate::mouseMoveEvent(QGraphicsSceneMouseEvent* ev)
       
    90 {
       
    91     // For some reason mouse press results in mouse hover (which is
       
    92     // converted to mouse move for WebKit). We ignore these hover
       
    93     // events by comparing lastPos with newPos.
       
    94     // NOTE: lastPos from the event always comes empty, so we work
       
    95     // around that here.
       
    96     static QPointF lastPos = QPointF();
       
    97     if (lastPos == ev->pos())
       
    98         return;
       
    99     lastPos = ev->pos();
       
   100 
       
   101     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 0);
       
   102     page->mouseEvent(mouseEvent);
       
   103 }
       
   104 
       
   105 void QWKPagePrivate::mousePressEvent(QGraphicsSceneMouseEvent* ev)
       
   106 {
       
   107     if (tripleClickTimer.isActive() && (ev->pos() - tripleClick).manhattanLength() < QApplication::startDragDistance()) {
       
   108         WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 3);
       
   109         page->mouseEvent(mouseEvent);
       
   110         return;
       
   111     }
       
   112 
       
   113     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 1);
       
   114     page->mouseEvent(mouseEvent);
       
   115 }
       
   116 
       
   117 void QWKPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev)
       
   118 {
       
   119     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 0);
       
   120     page->mouseEvent(mouseEvent);
       
   121 }
       
   122 
       
   123 void QWKPagePrivate::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* ev)
       
   124 {
       
   125     WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 2);
       
   126     page->mouseEvent(mouseEvent);
       
   127 
       
   128     tripleClickTimer.start(QApplication::doubleClickInterval(), q);
       
   129     tripleClick = ev->pos().toPoint();
       
   130 }
       
   131 
       
   132 void QWKPagePrivate::wheelEvent(QGraphicsSceneWheelEvent* ev)
       
   133 {
       
   134     WebWheelEvent wheelEvent = WebEventFactory::createWebWheelEvent(ev);
       
   135     page->wheelEvent(wheelEvent);
       
   136 }
       
   137 
       
   138 void QWKPagePrivate::updateAction(QWKPage::WebAction action)
       
   139 {
       
   140 #ifdef QT_NO_ACTION
       
   141     Q_UNUSED(action)
       
   142 #else
       
   143     QAction* a = actions[action];
       
   144     if (!a)
       
   145         return;
       
   146 
       
   147     RefPtr<WebKit::WebFrameProxy> mainFrame = page->mainFrame();
       
   148     if (!mainFrame)
       
   149         return;
       
   150 
       
   151     bool enabled = a->isEnabled();
       
   152     bool checked = a->isChecked();
       
   153 
       
   154     switch (action) {
       
   155     case QWKPage::Back:
       
   156         enabled = page->canGoBack();
       
   157         break;
       
   158     case QWKPage::Forward:
       
   159         enabled = page->canGoForward();
       
   160         break;
       
   161     case QWKPage::Stop:
       
   162         enabled = !(WebFrameProxy::LoadStateFinished == mainFrame->loadState());
       
   163         break;
       
   164     case QWKPage::Reload:
       
   165         enabled = (WebFrameProxy::LoadStateFinished == mainFrame->loadState());
       
   166         break;
       
   167     default:
       
   168         break;
       
   169     }
       
   170 
       
   171     a->setEnabled(enabled);
       
   172 
       
   173     if (a->isCheckable())
       
   174         a->setChecked(checked);
       
   175 #endif // QT_NO_ACTION
       
   176 }
       
   177 
       
   178 void QWKPagePrivate::updateNavigationActions()
       
   179 {
       
   180     updateAction(QWKPage::Back);
       
   181     updateAction(QWKPage::Forward);
       
   182     updateAction(QWKPage::Stop);
       
   183     updateAction(QWKPage::Reload);
       
   184 }
       
   185 
       
   186 #ifndef QT_NO_ACTION
       
   187 void QWKPagePrivate::_q_webActionTriggered(bool checked)
       
   188 {
       
   189     QAction* a = qobject_cast<QAction*>(q->sender());
       
   190     if (!a)
       
   191         return;
       
   192     QWKPage::WebAction action = static_cast<QWKPage::WebAction>(a->data().toInt());
       
   193     q->triggerAction(action, checked);
       
   194 }
       
   195 #endif // QT_NO_ACTION
       
   196 
       
   197 QWKPage::QWKPage(WKPageNamespaceRef namespaceRef)
       
   198     : d(new QWKPagePrivate(this, namespaceRef))
       
   199 {
       
   200     WKPageLoaderClient loadClient = {
       
   201         0,      /* version */
       
   202         this,   /* clientInfo */
       
   203         qt_wk_didStartProvisionalLoadForFrame,
       
   204         qt_wk_didReceiveServerRedirectForProvisionalLoadForFrame,
       
   205         qt_wk_didFailProvisionalLoadWithErrorForFrame,
       
   206         qt_wk_didCommitLoadForFrame,
       
   207         qt_wk_didFinishLoadForFrame,
       
   208         qt_wk_didFailLoadWithErrorForFrame,
       
   209         qt_wk_didReceiveTitleForFrame,
       
   210         qt_wk_didFirstLayoutForFrame,
       
   211         qt_wk_didFirstVisuallyNonEmptyLayoutForFrame,
       
   212         qt_wk_didStartProgress,
       
   213         qt_wk_didChangeProgress,
       
   214         qt_wk_didFinishProgress,
       
   215         qt_wk_didBecomeUnresponsive,
       
   216         qt_wk_didBecomeResponsive
       
   217     };
       
   218     WKPageSetPageLoaderClient(pageRef(), &loadClient);
       
   219 
       
   220     WKPageUIClient uiClient = {
       
   221         0,      /* version */
       
   222         this,   /* clientInfo */
       
   223         qt_wk_createNewPage,
       
   224         qt_wk_showPage,
       
   225         qt_wk_close,
       
   226         qt_wk_runJavaScriptAlert,
       
   227     };
       
   228     WKPageSetPageUIClient(pageRef(), &uiClient);
       
   229 }
       
   230 
       
   231 QWKPage::~QWKPage()
       
   232 {
       
   233     delete d;
       
   234     WKPageTerminate(pageRef());
       
   235 }
       
   236 
       
   237 void QWKPage::timerEvent(QTimerEvent* ev)
       
   238 {
       
   239     int timerId = ev->timerId();
       
   240     if (timerId == d->tripleClickTimer.timerId())
       
   241         d->tripleClickTimer.stop();
       
   242     else
       
   243         QObject::timerEvent(ev);
       
   244 }
       
   245 
       
   246 WKPageRef QWKPage::pageRef() const
       
   247 {
       
   248     return toRef(d->page.get());
       
   249 }
       
   250 
       
   251 void QWKPage::setCreateNewPageFunction(CreateNewPageFn function)
       
   252 {
       
   253     d->createNewPageFn = function;
       
   254 }
       
   255 
       
   256 void QWKPage::load(const QUrl& url)
       
   257 {
       
   258     WKRetainPtr<WKURLRef> wkurl(WKURLCreateWithQUrl(url));
       
   259     WKPageLoadURL(pageRef(), wkurl.get());
       
   260 }
       
   261 
       
   262 void QWKPage::setUrl(const QUrl& url)
       
   263 {
       
   264     load(url);
       
   265 }
       
   266 
       
   267 QUrl QWKPage::url() const
       
   268 {
       
   269     WKRetainPtr<WKFrameRef> frame = WKPageGetMainFrame(pageRef());
       
   270     if (!frame)
       
   271         return QUrl();
       
   272     return WKURLCopyQUrl(WKFrameGetURL(frame.get()));
       
   273 }
       
   274 
       
   275 QString QWKPage::title() const
       
   276 {
       
   277     return WKStringCopyQString(WKPageGetTitle(pageRef()));
       
   278 }
       
   279 
       
   280 void QWKPage::setViewportSize(const QSize& size)
       
   281 {
       
   282     if (d->page->drawingArea())
       
   283         d->page->drawingArea()->setSize(IntSize(size));
       
   284 }
       
   285 
       
   286 #ifndef QT_NO_ACTION
       
   287 void QWKPage::triggerAction(WebAction action, bool)
       
   288 {
       
   289     switch (action) {
       
   290     case Back:
       
   291         d->page->goBack();
       
   292         break;
       
   293     case Forward:
       
   294         d->page->goForward();
       
   295         break;
       
   296     case Stop:
       
   297         d->page->stopLoading();
       
   298         break;
       
   299     case Reload:
       
   300         d->page->reload(/* reloadFromOrigin */ true);
       
   301         break;
       
   302     default:
       
   303         break;
       
   304     }
       
   305 }
       
   306 #endif // QT_NO_ACTION
       
   307 
       
   308 #ifndef QT_NO_ACTION
       
   309 QAction* QWKPage::action(WebAction action) const
       
   310 {
       
   311     if (action == QWKPage::NoWebAction || action >= WebActionCount)
       
   312         return 0;
       
   313 
       
   314     if (d->actions[action])
       
   315         return d->actions[action];
       
   316 
       
   317     QString text;
       
   318     QIcon icon;
       
   319     QStyle* style = qobject_cast<QApplication*>(QCoreApplication::instance())->style();
       
   320     bool checkable = false;
       
   321 
       
   322     switch (action) {
       
   323     case Back:
       
   324         text = contextMenuItemTagGoBack();
       
   325         icon = style->standardIcon(QStyle::SP_ArrowBack);
       
   326         break;
       
   327     case Forward:
       
   328         text = contextMenuItemTagGoForward();
       
   329         icon = style->standardIcon(QStyle::SP_ArrowForward);
       
   330         break;
       
   331     case Stop:
       
   332         text = contextMenuItemTagStop();
       
   333         icon = style->standardIcon(QStyle::SP_BrowserStop);
       
   334         break;
       
   335     case Reload:
       
   336         text = contextMenuItemTagReload();
       
   337         icon = style->standardIcon(QStyle::SP_BrowserReload);
       
   338         break;
       
   339     default:
       
   340         return 0;
       
   341         break;
       
   342     }
       
   343 
       
   344     if (text.isEmpty())
       
   345         return 0;
       
   346 
       
   347     QAction* a = new QAction(d->q);
       
   348     a->setText(text);
       
   349     a->setData(action);
       
   350     a->setCheckable(checkable);
       
   351     a->setIcon(icon);
       
   352 
       
   353     connect(a, SIGNAL(triggered(bool)), this, SLOT(_q_webActionTriggered(bool)));
       
   354 
       
   355     d->actions[action] = a;
       
   356     d->updateAction(action);
       
   357     return a;
       
   358 }
       
   359 #endif // QT_NO_ACTION
       
   360 
       
   361 #include "moc_qwkpage.cpp"