browsercore/core/wrtbrowsercontainer.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 04 May 2010 12:39:35 +0300
changeset 0 1450b09d0cfd
child 3 0954f5dd2cd0
child 5 0f2326c2a325
permissions -rw-r--r--
Revision: 201015 Kit: 201018

/*
* 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 "browserpagefactory.h"
#include "webcontentview.h"
#include "wrtpage.h"
#include "wrtbrowsercontainer_p.h"
#include "wrtbrowsercontainer.h"
#include "webpagedata.h"
#include "qwebhistory.h"
#include "qwebframe.h"
#include "SchemeHandlerBr.h"
#include "webnetworkaccessmanager.h"
#ifdef QT_MOBILITY_BEARER_MANAGEMENT
#include "WebNetworkConnectionManager.h"
#endif // QT_MOBILITY_BEARER_MANAGEMENT
#include "webcookiejar.h"
#include "webnavigation.h"
#include "secureuicontroller.h"
#include "LoadController.h"
#include "WebDialogProvider.h"
#include "bedrockprovisioning.h"
#include <QPainter>
#include <QAuthenticator>
#include <QFile>
#include <QMessageBox>

namespace WRT
{

const int historyItemsCount = 20;

WrtBrowserContainerPrivate::WrtBrowserContainerPrivate(QObject* parent,
		WrtBrowserContainer* page/*never NULL*/) : m_schemeHandler(new SchemeHandler())
,   m_pageFactory(0)
,   m_widget(0)
{
    assert(page);
    m_page = page;

    m_secureController = new WRT::SecureUIController(parent);
    m_loadController = new  WRT::LoadController();
 
    // Turn off the scroll bars of main frame
    m_page->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
    m_page->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
    
}

WrtBrowserContainerPrivate::~WrtBrowserContainerPrivate()
{
	m_page->setView(0);
	if (m_page)
		m_page->disconnect();
	delete m_schemeHandler;
  delete m_secureController;
  delete m_loadController;
}

/*!
 * Static function which creates Wrt page with parent Widget
 * @param parent   : parent widget for the new page
 * @return WrtBrowserContainer : Page handle to the newly created page
 */
WrtBrowserContainer* WrtBrowserContainer::createPageWithWidgetParent(
		QObject* parent, WrtBrowserContainer* page)
{
    if (page)
    {
        page->setParent(parent);
        return page;
    }
    else
        return new WrtBrowserContainer(parent);
}

/*!
 * \class WrtBrowserContainer
 * \brief Description: This class is a handle to open page on which user can
 * load an url , view history items, load an history item into the page etc.
 * @see WrtPageManager
 */

/*!
 * WrtBrowserContainer Constructor
 * @param parent : Widget parent
 */
WrtBrowserContainer::WrtBrowserContainer(QObject* parent) :
	WrtPage(parent), d(new WrtBrowserContainerPrivate(this, this))
{
	// Download related enable "forwardUnsupportedContent" to redirect unsupported content to download manager
	setForwardUnsupportedContent(true);

#ifndef NO_NETWORK_ACCESS_MANAGER	
	setNetworkAccessManager(new WebNetworkAccessManager(this,this));
#endif
	
#ifdef QT_MOBILITY_BEARER_MANAGEMENT
	setNetworkConnectionManager(new WebNetworkConnectionManager(this));
#endif // QT_MOBILITY_BEARER_MANAGEMENT
	history()->setMaximumItemCount(historyItemsCount);

	connect(this,
			SIGNAL(saveFrameStateRequested(QWebFrame*, QWebHistoryItem*)),
			this, SLOT(savePageDataToHistoryItem(QWebFrame*, QWebHistoryItem*)));

    /* Connect secure related signals and slots */
    connect(mainFrame(), SIGNAL(urlChanged(QUrl)), d->m_secureController, SLOT(setTopLevelScheme(const QUrl &)));
    connect(this, SIGNAL(loadFinished(bool)), d->m_secureController, SLOT( endSecureCheck(bool) ) );
    connect(d->m_secureController, SIGNAL(pageSecureState(int)), this, SLOT(pageSecureState(int)));
    connect(networkAccessManager(), SIGNAL(sslErrors(QNetworkReply *, const QList<QSslError> &)), d->m_secureController, SLOT(onSslErrors(QNetworkReply *, const QList<QSslError> &)));

    connect(this, SIGNAL(loadStarted()), d->m_loadController, SLOT(loadStarted()));
    connect(this, SIGNAL(loadProgress(int)), d->m_loadController, SLOT(loadProgress(int)));
    connect(this, SIGNAL(loadFinished(bool)), d->m_loadController, SLOT(loadFinished(bool)));
    connect(mainFrame(), SIGNAL(urlChanged(QUrl)), d->m_loadController, SLOT(urlChanged(QUrl)));
    
	// All pages in the browser share the same pageGroup.
	d->m_pageGroupName = "nokia_page_group";
	setPageGroupName(d->m_pageGroupName);
}

