ginebra2/ContentViews/ScrollableWebContentView.cpp
changeset 6 1c3b8676e58c
child 9 b39122337a00
equal deleted inserted replaced
5:0f2326c2a325 6:1c3b8676e58c
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 *
       
     5 * This program is free software: you can redistribute it and/or modify
       
     6 * it under the terms of the GNU Lesser General Public License as published by
       
     7 * the Free Software Foundation, version 2.1 of the License.
       
     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
       
    12 * GNU Lesser General Public License for more details.
       
    13 *
       
    14 * You should have received a copy of the GNU Lesser General Public License
       
    15 * along with this program.  If not,
       
    16 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
       
    17 *
       
    18 * Description:
       
    19 *
       
    20 */
       
    21 
       
    22 #include "ScrollableWebContentView.h"
       
    23 
       
    24 #include "Gestures/GestureRecognizer.h"
       
    25 #include "Kinetics/KineticScroller.h"
       
    26 #include "ScrollableViewBase.h"
       
    27 #include "ViewportMetaDataParser.h"
       
    28 #include "WebContentAnimationItem.h"
       
    29 
       
    30 #include <QApplication>
       
    31 #include <QGraphicsScene>
       
    32 #include <QGraphicsSceneMouseEvent>
       
    33 #include <QGraphicsWebView>
       
    34 #include <QWebElement>
       
    35 #include <QWebHitTestResult>
       
    36 
       
    37 //Kinetic scroll constants
       
    38 static const int ScrollsPerSecond = 30;
       
    39 static const int MinimumScrollVelocity = 10;
       
    40 static const qreal AxisLockThreshold = .8;
       
    41 
       
    42 
       
    43 //Zooming constants
       
    44 static const int ZoomAnimationDuration = 300;   //ms. Zooming transition duration
       
    45 static const qreal ZoomStep = .5;               //Incremental zoom step
       
    46 const int TileUpdateEnableDelay = 500;         //Wait duration before tiling updates are enabled.
       
    47 
       
    48 namespace GVA {
       
    49 
       
    50 ScrollableWebContentView::ScrollableWebContentView(WebContentAnimationItem* webAnimationItem, QGraphicsItem* parent)
       
    51     : ScrollableViewBase(parent)
       
    52     , m_gestureRecognizer(this)
       
    53 {
       
    54     m_viewportMetaData = new ViewportMetaData();
       
    55 
       
    56     //Kinetic scroller settings
       
    57     //Sets the number of scrolls (frames) per second to sps.
       
    58     m_kineticScroller->setScrollsPerSecond(ScrollsPerSecond);
       
    59     //For elastic scroll in page edges
       
    60     m_kineticScroller->setOvershootPolicy(KineticScroller::OvershootWhenScrollable);
       
    61 
       
    62     //Gesture settings
       
    63     //For detecting scroll direction
       
    64     m_gestureRecognizer.setAxisLockThreshold(AxisLockThreshold);
       
    65     //To enable touch and drag scrolling
       
    66     m_gestureRecognizer.setMinimumVelocity(MinimumScrollVelocity);
       
    67 
       
    68     setWidget(webAnimationItem);
       
    69     //FIX ME : Revisit this code. Duplicate info sharing!
       
    70     webAnimationItem->setViewportMetaData(m_viewportMetaData);
       
    71 
       
    72 
       
    73     m_tileUpdateEnableTimer.setSingleShot(true);
       
    74     connect(&m_tileUpdateEnableTimer, SIGNAL(timeout()), webAnimationItem, SLOT(enableContentUpdates()));
       
    75 
       
    76     //Setup zooming animator
       
    77     m_zoomAnimator = new QPropertyAnimation(webAnimationItem, "geometry");
       
    78     m_zoomAnimator->setDuration(ZoomAnimationDuration);
       
    79     connect(m_zoomAnimator, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)), this, SLOT(zoomAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
       
    80 }
       
    81 
       
    82 ScrollableWebContentView::~ScrollableWebContentView()
       
    83 {
       
    84     delete m_viewportMetaData;
       
    85     delete m_kineticScroller;
       
    86 
       
    87     if(m_zoomAnimator) {
       
    88         m_zoomAnimator->stop();
       
    89         delete m_zoomAnimator;
       
    90     }
       
    91 }
       
    92 
       
    93 WebContentAnimationItem* ScrollableWebContentView::viewportWidget() const
       
    94 {
       
    95     return qobject_cast<WebContentAnimationItem*>(scrollWidget());
       
    96 }
       
    97 
       
    98 void ScrollableWebContentView::zoomToScreenCenter(bool zoomIn)
       
    99 {
       
   100     //If viewport metadata has user scalable false.
       
   101     //Do not zoom.
       
   102     if (!m_viewportMetaData->m_userScalable)
       
   103         return;
       
   104 
       
   105     qreal scale = 1;
       
   106     scale += ZoomStep;
       
   107 
       
   108     if (!zoomIn)
       
   109         scale = 1/scale;
       
   110 
       
   111     qreal curScale =  viewportWidget()->zoomScale();
       
   112 
       
   113     if (zoomIn && (curScale * scale > m_viewportMetaData->m_maximumScale))
       
   114         scale = m_viewportMetaData->m_maximumScale / curScale;
       
   115     else if (!zoomIn && (curScale * scale < m_viewportMetaData->m_minimumScale))
       
   116         scale = m_viewportMetaData->m_minimumScale / curScale;
       
   117 
       
   118     if(scale == 1.)
       
   119         return;
       
   120 
       
   121     //Screen center
       
   122     QPointF scrCenter(size().width()/2, size().height()/2);
       
   123     //Map screen center to document
       
   124     QPointF docPoint(viewportWidget()->mapFromScene(scrCenter));
       
   125     //Maintain that spot in the same point on the viewport
       
   126     QPointF docPointInScr(viewportWidget()->mapToParent(docPoint));
       
   127     startZoomAnimToItemHotspot(docPoint, docPointInScr, scale);
       
   128 }
       
   129 
       
   130 ZoomMetaData ScrollableWebContentView::currentPageInfo()
       
   131 {
       
   132     ZoomMetaData data;
       
   133 
       
   134     data.initialScale = m_viewportMetaData->m_initialScale;
       
   135     data.minScale = m_viewportMetaData->m_minimumScale;
       
   136     data.maxScale = m_viewportMetaData->m_maximumScale;
       
   137     data.userScalable = m_viewportMetaData->m_userScalable;
       
   138     data.m_specifiedWidth = m_viewportMetaData->m_specifiedData.m_width;
       
   139     data.m_specifiedHeight= m_viewportMetaData->m_specifiedData.m_height;
       
   140 
       
   141     data.rect = viewportWidget()->geometry();
       
   142     data.scale = viewportWidget()->zoomScale();
       
   143     data.webViewSize = viewportWidget()->webView()->geometry();
       
   144     data.viewportSize = size();
       
   145 
       
   146     return data;
       
   147 }
       
   148 
       
   149 void ScrollableWebContentView::setCurrentPageInfo(ZoomMetaData data)
       
   150 {
       
   151     m_viewportMetaData->m_initialScale = data.initialScale;
       
   152     m_viewportMetaData->m_minimumScale = data.minScale;
       
   153     m_viewportMetaData->m_maximumScale = data.maxScale;
       
   154     m_viewportMetaData->m_userScalable = data.userScalable;
       
   155     m_viewportMetaData->m_specifiedData.m_width = data.m_specifiedWidth;
       
   156     m_viewportMetaData->m_specifiedData.m_height = data.m_specifiedHeight;
       
   157     m_viewportMetaData->m_isValid = true;
       
   158 
       
   159     m_viewportMetaData->m_width = data.webViewSize.width();
       
   160     m_viewportMetaData->m_height = data.webViewSize.height();
       
   161 
       
   162     viewportWidget()->webView()->setGeometry(data.webViewSize);
       
   163     viewportWidget()->setZoomScale(data.scale, true);
       
   164     viewportWidget()->setGeometry(data.rect);
       
   165 
       
   166     if (data.viewportSize.width() != size().width())
       
   167         adjustViewportSize(data.viewportSize, size());
       
   168 }
       
   169 
       
   170 ZoomMetaData ScrollableWebContentView::defaultZoomData()
       
   171 {
       
   172     ZoomMetaData data;
       
   173 
       
   174     data.initialScale = m_viewportMetaData->m_initialScale;
       
   175     data.minScale = m_viewportMetaData->m_minimumScale;
       
   176     data.maxScale = m_viewportMetaData->m_maximumScale;
       
   177     data.userScalable = m_viewportMetaData->m_userScalable;
       
   178 
       
   179     data.scale = 1.0;
       
   180     data.rect = QRectF();
       
   181     data.webViewSize = QRectF();
       
   182     data.viewportSize = QSizeF();
       
   183 
       
   184     return data;
       
   185 }
       
   186 
       
   187 void ScrollableWebContentView::updatePreferredContentSize()
       
   188 {
       
   189     viewportWidget()->updatePreferredContentSize(QSize(m_viewportMetaData->m_width
       
   190                                                        , m_viewportMetaData->m_height));
       
   191 }
       
   192 
       
   193 void ScrollableWebContentView::setSuperPage()
       
   194 {
       
   195     m_viewportMetaData->m_initialScale = 1.;
       
   196     m_viewportMetaData->m_minimumScale = 1.;
       
   197     m_viewportMetaData->m_maximumScale = 1.;
       
   198     m_viewportMetaData->m_specifiedData.m_width = "device-width";
       
   199     m_viewportMetaData->m_specifiedData.m_height = "device-height";
       
   200     m_viewportMetaData->m_userScalable = false;
       
   201 
       
   202     QSize contentSize = viewportWidget()->contentsSize();
       
   203     QRect webViewRect(0, 0, size().width(), contentSize.height());
       
   204     viewportWidget()->webView()->setGeometry(webViewRect);
       
   205     viewportWidget()->setZoomScale(1., true);
       
   206     viewportWidget()->setGeometry(webViewRect);
       
   207 
       
   208     m_viewportMetaData->m_width = size().width();
       
   209     m_viewportMetaData->m_height = size().height();
       
   210     m_viewportMetaData->m_isValid = true;
       
   211 
       
   212     updatePreferredContentSize();
       
   213 }
       
   214 
       
   215 void ScrollableWebContentView::reset()
       
   216 {
       
   217     // TODO: INVESTIGATE: In the case of multiple windows loading pages simultaneously, it is possible
       
   218     // to be calling this slot on a signal from a frame that is not
       
   219     // the frame of the page saved here. It might be better to use 'sender' instead of
       
   220     // page->mainFrame() to get the metaData so that we use the meta data of the corresponding
       
   221     // frame
       
   222 
       
   223     QWebPage* page = viewportWidget()->webView()->page();
       
   224     if (!page)
       
   225         return;
       
   226 
       
   227     //Initialize viewport metadata
       
   228     m_viewportMetaData->reset();
       
   229 
       
   230     QWebFrame* frame = page->mainFrame();
       
   231     QMap<QString, QString> metaData = frame->metaData();
       
   232     QString viewportTag = metaData.value("viewport");
       
   233 
       
   234     QRect clientRect = geometry().toAlignedRect();
       
   235     ViewportMetaDataParser parser(clientRect);
       
   236     *m_viewportMetaData = parser.parse(viewportTag);
       
   237 
       
   238     updatePreferredContentSize();
       
   239     setViewportWidgetGeometry(QRectF(QPointF(),
       
   240                                      QSize(m_viewportMetaData->m_width, m_viewportMetaData->m_height)
       
   241                                      * m_viewportMetaData->m_initialScale));
       
   242 }
       
   243 
       
   244 void ScrollableWebContentView::contentsSizeChanged(const QSize& newContentSize)
       
   245 {
       
   246     QRect clientRect = geometry().toAlignedRect();
       
   247     m_viewportMetaData->updateViewportData(newContentSize, clientRect);
       
   248     viewportWidget()->resize(QSize(m_viewportMetaData->m_width, m_viewportMetaData->m_height)
       
   249                              * m_viewportMetaData->m_initialScale);
       
   250 }
       
   251 
       
   252 void ScrollableWebContentView::pageLoadFinished(bool ok)
       
   253 {
       
   254     Q_UNUSED(ok);
       
   255     QSize contentSize = viewportWidget()->contentsSize();
       
   256     QRect clientRect = geometry().toAlignedRect();
       
   257     m_viewportMetaData->updateViewportData(contentSize, clientRect);
       
   258 
       
   259     viewportWidget()->resize(QSize(m_viewportMetaData->m_width, m_viewportMetaData->m_height)
       
   260                              * m_viewportMetaData->m_initialScale);
       
   261     viewportWidget()->setZoomScale(m_viewportMetaData->m_initialScale, true);
       
   262 }
       
   263 
       
   264 bool ScrollableWebContentView::sceneEventFilter(QGraphicsItem* item, QEvent* event)
       
   265 {
       
   266     Q_UNUSED(item);
       
   267 
       
   268     bool handled = false;
       
   269     if (!isVisible())
       
   270         return handled;
       
   271 
       
   272     //Pass all events to recognizer
       
   273     handled  = m_gestureRecognizer.mouseEventFilter(static_cast<QGraphicsSceneMouseEvent *>(event));
       
   274     return handled;
       
   275 }
       
   276 
       
   277 void ScrollableWebContentView::handleGesture(GestureEvent* gestureEvent)
       
   278 {
       
   279     switch (gestureEvent->type()) {
       
   280     case GestureEvent::Touch:
       
   281         handlePress(gestureEvent);
       
   282         break;
       
   283     case GestureEvent::Release:
       
   284         handleRelease(gestureEvent);
       
   285         break;
       
   286     case GestureEvent::Pan:
       
   287         handlePan(gestureEvent);
       
   288         break;
       
   289     case GestureEvent::Flick:
       
   290         handleFlick(gestureEvent);
       
   291         break;
       
   292     case GestureEvent::DoubleTap:
       
   293         handleDoubleTap(gestureEvent);
       
   294         break;
       
   295     case GestureEvent::LongTap:
       
   296         handleLongTap(gestureEvent);
       
   297         break;
       
   298     default:
       
   299         break;
       
   300     }
       
   301 
       
   302 }
       
   303 
       
   304 void ScrollableWebContentView::handlePress(GestureEvent* gestureEvent)
       
   305 {
       
   306     m_kineticScroller->stop();
       
   307     QPointF pos = gestureEvent->position();
       
   308     sendEventToWebKit(QEvent::GraphicsSceneMousePress, pos);
       
   309 }
       
   310 
       
   311 void ScrollableWebContentView::handleRelease(GestureEvent* gestureEvent)
       
   312 {
       
   313     //Cache release event to send on release
       
   314     QPointF pos = gestureEvent->position();
       
   315     sendEventToWebKit(QEvent::GraphicsSceneMouseRelease, pos);
       
   316 }
       
   317 
       
   318 void ScrollableWebContentView::handleDoubleTap(GestureEvent* gestureEvent)
       
   319 {
       
   320     if (!m_viewportMetaData->m_userScalable)
       
   321         return;
       
   322 
       
   323     QRectF target;
       
   324     WebContentAnimationItem* webViewProxy = viewportWidget();
       
   325 
       
   326     // Contentview center is the focus hotspot
       
   327     QPointF viewTargetHotspot(size().width() / 2, size().height() / 2);
       
   328 
       
   329     //Get the focussable element rect from current touch position
       
   330     QPointF touchPoint = webViewProxy->mapFromScene(gestureEvent->position());
       
   331     QRectF zoomRect = webViewProxy->findZoomableRectForPoint(touchPoint);
       
   332 
       
   333     if (!zoomRect.isValid()) {
       
   334         //FIX ME: Add an event ignore animation
       
   335         return;
       
   336     }
       
   337 
       
   338     // target is the center of the identified rect x-wise
       
   339     // y-wise it's the place user touched
       
   340     QPointF hotspot(zoomRect.center().x(), touchPoint.y());
       
   341     qreal scale = size().width() / zoomRect.size().width();
       
   342     startZoomAnimToItemHotspot(hotspot, viewTargetHotspot, scale, zoomRect);
       
   343 }
       
   344 
       
   345 void ScrollableWebContentView::handlePan(GestureEvent* gestureEvent)
       
   346 {
       
   347     QPoint scrollPos = ScrollableViewBase::scrollPosition();
       
   348     m_kineticScroller->doPan(gestureEvent->delta());
       
   349     QPoint delta;
       
   350     delta.setX(-gestureEvent->delta().x());
       
   351     delta.setY(-gestureEvent->delta().y());
       
   352     emit viewScrolled(scrollPos, delta);
       
   353 }
       
   354 
       
   355 void ScrollableWebContentView::handleFlick(GestureEvent* gestureEvent)
       
   356 {
       
   357     QPoint scrollPos = ScrollableViewBase::scrollPosition();
       
   358     m_kineticScroller->doFlick(gestureEvent->velocity());
       
   359 }
       
   360 
       
   361 void ScrollableWebContentView::handleLongTap(GestureEvent* gestureEvent)
       
   362 {
       
   363     QWebPage* page = viewportWidget()->webView()->page();
       
   364     QPointF contextPt = viewportWidget()->webView()->mapFromScene(gestureEvent->position());
       
   365     QWebHitTestResult result = page->currentFrame()->hitTestContent(contextPt.toPoint());
       
   366 
       
   367     //Notify context menu observers
       
   368     emit contextEventObject(&result);
       
   369 }
       
   370 
       
   371 void ScrollableWebContentView::setViewportWidgetGeometry(const QRectF& r)
       
   372 {
       
   373     ScrollableViewBase::setScrollWidgetGeometry(r);
       
   374 }
       
   375 
       
   376 void ScrollableWebContentView::startZoomAnimToItemHotspot(const QPointF& hotspot, const QPointF& viewTargetHotspot, qreal scale,  QRectF target)
       
   377 {
       
   378     WebContentAnimationItem* animWidget = viewportWidget();
       
   379 
       
   380     QPointF newHotspot = hotspot * scale;
       
   381     QPointF newViewportOrigon = newHotspot - viewTargetHotspot;
       
   382     QRectF zoomedRect(-newViewportOrigon, animWidget->size() * scale);
       
   383 
       
   384     QRectF temp = adjustScrollWidgetRect(zoomedRect);
       
   385     qreal diff = qAbs(scrollWidget()->geometry().y() - temp.y());
       
   386 
       
   387     //FIX ME : Seperate the logic for centerzoom and block-focus zoom
       
   388     if (qFuzzyCompare(scrollWidget()->geometry().topLeft().x(), temp.topLeft().x())
       
   389         && qFuzzyCompare(scrollWidget()->geometry().width(), temp.width())
       
   390         && qFuzzyCompare(scrollWidget()->geometry().height(), temp.height())
       
   391         && !target.isEmpty() && (diff <= target.height())) {
       
   392 
       
   393             scale = size().width() / animWidget->size().width();
       
   394             newHotspot = QPointF(0, -animWidget->pos().y()) * scale;
       
   395             newViewportOrigon = newHotspot - viewTargetHotspot;
       
   396             zoomedRect = QRectF(-newViewportOrigon, animWidget->size() * scale);
       
   397     }
       
   398 
       
   399     startZoomAnimation(zoomedRect);
       
   400 }
       
   401 
       
   402 bool ScrollableWebContentView::isZoomedIn() const
       
   403 {
       
   404     return size().width() < viewportWidget()->size().width();
       
   405 }
       
   406 
       
   407 void ScrollableWebContentView::stateChanged(KineticScrollable::State oldState
       
   408                                             , KineticScrollable::State newState)
       
   409 {
       
   410     ScrollableViewBase::stateChanged(oldState, newState);
       
   411 
       
   412     if (newState == KineticScrollable::Pushing) {
       
   413         m_tileUpdateEnableTimer.stop();
       
   414         viewportWidget()->disableContentUpdates();
       
   415     }
       
   416     else if (newState == KineticScrollable::AutoScrolling) {
       
   417         m_tileUpdateEnableTimer.stop();
       
   418         viewportWidget()->disableContentUpdates();
       
   419     }
       
   420     else if (newState == KineticScrollable::Inactive) {
       
   421         m_tileUpdateEnableTimer.start(TileUpdateEnableDelay);
       
   422     }
       
   423 }
       
   424 
       
   425 void ScrollableWebContentView::startZoomAnimation(const QRectF& destRect)
       
   426 {
       
   427     QAbstractAnimation::State animState = m_zoomAnimator->state();
       
   428     if (animState == QAbstractAnimation::Running)
       
   429         return;
       
   430 
       
   431     m_zoomAnimator->setStartValue(scrollWidget()->geometry());
       
   432     m_animationEndRect = adjustScrollWidgetRect(destRect);
       
   433     m_zoomAnimator->setEndValue(m_animationEndRect);
       
   434     m_zoomAnimator->start();
       
   435 }
       
   436 
       
   437 void ScrollableWebContentView::stopZoomAnimation()
       
   438 {
       
   439     m_animationEndRect = QRectF();
       
   440     m_zoomAnimator->stop();
       
   441 }
       
   442 
       
   443 void ScrollableWebContentView::updateZoomEndRect()
       
   444 {
       
   445     if (m_animationEndRect.isValid())
       
   446         scrollWidget()->setGeometry(m_animationEndRect);
       
   447 }
       
   448 
       
   449 void ScrollableWebContentView::zoomAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
       
   450 {
       
   451     switch (newState) {
       
   452     case QAbstractAnimation::Stopped:
       
   453         updateZoomEndRect();
       
   454         break;
       
   455     default:
       
   456         break;
       
   457     }
       
   458 }
       
   459 
       
   460 void ScrollableWebContentView::resizeEvent(QGraphicsSceneResizeEvent* event)
       
   461 {
       
   462     QGraphicsWidget::resizeEvent(event);
       
   463 
       
   464     //Ignore resize when chrome is being still setup
       
   465     if (!event->oldSize().width())
       
   466         return;
       
   467 
       
   468     adjustViewportSize(event->oldSize(), event->newSize());
       
   469 }
       
   470 
       
   471 void ScrollableWebContentView::adjustViewportSize(QSizeF oldSize, QSizeF newSize)
       
   472 {
       
   473     //FIX ME : Check this
       
   474     if (m_viewportMetaData->m_isValid) {
       
   475 
       
   476         QRect clientRect = geometry().toAlignedRect();
       
   477         if (m_viewportMetaData->isLayoutNeeded())  {
       
   478             m_viewportMetaData->orientationChanged(clientRect);
       
   479             updatePreferredContentSize();
       
   480             return;
       
   481         } else
       
   482             m_viewportMetaData->updateViewportData(viewportWidget()->contentsSize(), clientRect);
       
   483     }
       
   484 
       
   485     qreal scale = newSize.width() / oldSize.width();
       
   486     QPointF middleLeft(0, oldSize.height()/2);
       
   487     QPointF docPoint(viewportWidget()->mapFromScene(middleLeft));
       
   488 
       
   489     QPointF resizedMiddleLeft(0, newSize.height()/2);
       
   490     QPointF resizedDocPoint(viewportWidget()->mapFromScene(resizedMiddleLeft));
       
   491     QPointF docPointInScr(viewportWidget()->mapToParent(resizedDocPoint));
       
   492 
       
   493     //FIX ME : Should be handled with only following function call
       
   494     //Since its not working, work-around is added. Plz fix it
       
   495     //startZoomAnimToItemHotspot(docPoint, docPointInScr, scale);
       
   496 
       
   497     QPointF newHotspot = docPoint * scale;
       
   498     QPointF newViewportOrigon = newHotspot - docPointInScr;
       
   499     QRectF zoomedRect(-newViewportOrigon,  viewportWidget()->size() * scale);
       
   500     QRectF adjustRect = adjustScrollWidgetRect(zoomedRect);
       
   501 
       
   502     setScrollWidgetGeometry(zoomedRect);
       
   503 }
       
   504 
       
   505 void ScrollableWebContentView::sendEventToWebKit(QEvent::Type type, QPointF& scenPos)
       
   506 {
       
   507     //Setup event and send it to webkit
       
   508     QGraphicsSceneMouseEvent event(type);
       
   509     event.setScenePos(scenPos);
       
   510     event.setPos(viewportWidget()->webView()->mapFromScene(event.scenePos()));
       
   511     event.setButton(Qt::LeftButton);
       
   512     event.setButtons(Qt::LeftButton);
       
   513     event.setModifiers(Qt::NoModifier);
       
   514 
       
   515     viewportWidget()->webView()->page()->event(&event);
       
   516 }
       
   517 
       
   518 } //namespace GVA