/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "OutlinerIterator.hxx"
#include "OutlinerIteratorImpl.hxx"
#include <svx/svditer.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include "Outliner.hxx"

#include "drawdoc.hxx"
#include "DrawViewShell.hxx"
#include "drawview.hxx"
#include "sdpage.hxx"
#ifndef SD_FRAME_VIEW
#include "FrameView.hxx"
#endif
#include "DrawDocShell.hxx"
#include "Window.hxx"

namespace sd { namespace outliner {


//===== IteratorPosition ======================================================

IteratorPosition::IteratorPosition (void)
: mnText(0)
, mnPageIndex(-1)
, mePageKind(PK_STANDARD)
, meEditMode(EM_PAGE)
{
}

IteratorPosition::IteratorPosition (const IteratorPosition& aPosition)
: mxObject(aPosition.mxObject)
, mnText(aPosition.mnText)
, mnPageIndex(aPosition.mnPageIndex)
, mePageKind(aPosition.mePageKind)
, meEditMode(aPosition.meEditMode)
{
}

IteratorPosition::~IteratorPosition (void)
{
}

IteratorPosition& IteratorPosition::operator= (const IteratorPosition& aPosition)
{
    mxObject = aPosition.mxObject;
    mnText = aPosition.mnText;
    mnPageIndex = aPosition.mnPageIndex;
    mePageKind = aPosition.mePageKind;
    meEditMode = aPosition.meEditMode;
    return *this;
}

bool IteratorPosition::operator== (const IteratorPosition& aPosition) const
{
    return mxObject.get() == aPosition.mxObject.get()
        && mnText == aPosition.mnText
        && mnPageIndex == aPosition.mnPageIndex
        && mePageKind == aPosition.mePageKind
        && meEditMode == aPosition.meEditMode;
}




//===== Iterator ==============================================================

Iterator::Iterator (void)
{
    mpIterator = NULL;
}

Iterator::Iterator (const Iterator& rIterator)
{
    mpIterator = rIterator.mpIterator->Clone();
}

Iterator::Iterator (IteratorImplBase* pObject)
{
    mpIterator = pObject;
}

Iterator::~Iterator (void)
{
    delete mpIterator;
}

Iterator& Iterator::operator= (const Iterator& rIterator)
{
    if (this != &rIterator)
    {
        delete mpIterator;
        if (rIterator.mpIterator != NULL)
            mpIterator = rIterator.mpIterator->Clone();
        else
            mpIterator = NULL;
    }
    return *this;
}

const IteratorPosition& Iterator::operator* () const
{
    DBG_ASSERT (mpIterator!=NULL, "::sd::outliner::Iterator::operator* : missing implementation object");
    return mpIterator->GetPosition();
}

Iterator& Iterator::operator++ ()
{
    if (mpIterator!=NULL)
        mpIterator->GotoNextText();
    return *this;
}

Iterator Iterator::operator++ (int)
{
    Iterator aTmp (*this);
    if (mpIterator!=NULL)
        mpIterator->GotoNextText();
    return aTmp;
}

bool Iterator::operator== (const Iterator& rIterator)
{
    if (mpIterator == NULL || rIterator.mpIterator==NULL)
        return mpIterator == rIterator.mpIterator;
    else
        return *mpIterator == *rIterator.mpIterator;
}

bool Iterator::operator!= (const Iterator& rIterator)
{
    return ! operator==(rIterator);
}

void Iterator::Reverse (void)
{
    if (mpIterator != NULL)
        mpIterator->Reverse();
}

//===== IteratorFactory =======================================================

OutlinerContainer::OutlinerContainer (Outliner* pOutliner)
: mpOutliner(pOutliner)
{
}

Iterator OutlinerContainer::begin (void)
{
    return CreateIterator (BEGIN);
}

Iterator OutlinerContainer::end (void)
{
    return CreateIterator (END);
}

Iterator OutlinerContainer::current (void)
{
    return CreateIterator (CURRENT);
}


Iterator OutlinerContainer::CreateIterator (IteratorLocation aLocation)
{
    // Decide on certain features of the outliner which kind of iterator to
    // use.
    if (mpOutliner->mbRestrictSearchToSelection)
        // There is a selection.  Search only in this.
        return CreateSelectionIterator (
            mpOutliner->maMarkListCopy,
            mpOutliner->mpDrawDocument,
            mpOutliner->mpViewShell,
            mpOutliner->mbDirectionIsForward,
            aLocation);
    else
        // Search in the whole document.
        return CreateDocumentIterator (
            mpOutliner->mpDrawDocument,
            mpOutliner->mpViewShell,
            mpOutliner->mbDirectionIsForward,
            aLocation);
}

Iterator OutlinerContainer::CreateSelectionIterator (
    const ::std::vector<SdrObjectWeakRef>& rObjectList,
    SdDrawDocument* pDocument,
    const ::boost::shared_ptr<ViewShell>& rpViewShell,
    bool bDirectionIsForward, 
    IteratorLocation aLocation)
{
    OSL_ASSERT(rpViewShell.get());
    
    sal_Int32 nObjectIndex;

    if (bDirectionIsForward)
        switch (aLocation)
        {
            case CURRENT:
            case BEGIN: 
            default:
                nObjectIndex = 0;
                break;
            case END:
                nObjectIndex = rObjectList.size();
                break;
        }
    else
        switch (aLocation)
        {
            case CURRENT:
            case BEGIN: 
            default:
                nObjectIndex = rObjectList.size()-1;
                break;
            case END:
                nObjectIndex = -1;
                break;
        }

    return Iterator (new SelectionIteratorImpl (
        rObjectList, nObjectIndex, pDocument, rpViewShell, bDirectionIsForward));
}

Iterator OutlinerContainer::CreateDocumentIterator (
    SdDrawDocument* pDocument, 
    const ::boost::shared_ptr<ViewShell>& rpViewShell,
    bool bDirectionIsForward, 
    IteratorLocation aLocation)
{
    OSL_ASSERT(rpViewShell.get());
    
    PageKind ePageKind;
    EditMode eEditMode;

    switch (aLocation)
    {
        case BEGIN:
        default:
            if (bDirectionIsForward)
            {
                ePageKind = PK_STANDARD;
                eEditMode = EM_PAGE;
            }
            else
            {
                ePageKind = PK_HANDOUT;
                eEditMode = EM_MASTERPAGE;
            }
            break;
            
        case END:
            if (bDirectionIsForward)
            {
                ePageKind = PK_HANDOUT;
                eEditMode = EM_MASTERPAGE;
            }
            else
            {
                ePageKind = PK_STANDARD;
                eEditMode = EM_PAGE;
            }
            break;

        case CURRENT:
            const ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
                ::boost::dynamic_pointer_cast<DrawViewShell>(rpViewShell));
            if (pDrawViewShell.get())
            {
                ePageKind = pDrawViewShell->GetPageKind();
                eEditMode = pDrawViewShell->GetEditMode();
            }
            else
            {
                ePageKind = PK_STANDARD;
                eEditMode = EM_PAGE;
            }
            break;
    }

