webengine/webkitutils/HistoryProvider/HistoryController.cpp
changeset 0 dd21522fd290
child 5 10e98eab6f85
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/webkitutils/HistoryProvider/HistoryController.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,622 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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:  Implementation of HistoryController
+*
+*/
+
+
+// INCLUDE FILES
+#include <../bidi.h>
+#include "HistoryController.h"
+#include "BrCtlDefs.h"
+#include "HistoryView.h"
+#include "HistoryEntry.h"
+#include "BrCtlDialogsProvider.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ============================= CLASSES METHODS===============================
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+EXPORT_C HistoryControllerInterface* HistoryController::initWithCallback( HistoryCallback* historyCallback,
+                                                      bool historyAllowed, bool backListAllowed )
+{
+    HistoryController* self = new HistoryController(historyCallback, historyAllowed, backListAllowed);
+    return self;
+}
+
+
+HistoryController::~HistoryController()
+{
+    clearHistoryList();
+}
+
+/**
+*/
+void HistoryController::insert( const TPtrC8& url, const TPtrC8& requestUrl, 
+                               TPtrC& formContentType, WebCore::FormData* formData)
+{
+    updateCurrentEntryPositionIfNeeded();
+    if (m_historyLoadOffset) {
+        m_historyLoadOffset = 0;
+        m_tempCurrentIndex = m_currentIndex;
+        return;
+    }
+    HistoryEntry* entry = HistoryEntry::initWithUrlAndFormData(url, requestUrl, formContentType, 
+        formData, m_historyCallback, m_historyCallback->wmlMode());
+    if (entry) {
+        int i;
+        // Remove all entries after this entry
+        for (i = historyLength() - 1; i > m_currentIndex; i--) {
+            HistoryEntry* deadEntry = m_historyStack[i];
+            m_historyStack.Remove(i);
+            delete deadEntry;
+        }
+        // Make sure we don't exceed the limit
+        if (historyLength() >= KHistoryStackSize) {
+            HistoryEntry* deadEntry = m_historyStack[0];
+            m_historyStack.Remove(0);
+            delete deadEntry;
+            m_currentIndex--;
+        }
+        int err = m_historyStack.Append(entry);
+	    m_historyStack.Compress();
+        if (err != KErrNone) { 
+            delete entry;
+        }
+        else {
+            m_currentIndex++;
+        }
+        m_tempCurrentIndex = m_currentIndex;
+    }    
+}
+
+/**
+*/
+bool HistoryController::containsItemForURL (const TPtrC& url)
+{
+    HBufC8* tempHBuf8 = HBufC8::New(url.Length());
+    if (! tempHBuf8)  return EFalse;
+	tempHBuf8->Des().Copy( url );
+
+    for (int i = historyLength() - 1; i>=0; i--){
+        HistoryEntry* deadEntry = m_historyStack[i];
+        if(deadEntry->requestUrl().Compare(tempHBuf8->Des()) == 0 ) {
+            if(tempHBuf8) delete tempHBuf8;    
+            return ETrue;
+        }
+    }
+    if(tempHBuf8) delete tempHBuf8;
+    return EFalse;
+}
+
+/**
+*/
+HBufC* HistoryController::pageInfoLC( TBrCtlDefs::TBrCtlPageInfo brCtlPageInfo )
+{
+    HBufC* pageInfo = NULL;
+    
+    switch( brCtlPageInfo )
+    {
+    case TBrCtlDefs::EPageInfoTitle:
+        {
+            TPtrC pageTitle = m_historyView->getCenterEntryTitle();
+            if( pageTitle.Length() != 0 ) {
+                pageInfo = pageTitle.AllocL();
+            }
+            break;
+        }
+    case TBrCtlDefs::EPageInfoUrl:
+        {
+            const HistoryEntry* currentEntry = entryByIndex(m_currentIndex);
+            if( currentEntry && currentEntry->responseUrl().Length() ) {
+                pageInfo = HBufC::NewL(currentEntry->responseUrl().Length());
+                pageInfo->Des().Copy(currentEntry->responseUrl());
+            }
+            break;
+        }
+    default:
+        {
+            break;
+        }
+    }
+    CleanupStack::PushL( pageInfo );
+    return pageInfo;
+}
+
+/**
+*/
+void HistoryController::handleHistoryCommandL(int command)
+{
+    m_tempCurrentIndex = m_currentIndex;
+    switch( command )
+    {
+    case TBrCtlDefs::ECommandReload:
+        {
+        // Get current url from history and call LoadUrlL(url)
+        loadHistoryUrl( EHistoryStackDirectionCurrent, TBrCtlDefs::ECacheModeNoCache, m_historyLoadOffset);
+        break;
+        }
+    case TBrCtlDefs::ECommandBack:
+        {
+        if (m_historyViewEnabled && m_backListAllowed) {
+            showHistoryViewL(true);
+        }
+        else {
+            loadHistoryUrl( EHistoryStackDirectionPrevious, TBrCtlDefs::ECacheModeHistory, -1);
+        }
+        break;
+        }
+    case TBrCtlDefs::ECommandOneStepBack:
+        {
+        loadHistoryUrl( EHistoryStackDirectionPrevious, TBrCtlDefs::ECacheModeHistory, -1);
+        break;
+        }
+    case TBrCtlDefs::ECommandForward:
+        {
+        // Get next url from history and call LoadUrlL(url)
+        loadHistoryUrl( EHistoryStackDirectionNext, TBrCtlDefs::ECacheModeHistory, 1);
+        break;
+        }
+    case TBrCtlDefs::ECommandShowHistory:
+        {
+        if (m_historyViewEnabled && m_backListAllowed) {
+            showHistoryViewL(false);
+        }
+        else {
+            showHistoryListL();
+        }
+        break;
+        }
+    case TBrCtlDefs::ECommandClearHistory:
+        {
+        // Clear History contents
+        clearHistoryList();
+        break;
+        }
+    case TBrCtlDefs::ECommandCancel:
+        {
+        if (m_historyViewEnabled && m_backListAllowed) {
+            closeHistoryView();
+            m_historyLoadOffset = 0;
+        }
+        break;
+        }
+    default:
+        {
+        break;
+        }
+    }
+}
+
+/**
+*/
+void HistoryController::clearHistoryList()
+{
+    int i;
+    for (i = historyLength() - 1; i >= 0; i--) {
+        if (i != m_currentIndex) {
+            HistoryEntry* deadEntry = m_historyStack[i];
+            m_historyStack.Remove(i);
+            delete deadEntry;
+        }
+    }
+    m_currentIndex  = (m_currentIndex != -1) ? 0: m_currentIndex ;
+    m_tempCurrentIndex = m_currentIndex;
+    m_historyLoadOffset = 0;
+}
+
+/**
+*/
+bool HistoryController::canGoBackOrForward(int distance)
+{
+    int newCurrent = m_currentIndex + distance;
+    if ( newCurrent >= 0 && newCurrent < m_historyStack.Count()) {
+        return true;
+    }
+    return false;
+}
+
+/**
+*/
+void HistoryController::updateHistoryEntryThumbnailL(const CFbsBitmap* bitmap)
+{
+    if(m_historyViewEnabled) {
+        HistoryEntry* entry = entryByIndex(m_currentIndex);
+        if (entry) {
+            TSize bmsize = bitmap->SizeInPixels();
+            TRect parentControlRect = m_historyCallback->parent()->Rect();
+            int historyViewWidth = parentControlRect.Width();
+            int historyViewHeight( parentControlRect.Height());
+            // Find out that in either portrait or landscape view what is the max height
+            int maxDimension = (historyViewWidth > historyViewHeight)? historyViewWidth:historyViewHeight;
+            int thumbnailHeight = Min(bmsize.iHeight, maxDimension*KCenterThumbnailHeightPercent/100);
+            int thumbnailWidth = Min(bmsize.iWidth, maxDimension*KCenterThumbnailWidthPercent/100);
+            entry->storeThumbnail(bitmap, TRect(0,0,thumbnailWidth, thumbnailHeight));
+        }
+    }
+}
+
+/**
+*/
+void HistoryController::setCurrentEntryTitle( const TPtrC& pageTitle )
+{
+    HistoryEntry* entry = entryByIndex(m_currentIndex);
+    if (entry) {
+        entry->setPageTitle(pageTitle);
+    }
+}
+
+/**
+*/
+void HistoryController::updateCurrentEntryPositionIfNeeded()
+{
+    HistoryEntry* entry = entryByIndex(m_tempCurrentIndex);
+    if (entry) {
+        TPoint cp(m_historyCallback->currentPosition());
+        if (!m_historyCallback->wmlMode()) {
+            // update the entry position
+            entry->setPosition(cp) ;
+        }
+    }
+}
+
+
+
+/**
+*/
+TPoint HistoryController::currentEntryPosition()
+{
+    HistoryEntry* entry = entryByIndex(m_currentIndex);
+    if (entry) {
+        return entry->position();
+    }
+    return TPoint(0, 0);
+}
+
+/**
+ */
+//void HistoryController::setRequestUrlL(const TPtrC& aUrl);
+
+/**
+ * Sets Url Response 
+ */
+//void HistoryController::setResponseUrlL(const TPtrC& aUrl);
+
+/**
+ * Gets the entry 
+ */
+HistoryEntry* HistoryController::entry(THistoryStackDirection direction)
+{
+    int index = 0;
+    switch (direction)
+        {
+        case EHistoryStackDirectionPrevious:
+            index = m_currentIndex - 1;
+            break;
+        case EHistoryStackDirectionNext:
+            index = m_currentIndex + 1;
+            break;
+        case EHistoryStackDirectionCurrent:
+        default:
+            index = m_currentIndex;
+            break;
+        }
+    return entryByIndex(index);
+}
+
+/**
+ */
+TPtrC8 HistoryController::requestUrl()
+{
+	    HistoryEntry* entry = entryByIndex(m_currentIndex);
+        if (! entry) {
+            return NULL;
+        }
+        return entry->requestUrl();
+}
+
+/**
+*/
+TPtrC8 HistoryController::responseUrl ()
+{
+	    HistoryEntry* entry = entryByIndex(m_currentIndex);
+        if (! entry) {
+            return NULL;
+        }
+        return entry->responseUrl();
+}
+
+/**
+*/
+HistoryEntry* HistoryController::entryByIndex (int historyIndex)
+{
+    if (historyIndex >= 0 && historyIndex < m_historyStack.Count()) {
+        return m_historyStack[historyIndex];
+    }
+    return NULL;    
+}
+
+/**
+ */
+int HistoryController::index (THistoryStackDirection direction)
+{
+	//return m_historyStack.index (direction);
+    TInt index = 0;
+    switch (direction)
+        {
+        case EHistoryStackDirectionPrevious:
+        index = currentIndex() - 1;
+        break;
+
+        case EHistoryStackDirectionNext:
+        index = currentIndex() + 1;
+        break;
+
+        case EHistoryStackDirectionCurrent:
+        default:
+        index = currentIndex();
+        break;
+        }
+
+    return index;
+}
+
+/**
+*/
+void HistoryController::deleteEntry(int index)
+{
+    if (index >= 0 && index < m_historyStack.Count()) {
+        HistoryEntry* deadEntry = m_historyStack[index];
+        m_historyStack.Remove(index);
+        delete deadEntry;
+		// Shift current page if removing previous pages
+        if (index <= m_currentIndex && m_currentIndex > 0)
+        	{
+        	m_currentIndex--;
+        	}
+    }
+}
+
+/**
+*/
+void HistoryController::setCurrentL ( THistoryStackDirection direction )
+{
+	setCurrentIndex(index(direction));
+}
+
+/**
+*/
+void HistoryController::updateGlobalHistoryForReload()
+{
+    HistoryEntry* entry = m_historyStack[m_currentIndex];
+    entry->touch();
+    updateCurrentEntryPositionIfNeeded();
+}
+
+/**
+*/
+void HistoryController::goBackOrForward(int distance)
+{
+    m_tempCurrentIndex = m_currentIndex;
+    m_currentIndex += distance;
+    m_historyLoadOffset = distance;
+    const HistoryEntry* currentEntry = entryByIndex(m_currentIndex);
+    if (currentEntry) {
+        TPtrC8 url = currentEntry->requestUrl();
+        m_historyCallback->doHistoryGet( url, TBrCtlDefs::ECacheModeHistory );
+    }
+}
+
+/**
+*/
+void HistoryController::closeHistoryView()
+{
+    m_historyLoadOffset = m_historyView->historyLoadOffset();
+    delete m_historyView;
+    m_historyView = NULL;
+    // Update the display
+    m_historyCallback->makeVisible(true);
+    m_historyCallback->parent()->DrawNow();
+    // inform UI that we have exited the History View
+    // This should update the softkeys
+    m_historyCallback->stateChanged(false);
+    // delete bitmaps (they can be recreated from buffer)
+    int i;
+    for (i = 0; i < historyLength(); i++ ) {
+        HistoryEntry* entry = m_historyStack[i];
+        entry->deleteThumbnail();
+    }
+    //reset deferred timers on closing history view
+    m_historyCallback->deferTimers(false);
+}
+
+/**
+ */
+void HistoryController::updateDisplay() const
+{
+    m_historyCallback->parent()->DrawNow();
+}
+
+/**
+ */
+HistoryController::HistoryController(HistoryCallback* historyCallback, bool historyAllowed, bool backListAllowed) : m_historyStack(20)
+{
+    m_historyView = NULL;
+    m_historyViewEnabled = historyAllowed;
+    m_backListAllowed = backListAllowed; 
+    m_historyLoadOffset = 0;
+    m_historyCallback = historyCallback;
+    m_currentIndex = -1;
+    m_tempCurrentIndex = m_currentIndex;
+    m_possibleWmlOEB = false;
+}
+
+/**
+*/
+void HistoryController::showHistoryViewL(bool previous)
+{
+    HistoryEntry* entry = entryByIndex(m_currentIndex);
+    if (entry && ! entry->thumbnail()) {
+        // get scaled page from PageScaler;
+        // update the history with new bitmap
+        CFbsBitmap* scaledPage = m_historyCallback->scaledPage();
+        if(scaledPage) {
+            // Get the browser control rect
+            updateHistoryEntryThumbnailL(scaledPage);
+        }
+            // ignore err since we will use the default image
+    }
+    //Defer refresh timers on showing history view
+    m_historyCallback->deferTimers(true);
+    m_historyView = HistoryView::NewL( *this, previous );
+    m_historyCallback->makeVisible(false);
+    m_historyCallback->parent()->DrawNow();
+    // inform UI that we have enterd the History View
+    // This should update the softkeys
+    m_historyCallback->stateChanged(true);
+    m_historyView->updateState(0);
+}
+
+/**
+*/
+void HistoryController::showHistoryListL()
+{
+    SelectArray* historyList = new( ELeave ) CArrayFixFlat<TBrCtlSelectOptionData>(10);
+    CleanupStack::PushL( historyList );
+    for( int i = m_historyStack.Count() - 1; i >= 0; i-- ) {
+        TBrCtlSelectOptionData t( TBrCtlSelectOptionData(entryByIndex(i)->pageTitle(), i == m_currentIndex, false, false) );
+        historyList->AppendL(t);
+    }
+    // Display history dialog
+    bool ret = m_historyCallback->dialogSelectOption(historyList);
+    if (ret) {
+        int index = 0;
+        for (; index < historyList->Count(); index++) {
+            if ((*historyList)[index].IsSelected())
+                break;
+        }
+        // Initialize a history load
+        m_tempCurrentIndex = m_currentIndex;
+        m_currentIndex = m_historyStack.Count() - index - 1;
+        m_historyLoadOffset = index;
+        loadHistoryUrl(EHistoryStackDirectionCurrent, TBrCtlDefs::ECacheModeNoCache, m_historyLoadOffset);
+    }
+    // else, user cancelled the dialog; do nothing about it
+    historyList->Reset();
+    CleanupStack::PopAndDestroy(); // historyList
+}
+
+/**
+* LoadHistoryEntry
+*
+* @since 3.x
+* @return void
+*/
+//void HistoryController::loadHistoryEntryL( CArrayFixFlat<TBrCtlSelectOptionData>& aHistoryList );
+
+void HistoryController::loadHistoryUrl(THistoryStackDirection direction, TBrCtlDefs::TBrCtlCacheMode cacheMode, int historyLoadOffset)
+{
+    const HistoryEntry* currentEntry = entry(direction);
+    if(currentEntry) {
+        m_historyLoadOffset = historyLoadOffset;
+        if (direction != EHistoryStackDirectionCurrent) {
+            m_currentIndex += historyLoadOffset;
+        }
+        TPtrC8 url = currentEntry->requestUrl();
+        if(currentEntry->postContentType().Length() && currentEntry->formData()) {
+            m_historyCallback->doHistoryPost(url, cacheMode, currentEntry->postContentType(), currentEntry->formData());
+        }
+        else {
+            m_historyCallback->doHistoryGet( url, cacheMode );
+        }
+    }
+}
+
+void HistoryController::performTransition(int direction)
+{
+	m_historyView->performTransition(direction);	
+}
+
+/**
+*/
+void HistoryController::updateCurrentEntryZoomLevelIfNeeded()
+{
+    HistoryEntry* entry = entryByIndex(m_tempCurrentIndex); 
+    if (entry) {
+        int cp(m_historyCallback->currentZoomLevel());
+        if (!m_historyCallback->wmlMode()) {
+            // update the entry position
+            entry->setZoomLevel(cp) ;
+        }
+    }
+}
+
+/**
+*/
+int HistoryController::currentEntryZoomLevel()
+{
+    HistoryEntry* entry = entryByIndex(m_currentIndex);
+
+    if (entry) {
+        return entry->zoomLevel();
+    }
+    return 0; // default value should use in this case
+}
+
+/**
+*/
+void HistoryController::updateCurrentEntryMinZoomLevelIfNeeded()
+{
+    HistoryEntry* entry = entryByIndex(m_tempCurrentIndex); 
+
+    if (entry) {
+        int cp(m_historyCallback->minZoomLevel());
+        if (!m_historyCallback->wmlMode()) {
+            // update the entry position
+            entry->setMinZoomLevel(cp) ;
+        }
+    }
+}
+
+/**
+*/
+int HistoryController::currentEntryMinZoomLevel()
+{
+    HistoryEntry* entry = entryByIndex(m_currentIndex);
+
+    if (entry) {
+        return entry->minZoomLevel();
+    }
+    return 0; // default value should use in this case
+}
+
+//  End of File