--- /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