    sal_Int32 nPageIndex = GetPageIndex (pDocument, rpViewShell, 
        ePageKind, eEditMode, bDirectionIsForward, aLocation);

    return Iterator (
        new DocumentIteratorImpl (nPageIndex, ePageKind, eEditMode,
            pDocument, rpViewShell, bDirectionIsForward));
}

sal_Int32 OutlinerContainer::GetPageIndex (
    SdDrawDocument* pDocument,
    const ::boost::shared_ptr<ViewShell>& rpViewShell,
    PageKind ePageKind, 
    EditMode eEditMode,
    bool bDirectionIsForward,
    IteratorLocation aLocation)
{
    OSL_ASSERT(rpViewShell);
    
    sal_Int32 nPageIndex;
    sal_Int32 nPageCount;

    const ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
        ::boost::dynamic_pointer_cast<DrawViewShell>(rpViewShell));

    switch (eEditMode)
    {
        case EM_PAGE:
            nPageCount = pDocument->GetSdPageCount (ePageKind);
            break;
        case EM_MASTERPAGE:
            nPageCount = pDocument->GetMasterSdPageCount(ePageKind);
            break;
        default:
            nPageCount = 0;
    }

    switch (aLocation)
    {
        case CURRENT:
            if (pDrawViewShell.get())
                nPageIndex = pDrawViewShell->GetCurPageId() - 1;
            else
            {
                const SdPage* pPage = rpViewShell->GetActualPage();
                if (pPage != NULL)
                    nPageIndex = (pPage->GetPageNum()-1)/2;
                else
                    nPageIndex = 0;
            }
            break;

        case BEGIN: 
        default:
            if (bDirectionIsForward)
                nPageIndex = 0;
            else
                nPageIndex = nPageCount-1;
            break;

        case END:
            if (bDirectionIsForward)
                nPageIndex = nPageCount;
            else
                nPageIndex = -1;
            break;
    }

