browsercore/appfw/Api/Views/mostvisitedpagestore.cpp
author hgs
Fri, 15 Oct 2010 17:30:59 -0400
changeset 16 3c88a81ff781
parent 9 b39122337a00
permissions -rw-r--r--
201041

/*
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 2.1 of the License.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, 
* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
*
* Description:
*
*/

#include <QtGui>

#include "mostvisitedpagestore.h"
#include "bedrockprovisioning.h"
#include "wrtbrowsercontainer.h"
#include "webpagecontroller.h"
#include "HistoryManager.h"

const QString KMostVistedStoreFile = "mostvisitedpages.dat";
const uint KMostVistedStoreVersion = 1;
const uint KMostVistedStoreLimit = 6;

const QString KDefaultPage1 = "http://www.nytimes.com/";
const QString KDefaultPage2 = "http://news.google.com/";
const QString KDefaultPage3 = "http://www.nokia.com/";
const QString KDefaultPage4 = "http://www.meego.com/";
const QString KDefaultPage5 = "http://www.cnn.com/";
const QString KDefaultPage6 = "http://www.iltalehti.fi/etusivu/";

MostVisitedPage::MostVisitedPage()
    : m_pageThumbnail(0)
    , m_pageRank(0)
{
}

MostVisitedPage::MostVisitedPage(QString url, QImage *pageThumbnail, uint pageRank)
    : m_url(url)
    , m_pageThumbnail(pageThumbnail)
    , m_pageRank(pageRank)
{

}

MostVisitedPage::~MostVisitedPage()
{
    delete m_pageThumbnail;
}

QDataStream& operator<<(QDataStream &out, const MostVisitedPage &page)
{
    //Writing pattern is as follows
    //URL
    //false or (true & Image)
    //pageRank


    //write page data to stream
    out << page.m_url;
    //check if page thumbnail is avilable, store the availability too
    if (!page.thumbnailAvailable())
        out << false;
    else {
        //this is needed to get the correct offset while reading
        out << true << *page.m_pageThumbnail;
    }
    out << page.m_pageRank;
    return out;
}

QDataStream& operator>>(QDataStream &in, MostVisitedPage &page)
{
    //Reading pattern is as follows
    //URL
    //false or (true & Image)
    //pageRank

    //read page data from stream
    in >> page.m_url;
   
    bool hasThumbnail = false;
    in >> hasThumbnail;

    if (hasThumbnail) {
        page.m_pageThumbnail = new QImage();
        in >> *page.m_pageThumbnail;
    }

    in >> page.m_pageRank;

    return in;
}


MostVisitedPageStore::MostVisitedPageStore()
        : m_needPersistWrite(false) 
{
    // initialize the dir used to store bookmarks
#ifndef QT_NO_DESKTOPSERVICES
        m_mvpFile = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/" + KMostVistedStoreFile;
        #ifdef Q_WS_MAEMO_5	
        	QString databaseDir = BEDROCK_PROVISIONING::BedrockProvisioning::createBedrockProvisioning()->valueAsString("DataBaseDirectory");
    			m_mvpFile = databaseDir + KMostVistedStoreFile;
    		#endif
#else
        m_mvpFile =  = QDir::homePath() + "/" +KMostVistedStoreFile;  
#endif

    readStore(); 
    
    //#ifdef Q_WS_MAEMO_5
    // Note: this should be done by the owner of the MostVisitedPageStore object.
    WebPageController* pageController = WebPageController::getSingleton();
    connect(pageController, SIGNAL(loadFinished(const bool)), this, SLOT(onLoadFinished(const bool)));
    connect(WRT::HistoryManager::getSingleton(),SIGNAL(historyCleared()),this,SLOT(clear()));
    //#endif

}


void MostVisitedPageStore::clear()
{
    for (int i = m_pageList.size() - 1; i >= 0; --i)
        delete m_pageList.takeAt(i);
    
    //deleting MVP file
    QFile file(m_mvpFile);
    file.remove();

    //create default thumbnails
    initializeDefaultPageThumbnails();
}

MostVisitedPageStore::~MostVisitedPageStore()
{
    writeStore();
    for (int i = m_pageList.size() - 1; i >= 0; --i)
        delete m_pageList.takeAt(i);
}

void MostVisitedPageStore::pageAccessed(const QUrl& url, QImage* pageThumbnail, int pageRank)
{
    QString accessedHost = url.host();
    int found = -1;

    for (int i = 0; i < m_pageList.size(); ++i) {
        MostVisitedPage* page = m_pageList[i];
        QUrl localUrl = page->m_url;
        QString localUrlHost = localUrl.host();
        if (compareUrls(localUrlHost, accessedHost)) {
            page->m_pageRank = pageRank;
            // move it up if needed
            int j = i;
            // '<=' is for the last access sorting, recently used items move up
            while (--j >= 0 && page->m_pageRank >= m_pageList.at(j)->m_pageRank)
                ;
            // position adjusting and check whether we really moved
            if (++j != i) 
                m_pageList.move(i, j);
            found = j;
            break;
        }
    }
    
    if (found == -1) {
        // insert to the top of the 1 refcount items. recently used sort
        int i = -1;
        while (++i < m_pageList.size() && m_pageList.at(i)->m_pageRank > pageRank)
            ;
        
        //if this page is not fitting in MV list, delete thumbnail passed
        if (i == m_pageList.size()) {
            delete pageThumbnail;
            return;
        }

        m_pageList.insert(i, new MostVisitedPage(url.toString(), pageThumbnail, pageRank));

        //check if we have crossed the store limit and remove last item if so
        if (m_pageList.size() > KMostVistedStoreLimit) {
            delete m_pageList.takeLast();
        }
    } else if (pageThumbnail) {
        // add thumbnail, delete if it has any old thumbnail
        
        //This check is specifically added to take into account of
        //future code changes if thumbnail gets assigned somewhere else
        if (m_pageList[found]->m_pageThumbnail) {
            delete m_pageList[found]->m_pageThumbnail;
        }
        
        m_pageList[found]->m_pageThumbnail = pageThumbnail;
    }
		m_needPersistWrite = true;    
    writeStore();
}

