/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the 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->mpWeakViewShell.lock(),
            mpOutliner->mbDirectionIsForward,
            aLocation);
    else
        // Search in the whole document.
        return CreateDocumentIterator (
            mpOutliner->mpDrawDocument,
            mpOutliner->mpWeakViewShell.lock(),
            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 (
                    (sal_uInt16)nPageIndex,
                    maPosition.mePageKind);
            else
                mpPage = mpDocument->GetMasterSdPage (
                    (sal_uInt16)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