    return nPageIndex;
}




//===== IteratorImplBase ====================================================

IteratorImplBase::IteratorImplBase(SdDrawDocument* pDocument,
    const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
    bool bDirectionIsForward)
:	maPosition()
,	mpDocument (pDocument)
,	mpViewShellWeak (rpViewShellWeak)
,	mbDirectionIsForward (bDirectionIsForward)
{
    ::boost::shared_ptr<DrawViewShell> pDrawViewShell;
    if ( ! mpViewShellWeak.expired())
        pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(rpViewShellWeak.lock());

    if (pDrawViewShell.get())
    {
        maPosition.mePageKind = pDrawViewShell->GetPageKind();
        maPosition.meEditMode = pDrawViewShell->GetEditMode();
    }
    else
    {
        maPosition.mePageKind = PK_STANDARD;
        maPosition.meEditMode = EM_PAGE;
    }
}

IteratorImplBase::IteratorImplBase( SdDrawDocument* pDocument,
    const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
    bool bDirectionIsForward, PageKind ePageKind, EditMode eEditMode)
: maPosition()
, mpDocument (pDocument)
, mpViewShellWeak (rpViewShellWeak)
, mbDirectionIsForward (bDirectionIsForward)
{
    maPosition.mePageKind = ePageKind;
    maPosition.meEditMode = eEditMode;
}

IteratorImplBase::~IteratorImplBase (void)
{}

bool IteratorImplBase::operator== (const IteratorImplBase& rIterator) const
{
    return maPosition == rIterator.maPosition;
}

bool IteratorImplBase::IsEqual (const IteratorImplBase& rIterator, IteratorType ) const
{
    // When this method is executed instead of the ones from derived classes
    // then the argument is of another type then the object itself.  In this
    // just compare the position objects.
    return maPosition == rIterator.maPosition;
}

const IteratorPosition& IteratorImplBase::GetPosition (void)
{
    return maPosition;
}




IteratorImplBase* IteratorImplBase::Clone (IteratorImplBase* pObject) const
{
    if (pObject != NULL)
    {
        pObject->maPosition = maPosition;
        pObject->mpDocument = mpDocument;
        pObject->mpViewShellWeak = mpViewShellWeak;
        pObject->mbDirectionIsForward = mbDirectionIsForward;
    }
    return pObject;
}



void IteratorImplBase::Reverse (void)
{
    mbDirectionIsForward = ! mbDirectionIsForward;
}



//===== SelectionIteratorImpl ===========================================

SelectionIteratorImpl::SelectionIteratorImpl (
    const ::std::vector<SdrObjectWeakRef>& rObjectList,
    sal_Int32 nObjectIndex,
    SdDrawDocument* pDocument,
    const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
    bool bDirectionIsForward)
    : IteratorImplBase (pDocument, rpViewShellWeak, bDirectionIsForward),
      mrObjectList(rObjectList),
      mnObjectIndex(nObjectIndex)
{
}

SelectionIteratorImpl::~SelectionIteratorImpl (void)
{}

IteratorImplBase* SelectionIteratorImpl::Clone (IteratorImplBase* pObject) const
{
    SelectionIteratorImpl* pIterator = static_cast<SelectionIteratorImpl*>(pObject);
    if (pIterator == NULL)
        pIterator = new SelectionIteratorImpl (
            mrObjectList, mnObjectIndex, mpDocument, mpViewShellWeak, mbDirectionIsForward);
    return pIterator;
}


