ginebra2/GWebTouchNavigation.cpp
changeset 3 0954f5dd2cd0
parent 0 1450b09d0cfd
child 16 3c88a81ff781
--- a/ginebra2/GWebTouchNavigation.cpp	Fri May 14 15:40:36 2010 +0300
+++ b/ginebra2/GWebTouchNavigation.cpp	Tue Jun 29 00:46:29 2010 -0400
@@ -1,41 +1,39 @@
 /*
 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, version 2.1 of the License.
 *
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU Lesser General Public License for more details.
 *
-* Contributors:
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not,
+* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
 *
-* Description: 
+* Description:
 *
 */
 
+#include "GWebTouchNavigation.h"
+#include "wrtBrowserUtils.h"
 
-#include "GWebTouchNavigation.h"
-#include "qwebpage.h"
-#include "qwebframe.h"
-#include "qapplication.h"
-#include "qwebelement.h"
-#include "GWebContentViewWidget.h"
-#include "GWebContentView.h"
+#include <QWebPage>
+#include <QWebFrame>
+#include <QApplication>
+#include <QWebElement>
 #include <QGraphicsSceneMouseEvent>
 #include <QTimer>
 #include <qmath.h>
 #include <QDebug>
 #include <QGraphicsView>
 
-#include "webcontentview.h"
-#include "wrtBrowserUtils.h"
-#include "ChromeWidget.h"
-#include <qdebug.h>
 
-
-#define LONG_PRESS_DURATION 500
+namespace GVA {
 
 const int KFlickSpeed = 400;
 const qreal PI = 3.1415926535897932;
@@ -55,19 +53,14 @@
 const int KPanThreshold = 2;
 const int KThreshHoldValForLink = 10;
 const qreal KDeccelaration = 1000.00;
-const int KDefaultViewportWidth = 980;
-const int KDefaultPortraitScaleWidth = 540;
-
-const int KKineticTimeout = 60;
 
 static const int KStartPanDistance = 50;
 static const int KWaitForClickTimeoutMS = 200;
+static const int KLongPressDuration = 1000;
+static const int KLongPressThreshold = 30;
 //The amount of pixels to try to pan before pan mode unlocks
 static const int KPanModeChangeDelta = 100;
 
-
-namespace GVA {
-
 /*!
     \class WebTouchNavigation
     \since cwrt 1.0
@@ -75,45 +68,60 @@
 
     \sa WebNavigation, WebHtmlTabIndexedNavigation, WebCursorNavigation, WebDirectionalNavigation
 */
-GWebTouchNavigation::GWebTouchNavigation(QWebPage* webPage,GWebContentViewWidget* view)
+GWebTouchNavigation::GWebTouchNavigation(QWebPage* webPage, QGraphicsWebView* view)
 : m_webPage(webPage)
 , m_view(view)
 , m_frame(0)
 , m_doubleClickTimer(0)
 , m_pressEvent(0)
-, m_scrollTimer(0)
 , m_releaseEvent(0)
 , m_focusedBlockPt(-1, -1)
 , m_ishighlighted(false)
 , m_offset(0)
 , m_longPressTimer(0)
 , m_finalzoomfactor(0)
+, m_scrollTimer(0)
 , m_kineticTimer(0)
 , m_isPanning(false)
 , m_enabled(true)
+, m_textSelected(false)
 , m_isLoading(false)
+, m_contentHeight(0)
+, m_isContextEvent(false)
+, m_wantSlideViewCalls(true)
+, m_doubleClickEnabled(true)
 {
         install();
-        connect(m_view, SIGNAL(BlockFocusChanged(QPoint)), this, SLOT(BlockFocusChanged(QPoint)));
         connect(m_webPage, SIGNAL(loadStarted()), this, SLOT(onLoadStarted()));
         connect(m_webPage, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
 }
 
+inline void GWebTouchNavigation::cancelPressEvent() {
+    if (m_pressEvent) {
+        delete m_pressEvent;
+        m_pressEvent = 0;
+    }
+}
+
+inline void GWebTouchNavigation::cancelReleaseEvent() {
+    if (m_releaseEvent) {
+        delete m_releaseEvent;
+        m_releaseEvent = 0;
+    }
+}
+
 /*!
 */
-GWebTouchNavigation::~GWebTouchNavigation() 
+GWebTouchNavigation::~GWebTouchNavigation()
 {
-    disconnect(m_doubleClickTimer, SIGNAL(timeout()), this, SLOT(doubleClickTimerExpired()));    
-    if (m_doubleClickTimer) {
-        m_doubleClickTimer->stop();
-        delete m_doubleClickTimer;
-    }
-    disconnect(m_scrollTimer, SIGNAL(timeout()),this,SLOT(pan()));
+    delete m_doubleClickTimer;
     delete m_scrollTimer;
-    
-    disconnect(m_kineticTimer, SIGNAL(timeout()),this,SLOT(kineticScroll()));
     delete m_kineticTimer;
+    delete m_longPressTimer;
     uninstall();
+
+    cancelPressEvent();
+    cancelReleaseEvent();
 }
 
 void GWebTouchNavigation::install()
@@ -123,7 +131,7 @@
 
 void GWebTouchNavigation::BlockFocusChanged(QPoint pt)
 {
-	m_focusedBlockPt = pt;
+    m_focusedBlockPt = pt;
 }
 
 void GWebTouchNavigation::uninstall()
@@ -171,15 +179,16 @@
                 return true;
             }
             break;
-        case QEvent::GraphicsSceneMouseRelease: 
+        case QEvent::GraphicsSceneMouseRelease:
             mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(event)->pos().toPoint());
             emit mouseEvent(QEvent::GraphicsSceneMouseRelease);
             return true;
-            break;
         case QEvent::GraphicsSceneMouseDoubleClick:
             mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent*>(event)->pos().toPoint());
             emit mouseEvent(QEvent::GraphicsSceneMouseDoubleClick);
             return true;
+        case QEvent::GraphicsSceneContextMenu:
+            contextMenuEvent();
             break;
         default:
             break;
@@ -189,73 +198,73 @@
 
 void GWebTouchNavigation::stopScrolling()
 {
-	if (m_scrollTimer && m_scrollTimer->isActive()) {
-	    m_scrollTimer->stop();
-	    m_scrollDelta = QPoint(0,0);
-	}
-	
-	if (m_kineticTimer && m_kineticTimer->isActive()) {
-	    m_kineticTimer->stop();
-	    m_kineticSpeed.setX(0.0);
-	    m_kineticSpeed.setY(0.0);
-	}
+    if (m_scrollTimer && m_scrollTimer->isActive()) {
+        m_scrollTimer->stop();
+        m_scrollDelta = QPoint(0,0);
+    }
+
+    if (m_kineticTimer && m_kineticTimer->isActive()) {
+        m_kineticTimer->stop();
+        m_kineticSpeed.setX(0.0);
+        m_kineticSpeed.setY(0.0);
+    }
 }
 
 
 void GWebTouchNavigation::pan()
 {
-	if (m_scrollDelta.x() != 0 || m_scrollDelta.y() != 0) {
+    if (m_scrollDelta.x() != 0 || m_scrollDelta.y() != 0) {
             scrollCurrentFrame(-m_scrollDelta.x(), m_scrollDelta.y());
-	    m_scrollDelta = QPoint(0,0);
-	}
+        m_scrollDelta = QPoint(0,0);
+    }
 }
 
