browsercore/core/webtouchnavigation.cpp
branchGCC_SURGE
changeset 8 2e16851ffecd
parent 2 bf4420e9fa4d
parent 6 1c3b8676e58c
equal deleted inserted replaced
2:bf4420e9fa4d 8:2e16851ffecd
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "webtouchnavigation.h"
       
    20 #include "qwebpage.h"
       
    21 #include "qwebframe.h"
       
    22 #include "qapplication.h"
       
    23 #include "qwebelement.h"
       
    24 #include <QGraphicsSceneMouseEvent>
       
    25 #include <QTimer>
       
    26 #include <qmath.h>
       
    27 
       
    28 #include "webcontentview.h"
       
    29 #include "wrtBrowserUtils.h"
       
    30 
       
    31 
       
    32 #define LONG_PRESS_DURATION 500
       
    33 
       
    34 const int KFlickSpeed = 400;
       
    35 const qreal PI = 3.1415926535897932;
       
    36 const qreal KAngleTolerance = 30;
       
    37 const int KAnimationTimeout = 40;
       
    38 const qreal KDecelerationFactor = 0.8;
       
    39 const int KMilliSecond = 1000;
       
    40 const int KThresholdForRightToLeftMotion = 100;  // 100 pixels
       
    41 const int KThresholdForLeftToRightMotion = -100; // 100 pixels
       
    42 const int XAlignVal = 10;
       
    43 const int KDecelerationTimer = 125; //Decelerate only if flicked/swiped after KDecelerationTimer milli seconds after last drag event
       
    44 const int KDoubleClickTimeOut = 400;
       
    45 const QPoint KFocussPoint(5, 50);
       
    46 const int KTouchThresholdX = 20;
       
    47 const int KTouchThresholdY = 20;
       
    48 const int KThreshHoldValForLink = 10;
       
    49 const qreal KDeccelaration = 1000.00;
       
    50 const int KDefaultViewportWidth = 980;
       
    51 const int KDefaultPortraitScaleWidth = 540;
       
    52 
       
    53 const int KKineticTimeout = 60;
       
    54 const int KMinBlockWidth = 50;
       
    55 
       
    56 static const int KStartPanDistance = 50;
       
    57 static const int KWaitForClickTimeoutMS = 200;
       
    58 //The amount of pixels to try to pan before pan mode unlocks
       
    59 static const int KPanModeChangeDelta = 100;
       
    60 
       
    61 namespace WRT {
       
    62 
       
    63 /*!
       
    64     \class WebTouchNavigation
       
    65     \since cwrt 1.0
       
    66     \brief cwrt navigation.
       
    67 
       
    68     \sa WebNavigation, WebHtmlTabIndexedNavigation, WebCursorNavigation, WebDirectionalNavigation
       
    69 */
       
    70 WebTouchNavigation::WebTouchNavigation(QWebPage* webPage,QObject* view)
       
    71 : m_webPage(webPage)
       
    72 , m_view(view)
       
    73 , m_frame(0)
       
    74 , m_scrollTimer(0)
       
    75 , m_doubleClickTimer(0)
       
    76 , m_pressEvent(0)
       
    77 , m_releaseEvent(0)
       
    78 , m_focusedBlockPt(-1, -1)
       
    79 , m_ishighlighted(false)
       
    80 , m_offset(0)
       
    81 , m_longPressTimer(0)
       
    82 , m_finalzoomfactor(0)
       
    83 , m_kineticTimer(0)
       
    84 , m_isPanning(false)
       
    85 {
       
    86 	install();
       
    87 	WebContentWidget* currentView = qobject_cast<WebContentWidget*>(m_view);  
       
    88 	connect(currentView, SIGNAL(BlockFocusChanged(QPoint)), this, SLOT(BlockFocusChanged(QPoint)));  
       
    89 }
       
    90 
       
    91 /*!
       
    92 */
       
    93 WebTouchNavigation::~WebTouchNavigation() 
       
    94 {
       
    95     disconnect(m_doubleClickTimer, SIGNAL(timeout()), this, SLOT(doubleClickTimerExpired()));    
       
    96     if (m_doubleClickTimer) {
       
    97         m_doubleClickTimer->stop();
       
    98         delete m_doubleClickTimer;
       
    99     }
       
   100     disconnect(m_scrollTimer, SIGNAL(timeout()),this,SLOT(pan()));
       
   101     delete m_scrollTimer;
       
   102     
       
   103     disconnect(m_kineticTimer, SIGNAL(timeout()),this,SLOT(kineticScroll()));
       
   104     delete m_kineticTimer;
       
   105     uninstall();
       
   106 }
       
   107 
       
   108 void WebTouchNavigation::install()
       
   109 {
       
   110     m_view->installEventFilter(this);
       
   111 }
       
   112 
       
   113 void WebTouchNavigation::BlockFocusChanged(QPoint pt)
       
   114 {
       
   115 	m_focusedBlockPt = pt;
       
   116 }
       
   117 
       
   118 void WebTouchNavigation::uninstall()
       
   119 {
       
   120     if (m_view)
       
   121         m_view->removeEventFilter(this);
       
   122 }
       
   123 
       
   124 bool WebTouchNavigation::eventFilter(QObject *object, QEvent *event)
       
   125 {
       
   126     bool ret = false;
       
   127     if (object != m_view)
       
   128         return false;
       
   129 
       
   130 {
       
   131         switch (event->type()) {
       
   132             case QEvent::MouseButtonPress:
       
   133                 if (static_cast<QMouseEvent *>(event)->buttons() & Qt::LeftButton) {
       
   134                     mousePressEvent(static_cast<QMouseEvent *>(event)->pos());
       
   135                     return true;
       
   136                 }
       
   137                 break;
       
   138             case QEvent::MouseMove:
       
   139                 if (static_cast<QMouseEvent *>(event)->buttons() & Qt::LeftButton) {
       
   140                     mouseMoveEvent(static_cast<QMouseEvent*>(event)->pos());
       
   141                     return true;
       
   142                 }
       
   143                 break;
       
   144             case QEvent::MouseButtonRelease:
       
   145                 mouseReleaseEvent(static_cast<QMouseEvent*>(event)->pos());
       
   146                 return true;
       
   147             case QEvent::MouseButtonDblClick:
       
   148                 mouseDoubleClickEvent(static_cast<QMouseEvent*>(event)->pos());
       
   149                 return true;
       
   150             case QEvent::GraphicsSceneMousePress:
       
   151                 if (static_cast<QGraphicsSceneMouseEvent*>(event)->buttons() & Qt::LeftButton) {
       
   152                     mousePressEvent(static_cast<QGraphicsSceneMouseEvent*>(event)->pos().toPoint());
       
   153                     return true;
       
   154                 }
       
   155             break;
       
   156             case QEvent::GraphicsSceneMouseMove:
       
   157                 if (static_cast<QGraphicsSceneMouseEvent *>(event)->buttons() & Qt::LeftButton) {
       
   158                     mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent*>(event)->pos().toPoint());
       
   159                     return true;
       
   160                 }
       
   161             break;
       
   162             case QEvent::GraphicsSceneMouseRelease: {
       
   163                 mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(event)->pos().toPoint());
       
   164                 return true;
       
   165             }
       
   166             break;
       
   167             case QEvent::GraphicsSceneMouseDoubleClick:
       
   168                  mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent*>(event)->pos().toPoint());
       
   169                  return true;
       
   170             break;
       
   171         default:
       
   172                 break;
       
   173         }
       
   174     }
       
   175     return false;
       
   176 }
       
   177 
       
   178 void WebTouchNavigation::stopScrolling()
       
   179 {
       
   180 	if (m_scrollTimer && m_scrollTimer->isActive()) {
       
   181 	    m_scrollTimer->stop();
       
   182 	    m_scrollDelta = QPoint(0,0);
       
   183 	}
       
   184 	
       
   185 	if (m_kineticTimer && m_kineticTimer->isActive()) {
       
   186 	    m_kineticTimer->stop();
       
   187 	    m_kineticSpeed.setX(0.0);
       
   188 	    m_kineticSpeed.setY(0.0);
       
   189 	}
       
   190 }
       
   191 
       
   192 
       
   193 void WebTouchNavigation::pan()
       
   194 {
       
   195 	if (m_scrollDelta.x() != 0 || m_scrollDelta.y() != 0) {
       
   196             scrollCurrentFrame(-m_scrollDelta.x(), m_scrollDelta.y());
       
   197 	    m_scrollDelta = QPoint(0,0);
       
   198 	}
       
   199 }
       
   200 
       
   201 #define DECELERATION 0.0002 
       
   202 
       
   203 void WebTouchNavigation::kineticScroll()
       
   204 {
       
   205 	qreal decelX = m_kineticSpeed.x() > 0 ? -DECELERATION : DECELERATION;
       
   206 	qreal decelY = m_kineticSpeed.y() > 0 ? -DECELERATION : DECELERATION;
       
   207 	qreal dx = 0;
       
   208 	qreal dy = 0;
       
   209 	qreal vx = 0;
       
   210 	qreal vy = 0;
       
   211 	
       
   212 	m_kineticScrollTime += m_actualTime.elapsed();
       
   213 	
       
   214 	if (m_kineticSpeed.x()) {
       
   215 		vx = m_kineticSpeed.x() + decelX * m_kineticScrollTime;
       
   216 		if (vx * m_kineticSpeed.x() < 0) {
       
   217 			dx = 0;
       
   218 			vx = 0;
       
   219 		}
       
   220 		else {
       
   221 	        dx = m_kineticScrollTime * m_kineticSpeed.x() + 
       
   222 		        0.5 * decelX * m_kineticScrollTime * m_kineticScrollTime;
       
   223 		}
       
   224 	}
       
   225 	
       
   226 	if (m_kineticSpeed.y()) {
       
   227 		vy = m_kineticSpeed.y() + decelY * m_kineticScrollTime;
       
   228 		if (vy * m_kineticSpeed.y() < 0) {
       
   229 			dy = 0;
       
   230 			vy = 0;
       
   231 		}
       
   232 		else {
       
   233 		    dy = m_kineticScrollTime * m_kineticSpeed.y() + 
       
   234 			     0.5 * decelY * m_kineticScrollTime * m_kineticScrollTime;
       
   235 		}
       
   236 	}
       
   237 		
       
   238 	QPoint scrollPos = m_frame->scrollPosition();
       
   239 	QPoint distPos = m_initialScrollPos + QPointF(dx, dy).toPoint();
       
   240 	
       
   241 	
       
   242     
       
   243 	if (vx != 0 || vy != 0) {
       
   244             setCurrentFrameScrollPosition(distPos);
       
   245 	}
       
   246     
       
   247 	if ((vx == 0 && vy == 0) || scrollPos == m_frame->scrollPosition()) {
       
   248     	stopScrolling();
       
   249     }
       
   250 
       
   251 }
       
   252 
       
   253 
       
   254 
       
   255 /*!
       
   256     Scrolls QWebFrame to the given position
       
   257     \sa QWebFrame::scroll()
       
   258 */
       
   259 void WebTouchNavigation::scrollFrame(const QPoint& pos)
       
   260 {
       
   261     if (m_touchPosition != pos) {
       
   262         QPoint diff = m_touchPosition-pos;
       
   263         if (qAbs(diff.x()) < 10 && qAbs(diff.y()) < 10)
       
   264             return;
       
   265 		else if(m_dragPoints.size() == 1) {	
       
   266 			WebContentWidget* view = qobject_cast<WebContentWidget*>(m_view);  
       
   267 			view->setBlockElement(QWebElement());
       
   268 		}
       
   269 
       
   270         if(!m_isPanning) {
       
   271             qreal dy = qAbs(diff.y());
       
   272             qreal dx = qAbs(diff.x());
       
   273             if (dy > KStartPanDistance || dx > KStartPanDistance
       
   274                 || m_delayedPressMoment.elapsed() > KWaitForClickTimeoutMS) {
       
   275                 //get the scroll direction
       
   276                 Direction scrollDir = findDirectionWithAngle(m_touchPosition,pos);
       
   277                 if(scrollDir == UP || scrollDir == DOWN)
       
   278                     startPanGesture(VerticalPan);
       
   279                 else if(scrollDir == LEFT || scrollDir == RIGHT)
       
   280                     startPanGesture(HorizontalPan);
       
   281                 else
       
   282                     startPanGesture(RandomPan);
       
   283                 m_isPanning = true;
       
   284                 m_dragStartPos = pos;
       
   285             }
       
   286         }
       
   287 
       
   288         if (m_isPanning) {
       
   289             m_scrolled= false;
       
   290             m_frame = getNextScrollableFrame(diff);
       
   291             QPoint scrollPosition = m_frame->scrollPosition();
       
   292             if (diff.manhattanLength())
       
   293                 panBy(diff);            
       
   294             
       
   295             m_scrolled = (scrollPosition != m_frame->scrollPosition());
       
   296             m_dragStartPos = pos;
       
   297         }
       
   298 				
       
   299         m_touchPosition = pos;
       
   300         DragPoint dragPoint;
       
   301         dragPoint.iPoint = pos;
       
   302         dragPoint.iTime = QTime::currentTime();
       
   303         m_dragPoints.append(dragPoint);
       
   304 
       
   305         QTime now(QTime::currentTime());
       
   306         m_lastMoveEventTime.setHMS(now.hour(),now.minute(), now.second(), now.msec());
       
   307 
       
   308         while (m_dragPoints.size() > 4)
       
   309             m_dragPoints.removeFirst();
       
   310         }
       
   311 }
       
   312 
       
   313 void WebTouchNavigation::startPanGesture(PanDirection directionHint) {
       
   314     m_panDirection = directionHint;
       
   315     m_panModeResidue = QPointF(0., 0.);
       
   316 }
       
   317 void WebTouchNavigation::panBy(const QPointF& delta) {
       
   318     
       
   319     m_panModeResidue += delta;
       
   320 
       
   321     if (qAbs(m_panModeResidue.x()) > KPanModeChangeDelta)
       
   322         m_panDirection = HorizontalPan;
       
   323     
       
   324     if (qAbs(m_panModeResidue.y()) > KPanModeChangeDelta)
       
   325         m_panDirection = VerticalPan;
       
   326    
       
   327     if(qAbs(m_panModeResidue.x()) > KPanModeChangeDelta 
       
   328         && qAbs(m_panModeResidue.y()) > KPanModeChangeDelta)
       
   329         m_panDirection = RandomPan;
       
   330     
       
   331     QPointF p;
       
   332     if(m_panDirection == HorizontalPan)
       
   333         p.setX(delta.x());
       
   334     if(m_panDirection == VerticalPan)
       
   335         p.setY(delta.y());
       
   336     if(m_panDirection == RandomPan) {
       
   337         p.setX(delta.x());     
       
   338         p.setY(delta.y());
       
   339     }
       
   340         
       
   341     scrollCurrentFrame(p.x(),p.y());
       
   342 }
       
   343 
       
   344 void WebTouchNavigation::highlightableElement(QMouseEvent* ev) {
       
   345     m_anchorElement = getClosestAnchorElement(ev);
       
   346 }
       
   347 
       
   348 inline int xInRect(const QRect& r, int x)
       
   349 {
       
   350     return std::min(std::max(x, r.x()), r.x() + r.width());
       
   351 }
       
   352 
       
   353 inline int yInRect(const QRect& r, int y)
       
   354 {
       
   355     return std::min(std::max(y, r.y()), r.y() + r.height());
       
   356 }
       
   357 
       
   358 bool WebTouchNavigation::traverseNextNode(QWebElement parentNode,QWebElement& nextNode) 
       
   359 { 
       
   360     if (!parentNode.firstChild().isNull()) {
       
   361         nextNode = parentNode.firstChild();
       
   362         return true;
       
   363     }
       
   364            
       
   365     if (!parentNode.nextSibling().isNull()) {
       
   366         nextNode = parentNode.nextSibling();
       
   367         return true;
       
   368     }
       
   369 
       
   370     QWebElement n = parentNode;
       
   371     while (!n.isNull() && n.nextSibling().isNull()) 
       
   372         n = n.parent (); 
       
   373     
       
   374     if (!n.isNull()) {
       
   375         nextNode = n.nextSibling();
       
   376         return true;
       
   377     }
       
   378 
       
   379     return false; 
       
   380 } 
       
   381 
       
   382 
       
   383 QWebElement WebTouchNavigation::getClosestAnchorElement(QMouseEvent* ev)
       
   384 {   
       
   385     QWebElement webElement;
       
   386     QWebHitTestResult htRes = getHitTestResult(ev);
       
   387     QWebElement hitElement = htRes.element();
       
   388     //check whether hit test returns a link element
       
   389     if(!htRes.linkElement().isNull()) {
       
   390         webElement = htRes.linkElement();              
       
   391 		m_higlightedPos = ev->pos();
       
   392         m_ishighlighted = true;
       
   393     }
       
   394     //get the closet anchor element
       
   395     else {
       
   396 		QPoint docPoint = (m_touchPosition + m_frame->scrollPosition());
       
   397         int dist = 99999999;
       
   398         QWebElement result;
       
   399         QWebElement ele = m_webPage->currentFrame()->documentElement();
       
   400         do {
       
   401             if(ele.tagName().compare("a",Qt::CaseInsensitive) == 0 ) {       
       
   402                 QRect r = ele.geometry();
       
   403                 if(r.contains(docPoint)) {
       
   404                     dist = 0;
       
   405                     result = ele;
       
   406                     break;
       
   407                 }
       
   408 
       
   409                 int x = xInRect(r, docPoint.x());
       
   410                 int y = yInRect(r, docPoint.y());
       
   411                 int d = (docPoint.x() - x) * (docPoint.x() - x) + (docPoint.y() - y) * (docPoint.y() - y);
       
   412                 if (dist > d) {
       
   413                     dist = d;
       
   414                     result = ele;
       
   415                 }
       
   416             }                       
       
   417         }while(traverseNextNode(ele,ele));
       
   418 
       
   419         WebContentWidget* view = qobject_cast<WebContentWidget*>(m_view);
       
   420 		// check if we are close enough and calcualte with zoom factor.
       
   421         if (dist< (KThreshHoldValForLink/view->zoomFactor())) {
       
   422             QRect r = result.geometry();
       
   423             r.translate(2,2); 
       
   424             r.setWidth(2+2); 
       
   425             r.setHeight(2+2); 
       
   426             webElement = result;
       
   427             m_higlightedPos = QPoint(xInRect(r, docPoint.x()), yInRect(r, docPoint.y())) - m_frame->scrollPosition(); 
       
   428             m_ishighlighted = true;
       
   429             QPoint centerpt = webElement.geometry().center();
       
   430             m_offset = (docPoint.x()- centerpt.x())*(docPoint.x()- centerpt.x()) + (docPoint.y()- centerpt.y())*(docPoint.y()- centerpt.y());
       
   431             
       
   432         }
       
   433     }
       
   434     return webElement;
       
   435 }
       
   436 
       
   437 /*!
       
   438     Sends a mouse press event to QWebPage
       
   439 */
       
   440 void WebTouchNavigation::mousePressEvent(const QPoint& pos)
       
   441 {
       
   442     m_delayedPressMoment.start();
       
   443     // stop deceleration and don't send further events to engine if scroll timer is active
       
   444     if(m_scrollTimer && m_scrollTimer->isActive()) {
       
   445         m_prevPoint.setX(0);
       
   446         m_prevPoint.setY(0);
       
   447         m_scrollDistance.setX(0);
       
   448         m_scrollDistance.setY(0);
       
   449         
       
   450         m_lastMoveEventTime.setHMS(0,0,0,0); //H, M, S, mS
       
   451         m_scrolled = false;
       
   452         m_ishighlighted = false;
       
   453         m_higlightedPos = m_touchPosition = pos;
       
   454         m_frame = m_webPage->frameAt(pos);
       
   455         if (!m_frame)
       
   456               m_frame = m_webPage->currentFrame(); 
       
   457           
       
   458         m_dragPoints.clear();
       
   459           
       
   460         DragPoint dragPoint;
       
   461         dragPoint.iPoint = m_touchPosition;
       
   462         dragPoint.iTime = QTime::currentTime();
       
   463         m_dragPoints.append(dragPoint);
       
   464         m_offset = 0;
       
   465         
       
   466         m_pressEvent = new QMouseEvent(QEvent::MouseButtonPress, m_touchPosition, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
       
   467         m_scrollTimer->stop();
       
   468         return;
       
   469     }
       
   470     
       
   471     if (m_doubleClickTimer) {
       
   472         // If there is another click event almost on the same region 
       
   473         // as the previous click before doubleClick timeout 
       
   474         // Consider it as double click.
       
   475         if (m_doubleClickTimer->isActive() && m_pressEvent) {
       
   476             QPoint diff = m_pressEvent->pos() - pos;
       
   477             if (qAbs(diff.x()) < KTouchThresholdX && qAbs(diff.y()) < KTouchThresholdY) {           
       
   478                 mouseDoubleClickEvent(pos);
       
   479                 return;
       
   480             }
       
   481         }
       
   482         m_doubleClickTimer->stop();
       
   483     } else {
       
   484         m_doubleClickTimer = new QTimer(this);
       
   485         connect(m_doubleClickTimer, SIGNAL(timeout()), this, SLOT(doubleClickTimerExpired()));    
       
   486     }
       
   487 
       
   488     //Clear the previous press and release events.
       
   489     if (m_pressEvent) {
       
   490         delete m_pressEvent;
       
   491         m_pressEvent = NULL;
       
   492     }
       
   493     
       
   494     if (m_releaseEvent) {
       
   495         delete m_releaseEvent;
       
   496         m_releaseEvent = NULL;
       
   497     }
       
   498 
       
   499     m_doubleClickTimer->start(KDoubleClickTimeOut);
       
   500     m_pressEvent = new QMouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
       
   501 }
       
   502 
       
   503 void WebTouchNavigation::handleMousePressEvent(QMouseEvent* ev)
       
   504 {
       
   505     m_lastMoveEventTime.setHMS(0,0,0,0); //H, M, S, mS
       
   506     if(!m_longPressTimer){
       
   507         delete m_longPressTimer;
       
   508         m_longPressTimer = 0;
       
   509     }
       
   510     startTimer();
       
   511     m_scrolled = false;
       
   512     m_ishighlighted = false;
       
   513     m_higlightedPos = m_touchPosition = ev->pos();
       
   514     m_frame = m_webPage->frameAt(ev->pos());
       
   515     if (!m_frame)
       
   516         m_frame = m_webPage->currentFrame(); 
       
   517     
       
   518     m_dragPoints.clear();
       
   519     
       
   520     DragPoint dragPoint;
       
   521     dragPoint.iPoint = m_touchPosition;
       
   522     dragPoint.iTime = QTime::currentTime();
       
   523     m_dragPoints.append(dragPoint);
       
   524 
       
   525 	m_offset = 0;
       
   526 	
       
   527     highlightableElement(ev);
       
   528     getFocusedElement();		
       
   529 
       
   530     //send a mouse press
       
   531     QMouseEvent iev(ev->type(), m_touchPosition, ev->button(), ev->buttons(), ev->modifiers());
       
   532     m_webPage->event(&iev);
       
   533 }
       
   534 
       
   535 void WebTouchNavigation::doubleClickTimerExpired()
       
   536 {   
       
   537     handleMousePressEvent(m_pressEvent);
       
   538 
       
   539     delete m_pressEvent;
       
   540     m_pressEvent = NULL;
       
   541     
       
   542     if (m_releaseEvent) {
       
   543         handleMouseReleaseEvent(m_releaseEvent);
       
   544 
       
   545 		//clear release event
       
   546 		delete m_releaseEvent;
       
   547         m_releaseEvent = NULL;
       
   548     }
       
   549 	if (m_doubleClickTimer && m_doubleClickTimer->isActive())
       
   550         m_doubleClickTimer->stop();
       
   551 }
       
   552 
       
   553 bool WebTouchNavigation::canDehighlight(QMouseEvent* ev)
       
   554  {
       
   555     bool checkDehighlight = false;  
       
   556     QPoint pt = ev->pos() + m_frame->scrollPosition();
       
   557     
       
   558     if(m_scrolled && m_ishighlighted) {
       
   559         checkDehighlight = true;
       
   560     }
       
   561     else if(!m_scrolled && m_ishighlighted) {
       
   562         QRect rect = m_anchorElement.geometry();
       
   563 
       
   564         if(m_anchorElement.geometry().contains(pt)) {
       
   565             checkDehighlight = false;
       
   566         }
       
   567         else if(m_offset){
       
   568             QPoint centerpt = m_anchorElement.geometry().center();
       
   569             int newoffset = (pt.x()- centerpt.x())*(pt.x()- centerpt.x()) + (pt.y()- centerpt.y())*(pt.y()- centerpt.y());
       
   570         
       
   571             if(newoffset <= m_offset ) {
       
   572                  m_offset = newoffset;
       
   573                  checkDehighlight = false;
       
   574             }
       
   575             else {
       
   576                 m_offset =0;
       
   577                 checkDehighlight = true;
       
   578             }
       
   579         }
       
   580         else {
       
   581             checkDehighlight = true;
       
   582         }
       
   583     }
       
   584     return checkDehighlight;
       
   585 }
       
   586  void  WebTouchNavigation::dehighlight(QMouseEvent* ev)
       
   587 {
       
   588     m_higlightedPos = QPoint(0,0);
       
   589     m_ishighlighted = false;
       
   590     QMouseEvent iev(QEvent::MouseButtonPress,m_higlightedPos,ev->button(), ev->buttons(), ev->modifiers());
       
   591     m_webPage->event(&iev);
       
   592 }
       
   593 
       
   594 void WebTouchNavigation::handleHighlightChange(QMouseEvent* ev)
       
   595 {
       
   596     if (!canDehighlight(ev)) return;
       
   597 
       
   598     dehighlight(ev);
       
   599 }
       
   600 
       
   601 /*!
       
   602     Scrolls the frame
       
   603     \sa scrollFrame()
       
   604 */
       
   605 void WebTouchNavigation::mouseMoveEvent(const QPoint& pos)
       
   606 {
       
   607     if (m_pressEvent) {
       
   608         QPoint diff = m_pressEvent->pos() - pos;
       
   609         if (qAbs(diff.x()) < KTouchThresholdX && qAbs(diff.y()) < KTouchThresholdY)
       
   610             return;    
       
   611     }
       
   612 
       
   613     if (m_doubleClickTimer && m_doubleClickTimer->isActive()) {
       
   614         //send mousePressEvent
       
   615         m_doubleClickTimer->stop();
       
   616         handleMousePressEvent(m_pressEvent);
       
   617         delete m_pressEvent;
       
   618         m_pressEvent = NULL;
       
   619     }
       
   620 
       
   621     stopTimer();
       
   622     QMouseEvent tmpEv(QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
       
   623     handleHighlightChange(&tmpEv);
       
   624 
       
   625     scrollFrame(pos);
       
   626 }
       
   627 
       
   628 /*!
       
   629     If WebCanvas or QWebFrame were scrolled starts the deceleration alogrithm
       
   630     Otherwise sends the mouse release event to QWebPage
       
   631     \sa startDeceleration()
       
   632 */
       
   633 void WebTouchNavigation::mouseReleaseEvent(const QPoint& pos)
       
   634 {
       
   635     if(m_isPanning)
       
   636         m_isPanning = false;
       
   637      if (m_doubleClickTimer && m_doubleClickTimer->isActive()) {
       
   638         m_releaseEvent = new QMouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
       
   639         return;
       
   640     }
       
   641     //mouseReleaseEvent is called in two cases. 1. Double click, 2. Mouse Drag
       
   642     //m_releaseEvent is not null only in Mouse double click
       
   643     //So delete m_releaseEvent only in double click case.
       
   644     //Send release event in mouse move case
       
   645     if (m_releaseEvent) {
       
   646         delete m_releaseEvent ;
       
   647         m_releaseEvent = NULL;
       
   648     } else {
       
   649         QMouseEvent tmpEv(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
       
   650         handleMouseReleaseEvent(&tmpEv);    
       
   651     }
       
   652 }
       
   653 
       
   654 void WebTouchNavigation::handleMouseReleaseEvent(QMouseEvent* ev)
       
   655 {
       
   656     m_frame = m_webPage->frameAt(ev->pos());
       
   657     if (!m_frame)
       
   658         m_frame = m_webPage->currentFrame(); 
       
   659     assert(m_frame);
       
   660     
       
   661      stopTimer();
       
   662      if (m_scrolled) {
       
   663         int msecs = 0;
       
   664         if (!m_lastMoveEventTime.isNull()) {
       
   665             //Start deceleration only if the delta since last drag event is less than threshold
       
   666             QTime now(QTime::currentTime());
       
   667             msecs = m_lastMoveEventTime.msecsTo(now);
       
   668             m_lastMoveEventTime.setHMS(0,0,0,0);
       
   669         }
       
   670         if (msecs < KDecelerationTimer) {
       
   671             if( isFlick()) {
       
   672                 updateFlickScrollDistance();
       
   673             }
       
   674             else {
       
   675                 QRect enclosingRect = findEnclosingBlock(ev);
       
   676                 QPoint blockDocPt(enclosingRect.x(), enclosingRect.y());
       
   677                 QPoint blockCanvasPoint(blockDocPt - m_frame->scrollPosition());
       
   678                 calculateActualScrollDistance();
       
   679                 int thresholdCheckVal = blockCanvasPoint.x() - m_actualScrollDistance.x();
       
   680                 setNewScrollDistance(blockCanvasPoint, thresholdCheckVal);
       
   681             }
       
   682             startScrollTimer();
       
   683         }
       
   684     } else {
       
   685         Qt::KeyboardModifier modifier = Qt::NoModifier;
       
   686         QWebHitTestResult htr = m_frame->hitTestContent(ev->pos());
       
   687         if (htr.element().tagName().toLower().compare("select")==0  && htr.element().hasAttribute("multiple"))
       
   688             modifier = Qt::ControlModifier;
       
   689 
       
   690         //send a mouse press
       
   691         if(m_ishighlighted) {
       
   692             QMouseEvent iev(ev->type(), m_higlightedPos, ev->button(), ev->buttons(), ev->modifiers());
       
   693             m_webPage->event(&iev);
       
   694         }
       
   695         else {
       
   696 			QMouseEvent ievr(QEvent::MouseButtonRelease, m_touchPosition, ev->button(), ev->buttons(), modifier);
       
   697 			m_webPage->event(&ievr);
       
   698 		}
       
   699 #if defined CWRTINTERNALWEBKIT && __SYMBIAN32__
       
   700 // FIXME Remove this, it is fixed Qt 4.6 
       
   701         if (ev->button() == Qt::LeftButton) {
       
   702             QWebHitTestResult htr = m_frame->hitTestContent(ev->pos());
       
   703             if (htr.isContentEditable()) {
       
   704                 QEvent vkbEvent(QEvent::RequestSoftwareInputPanel); 
       
   705                 QApplication::sendEvent(m_view, &vkbEvent);
       
   706             }
       
   707         }
       
   708 #endif
       
   709     }
       
   710 }
       
   711 
       
   712 void WebTouchNavigation::mouseDoubleClickEvent(const QPoint& pos)
       
   713 {
       
   714     
       
   715     if(m_doubleClickTimer && !m_doubleClickTimer->isActive())
       
   716         return;
       
   717     else if(m_doubleClickTimer)
       
   718         m_doubleClickTimer->stop();
       
   719 
       
   720     //If the page is already scrolling(because of a previous doubletap)
       
   721     //we need to stop the timer before we start scrolling the new block again.
       
   722     if (m_scrollTimer && m_scrollTimer->isActive())
       
   723         m_scrollTimer->stop();
       
   724 
       
   725     QMouseEvent tmpEv(QEvent::MouseButtonDblClick, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
       
   726     handleDoubleClickEvent(&tmpEv);
       
   727 }
       
   728 
       
   729 void WebTouchNavigation::handleDoubleClickEvent(QMouseEvent* ev)
       
   730 {
       
   731     QPoint imageFocusPoint;
       
   732     QWebHitTestResult hitTest = getHitTestResult(ev);
       
   733     
       
   734     QWebElement block = hitTest.element();
       
   735 
       
   736     if (block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == ""))
       
   737         block = hitTest.enclosingBlockElement();
       
   738 	
       
   739     while (!block.isNull() && block.geometry().width() < KMinBlockWidth) {
       
   740        block = block.parent();
       
   741     }
       
   742     if(block.isNull())
       
   743        return;
       
   744 
       
   745     QWebFrame* frame = m_webPage->frameAt(ev->pos());
       
   746     m_frame = (frame) ? frame : m_webPage->mainFrame();
       
   747     
       
   748     QRect enclosingRect = block.geometry();
       
   749           
       
   750     QPoint blockCanvasPt = QPoint(enclosingRect.topLeft()) - m_frame->scrollPosition();            
       
   751     WebContentWidget* view = qobject_cast<WebContentWidget*>(m_view);    
       
   752     view->setBlockElement(QWebElement());
       
   753 	if(m_focusedBlockPt == blockCanvasPt) {
       
   754 		m_focusedBlockPt.setX(-1);
       
   755 		m_focusedBlockPt.setY(-1);
       
   756 		qreal m_Ratiox = (qreal) blockCanvasPt.x() / block.geometry().width();
       
   757 		qreal m_Ratioy = (qreal) blockCanvasPt.y() / block.geometry().height();
       
   758 		view->setZoomFactor(view->initialScale());
       
   759 		QPoint m_InfocusBlockPt = QPoint(block.geometry().topLeft()) - m_webPage->mainFrame()->scrollPosition(); 
       
   760 		m_webPage->currentFrame()->scroll(m_InfocusBlockPt.x() - (m_Ratiox * block.geometry().width()),
       
   761 																					m_InfocusBlockPt.y() - (m_Ratioy * block.geometry().height()));
       
   762         m_finalzoomfactor = 0;
       
   763 	}else {     
       
   764         if(block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == "")) {
       
   765         	m_finalzoomfactor   = (qreal) (m_webPage->viewportSize().width() - 10) * view->zoomFactor();
       
   766         	m_finalzoomfactor = (qreal) m_finalzoomfactor / (enclosingRect.width());
       
   767         	QString str;
       
   768         	str.setNum(m_finalzoomfactor,'f',2);
       
   769 			m_finalzoomfactor = str.toDouble();
       
   770 		}else {																																     			
       
   771 			qreal factor;
       
   772 			factor = 1/view->initialScale();
       
   773 			int boundW = block.geometry().width() * factor/view->zoomFactor();
       
   774 			int boundH = block.geometry().height() * factor/view->zoomFactor();
       
   775 			qreal factorw = 0.0,factorh = 0.0 ;
       
   776 	     		
       
   777 			if( boundW > m_webPage->viewportSize().width())
       
   778 				factorw = (qreal)(m_webPage->viewportSize().width()-5)/ block.geometry().width();
       
   779 			
       
   780 			if(boundH > m_webPage->viewportSize().height())
       
   781 				factorh = (qreal)(m_webPage->viewportSize().height()-5)/ block.geometry().height();			
       
   782 
       
   783 			if( (factorw == 0.0) && (factorh == 0.0))
       
   784 				;
       
   785 			else if(factorw == 0.0)
       
   786 				factor = factorh * view->zoomFactor();
       
   787 			else if(factorh == 0.0)
       
   788 				factor = factorw * view->zoomFactor();
       
   789 			else {
       
   790 				factor = ((factorh < factorw) ? factorh : factorw) * view->zoomFactor();		
       
   791 			}	
       
   792 								
       
   793 			QString str;
       
   794 			str.setNum(factor,'f',2);
       
   795 			factor = str.toDouble();	
       
   796 							
       
   797 			if(m_finalzoomfactor != factor) 				    				  		     	
       
   798 				m_finalzoomfactor = factor;
       
   799 		}
       
   800 
       
   801     
       
   802 		if (m_finalzoomfactor != view->zoomFactor()) {                                                 
       
   803             view->setZoomFactor(m_finalzoomfactor); 
       
   804             m_focusedBlockPt = QPoint(block.geometry().topLeft()) - m_frame->scrollPosition(); 
       
   805     
       
   806 			if(block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == "")) 
       
   807             	scrollCurrentFrame(m_focusedBlockPt.x() - KFocussPoint.x() , m_focusedBlockPt.y() - KFocussPoint.y());
       
   808         	else {
       
   809             	if((m_webPage->viewportSize().width() - block.geometry().width()) > 0)
       
   810                 	imageFocusPoint.setX((m_webPage->viewportSize().width() - block.geometry().width())/2);
       
   811             	else
       
   812                 	imageFocusPoint.setX(0);
       
   813             
       
   814             	if((m_webPage->viewportSize().height() - block.geometry().height()) > 0)
       
   815                 	imageFocusPoint.setY((m_webPage->viewportSize().height() - block.geometry().height())/2);
       
   816             	else
       
   817                 	imageFocusPoint.setY(0);
       
   818             
       
   819             	scrollCurrentFrame(m_focusedBlockPt.x() - imageFocusPoint.x() , m_focusedBlockPt.y() - imageFocusPoint.y());
       
   820         	}
       
   821     
       
   822 			m_focusedBlockPt = QPoint(block.geometry().topLeft()) - m_frame->scrollPosition();      
       
   823         } else { 
       
   824 			//Get doc size and current bottom right view corner point in document
       
   825             QSize viewSize = m_webPage->viewportSize();
       
   826             QSize contentSize = m_frame->contentsSize();
       
   827             QPoint documentViewPoint = QPoint(viewSize.width(),viewSize.height()) + m_frame->scrollPosition();
       
   828     		QPoint docFocusPoint;
       
   829 
       
   830     		if(block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == "")) 
       
   831         		docFocusPoint = KFocussPoint + m_frame->scrollPosition();
       
   832     		else {
       
   833         		if((m_webPage->viewportSize().width() - block.geometry().width()) > 0)                                  
       
   834            			 imageFocusPoint.setX((m_webPage->viewportSize().width() - block.geometry().width())/2);
       
   835        			else
       
   836             		imageFocusPoint.setX(0);
       
   837     
       
   838         		if((m_webPage->viewportSize().height() - block.geometry().height()) > 0)    
       
   839             		imageFocusPoint.setY((m_webPage->viewportSize().height()- block.geometry().height())/2);
       
   840         		else
       
   841             		imageFocusPoint.setY(0);
       
   842     
       
   843         		docFocusPoint = imageFocusPoint + m_frame->scrollPosition();
       
   844    			}
       
   845 
       
   846             m_focusedBlockPt = QPoint(block.geometry().x(), block.geometry().y());
       
   847             m_scrollDistance.setX(m_focusedBlockPt.x() - docFocusPoint.x());
       
   848             m_scrollDistance.setY(m_focusedBlockPt.y() - docFocusPoint.y());
       
   849 
       
   850             QPoint scrollableDistance(0, 0);
       
   851             QPoint viewStartPoint = QPoint(0,0) + m_frame->scrollPosition();
       
   852     
       
   853    			if(m_scrollDistance.x() < 0)
       
   854              	scrollableDistance.setX(viewStartPoint.x());
       
   855    			 else
       
   856              	scrollableDistance.setX(contentSize.width() - documentViewPoint.x());
       
   857             
       
   858 
       
   859    			if(m_scrollDistance.y() < 0)
       
   860         		scrollableDistance.setY(viewStartPoint.y());
       
   861     		 else
       
   862 				scrollableDistance.setY(contentSize.height() - documentViewPoint.y());
       
   863 
       
   864 			if(abs(m_scrollDistance.x()) > abs(scrollableDistance.x())){
       
   865                 //m_scrollDistance.x() >= 0 means scroll from right to left
       
   866         		if(m_scrollDistance.x() >= 0)
       
   867                 	m_focusedBlockPt.setX(m_focusedBlockPt.x() - abs(scrollableDistance.x()));
       
   868                 //m_scrollDistance.x() < 0 means scroll from left to right
       
   869         		else
       
   870                 	m_focusedBlockPt.setX(m_focusedBlockPt.x() + abs(scrollableDistance.x()));
       
   871              } else
       
   872                 m_focusedBlockPt.setX(docFocusPoint.x());
       
   873 
       
   874 			if (abs(m_scrollDistance.y()) > abs(scrollableDistance.y())){
       
   875         		if(m_scrollDistance.y() >= 0)
       
   876                 	m_focusedBlockPt.setY(m_focusedBlockPt.y() - abs(scrollableDistance.y()));
       
   877         		else
       
   878                 	m_focusedBlockPt.setY(m_focusedBlockPt.y() + abs(scrollableDistance.y()));
       
   879             }
       
   880             else
       
   881             	m_focusedBlockPt.setY(docFocusPoint.y());
       
   882             
       
   883             m_focusedBlockPt = m_focusedBlockPt - m_frame->scrollPosition();
       
   884             startScrollTimer();
       
   885         }
       
   886 	view->setBlockElement(block);
       
   887 	}
       
   888 }
       
   889 
       
   890 /*!
       
   891     Returns the next scrollable frame in the frame tree give the x,y position
       
   892 */
       
   893 QWebFrame* WebTouchNavigation::getNextScrollableFrame(const QPoint& pos)
       
   894 {
       
   895     QWebFrame* frame = m_frame;
       
   896     while (frame) {
       
   897         if (pos.x() > 0) {
       
   898             if (frame->scrollBarValue(Qt::Horizontal) < frame->scrollBarMaximum(Qt::Horizontal))
       
   899                 break;
       
   900         }
       
   901         else if (pos.x() < 0) {
       
   902             if (frame->scrollBarValue(Qt::Horizontal) > frame->scrollBarMinimum(Qt::Horizontal))
       
   903                 break;
       
   904         }
       
   905 
       
   906         if (pos.y() > 0) {
       
   907             if (frame->scrollBarValue(Qt::Vertical) < frame->scrollBarMaximum(Qt::Vertical))
       
   908                 break;
       
   909         }
       
   910         else if (pos.y() < 0) {
       
   911             if (frame->scrollBarValue(Qt::Vertical) > frame->scrollBarMinimum(Qt::Vertical))
       
   912                 break;
       
   913         }
       
   914         frame = frame->parentFrame();
       
   915     }
       
   916     return (frame)?frame:m_webPage->mainFrame();
       
   917 }
       
   918 
       
   919 /*
       
   920 Starts the timer for scrolling smoothly to the destination location .
       
   921 The timer will do the decelaration while scrolling
       
   922 */
       
   923 void WebTouchNavigation::startScrollTimer()
       
   924 {
       
   925     if(!m_scrollTimer) {
       
   926         m_scrollTimer = new QTimer(this);
       
   927         connect(m_scrollTimer,SIGNAL(timeout()),this,SLOT(scrollToEdge()));
       
   928     }
       
   929     m_scrollTimer->stop();
       
   930     m_scrollTimer->start(KAnimationTimeout);
       
   931 }
       
   932 
       
   933 /*
       
   934 Update the scroll distance for flick gesture. Update the scroll distance upto the edge of the page
       
   935 */
       
   936 void WebTouchNavigation::updateFlickScrollDistance()
       
   937 {
       
   938 	m_initialSpeed = speed();
       
   939 	m_initialSpeed.setX(qAbs(m_initialSpeed.x()));
       
   940 	m_initialSpeed.setY(qAbs(m_initialSpeed.y()));
       
   941 	m_flickDirection = findDirectionWithAngle(m_dragPoints.first().iPoint,m_dragPoints.last().iPoint);
       
   942 	m_scrollDistance.setX((m_initialSpeed.x() * m_initialSpeed.x())/( 2 * KDeccelaration));
       
   943 	m_scrollDistance.setY((m_initialSpeed.y() * m_initialSpeed.y())/( 2 * KDeccelaration));
       
   944 		
       
   945     WebContentWidget* view = qobject_cast<WebContentWidget*>(m_view);    
       
   946     m_scrollDistance.setX(view->zoomFactor() * m_scrollDistance.x() / view->initialScale());
       
   947     m_scrollDistance.setY(view->zoomFactor() * m_scrollDistance.y() / view->initialScale());
       
   948 
       
   949     QSize viewSize = m_webPage->viewportSize();
       
   950   	QSize contentSize = m_frame->contentsSize();
       
   951   	QPoint documentViewPoint = QPoint(viewSize.width(),viewSize.height()) + m_frame->scrollPosition();
       
   952   	QPoint documentTouchPoint = m_touchPosition + m_frame->scrollPosition();;
       
   953    
       
   954 	switch(m_flickDirection)
       
   955     {
       
   956         case DOWN : 
       
   957                     m_scrollDistance.setX(0);
       
   958 					m_scrollDistance.setY(-(m_scrollDistance.y()));
       
   959 										
       
   960 					if(m_scrollDistance.y() < -(documentTouchPoint.y() - m_touchPosition.y()))
       
   961 						m_scrollDistance.setY(-(documentTouchPoint.y() - m_touchPosition.y()));
       
   962                     break;
       
   963         case UP :
       
   964                     m_scrollDistance.setX(0);
       
   965                     if(m_scrollDistance.y() > (contentSize.height() - documentViewPoint.y()))
       
   966                     	m_scrollDistance.setY(contentSize.height() - documentViewPoint.y());
       
   967                     break;
       
   968         case RIGHT:
       
   969                     m_scrollDistance.setX(-(m_scrollDistance.x()));
       
   970                     if(m_scrollDistance.x() < -(documentTouchPoint.x() - m_touchPosition.x()))
       
   971 						m_scrollDistance.setX(-(documentTouchPoint.x() - m_touchPosition.x()));
       
   972                     m_scrollDistance.setY(0);
       
   973                     break;
       
   974         case LEFT:              
       
   975 					m_scrollDistance.setY(0);
       
   976 					if(m_scrollDistance.x() > (contentSize.width() - documentViewPoint.x()))
       
   977 						m_scrollDistance.setX(contentSize.width() - documentViewPoint.x());
       
   978 					break;
       
   979         case BOTTOMRIGHT:
       
   980                     m_scrollDistance.setX(-(m_scrollDistance.x()));
       
   981 					m_scrollDistance.setY(-(m_scrollDistance.y())); 
       
   982 					if(m_scrollDistance.x() <  -(documentTouchPoint.x()-m_touchPosition.x()))
       
   983             			m_scrollDistance.setX(-(documentTouchPoint.x()-m_touchPosition.x()));
       
   984                     if(m_scrollDistance.y() < -((documentTouchPoint.y()-m_touchPosition.y())/2))
       
   985                     	m_scrollDistance.setY(-((documentTouchPoint.y()-m_touchPosition.y())/2));
       
   986 					break;
       
   987         case BOTTOMLEFT: 
       
   988 					m_scrollDistance.setY(-(m_scrollDistance.y()));  	
       
   989 					if(m_scrollDistance.x() > contentSize.width()-documentViewPoint.x())
       
   990                    		m_scrollDistance.setX(contentSize.width()-documentViewPoint.x());
       
   991                    	if(m_scrollDistance.y() < (-((documentTouchPoint.y()-m_touchPosition.y())/2)))
       
   992                     	m_scrollDistance.setY(-((documentTouchPoint.y()-m_touchPosition.y())/2));
       
   993                     break;
       
   994         case TOPLEFT:
       
   995                     if(m_scrollDistance.x() > (contentSize.width()-documentViewPoint.x()))
       
   996                    		m_scrollDistance.setX(contentSize.width()-documentViewPoint.x());
       
   997                    	if(m_scrollDistance.y() > ((contentSize.height()-documentViewPoint.y())/2))
       
   998                     	m_scrollDistance.setY((contentSize.height()-documentViewPoint.y())/2);
       
   999                     break;      
       
  1000         case TOPRIGHT:
       
  1001                     m_scrollDistance.setX(-(m_scrollDistance.x()));
       
  1002                     if(m_scrollDistance.x() < (-(documentTouchPoint.x()-m_touchPosition.x())))
       
  1003                     	m_scrollDistance.setX(-(documentTouchPoint.x()-m_touchPosition.x()));
       
  1004                     if(m_scrollDistance.y() > ((contentSize.height()-documentViewPoint.y())/2))
       
  1005 						m_scrollDistance.setY((contentSize.height()-documentViewPoint.y())/2);
       
  1006                     break;
       
  1007     }
       
  1008 }
       
  1009 
       
  1010 /*
       
  1011 Distinguishes b/w swipe and flick
       
  1012 */
       
  1013 bool WebTouchNavigation::isFlick() 
       
  1014 {
       
  1015     bool flick = false;
       
  1016     QPoint moveSpeed = speed();
       
  1017     int xSpeed = moveSpeed.x();
       
  1018     int ySpeed = moveSpeed.y();
       
  1019      
       
  1020     flick = (qAbs(xSpeed) > KFlickSpeed || 
       
  1021              qAbs(ySpeed) > KFlickSpeed);
       
  1022  
       
  1023     return flick;
       
  1024 }
       
  1025 
       
  1026 /*
       
  1027 Calculates the speed of te scroll along x-axis and y-axis
       
  1028 */
       
  1029 QPoint WebTouchNavigation::speed() 
       
  1030 {
       
  1031     // Speed is only evaluated at the end of the swipe
       
  1032     QPoint dragSpeed(0,0);
       
  1033     qreal time =  dragTime() / KMilliSecond;
       
  1034     if (time > 0) {
       
  1035         QPoint distance = currentPos() - previousPos();
       
  1036         dragSpeed.setX((distance.x()) / time);
       
  1037         dragSpeed.setY((distance.y()) / time);
       
  1038     }
       
  1039     return dragSpeed;
       
  1040 }
       
  1041 
       
  1042 /*
       
  1043 Returns the last point in the m_dragPoints list
       
  1044 */
       
  1045 QPoint WebTouchNavigation::currentPos()
       
  1046 {
       
  1047     return m_dragPoints[m_dragPoints.size()-1].iPoint;
       
  1048 }
       
  1049 
       
  1050 /*
       
  1051 Returns the first point in the m_dragPoints list
       
  1052 */
       
  1053 QPoint WebTouchNavigation::previousPos()
       
  1054 {
       
  1055     return m_dragPoints[0].iPoint;
       
  1056 }
       
  1057 
       
  1058 /*
       
  1059 Finds the time difference b/w the first and last dragpoint
       
  1060 */
       
  1061 qreal WebTouchNavigation::dragTime() const
       
  1062 {
       
  1063     if(m_dragPoints.isEmpty())
       
  1064         return 0.0;
       
  1065     else
       
  1066         return  m_dragPoints[0].iTime.msecsTo(m_dragPoints[m_dragPoints.size()-1].iTime);
       
  1067 }
       
  1068 
       
  1069 /*!
       
  1070 Find the flick direction with respect to angle of flick
       
  1071 */
       
  1072 Direction WebTouchNavigation::findDirectionWithAngle(const QPoint& stPoint,const QPoint& endPoint)
       
  1073 {
       
  1074     Direction direction;
       
  1075     int xDelta = endPoint.x() - stPoint.x();
       
  1076     int yDelta = endPoint.y() - stPoint.y();
       
  1077 
       
  1078     qreal angle = findAngle(xDelta, yDelta);
       
  1079     if(isNear(angle, 60.0, 120.0)) {
       
  1080          direction = DOWN;
       
  1081      }
       
  1082     else if(isNear(angle, 150.0, 210.0)) {
       
  1083         direction = LEFT;
       
  1084     }
       
  1085     else if(isNear(angle, 240.0, 300.0)) {
       
  1086         direction = UP;
       
  1087     }
       
  1088     else if(360.0 - KAngleTolerance <= angle || angle <= KAngleTolerance) {
       
  1089         direction = RIGHT;
       
  1090     }
       
  1091     else if(isNear(angle, 30.0, 60.0)) {
       
  1092         direction = BOTTOMRIGHT;
       
  1093     }
       
  1094     else if(isNear(angle, 120.0, 150.0)) {
       
  1095         direction = BOTTOMLEFT;
       
  1096     }
       
  1097     else if(isNear(angle, 210.0, 240.0)) {
       
  1098         direction = TOPLEFT;
       
  1099     }
       
  1100     else if(isNear(angle, 300.0, 330.0)) {
       
  1101         direction = TOPRIGHT;
       
  1102     }
       
  1103 
       
  1104     return direction;
       
  1105 }
       
  1106 
       
  1107 /*
       
  1108 Check the angle is in the range of aMinAngle and aMaxAngle
       
  1109 */
       
  1110 bool WebTouchNavigation::isNear(qreal angleUnderTest, qreal minAngle, qreal maxAngle)
       
  1111 {
       
  1112     return (minAngle < angleUnderTest) &&  (angleUnderTest <= maxAngle);
       
  1113 }
       
  1114 
       
  1115 /*
       
  1116 Find the angle from x and y displacement
       
  1117 */
       
  1118 qreal WebTouchNavigation::findAngle(const int& xDelta,const int& yDelta)
       
  1119 {
       
  1120     qreal angle = 0;
       
  1121     qreal hypotenuse = qSqrt(xDelta*xDelta + yDelta*yDelta);
       
  1122 
       
  1123     if(hypotenuse != 0) {
       
  1124         angle = qAcos(xDelta / hypotenuse);
       
  1125 
       
  1126         if(yDelta < 0) { 
       
  1127             angle = (2 * PI) - angle;
       
  1128         }
       
  1129     }
       
  1130 
       
  1131     return (angle * 180) / PI;
       
  1132 }
       
  1133 
       
  1134 int WebTouchNavigation::roundOff(qreal num) 
       
  1135 {
       
  1136 	return (num + 0.5);
       
  1137 }
       
  1138 
       
  1139 /*
       
  1140 Finds out the enclosing block 
       
  1141 */
       
  1142 QRect WebTouchNavigation::findEnclosingBlock(QMouseEvent* ev)
       
  1143 {
       
  1144     QWebHitTestResult htr = getHitTestResult(ev);
       
  1145     QRect rect = htr.enclosingBlockElement().geometry();
       
  1146     return rect;
       
  1147 }
       
  1148 
       
  1149 /*
       
  1150 Gets the hitTestResult for a particular event
       
  1151 */
       
  1152 QWebHitTestResult WebTouchNavigation::getHitTestResult(QMouseEvent* ev)
       
  1153 {
       
  1154     QPoint pt = ev->pos();
       
  1155     QWebFrame* frame = m_webPage->frameAt(pt);
       
  1156     frame = (frame) ? frame : m_webPage->mainFrame();
       
  1157     QWebHitTestResult htr = frame->hitTestContent(pt);
       
  1158     return htr;
       
  1159 }
       
  1160 
       
  1161 /*
       
  1162 Finds out the scroll distance associated with a swipe 
       
  1163 */
       
  1164 void WebTouchNavigation::calculateActualScrollDistance()
       
  1165 {
       
  1166     m_actualScrollDistance.setX(0);
       
  1167     m_actualScrollDistance.setY(0);
       
  1168     if (!m_dragPoints.isEmpty()) {
       
  1169         QPoint distance = previousPos() - currentPos();
       
  1170         if (qAbs(distance.x()) > 0 || qAbs(distance.y()) > 0) {
       
  1171             m_actualScrollDistance = distance / m_dragPoints.size() * 2;
       
  1172         }
       
  1173     }
       
  1174 }
       
  1175 
       
  1176 /*
       
  1177 In the case of slow swipe, if the destination location lies within the threshold area, then
       
  1178 we need to align the block to te left edge of the mobile screen. This method finds out the 
       
  1179 new scroll distance
       
  1180 */
       
  1181 void WebTouchNavigation::setNewScrollDistance(QPoint blockCanvasPoint, int thresholdCheckVal)
       
  1182 {
       
  1183     m_scrollDistance.setX(m_actualScrollDistance.x());
       
  1184     m_scrollDistance.setY(m_actualScrollDistance.y());
       
  1185     if(blockCanvasPoint.x() > 0) {
       
  1186         //Checks whether the block falls within the threshold after right to left swipe
       
  1187         if( (thresholdCheckVal <  KThresholdForRightToLeftMotion) && (thresholdCheckVal > 0)) {
       
  1188             //if the block is within the threshold range already and the user tries
       
  1189             //to swipe from left to right , then let it move to right. Dont try to
       
  1190             //snap to the left edge .
       
  1191             if(m_actualScrollDistance.x() > 0) {
       
  1192                 m_scrollDistance.setX(blockCanvasPoint.x() - XAlignVal);
       
  1193             }
       
  1194         }
       
  1195     }
       
  1196     else {
       
  1197         //Checks whether the block falls within the threshold after left to right swipe
       
  1198         if( (thresholdCheckVal >  KThresholdForLeftToRightMotion) && (thresholdCheckVal < 0)) {
       
  1199             //if the block is within the threshold range already and the user tries
       
  1200             //to swipe from right to left , then let it move to left. Dont try to
       
  1201             //snap to the left edge .
       
  1202             if (m_actualScrollDistance.x() < 0) {
       
  1203                 m_scrollDistance.setX(blockCanvasPoint.x() - XAlignVal);
       
  1204             }
       
  1205         }
       
  1206         
       
  1207     }
       
  1208 }
       
  1209 
       
  1210 
       
  1211 /*
       
  1212 SLOT associated with the timer to adjust the scroll to the edge
       
  1213 */
       
  1214 void WebTouchNavigation::scrollToEdge()
       
  1215 {
       
  1216     m_prevPoint.setX(m_scrollDistance.x());
       
  1217     m_prevPoint.setY(m_scrollDistance.y());
       
  1218 
       
  1219     m_scrollDistance.setX(m_scrollDistance.x() * KDecelerationFactor);
       
  1220     m_scrollDistance.setY(m_scrollDistance.y() * KDecelerationFactor);
       
  1221  
       
  1222     //round off the values
       
  1223     m_scrollDistance.setX(roundOff(m_scrollDistance.x()));
       
  1224     m_scrollDistance.setY(roundOff(m_scrollDistance.y()));
       
  1225 
       
  1226     int diffX = m_prevPoint.x() - m_scrollDistance.x();
       
  1227     int diffY = m_prevPoint.y() - m_scrollDistance.y();
       
  1228 
       
  1229     if (((m_scrollDistance.x() == 0) && (m_scrollDistance.y() == 0)) 
       
  1230          || ((diffX == 0) && (diffY == 0))) {
       
  1231         scrollCurrentFrame(m_prevPoint.x(), m_prevPoint.y());
       
  1232         m_scrollTimer->stop();
       
  1233         return;
       
  1234     }
       
  1235     scrollCurrentFrame(diffX, diffY);
       
  1236 }
       
  1237 void WebTouchNavigation::timerControl()
       
  1238 {
       
  1239 	stopTimer();// stop timer as soon as timeout 
       
  1240     emit longPressEvent();
       
  1241 }
       
  1242 void WebTouchNavigation::startTimer()
       
  1243 {
       
  1244     m_longPressTimer = new QTimer(this);
       
  1245     connect(m_longPressTimer,SIGNAL(timeout()),this,SLOT(timerControl()));
       
  1246     m_longPressTimer->start(LONG_PRESS_DURATION);
       
  1247 }
       
  1248 void WebTouchNavigation::stopTimer()
       
  1249 {
       
  1250     if(m_longPressTimer){
       
  1251             m_longPressTimer->stop();
       
  1252             delete m_longPressTimer;
       
  1253             m_longPressTimer = 0;
       
  1254         }
       
  1255 }
       
  1256 void WebTouchNavigation::getFocusedElement()
       
  1257 {
       
  1258 	QWebHitTestResult htRes = m_frame->hitTestContent(m_touchPosition);
       
  1259 	wrtBrowserDefs::BrowserElementType elType = wrtBrowserUtils::getTypeFromElement(htRes);
       
  1260 	emit focusElementChanged(elType);
       
  1261 }
       
  1262 
       
  1263 void WebTouchNavigation::scrollCurrentFrame (int dx, int dy)
       
  1264 {
       
  1265     QPoint scrollPosition = m_frame->scrollPosition();
       
  1266     m_frame->scroll(dx, dy);
       
  1267 
       
  1268     /* emit pageScrollPositionZero singal if it's mainFrame scrolling or scroll to top*/
       
  1269     if (m_frame == m_webPage->mainFrame()) {
       
  1270         if (scrollPosition.y() == 0 || m_frame->scrollPosition().y() == 0) {
       
  1271             emit pageScrollPositionZero();
       
  1272         }
       
  1273     }
       
  1274 }
       
  1275 
       
  1276 void WebTouchNavigation::setCurrentFrameScrollPosition (QPoint& pos)
       
  1277 {
       
  1278     QPoint scrollPosition = m_frame->scrollPosition();
       
  1279     m_frame->setScrollPosition(pos);
       
  1280 
       
  1281     /* emit pageScrollPositionZero singal if it's mainFrame scrolling or scroll to top*/
       
  1282     if (m_frame == m_webPage->mainFrame()) {
       
  1283         if (scrollPosition.y() == 0 || m_frame->scrollPosition().y() == 0) {
       
  1284             emit pageScrollPositionZero();
       
  1285         }
       
  1286     }
       
  1287 }
       
  1288 }