void SelectionIteratorImpl::GotoNextText (void)
{
    SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mrObjectList.at(mnObjectIndex).get() ); 
    if (mbDirectionIsForward)
    {
        if( pTextObj )
        {
            ++maPosition.mnText;
            if( maPosition.mnText >= pTextObj->getTextCount() )
            {
                maPosition.mnText = 0;
                ++mnObjectIndex;
            }			
        }
        else
        {
            ++mnObjectIndex;
        }
    }
    else
    {
        if( pTextObj )
        {
            --maPosition.mnText;
            if( maPosition.mnText < 0 )
            {
                maPosition.mnText = -1;
                --mnObjectIndex;
            }			
        }
        else
        {
            --mnObjectIndex;
            maPosition.mnText = -1;
        }

        if( (maPosition.mnText == -1) && (mnObjectIndex >= 0) )
        {
            pTextObj = dynamic_cast< SdrTextObj* >( mrObjectList.at(mnObjectIndex).get() ); 
            if( pTextObj )
                maPosition.mnText = pTextObj->getTextCount() - 1;
        }

        if( maPosition.mnText == -1 )
            maPosition.mnText = 0;
    }
}


const IteratorPosition& SelectionIteratorImpl::GetPosition (void)
{
    maPosition.mxObject = mrObjectList.at(mnObjectIndex);

    return maPosition;
}


bool SelectionIteratorImpl::operator== (const IteratorImplBase& rIterator) const
{
    return rIterator.IsEqual (*this, SELECTION);
}


bool SelectionIteratorImpl::IsEqual (
    const IteratorImplBase& rIterator,
    IteratorType aType) const
{
    if (aType == SELECTION)
    {
        const SelectionIteratorImpl* pSelectionIterator = 
            static_cast<const SelectionIteratorImpl*>(&rIterator);
        return mpDocument == pSelectionIterator->mpDocument 
            && mnObjectIndex == pSelectionIterator->mnObjectIndex;
    }
    else
        return false;
}




//===== ViewIteratorImpl ================================================

ViewIteratorImpl::ViewIteratorImpl (
    sal_Int32 nPageIndex,
    SdDrawDocument* pDocument,
    const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
    bool bDirectionIsForward)
    : IteratorImplBase (pDocument, rpViewShellWeak, bDirectionIsForward),
      mbPageChangeOccured(false),
      mpPage(NULL),
      mpObjectIterator(NULL)
{
    SetPage (nPageIndex);
}




ViewIteratorImpl::ViewIteratorImpl (
    sal_Int32 nPageIndex,
    SdDrawDocument* pDocument, 
    const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
    bool bDirectionIsForward,
    PageKind ePageKind,
    EditMode eEditMode)
    : IteratorImplBase (pDocument, rpViewShellWeak, bDirectionIsForward, ePageKind, eEditMode),
      mbPageChangeOccured(false),
      mpPage(NULL),
      mpObjectIterator(NULL)
{
    SetPage (nPageIndex);
}




ViewIteratorImpl::~ViewIteratorImpl (void)
{
}




IteratorImplBase* ViewIteratorImpl::Clone (IteratorImplBase* pObject) const
{
    
    ViewIteratorImpl* pIterator = static_cast<ViewIteratorImpl*>(pObject);
    if (pIterator == NULL)
        pIterator = new ViewIteratorImpl (
            maPosition.mnPageIndex, mpDocument, mpViewShellWeak, mbDirectionIsForward);

    IteratorImplBase::Clone (pObject);

    if (mpObjectIterator != NULL)
    {
        pIterator->mpObjectIterator = new SdrObjListIter(*mpPage, IM_DEEPNOGROUPS, !mbDirectionIsForward);

        // No direct way to set the object iterator to the current object.
        pIterator->maPosition.mxObject.reset(NULL);
        while (pIterator->mpObjectIterator->IsMore() && pIterator->maPosition.mxObject!=maPosition.mxObject)
            pIterator->maPosition.mxObject.reset(pIterator->mpObjectIterator->Next());
    }
    else
        pIterator->mpObjectIterator = NULL;

    return pIterator;
}