/*!
 * WrtBrowserContainer destructor
 */
WrtBrowserContainer::~WrtBrowserContainer()
{
	// gracefully but warn, disconnect anything connected to this page
	if (!disconnect())
		qWarning("WrtPage destructor blanket disconnect failed");

    //setNetworkAccessManager(NULL);
   delete d;
}

QGraphicsWidget* WrtBrowserContainer::webWidget() const
{
    return d->m_widget;
}

void WrtBrowserContainer::setWebWidget(QGraphicsWidget* view)
{
    if(d->m_widget) {
        disconnect(static_cast<WebContentWidget*>(webWidget()), SIGNAL(pageZoomMetaDataChange(QWebFrame*, ZoomMetaData)), this, SLOT(pageZoomMetaDataChange(QWebFrame*, ZoomMetaData)));
    }

    d->m_widget = view;

    if (view)
    {
        QGraphicsWebView* webView = static_cast<QGraphicsWebView*>(view);
        if(webView)
            webView->setPage(this);

        /* Currently connecting it here. Need to revisit if the dialog is enabled in the
         * context of multiple windows */
        connect( d->m_secureController, SIGNAL( showMessageBox(WRT::MessageBoxProxy*)), static_cast<WebContentWidget*>(webWidget())->view(), SLOT( showMessageBox(WRT::MessageBoxProxy*)));

        connect(static_cast<WebContentWidget*>(webWidget()), SIGNAL(pageZoomMetaDataChange(QWebFrame*, ZoomMetaData)), this, SLOT(pageZoomMetaDataChange(QWebFrame*, ZoomMetaData)));
    }
}
 
/*!
 * Handles pageSecureState state 
 */
void WrtBrowserContainer::pageSecureState(int state) {

    emit secureStateChange(state);

}

/*!
 * Returns schemeHandler
 */
SchemeHandler* WrtBrowserContainer::schemeHandler() const
{
   return d->m_schemeHandler;
}

/*!
 * Gets the history count for this page, i.e gets the number of urls loaded
 * onto this page
 * @return  History count of this page
 */
int WrtBrowserContainer::getHistoryCount() const
{
	return history()->count();
}

/*!
 * Triggers public Action
 * @param WebAction : web action to be triggred
 * @param checked  : true/false
 * @see   WebAction
 */
/*void WrtBrowserContainer::triggerAction(QWebPage::WebAction action, bool checked)
 {
 triggerAction(action, checked);
 }
 */

/*!
 * clears cookies
 */
void WrtBrowserContainer::clearCookies()
{
	return ((CookieJar*) networkAccessManager()->cookieJar())->clear();
}

bool WrtBrowserContainer::clearNetworkCache()
{
   bool ok = false;
    QAbstractNetworkCache* diskCache = networkAccessManager()->cache();
    diskCache->clear();
    if (!diskCache->cacheSize()) { 
       // Unless there was failures clearing the cache cacheSize() should return 0 after a call to clear 
       ok = true;
   }
   return ok;
}

/*!
 * This function page thumbnail for this page as specified by X & Y co-ordinate scale factors
 * @param  scaleX :  X Co-ordinate scale factor for the page thumbnail
 * @param  scaleY :  y Co-ordinate scale factor for the page thumbnail
 */
