/*
* 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".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/


#include "GWebTouchNavigation.h"
#include "qwebpage.h"
#include "qwebframe.h"
#include "qapplication.h"
#include "qwebelement.h"
#include "GWebContentViewWidget.h"
#include "GWebContentView.h"
#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

const int KFlickSpeed = 400;
const qreal PI = 3.1415926535897932;
const qreal KAngleTolerance = 30;
const int KAnimationTimeout = 40;
const qreal KDecelerationFactor = 0.8;
const int KMilliSecond = 1000;
const int KThresholdForRightToLeftMotion = 100;  // 100 pixels
const int KThresholdForLeftToRightMotion = -100; // 100 pixels
const int XAlignVal = 10;
const int KDecelerationTimer = 125; //Decelerate only if flicked/swiped after KDecelerationTimer milli seconds after last drag event

const int KDoubleClickTimeOut = 400;
const QPoint KFocussPoint(5, 50);
const int KTouchThresholdX = 20;
const int KTouchThresholdY = 20;
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;
//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
    \brief cwrt navigation.

    \sa WebNavigation, WebHtmlTabIndexedNavigation, WebCursorNavigation, WebDirectionalNavigation
*/
GWebTouchNavigation::GWebTouchNavigation(QWebPage* webPage,GWebContentViewWidget* 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_kineticTimer(0)
, m_isPanning(false)
, m_enabled(true)
, m_isLoading(false)
{
        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)));
}

/*!
*/
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_scrollTimer;
    
    disconnect(m_kineticTimer, SIGNAL(timeout()),this,SLOT(kineticScroll()));
    delete m_kineticTimer;
    uninstall();
}

void GWebTouchNavigation::install()
{
    m_view->installEventFilter(this);
}

void GWebTouchNavigation::BlockFocusChanged(QPoint pt)
{
	m_focusedBlockPt = pt;
}

void GWebTouchNavigation::uninstall()
{
    if (m_view)
        m_view->removeEventFilter(this);
}

bool GWebTouchNavigation::eventFilter(QObject *object, QEvent *event)
{
    if (object != m_view || !enabled())
        return false;

    switch (event->type()) {
        case QEvent::MouseButtonPress:
            if (static_cast<QMouseEvent *>(event)->buttons() & Qt::LeftButton) {
                mousePressEvent(static_cast<QMouseEvent *>(event)->pos());
                return true;
            }
            break;
        case QEvent::MouseMove:
            if (static_cast<QMouseEvent *>(event)->buttons() & Qt::LeftButton) {
                QPoint diff = m_touchPosition - static_cast<QMouseEvent*>(event)->globalPos();
                mouseMoveEvent(static_cast<QMouseEvent*>(event)->pos(), diff);
                return true;
            }
            break;
        case QEvent::MouseButtonRelease:
            mouseReleaseEvent(static_cast<QMouseEvent*>(event)->pos());
            return true;
        case QEvent::MouseButtonDblClick:
            mouseDoubleClickEvent(static_cast<QMouseEvent*>(event)->pos());
            return true;
        case QEvent::GraphicsSceneMousePress:
            if (static_cast<QGraphicsSceneMouseEvent*>(event)->buttons() & Qt::LeftButton) {
                mousePressEvent(static_cast<QGraphicsSceneMouseEvent*>(event)->pos().toPoint());
                emit mouseEvent(QEvent::GraphicsSceneMousePress);
                return true;
            }
            break;
        case QEvent::GraphicsSceneMouseMove:
            if (static_cast<QGraphicsSceneMouseEvent *>(event)->buttons() & Qt::LeftButton) {
                QPoint diff = static_cast<QGraphicsSceneMouseEvent*>(event)->lastScenePos().toPoint() - static_cast<QGraphicsSceneMouseEvent*>(event)->scenePos().toPoint();
                mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent*>(event)->pos().toPoint(), diff);
                return true;
            }
            break;
        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;
            break;
        default:
            break;
    }
    return false;
}

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);
	}
}


