You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1009 lines
29 KiB
1009 lines
29 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1999 - 1999
|
|
//
|
|
// File: histlist.cpp
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
#include "histlist.h"
|
|
#include "cstr.h"
|
|
#include "amcmsgid.h"
|
|
#include "websnk.h"
|
|
#include "webctrl.h"
|
|
|
|
|
|
//############################################################################
|
|
//############################################################################
|
|
//
|
|
// Traces
|
|
//
|
|
//############################################################################
|
|
//############################################################################
|
|
#ifdef DBG
|
|
CTraceTag tagHistory(TEXT("History"), TEXT("History"));
|
|
|
|
LPCTSTR SzHistoryEntryType(CHistoryEntry &entry)
|
|
{
|
|
if(entry.IsListEntry())
|
|
return TEXT("ListView");
|
|
|
|
else if(entry.IsOCXEntry())
|
|
return TEXT("OCXView ");
|
|
|
|
else if(entry.IsWebEntry())
|
|
return TEXT("WebView ");
|
|
|
|
else
|
|
ASSERT(0 && "Should not come here");
|
|
return TEXT("Illegal entry");
|
|
}
|
|
|
|
#define TraceHistory(Name, iter) \
|
|
{ \
|
|
USES_CONVERSION; \
|
|
Trace(tagHistory, TEXT("%s hNode = %d, %s, viewMode = %d, strOCX = \"%s\" iterator = %d "), \
|
|
Name, iter->hnode, SzHistoryEntryType(*iter), iter->viewMode, \
|
|
TEXT(""), (LPARAM) &*iter); \
|
|
}
|
|
|
|
#else // DBG
|
|
|
|
#define TraceHistory(Name, iter)
|
|
|
|
#endif // DBG
|
|
|
|
|
|
//############################################################################
|
|
//############################################################################
|
|
//
|
|
// Implementation of class CHistoryEntry
|
|
//
|
|
//############################################################################
|
|
//############################################################################
|
|
|
|
bool
|
|
CHistoryEntry::operator == (const CHistoryEntry &other) const
|
|
{
|
|
if( hnode != other.hnode)
|
|
return false;
|
|
|
|
if( guidTaskpad != other.guidTaskpad)
|
|
return false;
|
|
|
|
if(resultViewType != other.resultViewType) // NOTE: implement operator == for CResultViewType.
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
CHistoryEntry::operator != (const CHistoryEntry &other) const
|
|
{
|
|
return !operator == (other);
|
|
}
|
|
|
|
|
|
//############################################################################
|
|
//############################################################################
|
|
//
|
|
// Implementation of class CHistoryList
|
|
//
|
|
//############################################################################
|
|
//############################################################################
|
|
|
|
|
|
int CHistoryList::s_nPageBreak = 0;
|
|
|
|
CHistoryList::CHistoryList(CAMCView* pAMCView)
|
|
: m_bBrowserBackEnabled(false),
|
|
m_bBrowserForwardEnabled(false),
|
|
m_pWebViewCtrl(NULL),
|
|
m_bPageBreak(false),
|
|
m_bWithin_CHistoryList_Back(false),
|
|
m_bWithin_CHistoryList_Forward(false),
|
|
m_bNavigateAfterPageBreak(false)
|
|
{
|
|
m_pView = pAMCView;
|
|
m_iterCurrent = m_entries.begin();
|
|
m_navState = MMC_HISTORY_READY; // not busy
|
|
|
|
}
|
|
CHistoryList::~CHistoryList()
|
|
{
|
|
}
|
|
|
|
SC
|
|
CHistoryList::ScOnPageBreak(int nPageBreakID)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CHistoryList::ScOnPageBreak"));
|
|
|
|
// handle recursion
|
|
if(MMC_HISTORY_PAGE_BREAK == m_navState)
|
|
{
|
|
USES_CONVERSION;
|
|
Trace(tagHistory, _T("OnPageBreak() - while inserting pagebreak"));
|
|
|
|
// we were trying to navigate to a page break
|
|
if(m_bNavigateAfterPageBreak)
|
|
{
|
|
m_bNavigateAfterPageBreak = false;
|
|
m_pWebViewCtrl->Navigate( OLE2CT(m_szURLToNavigate.data()), NULL );
|
|
}
|
|
|
|
m_navState = MMC_HISTORY_READY;
|
|
return sc;
|
|
}
|
|
|
|
bool bHandled = false;
|
|
|
|
//Page breaks are only hit if navigating out of a current web entry. The web
|
|
//entry keeps track of the bounding page breaks. From this, we can determine
|
|
//whether we are navigating forward or backwards in history
|
|
ASSERT(m_iterCurrent->IsWebEntry());
|
|
bool bCurrentStateIsForward = (nPageBreakID > m_iterCurrent->prevPageBreakID);
|
|
|
|
if(bCurrentStateIsForward)
|
|
{
|
|
Trace(tagHistory, _T("OnPageBreak() - while going Forward"));
|
|
Forward(bHandled, false);
|
|
}
|
|
else
|
|
{
|
|
Trace(tagHistory, _T("OnPageBreak() - while going Back"));
|
|
Back(bHandled, false);
|
|
}
|
|
|
|
if(!bHandled)
|
|
{
|
|
Trace(tagHistory, _T("OnPageBreak() - unhandled, passing back to web browser"));
|
|
if (bCurrentStateIsForward)
|
|
GetWebViewCtrl()->Forward();
|
|
else
|
|
GetWebViewCtrl()->Back();
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
void
|
|
CHistoryList::OnPageBreakStateChange(bool bPageBreak)
|
|
{
|
|
m_bPageBreak = bPageBreak;
|
|
|
|
return;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::OnBrowserStateChange
|
|
*
|
|
* PURPOSE: Callback that receives events from the IE control that the
|
|
* forward/back button needs to be enabled/disabled. A
|
|
* combination of this information with any non-HTML states in the
|
|
* history list is used to enable/disable the actual UI.
|
|
*
|
|
* PARAMETERS:
|
|
* bool bForward :
|
|
* bool bEnable :
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CHistoryList::OnBrowserStateChange(bool bEnableForward, bool bEnableBack)
|
|
{
|
|
#if DBG
|
|
CStr strTrace;
|
|
strTrace.Format(_T("OnBrowserStateChange() - bEnableForward = %s, bEnableBack = %s"),
|
|
bEnableForward ? _T("true") : _T("false"),
|
|
bEnableBack ? _T("true") : _T("false"));
|
|
Trace(tagHistory, strTrace);
|
|
#endif
|
|
|
|
// handle the forward case.
|
|
if(m_bBrowserForwardEnabled && !bEnableForward && !m_bPageBreak)
|
|
{
|
|
// the button was originally enabled but is now disabled.
|
|
// This means that the user branched forward. So we need to throw away
|
|
// any history ahead of the present time.
|
|
if(m_iterCurrent != m_entries.end())
|
|
{
|
|
iterator iterTemp = m_iterCurrent;
|
|
TraceHistory(TEXT("CHistoryList::Deleting all subsequent entries after"), iterTemp);
|
|
++iterTemp;
|
|
m_entries.erase(iterTemp, m_entries.end());
|
|
}
|
|
}
|
|
|
|
m_bBrowserForwardEnabled = bEnableForward;
|
|
m_bBrowserBackEnabled = bEnableBack;
|
|
|
|
MaintainWebBar();
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::IsFirst
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* RETURNS:
|
|
* BOOL: TRUE if we should not light up the "Back" button.
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
BOOL
|
|
CHistoryList::IsFirst()
|
|
{
|
|
return (m_iterCurrent == m_entries.begin());
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::IsLast
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* RETURNS:
|
|
* BOOL : TRUE if we should not light up the "Forward" button
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
BOOL
|
|
CHistoryList::IsLast()
|
|
{
|
|
// see notes above
|
|
if(m_iterCurrent == m_entries.end())
|
|
return TRUE;
|
|
|
|
// find next unique entry, if any
|
|
iterator iter = m_iterCurrent;
|
|
++iter; // this must exist, we've already taken care of the end case.
|
|
return(iter == m_entries.end());
|
|
}
|
|
|
|
SC
|
|
CHistoryList::ScDoPageBreak()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CHistoryList::ScDoPageBreak"));
|
|
|
|
sc = ScCheckPointers(GetWebViewCtrl());
|
|
if(sc)
|
|
return sc;
|
|
|
|
Trace(tagHistory, _T("ScDoPageBreak()"));
|
|
|
|
// navigate to the "break" page.
|
|
m_navState = MMC_HISTORY_PAGE_BREAK;
|
|
|
|
|
|
CStr strResultPane;
|
|
sc = ScGeneratePageBreakURL (strResultPane);
|
|
if (sc)
|
|
return (sc);
|
|
|
|
GetWebViewCtrl()->Navigate(strResultPane, NULL);
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::ScAddEntry
|
|
*
|
|
* PURPOSE: Adds a history entry
|
|
*
|
|
* PARAMETERS:
|
|
* CResultViewType & rvt :
|
|
* int viewMode: The list view mode (large icon, etc)
|
|
* GUID & guidTaskpad :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CHistoryList::ScAddEntry(CResultViewType &rvt, int viewMode, GUID &guidTaskpad)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CHistoryList::ScAddEntry"));
|
|
|
|
if(m_navState != MMC_HISTORY_READY)
|
|
{
|
|
#ifdef DBG
|
|
CHistoryEntry entry;
|
|
entry.viewMode = viewMode;
|
|
entry.resultViewType = rvt;
|
|
entry.guidTaskpad = guidTaskpad;
|
|
TraceHistory(TEXT("CHistoryList::Busy-RejectEntry"), (&entry));
|
|
#endif //DBG
|
|
MaintainWebBar();
|
|
return sc;
|
|
}
|
|
|
|
BOOL bIsWebEntry = rvt.HasWebBrowser();
|
|
|
|
// must be in the MMC_HISTORY_READY state at this point, ie not busy.
|
|
// figure out current node
|
|
HNODE hnode = m_pView->GetSelectedNode();
|
|
if(hnode == NULL)
|
|
return sc; // not initialized yet
|
|
|
|
/* if selection change includes the web page (either as 'from' or 'to' node)
|
|
* we need to perform proper separation of the webentries by inserting the pagebreaks.
|
|
* This is to be done to ensure 2 goals:
|
|
* - to detect when navigation should leave the IE history and use MMC history navigation
|
|
* - to ensure we always leave IE only after navigating to a pagebreak - to stop the
|
|
* scripts on the page as soon as we hide it. to achieve that we need pagebreaks
|
|
* before every web page and after every web page.
|
|
*
|
|
* to do so we need one of the following:
|
|
*
|
|
* 1. Add a pagebreak (used when selection changes from the web page to non-web view)
|
|
* 2. Add a pagebreak and navigate
|
|
* (a. when selection changes from web page to another web page)
|
|
* (b. when selection changes from non-web view to the webpage
|
|
* and it is the first web page in the history)
|
|
* 3. Navigate only. ( when selection changes from non-web view to the
|
|
* webpage [except #2.b case] - pagebreak had to be added when leaving the
|
|
* previous web page)
|
|
*
|
|
* inverting the said will result in:
|
|
* - add a pagebreak if :
|
|
* C1: web page is a 'from' node (#1. and #2.a.)
|
|
* C2: web page is a 'to' node
|
|
* && no previous web pages
|
|
* && 'from' node is a non-web view (#2.b)
|
|
* - navigate to web page if:
|
|
* C3: "to' node is the web page
|
|
*/
|
|
|
|
// see if we were in the web before this
|
|
// Note: both following variables may be false (in case it there are no entries)
|
|
bool bPreviousPageWasWeb = (m_entries.size() != 0) && m_iterCurrent->IsWebEntry();
|
|
bool bPreviousPageWasNonWeb = (m_entries.size() != 0) && !bPreviousPageWasWeb;
|
|
|
|
CHistoryEntry* prevWebPageEntry = GetPreviousWebPageEntry();
|
|
|
|
// see if we need a pagebreak
|
|
bool bNeedAPageBreak = false;
|
|
if ( bPreviousPageWasWeb )
|
|
{
|
|
// condition C1 in the comment above
|
|
bNeedAPageBreak = true;
|
|
}
|
|
else if ( bIsWebEntry && !prevWebPageEntry && bPreviousPageWasNonWeb )
|
|
{
|
|
// condition C2 in the comment above
|
|
bNeedAPageBreak = true;
|
|
}
|
|
|
|
|
|
DeleteSubsequentEntries();
|
|
|
|
// add an entry to the end of the list.
|
|
CHistoryEntry entry;
|
|
ZeroMemory(&entry, sizeof(entry));
|
|
m_entries.push_back(entry);
|
|
m_iterCurrent = m_entries.end();
|
|
--m_iterCurrent; // points to the newly inserted item.
|
|
|
|
m_iterCurrent->viewMode = viewMode;
|
|
m_iterCurrent->guidTaskpad = guidTaskpad;
|
|
m_iterCurrent->hnode = hnode;
|
|
m_iterCurrent->resultViewType = rvt;
|
|
|
|
//The lower bounding page break is recorded as the upper bound page break of the
|
|
//previous web entry if one exists.
|
|
//
|
|
if(bIsWebEntry && prevWebPageEntry)
|
|
{
|
|
m_iterCurrent->prevPageBreakID = prevWebPageEntry->nextPageBreakID;
|
|
}
|
|
|
|
TraceHistory(TEXT("CHistoryList::AddEntry"), m_iterCurrent);
|
|
|
|
|
|
m_bNavigateAfterPageBreak = false; // initialize
|
|
|
|
// See the above comment. This if-else sequence does every possible combination
|
|
if(bIsWebEntry && bNeedAPageBreak)
|
|
{
|
|
USES_CONVERSION;
|
|
sc = ScDoPageBreak();
|
|
if(sc)
|
|
return sc;
|
|
|
|
m_szURLToNavigate = rvt.GetURL();
|
|
m_bNavigateAfterPageBreak = true;
|
|
|
|
|
|
//This case is hit when there is no previous web entry in the history. A new
|
|
//page break has been inserted before navigating to the URL.
|
|
//The page break generator uses a pre-increment, so s_nPageBreak is the ID of the
|
|
//newly generated page break;
|
|
m_iterCurrent->prevPageBreakID = s_nPageBreak;
|
|
}
|
|
else if(bIsWebEntry && !bNeedAPageBreak)
|
|
{
|
|
USES_CONVERSION;
|
|
m_pWebViewCtrl->Navigate( OLE2CT( rvt.GetURL() ), NULL );
|
|
|
|
}
|
|
else if(!bIsWebEntry && bNeedAPageBreak)
|
|
{
|
|
sc = ScDoPageBreak();
|
|
if(sc)
|
|
return sc;
|
|
|
|
if (prevWebPageEntry)
|
|
{
|
|
//currently in a web entry and are navigating out of it,
|
|
//so the newly generated page break is an upper bound
|
|
//for the web entry.
|
|
prevWebPageEntry->nextPageBreakID = s_nPageBreak;
|
|
}
|
|
}
|
|
else // (!bIsWebEntry && !bNeedAPageBreak)
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
Compact();
|
|
MaintainWebBar();
|
|
return sc;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::DeleteSubsequentEntries
|
|
*
|
|
* PURPOSE: When a new entry is inserted, all subsequent entries need to be
|
|
* deleted, because a new branch has been taken.
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CHistoryList::DeleteSubsequentEntries()
|
|
{
|
|
if(m_iterCurrent == m_entries.end())
|
|
return; // nothing to do.
|
|
|
|
iterator iterTemp = m_iterCurrent;
|
|
++iterTemp;
|
|
|
|
while(iterTemp != m_entries.end())
|
|
{
|
|
iterator iterNext = iterTemp;
|
|
++iterNext; // point to the next element.
|
|
|
|
TraceHistory(TEXT("CHistoryList::DeleteSubsequentEntries"), iterTemp);
|
|
|
|
m_entries.erase(iterTemp);
|
|
iterTemp = iterNext;
|
|
}
|
|
|
|
// the current entry must be the last at this stage.
|
|
#ifdef DBG
|
|
{
|
|
iterator iterTemp = m_iterCurrent;
|
|
++iterTemp;
|
|
ASSERT(iterTemp == m_entries.end());
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::Back
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* bool & bHandled :
|
|
*
|
|
* RETURNS:
|
|
* HRESULT
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CHistoryList::Back(bool &bHandled, bool bUseBrowserHistory)
|
|
{
|
|
Trace(tagHistory, TEXT("Back()"));
|
|
|
|
// change the state to indicate we are navigating back.
|
|
// and assure it is reset on function exit
|
|
m_bWithin_CHistoryList_Back = true;
|
|
CAutoAssignOnExit<bool, false> auto_reset( m_bWithin_CHistoryList_Back );
|
|
|
|
// if we're in browser mode AND
|
|
// if the back button is enabled by the browser use browser history.
|
|
if( (m_iterCurrent->IsWebEntry()) && bUseBrowserHistory)
|
|
{
|
|
if(m_bBrowserBackEnabled)
|
|
{
|
|
Trace(tagHistory, TEXT("Back() web entry - not handling"));
|
|
bHandled = false;
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
bHandled = true;
|
|
|
|
// BOGUS assert - amcview calls Back when ALT <- is pressed
|
|
// regardless of the state of the button.
|
|
//ASSERT (m_iterCurrent != m_entries.begin());
|
|
if(m_iterCurrent == m_entries.begin())
|
|
return S_FALSE;
|
|
|
|
--m_iterCurrent;
|
|
|
|
HRESULT hr = ExecuteCurrent();
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
if(m_iterCurrent->IsWebEntry())
|
|
{
|
|
if(m_bPageBreak) // if we're at a page break, go past it.
|
|
{
|
|
Trace(tagHistory, TEXT("Back() - stepped on the pagebreak"));
|
|
bHandled = false; // this tells the caller to use the Browser's Back button.
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::Forward
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* bool & bHandled :
|
|
*
|
|
* RETURNS:
|
|
* HRESULT
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CHistoryList::Forward(bool &bHandled, bool bUseBrowserHistory)
|
|
{
|
|
// change the state to indicate we are navigating forward.
|
|
// and assure it is reset on function exit
|
|
m_bWithin_CHistoryList_Forward = true;
|
|
CAutoAssignOnExit<bool, false> auto_reset( m_bWithin_CHistoryList_Forward );
|
|
|
|
// if we're in browser mode AND
|
|
// if the forward button is enabled by the browser use browser history.
|
|
if( (m_iterCurrent->IsWebEntry()) && bUseBrowserHistory)
|
|
{
|
|
if(m_bBrowserForwardEnabled)
|
|
{
|
|
bHandled = false;
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
bHandled = true;
|
|
|
|
//jmessec: 2002/05/23: This ASSERT should be valid now that we have test iterator code below,
|
|
//since we should now never iterate past the end of our list. Consider putting it back in
|
|
|
|
// BOGUS assert - amcview calls Forward when ALT -> is pressed
|
|
// regardless of the state of the Forward button.
|
|
//ASSERT (m_iterCurrent != m_entries.end());
|
|
if(m_iterCurrent == m_entries.end())
|
|
return S_FALSE;
|
|
|
|
//create a temporary iterator to probe whether or
|
|
//not we are already at the end of the hist list
|
|
iterator iterTestHistoryEnd = m_iterCurrent;
|
|
|
|
++iterTestHistoryEnd;
|
|
|
|
if(iterTestHistoryEnd == m_entries.end())
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
++m_iterCurrent;
|
|
|
|
HRESULT hr = ExecuteCurrent();
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
if(m_iterCurrent->IsWebEntry())
|
|
{
|
|
if(m_bPageBreak) // if we're at a page break, go past it.
|
|
bHandled = false; // this tells the caller to use the Browser's Forward button.
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::ExecuteCurrent
|
|
*
|
|
* PURPOSE: Sets the state of MMC to that of the current History entry. Called
|
|
* by Back() and Forward().
|
|
*
|
|
* RETURNS:
|
|
* HRESULT
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CHistoryList::ExecuteCurrent()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CHistoryList::ExecuteCurrent"));
|
|
INodeCallback* pNC = m_pView->GetNodeCallback();
|
|
MTNODEID id;
|
|
|
|
TraceHistory(TEXT("CHistoryList::ExecuteCurrent"), m_iterCurrent);
|
|
|
|
pNC->GetMTNodeID (m_iterCurrent->hnode, &id);
|
|
m_navState = MMC_HISTORY_NAVIGATING;
|
|
|
|
// store values to local variables to avoid losing them
|
|
// when an entry is removed from history
|
|
GUID guidTaskpad = m_iterCurrent->guidTaskpad;
|
|
bool bIsListEntry = m_iterCurrent->IsListEntry();
|
|
DWORD viewMode = m_iterCurrent->viewMode;
|
|
|
|
m_pView->SelectNode (id, guidTaskpad);
|
|
|
|
if(bIsListEntry)
|
|
{
|
|
sc = m_pView->ScChangeViewMode(viewMode);
|
|
if (sc)
|
|
sc.TraceAndClear();
|
|
}
|
|
|
|
m_navState = MMC_HISTORY_READY;
|
|
|
|
MaintainWebBar();
|
|
return sc.ToHr();
|
|
}
|
|
|
|
void CHistoryList::MaintainWebBar()
|
|
{
|
|
bool bWebEntry = ((m_entries.size() != 0) && m_iterCurrent->IsWebEntry());
|
|
|
|
UpdateWebBar ( HB_BACK, ( bWebEntry && m_bBrowserBackEnabled ) || !IsFirst()); // back
|
|
UpdateWebBar ( HB_FORWARD, ( bWebEntry && m_bBrowserForwardEnabled ) || !IsLast () ); // forward
|
|
}
|
|
|
|
void CHistoryList::UpdateWebBar (HistoryButton button, BOOL bOn)
|
|
{
|
|
DECLARE_SC (sc, _T("CHistoryList::UpdateWebBar"));
|
|
|
|
if (NULL == m_pView)
|
|
{
|
|
sc = E_UNEXPECTED;
|
|
return;
|
|
}
|
|
|
|
CStandardToolbar* pStandardToolbar = m_pView->GetStdToolbar();
|
|
if (NULL == pStandardToolbar)
|
|
{
|
|
sc = E_UNEXPECTED;
|
|
return;
|
|
}
|
|
|
|
switch (button)
|
|
{
|
|
case HB_BACK:
|
|
sc = pStandardToolbar->ScEnableButton(IDS_MMC_WEB_BACK, bOn);
|
|
break;
|
|
case HB_STOP:
|
|
sc = pStandardToolbar->ScEnableButton(IDS_MMC_WEB_STOP, bOn);
|
|
break;
|
|
case HB_FORWARD:
|
|
sc = pStandardToolbar->ScEnableButton(IDS_MMC_WEB_FORWARD, bOn);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::ScGetCurrentResultViewType
|
|
*
|
|
* PURPOSE: Returns the current history entry.
|
|
*
|
|
* PARAMETERS:
|
|
* CResultViewType & rvt :
|
|
* int& viewMode :
|
|
* GUID & guidTaskpad :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CHistoryList::ScGetCurrentResultViewType (CResultViewType &rvt, int& viewMode, GUID &guidTaskpad)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CHistoryList::ScGetCurrentResultViewType"));
|
|
|
|
if(m_iterCurrent == m_entries.end())
|
|
return (sc = E_FAIL); // should never happen
|
|
|
|
rvt = m_iterCurrent->resultViewType;
|
|
viewMode = m_iterCurrent->viewMode;
|
|
guidTaskpad = m_iterCurrent->guidTaskpad;
|
|
|
|
return sc;
|
|
}
|
|
|
|
void CHistoryList::SetCurrentViewMode (long nViewMode)
|
|
{
|
|
if(m_navState != MMC_HISTORY_READY)
|
|
return;
|
|
if(m_iterCurrent == m_entries.end())
|
|
return;
|
|
|
|
m_iterCurrent->viewMode = nViewMode;
|
|
}
|
|
|
|
void CHistoryList::Clear()
|
|
{
|
|
Trace(tagHistory, TEXT("Clear"));
|
|
m_entries.erase(m_entries.begin(), m_entries.end());
|
|
m_iterCurrent = m_entries.begin();
|
|
MaintainWebBar();
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::ScModifyViewTab
|
|
*
|
|
* PURPOSE: Adds an entry to the history list, which is the same as the current
|
|
* entry, except that the changes specified by the dwFlags and history
|
|
* entry parameters are applied
|
|
*
|
|
* PARAMETERS:
|
|
* const GUID& guidTab : Specifies guid of selected view tab
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CHistoryList::ScModifyViewTab(const GUID& guidTab)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CHistoryList::ScAddModifiedEntry"));
|
|
|
|
// we are not going to modify anything if we navigating "Back" or ""Forward"
|
|
// thru the history enries
|
|
if ( m_bWithin_CHistoryList_Back || m_bWithin_CHistoryList_Forward )
|
|
return sc;
|
|
|
|
if( m_iterCurrent == m_entries.end() )
|
|
{
|
|
return (sc = E_UNEXPECTED);
|
|
}
|
|
|
|
// for web we cannot add new entries without reselecting the node
|
|
// (same is true about deleting subsequen entries)
|
|
// since that would make MMC and IE histories out of sync
|
|
// instead we just modify the current history entry
|
|
|
|
if ( !m_iterCurrent->IsWebEntry() ) // in case it is a regular entry
|
|
{
|
|
DeleteSubsequentEntries(); // delete everything ahead of this one.
|
|
|
|
// add an entry to the end of the list.
|
|
CHistoryEntry entry;
|
|
ZeroMemory(&entry, sizeof(entry));
|
|
m_entries.push_back(entry);
|
|
iterator iterNew = m_entries.end();
|
|
--iterNew; // point to the new entry.
|
|
|
|
// create a duplicate of the current entry.
|
|
*iterNew = *m_iterCurrent;
|
|
|
|
//set the pointer.
|
|
m_iterCurrent = iterNew;
|
|
}
|
|
|
|
// change the guid of the tab.
|
|
m_iterCurrent->guidTaskpad = guidTab;
|
|
|
|
// we're done.
|
|
Compact();
|
|
MaintainWebBar();
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::ScChangeViewMode
|
|
*
|
|
* PURPOSE: Changes the view mode of the current entry. Changing the view
|
|
* mode does not add a new entry. Instead, history remembers the last
|
|
* view mode that a node was at and always restores to that
|
|
*
|
|
* PARAMETERS:
|
|
* int viewMode :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CHistoryList::ScChangeViewMode(int viewMode)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CHistoryList::ScChangeViewMode"));
|
|
|
|
if( m_iterCurrent == m_entries.end() )
|
|
{
|
|
return (sc = E_UNEXPECTED);
|
|
}
|
|
|
|
m_iterCurrent->viewMode = viewMode; // set the view mode.
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::DeleteEntry
|
|
*
|
|
* PURPOSE: Deletes all entries for a node from the history list.
|
|
*
|
|
* PARAMETERS:
|
|
* HNODE hnode :
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CHistoryList::DeleteEntry (HNODE hnode)
|
|
{
|
|
for(iterator i= m_entries.begin(); i != m_entries.end(); )
|
|
{
|
|
if(i->hnode == hnode)
|
|
{
|
|
iterator iNext = i;
|
|
++iNext;
|
|
if(m_iterCurrent==i)
|
|
m_iterCurrent=iNext;
|
|
TraceHistory(TEXT("CHistoryList::Deleting entry"), i);
|
|
m_entries.erase(i);
|
|
|
|
i= iNext;
|
|
}
|
|
else
|
|
{
|
|
++i;
|
|
}
|
|
}
|
|
Compact();
|
|
MaintainWebBar();
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CHistoryList::Compact
|
|
*
|
|
* PURPOSE: 1) Removes redundancies in the history list by eliminating duplicates.
|
|
* 2) Ensures that a maximum of MAX_HISTORY_ENTRIES entries is retained.
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CHistoryList::Compact()
|
|
{
|
|
if (m_entries.size() == 0)
|
|
return;
|
|
|
|
// discard duplicates.
|
|
for (iterator i= m_entries.begin(); i != m_entries.end(); )
|
|
{
|
|
iterator iNext = i;
|
|
++iNext;
|
|
if(iNext == m_entries.end())
|
|
break;
|
|
|
|
// do not delete if it is a webentry (there is no way for us to tell IE
|
|
// to delete that history entry).
|
|
if ( (i->IsWebEntry() == false) && ( *i == *iNext))
|
|
{
|
|
if(m_iterCurrent==i)
|
|
m_iterCurrent=iNext;
|
|
|
|
TraceHistory(TEXT("CHistoryList::Deleting entry"), i);
|
|
m_entries.erase(i);
|
|
i = iNext;
|
|
}
|
|
else
|
|
{
|
|
++i;
|
|
}
|
|
}
|
|
|
|
iterator iter = m_entries.begin();
|
|
iterator iterNext = iter;
|
|
int nExcess = m_entries.size() - MAX_HISTORY_ENTRIES;
|
|
while(nExcess-- > 0)
|
|
{
|
|
iterNext = iter;
|
|
++iterNext;
|
|
|
|
if(iter == m_iterCurrent) // make sure we don't delete the current entry.
|
|
break;
|
|
|
|
TraceHistory(TEXT("CHistoryList::Deleting entry"), i);
|
|
m_entries.erase(iter);
|
|
iter = iterNext;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* METHOD: CHistoryList::GetPreviousWebPageEntry
|
|
*
|
|
* PURPOSE: looks back to see if there are any web pages in the history
|
|
* up to the current mark (including it)
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
* RETURNS:
|
|
* CHistoryEntry* : Previous web entry if any, NULL otherwise
|
|
*
|
|
\***************************************************************************/
|
|
CHistoryEntry* CHistoryList::GetPreviousWebPageEntry()
|
|
{
|
|
if ( m_entries.size() && m_iterCurrent == m_entries.end() )
|
|
{
|
|
ASSERT(FALSE); // need to point to a valid entry !!!
|
|
return NULL;
|
|
}
|
|
|
|
// will loop past the current entry.
|
|
iterator end = m_iterCurrent;
|
|
++end;
|
|
|
|
for ( iterator it = m_entries.begin(); it != end; ++it )
|
|
{
|
|
if ( it->IsWebEntry() )
|
|
return it.operator->(); //Using operator -> to get a pointer to the History entry
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* ScGetPageBreakURL
|
|
*
|
|
* Returns the URL for MMC's HTML page containing a page break.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
SC CHistoryList::ScGeneratePageBreakURL(CStr& strPageBreakURL)
|
|
{
|
|
DECLARE_SC (sc, _T("ScGeneratePageBreakURL"));
|
|
|
|
/*
|
|
* clear out the old value, if any
|
|
*/
|
|
strPageBreakURL.Empty();
|
|
|
|
// generate new pagebreak URL every time ( prevent web browser from compacting it)
|
|
strPageBreakURL.Format( _T("%s%d"), PAGEBREAK_URL, ++s_nPageBreak );
|
|
|
|
return (sc);
|
|
}
|