QImage WrtBrowserContainer::pageThumbnail(qreal scaleX, qreal scaleY)
{
    qDebug() << "WrtBrowserContainer::pageThumbnail:" << webWidget()->size();
    QSize size = webWidget()->size().toSize();
    QImage image(size, QImage::Format_RGB32);

    QPainter painter(&image);
    QRect r(0, 0, size.width(), size.height());
    QRegion clip(r);
    painter.save();
    painter.setBrush(Qt::white);
    painter.drawRect(r);
    painter.restore();
    mainFrame()->render(&painter, clip);
    return image;
}

/*!
 * sets the page zoom factor as specified by zoom
 * @param zoom : page zoom factor to be set
 */
void WrtBrowserContainer::setPageZoomFactor(qreal zoom)
{
   // FiX ME ... canvas zoom doesn't seem to support text-only zooming.
   //static_cast<WebCanvasWidget*>(webWidget())->canvas()->setPageZoomFactor(zoom);

	bool isZoomTextOnly = BEDROCK_PROVISIONING::BedrockProvisioning::createBedrockProvisioning()->value(
			"ZoomTextOnly").toBool();

	if (!isZoomTextOnly)
	{
		// mainFrame()->setZoomFactor(zoom);
		static_cast<WebContentWidget*> (webWidget())->setZoomFactor(zoom);
	}
	else
	{
		//mainFrame()->setTextSizeMultiplier(zoom);
		static_cast<WebContentWidget*> (webWidget())->setTextSizeMultiplier(
				zoom);
    }
}

/*!
 * setpageDirtyZoomFactor
 * @param zoom: page zoom factor to be set
 */
void WrtBrowserContainer::setPageDirtyZoomFactor(qreal zoom)
{
   // FIXME: dirty page zoom is not supported yet in single-buffer mode.
   static_cast<WebContentWidget*> (webWidget())->setDirtyZoomFactor(zoom);
}

/*!
 * setpageCenterZoomFactor
 * @param zoom: center page zoom factor to be set
 */
// TODO: hold on this change until zoom/scrolling improvement 
/*
 void WrtBrowserContainer::setPageCenterZoomFactor(qreal zoom)
 {
 static_cast<WebCanvasWidget*>(webWidget())->canvas()->setPageCenterZoomFactor(zoom);
 }
 */
/*!
 * returns the current page zoom factor of this page
 * @return current zoom factor
 */
qreal WrtBrowserContainer::pageZoomFactor() const
{
   return static_cast<WebContentWidget*> (webWidget())->zoomFactor();
}

/*!
 * sets the Canvas ScaleFactor  for this page
 * @param  scaleX :  X Co-ordinate scale factor
 * @param  scaleY :  Y Co-ordinate scale factor
 */
void WrtBrowserContainer::setCanvasScaleFactor(qreal scaleX, qreal scaleY)
{
   QTransform transform;
   transform.scale(scaleX, scaleY);
   //     static_cast<ContentView*>(webWidget())->setTransform(transform);
}

/*!
 * allows offlineStorage for url
 * @param url : url for which offlinestorage has to be enabled
 */
bool WrtBrowserContainer::allowOfflineStorage(const QUrl& url)
{
   if (BEDROCK_PROVISIONING::BedrockProvisioning::createBedrockProvisioning()->value("SecurityLevel").toInt()
         != SecurityHigh)
      return true;

	QStringList yesno;
	yesno << "Yes" << "No";
	return (WebDialogProvider::getButtonResponse(
			0, /* webWidget(), Check, that widget is required */
			QString(
					"Offline Database: This host asking for storing data in offline database, allow?"),
			yesno));
}


/*!
 Pulic Slots:
 void savePageDataToHistoryItem(QWebFrame*, QWebHistoryItem* item);
 void slotAuthenticationRequired(QNetworkReply *, QAuthenticator *);
 void slotProxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
 */

/*!
 * Public slot, saves the page data (like thumbail, current position, zoom factor etc ) to WebHistoryItem
 * @frame  main frame for which the data has to be stored
 * @item   handle to QWebHistoryItem into which the page data has to be saved.
 */