void GWebTouchNavigation::pan()
{
	if (m_scrollDelta.x() != 0 || m_scrollDelta.y() != 0) {
            scrollCurrentFrame(-m_scrollDelta.x(), m_scrollDelta.y());
	    m_scrollDelta = QPoint(0,0);
	}
}

#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) {
            setCurrentFrameScrollPosition(distPos);
	}
    
	if ((vx == 0 && vy == 0) || scrollPos == m_frame->scrollPosition()) {
    	stopScrolling();
    }

}



/*!
    Scrolls QWebFrame to the given position
    \sa QWebFrame::scroll()
*/
void GWebTouchNavigation::scrollFrame(const QPoint& diff)
{
    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) {
        qreal dy = qAbs(diff.y());
        qreal dx = qAbs(diff.x());
        if (dy > KStartPanDistance || dx > KStartPanDistance
        || m_delayedPressMoment.elapsed() > KWaitForClickTimeoutMS) {
            //get the scroll direction
            Direction scrollDir = findDirectionWithAngle(diff);
            if(scrollDir == UP || scrollDir == DOWN)
                startPanGesture(VerticalPan);
            else if(scrollDir == LEFT || scrollDir == RIGHT)
                startPanGesture(HorizontalPan);
            else
                startPanGesture(RandomPan);
            m_isPanning = true;
        }
    }

		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) {
    emit startingPanGesture((int)directionHint);
    m_panDirection = directionHint;
    m_panModeResidue = QPointF(0., 0.);
}

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 
        && qAbs(m_panModeResidue.y()) > KPanModeChangeDelta)
        m_panDirection = RandomPan;
    
    QPointF p;
    if(m_panDirection == HorizontalPan)
        p.setX(delta.x());
    if(m_panDirection == VerticalPan)
        p.setY(delta.y());
    if(m_panDirection == RandomPan) {
        p.setX(delta.x());     
        p.setY(delta.y());
    }
        
    scrollCurrentFrame(p.x(),p.y());
}

void GWebTouchNavigation::highlightableElement(QMouseEvent* ev) {
    m_anchorElement = getClosestAnchorElement(ev);
}

inline int xInRect(const QRect& r, int x)
{
    return std::min(std::max(x, r.x()), r.x() + r.width());
}

inline int yInRect(const QRect& r, int y)
{
    return std::min(std::max(y, r.y()), r.y() + r.height());
}

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 (); 
    
    if (!n.isNull()) {
        nextNode = n.nextSibling();
        return true;
    }

    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();
        m_ishighlighted = true;
    }
    //get the closet anchor element
    else {
		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 ) {       
                QRect r = ele.geometry();
                if(r.contains(docPoint)) {
                    dist = 0;
                    result = ele;
                    break;
                }

                int x = xInRect(r, docPoint.x());
                int y = yInRect(r, docPoint.y());
                int d = (docPoint.x() - x) * (docPoint.x() - x) + (docPoint.y() - y) * (docPoint.y() - y);
                if (dist > d) {
                    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.
        if (dist< (KThreshHoldValForLink/m_view->zoomFactor())) {
            QRect r = result.geometry();
            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_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;
}

/*!
    Sends a mouse press event to QWebPage
*/
void GWebTouchNavigation::mousePressEvent(const QPoint& pos)
{
    m_delayedPressMoment.start();
    // stop deceleration and don't send further events to engine if scroll timer is active
    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_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 
        // 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) {           
                mouseDoubleClickEvent(pos);
                return;
            }
        }
        m_doubleClickTimer->stop();
    } else {
        m_doubleClickTimer = new QTimer(this);
        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;
    }

    m_doubleClickTimer->start(KDoubleClickTimeOut);
    m_pressEvent = new QMouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, getEventModifier(pos));
}

