browsercore/appfw/Api/Views/webcontentview.cpp
branchGCC_SURGE
changeset 8 2e16851ffecd
parent 2 bf4420e9fa4d
parent 6 1c3b8676e58c
equal deleted inserted replaced
2:bf4420e9fa4d 8:2e16851ffecd
     1 /*
       
     2 * Copyright (c) 2010 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 <QDebug>
       
    20 #include "qwebframe.h"
       
    21 #include <QGraphicsSceneResizeEvent>
       
    22 #include <QGraphicsView>
       
    23 #include <QGraphicsWebView>
       
    24 #include <QNetworkReply>
       
    25 #include <QPainter>
       
    26 #include <QSettings>
       
    27 #include <QWebPage>
       
    28 #include <QWebHistory>
       
    29 #include <qwebelement.h>
       
    30 #include <QGraphicsSceneContextMenuEvent>
       
    31 #include <QTimer>
       
    32 #include <qevent.h>
       
    33 
       
    34 #include "browserpagefactory.h"
       
    35 #include "webcontentview.h"
       
    36 #include "controllableviewjsobject.h"
       
    37 #include "scriptobjects.h"
       
    38 #include "WebViewEventContext.h"
       
    39 
       
    40 #define safe_connect(src, srcSig, target, targetSlot) \
       
    41     { int res = connect(src, srcSig, target, targetSlot); assert(res); }
       
    42 
       
    43 // ----------------------------------------------------------
       
    44 
       
    45 const QString KViewPortWidthTag("width");
       
    46 const QString KViewPortHeightTag("height");
       
    47 const QString KViewPortInitialScaleTag("initial-scale");
       
    48 const QString KViewPortMinScaleTag("minimum-scale");
       
    49 const QString KViewPortMaxScaleTag("maximum-scale");
       
    50 const QString KViewPortUserScalableTag("user-scalable");
       
    51 const QString KViewPortDeviceWidthTag("device-width");
       
    52 const QString KViewPortDeviceHeightTag("device-height");
       
    53 
       
    54 
       
    55 const int KDefaultViewportWidth = 980;
       
    56 const int KDefaultPortraitScaleWidth = 540;
       
    57 const int KMinViewportWidth = 200;
       
    58 const int KMaxViewportWidth = 10000;
       
    59 const int KMinViewportHeight = 200;
       
    60 const int KMaxViewportHeight = 10000;
       
    61 const int KMaxPageZoom = 10;
       
    62 const qreal KDefaultMinScale = 0.25;
       
    63 const qreal KDefaultMaxScale = 10.00;
       
    64 const QPoint KFocussPoint(5, 50);
       
    65 const qreal KZoomInStep = 1.05;
       
    66 const qreal KZoomOutStep = 0.95238;
       
    67 const int checkerSize = 16;
       
    68 const unsigned checkerColor1 = 0xff555555;
       
    69 const unsigned checkerColor2 = 0xffaaaaaa;
       
    70 
       
    71 WebContentView::WebContentView(QWebPage* pg,QWidget *parent)
       
    72   : m_networkMgr(0)
       
    73   ,m_timer(NULL)
       
    74 
       
    75 //, m_flickCharm(0)
       
    76 {
       
    77     qDebug() << "WebContentView::WebContentView";
       
    78     m_widget = new WebContentWidget(parent,this,pg);
       
    79     setZoomActions();
       
    80 
       
    81     m_jsObject = new WebContentViewJSObject(this, 0);
       
    82 
       
    83     m_networkMgr = webView()->page()->networkAccessManager();
       
    84 
       
    85     webView()->page()->currentFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
       
    86     webView()->page()->currentFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
       
    87     
       
    88  
       
    89     connectAll();
       
    90 }
       
    91 
       
    92 void WebContentView::connectAll() {
       
    93 
       
    94     safe_connect(widget(), SIGNAL(contextEvent(WebViewEventContext *)), m_jsObject, SLOT(onContextEvent(WebViewEventContext *)));
       
    95 }
       
    96 
       
    97 WebContentView::~WebContentView() {
       
    98     disconnect(m_jsObject);
       
    99     disconnect(webView());
       
   100 
       
   101     delete m_actionZoomIn;
       
   102     delete m_actionZoomOut;
       
   103 
       
   104     delete m_widget;
       
   105 }
       
   106 
       
   107 QVariant WebContentView::getContentWindowObject() {
       
   108     try {
       
   109         return webView()->page()->mainFrame()->evaluateJavaScript("window");
       
   110     }
       
   111     catch(...) {
       
   112         qDebug() << "WebContentView::getContentWindowObject: caught expection";
       
   113         return QVariant();
       
   114     }
       
   115 }
       
   116 
       
   117 void WebContentView::setZoomActions(){
       
   118 
       
   119     // Create zoomIn and zoomOut actions */
       
   120     m_actionZoomIn = new QAction("zoomIn", this);
       
   121     m_actionZoomIn->setObjectName("zoomIn");
       
   122 
       
   123     m_actionZoomOut = new QAction("zoomOut", this);
       
   124     m_actionZoomOut->setObjectName("zoomOut");
       
   125     /* Disable zoomOut action initially as we are the the minimum scale */
       
   126     /* Revisit this to determine whether we can use the change signal to 
       
   127      * set the zoomOut button image initially as well
       
   128      */
       
   129     m_actionZoomOut->setEnabled(false);
       
   130 
       
   131     connect(m_actionZoomIn, SIGNAL(triggered()), this, SLOT(zoomIn()));
       
   132     connect(m_actionZoomOut, SIGNAL(triggered()), this, SLOT(zoomOut()));
       
   133 
       
   134 
       
   135 }
       
   136 
       
   137 
       
   138 void WebContentView::bitmapZoomStop()
       
   139 {
       
   140     if(m_timer) {
       
   141         m_timer->stop();
       
   142         disconnect(m_timer,SIGNAL(timeout()));
       
   143         delete m_timer;
       
   144         m_timer = NULL;	
       
   145 	}	
       
   146     qreal zoomFactor = m_value * webView()->zoomFactor();
       
   147     ( (zoomFactor+0.001) >= webView()->maximumScale() )? webView()->setZoomFactor(webView()->maximumScale()):webView()->setZoomFactor(zoomFactor);
       
   148     webView()->bitmapZoomCleanup();
       
   149 }
       
   150 
       
   151 void WebContentView::zoomP()
       
   152 {
       
   153     if((m_value * webView()->zoomFactor()) >  webView()->maximumScale()) {
       
   154 	    if(m_timer && m_timer->isActive())
       
   155 		    bitmapZoomStop();
       
   156     }else {
       
   157         if(m_timer->isSingleShot()) {
       
   158             m_timer->setSingleShot(false);
       
   159             m_timer->start(1);
       
   160         }
       
   161 	    webView()->setBitmapZoom(m_value * webView()->zoomFactor());
       
   162 	    m_value *= KZoomInStep;
       
   163     }
       
   164 }
       
   165 
       
   166 void WebContentView::zoomN()
       
   167 {
       
   168     if((m_value * webView()->zoomFactor()) <  webView()->minimumScale()){
       
   169 	    if(m_timer && m_timer->isActive())
       
   170 		    bitmapZoomStop();	
       
   171     }else {
       
   172         if(m_timer->isSingleShot()) {
       
   173             m_timer->setSingleShot(false);
       
   174             m_timer->start(1);
       
   175         }
       
   176         webView()->setBitmapZoom(m_value * webView()->zoomFactor());
       
   177 	    m_value *= KZoomOutStep;
       
   178     }
       
   179 }
       
   180 
       
   181 void WebContentView::zoomIn(qreal deltaPercent)	
       
   182 {	
       
   183     if(webView() && webView()->isUserScalable()) {
       
   184         if(m_timer && m_timer->isActive()) {
       
   185             if(!m_timer->isSingleShot())
       
   186                 m_value /= KZoomInStep;
       
   187 	        bitmapZoomStop();
       
   188 	        return;
       
   189         }else if(!m_timer)
       
   190             m_timer = new QTimer(this);
       
   191   
       
   192         m_value = KZoomInStep;
       
   193 	
       
   194         if( (m_value * webView()->zoomFactor()) <  webView()->maximumScale()) {
       
   195   	        webView()->createPageSnapShot();
       
   196 		    bool ret = connect(m_timer,SIGNAL(timeout()),this,SLOT(zoomP()));
       
   197 		    zoomP();
       
   198             m_timer->setSingleShot(true);
       
   199 		    m_timer->start(500);
       
   200         }else {
       
   201             delete m_timer;
       
   202 	        m_timer = NULL;
       
   203 	        webView()->setZoomFactor(m_value * webView()->zoomFactor());
       
   204         }
       
   205     }   
       
   206 }
       
   207 
       
   208 void WebContentView::zoomOut(qreal deltaPercent)	
       
   209 {
       
   210     if(webView() && webView()->isUserScalable()) {
       
   211         if(m_timer && m_timer->isActive()) {
       
   212             if(!m_timer->isSingleShot())
       
   213 		        m_value /= KZoomOutStep;
       
   214 		    bitmapZoomStop();
       
   215 	        return;
       
   216         }else if(!m_timer)
       
   217 		    m_timer = new QTimer(this);
       
   218  
       
   219         m_value = KZoomOutStep;
       
   220 
       
   221         if( (m_value * webView()->zoomFactor()) >  webView()->minimumScale()) {
       
   222             webView()->createPageSnapShot();
       
   223             bool ret = connect(m_timer,SIGNAL(timeout()),this,SLOT(zoomN()));
       
   224             zoomN();
       
   225             m_timer->setSingleShot(true);
       
   226             m_timer->start(500);
       
   227         }else {
       
   228 	        delete m_timer;
       
   229 	        m_timer = NULL;
       
   230   	        webView()->setZoomFactor(m_value * webView()->zoomFactor());
       
   231         }
       
   232     }
       
   233 }
       
   234 void WebContentView::deactivateZoomActions()
       
   235 {
       
   236 	m_actionZoomOut->setEnabled(false);
       
   237 	m_actionZoomIn->setEnabled(false);
       
   238 }
       
   239 
       
   240 void WebContentView::changeZoomAction(qreal zoom){
       
   241     
       
   242     if(!(webView()->isUserScalable() ) ){
       
   243         deactivateZoomActions();
       
   244     }
       
   245     else {
       
   246 
       
   247         if (zoom <=   webView()->minimumScale() ) {
       
   248            m_actionZoomOut->setEnabled(false); 
       
   249         }
       
   250         else { 
       
   251            m_actionZoomOut->setEnabled(true); 
       
   252         }
       
   253 
       
   254         if (zoom >=  webView()->maximumScale()  ){
       
   255            m_actionZoomIn->setEnabled(false); 
       
   256         }
       
   257         else { 
       
   258            m_actionZoomIn->setEnabled(true); 
       
   259         }
       
   260     }
       
   261 }
       
   262 
       
   263 void WebContentView::setZoomFactor(qreal factor){
       
   264   if(webView())
       
   265       webView()->setZoomFactor(factor);
       
   266 }
       
   267 
       
   268 qreal WebContentView::getZoomFactor() const {
       
   269   return webViewConst() ? webViewConst()->zoomFactor() : 0.0;
       
   270 }
       
   271 
       
   272 
       
   273 
       
   274 
       
   275 void WebContentView::activate() {
       
   276     WebContentViewBase::activate();
       
   277 }
       
   278 
       
   279 void WebContentView::deactivate() {
       
   280     WebContentViewBase::deactivate();
       
   281 }
       
   282 
       
   283 static void appendAction(QWebPage* page, QList<QAction*> &list, enum QWebPage::WebAction webAction, const QString &name) {
       
   284     QAction *action = page->action(webAction);
       
   285     if(action) {
       
   286         action->setObjectName(name);
       
   287         list.append(action);
       
   288     }
       
   289 }
       
   290 
       
   291 /*!
       
   292   Return the list of public QActions most relevant to the view's current context.
       
   293   @return  List of public actions
       
   294 */
       
   295 QList<QAction *> WebContentView::getContext()
       
   296 {
       
   297     // Get some of the actions from the page (there are many more available) and build a list
       
   298     // list of them.  
       
   299 
       
   300     QList<QAction*> actions;
       
   301 
       
   302     /* Add zoomIn and zoomOut actions created earlier*/
       
   303     actions.append(m_actionZoomIn);
       
   304     actions.append(m_actionZoomOut);
       
   305      
       
   306     return actions;
       
   307 }
       
   308 
       
   309 void WebContentView::scrollViewBy(int dx, int dy)
       
   310 {
       
   311     wrtPage()->mainFrame()->scroll(dx, dy);
       
   312 }
       
   313 
       
   314 void WebContentView::scrollViewTo(int x, int y)
       
   315 {
       
   316     wrtPage()->mainFrame()->setScrollPosition(QPoint(x, y));
       
   317 }
       
   318 
       
   319 
       
   320 void WebContentView::showMessageBox(WRT::MessageBoxProxy* proxy)
       
   321 {
       
   322 /*
       
   323     QMessageBox msgBox(this);
       
   324     msgBox.setText(proxy->m_text);
       
   325     msgBox.setInformativeText(proxy->m_informativeText);
       
   326     msgBox.setDetailedText(proxy->m_detailedText);
       
   327     msgBox.setStandardButtons(proxy->m_buttons);
       
   328     msgBox.setDefaultButton(proxy->m_defaultButton);
       
   329     msgBox.setIcon(proxy->m_icon);
       
   330     int ret = msgBox.exec();
       
   331     */
       
   332     QString displayText = proxy->m_text + QLatin1String("\n") + QLatin1String("\n")+ proxy->m_detailedText + QLatin1String("\n") + QLatin1String("\n") + proxy->m_informativeText;
       
   333     int ret = QMessageBox::warning(0/* TODO: find appropriate widget if required or just remove this widget()*/, 
       
   334                                    proxy->m_text, displayText, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
       
   335     proxy->onMessageBoxResponse(ret);
       
   336 }
       
   337 
       
   338 ControllableView* WebContentView::createNew(QWidget *parent) 
       
   339 { 
       
   340     QWebPage* page = BrowserPageFactory::openBrowserPage();
       
   341     return new WebContentView(page, parent);
       
   342 }
       
   343 
       
   344 
       
   345 // ---------------------------------------------------------------------------
       
   346 // WebContentViewJSObject
       
   347 // ---------------------------------------------------------------------------
       
   348 
       
   349 void WebContentViewJSObject::statusBarMessage( const QString & text ){
       
   350     emit onStatusBarMessage(text);
       
   351 }
       
   352 
       
   353 void WebContentViewJSObject::statusBarVisibilityChangeRequested(bool visible){
       
   354     emit onStatusBarVisibilityChangeRequested(visible);
       
   355 }
       
   356 
       
   357 void WebContentViewJSObject::onContextEvent(WebViewEventContext *context){
       
   358     QWebFrame *chrome = chromeFrame();
       
   359     if(chrome) {
       
   360         chrome->addToJavaScriptWindowObject(context->objectName(), context, QScriptEngine::ScriptOwnership);
       
   361     }
       
   362     emit contextEvent(context);
       
   363 }
       
   364 
       
   365 // ---------------------------------------------------------------------------
       
   366 // WebContentWidget
       
   367 // ---------------------------------------------------------------------------
       
   368 void WebContentWidget::updateViewport()
       
   369 {
       
   370     if (page() && size() != page()->viewportSize()) {
       
   371         page()->setViewportSize(size().toSize());
       
   372     }
       
   373     setViewportSize();
       
   374 }
       
   375 
       
   376 void WebContentWidget::setBlockElement(QWebElement pt)
       
   377 {
       
   378 	m_BlockElement = pt;
       
   379 }
       
   380 
       
   381 QImage WebContentWidget::getPageSnapshot()
       
   382 {
       
   383     QImage img(size().toSize(), QImage::Format_RGB32);
       
   384     QPainter painter(&img);
       
   385     QWebFrame *frame = page()->mainFrame();
       
   386 
       
   387     painter.fillRect(0, 0, size().width(), size().height(), QColor(255, 255, 255));
       
   388 //    QTransform transform;
       
   389 //    transform.scale(d->m_pageZoomFactor, d->m_pageZoomFactor);
       
   390 //    painter.translate(-transform.map(frame->scrollPosition()));
       
   391 
       
   392     QRegion clipRegion(QRect(QPoint(0,0),size().toSize()));
       
   393 //    QTransform invert = transform.inverted();
       
   394 //    clipRegion = invert.map(clipRegion);
       
   395 //    clipRegion.translate(frame->scrollPosition());
       
   396 
       
   397 //    painter.scale(d->m_pageZoomFactor, d->m_pageZoomFactor);
       
   398 //    d->m_webPage->mainFrame()->renderContents(&painter, clipRegion);
       
   399     frame->render(&painter, clipRegion);
       
   400 
       
   401     return img;
       
   402 }
       
   403 
       
   404 void WebContentWidget::updateViewportSize(QGraphicsSceneResizeEvent* e)
       
   405 {
       
   406     //if there is change in mode (like landscape, potraite relayout the content)
       
   407     if (e->newSize().width() == e->oldSize().width())
       
   408         return;
       
   409 	m_isResize = true;
       
   410     setViewportSize();
       
   411 	m_isResize = false;
       
   412 }
       
   413 
       
   414 void WebContentWidget::resizeEvent(QGraphicsSceneResizeEvent* e)
       
   415 {
       
   416     // set the fixed text layout size for text wrapping
       
   417     if (page()) {
       
   418 #if defined CWRTINTERNALWEBKIT
       
   419         p->m_webPage->settings()->setMaximumTextColumnWidth(e->newSize().width() - 6);
       
   420 #endif
       
   421     }
       
   422 
       
   423 	m_previousViewPortwidth = page()->viewportSize().width();
       
   424 	
       
   425     const QSize &s = e->newSize().toSize();
       
   426     if (page() && s != page()->viewportSize()) {
       
   427 		if(m_BlockElement.isNull()) {
       
   428 			QPoint pos = QPoint(0,0);
       
   429 			QWebFrame* frame = page()->frameAt(pos);
       
   430 			frame = (frame) ? frame : page()->currentFrame();
       
   431 			QWebHitTestResult htr = frame->hitTestContent(pos);
       
   432 			m_BlockInFocus = htr.element();
       
   433 
       
   434 			if(m_BlockInFocus.tagName() != "IMG")
       
   435 				m_BlockInFocus = htr.enclosingBlockElement();
       
   436 
       
   437 			QPoint position = m_BlockInFocus.geometry().topLeft() - page()->currentFrame()->scrollPosition();
       
   438 			m_Ratiox = (qreal) position.x() / m_BlockInFocus.geometry().width();
       
   439 			m_Ratioy = (qreal) position.y() / m_BlockInFocus.geometry().height();
       
   440 		}
       
   441         page()->setViewportSize(s);
       
   442     }
       
   443 
       
   444     updateViewportSize(e);
       
   445 }
       
   446 
       
   447 void WebContentWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) 
       
   448 {
       
   449     QPoint p = event->pos().toPoint();
       
   450     QWebHitTestResult hitTest = page()->currentFrame()->hitTestContent(p); 
       
   451 
       
   452     WebViewEventContext *context = 
       
   453         new WebViewEventContext(view()->type(), hitTest);
       
   454     
       
   455     emit contextEvent(context);
       
   456     event->accept();
       
   457 }
       
   458 
       
   459 void WebContentWidget::setZoomFactor(qreal zoom)
       
   460 {
       
   461     this->setFocus();
       
   462     if (!m_userScalable)
       
   463         return;
       
   464 
       
   465     setPageZoomFactor(zoom);
       
   466 }
       
   467 
       
   468 void WebContentWidget::setPageZoomFactor(qreal zoom)
       
   469 {
       
   470 
       
   471     //qDebug() << __func__ << "Zoom " << zoom << "Max : " << m_maximumScale << "Min: " << m_minimumScale;
       
   472 
       
   473     if (zoom < m_minimumScale)
       
   474         zoom = m_minimumScale;
       
   475     else if (zoom > m_maximumScale)
       
   476         zoom = m_maximumScale;
       
   477 
       
   478  
       
   479 	QPoint pos = QPoint(0,0);
       
   480 	
       
   481 	if(!m_isResize) {
       
   482 		QWebFrame* frame = page()->frameAt(pos);
       
   483 		frame = (frame) ? frame : page()->currentFrame();
       
   484 		QWebHitTestResult htr = frame->hitTestContent(pos);
       
   485 		m_BlockInFocus = htr.element();
       
   486 
       
   487 		if(m_BlockInFocus.tagName() != "IMG")
       
   488 			m_BlockInFocus = htr.enclosingBlockElement();
       
   489 
       
   490 		QPoint position = m_BlockInFocus.geometry().topLeft() - page()->currentFrame()->scrollPosition();
       
   491 		m_Ratiox = (qreal) position.x() / m_BlockInFocus.geometry().width();
       
   492 		m_Ratioy = (qreal) position.y() / m_BlockInFocus.geometry().height();
       
   493 	}
       
   494     
       
   495     if( m_dirtyZoomFactor != zoom ) {
       
   496         m_dirtyZoomFactor = zoom;
       
   497     }
       
   498 
       
   499     QGraphicsWebView::setZoomFactor( zoom );
       
   500    
       
   501 	if(!m_BlockElement.isNull() && m_isResize) {
       
   502 		QPoint imageFocusPoint;
       
   503 		QPoint m_focusedBlockPt = QPoint(m_BlockElement.geometry().topLeft()) - page()->mainFrame()->scrollPosition(); 
       
   504 		if(m_BlockElement.tagName() != "IMG" && (m_BlockElement.styleProperty(QString("background-image"),QWebElement::InlineStyle) == "")) 
       
   505 			page()->mainFrame()->scroll(m_focusedBlockPt.x() - KFocussPoint.x() , m_focusedBlockPt.y() - KFocussPoint.y());                                    
       
   506 		else {
       
   507 			if((page()->viewportSize().width() - m_BlockElement.geometry().width()) > 0)
       
   508 				imageFocusPoint.setX((page()->viewportSize().width() - m_BlockElement.geometry().width())/2);
       
   509 			else
       
   510 				imageFocusPoint.setX(0);
       
   511 
       
   512 			if((page()->viewportSize().height() - m_BlockElement.geometry().height()) > 0)
       
   513 				imageFocusPoint.setY((page()->viewportSize().height() - m_BlockElement.geometry().height())/2);
       
   514 			else
       
   515 				imageFocusPoint.setY(0);
       
   516 
       
   517 			page()->mainFrame()->scroll(m_focusedBlockPt.x() - imageFocusPoint.x() , 
       
   518 										m_focusedBlockPt.y() - imageFocusPoint.y());
       
   519 			}
       
   520 			m_focusedBlockPt = QPoint(m_BlockElement.geometry().topLeft()) - page()->mainFrame()->scrollPosition();
       
   521 			emit BlockFocusChanged(m_focusedBlockPt);
       
   522 	} else {
       
   523 		QPoint m_focusedBlockPt = QPoint(m_BlockInFocus.geometry().topLeft()) - page()->mainFrame()->scrollPosition(); 
       
   524 		page()->currentFrame()->scroll(m_focusedBlockPt.x() - (m_Ratiox * m_BlockInFocus.geometry().width()),
       
   525 									m_focusedBlockPt.y() - (m_Ratioy * m_BlockInFocus.geometry().height()));
       
   526 		m_BlockElement = QWebElement();
       
   527 	}
       
   528 		
       
   529     m_webContentView->changeZoomAction(zoom);
       
   530     
       
   531 }
       
   532 
       
   533 void WebContentWidget::setDirtyZoomFactor(qreal zoom)
       
   534 {
       
   535     if( m_dirtyZoomFactor == zoom )
       
   536         return;
       
   537 
       
   538     m_dirtyZoomFactor = zoom;
       
   539 
       
   540     update();
       
   541 }
       
   542 
       
   543 
       
   544 void WebContentWidget::setCheckeredPixmap()
       
   545 {
       
   546     delete m_checkeredBoxPixmap;
       
   547     m_checkeredBoxPixmap = NULL;
       
   548     int checkerPixmapSizeX = size().toSize().width();
       
   549     int checkerPixmapSizeY = size().toSize().height() + 50;
       
   550     m_checkeredBoxPixmap = new QPixmap(size().width(), size().height() + 50);
       
   551     QPainter painter(m_checkeredBoxPixmap);
       
   552    
       
   553     for (int y = 0; y < checkerPixmapSizeY; y += checkerSize / 2) {
       
   554         bool alternate = y % checkerSize;
       
   555         for (int x = 0; x < checkerPixmapSizeX; x += checkerSize / 2) {
       
   556             QColor color(alternate ? checkerColor1 : checkerColor2);
       
   557             painter.fillRect(x, y, checkerSize / 2, checkerSize / 2, color);
       
   558             alternate = !alternate;
       
   559         }
       
   560     }
       
   561 }
       
   562 
       
   563 void WebContentWidget::createPageSnapShot()
       
   564 {
       
   565     bitmapZoomCleanup();
       
   566     QRegion clipRegion;
       
   567     QWebFrame *frame = page()->mainFrame();
       
   568     m_bitmapImage = new QImage(size().width() ,size().height(),QImage::Format_RGB32);
       
   569     clipRegion = QRect(QPoint(0,0),size().toSize());
       
   570     QPainter painterImage(m_bitmapImage);
       
   571     painterImage.fillRect(0, 0, size().width(), size().height(), QColor(255, 255, 255));
       
   572     frame->render(&painterImage,clipRegion);
       
   573 }
       
   574 
       
   575 void WebContentWidget::bitmapZoomCleanup()
       
   576 {
       
   577     m_bitmapZoom = false;
       
   578     if(m_bitmapImage) {
       
   579 	    delete m_bitmapImage;
       
   580 		m_bitmapImage = NULL;
       
   581 	}
       
   582 }
       
   583 
       
   584 void WebContentWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) 
       
   585 {
       
   586     //if(!m_active) return;
       
   587     if(m_freezeCount > 0) {
       
   588         // Frozen, paint the snapshot.
       
   589         painter->drawPixmap(0, 0, *m_frozenPixmap);
       
   590     }else {
       
   591         if (m_bitmapZoom) {
       
   592             qreal czf = 1;
       
   593             qreal zoomF = zoomFactor();
       
   594 
       
   595             if( m_bitmapZoomFactor != zoomF )
       
   596                 czf = m_bitmapZoomFactor/zoomF;
       
   597 				
       
   598 	        painter->save();
       
   599 	       
       
   600             if(czf < 1) 
       
   601 		        painter->drawPixmap(QPoint(0,0), *m_checkeredBoxPixmap);
       
   602 	        
       
   603 	        painter->drawImage(QRectF(0,0,size().width() * czf,size().height() * czf), *m_bitmapImage);
       
   604 	        painter->restore();
       
   605         } else if( zoomFactor() == m_dirtyZoomFactor ) {
       
   606             // Cannot use normal QGraphicsWebView paint because have to fill background with white for the phone build
       
   607             // QGraphicsWebView::paintEvent( event);
       
   608             QWebFrame* frame = page()->mainFrame();
       
   609             painter->fillRect(0, 0, size().width(), size().height(), QColor(255, 255, 255));
       
   610             QGraphicsWebView::paint(painter, option, widget);
       
   611         } else {
       
   612             qreal czf = m_dirtyZoomFactor / zoomFactor();
       
   613 
       
   614             QWebFrame* frame = page()->mainFrame();
       
   615 
       
   616             painter->save();
       
   617             painter->fillRect(0, 0, size().width(), size().height(), QColor(255, 255, 255));
       
   618             QTransform transform;
       
   619             transform.scale(czf, czf);
       
   620             //painter.translate(-transform.map(frame->scrollPosition()));
       
   621 
       
   622             QRegion clipRegion = geometry().toRect();
       
   623         
       
   624             if(option && !option->exposedRect.isEmpty())
       
   625                 clipRegion.intersect( option->exposedRect.toRect());
       
   626         
       
   627             QTransform invert = transform.inverted();
       
   628             clipRegion = invert.map(clipRegion);
       
   629             //clipRegion.translate(frame->scrollPosition());
       
   630 
       
   631             painter->scale(czf, czf);
       
   632             //p->m_webPage->mainFrame()->renderContents(&painter, clipRegion);
       
   633             frame->render(painter, clipRegion);
       
   634             painter->restore();   
       
   635         }
       
   636     }
       
   637 }
       
   638  
       
   639 WebContentWidget::WebContentWidget(QObject* parent, WebContentView* view,QWebPage* pg) : QGraphicsWebView(0)    
       
   640 , m_webContentView(view)
       
   641 , m_dirtyZoomFactor(1)
       
   642 , m_frozenPixmap(0)
       
   643 , m_freezeCount(0)
       
   644 , m_wrtPage(0)
       
   645 , m_bitmapZoom(false)
       
   646 , m_pagePixmap(0)
       
   647 , m_isResize(false)
       
   648 , m_currentinitialScale(0)
       
   649 , m_previousViewPortwidth(size().toSize().width())
       
   650 , m_bitmapImage(NULL)
       
   651 , m_checkeredBoxPixmap(NULL)
       
   652 {
       
   653     setParent(parent);
       
   654     if( pg )
       
   655     {
       
   656         setPage(pg);
       
   657     }
       
   658 	m_currentinitialScale = zoomFactor();
       
   659 	connect(page()->mainFrame(), SIGNAL(initialLayoutCompleted()), this, SLOT(setViewportSize()));
       
   660 }
       
   661 
       
   662 WebContentWidget::~WebContentWidget()
       
   663 {
       
   664     if(m_wrtPage) 
       
   665     {
       
   666         m_wrtPage->setView(0);
       
   667         setPage(0);
       
   668     }
       
   669     if(m_bitmapImage)
       
   670 	    delete m_bitmapImage;
       
   671     if(m_checkeredBoxPixmap)
       
   672         delete m_checkeredBoxPixmap;
       
   673 }
       
   674 
       
   675 void WebContentWidget::setPage(QWebPage* pg)
       
   676 {
       
   677     if(m_wrtPage) {
       
   678         m_wrtPage->setView(0);
       
   679     }
       
   680     /* Reset the webview page as well - for its internal clean up */
       
   681     QGraphicsWebView::setPage(pg);    
       
   682      
       
   683     m_wrtPage = pg;
       
   684 
       
   685 }
       
   686 
       
   687 void WebContentWidget::createPagePixmap()
       
   688 {
       
   689     if (m_pagePixmap)
       
   690        delete m_pagePixmap;
       
   691 
       
   692     m_pagePixmap = new QPixmap(size().toSize());
       
   693     QStyleOptionGraphicsItem op;
       
   694     QPainter p(m_pagePixmap);
       
   695     paint(&p,&op,0);
       
   696     p.end();
       
   697 }
       
   698 
       
   699 void WebContentWidget::setBitmapZoom(qreal zoomF) {
       
   700     if (!m_userScalable || (zoomF == zoomFactor()))
       
   701         return;
       
   702     if (zoomF < m_minimumScale)
       
   703         zoomF = m_minimumScale;
       
   704     else if (zoomF > m_maximumScale)
       
   705         zoomF = m_maximumScale;
       
   706 
       
   707     m_bitmapZoom = true;
       
   708     m_bitmapZoomFactor = zoomF;
       
   709     update();
       
   710 }
       
   711 
       
   712 void WebContentWidget::deletePagePixmap()
       
   713 {
       
   714     if (m_pagePixmap) {
       
   715         delete m_pagePixmap;
       
   716         m_pagePixmap = 0;
       
   717     }
       
   718     m_bitmapZoom = false;
       
   719 }
       
   720 
       
   721 void WebContentWidget::setPageCenterZoomFactor(qreal zoom)
       
   722 {
       
   723     //calculating the center of the widget
       
   724     QPoint widgetCenter = rect().center().toPoint();
       
   725     //find the content size before applying zoom
       
   726     QSize docSizeBeforeZoom = page()->mainFrame()->contentsSize();
       
   727 
       
   728     qDebug()<<"setPageCenterZoomFactor() : "<<zoom;
       
   729     setZoomFactor(zoom);
       
   730     //after applying zoom calculate the document size and document center point
       
   731     QSize docSizeAfterZoom = page()->mainFrame()->contentsSize();
       
   732     QPoint docPoint = widgetCenter + page()->mainFrame()->scrollPosition();
       
   733     
       
   734     //calculate the shift in center point after applying zoom
       
   735     int dx = docSizeAfterZoom.width() * docPoint.x() / docSizeBeforeZoom.width();
       
   736     int dy = docSizeAfterZoom.height() * docPoint.y() / docSizeBeforeZoom.height();
       
   737 
       
   738     //move back the shifted center
       
   739     page()->mainFrame()->scroll(dx-docPoint.x(), dy-docPoint.y()); 
       
   740 }
       
   741 
       
   742 void WebContentWidget::initializeViewportParams()
       
   743 {    
       
   744     m_maximumScale = KDefaultMaxScale;
       
   745     m_userScalable = true;
       
   746     m_inferWidthHeight = true;
       
   747 
       
   748     m_aspectRation = size().width() / size().height();
       
   749     m_viewportWidth = KDefaultViewportWidth;
       
   750     m_viewportHeight = (int)size().height();
       
   751 	     
       
   752     if( size().width() < size().height())				//if Portrait 
       
   753     	m_initialScale = size().width() / KDefaultPortraitScaleWidth;
       
   754     else
       
   755     	m_initialScale = size().width() / KDefaultViewportWidth;
       
   756     m_minimumScale = m_initialScale;
       
   757 
       
   758 }
       
   759 
       
   760 /*!
       
   761  * Provides the default values - used when opening a new blank window
       
   762  */ 
       
   763 ZoomMetaData WebContentWidget::defaultZoomData()
       
   764 {    
       
   765     ZoomMetaData data;
       
   766 
       
   767     data.maxScale = KDefaultMaxScale;
       
   768     data.minScale =  KDefaultMinScale;
       
   769     data.userScalable = false;
       
   770 
       
   771     return data;
       
   772 }
       
   773 
       
   774 /*!
       
   775  * Set the viewport Size
       
   776  */ 
       
   777 void WebContentWidget::setViewportSize()
       
   778 {
       
   779     QWebFrame* frame = page()->mainFrame();
       
   780 
       
   781     initializeViewportParams();
       
   782 
       
   783     // TODO: INVESTIGATE: In the case of multiple windows loading pages simultaneously, it is possible
       
   784     // to be calling this slot on a signal from a frame that is not
       
   785     // the frame of the page saved here. It might be better to use 'sender' instead of
       
   786     // page->mainFrame() to get the metaData so that we use the meta data of the corresponding
       
   787     // frame
       
   788     QMap<QString, QString> metaData = frame->metaData();
       
   789     QString viewportTag = metaData.value("viewport");
       
   790     
       
   791     if (!viewportTag.isEmpty()) {
       
   792         QStringList paramList;
       
   793 
       
   794         if (viewportTag.contains(';')) {
       
   795             paramList = viewportTag.split(";", QString::SkipEmptyParts);
       
   796         } else {
       
   797             paramList = viewportTag.split(",", QString::SkipEmptyParts);
       
   798         }
       
   799 
       
   800         int paramCount = 0;
       
   801         while (paramCount < paramList.count()) { 
       
   802             QStringList subParamList = paramList[paramCount].split ('=', QString::SkipEmptyParts);
       
   803             paramCount++;
       
   804             QString viewportProperty = subParamList.front();
       
   805             QString propertyValue = subParamList.back();
       
   806             parseViewPortParam(viewportProperty.trimmed(), propertyValue.trimmed());
       
   807         }    
       
   808     }
       
   809 
       
   810     m_initialScale = qBound(m_minimumScale, m_initialScale, m_maximumScale);
       
   811 
       
   812 #if QT_VERSION < 0x040600
       
   813     page()->setFixedContentsSize(QSize(m_viewportWidth, m_viewportHeight));
       
   814 #else    
       
   815     page()->setPreferredContentsSize(QSize(m_viewportWidth, m_viewportHeight)); 
       
   816 #endif
       
   817 	qreal zoomF = 0.0;
       
   818 	QString str;
       
   819 	if(m_isResize &&  (m_currentinitialScale != zoomFactor())) {
       
   820 		zoomF = ((qreal)(page()->viewportSize().width()-10) * zoomFactor())/(m_previousViewPortwidth-10);
       
   821 		str.setNum(zoomF,'f',2);
       
   822 		zoomF = str.toDouble();
       
   823 		setPageZoomFactor(zoomF);
       
   824 	}
       
   825 	else {
       
   826 		setPageZoomFactor(m_initialScale);
       
   827 	}
       
   828 	m_BlockInFocus = QWebElement();
       
   829 	m_currentinitialScale = m_initialScale;
       
   830 	
       
   831 	setCheckeredPixmap();
       
   832     
       
   833 	// Let the page save the data. Even though it is part of the frame, it is easier to
       
   834     // save the info in the page to avoid parsing the meta data again. 
       
   835     emit pageZoomMetaDataChange(frame, pageZoomMetaData());
       
   836 }
       
   837 
       
   838 qreal WebContentWidget::initialScale() 
       
   839 {
       
   840 	return 	m_initialScale;
       
   841 }
       
   842 
       
   843 void WebContentWidget::parseViewPortParam(const QString &propertyName, const QString &propertyValue)
       
   844 {
       
   845     if (propertyName == KViewPortWidthTag) {
       
   846 	    if (propertyValue == KViewPortDeviceWidthTag) {
       
   847             m_viewportWidth = (int)size().width();
       
   848 		    m_viewportHeight = m_viewportWidth * m_aspectRation;
       
   849 	    }
       
   850         else if(propertyValue == KViewPortDeviceHeightTag) {
       
   851             m_viewportWidth = (int)size().height();
       
   852 		    m_viewportHeight = m_viewportWidth * m_aspectRation;        
       
   853         }
       
   854         else {
       
   855 		    m_viewportWidth = propertyValue.toInt();
       
   856 
       
   857             if (m_viewportWidth < KMinViewportWidth)
       
   858 			    m_viewportWidth = KMinViewportWidth;
       
   859 		    else if (m_viewportWidth > KMaxViewportWidth)
       
   860 			    m_viewportWidth = KMaxViewportWidth;
       
   861 
       
   862             m_viewportHeight = m_viewportWidth * m_aspectRation;
       
   863 	    }
       
   864         m_initialScale = size().width() / m_viewportWidth;
       
   865         if (m_initialScale < KDefaultMinScale || m_initialScale > KDefaultMaxScale)
       
   866             m_initialScale = KDefaultMinScale;
       
   867         m_minimumScale = m_initialScale;
       
   868         m_inferWidthHeight = false;
       
   869     }
       
   870     else if (propertyName == KViewPortHeightTag) {
       
   871 	    if (propertyValue == KViewPortDeviceWidthTag) {
       
   872             m_viewportHeight = (int)size().width();
       
   873 		    m_viewportWidth = m_viewportHeight * m_aspectRation;
       
   874 	    }
       
   875         else if (propertyValue == KViewPortDeviceHeightTag) {
       
   876             m_viewportHeight = (int)size().height();
       
   877 		    m_viewportWidth = m_viewportHeight * m_aspectRation;        
       
   878         }
       
   879         else {
       
   880 		    m_viewportHeight = propertyValue.toInt();
       
   881 
       
   882             if (m_viewportHeight < KMinViewportHeight)
       
   883 			    m_viewportHeight = KMinViewportHeight;
       
   884 		    else if (m_viewportHeight > KMaxViewportHeight)
       
   885 			    m_viewportHeight = KMaxViewportHeight;
       
   886 
       
   887             m_viewportWidth = m_viewportHeight * m_aspectRation;
       
   888 	    }
       
   889         m_initialScale = size().height() / m_viewportHeight;
       
   890         if (m_initialScale < KDefaultMinScale || m_initialScale > KDefaultMaxScale)
       
   891             m_initialScale = KDefaultMinScale;
       
   892         m_minimumScale = m_initialScale;
       
   893         m_inferWidthHeight = false;
       
   894     }
       
   895     else if (propertyName == KViewPortInitialScaleTag) {
       
   896         m_initialScale = propertyValue.toDouble();
       
   897         if (m_inferWidthHeight) {
       
   898             m_viewportWidth = (int)size().width();
       
   899             m_viewportHeight = m_viewportWidth * m_aspectRation;
       
   900         }
       
   901     }
       
   902     else if (propertyName == KViewPortMinScaleTag) {
       
   903         m_minimumScale = propertyValue.toDouble();
       
   904         if (m_minimumScale < 0 
       
   905             || m_minimumScale > KMaxPageZoom
       
   906             || m_minimumScale > m_maximumScale)
       
   907             m_minimumScale = KDefaultMinScale;
       
   908     }
       
   909     else if (propertyName == KViewPortMaxScaleTag) {
       
   910         m_maximumScale = propertyValue.toDouble();
       
   911         if (m_maximumScale < 0 
       
   912             || m_maximumScale > KMaxPageZoom 
       
   913             || m_maximumScale < m_minimumScale)
       
   914 
       
   915             m_maximumScale = KDefaultMaxScale;
       
   916     }
       
   917     else if (propertyName == KViewPortUserScalableTag) {
       
   918         if (propertyValue =="no" || propertyValue =="0")
       
   919 		{
       
   920 			m_userScalable = false;
       
   921 			view()->deactivateZoomActions();
       
   922 		}
       
   923         else
       
   924             m_userScalable = true;
       
   925     }
       
   926 }
       
   927 
       
   928 
       
   929 bool WebContentWidget::isUserScalable()
       
   930 {
       
   931     return m_userScalable;
       
   932 }
       
   933 
       
   934 qreal WebContentWidget::minimumScale()
       
   935 {
       
   936     return m_minimumScale;
       
   937 }
       
   938 
       
   939 qreal WebContentWidget::maximumScale()
       
   940 {
       
   941     return m_maximumScale;
       
   942 }
       
   943 
       
   944 ZoomMetaData WebContentWidget::pageZoomMetaData() {
       
   945 
       
   946     ZoomMetaData data;
       
   947 
       
   948     data.minScale = m_minimumScale;
       
   949     data.maxScale = m_maximumScale;
       
   950     data.userScalable = m_userScalable;
       
   951 
       
   952     return data;
       
   953 }
       
   954 
       
   955 void WebContentWidget::setPageZoomMetaData(ZoomMetaData data) {
       
   956 
       
   957     m_minimumScale = data.minScale ;
       
   958     m_maximumScale = data.maxScale ;
       
   959     m_userScalable = data.userScalable;
       
   960 }
       
   961 
       
   962 QWebPage* WebContentWidget::page() const
       
   963 {
       
   964     if (!m_wrtPage) {
       
   965         WebContentWidget* that = const_cast<WebContentWidget*>(this);
       
   966         that->setPage(BrowserPageFactory::openBrowserPage());
       
   967     }
       
   968     return m_wrtPage;
       
   969 }
       
   970 
       
   971 QPointF WebContentWidget::mapToGlobal(const QPointF& p)
       
   972 {
       
   973     QList<QGraphicsView*> gvList = scene()->views();
       
   974     QList<QGraphicsView*>::iterator it;
       
   975     for(it = gvList.begin(); it != gvList.end(); it++) 
       
   976         {
       
   977             if (static_cast<QGraphicsView*>(*it)->hasFocus()) 
       
   978                 {
       
   979                     QWidget* viewport = static_cast<QGraphicsView*>(*it)->viewport();
       
   980                     return viewport->mapToGlobal(mapToScene(p).toPoint());
       
   981                 }
       
   982         }
       
   983 
       
   984     return QPoint(0, 0);
       
   985 }
       
   986 
       
   987 QPointF WebContentWidget::mapFromGlobal(const QPointF& p)
       
   988 {
       
   989     QList<QGraphicsView*> gvList = scene()->views();
       
   990     QList<QGraphicsView*>::iterator it;
       
   991     for(it = gvList.begin(); it != gvList.end(); it++) 
       
   992         {
       
   993             if (static_cast<QGraphicsView*>(*it)->hasFocus()) 
       
   994                 {
       
   995                     QWidget* viewport = static_cast<QGraphicsView*>(*it)->viewport();
       
   996                     return mapFromScene(viewport->mapFromGlobal(p.toPoint()));
       
   997                 }
       
   998         }
       
   999 
       
  1000     return QPoint(0, 0);
       
  1001 }
       
  1002 
       
  1003 void WebContentWidget::setTextSizeMultiplier(qreal factor)
       
  1004 {
       
  1005     page()->mainFrame()->setTextSizeMultiplier(factor);
       
  1006 }
       
  1007