void ViewIteratorImpl::GotoNextText(void)
{
    SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( maPosition.mxObject.get() ); 
    if( pTextObj )
    {
        if (mbDirectionIsForward)
        {
            ++maPosition.mnText;
            if( maPosition.mnText < pTextObj->getTextCount() )
                return;
        }
        else
        {
            --maPosition.mnText;
            if( maPosition.mnText >= 0 )
                return;
        }
    }

    if (mpObjectIterator != NULL && mpObjectIterator->IsMore())
        maPosition.mxObject.reset(mpObjectIterator->Next());
    else
        maPosition.mxObject.reset(NULL);

    if (!maPosition.mxObject.is() )
    {
        if (mbDirectionIsForward)
            SetPage (maPosition.mnPageIndex+1);
        else
            SetPage (maPosition.mnPageIndex-1);

        if (mpPage != NULL)
            mpObjectIterator = new SdrObjListIter(*mpPage, IM_DEEPNOGROUPS, !mbDirectionIsForward);
        if (mpObjectIterator!=NULL && mpObjectIterator->IsMore())
            maPosition.mxObject.reset(mpObjectIterator->Next());
        else
            maPosition.mxObject.reset(NULL);
    }

    maPosition.mnText = 0;
    if( !mbDirectionIsForward && maPosition.mxObject.is() )
    {
        pTextObj = dynamic_cast< SdrTextObj* >( maPosition.mxObject.get() ); 
        if( pTextObj )
            maPosition.mnText = pTextObj->getTextCount() - 1;
    }
}




void ViewIteratorImpl::SetPage (sal_Int32 nPageIndex)
{
    mbPageChangeOccured = (maPosition.mnPageIndex!=nPageIndex);
    if (mbPageChangeOccured)
    {
        maPosition.mnPageIndex = nPageIndex;

        sal_Int32 nPageCount;
        if (maPosition.meEditMode == EM_PAGE)
            nPageCount = mpDocument->GetSdPageCount(maPosition.mePageKind);
        else
            nPageCount = mpDocument->GetMasterSdPageCount(
                maPosition.mePageKind);

        // Get page pointer.  Here we have three cases: regular pages,
        // master pages and invalid page indices.  The later ones are not
        // errors but the effect of the iterator advancing to the next page
        // and going past the last one.  This dropping of the rim at the far
        // side is detected here and has to be reacted to by the caller.
        if (nPageIndex>=0 && nPageIndex < nPageCount)
        {
            if (maPosition.meEditMode == EM_PAGE)
                mpPage = mpDocument->GetSdPage (
                    (USHORT)nPageIndex, 
                    maPosition.mePageKind);
            else
                mpPage = mpDocument->GetMasterSdPage (
                    (USHORT)nPageIndex, 
                    maPosition.mePageKind);
        }
        else
            mpPage = NULL;
    }

    // Set up object list iterator.
    if (mpPage != NULL)
        mpObjectIterator = new SdrObjListIter(*mpPage, IM_DEEPNOGROUPS, ! mbDirectionIsForward);
    else
        mpObjectIterator = NULL;

    // Get object pointer.
    if (mpObjectIterator!=NULL && mpObjectIterator->IsMore())
        maPosition.mxObject.reset( mpObjectIterator->Next() );
    else
        maPosition.mxObject.reset( NULL );

    maPosition.mnText = 0;
    if( !mbDirectionIsForward && maPosition.mxObject.is() )
    {
        SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( maPosition.mxObject.get() ); 
        if( pTextObj )
            maPosition.mnText = pTextObj->getTextCount() - 1;
    }

}




void ViewIteratorImpl::Reverse (void)
{
    IteratorImplBase::Reverse ();

    // Create reversed object list iterator.
    if (mpObjectIterator != NULL)
        delete mpObjectIterator;
    if (mpPage != NULL)
        mpObjectIterator = new SdrObjListIter(*mpPage, IM_DEEPNOGROUPS, ! mbDirectionIsForward);
    else
        mpObjectIterator = NULL;

    // Move iterator to the current object.
    SdrObjectWeakRef xObject = maPosition.mxObject;
    maPosition.mxObject.reset(NULL);
    while (mpObjectIterator->IsMore() && maPosition.mxObject != xObject)
        maPosition.mxObject.reset(mpObjectIterator->Next());
}