void GWebTouchNavigation::handleMousePressEvent(QMouseEvent* ev)
{
    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_dragPoints.clear();
    
    DragPoint dragPoint;
    dragPoint.iPoint = m_touchPosition;
    dragPoint.iTime = QTime::currentTime();
    m_dragPoints.append(dragPoint);

	m_offset = 0;
	
    highlightableElement(ev);
    getFocusedElement();		

    //send a mouse press
    QMouseEvent iev(ev->type(), m_touchPosition, ev->button(), ev->buttons(), getEventModifier(m_higlightedPos));
    m_webPage->event(&iev);
}

void GWebTouchNavigation::doubleClickTimerExpired()
{   
    handleMousePressEvent(m_pressEvent);

    delete m_pressEvent;
    m_pressEvent = NULL;
    
    if (m_releaseEvent) {
        handleMouseReleaseEvent(m_releaseEvent);

		//clear release event
		delete m_releaseEvent;
        m_releaseEvent = NULL;
    }
	if (m_doubleClickTimer && m_doubleClickTimer->isActive())
        m_doubleClickTimer->stop();
}

bool GWebTouchNavigation::canDehighlight(QMouseEvent* ev)
 {
    bool checkDehighlight = false;  
    QPoint pt = ev->pos() + m_frame->scrollPosition();
    
    if(m_scrolled && m_ishighlighted) {
        checkDehighlight = true;
    }
    else if(!m_scrolled && m_ishighlighted) {
        QRect rect = m_anchorElement.geometry();

        if(m_anchorElement.geometry().contains(pt)) {
            checkDehighlight = false;
        }
        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;
            }
            else {
                m_offset =0;
                checkDehighlight = true;
            }
        }
        else {
            checkDehighlight = true;
        }
    }
    return checkDehighlight;
}
 void  GWebTouchNavigation::dehighlight(QMouseEvent* ev)
{
    m_higlightedPos = QPoint(0,0);
    m_ishighlighted = false;
    QMouseEvent iev(QEvent::MouseButtonPress,m_higlightedPos,ev->button(), ev->buttons(), ev->modifiers());
    m_webPage->event(&iev);
}

void GWebTouchNavigation::handleHighlightChange(QMouseEvent* ev)
{
    if (!canDehighlight(ev)) return;

    dehighlight(ev);
}

/*!
    Scrolls the frame
    \sa scrollFrame()
*/
void GWebTouchNavigation::mouseMoveEvent(const QPoint& pos, const QPoint& diff)
{
	
    if (m_pressEvent){
    	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;
    }

    stopTimer();
    QMouseEvent tmpEv(QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    handleHighlightChange(&tmpEv);

    scrollFrame(diff);

		//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());

		while (m_dragPoints.size() > 4)
				m_dragPoints.removeFirst();
    
}

/*!
    If WebCanvas or QWebFrame were scrolled starts the deceleration alogrithm
    Otherwise sends the mouse release event to QWebPage
    \sa startDeceleration()
*/
void GWebTouchNavigation::mouseReleaseEvent(const QPoint& pos)
{
    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;
    }
    //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;
    } else {
        QMouseEvent tmpEv(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
        handleMouseReleaseEvent(&tmpEv);    
    }
}
Qt::KeyboardModifier GWebTouchNavigation::getEventModifier(const QPoint& pos)
{
    QWebFrame *frame = m_webPage->frameAt(pos);
    if (!frame)
          frame = m_webPage->currentFrame(); 
    QWebHitTestResult htr = frame->hitTestContent(pos);
    if (htr.element().tagName().toLower().compare("select")==0  && htr.element().hasAttribute("multiple"))
        return Qt::ControlModifier;
    return Qt::NoModifier;
}