bool MostVisitedPageStore::contains(const QString& url, bool checkThumbnail)
{
    if (!url.size())
        return false;
    
    QUrl accessUrl(url);
    QString accessedHost = accessUrl.host();

    for (int i = 0; i < m_pageList.size(); ++i) {
        QUrl localUrl = m_pageList[i]->m_url;
        QString localUrlHost = localUrl.host();

        if (compareUrls(localUrlHost, accessedHost) 
                && (!checkThumbnail
                    || (checkThumbnail && m_pageList.at(i)->thumbnailAvailable()))) {
            return true;
        }
    }
    return false;
}

MostVisitedPage *MostVisitedPageStore::pageAt(int index)
{
    if (index < 0 || index >= m_pageList.size())
        return 0;

    return m_pageList.at(index);

}

bool MostVisitedPageStore::compareUrls(QString& url1, QString &url2)
{
    // www.nytimes.com == www.nytimes.com
    if (url1 == url2)
        return true;

    // www.nytimes.com == nytimes.com
    if ((url1.startsWith("www.") && url1.mid(4) == url2) || 
        (url2.startsWith("www.") && url2.mid(4) == url1))
        return true;
    return false;
}

void MostVisitedPageStore::readStore()
{
    QFile file(m_mvpFile);
     
     
    
   	#ifndef Q_WS_MAEMO_5
   	if(!file.exists()){
    	file.copy("Z:/Private/10008d39/localpages/mostvisitedpages.dat", "C:/Private/10008d39/mostvisitedpages.dat"); // will be replaced by value from .ini file
    }
   	#endif
   
    if (file.open(QFile::ReadOnly)) {
        QDataStream in(&file);   
        //Check the store version.
        uint version;
        in>>version;

        if (version == KMostVistedStoreVersion ) {
            while (!in.atEnd()) {
                MostVisitedPage *mvPage = new MostVisitedPage();
                in>>*mvPage;
                m_pageList.append(mvPage);
            }
        }
        file.close();
    }   	
    
    
    initializeDefaultPageThumbnails();
}

void MostVisitedPageStore::writeStore()
{  
    //if only store is modified then save it.
    
    bool enabled = (bool) BEDROCK_PROVISIONING::BedrockProvisioning::createBedrockProvisioning()->valueAsInt("SaveHistory");    	
    
    if ((!m_needPersistWrite) || (!enabled))
        return;

    // save url store
    // version
    // url, thumbnail, rank
    QFile file(m_mvpFile);

    if (file.open(QFile::WriteOnly | QIODevice::Truncate)) {
        QDataStream out(&file);
        out<<KMostVistedStoreVersion;
        for (int i = 0; i < m_pageList.size(); ++i) {
            out<<*m_pageList[i];
        }
        file.close();
    } 
    m_needPersistWrite = false;
}

void MostVisitedPageStore::initializeDefaultPageThumbnails() 
{
    if (!m_pageList.isEmpty()) 
        return;
    
    
    m_pageList.append(new MostVisitedPage(KDefaultPage1));
    m_pageList.append(new MostVisitedPage(KDefaultPage2));
    m_pageList.append(new MostVisitedPage(KDefaultPage3));
    m_pageList.append(new MostVisitedPage(KDefaultPage4));
    m_pageList.append(new MostVisitedPage(KDefaultPage5));
    m_pageList.append(new MostVisitedPage(KDefaultPage6));
}


void MostVisitedPageStore::onLoadFinished(const bool ok)   // slot
{
	 //#ifdef Q_WS_MAEMO_5
    if (ok) {
       WRT::WrtBrowserContainer * activePage = WebPageController::getSingleton()->currentPage();
       update(activePage);
    }
   //#endif
  
}

void MostVisitedPageStore::update(WRT::WrtBrowserContainer *page) 
{
	//#ifdef Q_WS_MAEMO_5
    Q_ASSERT(page);
    //Q_ASSERT(!page->mainFrame()->url().isEmpty());

    // Url is empty on history loads. Do not add it to most visited in this case.
    if(page->mainFrame()->url().isEmpty())
        return;

    QUrl pageUrl = page->mainFrame()->url();
    int pageRank = 0;
    QImage* pageThumbnail = NULL;
    //check if page exists in store along with its thumbnail
    if (!contains(pageUrl.toString(), true)) {
        QImage img = page->pageThumbnail(0.30375, 0.30375);
        pageThumbnail = new QImage(img);        
    }

    //if it is a new page to the store, get its rank from history
    //FIX ME : need to optimize this code
    pageRank = WRT::HistoryManager::getSingleton()->getPageRank(pageUrl.toString());
    pageAccessed(pageUrl, pageThumbnail, pageRank);
    // #endif
}