-#define DECELERATION 0.0002 
+#define DECELERATION 0.0002
 
 void GWebTouchNavigation::kineticScroll()
 {
-	qreal decelX = m_kineticSpeed.x() > 0 ? -DECELERATION : DECELERATION;
-	qreal decelY = m_kineticSpeed.y() > 0 ? -DECELERATION : DECELERATION;
-	qreal dx = 0;
-	qreal dy = 0;
-	qreal vx = 0;
-	qreal vy = 0;
-	
-	m_kineticScrollTime += m_actualTime.elapsed();
-	
-	if (m_kineticSpeed.x()) {
-		vx = m_kineticSpeed.x() + decelX * m_kineticScrollTime;
-		if (vx * m_kineticSpeed.x() < 0) {
-			dx = 0;
-			vx = 0;
-		}
-		else {
-	        dx = m_kineticScrollTime * m_kineticSpeed.x() + 
-		        0.5 * decelX * m_kineticScrollTime * m_kineticScrollTime;
-		}
-	}
-	
-	if (m_kineticSpeed.y()) {
-		vy = m_kineticSpeed.y() + decelY * m_kineticScrollTime;
-		if (vy * m_kineticSpeed.y() < 0) {
-			dy = 0;
-			vy = 0;
-		}
-		else {
-		    dy = m_kineticScrollTime * m_kineticSpeed.y() + 
-			     0.5 * decelY * m_kineticScrollTime * m_kineticScrollTime;
-		}
-	}
-		
-	QPoint scrollPos = m_frame->scrollPosition();
-	QPoint distPos = m_initialScrollPos + QPointF(dx, dy).toPoint();
-	
-	if (vx != 0 || vy != 0) {
+    qreal decelX = m_kineticSpeed.x() > 0 ? -DECELERATION : DECELERATION;
+    qreal decelY = m_kineticSpeed.y() > 0 ? -DECELERATION : DECELERATION;
+    qreal dx = 0;
+    qreal dy = 0;
+    qreal vx = 0;
+    qreal vy = 0;
+
+    m_kineticScrollTime += m_actualTime.elapsed();
+
+    if (m_kineticSpeed.x()) {
+        vx = m_kineticSpeed.x() + decelX * m_kineticScrollTime;
+        if (vx * m_kineticSpeed.x() < 0) {
+            dx = 0;
+            vx = 0;
+        }
+        else {
+            dx = m_kineticScrollTime * m_kineticSpeed.x() +
+                0.5 * decelX * m_kineticScrollTime * m_kineticScrollTime;
+        }
+    }
+
+    if (m_kineticSpeed.y()) {
+        vy = m_kineticSpeed.y() + decelY * m_kineticScrollTime;
+        if (vy * m_kineticSpeed.y() < 0) {
+            dy = 0;
+            vy = 0;
+        }
+        else {
+            dy = m_kineticScrollTime * m_kineticSpeed.y() +
+                 0.5 * decelY * m_kineticScrollTime * m_kineticScrollTime;
+        }
+    }
+
+    QPoint scrollPos = m_frame->scrollPosition();
+    QPoint distPos = m_initialScrollPos + QPointF(dx, dy).toPoint();
+
+    if (vx != 0 || vy != 0) {
             setCurrentFrameScrollPosition(distPos);
-	}
-    
-	if ((vx == 0 && vy == 0) || scrollPos == m_frame->scrollPosition()) {
-    	stopScrolling();
+    }
+
+    if ((vx == 0 && vy == 0) || scrollPos == m_frame->scrollPosition()) {
+        stopScrolling();
     }
 
 }
@@ -270,21 +279,20 @@
 {
     if (qAbs(diff.x()) < KPanThreshold && qAbs(diff.y()) < KPanThreshold)
         return;
-		else if(m_dragPoints.size() == 1) {	
-        //WebContentWidget* view = qobject_cast<WebContentWidget*>(m_view);
-        m_view->setBlockElement(QWebElement());
-		}
-        
-		if(!m_isPanning) {
+    else if (m_dragPoints.size() == 1) {
+        setViewBlockElement(QWebElement());
+    }
+
+    if (!m_isPanning) {
         qreal dy = qAbs(diff.y());
         qreal dx = qAbs(diff.x());
         if (dy > KStartPanDistance || dx > KStartPanDistance
-        || m_delayedPressMoment.elapsed() > KWaitForClickTimeoutMS) {
+            || m_delayedPressMoment.elapsed() > KWaitForClickTimeoutMS) {
             //get the scroll direction
             Direction scrollDir = findDirectionWithAngle(diff);
-            if(scrollDir == UP || scrollDir == DOWN)
+            if (scrollDir == UP || scrollDir == DOWN)
                 startPanGesture(VerticalPan);
-            else if(scrollDir == LEFT || scrollDir == RIGHT)
+            else if (scrollDir == LEFT || scrollDir == RIGHT)
                 startPanGesture(HorizontalPan);
             else
                 startPanGesture(RandomPan);
@@ -292,15 +300,15 @@
         }
     }
 
-		if (m_isPanning) {
-				m_scrolled= false;
-				m_frame = getNextScrollableFrame(diff);
-				QPoint scrollPosition = m_frame->scrollPosition();
-				if (diff.manhattanLength())
-						panBy(diff);            
-				
-				m_scrolled = (scrollPosition != m_frame->scrollPosition());
-		}
+    if (m_isPanning) {
+        m_scrolled= false;
+        m_frame = getNextScrollableFrame(diff);
+        QPoint scrollPosition = m_frame->scrollPosition();
+        if (diff.manhattanLength())
+            panBy(diff);
+
+        m_scrolled = (scrollPosition != m_frame->scrollPosition());
+    }
 }
 
 void GWebTouchNavigation::startPanGesture(PanDirection directionHint) {
@@ -310,29 +318,29 @@
 }
 
 void GWebTouchNavigation::panBy(const QPointF& delta) {
-    
+
     m_panModeResidue += delta;
 
     if (qAbs(m_panModeResidue.x()) > KPanModeChangeDelta)
         m_panDirection = HorizontalPan;
-    
+
     if (qAbs(m_panModeResidue.y()) > KPanModeChangeDelta)
         m_panDirection = VerticalPan;
-   
-    if(qAbs(m_panModeResidue.x()) > KPanModeChangeDelta 
+
+    if (qAbs(m_panModeResidue.x()) > KPanModeChangeDelta
         && qAbs(m_panModeResidue.y()) > KPanModeChangeDelta)
         m_panDirection = RandomPan;
-    
+
     QPointF p;
-    if(m_panDirection == HorizontalPan)
+    if (m_panDirection == HorizontalPan)
         p.setX(delta.x());
-    if(m_panDirection == VerticalPan)
+    if (m_panDirection == VerticalPan)
         p.setY(delta.y());
-    if(m_panDirection == RandomPan) {
-        p.setX(delta.x());     
+    if (m_panDirection == RandomPan) {
+        p.setX(delta.x());
         p.setY(delta.y());
     }
-        
+
     scrollCurrentFrame(p.x(),p.y());
 }
 
@@ -350,52 +358,52 @@
     return std::min(std::max(y, r.y()), r.y() + r.height());
 }
 
-bool GWebTouchNavigation::traverseNextNode(QWebElement parentNode,QWebElement& nextNode) 
-{ 
+bool GWebTouchNavigation::traverseNextNode(QWebElement parentNode,QWebElement& nextNode)
+{
     if (!parentNode.firstChild().isNull()) {
         nextNode = parentNode.firstChild();
         return true;
     }
-           
+
     if (!parentNode.nextSibling().isNull()) {
         nextNode = parentNode.nextSibling();
         return true;
     }
 
     QWebElement n = parentNode;
-    while (!n.isNull() && n.nextSibling().isNull()) 
-        n = n.parent (); 
-    
+    while (!n.isNull() && n.nextSibling().isNull())
+        n = n.parent ();
+
     if (!n.isNull()) {
         nextNode = n.nextSibling();
         return true;
     }
 
-    return false; 
-} 
+    return false;
+}
 
 
 QWebElement GWebTouchNavigation::getClosestAnchorElement(QMouseEvent* ev)
-{   
+{
     QWebElement webElement;
     QWebHitTestResult htRes = getHitTestResult(ev);
     QWebElement hitElement = htRes.element();
     //check whether hit test returns a link element
-    if(!htRes.linkElement().isNull()) {
-        webElement = htRes.linkElement();              
-		m_higlightedPos = ev->pos();
+    if (!htRes.linkElement().isNull()) {
+        webElement = htRes.linkElement();
+        m_higlightedPos = ev->pos();
         m_ishighlighted = true;
     }
     //get the closet anchor element
     else {
-		QPoint docPoint = (m_touchPosition + m_frame->scrollPosition());
+        QPoint docPoint = (m_touchPosition + m_frame->scrollPosition());
         int dist = 99999999;
         QWebElement result;
         QWebElement ele = m_webPage->currentFrame()->documentElement();
         do {
-            if(ele.tagName().compare("a",Qt::CaseInsensitive) == 0 ) {       
+            if (ele.tagName().compare("a",Qt::CaseInsensitive) == 0 ) {
                 QRect r = ele.geometry();
-                if(r.contains(docPoint)) {
+                if (r.contains(docPoint)) {
                     dist = 0;
                     result = ele;
                     break;
@@ -408,22 +416,21 @@
                     dist = d;
                     result = ele;
                 }
-            }                       
+            }
         }while(traverseNextNode(ele,ele));
 
-//        WebContentWidget* view = qobject_cast<WebContentWidget*>(m_view);
-		// check if we are close enough and calcualte with zoom factor.
+        // check if we are close enough and calculate with zoom factor.
         if (dist< (KThreshHoldValForLink/m_view->zoomFactor())) {
             QRect r = result.geometry();
-            r.translate(2,2); 
-            r.setWidth(2+2); 
-            r.setHeight(2+2); 
+            r.translate(2,2);
+            r.setWidth(2+2);
+            r.setHeight(2+2);
             webElement = result;
-            m_higlightedPos = QPoint(xInRect(r, docPoint.x()), yInRect(r, docPoint.y())) - m_frame->scrollPosition(); 
+            m_higlightedPos = QPoint(xInRect(r, docPoint.x()), yInRect(r, docPoint.y())) - m_frame->scrollPosition();
             m_ishighlighted = true;
             QPoint centerpt = webElement.geometry().center();
             m_offset = (docPoint.x()- centerpt.x())*(docPoint.x()- centerpt.x()) + (docPoint.y()- centerpt.y())*(docPoint.y()- centerpt.y());
-            
+
         }
     }
     return webElement;
@@ -436,40 +443,40 @@
 {
     m_delayedPressMoment.start();
     // stop deceleration and don't send further events to engine if scroll timer is active
-    if(m_scrollTimer && m_scrollTimer->isActive()) {
+    if (m_scrollTimer && m_scrollTimer->isActive()) {
         m_prevPoint.setX(0);
         m_prevPoint.setY(0);
         m_scrollDistance.setX(0);
         m_scrollDistance.setY(0);
-        
+
         m_lastMoveEventTime.setHMS(0,0,0,0); //H, M, S, mS
         m_scrolled = false;
         m_ishighlighted = false;
         m_higlightedPos = m_touchPosition = pos;
         m_frame = m_webPage->frameAt(pos);
         if (!m_frame)
-              m_frame = m_webPage->currentFrame(); 
-          
+            m_frame = m_webPage->currentFrame();
+
         m_dragPoints.clear();
-          
+
         DragPoint dragPoint;
         dragPoint.iPoint = m_touchPosition;
         dragPoint.iTime = QTime::currentTime();
         m_dragPoints.append(dragPoint);
         m_offset = 0;
-        
+
         m_pressEvent = new QMouseEvent(QEvent::MouseButtonPress, m_touchPosition, Qt::LeftButton, Qt::LeftButton, getEventModifier(m_touchPosition));
         m_scrollTimer->stop();
         return;
     }
-    
+
     if (m_doubleClickTimer) {
-        // If there is another click event almost on the same region 
-        // as the previous click before doubleClick timeout 
+        // If there is another click event almost on the same region
+        // as the previous click before doubleClick timeout
         // Consider it as double click.
         if (m_doubleClickTimer->isActive() && m_pressEvent) {
             QPoint diff = m_pressEvent->pos() - pos;
-            if (qAbs(diff.x()) < KTouchThresholdX && qAbs(diff.y()) < KTouchThresholdY) {           
+            if (qAbs(diff.x()) < KTouchThresholdX && qAbs(diff.y()) < KTouchThresholdY) {
                 mouseDoubleClickEvent(pos);
                 return;
             }
@@ -477,95 +484,85 @@
         m_doubleClickTimer->stop();
     } else {
         m_doubleClickTimer = new QTimer(this);
-        connect(m_doubleClickTimer, SIGNAL(timeout()), this, SLOT(doubleClickTimerExpired()));    
+        connect(m_doubleClickTimer, SIGNAL(timeout()), this, SLOT(doubleClickTimerExpired()));
     }
 
     //Clear the previous press and release events.
-    if (m_pressEvent) {
-        delete m_pressEvent;
-        m_pressEvent = NULL;
-    }
-    
-    if (m_releaseEvent) {
-        delete m_releaseEvent;
-        m_releaseEvent = NULL;
-    }
+    cancelPressEvent();
+    cancelReleaseEvent();
 
     m_doubleClickTimer->start(KDoubleClickTimeOut);
     m_pressEvent = new QMouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, getEventModifier(pos));
+    m_longPressPosition = pos;
+    startLongPressTimer();
 }
 
 void GWebTouchNavigation::handleMousePressEvent(QMouseEvent* ev)
 {
+    if (!ev) return;
     m_lastMoveEventTime.setHMS(0,0,0,0); //H, M, S, mS
-    if(!m_longPressTimer){
-        delete m_longPressTimer;
-        m_longPressTimer = 0;
-    }
-    startTimer();
     m_scrolled = false;
     m_ishighlighted = false;
     m_higlightedPos = m_touchPosition = ev->pos();
     m_frame = m_webPage->frameAt(ev->pos());
     if (!m_frame)
-        m_frame = m_webPage->currentFrame(); 
-    
+        m_frame = m_webPage->currentFrame();
+
     m_dragPoints.clear();
-    
+
     DragPoint dragPoint;
     dragPoint.iPoint = m_touchPosition;
     dragPoint.iTime = QTime::currentTime();
     m_dragPoints.append(dragPoint);
 
-	m_offset = 0;
-	
+    m_offset = 0;
+
     highlightableElement(ev);
-    getFocusedElement();		
+    emitFocusedElementChanged();
 
     //send a mouse press
     QMouseEvent iev(ev->type(), m_touchPosition, ev->button(), ev->buttons(), getEventModifier(m_higlightedPos));
     m_webPage->event(&iev);
+    m_textSelected = false;
 }
 
 void GWebTouchNavigation::doubleClickTimerExpired()
-{   
+{
     handleMousePressEvent(m_pressEvent);
 
-    delete m_pressEvent;
-    m_pressEvent = NULL;
-    
+    cancelPressEvent();
+
     if (m_releaseEvent) {
         handleMouseReleaseEvent(m_releaseEvent);
 
-		//clear release event
-		delete m_releaseEvent;
-        m_releaseEvent = NULL;
+        //clear release event
+        cancelReleaseEvent();
     }
-	if (m_doubleClickTimer && m_doubleClickTimer->isActive())
+    if (m_doubleClickTimer && m_doubleClickTimer->isActive())
         m_doubleClickTimer->stop();
 }
 
 bool GWebTouchNavigation::canDehighlight(QMouseEvent* ev)
- {
-    bool checkDehighlight = false;  
+{
+    bool checkDehighlight = false;
     QPoint pt = ev->pos() + m_frame->scrollPosition();
-    
-    if(m_scrolled && m_ishighlighted) {
+
+    if (m_scrolled && m_ishighlighted) {
         checkDehighlight = true;
     }
-    else if(!m_scrolled && m_ishighlighted) {
+    else if (!m_scrolled && m_ishighlighted) {
         QRect rect = m_anchorElement.geometry();
 
-        if(m_anchorElement.geometry().contains(pt)) {
+        if (m_anchorElement.geometry().contains(pt)) {
             checkDehighlight = false;
         }
-        else if(m_offset){
+        else if (m_offset){
             QPoint centerpt = m_anchorElement.geometry().center();
             int newoffset = (pt.x()- centerpt.x())*(pt.x()- centerpt.x()) + (pt.y()- centerpt.y())*(pt.y()- centerpt.y());
-        
-            if(newoffset <= m_offset ) {
-                 m_offset = newoffset;
-                 checkDehighlight = false;
+
+            if (newoffset <= m_offset ) {
+                m_offset = newoffset;
+                checkDehighlight = false;
             }
             else {
                 m_offset =0;
@@ -578,7 +575,7 @@
     }
     return checkDehighlight;
 }
- void  GWebTouchNavigation::dehighlight(QMouseEvent* ev)
+void  GWebTouchNavigation::dehighlight(QMouseEvent* ev)
 {
     m_higlightedPos = QPoint(0,0);
     m_ishighlighted = false;
@@ -599,39 +596,60 @@
 */
 void GWebTouchNavigation::mouseMoveEvent(const QPoint& pos, const QPoint& diff)
 {
-	
+    if (m_longPressTimer && m_longPressTimer->isActive()){
+        QPoint diff2 = m_longPressPosition - pos;
+        if (qAbs(diff2.x()) > KLongPressThreshold || qAbs(diff2.y()) > KLongPressThreshold) {
+            stopLongPressTimer();
+        }
+    }
+
     if (m_pressEvent){
-    	QPoint diff2 = m_pressEvent->pos() - pos;
-      if (qAbs(diff2.x()) < KTouchThresholdX && qAbs(diff2.y()) < KTouchThresholdY)
-        return;    
-    }	
-       
+        QPoint diff2 = m_pressEvent->pos() - pos;
+        if (qAbs(diff2.x()) < KTouchThresholdX && qAbs(diff2.y()) < KTouchThresholdY) {
+            return;
+        }
+    }
+
     if (m_doubleClickTimer && m_doubleClickTimer->isActive()) {
         //send mousePressEvent
         m_doubleClickTimer->stop();
         handleMousePressEvent(m_pressEvent);
-        delete m_pressEvent;
-        m_pressEvent = NULL;
+        cancelPressEvent();
     }
 
-    stopTimer();
     QMouseEvent tmpEv(QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
     handleHighlightChange(&tmpEv);
 
-    scrollFrame(diff);
+    //the viewport hasn't been scrolled
+    if (!m_scrolled) {
+        QWebHitTestResult hitTestResult = m_frame->hitTestContent(m_touchPosition);
+        QWebElement oriElement = hitTestResult.element();
+        QWebElement curElement = m_frame->hitTestContent(pos).element();
+        // the mousepress event and the mousemove event have the same target
+        if (oriElement == curElement) {
+            // the mousemove event's position is in an input field
+            if (hitTestResult.isContentEditable()) {
+                QMouseEvent moveEvt(QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+                m_webPage->event(&moveEvt);
+                m_textSelected = true;
+            }
+        }
+    }
+    if (!m_textSelected)
+        scrollFrame(diff);
 
-		//m_touchPosition = pos;
-		DragPoint dragPoint;
-		dragPoint.iPoint = pos;
-		dragPoint.iTime = QTime::currentTime();
-		m_dragPoints.append(dragPoint);
+    //m_touchPosition = pos;
+    DragPoint dragPoint;
+    dragPoint.iPoint = pos;
+    dragPoint.iTime = QTime::currentTime();
+    m_dragPoints.append(dragPoint);
 
-		QTime now(QTime::currentTime());
-		m_lastMoveEventTime.setHMS(now.hour(),now.minute(), now.second(), now.msec());
+    QTime now(QTime::currentTime());
+    m_lastMoveEventTime.setHMS(now.hour(),now.minute(), now.second(), now.msec());
 
-		while (m_dragPoints.size() > 4)
-				m_dragPoints.removeFirst();
-    
+    while (m_dragPoints.size() > 4)
+        m_dragPoints.removeFirst();
+
 }
 
 /*!
@@ -641,29 +659,36 @@
 */
 void GWebTouchNavigation::mouseReleaseEvent(const QPoint& pos)
 {
-    if(m_isPanning)
+    stopLongPressTimer();
+
+    if (m_isPanning)
         m_isPanning = false;
     if (m_doubleClickTimer && m_doubleClickTimer->isActive()) {
         m_releaseEvent = new QMouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
         return;
     }
+
+    if (m_isContextEvent) {
+        // A context event just occurred, ignore the release event so that links are not activated.
+        m_isContextEvent = false;
+        return;
+    }
     //mouseReleaseEvent is called in two cases. 1. Double click, 2. Mouse Drag
     //m_releaseEvent is not null only in Mouse double click
     //So delete m_releaseEvent only in double click case.
     //Send release event in mouse move case
     if (m_releaseEvent) {
-        delete m_releaseEvent ;
-        m_releaseEvent = NULL;
+        cancelReleaseEvent();
     } else {
         QMouseEvent tmpEv(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
-        handleMouseReleaseEvent(&tmpEv);    
+        handleMouseReleaseEvent(&tmpEv);
     }
 }
 Qt::KeyboardModifier GWebTouchNavigation::getEventModifier(const QPoint& pos)
 {
     QWebFrame *frame = m_webPage->frameAt(pos);
     if (!frame)
-          frame = m_webPage->currentFrame(); 
+          frame = m_webPage->currentFrame();
     QWebHitTestResult htr = frame->hitTestContent(pos);
     if (htr.element().tagName().toLower().compare("select")==0  && htr.element().hasAttribute("multiple"))
         return Qt::ControlModifier;
@@ -674,11 +699,11 @@
 {
     m_frame = m_webPage->frameAt(ev->pos());
     if (!m_frame)
-        m_frame = m_webPage->currentFrame(); 
-    assert(m_frame);
-    
-     stopTimer();
-     if (m_scrolled) {
+        m_frame = m_webPage->currentFrame();
+    Q_ASSERT(m_frame);
+
+    stopLongPressTimer();
+    if (m_scrolled) {
         int msecs = 0;
         if (!m_lastMoveEventTime.isNull()) {
             //Start deceleration only if the delta since last drag event is less than threshold
@@ -687,7 +712,7 @@
             m_lastMoveEventTime.setHMS(0,0,0,0);
         }
         if (msecs < KDecelerationTimer) {
-            if( isFlick()) {
+            if ( isFlick()) {
                 updateFlickScrollDistance();
             }
             else {
@@ -701,12 +726,16 @@
             startScrollTimer();
         }
     } else {
-        QMouseEvent iev = m_ishighlighted ? 
+        // we don't want to automatically display the SIP (Software input panel) by qtwebkit
+        bool sipEnabled = qApp->autoSipEnabled();
+        qApp->setAutoSipEnabled(false);
+        QMouseEvent iev = m_ishighlighted ?
         QMouseEvent(ev->type(), m_higlightedPos, ev->button(), ev->buttons(), getEventModifier(m_higlightedPos)) :
         QMouseEvent(QEvent::MouseButtonRelease, m_touchPosition, ev->button(), ev->buttons(), getEventModifier(m_touchPosition));
         m_webPage->event(&iev);
+        qApp->setAutoSipEnabled(sipEnabled);
 #if defined __SYMBIAN32__
-// FIXME Remove this, it will be fixed Qt 4.6.3 ? 
+// FIXME Remove this, it will be fixed Qt 4.6.3 ?
         if (ev->button() == Qt::LeftButton) {
             QWebHitTestResult htr = m_frame->hitTestContent(ev->pos());
             if (htr.isContentEditable()) {
@@ -723,10 +752,10 @@
 
 void GWebTouchNavigation::mouseDoubleClickEvent(const QPoint& pos)
 {
-    
-    if(m_doubleClickTimer && !m_doubleClickTimer->isActive())
+
+    if (m_doubleClickTimer && !m_doubleClickTimer->isActive())
         return;
-    else if(m_doubleClickTimer)
+    else if (m_doubleClickTimer)
         m_doubleClickTimer->stop();
 
     //If the page is already scrolling(because of a previous doubletap)
@@ -740,9 +769,12 @@
 
 void GWebTouchNavigation::handleDoubleClickEvent(QMouseEvent* ev)
 {
+    if (!m_doubleClickEnabled)
+        return;
+
     QPoint imageFocusPoint;
     QWebHitTestResult hitTest = getHitTestResult(ev);
-    
+
     QWebElement block = hitTest.element();
 
     if (block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == ""))
@@ -750,104 +782,103 @@
 
     QWebFrame* frame = m_webPage->frameAt(ev->pos());
     m_frame = (frame) ? frame : m_webPage->mainFrame();
-    
+
     QRect enclosingRect = block.geometry();
-          
-    QPoint blockCanvasPt = QPoint(enclosingRect.topLeft()) - m_frame->scrollPosition();            
-    //WebContentWidget* view = qobject_cast<WebContentWidget*>(m_view);
-    m_view->setBlockElement(QWebElement());
-	if(m_focusedBlockPt == blockCanvasPt) {
-		m_focusedBlockPt.setX(-1);
-		m_focusedBlockPt.setY(-1);
-		qreal m_Ratiox = (qreal) blockCanvasPt.x() / block.geometry().width();
-		qreal m_Ratioy = (qreal) blockCanvasPt.y() / block.geometry().height();
-        m_view->setZoomFactor(m_view->initialScale());
-		QPoint m_InfocusBlockPt = QPoint(block.geometry().topLeft()) - m_webPage->mainFrame()->scrollPosition(); 
-		m_webPage->currentFrame()->scroll(m_InfocusBlockPt.x() - (m_Ratiox * block.geometry().width()),
-																					m_InfocusBlockPt.y() - (m_Ratioy * block.geometry().height()));
+
+    QPoint blockCanvasPt = QPoint(enclosingRect.topLeft()) - m_frame->scrollPosition();
+    setViewBlockElement(QWebElement());
+    if (m_focusedBlockPt == blockCanvasPt) {
+        m_focusedBlockPt.setX(-1);
+        m_focusedBlockPt.setY(-1);
+        qreal m_Ratiox = (qreal) blockCanvasPt.x() / block.geometry().width();
+        qreal m_Ratioy = (qreal) blockCanvasPt.y() / block.geometry().height();
+        setViewZoomFactor(viewInitialScale());
+        QPoint m_InfocusBlockPt = QPoint(block.geometry().topLeft()) - m_webPage->mainFrame()->scrollPosition();
+        m_webPage->currentFrame()->scroll(m_InfocusBlockPt.x() - (m_Ratiox * block.geometry().width()),
+                                                                                    m_InfocusBlockPt.y() - (m_Ratioy * block.geometry().height()));
         m_finalzoomfactor = 0;
-	}else {     
-        if(block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == "")) {
+    }else {
+        if (block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == "")) {
             m_finalzoomfactor   = (qreal) (m_webPage->viewportSize().width() - 10) * m_view->zoomFactor();
-        	m_finalzoomfactor = (qreal) m_finalzoomfactor / (enclosingRect.width());
-        	QString str;
-        	str.setNum(m_finalzoomfactor,'f',2);
-			m_finalzoomfactor = str.toDouble();
-		}else {																																     			
-			qreal factor;
-            factor = 1/m_view->initialScale();
+            m_finalzoomfactor = (qreal) m_finalzoomfactor / (enclosingRect.width());
+            QString str;
+            str.setNum(m_finalzoomfactor,'f',2);
+            m_finalzoomfactor = str.toDouble();
+        }else {
+            qreal factor;
+            factor = 1/viewInitialScale();
             int boundW = block.geometry().width() * factor/m_view->zoomFactor();
             int boundH = block.geometry().height() * factor/m_view->zoomFactor();
-			qreal factorw = 0.0,factorh = 0.0 ;
-	     		
-			if( boundW > m_webPage->viewportSize().width())
-				factorw = (qreal)(m_webPage->viewportSize().width()-5)/ block.geometry().width();
-			
-			if(boundH > m_webPage->viewportSize().height())
-				factorh = (qreal)(m_webPage->viewportSize().height()-5)/ block.geometry().height();			
+            qreal factorw = 0.0,factorh = 0.0 ;
+
+            if ( boundW > m_webPage->viewportSize().width())
+                factorw = (qreal)(m_webPage->viewportSize().width()-5)/ block.geometry().width();
+
+            if (boundH > m_webPage->viewportSize().height())
+                factorh = (qreal)(m_webPage->viewportSize().height()-5)/ block.geometry().height();
 
-			if( (factorw == 0.0) && (factorh == 0.0))
-				;
-			else if(factorw == 0.0)
+            if ( (factorw == 0.0) && (factorh == 0.0))
+                ;
+            else if (factorw == 0.0)
                 factor = factorh * m_view->zoomFactor();
-			else if(factorh == 0.0)
+            else if (factorh == 0.0)
                 factor = factorw * m_view->zoomFactor();
-			else {
+            else {
                 factor = ((factorh < factorw) ? factorh : factorw) * m_view->zoomFactor();
-			}	
-								
-			QString str;
-			str.setNum(factor,'f',2);
-			factor = str.toDouble();	
-							
-			if(m_finalzoomfactor != factor) 				    				  		     	
-				m_finalzoomfactor = factor;
-		}
+            }
+
+            QString str;
+            str.setNum(factor,'f',2);
+            factor = str.toDouble();
 
-    
+            if (m_finalzoomfactor != factor)
+                m_finalzoomfactor = factor;
+        }
+
+
         if (m_finalzoomfactor != m_view->zoomFactor()) {
-            m_view->setZoomFactor(m_finalzoomfactor);
-            m_focusedBlockPt = QPoint(block.geometry().topLeft()) - m_frame->scrollPosition(); 
-    
-			if(block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == "")) 
-            	scrollCurrentFrame(m_focusedBlockPt.x() - KFocussPoint.x() , m_focusedBlockPt.y() - KFocussPoint.y());
-        	else {
-            	if((m_webPage->viewportSize().width() - block.geometry().width()) > 0)
-                	imageFocusPoint.setX((m_webPage->viewportSize().width() - block.geometry().width())/2);
-            	else
-                	imageFocusPoint.setX(0);
-            
-            	if((m_webPage->viewportSize().height() - block.geometry().height()) > 0)
-                	imageFocusPoint.setY((m_webPage->viewportSize().height() - block.geometry().height())/2);
-            	else
-                	imageFocusPoint.setY(0);
-            
-            	scrollCurrentFrame(m_focusedBlockPt.x() - imageFocusPoint.x() , m_focusedBlockPt.y() - imageFocusPoint.y());
-        	}
-    
-			m_focusedBlockPt = QPoint(block.geometry().topLeft()) - m_frame->scrollPosition();      
-        } else { 
-			//Get doc size and current bottom right view corner point in document
+            setViewZoomFactor(m_finalzoomfactor);
+            m_focusedBlockPt = QPoint(block.geometry().topLeft()) - m_frame->scrollPosition();
+
+            if (block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == ""))
+                scrollCurrentFrame(m_focusedBlockPt.x() - KFocussPoint.x() , m_focusedBlockPt.y() - KFocussPoint.y());
+            else {
+                if ((m_webPage->viewportSize().width() - block.geometry().width()) > 0)
+                    imageFocusPoint.setX((m_webPage->viewportSize().width() - block.geometry().width())/2);
+                else
+                    imageFocusPoint.setX(0);
+
+                if ((m_webPage->viewportSize().height() - block.geometry().height()) > 0)
+                    imageFocusPoint.setY((m_webPage->viewportSize().height() - block.geometry().height())/2);
+                else
+                    imageFocusPoint.setY(0);
+
+                scrollCurrentFrame(m_focusedBlockPt.x() - imageFocusPoint.x() , m_focusedBlockPt.y() - imageFocusPoint.y());
+            }
+
+            m_focusedBlockPt = QPoint(block.geometry().topLeft()) - m_frame->scrollPosition();
+        } else {
+            //Get doc size and current bottom right view corner point in document
             QSize viewSize = m_webPage->viewportSize();
             QSize contentSize = m_frame->contentsSize();
             QPoint documentViewPoint = QPoint(viewSize.width(),viewSize.height()) + m_frame->scrollPosition();
-    		QPoint docFocusPoint;
+            QPoint docFocusPoint;
 
-    		if(block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == "")) 
-        		docFocusPoint = KFocussPoint + m_frame->scrollPosition();
-    		else {
-        		if((m_webPage->viewportSize().width() - block.geometry().width()) > 0)                                  
-           			 imageFocusPoint.setX((m_webPage->viewportSize().width() - block.geometry().width())/2);
-       			else
-            		imageFocusPoint.setX(0);
-    
-        		if((m_webPage->viewportSize().height() - block.geometry().height()) > 0)    
-            		imageFocusPoint.setY((m_webPage->viewportSize().height()- block.geometry().height())/2);
-        		else
-            		imageFocusPoint.setY(0);
-    
-        		docFocusPoint = imageFocusPoint + m_frame->scrollPosition();
-   			}
+            if (block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == ""))
+                docFocusPoint = KFocussPoint + m_frame->scrollPosition();
+            else {
+                if ((m_webPage->viewportSize().width() - block.geometry().width()) > 0)
+                     imageFocusPoint.setX((m_webPage->viewportSize().width() - block.geometry().width())/2);
+                else
+                    imageFocusPoint.setX(0);
+
+                if ((m_webPage->viewportSize().height() - block.geometry().height()) > 0)
+                    imageFocusPoint.setY((m_webPage->viewportSize().height()- block.geometry().height())/2);
+                else
+                    imageFocusPoint.setY(0);
+
+                docFocusPoint = imageFocusPoint + m_frame->scrollPosition();
+            }
 
             m_focusedBlockPt = QPoint(block.geometry().x(), block.geometry().y());
             m_scrollDistance.setX(m_focusedBlockPt.x() - docFocusPoint.x());
@@ -855,44 +886,50 @@
 
             QPoint scrollableDistance(0, 0);
             QPoint viewStartPoint = QPoint(0,0) + m_frame->scrollPosition();
-    
-   			if(m_scrollDistance.x() < 0)
-             	scrollableDistance.setX(viewStartPoint.x());
-   			 else
-             	scrollableDistance.setX(contentSize.width() - documentViewPoint.x());
-            
+
+            if (m_scrollDistance.x() < 0)
+                scrollableDistance.setX(viewStartPoint.x());
+             else
+                scrollableDistance.setX(contentSize.width() - documentViewPoint.x());
+
 
-   			if(m_scrollDistance.y() < 0)
-        		scrollableDistance.setY(viewStartPoint.y());
-    		 else
-				scrollableDistance.setY(contentSize.height() - documentViewPoint.y());
+            if (m_scrollDistance.y() < 0)
+                scrollableDistance.setY(viewStartPoint.y());
+             else
+                scrollableDistance.setY(contentSize.height() - documentViewPoint.y());
 
-			if(abs(m_scrollDistance.x()) > abs(scrollableDistance.x())){
+            if (abs(m_scrollDistance.x()) > abs(scrollableDistance.x())){
                 //m_scrollDistance.x() >= 0 means scroll from right to left
-        		if(m_scrollDistance.x() >= 0)
-                	m_focusedBlockPt.setX(m_focusedBlockPt.x() - abs(scrollableDistance.x()));
+                if (m_scrollDistance.x() >= 0)
+                    m_focusedBlockPt.setX(m_focusedBlockPt.x() - abs(scrollableDistance.x()));
                 //m_scrollDistance.x() < 0 means scroll from left to right
-        		else
-                	m_focusedBlockPt.setX(m_focusedBlockPt.x() + abs(scrollableDistance.x()));
+                else
+                    m_focusedBlockPt.setX(m_focusedBlockPt.x() + abs(scrollableDistance.x()));
              } else
                 m_focusedBlockPt.setX(docFocusPoint.x());
 
-			if (abs(m_scrollDistance.y()) > abs(scrollableDistance.y())){
-        		if(m_scrollDistance.y() >= 0)
-                	m_focusedBlockPt.setY(m_focusedBlockPt.y() - abs(scrollableDistance.y()));
-        		else
-                	m_focusedBlockPt.setY(m_focusedBlockPt.y() + abs(scrollableDistance.y()));
+            if (abs(m_scrollDistance.y()) > abs(scrollableDistance.y())){
+                if (m_scrollDistance.y() >= 0)
+                    m_focusedBlockPt.setY(m_focusedBlockPt.y() - abs(scrollableDistance.y()));
+                else
+                    m_focusedBlockPt.setY(m_focusedBlockPt.y() + abs(scrollableDistance.y()));
             }
             else
-            	m_focusedBlockPt.setY(docFocusPoint.y());
-            
+                m_focusedBlockPt.setY(docFocusPoint.y());
+
             m_focusedBlockPt = m_focusedBlockPt - m_frame->scrollPosition();
             startScrollTimer();
         }
-    m_view->setBlockElement(block);
-	}
+    setViewBlockElement(block);
+    }
 }
 
+void GWebTouchNavigation::contextMenuEvent() {
+    m_isContextEvent = true;
+    cancelPressEvent();
+}
+
+
 /*!
     Returns the next scrollable frame in the frame tree give the x,y position
 */
@@ -928,7 +965,7 @@
 */
 void GWebTouchNavigation::startScrollTimer()
 {
-    if(!m_scrollTimer) {
+    if (!m_scrollTimer) {
         m_scrollTimer = new QTimer(this);
         connect(m_scrollTimer,SIGNAL(timeout()),this,SLOT(scrollToEdge()));
     }
@@ -941,97 +978,98 @@
 */
 void GWebTouchNavigation::updateFlickScrollDistance()
 {
-	m_initialSpeed = speed();
-	m_initialSpeed.setX(qAbs(m_initialSpeed.x()));
-	m_initialSpeed.setY(qAbs(m_initialSpeed.y()));
-	m_flickDirection = findDirectionWithAngle(m_dragPoints.first().iPoint - m_dragPoints.last().iPoint);
-	m_scrollDistance.setX((m_initialSpeed.x() * m_initialSpeed.x())/( 2 * KDeccelaration));
-	m_scrollDistance.setY((m_initialSpeed.y() * m_initialSpeed.y())/( 2 * KDeccelaration));
-	  
-    m_scrollDistance.setX(m_view->zoomFactor() * m_scrollDistance.x() / m_view->initialScale());
-    m_scrollDistance.setY(m_view->zoomFactor() * m_scrollDistance.y() / m_view->initialScale());
+    m_initialSpeed = speed();
+    m_initialSpeed.setX(qAbs(m_initialSpeed.x()));
+    m_initialSpeed.setY(qAbs(m_initialSpeed.y()));
+    m_flickDirection = findDirectionWithAngle(m_dragPoints.first().iPoint - m_dragPoints.last().iPoint);
+    m_scrollDistance.setX((m_initialSpeed.x() * m_initialSpeed.x())/( 2 * KDeccelaration));
+    m_scrollDistance.setY((m_initialSpeed.y() * m_initialSpeed.y())/( 2 * KDeccelaration));
+
+    m_scrollDistance.setX(m_view->zoomFactor() * m_scrollDistance.x() / viewInitialScale());
+    m_scrollDistance.setY(m_view->zoomFactor() * m_scrollDistance.y() / viewInitialScale());
 
-	QSize viewSize = m_webPage->viewportSize();
-  	QSize contentSize = m_frame->contentsSize();
-  	QPoint documentViewPoint = QPoint(viewSize.width(),viewSize.height()) + m_frame->scrollPosition();
-  	QPoint documentTouchPoint = m_touchPosition + m_frame->scrollPosition();;
-   
-	switch(m_flickDirection)
+    QSize viewSize = m_webPage->viewportSize();
+    QSize contentSize = m_frame->contentsSize();
+    QPoint documentViewPoint = QPoint(viewSize.width(),viewSize.height()) + m_frame->scrollPosition();
+    QPoint documentTouchPoint = m_touchPosition + m_frame->scrollPosition();;
+
+    switch (m_flickDirection)
     {
-        case DOWN : 
+        case DOWN :
                     m_scrollDistance.setX(0);
-					m_scrollDistance.setY(-(m_scrollDistance.y()));
-										
-					if(m_scrollDistance.y() < -(documentTouchPoint.y() - m_touchPosition.y()))
-						m_scrollDistance.setY(-(documentTouchPoint.y() - m_touchPosition.y()));
+                    m_scrollDistance.setY(-(m_scrollDistance.y()));
+
+                    if (m_scrollDistance.y() < -(documentTouchPoint.y() - m_touchPosition.y()))
+                        m_scrollDistance.setY(-(documentTouchPoint.y() - m_touchPosition.y()));
                     break;
         case UP :
                     m_scrollDistance.setX(0);
-                    if(m_scrollDistance.y() > (contentSize.height() - documentViewPoint.y()))
-                    	m_scrollDistance.setY(contentSize.height() - documentViewPoint.y());
+                    if (m_scrollDistance.y() > (contentSize.height() - documentViewPoint.y()))
+                        m_scrollDistance.setY(contentSize.height() - documentViewPoint.y());
                     break;
         case RIGHT:
                     m_scrollDistance.setX(-(m_scrollDistance.x()));
-                    if(m_scrollDistance.x() < -(documentTouchPoint.x() - m_touchPosition.x()))
-						m_scrollDistance.setX(-(documentTouchPoint.x() - m_touchPosition.x()));
+                    if (m_scrollDistance.x() < -(documentTouchPoint.x() - m_touchPosition.x()))
+                        m_scrollDistance.setX(-(documentTouchPoint.x() - m_touchPosition.x()));
                     m_scrollDistance.setY(0);
                     break;
-        case LEFT:              
-					m_scrollDistance.setY(0);
-					if(m_scrollDistance.x() > (contentSize.width() - documentViewPoint.x()))
-						m_scrollDistance.setX(contentSize.width() - documentViewPoint.x());
-					break;
+        case LEFT:
+                    m_scrollDistance.setY(0);
+                    if (m_scrollDistance.x() > (contentSize.width() - documentViewPoint.x()))
+                        m_scrollDistance.setX(contentSize.width() - documentViewPoint.x());
+                    break;
         case BOTTOMRIGHT:
                     m_scrollDistance.setX(-(m_scrollDistance.x()));
-					m_scrollDistance.setY(-(m_scrollDistance.y())); 
-					if(m_scrollDistance.x() <  -(documentTouchPoint.x()-m_touchPosition.x()))
-            			m_scrollDistance.setX(-(documentTouchPoint.x()-m_touchPosition.x()));
-                    if(m_scrollDistance.y() < -((documentTouchPoint.y()-m_touchPosition.y())/2))
-                    	m_scrollDistance.setY(-((documentTouchPoint.y()-m_touchPosition.y())/2));
-					break;
-        case BOTTOMLEFT: 
-					m_scrollDistance.setY(-(m_scrollDistance.y()));  	
-					if(m_scrollDistance.x() > contentSize.width()-documentViewPoint.x())
-                   		m_scrollDistance.setX(contentSize.width()-documentViewPoint.x());
-                   	if(m_scrollDistance.y() < (-((documentTouchPoint.y()-m_touchPosition.y())/2)))
-                    	m_scrollDistance.setY(-((documentTouchPoint.y()-m_touchPosition.y())/2));
+                    m_scrollDistance.setY(-(m_scrollDistance.y()));
+                    if (m_scrollDistance.x() <  -(documentTouchPoint.x()-m_touchPosition.x()))
+                        m_scrollDistance.setX(-(documentTouchPoint.x()-m_touchPosition.x()));
+                    if (m_scrollDistance.y() < -((documentTouchPoint.y()-m_touchPosition.y())/2))
+                        m_scrollDistance.setY(-((documentTouchPoint.y()-m_touchPosition.y())/2));
+                    break;
+        case BOTTOMLEFT:
+                    m_scrollDistance.setY(-(m_scrollDistance.y()));
+                    if (m_scrollDistance.x() > contentSize.width()-documentViewPoint.x())
+                        m_scrollDistance.setX(contentSize.width()-documentViewPoint.x());
+                    if (m_scrollDistance.y() < (-((documentTouchPoint.y()-m_touchPosition.y())/2)))
+                        m_scrollDistance.setY(-((documentTouchPoint.y()-m_touchPosition.y())/2));
                     break;
         case TOPLEFT:
-                    if(m_scrollDistance.x() > (contentSize.width()-documentViewPoint.x()))
-                   		m_scrollDistance.setX(contentSize.width()-documentViewPoint.x());
-                   	if(m_scrollDistance.y() > ((contentSize.height()-documentViewPoint.y())/2))
-                    	m_scrollDistance.setY((contentSize.height()-documentViewPoint.y())/2);
-                    break;      
+                    if (m_scrollDistance.x() > (contentSize.width()-documentViewPoint.x()))
+                        m_scrollDistance.setX(contentSize.width()-documentViewPoint.x());
+                    if (m_scrollDistance.y() > ((contentSize.height()-documentViewPoint.y())/2))
+                        m_scrollDistance.setY((contentSize.height()-documentViewPoint.y())/2);
+                    break;
         case TOPRIGHT:
                     m_scrollDistance.setX(-(m_scrollDistance.x()));
-                    if(m_scrollDistance.x() < (-(documentTouchPoint.x()-m_touchPosition.x())))
-                    	m_scrollDistance.setX(-(documentTouchPoint.x()-m_touchPosition.x()));
-                    if(m_scrollDistance.y() > ((contentSize.height()-documentViewPoint.y())/2))
-						m_scrollDistance.setY((contentSize.height()-documentViewPoint.y())/2);
+                    if (m_scrollDistance.x() < (-(documentTouchPoint.x()-m_touchPosition.x())))
+                        m_scrollDistance.setX(-(documentTouchPoint.x()-m_touchPosition.x()));
+                    if (m_scrollDistance.y() > ((contentSize.height()-documentViewPoint.y())/2))
+                        m_scrollDistance.setY((contentSize.height()-documentViewPoint.y())/2);
                     break;
+        default: break;
     }
 }
 
 /*
 Distinguishes b/w swipe and flick
 */
-bool GWebTouchNavigation::isFlick() 
+bool GWebTouchNavigation::isFlick()
 {
     bool flick = false;
     QPoint moveSpeed = speed();
     int xSpeed = moveSpeed.x();
     int ySpeed = moveSpeed.y();
-     
-    flick = (qAbs(xSpeed) > KFlickSpeed || 
+
+    flick = (qAbs(xSpeed) > KFlickSpeed ||
              qAbs(ySpeed) > KFlickSpeed);
- 
+
     return flick;
 }
 
 /*
 Calculates the speed of te scroll along x-axis and y-axis
 */
-QPoint GWebTouchNavigation::speed() 
+QPoint GWebTouchNavigation::speed()
 {
     // Speed is only evaluated at the end of the swipe
     QPoint dragSpeed(0,0);
@@ -1065,7 +1103,7 @@
 */
 qreal GWebTouchNavigation::dragTime() const
 {
-    if(m_dragPoints.isEmpty())
+    if (m_dragPoints.isEmpty())
         return 0.0;
     else
         return  m_dragPoints[0].iTime.msecsTo(m_dragPoints[m_dragPoints.size()-1].iTime);
@@ -1074,37 +1112,38 @@
 /*!
 Find the flick direction with respect to angle of flick
 */
-Direction GWebTouchNavigation::findDirectionWithAngle(const QPoint& diff)
+GWebTouchNavigation::Direction GWebTouchNavigation::findDirectionWithAngle(const QPoint& diff)
 {
-    Direction direction;
+    Direction direction = NONE;
     int xDelta = -diff.x();
     int yDelta = -diff.y();
 
     qreal angle = findAngle(xDelta, yDelta);
-    if(isNear(angle, 60.0, 120.0)) {
+    if (isNear(angle, 60.0, 120.0)) {
          direction = DOWN;
      }
-    else if(isNear(angle, 150.0, 210.0)) {
+    else if (isNear(angle, 150.0, 210.0)) {
         direction = LEFT;
     }
-    else if(isNear(angle, 240.0, 300.0)) {
+    else if (isNear(angle, 240.0, 300.0)) {
         direction = UP;
     }
-    else if(360.0 - KAngleTolerance <= angle || angle <= KAngleTolerance) {
+    else if (360.0 - KAngleTolerance <= angle || angle <= KAngleTolerance) {
         direction = RIGHT;
     }
-    else if(isNear(angle, 30.0, 60.0)) {
+    else if (isNear(angle, 30.0, 60.0)) {
         direction = BOTTOMRIGHT;
     }
-    else if(isNear(angle, 120.0, 150.0)) {
+    else if (isNear(angle, 120.0, 150.0)) {
         direction = BOTTOMLEFT;
     }
-    else if(isNear(angle, 210.0, 240.0)) {
+    else if (isNear(angle, 210.0, 240.0)) {
         direction = TOPLEFT;
     }
-    else if(isNear(angle, 300.0, 330.0)) {
+    else if (isNear(angle, 300.0, 330.0)) {
         direction = TOPRIGHT;
     }
+    Q_ASSERT(direction != NONE);
 
     return direction;
 }
@@ -1125,10 +1164,10 @@
     qreal angle = 0;
     qreal hypotenuse = qSqrt(xDelta*xDelta + yDelta*yDelta);
 
-    if(hypotenuse != 0) {
+    if (hypotenuse != 0) {
         angle = qAcos(xDelta / hypotenuse);
 
-        if(yDelta < 0) { 
+        if (yDelta < 0) {
             angle = (2 * PI) - angle;
         }
     }
@@ -1136,13 +1175,13 @@
     return (angle * 180) / PI;
 }
 
-int GWebTouchNavigation::roundOff(qreal num) 
+int GWebTouchNavigation::roundOff(qreal num)
 {
-	return (num + 0.5);
+    return (num + 0.5);
 }
 
 /*
-Finds out the enclosing block 
+Finds out the enclosing block
 */
 QRect GWebTouchNavigation::findEnclosingBlock(QMouseEvent* ev)
 {
@@ -1164,7 +1203,7 @@
 }
 
 /*
-Finds out the scroll distance associated with a swipe 
+Finds out the scroll distance associated with a swipe
 */
 void GWebTouchNavigation::calculateActualScrollDistance()
 {
@@ -1180,27 +1219,27 @@
 
 /*
 In the case of slow swipe, if the destination location lies within the threshold area, then
-we need to align the block to te left edge of the mobile screen. This method finds out the 
+we need to align the block to te left edge of the mobile screen. This method finds out the
 new scroll distance
 */
 void GWebTouchNavigation::setNewScrollDistance(QPoint blockCanvasPoint, int thresholdCheckVal)
 {
     m_scrollDistance.setX(m_actualScrollDistance.x());
     m_scrollDistance.setY(m_actualScrollDistance.y());
-    if(blockCanvasPoint.x() > 0) {
+    if (blockCanvasPoint.x() > 0) {
         //Checks whether the block falls within the threshold after right to left swipe
-        if( (thresholdCheckVal <  KThresholdForRightToLeftMotion) && (thresholdCheckVal > 0)) {
+        if ( (thresholdCheckVal <  KThresholdForRightToLeftMotion) && (thresholdCheckVal > 0)) {
             //if the block is within the threshold range already and the user tries
             //to swipe from left to right , then let it move to right. Dont try to
             //snap to the left edge .
-            if(m_actualScrollDistance.x() > 0) {
+            if (m_actualScrollDistance.x() > 0) {
                 m_scrollDistance.setX(blockCanvasPoint.x() - XAlignVal);
             }
         }
     }
     else {
         //Checks whether the block falls within the threshold after left to right swipe
-        if( (thresholdCheckVal >  KThresholdForLeftToRightMotion) && (thresholdCheckVal < 0)) {
+        if ( (thresholdCheckVal >  KThresholdForLeftToRightMotion) && (thresholdCheckVal < 0)) {
             //if the block is within the threshold range already and the user tries
             //to swipe from right to left , then let it move to left. Dont try to
             //snap to the left edge .
@@ -1208,7 +1247,7 @@
                 m_scrollDistance.setX(blockCanvasPoint.x() - XAlignVal);
             }
         }
-        
+
     }
 }
 
@@ -1223,7 +1262,7 @@
 
     m_scrollDistance.setX(m_scrollDistance.x() * KDecelerationFactor);
     m_scrollDistance.setY(m_scrollDistance.y() * KDecelerationFactor);
- 
+
     //round off the values
     m_scrollDistance.setX(roundOff(m_scrollDistance.x()));
     m_scrollDistance.setY(roundOff(m_scrollDistance.y()));
@@ -1231,7 +1270,7 @@
     int diffX = m_prevPoint.x() - m_scrollDistance.x();
     int diffY = m_prevPoint.y() - m_scrollDistance.y();
 
-    if (((m_scrollDistance.x() == 0) && (m_scrollDistance.y() == 0)) 
+    if (((m_scrollDistance.x() == 0) && (m_scrollDistance.y() == 0))
          || ((diffX == 0) && (diffY == 0))) {
         scrollCurrentFrame(m_prevPoint.x(), m_prevPoint.y());
         m_scrollTimer->stop();
@@ -1239,83 +1278,129 @@
     }
     scrollCurrentFrame(diffX, diffY);
 }
-void GWebTouchNavigation::timerControl()
+
+void GWebTouchNavigation::onLongPressTimer()
 {
-	stopTimer();// stop timer as soon as timeout 
-    emit longPressEvent();
-}
-void GWebTouchNavigation::startTimer()
-{
-    m_longPressTimer = new QTimer(this);
-    connect(m_longPressTimer,SIGNAL(timeout()),this,SLOT(timerControl()));
-    m_longPressTimer->start(LONG_PRESS_DURATION);
+    stopLongPressTimer();// stop timer as soon as timeout
+    emit longPressEvent(m_touchPosition);
 }
-void GWebTouchNavigation::stopTimer()
+
+void GWebTouchNavigation::startLongPressTimer()
 {
-    if(m_longPressTimer){
-            m_longPressTimer->stop();
-            delete m_longPressTimer;
-            m_longPressTimer = 0;
-        }
+    if(!m_longPressTimer) {
+        m_longPressTimer = new QTimer(this);
+        connect(m_longPressTimer, SIGNAL(timeout()), this, SLOT(onLongPressTimer()));
+    }
+    else {
+        m_longPressTimer->stop();
+    }
+    m_longPressTimer->start(KLongPressDuration);
 }
-void GWebTouchNavigation::getFocusedElement()
+
+void GWebTouchNavigation::stopLongPressTimer()
 {
-	QWebHitTestResult htRes = m_frame->hitTestContent(m_touchPosition);
-	wrtBrowserDefs::BrowserElementType elType = wrtBrowserUtils::getTypeFromElement(htRes);
-	emit focusElementChanged(elType);
+    if (m_longPressTimer){
+        m_longPressTimer->stop();
+        delete m_longPressTimer;
+        m_longPressTimer = 0;
+    }
+}
+
+void GWebTouchNavigation::emitFocusedElementChanged()
+{
+    QWebHitTestResult htRes = m_frame->hitTestContent(m_touchPosition);
+    wrtBrowserDefs::BrowserElementType elType = wrtBrowserUtils::getTypeFromElement(htRes);
+    emit focusElementChanged(elType);
 }
 
 void GWebTouchNavigation::scrollCurrentFrame (int dx, int dy)
 {
-   QPoint scrollPosition = m_frame->scrollPosition();
-   if (m_frame == m_webPage->mainFrame() && 
-        //scrollPosition.y() < m_chrome->getSnippetRect("UrlSearchChromeId").height()) {
-        scrollPosition.y() <=0  &&
-        !m_isLoading &&
-        !m_view->view()->currentPageIsSuperPage()) {
-    	  qreal slide = m_chrome->slideView(-dy);
-    	  dy+=slide;
-    }
-    
-    m_frame->scroll(dx, dy);
+    QPoint scrollPosition = m_frame->scrollPosition();
+    /* slide the url bar up if content is scrolled to top */
+    if (m_frame == m_webPage->mainFrame() &&
+         scrollPosition.y() <=0  && !m_isLoading && m_wantSlideViewCalls) {
+         qreal slide = slideView(-dy);
+         dy+=slide;
+     }
+
+     /* shrink the viewport size at bottom if content is scrolled to bottom,
+        so that use can click the link under the toolbar */
+    /*
+     if (m_frame == m_webPage->mainFrame()) {
+        if (scrollPosition.y() + m_webPage->viewportSize().height() >= m_frame->contentsSize().height()) {
+            qreal slide = shrinkView(-dy);
+            dy+=slide;
+        }
+     }
+     */
+     m_frame->scroll(dx, dy);
+
 }
 
 void GWebTouchNavigation::setCurrentFrameScrollPosition (QPoint& pos)
 {
     QPoint scrollPosition = m_frame->scrollPosition();
     QPoint finalPos = pos;
-    
-    
-    /* emit pageScrollPositionZero singal if it's mainFrame scrolling or scroll to top*/
-    if (m_frame == m_webPage->mainFrame() && 
-        //scrollPosition.y() < m_chrome->getSnippetRect("UrlSearchChromeId").height()) {
+    int dy = scrollPosition.y() - pos.y();
+
+    if (m_frame == m_webPage->mainFrame() &&
         scrollPosition.y() <=0 &&
         !m_isLoading &&
-        !m_view->view()->currentPageIsSuperPage()) {
-        	
-    	  int dy = scrollPosition.y() - pos.y();
-    	  qreal slide = m_chrome->slideView(-dy);
-    	  dy+=slide;
-    	  finalPos.setY(scrollPosition.y() - dy);
+        m_wantSlideViewCalls) {
+
+          qreal slide = slideView(-dy);
+          dy+=slide;
+          finalPos.setY(scrollPosition.y() - dy);
     }
-    	
+    /*
+    if (m_frame == m_webPage->mainFrame()) {
+       if (scrollPosition.y() + m_webPage->viewportSize().height() == m_frame->contentsSize().height()) {
+           qreal slide = shrinkView(-dy);
+           dy-=slide;
+       }
+       finalPos.setY(scrollPosition.y() - dy);
+    }
+    */
     m_frame->setScrollPosition(finalPos);
 }
 
 void GWebTouchNavigation::onLoadStarted()
-{ 
-  	m_isLoading = true; 
+{
+    m_isLoading = true;
 }
+
 void GWebTouchNavigation::onLoadFinished(bool ok)
 {
-	  m_isLoading = false;
+    Q_UNUSED(ok)
+    m_isLoading = false;
 }
 void GWebTouchNavigation::setPage( QWebPage * page)
-{ 
-	  disconnect(m_webPage, SIGNAL(loadStarted()), this, SLOT(onLoadStarted()));
-    disconnect(m_webPage, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
-	  m_webPage = page ;
-	  connect(m_webPage, SIGNAL(loadStarted()), this, SLOT(onLoadStarted()));
-    connect(m_webPage, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
+{
+    if (m_webPage) {
+        disconnect(m_webPage, SIGNAL(loadStarted()), this, SLOT(onLoadStarted()));
+        disconnect(m_webPage, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
+        //disconnect(m_webPage->mainFrame(), SIGNAL(contentsSizeChanged(const QSize &)), this, SLOT(onContentsSizeChanged(const QSize &)));
+    }
+    m_webPage = page;
+    if (m_webPage) {
+        connect(m_webPage, SIGNAL(loadStarted()), this, SLOT(onLoadStarted()));
+        connect(m_webPage, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
+        //connect(m_webPage->mainFrame(), SIGNAL(contentsSizeChanged(const QSize &)), this, SLOT(onContentsSizeChanged(const QSize &)));
+    }
+}
+
+void GWebTouchNavigation::onContentsSizeChanged(const QSize & size)
+{
+    Q_UNUSED(size)
+    /* get the new content height, and resize the viewport size */
+    if (m_webPage->mainFrame()->contentsSize().height() != m_contentHeight) {
+        m_contentHeight = m_webPage->mainFrame()->contentsSize().height();
+        shrinkView(100);
+    }
+}
+
+void GWebTouchNavigation::enableDClick(bool aValue)
+{
+    m_doubleClickEnabled = aValue;
 }
 }