void GWebTouchNavigation::handleMouseReleaseEvent(QMouseEvent* ev)
{
    m_frame = m_webPage->frameAt(ev->pos());
    if (!m_frame)
        m_frame = m_webPage->currentFrame(); 
    assert(m_frame);
    
     stopTimer();
     if (m_scrolled) {
        int msecs = 0;
        if (!m_lastMoveEventTime.isNull()) {
            //Start deceleration only if the delta since last drag event is less than threshold
            QTime now(QTime::currentTime());
            msecs = m_lastMoveEventTime.msecsTo(now);
            m_lastMoveEventTime.setHMS(0,0,0,0);
        }
        if (msecs < KDecelerationTimer) {
            if( isFlick()) {
                updateFlickScrollDistance();
            }
            else {
                QRect enclosingRect = findEnclosingBlock(ev);
                QPoint blockDocPt(enclosingRect.x(), enclosingRect.y());
                QPoint blockCanvasPoint(blockDocPt - m_frame->scrollPosition());
                calculateActualScrollDistance();
                int thresholdCheckVal = blockCanvasPoint.x() - m_actualScrollDistance.x();
                setNewScrollDistance(blockCanvasPoint, thresholdCheckVal);
            }
            startScrollTimer();
        }
    } else {
        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);
#if defined __SYMBIAN32__
// 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()) {
                QEvent vkbEvent(QEvent::RequestSoftwareInputPanel);
                QList<QGraphicsView*> views = m_view->scene()->views();
                QWidget* view = qobject_cast<QWidget*>(views.value(0));
                if (view)
                    QApplication::sendEvent(view, &vkbEvent);
            }
        }
#endif
    }
}

void GWebTouchNavigation::mouseDoubleClickEvent(const QPoint& pos)
{
    
    if(m_doubleClickTimer && !m_doubleClickTimer->isActive())
        return;
    else if(m_doubleClickTimer)
        m_doubleClickTimer->stop();

    //If the page is already scrolling(because of a previous doubletap)
    //we need to stop the timer before we start scrolling the new block again.
    if (m_scrollTimer && m_scrollTimer->isActive())
        m_scrollTimer->stop();

    QMouseEvent tmpEv(QEvent::MouseButtonDblClick, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    handleDoubleClickEvent(&tmpEv);
}

void GWebTouchNavigation::handleDoubleClickEvent(QMouseEvent* ev)
{
    QPoint imageFocusPoint;
    QWebHitTestResult hitTest = getHitTestResult(ev);
    
    QWebElement block = hitTest.element();

    if (block.tagName() != "IMG" && (block.styleProperty(QString("background-image"),QWebElement::InlineStyle) == ""))
        block = hitTest.enclosingBlockElement();

    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()));
        m_finalzoomfactor = 0;
	}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();
            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();			

			if( (factorw == 0.0) && (factorh == 0.0))
				;
			else if(factorw == 0.0)
                factor = factorh * m_view->zoomFactor();
			else if(factorh == 0.0)
                factor = factorw * m_view->zoomFactor();
			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;
		}

    
        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
            QSize viewSize = m_webPage->viewportSize();
            QSize contentSize = m_frame->contentsSize();
            QPoint documentViewPoint = QPoint(viewSize.width(),viewSize.height()) + m_frame->scrollPosition();
    		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();
   			}

            m_focusedBlockPt = QPoint(block.geometry().x(), block.geometry().y());
            m_scrollDistance.setX(m_focusedBlockPt.x() - docFocusPoint.x());
            m_scrollDistance.setY(m_focusedBlockPt.y() - docFocusPoint.y());

            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.y() < 0)
        		scrollableDistance.setY(viewStartPoint.y());
    		 else
				scrollableDistance.setY(contentSize.height() - documentViewPoint.y());

			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()));
                //m_scrollDistance.x() < 0 means scroll from left to right
        		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()));
            }
            else
            	m_focusedBlockPt.setY(docFocusPoint.y());
            
            m_focusedBlockPt = m_focusedBlockPt - m_frame->scrollPosition();
            startScrollTimer();
        }
    m_view->setBlockElement(block);
	}
}