//===== DocumentIteratorImpl ============================================

DocumentIteratorImpl::DocumentIteratorImpl (
    sal_Int32 nPageIndex,
    PageKind ePageKind, EditMode eEditMode,
    SdDrawDocument* pDocument,
    const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
    bool bDirectionIsForward)
    : ViewIteratorImpl (nPageIndex, pDocument, rpViewShellWeak, bDirectionIsForward,
        ePageKind, eEditMode)
{
    if (eEditMode == EM_PAGE)
        mnPageCount = pDocument->GetSdPageCount (ePageKind);
    else
        mnPageCount = pDocument->GetMasterSdPageCount(ePageKind);
}




DocumentIteratorImpl::~DocumentIteratorImpl (void)
{}




IteratorImplBase* DocumentIteratorImpl::Clone (IteratorImplBase* pObject) const
{
    DocumentIteratorImpl* pIterator = static_cast<DocumentIteratorImpl*>(pObject);
    if (pIterator == NULL)
        pIterator = new DocumentIteratorImpl (
            maPosition.mnPageIndex, maPosition.mePageKind, maPosition.meEditMode,
            mpDocument, mpViewShellWeak, mbDirectionIsForward);
    // Finish the cloning.
    return ViewIteratorImpl::Clone (pIterator);
}




void DocumentIteratorImpl::GotoNextText (void)
{
    bool bSetToOnePastLastPage = false;
    bool bViewChanged = false;

    ViewIteratorImpl::GotoNextText();

    if (mbDirectionIsForward)
    {
        if (maPosition.mnPageIndex >= mnPageCount)
        {   
            // Switch to master page.
            if (maPosition.meEditMode == EM_PAGE)
            {
                maPosition.meEditMode = EM_MASTERPAGE;
                SetPage (0);
            }
            
            // Switch to next view mode.
            else
            {
                if (maPosition.mePageKind == PK_HANDOUT)
                    // Not really necessary but makes things more clear.
                    bSetToOnePastLastPage = true;
                else
                {
                    maPosition.meEditMode = EM_PAGE;
                    if (maPosition.mePageKind == PK_STANDARD)
                        maPosition.mePageKind = PK_NOTES;
                    else if (maPosition.mePageKind == PK_NOTES)
                        maPosition.mePageKind = PK_HANDOUT;
                    SetPage (0);
                }
            }
            bViewChanged = true;
        }
    }
    else
        if (maPosition.mnPageIndex < 0)
        {
            // Switch from master pages to draw pages.
            if (maPosition.meEditMode == EM_MASTERPAGE)
            {
                maPosition.meEditMode = EM_PAGE;
                bSetToOnePastLastPage = true;
            }
            
            // Switch to previous view mode.
            else
            {
                if (maPosition.mePageKind == PK_STANDARD)
                    SetPage (-1);
                else
                {
                    maPosition.meEditMode = EM_MASTERPAGE;
                    if (maPosition.mePageKind == PK_HANDOUT)
                        maPosition.mePageKind = PK_NOTES;
                    else if (maPosition.mePageKind == PK_NOTES)
                        maPosition.mePageKind = PK_STANDARD;
                    bSetToOnePastLastPage = true;
                }
            }
            bViewChanged = true;
        }

    if (bViewChanged)
    {
        // Get new page count;
        sal_Int32 nPageCount;
        if (maPosition.meEditMode == EM_PAGE)
            nPageCount = mpDocument->GetSdPageCount (maPosition.mePageKind);
        else
            nPageCount = mpDocument->GetMasterSdPageCount(maPosition.mePageKind);
                        
        // Now that we know the number of pages we can set the current page index.
        if (bSetToOnePastLastPage)
            SetPage (nPageCount);
    }
}


} } // end of namespace ::sd::outliner

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
