ginebra2/ContentViews/ScrollableWebContentView.cpp
changeset 16 3c88a81ff781
parent 9 b39122337a00
equal deleted inserted replaced
14:6aeb7a756187 16:3c88a81ff781
    18 * Description:
    18 * Description:
    19 *
    19 *
    20 */
    20 */
    21 
    21 
    22 #include "ScrollableWebContentView.h"
    22 #include "ScrollableWebContentView.h"
    23 
       
    24 #include "Gestures/GestureRecognizer.h"
       
    25 #include "Kinetics/KineticScroller.h"
    23 #include "Kinetics/KineticScroller.h"
    26 #include "ScrollableViewBase.h"
    24 #include "ScrollableViewBase.h"
    27 #include "ViewportMetaDataParser.h"
    25 #include "ViewportMetaDataParser.h"
    28 #include "WebContentAnimationItem.h"
    26 #include "WebView.h"
       
    27 #include "qstmgestureevent.h"
       
    28 #include "qstmfilelogger.h"
       
    29 #include "bedrockprovisioning.h"
       
    30 #include "ScrollHelper.h"
    29 
    31 
    30 #include <QApplication>
    32 #include <QApplication>
    31 #include <QGraphicsScene>
    33 #include <QGraphicsScene>
    32 #include <QGraphicsSceneMouseEvent>
    34 #include <QGraphicsSceneMouseEvent>
    33 #include <QGraphicsWebView>
    35 #include <QGraphicsWebView>
       
    36 #include <QStyleOptionGraphicsItem>
    34 #include <QWebElement>
    37 #include <QWebElement>
    35 #include <QWebHitTestResult>
    38 #include <QWebHitTestResult>
    36 
    39 #include <QWebPage>
       
    40 #include <QWebHistory>
       
    41 #include <QInputContext>
       
    42 
       
    43 #include "Gestures/GestureRecognizer.h"
       
    44 #ifdef ORBIT_UI
       
    45 #include <hbinputmethod.h>
       
    46 #endif // ORBIT_UI
       
    47 
       
    48 namespace GVA {
    37 //Kinetic scroll constants
    49 //Kinetic scroll constants
    38 static const int ScrollsPerSecond = 30;
    50 static const int ScrollsPerSecond = 30;
    39 static const int MinimumScrollVelocity = 10;
    51 static const int MinimumScrollVelocity = 10;
    40 static const qreal AxisLockThreshold = .8;
    52 static const qreal AxisLockThreshold = .8;
    41 
    53 
    42 
       
    43 //Zooming constants
    54 //Zooming constants
    44 static const int ZoomAnimationDuration = 300;   //ms. Zooming transition duration
    55 const int ZoomAnimationDuration = 600;   //ms. Zooming transition duration
       
    56 const int MaxZoomAnimationDuration = 2000;   //ms. Zooming transition duration
    45 static const qreal ZoomStep = .5;               //Incremental zoom step
    57 static const qreal ZoomStep = .5;               //Incremental zoom step
    46 const int TileUpdateEnableDelay = 500;         //Wait duration before tiling updates are enabled.
    58 #ifdef Q_WS_MAEMO_5
    47 
    59 const int TileUpdateEnableDelay = 10;         //Wait duration before tiling updates are enabled.
    48 namespace GVA {
    60 #else
    49 
    61 const int TileUpdateEnableDelay = 150;         //Wait duration before tiling updates are enabled.
    50 ScrollableWebContentView::ScrollableWebContentView(WebContentAnimationItem* webAnimationItem, QGraphicsItem* parent)
    62 #endif
       
    63 static const int MinDoubleClickZoomTargetWidth = 100;     //Target block width for applying double tap zoom
       
    64 static const int ZoomCommitDuration = 60;                //Timeout before commiting zoom
       
    65 static const qreal ZoomableContentMinWidth = 300.;
       
    66 
       
    67 static const qreal InvalidCoord = 1e10;
       
    68 static const int TouchDownTimeout = 200;
       
    69 static const int HoverTimeout = 100;
       
    70 
       
    71 #undef USE_KINETIC_SCROLLER
       
    72 using namespace qstmGesture;
       
    73 
       
    74 ScrollableWebContentView::ScrollableWebContentView(WebView* scrolledWidget, QGraphicsItem* parent)
    51     : ScrollableViewBase(parent)
    75     : ScrollableViewBase(parent)
    52     , m_gestureRecognizer(this)
    76     , m_gestureRecognizer(this)
       
    77     , m_isInputOn(false)
       
    78     , m_ignoreNextRelease(false)
    53 {
    79 {
    54     m_viewportMetaData = new ViewportMetaData();
    80     m_viewportMetaData = new ViewportMetaData();
    55 
    81 
       
    82     scrolledWidget->installEventFilter(this);
       
    83     
    56     //Kinetic scroller settings
    84     //Kinetic scroller settings
    57     //Sets the number of scrolls (frames) per second to sps.
    85     //Sets the number of scrolls (frames) per second to sps.
    58     m_kineticScroller->setScrollsPerSecond(ScrollsPerSecond);
    86     m_kineticScroller->setScrollsPerSecond(ScrollsPerSecond);
    59     //For elastic scroll in page edges
    87     //For elastic scroll in page edges
    60     m_kineticScroller->setOvershootPolicy(KineticScroller::OvershootWhenScrollable);
    88     m_kineticScroller->setOvershootPolicy(KineticScroller::OvershootWhenScrollable);
    61 
    89 
       
    90     setWidget(scrolledWidget);
       
    91 
       
    92     m_tileUpdateEnableTimer.setSingleShot(true);
       
    93     connect(&m_tileUpdateEnableTimer, SIGNAL(timeout()), this, SLOT(enableContentUpdates()));
       
    94     m_zoomCommitTimer.setSingleShot(true);
       
    95     connect(&m_zoomCommitTimer, SIGNAL(timeout()),this,SLOT(commitZoom()));
       
    96 
       
    97     //Setup zooming animator
       
    98     m_zoomAnimator = new QPropertyAnimation(this, "viewableRect");
       
    99     //m_zoomAnimator->setDuration(ZoomAnimationDuration);
       
   100     connect(m_zoomAnimator, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)), 
       
   101             this, SLOT(zoomAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
       
   102     
       
   103     m_isSuperPage = false;
       
   104     m_gesturesEnabled = true;
       
   105     m_isLoading = false;
       
   106     m_touchDownTimer = UiTimer::New();
       
   107     m_touchDownTimer->setTimerCallback((char*)"touchDownCallback");
       
   108     
       
   109     m_hoverTimer = UiTimer::New();
       
   110     m_hoverTimer->setTimerCallback((char*)"hoverCallback");
       
   111         
       
   112     m_touchDownTimer->setPriority(150);
       
   113     m_pinchFinishTime = QTime::currentTime();
       
   114     // ScrollHelper
       
   115     m_scrollHelper = new ScrollHelper(this);
       
   116     initScrollHelper();
       
   117         
    62     //Gesture settings
   118     //Gesture settings
    63     //For detecting scroll direction
   119     //For detecting scroll direction
    64     m_gestureRecognizer.setAxisLockThreshold(AxisLockThreshold);
   120     m_gestureRecognizer.setAxisLockThreshold(AxisLockThreshold);
    65     //To enable touch and drag scrolling
   121     //To enable touch and drag scrolling
    66     m_gestureRecognizer.setMinimumVelocity(MinimumScrollVelocity);
   122     m_gestureRecognizer.setMinimumVelocity(MinimumScrollVelocity);
    67 
   123 
    68     setWidget(webAnimationItem);
   124     grabGesture(QStm_Gesture::assignedType());
    69     //FIX ME : Revisit this code. Duplicate info sharing!
   125     connect(this, SIGNAL(viewScrolled(QPoint&, QPoint&)), scrolledWidget, SLOT(viewScrolled(QPoint&, QPoint&)));
    70     webAnimationItem->setViewportMetaData(m_viewportMetaData);
   126     installEventFilter(this);
    71 
   127 }
    72 
   128 
    73     m_tileUpdateEnableTimer.setSingleShot(true);
   129 void ScrollableWebContentView::initScrollHelper()
    74     connect(&m_tileUpdateEnableTimer, SIGNAL(timeout()), webAnimationItem, SLOT(enableContentUpdates()));
   130 {
    75 
   131     qreal decel = BedrockSettings->value("KineticDeceleration").toDouble();
    76     //Setup zooming animator
   132     m_scrollHelper->setDeceleration(decel);
    77     m_zoomAnimator = new QPropertyAnimation(webAnimationItem, "geometry");
   133 
    78     m_zoomAnimator->setDuration(ZoomAnimationDuration);
   134     qreal maxFlickKoef = BedrockSettings->value("MaxFlickInViewportUnits").toDouble();
    79     connect(m_zoomAnimator, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)), this, SLOT(zoomAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
   135     qreal minFlickKoef = BedrockSettings->value("MinFlickInViewportUnits").toDouble();
       
   136     qreal midFlickKoef = BedrockSettings->value("MidFlickInViewportUnits").toDouble();
       
   137     m_scrollHelper->setFlickLimits(minFlickKoef, midFlickKoef, maxFlickKoef);
       
   138 
       
   139     qreal maxFlickSpeed = BedrockSettings->value("MaxFlickSpeed").toDouble();
       
   140     qreal minFlickSpeed = BedrockSettings->value("MinFlickSpeed").toDouble();
       
   141     qreal midFlickSpeed = BedrockSettings->value("MidFlickSpeed").toDouble();
       
   142     m_scrollHelper->setFlickSpeedLimits(minFlickSpeed, midFlickSpeed, maxFlickSpeed);
       
   143 
       
   144     int maxFlickDuration = BedrockSettings->value("MaxFlickDuration").toInt();
       
   145     int minFlickDuration = BedrockSettings->value("MinFlickDuration").toInt();
       
   146     int midFlickDuration = BedrockSettings->value("MidFlickDuration").toInt();
       
   147     m_scrollHelper->setFlickDurationLimits(minFlickDuration, midFlickDuration, maxFlickDuration);
       
   148     
       
   149     connect(m_scrollHelper, SIGNAL(scrollFinished()), this, SLOT(stopScrolling()));
    80     
   150     
    81     m_gesturesEnabled = true;
   151     m_gesturesEnabled = true;
    82 }
   152 }
    83 
   153 
    84 ScrollableWebContentView::~ScrollableWebContentView()
   154 ScrollableWebContentView::~ScrollableWebContentView()
    85 {
   155 {
    86     delete m_viewportMetaData;
   156     delete m_viewportMetaData;
    87     delete m_kineticScroller;
       
    88 
       
    89     if(m_zoomAnimator) {
   157     if(m_zoomAnimator) {
    90         m_zoomAnimator->stop();
   158         m_zoomAnimator->stop();
    91         delete m_zoomAnimator;
   159         delete m_zoomAnimator;
    92     }
   160     }
    93 }
   161     
    94 
   162     m_touchDownTimer->stop();
    95 WebContentAnimationItem* ScrollableWebContentView::viewportWidget() const
   163     delete m_touchDownTimer;
    96 {
   164     
    97     return qobject_cast<WebContentAnimationItem*>(scrollWidget());
   165     m_hoverTimer->stop();
    98 }
   166     delete m_hoverTimer;
    99 
   167 
   100 void ScrollableWebContentView::zoomToScreenCenter(bool zoomIn)
   168 }
       
   169 
       
   170 void ScrollableWebContentView::stepZoom(bool zoomIn)
   101 {
   171 {
   102     //If viewport metadata has user scalable false.
   172     //If viewport metadata has user scalable false.
   103     //Do not zoom.
   173     //Do not zoom.
   104     if (!m_viewportMetaData->m_userScalable)
   174     if (!m_viewportMetaData->m_userScalable)
   105         return;
   175         return;
   106 
   176 
       
   177     if (isZooming()) {
       
   178         stopZoomAnimation();
       
   179         return;
       
   180     }
       
   181     
   107     qreal scale = 1;
   182     qreal scale = 1;
   108     scale += ZoomStep;
   183     scale += ZoomStep;
   109 
   184 
   110     if (!zoomIn)
   185     if (!zoomIn)
   111         scale = 1/scale;
   186         scale = 1/scale;
   112 
   187 
   113     qreal curScale =  viewportWidget()->zoomScale();
   188     qreal curScale =  scrollWidget()->scale();
   114 
   189     qreal destScale = curScale * scale;
   115     if (zoomIn && (curScale * scale > m_viewportMetaData->m_maximumScale))
   190 
   116         scale = m_viewportMetaData->m_maximumScale / curScale;
   191     if (zoomIn && (destScale > m_viewportMetaData->m_maximumScale))
   117     else if (!zoomIn && (curScale * scale < m_viewportMetaData->m_minimumScale))
   192         destScale = m_viewportMetaData->m_maximumScale;
   118         scale = m_viewportMetaData->m_minimumScale / curScale;
   193     else if (!zoomIn && (destScale < m_viewportMetaData->m_minimumScale))
   119 
   194         destScale = m_viewportMetaData->m_minimumScale;
   120     if(scale == 1.)
   195 
       
   196     if(destScale == curScale)
   121         return;
   197         return;
   122 
   198 
   123     //Screen center
   199     //Screen center
   124     QPointF scrCenter(size().width()/2, size().height()/2);
   200     //QPointF zoomHotSpot(size().width()/2, size().height()/2); //center zoom looks ugly in some cases
   125     //Map screen center to document
   201     QPointF zoomHotSpot(0, 0);
   126     QPointF docPoint(viewportWidget()->mapFromScene(scrCenter));
   202     
   127     //Maintain that spot in the same point on the viewport
   203     startZoomAnimationToHotSpot(zoomHotSpot, destScale);
   128     QPointF docPointInScr(viewportWidget()->mapToParent(docPoint));
   204 }
   129     startZoomAnimToItemHotspot(docPoint, docPointInScr, scale);
   205 
   130 }
   206 
   131 
   207 int ScrollableWebContentView::zoomAnimationTime(bool zoomIn, qreal targetScale)
   132 ZoomMetaData ScrollableWebContentView::currentPageInfo()
   208 {
   133 {
   209     qreal curScale = zoomScale(); 
   134     ZoomMetaData data;
   210     qreal scaleRatio = zoomIn ? (targetScale / curScale) :
   135 
   211                             1.2 * (curScale / targetScale);
       
   212     qreal fullScaleRatio = (m_viewportMetaData->m_maximumScale / m_viewportMetaData->m_minimumScale);
       
   213     return MaxZoomAnimationDuration * scaleRatio / fullScaleRatio;
       
   214 }
       
   215 
       
   216 void ScrollableWebContentView::toggleZoom(bool zoomIn)
       
   217 {
       
   218     m_scrollHelper->stopScrollNoSignal();
       
   219     if (isZooming()) {
       
   220         stopZoomAnimation();
       
   221         commitZoom();
       
   222         return;
       
   223     }
       
   224     qreal scale = zoomIn ? m_viewportMetaData->m_maximumScale : m_viewportMetaData->m_minimumScale;
       
   225     int t = zoomAnimationTime(zoomIn, scale);
       
   226     QPointF zoomHotSpot(0, 0);
       
   227     startZoomAnimationToHotSpot(zoomHotSpot, scale, t);
       
   228 }
       
   229 
       
   230 QRectF ScrollableWebContentView::viewportRectInPageCoord(const QPointF& viewportHotSpot, 
       
   231                                                          const qreal destScale)
       
   232 {
       
   233     QSizeF vpSize = size();
       
   234     QSizeF contentSize = webView()->size();
       
   235     QSizeF scaleVpSize(vpSize.width() / destScale, vpSize.height() / destScale);
       
   236     QPointF contentHotSpot = webView()->mapFromParent(viewportHotSpot);
       
   237     QPointF scaledHotSpot = viewportHotSpot / destScale; 
       
   238     QRectF destViewRect( contentHotSpot - scaledHotSpot, scaleVpSize);
       
   239     return destViewRect;
       
   240 }
       
   241 
       
   242 void ScrollableWebContentView::startZoomAnimationToHotSpot(const QPointF& viewportHotSpot, 
       
   243                                                            const qreal destScale, int animTime)
       
   244 {
       
   245     QRectF destViewRect = viewportRectInPageCoord(viewportHotSpot, destScale);
       
   246     startZoomAnimation(destViewRect, animTime);
       
   247 }
       
   248 
       
   249 void ScrollableWebContentView::zoomToHotSpot(const QPointF& viewportHotSpot, const qreal destScale)
       
   250 {
       
   251     QRectF destViewRect = viewportRectInPageCoord(viewportHotSpot, destScale);
       
   252     destViewRect = validateViewportRect(destViewRect);
       
   253     setViewableRect(destViewRect);
       
   254 }
       
   255 
       
   256 WebPageData ScrollableWebContentView::pageDataFromViewportInfo()
       
   257 {
       
   258     if(!m_viewportMetaData->m_isValid) return WebPageData();
       
   259 
       
   260     // No viewport data saving or restoring for superpages
       
   261     if(isSuperPage()) return WebPageData();
       
   262 
       
   263     // invalidate viewport meta data after saving to history
       
   264     // cannot do it earlier because loadStarted event comes earlier than save to history
       
   265     if(m_isLoading)
       
   266         m_viewportMetaData->m_isValid = false;
       
   267 
       
   268     bool fitToScreen = qFuzzyCompare(m_viewportMetaData->m_width / webView()->size().width(), zoomScale());
       
   269 
       
   270     return WebPageData(m_viewportMetaData->m_maximumScale, m_viewportMetaData->m_minimumScale,
       
   271                        m_viewportMetaData->m_userScalable, m_viewportMetaData->m_initialScale,
       
   272                        geometry(), webView()->geometry(), scrollWidget()->scale(), size(),
       
   273                        m_viewportMetaData->m_specifiedData.m_width, m_viewportMetaData->m_specifiedData.m_height,
       
   274                        fitToScreen);
       
   275 }
       
   276 
       
   277 QSizeF ScrollableWebContentView::parentSize() const
       
   278 {
       
   279     return static_cast<QGraphicsWidget*>(parentItem())->size();
       
   280 }
       
   281 
       
   282 void ScrollableWebContentView::setPageDataToViewportInfo(const WebPageData& data)
       
   283 {
       
   284     if(!data.isValid()) return;
       
   285 
       
   286     // No viewport data saving or restoring for superpages
       
   287     if(isSuperPage()) return;
       
   288 
       
   289     m_viewportMetaData->m_initialScale = data.initialScale;
       
   290     m_viewportMetaData->m_minimumScale = data.minScale;
       
   291     m_viewportMetaData->m_maximumScale = data.maxScale;
       
   292     m_viewportMetaData->m_userScalable = data.userScalable;
       
   293     m_viewportMetaData->m_specifiedData.m_width = data.specifiedWidth;
       
   294     m_viewportMetaData->m_specifiedData.m_height = data.specifiedHeight;
       
   295     m_viewportMetaData->m_isValid = true;
       
   296     m_viewportMetaData->m_width = data.viewportSize.width();
       
   297     m_viewportMetaData->m_height = data.viewportSize.height();
       
   298 
       
   299 
       
   300     if(m_viewportMetaData->m_width < 0 ||
       
   301        m_viewportMetaData->m_width < 0) {
       
   302         m_viewportMetaData->m_isValid = false;
       
   303         reset();
       
   304         return;
       
   305     }
       
   306 
       
   307     QSizeF newSize = parentSize();
       
   308     if(newSize.isEmpty())
       
   309         newSize = data.viewportSize;
       
   310 
       
   311     disableContentUpdates();
       
   312     //    updateViewportMetaDataFromPageTag();
       
   313 
       
   314 
       
   315     QSizeF vpSz(m_viewportMetaData->m_width, m_viewportMetaData->m_height);
       
   316     if(vpSz.isEmpty())
       
   317         vpSz = newSize;
       
   318 
       
   319     // sometimes on load from history webpage doesn't resize webView
       
   320     // set correct size of webView here
       
   321     webView()->setGeometry(QRectF( QPointF(0, 0),
       
   322                                    QSizeF(webView()->page()->mainFrame()->contentsSize())));
       
   323 
       
   324     qreal sc = data.scale; //qBound(m_viewportMetaData->m_minimumScale,data.scale,m_viewportMetaData->m_maximumScale);
       
   325     webView()->setScale(sc);
       
   326 
       
   327 //    qreal fitToScreenScale = data.viewportSize.width() / webView()->size().width();
       
   328 //    bool isFitToScreen = qFuzzyCompare(zoomScale(), fitToScreenScale);
       
   329     adjustViewportSize(data.viewportSize, newSize);
       
   330     m_viewportMetaData->adjustZoomValues(webView()->size());
       
   331     if(data.fitToScreen && newSize.width() != vpSz.width()) {
       
   332         qreal fitToScreenScale = size().width() / webView()->size().width();
       
   333         fitToScreenScale = qBound(m_viewportMetaData->m_minimumScale,
       
   334                                   fitToScreenScale,m_viewportMetaData->m_minimumScale);
       
   335         webView()->setScale(fitToScreenScale);
       
   336     }
       
   337 //    else
       
   338 //       updatePreferredContentSize();
       
   339 
       
   340     if (newSize.width() != m_viewportMetaData->m_width ||
       
   341         newSize.height() != m_viewportMetaData->m_height) {
       
   342         //setGeometry(0, 0, m_viewportMetaData->m_width, m_viewportMetaData->m_height);
       
   343         m_scrollHelper->setViewportSize(size());
       
   344     }
       
   345 
       
   346 
       
   347     if (data.webViewRect.isValid()) {
       
   348         QPointF webViewPos = data.webViewRect.topLeft();
       
   349         qreal newSc = webView()->scale(); // might be adjust by fitToScreen
       
   350         webViewPos = webViewPos / sc * newSc; // recalc pos if scale changed by fitToScreen
       
   351         QSizeF ss = webView()->size() * newSc;
       
   352         if(!ss.isEmpty()) {
       
   353             webViewPos.setX(qBound((qreal)m_viewportMetaData->m_width - (qreal)ss.width(), (qreal)webViewPos.x(), (qreal)0.0));
       
   354             webViewPos.setY(qBound((qreal)m_viewportMetaData->m_height - (qreal)ss.height(), (qreal)webViewPos.y(), (qreal)0.0));
       
   355             if(ss.width() < m_viewportMetaData->m_width) webViewPos.setX(0);
       
   356             if(ss.height() < m_viewportMetaData->m_height) webViewPos.setY(0);
       
   357         }
       
   358         setScrollWidgetPos(webViewPos);
       
   359     }
       
   360     enableContentUpdates();
       
   361 //    updatePreferredContentSize();
       
   362     
       
   363 
       
   364     // emit scrolled event to hide/show url bar
       
   365 
       
   366     QPoint p(0, 0);
       
   367     if(!m_isLoading) {
       
   368         p = scrollPosition();
       
   369     }
       
   370     QPoint d(0, 0);
       
   371     emit viewScrolled(p, d);
       
   372 
       
   373 }
       
   374 
       
   375 WebPageData ScrollableWebContentView::defaultZoomData()
       
   376 {
       
   377     WebPageData data;
       
   378 
       
   379     data.magic = 0;
   136     data.initialScale = m_viewportMetaData->m_initialScale;
   380     data.initialScale = m_viewportMetaData->m_initialScale;
   137     data.minScale = m_viewportMetaData->m_minimumScale;
   381     data.minScale = m_viewportMetaData->m_minimumScale;
   138     data.maxScale = m_viewportMetaData->m_maximumScale;
   382     data.maxScale = m_viewportMetaData->m_maximumScale;
   139     data.userScalable = m_viewportMetaData->m_userScalable;
   383     data.userScalable = m_viewportMetaData->m_userScalable;
   140     data.m_specifiedWidth = m_viewportMetaData->m_specifiedData.m_width;
   384 
   141     data.m_specifiedHeight= m_viewportMetaData->m_specifiedData.m_height;
   385     data.scale = 1.0;
   142 
   386     data.rect = rect();
   143     data.rect = viewportWidget()->geometry();
   387     data.webViewRect = webView()->rect();
   144     data.scale = viewportWidget()->zoomScale();
   388     data.viewportSize = QSizeF(m_viewportMetaData->m_width, m_viewportMetaData->m_height);
   145     data.webViewSize = viewportWidget()->webView()->geometry();
       
   146     data.viewportSize = size();
       
   147 
   389 
   148     return data;
   390     return data;
   149 }
   391 }
   150 
   392 
   151 void ScrollableWebContentView::setCurrentPageInfo(ZoomMetaData data)
       
   152 {
       
   153     m_viewportMetaData->m_initialScale = data.initialScale;
       
   154     m_viewportMetaData->m_minimumScale = data.minScale;
       
   155     m_viewportMetaData->m_maximumScale = data.maxScale;
       
   156     m_viewportMetaData->m_userScalable = data.userScalable;
       
   157     m_viewportMetaData->m_specifiedData.m_width = data.m_specifiedWidth;
       
   158     m_viewportMetaData->m_specifiedData.m_height = data.m_specifiedHeight;
       
   159     m_viewportMetaData->m_isValid = true;
       
   160 
       
   161     m_viewportMetaData->m_width = data.webViewSize.width();
       
   162     m_viewportMetaData->m_height = data.webViewSize.height();
       
   163 
       
   164     viewportWidget()->webView()->setGeometry(data.webViewSize);
       
   165     viewportWidget()->setZoomScale(data.scale, true);
       
   166     viewportWidget()->setGeometry(data.rect);
       
   167 
       
   168     if (data.viewportSize.width() != size().width())
       
   169         adjustViewportSize(data.viewportSize, size());
       
   170 }
       
   171 
       
   172 ZoomMetaData ScrollableWebContentView::defaultZoomData()
       
   173 {
       
   174     ZoomMetaData data;
       
   175 
       
   176     data.initialScale = m_viewportMetaData->m_initialScale;
       
   177     data.minScale = m_viewportMetaData->m_minimumScale;
       
   178     data.maxScale = m_viewportMetaData->m_maximumScale;
       
   179     data.userScalable = m_viewportMetaData->m_userScalable;
       
   180 
       
   181     data.scale = 1.0;
       
   182     data.rect = QRectF();
       
   183     data.webViewSize = QRectF();
       
   184     data.viewportSize = QSizeF();
       
   185 
       
   186     return data;
       
   187 }
       
   188 
       
   189 void ScrollableWebContentView::updatePreferredContentSize()
   393 void ScrollableWebContentView::updatePreferredContentSize()
   190 {
   394 {
   191     viewportWidget()->updatePreferredContentSize(QSize(m_viewportMetaData->m_width
   395 #ifdef VIEWPORT_ALWAYS_ALLOW_ZOOMING
   192                                                        , m_viewportMetaData->m_height));
   396     // Don't call updatePreferredContentSize() if we've over-ridden user-scalable because it
       
   397     // resets the content size and zoom factor.
       
   398     if(m_viewportMetaData->m_userScalableOverRidden)
       
   399         return;
       
   400 #endif
       
   401     QSize s = m_viewportMetaData->getSpecifiedSize();
       
   402 /*    if (!isSuperPage()) {
       
   403         prefferedHeight = qMax(m_viewportMetaData->m_width, m_viewportMetaData->m_height);
       
   404         prefferedWidth = m_viewportMetaData->m_width;        
       
   405         if(m_viewportMetaData->m_width * 1.5 < prefferedHeight) {
       
   406             // If the screen sides ratio is less than 3:2, than vertical width is
       
   407             // too narrow for normal page layout, but setting preffered width to the biggest side
       
   408             // makes page too scaled. Because of this set the page to the average of 2 viewport sides.
       
   409             prefferedWidth = (m_viewportMetaData->m_width + prefferedHeight) / 2;
       
   410         }
       
   411     }
       
   412 
       
   413 //    if(m_viewportMetaData->m_specifiedData.)
       
   414 */
       
   415     webView()->page()->setPreferredContentsSize(s);
       
   416 }
       
   417                                                                                                                                                                                                                                                                 
       
   418 void ScrollableWebContentView::setPage(QWebPage* page)
       
   419 {
       
   420     m_isSuperPage = false;
       
   421     m_gesturesEnabled = true;
       
   422     webView()->setPage(page);
   193 }
   423 }
   194 
   424 
   195 void ScrollableWebContentView::setSuperPage()
   425 void ScrollableWebContentView::setSuperPage()
   196 {
   426 {
       
   427     m_isSuperPage = true;
   197     m_viewportMetaData->m_initialScale = 1.;
   428     m_viewportMetaData->m_initialScale = 1.;
   198     m_viewportMetaData->m_minimumScale = 1.;
   429     m_viewportMetaData->m_minimumScale = 1.;
   199     m_viewportMetaData->m_maximumScale = 1.;
   430     m_viewportMetaData->m_maximumScale = 1.;
   200     m_viewportMetaData->m_specifiedData.m_width = "device-width";
   431     m_viewportMetaData->m_specifiedData.m_width = "device-width";
   201     m_viewportMetaData->m_specifiedData.m_height = "device-height";
   432     m_viewportMetaData->m_specifiedData.m_height = "device-height";
   202     m_viewportMetaData->m_userScalable = false;
   433     m_viewportMetaData->m_userScalable = false;
   203 
   434 
   204     QSize contentSize = viewportWidget()->contentsSize();
   435     disableContentUpdates();
   205     QRect webViewRect(0, 0, size().width(), contentSize.height());
   436     webView()->setScale(1.);
   206     viewportWidget()->webView()->setGeometry(webViewRect);
   437     //QSize contentSize = (webView()->size() * zoomScale()).toSize();
   207     viewportWidget()->setZoomScale(1., true);
   438     //QRect webViewRect(0, 0, size().width(), contentSize.height());
   208     viewportWidget()->setGeometry(webViewRect);
   439     //webView()->setGeometry(webViewRect);
       
   440     setScrollWidgetPos(QPointF(0, 0));
   209 
   441 
   210     m_viewportMetaData->m_width = size().width();
   442     m_viewportMetaData->m_width = size().width();
   211     m_viewportMetaData->m_height = size().height();
   443     m_viewportMetaData->m_height = size().height();
   212     m_viewportMetaData->m_isValid = true;
   444     m_viewportMetaData->m_isValid = true;
   213 
   445     enableContentUpdates();
       
   446 #ifdef VIEWPORT_ALWAYS_ALLOW_ZOOMING
   214     updatePreferredContentSize();
   447     updatePreferredContentSize();
       
   448     //viewportWidget()->updatePreferredContentSize(QSize(m_viewportMetaData->m_width
       
   449      //                                                  , m_viewportMetaData->m_height));
       
   450 #else
       
   451     updatePreferredContentSize();
       
   452 #endif
       
   453 }
       
   454 
       
   455 void ScrollableWebContentView::updateViewportMetaDataFromPageTag()
       
   456 {
       
   457     QWebPage* page = webView()->page();
       
   458     if (!page)
       
   459         return;
       
   460 
       
   461     QWebFrame* frame = page->mainFrame();
       
   462     QMap<QString, QString> metaData = frame->metaData();
       
   463     QString viewportTag = metaData.value("viewport");
       
   464 
       
   465     QRect clientRect = geometry().toAlignedRect();
       
   466     ViewportMetaDataParser parser(clientRect);
       
   467     parser.parse(viewportTag, *m_viewportMetaData);
       
   468 
       
   469     m_viewportMetaData->adjustZoomValues(webView()->size());
   215 }
   470 }
   216 
   471 
   217 void ScrollableWebContentView::reset()
   472 void ScrollableWebContentView::reset()
   218 {
   473 {
   219     // TODO: INVESTIGATE: In the case of multiple windows loading pages simultaneously, it is possible
   474     // TODO: INVESTIGATE: In the case of multiple windows loading pages simultaneously, it is possible
   220     // to be calling this slot on a signal from a frame that is not
   475     // to be calling this slot on a signal from a frame that is not
   221     // the frame of the page saved here. It might be better to use 'sender' instead of
   476     // the frame of the page saved here. It might be better to use 'sender' instead of
   222     // page->mainFrame() to get the metaData so that we use the meta data of the corresponding
   477     // page->mainFrame() to get the metaData so that we use the meta data of the corresponding
   223     // frame
   478     // frame
   224 
   479 
   225     QWebPage* page = viewportWidget()->webView()->page();
   480     QWebPage* page = webView()->page();
   226     if (!page)
   481     if (!page)
   227         return;
   482         return;
       
   483 //    if(m_viewportMetaData->m_isValid) return;
   228 
   484 
   229     //Initialize viewport metadata
   485     //Initialize viewport metadata
   230     m_viewportMetaData->reset();
   486     m_viewportMetaData->reset();
   231 
   487 
   232     QWebFrame* frame = page->mainFrame();
   488     disableContentUpdates();
   233     QMap<QString, QString> metaData = frame->metaData();
   489 
   234     QString viewportTag = metaData.value("viewport");
   490     webView()->setScale(1);
   235 
   491 
   236     QRect clientRect = geometry().toAlignedRect();
   492     // sometimes on load from history webpage doesn't resize webView
   237     ViewportMetaDataParser parser(clientRect);
   493     // set correct size of webView here
   238     *m_viewportMetaData = parser.parse(viewportTag);
   494     webView()->setGeometry(QRectF( QPointF(0, 0),
   239 
   495                                    QSizeF(webView()->page()->mainFrame()->contentsSize())));
       
   496 
       
   497     updateViewportMetaDataFromPageTag();
       
   498 
       
   499     //setViewportWidgetGeometry(QRectF(QPointF(),
       
   500     //                                 QSize(m_viewportMetaData->m_width, m_viewportMetaData->m_height)));
       
   501 
       
   502     static const QPoint nullP(0,0);
       
   503     setScrollPosition(nullP,nullP);
       
   504 
       
   505     QSizeF sz(m_viewportMetaData->m_width, m_viewportMetaData->m_height);
       
   506     adjustViewportSize(sz, size());
       
   507 
       
   508     qreal initScale = m_viewportMetaData->m_initialScale > 0 ? m_viewportMetaData->m_initialScale :
       
   509                       m_viewportMetaData->m_width / webView()->size().width();
       
   510     // m_viewportMetaData->m_initialScale = m_viewportMetaData->m_width / webView()->size().width();
       
   511     webView()->setScale(initScale);
       
   512 
       
   513     enableContentUpdates();
       
   514 
       
   515     m_scrollHelper->setViewportSize(size());
       
   516 
       
   517     // Update corrected viewport data back to webpage metadata
       
   518     emit viewPortChanged();
       
   519 }
       
   520 
       
   521 void ScrollableWebContentView::contentsSizeChanged(const QSize& newContentSize)
       
   522 {
       
   523     m_viewportMetaData->adjustZoomValues(newContentSize);
       
   524     qreal sc = zoomScale();
       
   525     sc = qBound(m_viewportMetaData->m_minimumScale, sc, m_viewportMetaData->m_maximumScale);
       
   526     if(!qFuzzyCompare(sc, zoomScale()))
       
   527         webView()->setScale(sc);
       
   528     emit viewPortChanged();
       
   529 }
       
   530 
       
   531 void ScrollableWebContentView::pageLoadStarted()
       
   532 {
       
   533     m_isLoading = true;
       
   534 //    m_viewportMetaData->m_isValid = false;
       
   535 }
       
   536 
       
   537 void ScrollableWebContentView::pageLoadProgress(int progress)
       
   538 {
       
   539 }
       
   540 
       
   541 void ScrollableWebContentView::pageLoadFinished(bool ok)
       
   542 {
       
   543     Q_UNUSED(ok);
       
   544     m_isLoading = false;
       
   545     if(!m_viewportMetaData->m_isValid)
       
   546         m_viewportMetadataResetTimer.singleShot(0,this,SLOT(reset()));
       
   547     else {
       
   548         QSize contentSize = scrollWidget()->size().toSize();
       
   549         m_viewportMetaData->adjustZoomValues(contentSize);
       
   550     }
       
   551 
       
   552     // report scroll position to hide url bar if necessary
       
   553     QPoint p = scrollPosition();
       
   554     QPoint d(0, 0);
       
   555     emit viewScrolled(p, d);
       
   556     
       
   557     webView()->update(); // invalidate the view to force tiles update
       
   558 }
       
   559 
       
   560 
       
   561 void ScrollableWebContentView::zoomAtPoint(QPointF touchPoint)
       
   562 {
       
   563     QRectF target;
       
   564 
       
   565     //Get the focusable element rect from current touch position
       
   566     if(isZoomedIn()) {
       
   567         startZoomAnimationToHotSpot(touchPoint,size().width() / webView()->size().width());
       
   568         return;
       
   569     }
       
   570 
       
   571     //Pass all events to recognizer
       
   572     QRectF zoomRect = findZoomableRectForPoint(touchPoint);
       
   573 
       
   574     if (!zoomRect.isValid()) {
       
   575         //FIX ME: Add an event ignore animation
       
   576         return;
       
   577     }
       
   578 
       
   579     startZoomAnimation(zoomRect);
       
   580 }
       
   581 
       
   582 
       
   583 void ScrollableWebContentView::setViewportWidgetGeometry(const QRectF& r)
       
   584 {
       
   585     if(r != geometry()) {
       
   586         setGeometry(r);
       
   587         emit viewPortChanged();
       
   588     }
       
   589 }
       
   590 
       
   591 
       
   592 bool ScrollableWebContentView::isZoomedIn() const
       
   593 {
       
   594     qreal vpWidth = size().width();
       
   595     qreal scaledContentWidth = scrollWidget()->size().width() * zoomScale(); 
       
   596     qreal diff = scaledContentWidth - vpWidth; 
       
   597     return  diff > 0.01f;
       
   598 }
       
   599 
       
   600 void ScrollableWebContentView::stateChanged(KineticScrollable::State oldState,
       
   601                                             KineticScrollable::State newState)
       
   602 {
       
   603     ScrollableViewBase::stateChanged(oldState, newState);
       
   604 
       
   605     switch(newState) {
       
   606         case KineticScrollable::Pushing :
       
   607         case KineticScrollable::AutoScrolling :
       
   608             m_tileUpdateEnableTimer.stop();
       
   609             //disableContentUpdates();
       
   610         break;
       
   611         case KineticScrollable::Inactive :
       
   612             m_tileUpdateEnableTimer.start(TileUpdateEnableDelay);
       
   613         break;
       
   614     }
       
   615 }
       
   616 
       
   617 QRectF ScrollableWebContentView::validateViewportRect(const QRectF& rect)
       
   618 {
       
   619     QRectF ret(rect);
       
   620 
       
   621     if(ret.right() > webView()->size().width())
       
   622         ret.moveLeft(webView()->size().width() - ret.width());
       
   623     if(ret.bottom() > webView()->size().height())
       
   624         ret.moveTop(webView()->size().height() - ret.height());
       
   625     if(ret.x() < 0) ret.moveLeft(0);
       
   626     if(ret.y() < 0) ret.moveTop(0);
       
   627 //    if(ret.width() > webView()->size().width()) ret.setWidth(webView()->size().width());
       
   628     if(ret.width() > webView()->size().width())
       
   629         ret.moveLeft(0); // do not center! ret.moveLeft(webView()->size().width() / 2 - ret.width() / 2);
       
   630     if(ret.height() > webView()->size().height())
       
   631         ret.moveTop(0); // do not center! ret.moveTop(webView()->size().height() / 2 - ret.height() / 2);
       
   632 
       
   633     return ret;
       
   634 }
       
   635 
       
   636 QRectF ScrollableWebContentView::viewableRect()
       
   637 {
       
   638     return webView()->mapRectFromParent(geometry());
       
   639 }
       
   640 
       
   641 void ScrollableWebContentView::setViewableRect(const QRectF& rect)
       
   642 {
       
   643     qreal scale = size().width() / rect.width(); 
       
   644     qstmDebug() << "setViewableRect: rect: " << rect << ", scale: " << scale << "\n";
       
   645     setZoomScale(scale, false);
       
   646     m_isScrolling = true;
       
   647     scrollPageTo(rect.topLeft());
       
   648     m_isScrolling = false;
       
   649 }
       
   650 
       
   651 void ScrollableWebContentView::startZoomAnimation(const QRectF& destViewRect, int animTime)
       
   652 {
       
   653     if (webView()->geometry().isValid()) {
       
   654         m_zoomAnimator->setDuration(animTime);
       
   655         m_zoomAnimator->setStartValue(webView()->mapRectFromParent(geometry()));
       
   656         m_animationEndRect = validateViewportRect(destViewRect);
       
   657         m_zoomAnimator->setEndValue(m_animationEndRect);
       
   658         m_zoomAnimator->start();
       
   659     }
       
   660 }
       
   661 
       
   662 void ScrollableWebContentView::stopZoomAnimation()
       
   663 {
       
   664     m_zoomAnimator->stop();
       
   665 }
       
   666 
       
   667 void ScrollableWebContentView::zoomAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
       
   668 {
       
   669     switch (newState) {
       
   670     case QAbstractAnimation::Stopped:
       
   671         commitZoom();
       
   672         break;
       
   673     case QAbstractAnimation::Running:
       
   674         disableContentUpdates();
       
   675         break;
       
   676     default:
       
   677         break;
       
   678     }
       
   679 }
       
   680 
       
   681 void ScrollableWebContentView::resizeEvent(QGraphicsSceneResizeEvent* event)
       
   682 {
       
   683     //Ignore resize when chrome is being still setup
       
   684     if (event->oldSize().width()) {
       
   685 
       
   686         qreal fitToScreenScale = event->oldSize().width() / webView()->size().width();
       
   687         bool isFitToScreen = qFuzzyCompare(zoomScale(), fitToScreenScale);
       
   688         QGraphicsWidget::resizeEvent(event);
       
   689         adjustViewportSize(event->oldSize(), event->newSize());
       
   690         if (isFitToScreen && !isSuperPage()) {
       
   691             QPointF docViewTopLeft(webView()->mapFromParent(QPointF(0,0)));
       
   692             fitToScreenScale = size().width() / webView()->size().width();
       
   693             zoomToHotSpot(docViewTopLeft, fitToScreenScale);
       
   694             m_zoomCommitTimer.start(ZoomCommitDuration);
       
   695         } else {
       
   696             QRectF viewRect = mapRectToItem(webView(), QRectF(QPointF(0,0), size()));
       
   697             QRectF validRect = validateViewportRect(viewRect);
       
   698             if(validRect != viewRect)
       
   699                 setViewableRect(validRect);
       
   700         }
       
   701         m_scrollHelper->setViewportSize(size());
       
   702     }
       
   703 
       
   704 #ifdef OWN_BACKING_STORE
       
   705     webView()->viewportUpdated();
       
   706 #endif // OWN_BACKING_STORE
       
   707 }
       
   708 
       
   709 bool  ScrollableWebContentView::isChangedToPortrait(QSizeF oldSize, QSizeF newSize)
       
   710 {
       
   711     return (oldSize.width() > oldSize.height()) && 
       
   712            (newSize.width() < newSize.height());
       
   713 }
       
   714 
       
   715 bool  ScrollableWebContentView::isChangedToLandscape(QSizeF oldSize, QSizeF newSize)
       
   716 {
       
   717     return (oldSize.width() < oldSize.height()) && 
       
   718            (newSize.width() > newSize.height());
       
   719     emit mouseEvent(QEvent::GraphicsSceneMouseRelease);
       
   720 }
       
   721 
       
   722 bool ScrollableWebContentView::isOrientationChanged(QSizeF oldSize, QSizeF newSize)
       
   723 {
       
   724     return isChangedToPortrait(oldSize, newSize) || 
       
   725            isChangedToLandscape(oldSize, newSize);
       
   726 }
       
   727 
       
   728 
       
   729 void ScrollableWebContentView::adjustViewportSize(QSizeF oldSize, QSizeF newSize)
       
   730 {
       
   731     if(newSize.isNull()) return;
       
   732 
       
   733     if (isOrientationChanged(oldSize, newSize)) {
       
   734         m_viewportMetaData->orientationChanged(oldSize);
       
   735     }
       
   736     m_viewportMetaData->adjustViewportData(newSize);
   240     updatePreferredContentSize();
   737     updatePreferredContentSize();
   241     setViewportWidgetGeometry(QRectF(QPointF(),
   738     return;    
   242                                      QSize(m_viewportMetaData->m_width, m_viewportMetaData->m_height)
   739 }
   243                                      * m_viewportMetaData->m_initialScale));
   740 
   244 }
   741 void ScrollableWebContentView::sendEventToWebKit(QEvent::Type type, const QPointF& scenePos, bool select)
   245 
   742 {
   246 void ScrollableWebContentView::contentsSizeChanged(const QSize& newContentSize)
   743     QGraphicsSceneMouseEvent event(type);
   247 {
   744     qstmSetGraphicsSceneMouseEvent(scenePos, webView(), event, select);
   248     QRect clientRect = geometry().toAlignedRect();
   745     webView()->page()->event(&event);
   249     m_viewportMetaData->updateViewportData(newContentSize, clientRect);
   746 }
   250     viewportWidget()->resize(QSize(m_viewportMetaData->m_width, m_viewportMetaData->m_height)
   747 
   251                              * m_viewportMetaData->m_initialScale);
   748 void ScrollableWebContentView::disableContentUpdates()
   252 }
   749 {
   253 
   750     if (m_zoomCommitTimer.isActive()) {
   254 void ScrollableWebContentView::pageLoadFinished(bool ok)
   751         m_zoomCommitTimer.stop();
   255 {
   752     }
   256     Q_UNUSED(ok);
   753     webView()->setTiledBackingStoreFrozen(true);
   257     QSize contentSize = viewportWidget()->contentsSize();
   754 }
   258     QRect clientRect = geometry().toAlignedRect();
   755 
   259     m_viewportMetaData->updateViewportData(contentSize, clientRect);
   756 void ScrollableWebContentView::enableContentUpdates()
   260 
   757 {
   261     viewportWidget()->resize(QSize(m_viewportMetaData->m_width, m_viewportMetaData->m_height)
   758     webView()->setTiledBackingStoreFrozen(false);
   262                              * m_viewportMetaData->m_initialScale);
   759 }
   263     viewportWidget()->setZoomScale(m_viewportMetaData->m_initialScale, true);
   760 
   264 }
   761 void ScrollableWebContentView::commitZoom()
       
   762 {         
       
   763     m_zoomCommitTimer.stop();
       
   764     notifyZoomActions(zoomScale());
       
   765     enableContentUpdates();
       
   766     emit scaleChanged(zoomScale());
       
   767 }
       
   768 
       
   769 WebView* ScrollableWebContentView::webView() const
       
   770 {
       
   771     return static_cast<WebView*>(scrollWidget());
       
   772 }
       
   773 
       
   774 void ScrollableWebContentView::setZoomScale(qreal value, bool immediateCommit)
       
   775 {
       
   776     value = qBound(m_viewportMetaData->m_minimumScale, value, m_viewportMetaData->m_maximumScale);
       
   777     qreal curZoomScale = zoomScale();
       
   778 
       
   779     if (qFuzzyCompare(value, curZoomScale)) {
       
   780         notifyZoomActions(curZoomScale);
       
   781         return;
       
   782     }
       
   783 
       
   784     if (!immediateCommit)
       
   785         disableContentUpdates();
       
   786 
       
   787     webView()->setScale(value);
       
   788 
       
   789     if (immediateCommit)
       
   790         commitZoom();
       
   791 //    else
       
   792 //        m_zoomCommitTimer.start(ZoomCommitDuration);
       
   793 }
       
   794 
       
   795 qreal ScrollableWebContentView::zoomScale() const
       
   796 {
       
   797     if (!webView())
       
   798         return 1.;
       
   799 
       
   800     return webView()->scale();
       
   801 }
       
   802 
       
   803 QRectF ScrollableWebContentView::findZoomableRectForPoint(const QPointF& point)
       
   804 {
       
   805     QPointF zoomPoint = webView()->mapFromParent(point);
       
   806 
       
   807     QWebHitTestResult hitResult = webView()->page()->mainFrame()->hitTestContent(zoomPoint.toPoint());
       
   808     QWebElement targetElement = hitResult.enclosingBlockElement();
       
   809 
       
   810     while (!targetElement.isNull() && targetElement.geometry().width() < MinDoubleClickZoomTargetWidth)
       
   811         targetElement = targetElement.parent();
       
   812 
       
   813     if (!targetElement.isNull()) {
       
   814         QRectF elementRect = targetElement.geometry();
       
   815         qreal overMinWidth = elementRect.width() - ZoomableContentMinWidth;
       
   816         if (overMinWidth < 0)
       
   817             elementRect.adjust(overMinWidth / 2, 0, -overMinWidth / 2, 0);
       
   818         qreal destScale = size().width() / elementRect.width();
       
   819         QPointF rectPoint(elementRect.x(),zoomPoint.y() - point.y() / destScale);
       
   820         return QRectF(rectPoint, elementRect.size());
       
   821     }
       
   822     return QRectF();
       
   823 }
       
   824 
       
   825 void ScrollableWebContentView::notifyZoomActions(qreal newScale)
       
   826 {
       
   827     bool enableZoomIn = false;
       
   828     bool enableZoomOut = false;
       
   829 
       
   830     if (m_viewportMetaData->m_userScalable) {
       
   831 
       
   832         if (newScale > m_viewportMetaData->m_minimumScale)
       
   833             enableZoomOut = true;
       
   834         else
       
   835             enableZoomOut = false;
       
   836 
       
   837         if (newScale < m_viewportMetaData->m_maximumScale)
       
   838             enableZoomIn = true;
       
   839         else
       
   840             enableZoomIn = false;
       
   841     }
       
   842 
       
   843     emit updateZoomActions(enableZoomIn, enableZoomOut);
       
   844 }
       
   845 
       
   846 
       
   847 
       
   848 bool ScrollableWebContentView::eventFilter(QObject* o, QEvent* e)
       
   849 {
       
   850     if (o != scrollWidget()) return false;
       
   851     bool ret = false;
       
   852 
       
   853     if (m_gesturesEnabled) {
       
   854             ret = QStm_GestureEventFilter::instance()->eventFilter(o, e);
       
   855         }
       
   856 
       
   857     // Superpages should never receive contextmenu events
       
   858     if (isSuperPage() && (e->type() == QEvent::GraphicsSceneContextMenu || e->type() == QEvent::ContextMenu))
       
   859         ret = true;
       
   860     
       
   861     return ret;
       
   862 }
       
   863 
       
   864 bool ScrollableWebContentView::event(QEvent * e) 
       
   865 {
       
   866     if (e->type() == QEvent::Gesture && m_gesturesEnabled) {
       
   867           QStm_Gesture* gesture = getQStmGesture(e);
       
   868           if (gesture) {
       
   869               bool ret = handleQStmGesture(gesture);
       
   870               if (gesture->getGestureStmType() == QStmTouchGestureType)
       
   871                   e->accept();
       
   872               return ret;
       
   873           }
       
   874     }
       
   875     return QGraphicsWidget::event(e);
       
   876 }
       
   877 
       
   878 
       
   879 
       
   880 bool  ScrollableWebContentView::handleQStmGesture(QStm_Gesture* gesture)
       
   881 {
       
   882 #ifdef OWN_BACKING_STORE
       
   883     // Signal tiling to minimize tile update activity while user does something
       
   884     webView()->userActivity();
       
   885 #endif
       
   886     QStm_GestureType type = gesture->getGestureStmType();
       
   887     bool ret = false;
       
   888     switch (type) {
       
   889         case QStmTapGestureType:
       
   890         {
       
   891             ret = doTap(gesture);
       
   892             break;
       
   893         }
       
   894 
       
   895         case QStmMaybeTapGestureType:
       
   896         {
       
   897             ret = doMaybeTap(gesture);
       
   898             break;
       
   899         }
       
   900 
       
   901         case QStmReleaseGestureType:
       
   902         {
       
   903             ret = doRelease(gesture);
       
   904             break;
       
   905         }
       
   906         case QStmLeftRightGestureType:
       
   907         {
       
   908             ret = doLeftRight(gesture);
       
   909             break;
       
   910         }
       
   911         case QStmUpDownGestureType:
       
   912         {
       
   913             ret = doUpDown(gesture);
       
   914             break;
       
   915         }
       
   916         case QStmPanGestureType:
       
   917         {
       
   918             ret = doPan(gesture);
       
   919             break;
       
   920         }
       
   921         case QStmFlickGestureType:
       
   922         {
       
   923             ret = doFlick(gesture);
       
   924             break;
       
   925         }
       
   926         case QStmDoubleTapGestureType:
       
   927         {
       
   928             ret = doDoubleTap(gesture);
       
   929             break;
       
   930         }
       
   931         case QStmTouchGestureType:
       
   932         {
       
   933             ret = doTouch(gesture);
       
   934             break;
       
   935         }
       
   936         case QStmPinchGestureType:
       
   937         {
       
   938             ret = doPinch(gesture);  
       
   939             break;
       
   940         }
       
   941         case QStmLongPressGestureType:
       
   942         {
       
   943             ret = doLongPress(gesture);
       
   944             break;
       
   945         }
       
   946         
       
   947         default: 
       
   948         {
       
   949             ret = true;
       
   950         }
       
   951     }
       
   952     
       
   953     return ret;
       
   954 }
       
   955 
       
   956 QWebHitTestResult  ScrollableWebContentView::hitTest(const QPointF& scenePos)
       
   957 {
       
   958     QPointF contextPt = webView()->mapFromScene(scenePos);
       
   959     QWebPage* page = webView()->page();
       
   960     return page->currentFrame()->hitTestContent(contextPt.toPoint()); 
       
   961 }
       
   962 
       
   963 
       
   964 
       
   965 bool ScrollableWebContentView::toggleVkb()
       
   966 {
       
   967     bool inputEnabled = false;
       
   968     QInputContext *ic = qApp->inputContext();
       
   969     if (m_hitTest.isContentEditable()) {
       
   970         QEvent sipe(QEvent::RequestSoftwareInputPanel);
       
   971         ic->filterEvent(&sipe);
       
   972         inputEnabled = true;
       
   973     }
       
   974     else {
       
   975         QEvent sipe(QEvent::CloseSoftwareInputPanel);
       
   976         ic->filterEvent(&sipe);
       
   977 
       
   978     }
       
   979     m_isInputOn = inputEnabled;
       
   980     return inputEnabled;
       
   981 }
       
   982 
       
   983 bool  ScrollableWebContentView::toggleInputMethod(bool on)
       
   984 {
       
   985     QGraphicsView* gv = qstmGetGraphicsView(webView());
       
   986     bool oldInputEnabled = false;
       
   987     if (gv != NULL) {
       
   988         gv->testAttribute(Qt::WA_InputMethodEnabled);
       
   989         gv->setAttribute(Qt::WA_InputMethodEnabled, on);
       
   990     }
       
   991     m_isInputOn = on;
       
   992     return oldInputEnabled;
       
   993 }
       
   994 
       
   995 bool  ScrollableWebContentView::inputMethodEnabled()
       
   996 {
       
   997 #ifdef ORBIT_UI
       
   998     HbInputMethod* im = HbInputMethod::activeInputMethod();
       
   999     
       
  1000     QGraphicsView* gv = qstmGetGraphicsView(webView());
       
  1001     bool enabled = false;
       
  1002     if (gv) {
       
  1003         enabled = gv->testAttribute(Qt::WA_InputMethodEnabled);
       
  1004     }
       
  1005     return enabled; 
       
  1006 #else
       
  1007     return false;
       
  1008 #endif // ORBIT_UI
       
  1009 }
       
  1010 
       
  1011 bool  ScrollableWebContentView::doLongPress(QStm_Gesture* gesture)
       
  1012 {
       
  1013     bool willHandle = m_gesturesEnabled && !isSuperPage();
       
  1014     if (willHandle) {
       
  1015 //        QWebPage* page = webView()->page();
       
  1016         QPoint gpos = gesture->position();
       
  1017         QPointF pos = qstmMapToScene(gpos, this);
       
  1018 //        QPointF contextPt = webView()->mapFromScene(pos);
       
  1019         //QWebHitTestResult result = page->currentFrame()->hitTestContent(contextPt.toPoint());
       
  1020     //Notify context menu observers
       
  1021         emit contextEventObject(&m_hitTest, pos);
       
  1022         m_ignoreNextRelease = true;
       
  1023     }
       
  1024     return willHandle;
       
  1025 }
       
  1026 
       
  1027 
       
  1028 
       
  1029 bool ScrollableWebContentView::doTouch(QStm_Gesture* gesture)
       
  1030 {
       
  1031     bool willHandle = m_gesturesEnabled;
       
  1032     m_scrollHelper->stopScrollNoSignal();
       
  1033     m_touchDownPos = gesture->scenePosition(this);
       
  1034     if (!isSuperPage()) {
       
  1035         m_hitTest = hitTest(m_touchDownPos);
       
  1036         //toggleInputMethod(false);
       
  1037         qreal scale = zoomScale();
       
  1038 
       
  1039         m_hoverTimer->stop();
       
  1040         m_hoverTimer->setSingleShot(true);
       
  1041         
       
  1042         m_touchDownTimer->stop();
       
  1043         m_touchDownTimer->setSingleShot(true);
       
  1044                 
       
  1045         m_touchDownTimer->start(TouchDownTimeout, this);
       
  1046         m_hoverTimer->start(HoverTimeout, this);
       
  1047     }
       
  1048     else {
       
  1049         sendEventToWebKit(QEvent::GraphicsSceneMousePress, m_touchDownPos);
       
  1050     }
       
  1051     return willHandle;
       
  1052 }
       
  1053 
       
  1054 void ScrollableWebContentView::touchDownCallback()
       
  1055 {
       
  1056     m_touchDownTimer->stop();
       
  1057     if (m_gesturesEnabled) {
       
  1058         sendEventToWebKit(QEvent::GraphicsSceneMousePress, m_touchDownPos);
       
  1059     }
       
  1060 }
       
  1061 
       
  1062 void ScrollableWebContentView::hoverCallback()
       
  1063 {
       
  1064     m_hoverTimer->stop();
       
  1065     if (m_gesturesEnabled && !isSuperPage()) {
       
  1066         sendEventToWebKit(QEvent::GraphicsSceneMouseMove, m_touchDownPos);
       
  1067     }
       
  1068 }
       
  1069 
       
  1070 
       
  1071 bool ScrollableWebContentView::doTap(QStm_Gesture* gesture)
       
  1072 {
       
  1073     bool willHandle = m_gesturesEnabled;
       
  1074     if (willHandle && !isSuperPage()) {
       
  1075         QPointF pos = gesture->scenePosition(this);
       
  1076         bool hasInputMethod = toggleVkb();
       
  1077         sendEventToWebKit(QEvent::GraphicsSceneMouseRelease, pos);
       
  1078         emit contentViewMouseEvent(QEvent::GraphicsSceneMouseRelease);
       
  1079     }
       
  1080     return willHandle;
       
  1081 }
       
  1082 
       
  1083 bool ScrollableWebContentView::doMaybeTap(QStm_Gesture* gesture)
       
  1084 {
       
  1085     bool willHandle = m_gesturesEnabled;
       
  1086     if (willHandle && isSuperPage()) {
       
  1087         QPointF pos = gesture->scenePosition(this);
       
  1088         sendEventToWebKit(QEvent::GraphicsSceneMouseRelease, pos);
       
  1089     }
       
  1090     return willHandle;
       
  1091 }
       
  1092 
       
  1093 #ifdef USE_KINETIC_SCROLLER
       
  1094 bool ScrollableWebContentView::doPan(QStm_Gesture* gesture)
       
  1095 {
       
  1096     if (m_touchDownTimer->isActive()) {
       
  1097         m_touchDownTimer->stop();
       
  1098     }
       
  1099     
       
  1100     QStm_GestureType type = gesture->getGestureStmType();
       
  1101     bool willHandle = m_gesturesEnabled;
       
  1102     
       
  1103     if (willHandle) {
       
  1104         QPoint scrollPos = ScrollableViewBase::scrollPosition();
       
  1105         QPoint delta = gesture->getLengthAndDirection();
       
  1106         delta.ry() = -delta.y();
       
  1107         m_kineticScroller->doPan(delta);
       
  1108     }
       
  1109     return willHandle;
       
  1110 }
       
  1111 #else
       
  1112 
       
  1113 
       
  1114 bool ScrollableWebContentView::doLeftRight(QStm_Gesture* gesture)
       
  1115 {
       
  1116     bool ret = true;
       
  1117     if (m_hitTest.isContentEditable() && m_isInputOn) {
       
  1118         QPointF pos = gesture->scenePosition(this);
       
  1119         sendEventToWebKit(QEvent::GraphicsSceneMouseMove, pos, true);
       
  1120     }
       
  1121     else {
       
  1122         ret = doPan(gesture);
       
  1123     }
       
  1124     return ret;
       
  1125 }
       
  1126 
       
  1127 
       
  1128 bool ScrollableWebContentView::doUpDown(QStm_Gesture* gesture)
       
  1129 {
       
  1130     bool ret = true;
       
  1131     if (m_hitTest.isContentEditable() && m_isInputOn) {
       
  1132         QPointF pos = gesture->scenePosition(this);
       
  1133         sendEventToWebKit(QEvent::GraphicsSceneMouseMove, pos, true);
       
  1134     }
       
  1135     else {
       
  1136         ret = doPan(gesture);
       
  1137     }
       
  1138     return ret;
       
  1139 }
       
  1140 
       
  1141 
       
  1142 
       
  1143 bool ScrollableWebContentView::doPan(QStm_Gesture* gesture)
       
  1144 {
       
  1145     bool willHandle = m_gesturesEnabled;
       
  1146     if (m_hitTest.isContentEditable() && m_isInputOn) {
       
  1147         QPointF pos = gesture->scenePosition(this);
       
  1148         sendEventToWebKit(QEvent::GraphicsSceneMouseMove, pos, true);
       
  1149     }
       
  1150     else {
       
  1151         dehighlightWebElement();
       
  1152         if (willHandle) {
       
  1153             if (gesture->gestureState() != Qt::GestureFinished) {
       
  1154                 QPointF delta = gesture->sceneLengthAndDirection(this);
       
  1155 
       
  1156                 if (isSuperPage()) {
       
  1157                     delta.rx() = 0.0;
       
  1158                 }
       
  1159                 else {
       
  1160                     //delta.rx() = -delta.x();
       
  1161                 }
       
  1162             
       
  1163                 //disableContentUpdates();
       
  1164                 qstmDebug() << "doPan: gesture timestamp: " << gesture->timestamp().toString("hh:mm:ss.zzz") <<
       
  1165                         ", delta: " << delta << "\n";
       
  1166 
       
  1167                 m_scrollHelper->scroll(delta);
       
  1168             }
       
  1169         }
       
  1170     }
       
  1171     return willHandle;
       
  1172 }
       
  1173 #endif //USE_KINETIC_SCROLLER
       
  1174 
       
  1175 
       
  1176 bool ScrollableWebContentView::doRelease(QStm_Gesture* gesture)
       
  1177 {
       
  1178     bool willHandle = m_gesturesEnabled;
       
  1179     if (willHandle) {
       
  1180         if (m_ignoreNextRelease) {
       
  1181             m_ignoreNextRelease = false;
       
  1182         }
       
  1183         else if (m_scrollHelper->isScrolling()) {
       
  1184             m_scrollHelper->panFromOvershoot();
       
  1185 //            enableContentUpdates();
       
  1186         }
       
  1187         else {
       
  1188             /*
       
  1189              * on tap we send mouseRelease
       
  1190              * assumption here is that we can get
       
  1191              * either tap or release gesture but not both.
       
  1192              */
       
  1193             doTap(gesture);
       
  1194         }
       
  1195     }
       
  1196     return willHandle;
       
  1197 }
       
  1198 
       
  1199 #ifdef USE_KINETIC_SCROLLER
       
  1200 bool ScrollableWebContentView::doFlick(QStm_Gesture* gesture)
       
  1201 {
       
  1202     int direction = gesture->getDirection();
       
  1203     QStm_GestureType type = gesture->getGestureStmType();
       
  1204     bool willHandle = m_gesturesEnabled;
       
  1205     if (willHandle ) {          
       
  1206         m_kineticScroller->doFlick(90 * gesture->getSpeedVec());
       
  1207     }
       
  1208 }
       
  1209 
       
  1210 #else
       
  1211 bool ScrollableWebContentView::doFlick(QStm_Gesture* gesture)
       
  1212 {    
       
  1213     bool willHandle = m_gesturesEnabled;
       
  1214     int afterPinch = m_pinchFinishTime.elapsed();
       
  1215     if (willHandle && afterPinch > 100 && m_scrollHelper->isScrolling()) {
       
  1216         dehighlightWebElement();
       
  1217         int direction = gesture->sceneDirection(this);
       
  1218         QPointF v = gesture->sceneSpeedVec(this);
       
  1219         QPointF vOrig = v;
       
  1220         qstmDebug() << "doFlick: timestamp: " << gesture->timestamp().toString("hh:mm:ss.zzz") <<
       
  1221                 ", v: " << v << "\n";
       
  1222         if (v.x() != 0.0 || v.y() != 0.0) {
       
  1223             if (direction == EEast || direction == EWest) {
       
  1224                 v.ry() = 0.0;
       
  1225             }
       
  1226             if (direction == ENorth || direction == ESouth) {
       
  1227                 v.rx() = 0.0;
       
  1228             }
       
  1229             m_scrollHelper->kineticScroll(v);
       
  1230             //enableContentUpdates();
       
  1231             //m_tileUpdateEnableTimer.start(TileUpdateEnableDelay);
       
  1232         }
       
  1233         else if (afterPinch <= 500) {
       
  1234             qstmDebug() << "doFlick: Flick is too soon after pinch\n";
       
  1235         }
       
  1236     }
       
  1237     return willHandle;
       
  1238 }
       
  1239 #endif //USE_KINETIC_SCROLLER
       
  1240 
       
  1241 bool ScrollableWebContentView::doDoubleTap(QStm_Gesture* gesture)
       
  1242 {
       
  1243     if (!m_gesturesEnabled || !m_viewportMetaData->m_userScalable) {
       
  1244         m_touchDownTimer->stop();
       
  1245         m_hoverTimer->stop();
       
  1246         return m_gesturesEnabled;    
       
  1247     }
       
  1248     dehighlightWebElement();
       
  1249     QPointF pos = gesture->scenePosition(this);
       
  1250     pos = mapFromScene(pos);
       
  1251     qstmDebug() << "doDoubleTap: zoom at pos: " << pos << "\n";
       
  1252     zoomAtPoint(pos);
       
  1253     
       
  1254     return m_gesturesEnabled;
       
  1255 }
       
  1256 
       
  1257 #define square(x) (x)*(x)
       
  1258 
       
  1259 qreal ScrollableWebContentView::calcScale(int origDistance, QPointF p1, QPointF p2)
       
  1260 {
       
  1261     qreal d1f = origDistance;
       
  1262     qreal dist = calcDistance(p1, p2);
       
  1263     return (dist/ d1f);
       
  1264 }
       
  1265 
       
  1266 qreal ScrollableWebContentView::calcDistance(QPointF pt1, QPointF pt2)
       
  1267 {
       
  1268     return (sqrt((double)square(pt2.x() - pt1.x()) + square(pt2.y() - pt1.y())));
       
  1269 }
       
  1270 
       
  1271 QPointF ScrollableWebContentView::calcCenter(QPointF pt1, QPointF pt2)
       
  1272 {
       
  1273     return((pt1 + pt2) / 2);
       
  1274 }
       
  1275 
       
  1276 bool ScrollableWebContentView::doPinch(QStm_Gesture* gesture)
       
  1277 {
       
  1278     m_scrollHelper->stopScrollNoSignal();
       
  1279     dehighlightWebElement();
       
  1280     m_pinchFinishTime.restart();
       
  1281     if (!m_gesturesEnabled || !m_viewportMetaData->m_userScalable)
       
  1282         return m_gesturesEnabled;
       
  1283 
       
  1284     // Normally, "details" contains the distance between the two touched points
       
  1285     // It's null when the pinch starts (which in effect is zero)
       
  1286     // When we start pinch, we don't zoom because there is no delta
       
  1287     QPointF p1 = gesture->scenePosition(this);
       
  1288     QPointF p2 = gesture->scenePosition2(this);
       
  1289     if (gesture->gestureState() == Qt::GestureFinished) {
       
  1290         commitZoom();        
       
  1291         return m_gesturesEnabled;
       
  1292     }
       
  1293 
       
  1294     if (!gesture->getDetails()) {
       
  1295         m_pinchStartDistance = calcDistance(p1, p2);
       
  1296         m_pinchStartScale = zoomScale();
       
  1297     }
       
  1298     else {
       
  1299         qreal scale = calcScale(m_pinchStartDistance, p1, p2);
       
  1300         qreal newScale = qBound(m_viewportMetaData->m_minimumScale, 
       
  1301                                 scale * m_pinchStartScale,
       
  1302                                 m_viewportMetaData->m_maximumScale);
       
  1303         // Don't allow zooming beyond the min/max but still call the zoom animation (coz the hotspot could be moving and we want to pan with it)
       
  1304         //zoomToHotSpot(calcCenter(p1, p2), newScale);
       
  1305         if (!qFuzzyCompare(zoomScale(), newScale)) {
       
  1306             startZoomAnimationToHotSpot(calcCenter(p1, p2), newScale, ZoomAnimationDuration);
       
  1307         }
       
  1308     }
       
  1309     return m_gesturesEnabled;
       
  1310 }
       
  1311 
       
  1312 bool ScrollableWebContentView::isZooming()
       
  1313 {
       
  1314     return m_zoomAnimator->state() == QAbstractAnimation::Running;     
       
  1315 }
       
  1316 
       
  1317 void ScrollableWebContentView::setGesturesEnabled(bool value) 
       
  1318 { 
       
  1319     if (!value && m_touchDownTimer->isActive()) {
       
  1320         m_touchDownTimer->stop();
       
  1321     }
       
  1322 
       
  1323     m_gesturesEnabled = value;
       
  1324 }
       
  1325 
       
  1326 bool ScrollableWebContentView::gesturesEnabled() 
       
  1327 { 
       
  1328     return m_gesturesEnabled; 
       
  1329 }
       
  1330 
       
  1331 
       
  1332 void ScrollableWebContentView::dehighlightWebElement()
       
  1333 {
       
  1334     m_touchDownTimer->stop();
       
  1335     m_hoverTimer->stop();
       
  1336     
       
  1337     QSizeF contentSize = webView()->size();
       
  1338     QPointF dummyPosF(-contentSize.width() - 2.0, -contentSize.height( ) - 2.0);
       
  1339     QPoint dummyPos(-1, -1);
       
  1340     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
       
  1341     event.setScenePos(dummyPos);
       
  1342     event.setPos(dummyPos);
       
  1343     event.setButton(Qt::LeftButton);
       
  1344 
       
  1345     bool hasInputMethod = toggleInputMethod(false);
       
  1346     webView()->page()->event(&event);
       
  1347     toggleInputMethod(hasInputMethod);
       
  1348     //sendEventToWebKit(QEvent::GraphicsSceneMouseRelease, dummyPos);    
       
  1349 }
       
  1350 
       
  1351 
       
  1352 void ScrollableWebContentView::stopScrolling()
       
  1353 {
       
  1354     m_isScrolling = false;
       
  1355     //enableContentUpdates();
       
  1356 }
       
  1357 
       
  1358 
   265 
  1359 
   266 bool ScrollableWebContentView::sceneEventFilter(QGraphicsItem* item, QEvent* event)
  1360 bool ScrollableWebContentView::sceneEventFilter(QGraphicsItem* item, QEvent* event)
   267 {
  1361 {
   268     Q_UNUSED(item);
  1362     Q_UNUSED(item);
   269 
  1363 
   270     bool handled = false;
  1364     bool handled = false;
   271     
  1365 #ifdef USE_KINETIC_SCROLLER    
   272     if (!isVisible() || !m_gesturesEnabled) {
  1366     if (!isVisible())
   273         if (event->type() == QEvent::GraphicsSceneContextMenu)
  1367         return handled;
   274             return true;
       
   275         else
       
   276             return handled;
       
   277     }
       
   278 
  1368 
   279     //Pass all events to recognizer
  1369     //Pass all events to recognizer
   280     handled  = m_gestureRecognizer.mouseEventFilter(static_cast<QGraphicsSceneMouseEvent *>(event));
  1370     handled  = m_gestureRecognizer.mouseEventFilter(static_cast<QGraphicsSceneMouseEvent *>(event));
       
  1371 #endif
   281     return handled;
  1372     return handled;
   282 }
  1373 }
       
  1374 
   283 
  1375 
   284 void ScrollableWebContentView::handleGesture(GestureEvent* gestureEvent)
  1376 void ScrollableWebContentView::handleGesture(GestureEvent* gestureEvent)
   285 {
  1377 {
   286     switch (gestureEvent->type()) {
  1378     switch (gestureEvent->type()) {
   287     case GestureEvent::Touch:
  1379     case GestureEvent::Touch:
   315     sendEventToWebKit(QEvent::GraphicsSceneMousePress, pos);
  1407     sendEventToWebKit(QEvent::GraphicsSceneMousePress, pos);
   316 }
  1408 }
   317 
  1409 
   318 void ScrollableWebContentView::handleRelease(GestureEvent* gestureEvent)
  1410 void ScrollableWebContentView::handleRelease(GestureEvent* gestureEvent)
   319 {
  1411 {
   320     //FIX ME:
       
   321     emit mouseEvent(QEvent::GraphicsSceneMousePress);
       
   322     //Cache release event to send on release
  1412     //Cache release event to send on release
   323     QPointF pos = gestureEvent->position();
  1413     QPointF pos = gestureEvent->position();
   324     sendEventToWebKit(QEvent::GraphicsSceneMouseRelease, pos);
  1414     sendEventToWebKit(QEvent::GraphicsSceneMouseRelease, pos);
   325     emit mouseEvent(QEvent::GraphicsSceneMouseRelease);
       
   326 }
  1415 }
   327 
  1416 
   328 void ScrollableWebContentView::handleDoubleTap(GestureEvent* gestureEvent)
  1417 void ScrollableWebContentView::handleDoubleTap(GestureEvent* gestureEvent)
   329 {
  1418 {
   330     if (!m_viewportMetaData->m_userScalable)
  1419     if (!m_viewportMetaData->m_userScalable)
   331         return;
  1420         return;
   332 
  1421 
   333     QRectF target;
  1422     QRectF target;
   334     WebContentAnimationItem* webViewProxy = viewportWidget();
       
   335 
       
   336     // Contentview center is the focus hotspot
       
   337     QPointF viewTargetHotspot(size().width() / 2, size().height() / 2);
       
   338 
  1423 
   339     //Get the focussable element rect from current touch position
  1424     //Get the focussable element rect from current touch position
   340     QPointF touchPoint = webViewProxy->mapFromScene(gestureEvent->position());
  1425     QPointF touchPoint = mapFromScene(gestureEvent->position());
   341     QRectF zoomRect = webViewProxy->findZoomableRectForPoint(touchPoint);
  1426 
       
  1427     if(isZoomedIn()) {
       
  1428         startZoomAnimationToHotSpot(touchPoint,size().width() / webView()->size().width());
       
  1429             return;
       
  1430     }
       
  1431 
       
  1432     QRectF zoomRect = findZoomableRectForPoint(touchPoint);
   342 
  1433 
   343     if (!zoomRect.isValid()) {
  1434     if (!zoomRect.isValid()) {
   344         //FIX ME: Add an event ignore animation
  1435         //FIX ME: Add an event ignore animation
   345         return;
  1436         return;
   346     }
  1437     }
   347 
  1438 
   348     // target is the center of the identified rect x-wise
  1439     startZoomAnimation(zoomRect);
   349     // y-wise it's the place user touched
       
   350     QPointF hotspot(zoomRect.center().x(), touchPoint.y());
       
   351     qreal scale = size().width() / zoomRect.size().width();
       
   352     startZoomAnimToItemHotspot(hotspot, viewTargetHotspot, scale, zoomRect);
       
   353 }
  1440 }
   354 
  1441 
   355 void ScrollableWebContentView::handlePan(GestureEvent* gestureEvent)
  1442 void ScrollableWebContentView::handlePan(GestureEvent* gestureEvent)
   356 {
  1443 {
   357     QPoint scrollPos = ScrollableViewBase::scrollPosition();
  1444     QPoint scrollPos = ScrollableViewBase::scrollPosition();
   358     m_kineticScroller->doPan(gestureEvent->delta());
  1445     m_kineticScroller->doPan(gestureEvent->delta());
   359     QPoint delta;
       
   360     delta.setX(-gestureEvent->delta().x());
       
   361     delta.setY(-gestureEvent->delta().y());
       
   362     emit viewScrolled(scrollPos, delta);
       
   363 }
  1446 }
   364 
  1447 
   365 void ScrollableWebContentView::handleFlick(GestureEvent* gestureEvent)
  1448 void ScrollableWebContentView::handleFlick(GestureEvent* gestureEvent)
   366 {
  1449 {
   367     QPoint scrollPos = ScrollableViewBase::scrollPosition();
  1450     QPoint scrollPos = ScrollableViewBase::scrollPosition();
   368     m_kineticScroller->doFlick(gestureEvent->velocity());
  1451     m_kineticScroller->doFlick(gestureEvent->velocity());
   369 }
  1452 }
   370 
  1453 
   371 void ScrollableWebContentView::handleLongTap(GestureEvent* gestureEvent)
  1454 void ScrollableWebContentView::handleLongTap(GestureEvent* gestureEvent)
   372 {
  1455 {
   373     QWebPage* page = viewportWidget()->webView()->page();
  1456     QWebPage* page = webView()->page();
   374     QPointF contextPt = viewportWidget()->webView()->mapFromScene(gestureEvent->position());
  1457     QPointF contextPt = webView()->mapFromScene(gestureEvent->position());
   375     QWebHitTestResult result = page->currentFrame()->hitTestContent(contextPt.toPoint());
  1458     QWebHitTestResult result = page->currentFrame()->hitTestContent(contextPt.toPoint());
   376 
  1459     
   377     //Notify context menu observers
  1460     //Notify context menu observers
   378     emit contextEventObject(&result);
  1461     emit contextEventObject(&result, gestureEvent->position());
   379 }
  1462 }
   380 
  1463 
   381 void ScrollableWebContentView::setViewportWidgetGeometry(const QRectF& r)
  1464 void ScrollableWebContentView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
   382 {
  1465 {
   383     ScrollableViewBase::setScrollWidgetGeometry(r);
  1466 
   384 }
  1467     QRectF fillRect = option ? option->exposedRect : QRectF(QPoint(0, 0), size());
   385 
  1468 
   386 void ScrollableWebContentView::startZoomAnimToItemHotspot(const QPointF& hotspot, const QPointF& viewTargetHotspot, qreal scale,  QRectF target)
  1469     painter->fillRect(fillRect, Qt::white);
   387 {
  1470 }
   388     WebContentAnimationItem* animWidget = viewportWidget();
  1471 
   389 
       
   390     QPointF newHotspot = hotspot * scale;
       
   391     QPointF newViewportOrigon = newHotspot - viewTargetHotspot;
       
   392     QRectF zoomedRect(-newViewportOrigon, animWidget->size() * scale);
       
   393 
       
   394     QRectF temp = adjustScrollWidgetRect(zoomedRect);
       
   395     qreal diff = qAbs(scrollWidget()->geometry().y() - temp.y());
       
   396 
       
   397     //FIX ME : Seperate the logic for centerzoom and block-focus zoom
       
   398     if (qFuzzyCompare(scrollWidget()->geometry().topLeft().x(), temp.topLeft().x())
       
   399         && qFuzzyCompare(scrollWidget()->geometry().width(), temp.width())
       
   400         && qFuzzyCompare(scrollWidget()->geometry().height(), temp.height())
       
   401         && !target.isEmpty() && (diff <= target.height())) {
       
   402 
       
   403             scale = size().width() / animWidget->size().width();
       
   404             newHotspot = QPointF(0, -animWidget->pos().y()) * scale;
       
   405             newViewportOrigon = newHotspot - viewTargetHotspot;
       
   406             zoomedRect = QRectF(-newViewportOrigon, animWidget->size() * scale);
       
   407     }
       
   408 
       
   409     startZoomAnimation(zoomedRect);
       
   410 }
       
   411 
       
   412 bool ScrollableWebContentView::isZoomedIn() const
       
   413 {
       
   414     return size().width() < viewportWidget()->size().width();
       
   415 }
       
   416 
       
   417 void ScrollableWebContentView::stateChanged(KineticScrollable::State oldState
       
   418                                             , KineticScrollable::State newState)
       
   419 {
       
   420     ScrollableViewBase::stateChanged(oldState, newState);
       
   421 
       
   422     if (newState == KineticScrollable::Pushing) {
       
   423         m_tileUpdateEnableTimer.stop();
       
   424         viewportWidget()->disableContentUpdates();
       
   425     }
       
   426     else if (newState == KineticScrollable::AutoScrolling) {
       
   427         m_tileUpdateEnableTimer.stop();
       
   428         viewportWidget()->disableContentUpdates();
       
   429     }
       
   430     else if (newState == KineticScrollable::Inactive) {
       
   431         m_tileUpdateEnableTimer.start(TileUpdateEnableDelay);
       
   432     }
       
   433 }
       
   434 
       
   435 void ScrollableWebContentView::startZoomAnimation(const QRectF& destRect)
       
   436 {
       
   437     QAbstractAnimation::State animState = m_zoomAnimator->state();
       
   438     if (animState == QAbstractAnimation::Running)
       
   439         return;
       
   440 
       
   441     m_zoomAnimator->setStartValue(scrollWidget()->geometry());
       
   442     m_animationEndRect = adjustScrollWidgetRect(destRect);
       
   443     m_zoomAnimator->setEndValue(m_animationEndRect);
       
   444     m_zoomAnimator->start();
       
   445 }
       
   446 
       
   447 void ScrollableWebContentView::stopZoomAnimation()
       
   448 {
       
   449     m_animationEndRect = QRectF();
       
   450     m_zoomAnimator->stop();
       
   451 }
       
   452 
       
   453 void ScrollableWebContentView::updateZoomEndRect()
       
   454 {
       
   455     if (m_animationEndRect.isValid())
       
   456         scrollWidget()->setGeometry(m_animationEndRect);
       
   457 }
       
   458 
       
   459 void ScrollableWebContentView::zoomAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
       
   460 {
       
   461     switch (newState) {
       
   462     case QAbstractAnimation::Stopped:
       
   463         updateZoomEndRect();
       
   464         break;
       
   465     default:
       
   466         break;
       
   467     }
       
   468 }
       
   469 
       
   470 void ScrollableWebContentView::resizeEvent(QGraphicsSceneResizeEvent* event)
       
   471 {
       
   472     QGraphicsWidget::resizeEvent(event);
       
   473 
       
   474     //Ignore resize when chrome is being still setup
       
   475     if (!event->oldSize().width())
       
   476         return;
       
   477 
       
   478     adjustViewportSize(event->oldSize(), event->newSize());
       
   479 }
       
   480 
       
   481 void ScrollableWebContentView::adjustViewportSize(QSizeF oldSize, QSizeF newSize)
       
   482 {
       
   483     //FIX ME : Check this
       
   484     if (m_viewportMetaData->m_isValid) {
       
   485 
       
   486         QRect clientRect = geometry().toAlignedRect();
       
   487         if (m_viewportMetaData->isLayoutNeeded())  {
       
   488             m_viewportMetaData->orientationChanged(clientRect);
       
   489             updatePreferredContentSize();
       
   490             return;
       
   491         } else
       
   492             m_viewportMetaData->updateViewportData(viewportWidget()->contentsSize(), clientRect);
       
   493     }
       
   494 
       
   495     qreal scale = newSize.width() / oldSize.width();
       
   496     QPointF middleLeft(0, oldSize.height()/2);
       
   497     QPointF docPoint(viewportWidget()->mapFromScene(middleLeft));
       
   498 
       
   499     QPointF resizedMiddleLeft(0, newSize.height()/2);
       
   500     QPointF resizedDocPoint(viewportWidget()->mapFromScene(resizedMiddleLeft));
       
   501     QPointF docPointInScr(viewportWidget()->mapToParent(resizedDocPoint));
       
   502 
       
   503     //FIX ME : Should be handled with only following function call
       
   504     //Since its not working, work-around is added. Plz fix it
       
   505     //startZoomAnimToItemHotspot(docPoint, docPointInScr, scale);
       
   506 
       
   507     QPointF newHotspot = docPoint * scale;
       
   508     QPointF newViewportOrigon = newHotspot - docPointInScr;
       
   509     QRectF zoomedRect(-newViewportOrigon,  viewportWidget()->size() * scale);
       
   510     QRectF adjustRect = adjustScrollWidgetRect(zoomedRect);
       
   511 
       
   512     setScrollWidgetGeometry(zoomedRect);
       
   513 }
       
   514 
       
   515 void ScrollableWebContentView::sendEventToWebKit(QEvent::Type type, QPointF& scenPos)
       
   516 {
       
   517     //Setup event and send it to webkit
       
   518     QGraphicsSceneMouseEvent event(type);
       
   519     event.setScenePos(scenPos);
       
   520     event.setPos(viewportWidget()->webView()->mapFromScene(event.scenePos()));
       
   521     event.setButton(Qt::LeftButton);
       
   522     event.setButtons(Qt::LeftButton);
       
   523     event.setModifiers(Qt::NoModifier);
       
   524     viewportWidget()->webView()->page()->event(&event);
       
   525 }
       
   526 
  1472 
   527 } //namespace GVA
  1473 } //namespace GVA