/*!
    Returns the next scrollable frame in the frame tree give the x,y position
*/
QWebFrame* GWebTouchNavigation::getNextScrollableFrame(const QPoint& pos)
{
    QWebFrame* frame = m_frame;
    while (frame) {
        if (pos.x() > 0) {
            if (frame->scrollBarValue(Qt::Horizontal) < frame->scrollBarMaximum(Qt::Horizontal))
                break;
        }
        else if (pos.x() < 0) {
            if (frame->scrollBarValue(Qt::Horizontal) > frame->scrollBarMinimum(Qt::Horizontal))
                break;
        }

        if (pos.y() > 0) {
            if (frame->scrollBarValue(Qt::Vertical) < frame->scrollBarMaximum(Qt::Vertical))
                break;
        }
        else if (pos.y() < 0) {
            if (frame->scrollBarValue(Qt::Vertical) > frame->scrollBarMinimum(Qt::Vertical))
                break;
        }
        frame = frame->parentFrame();
    }
    return (frame)?frame:m_webPage->mainFrame();
}

/*
Starts the timer for scrolling smoothly to the destination location .
The timer will do the decelaration while scrolling
*/
void GWebTouchNavigation::startScrollTimer()
{
    if(!m_scrollTimer) {
        m_scrollTimer = new QTimer(this);
        connect(m_scrollTimer,SIGNAL(timeout()),this,SLOT(scrollToEdge()));
    }
    m_scrollTimer->stop();
    m_scrollTimer->start(KAnimationTimeout);
}

/*
Update the scroll distance for flick gesture. Update the scroll distance upto the edge of the page
*/
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());

	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 : 
                    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()));
                    break;
        case UP :
                    m_scrollDistance.setX(0);
                    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()));
                    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 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));
                    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;      
        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);
                    break;
    }
}

/*
Distinguishes b/w swipe and flick
*/
bool GWebTouchNavigation::isFlick() 
{
    bool flick = false;
    QPoint moveSpeed = speed();
    int xSpeed = moveSpeed.x();
    int ySpeed = moveSpeed.y();
     
    flick = (qAbs(xSpeed) > KFlickSpeed || 
             qAbs(ySpeed) > KFlickSpeed);
 
    return flick;
}

/*
Calculates the speed of te scroll along x-axis and y-axis
*/
QPoint GWebTouchNavigation::speed() 
{
    // Speed is only evaluated at the end of the swipe
    QPoint dragSpeed(0,0);
    qreal time =  dragTime() / KMilliSecond;
    if (time > 0) {
        QPoint distance = currentPos() - previousPos();
        dragSpeed.setX((distance.x()) / time);
        dragSpeed.setY((distance.y()) / time);
    }
    return dragSpeed;
}

/*
Returns the last point in the m_dragPoints list
*/
QPoint GWebTouchNavigation::currentPos()
{
    return m_dragPoints[m_dragPoints.size()-1].iPoint;
}

/*
Returns the first point in the m_dragPoints list
*/
QPoint GWebTouchNavigation::previousPos()
{
    return m_dragPoints[0].iPoint;
}

/*
Finds the time difference b/w the first and last dragpoint
*/
qreal GWebTouchNavigation::dragTime() const
{
    if(m_dragPoints.isEmpty())
        return 0.0;
    else
        return  m_dragPoints[0].iTime.msecsTo(m_dragPoints[m_dragPoints.size()-1].iTime);
}

/*!
Find the flick direction with respect to angle of flick
*/
Direction GWebTouchNavigation::findDirectionWithAngle(const QPoint& diff)
{
    Direction direction;
    int xDelta = -diff.x();
    int yDelta = -diff.y();

    qreal angle = findAngle(xDelta, yDelta);
    if(isNear(angle, 60.0, 120.0)) {
         direction = DOWN;
     }
    else if(isNear(angle, 150.0, 210.0)) {
        direction = LEFT;
    }
    else if(isNear(angle, 240.0, 300.0)) {
        direction = UP;
    }
    else if(360.0 - KAngleTolerance <= angle || angle <= KAngleTolerance) {
        direction = RIGHT;
    }
    else if(isNear(angle, 30.0, 60.0)) {
        direction = BOTTOMRIGHT;
    }
    else if(isNear(angle, 120.0, 150.0)) {
        direction = BOTTOMLEFT;
    }
    else if(isNear(angle, 210.0, 240.0)) {
        direction = TOPLEFT;
    }
    else if(isNear(angle, 300.0, 330.0)) {
        direction = TOPRIGHT;
    }

    return direction;
}