void WrtBrowserContainer::savePageDataToHistoryItem(QWebFrame* frame,
      QWebHistoryItem* item)
{
    if (frame != mainFrame() || !item->isValid() || !webWidget())
    {
        return;
    }
    if (restoreSession()) return;
    	
    WebPageData data(this);
    //   WebPageData data = item->userData().value<WebPageData>();
    data.m_zoomFactor = pageZoomFactor();
    data.m_thumbnail = pageThumbnail(1.0, 1.0);//data.m_zoomFactor, data.m_zoomFactor);

    QPoint pos(0, 0);
    //    pos = static_cast<WebCanvasWidget*>(webWidget())->canvas()->canvasToDocument(pos);
    pos = mainFrame()->scrollPosition();
    data.m_contentsPos = pos;
    QVariant variant;
    variant.setValue(data);
    item->setUserData(variant);
    //ii++;
}

/*!
 * Public slot  AuthenticationRequired
 * Launches dialog for user name and password if Authentication is required for page load.
 * @param reply     : network reply
 * @param  athenticator : athenticator
 */
void WrtBrowserContainer::slotAuthenticationRequired(QNetworkReply* reply,
      QAuthenticator* authenticator)
{
	QString username, password;
	if (WebDialogProvider::getUsernamePassword(0/*webWidget()*/, username, password))
	{
		authenticator->setUser(username);
		authenticator->setPassword(password);
    }
}

/*!
 * public slot for setting proxy when Authentication is Required
 * @param networkProxy : network Proxy
 * @param authenticator : authenticator
 */
void WrtBrowserContainer::slotProxyAuthenticationRequired(
      const QNetworkProxy& networkProxy, QAuthenticator* authenticator)
{
	QString username, password;
	if (WebDialogProvider::getUsernamePassword(0/*webWidget()*/, username, password))
	{
		authenticator->setUser(username);
		authenticator->setPassword(password);
    }
}

QWebPage* WrtBrowserContainer::createWindow(
    QWebPage::WebWindowType webWindowType)
{

    /* When WrtPage is created, QWebSettings::JavascriptCanOpenWindows is initialized
     * to popup setting value. Need not do any check here 
     */
    if (d->m_pageFactory)
    {
        // no need to signal in this case
        return d->m_pageFactory->openPage();
    }

    WrtBrowserContainer* wrtPage = new WrtBrowserContainer();
    emit createNewWindow(wrtPage);
    return wrtPage;
}

void WrtBrowserContainer::setPageFactory(BrowserPageFactory* f)
{
    d->m_pageFactory = f;
}

void WrtBrowserContainer::setElementType(
      wrtBrowserDefs::BrowserElementType& aElType)
{
    m_elementType = aElType;
}
wrtBrowserDefs::BrowserElementType WrtBrowserContainer::getElementType()
{
   return m_elementType;
}

QString WrtBrowserContainer::pageTitle(){

    QString title = mainFrame()->title();
    
    // If mainFrame title is empty we may be restoring session
    // Check history title
    if (title.isEmpty()){ 
    	title = history()->currentItem().title();
    }
    
    /* If there is no title, provide the partial url */
    if (title.isEmpty()) {
        QUrl url  = mainFrame()->url(); 
        // If mainframe url is empty, we may be restoring session
        // check history url
        if (url.isEmpty()) {
        	url = history()->currentItem().url();
        }
        title = url.toString();
        QString scheme=url.scheme();
        title.remove(0, scheme.length() + 3); // remove "scheme://"
        if (title.startsWith("www.", Qt::CaseInsensitive)) {
            title.remove(0, 4);
        }

    }
    return title;
}

int WrtBrowserContainer::secureState() {

    return d->m_secureController->secureState();
}
bool WrtBrowserContainer::restoreSession() {
	if (d->m_pageFactory)
    return d->m_pageFactory->m_bRestoreSession;
  else
    return true;
}

bool WrtBrowserContainer::emptyWindow() {

    bool result= false;
    if (mainFrame()->title()  == "" && mainFrame()->url().toString() == "" )
        result = true;

    return result;
}

void WrtBrowserContainer::pageZoomMetaDataChange(QWebFrame* frame,  ZoomMetaData  zoomData ){

    //qDebug() << __func__ << "Frame " << frame << "My Frame " << mainFrame();
    if (frame == mainFrame()) {
        setPageZoomMetaData(zoomData);
    } 
}

ZoomMetaData WrtBrowserContainer::pageZoomMetaData() {
    return d->m_zoomData ;

}
void WrtBrowserContainer::setPageZoomMetaData( ZoomMetaData  zoomData ){

    d->m_zoomData = zoomData;
}


}