diff -r 000000000000 -r dd21522fd290 webengine/webkitutils/HistoryProvider/HistoryController.cpp --- /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(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& 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