/*
Check the angle is in the range of aMinAngle and aMaxAngle
*/
bool GWebTouchNavigation::isNear(qreal angleUnderTest, qreal minAngle, qreal maxAngle)
{
    return (minAngle < angleUnderTest) &&  (angleUnderTest <= maxAngle);
}

/*
Find the angle from x and y displacement
*/
qreal GWebTouchNavigation::findAngle(const int& xDelta,const int& yDelta)
{
    qreal angle = 0;
    qreal hypotenuse = qSqrt(xDelta*xDelta + yDelta*yDelta);

    if(hypotenuse != 0) {
        angle = qAcos(xDelta / hypotenuse);

        if(yDelta < 0) { 
            angle = (2 * PI) - angle;
        }
    }

    return (angle * 180) / PI;
}

int GWebTouchNavigation::roundOff(qreal num) 
{
	return (num + 0.5);
}

/*
Finds out the enclosing block 
*/
QRect GWebTouchNavigation::findEnclosingBlock(QMouseEvent* ev)
{
    QWebHitTestResult htr = getHitTestResult(ev);
    QRect rect = htr.enclosingBlockElement().geometry();
    return rect;
}

/*
Gets the hitTestResult for a particular event
*/
QWebHitTestResult GWebTouchNavigation::getHitTestResult(QMouseEvent* ev)
{
    QPoint pt = ev->pos();
    QWebFrame* frame = m_webPage->frameAt(pt);
    frame = (frame) ? frame : m_webPage->mainFrame();
    QWebHitTestResult htr = frame->hitTestContent(pt);
    return htr;
}

/*
Finds out the scroll distance associated with a swipe 
*/
void GWebTouchNavigation::calculateActualScrollDistance()
{
    m_actualScrollDistance.setX(0);
    m_actualScrollDistance.setY(0);
    if (!m_dragPoints.isEmpty()) {
        QPoint distance = previousPos() - currentPos();
        if (qAbs(distance.x()) > 0 || qAbs(distance.y()) > 0) {
            m_actualScrollDistance = distance / m_dragPoints.size() * 2;
        }
    }
}

/*
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 
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) {
        //Checks whether the block falls within the threshold after right to left swipe
        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) {
                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 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 .
            if (m_actualScrollDistance.x() < 0) {
                m_scrollDistance.setX(blockCanvasPoint.x() - XAlignVal);
            }
        }
        
    }
}


/*
SLOT associated with the timer to adjust the scroll to the edge
*/
void GWebTouchNavigation::scrollToEdge()
{
    m_prevPoint.setX(m_scrollDistance.x());
    m_prevPoint.setY(m_scrollDistance.y());

    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()));

    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)) 
         || ((diffX == 0) && (diffY == 0))) {
        scrollCurrentFrame(m_prevPoint.x(), m_prevPoint.y());
        m_scrollTimer->stop();
        return;
    }
    scrollCurrentFrame(diffX, diffY);
}
void GWebTouchNavigation::timerControl()
{
	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);
}
void GWebTouchNavigation::stopTimer()
{
    if(m_longPressTimer){
            m_longPressTimer->stop();
            delete m_longPressTimer;
            m_longPressTimer = 0;
        }
}
void GWebTouchNavigation::getFocusedElement()
{
	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);
}

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()) {
        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_frame->setScrollPosition(finalPos);
}

void GWebTouchNavigation::onLoadStarted()
{ 
  	m_isLoading = true; 
}
void GWebTouchNavigation::onLoadFinished(bool 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)));
}
}
