/**************************************************************
 *
 * 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 "Outliner.hxx"
#include <vcl/wrkwin.hxx>
#include <svl/srchitem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/eeitem.hxx>
#include <editeng/editstat.hxx>
#include <vcl/outdev.hxx>
#include <svx/dlgutil.hxx>
#include <svx/xtable.hxx>
#include <vcl/msgbox.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/printer.hxx>
#include <svx/svxerr.hxx>
#include <svx/svdotext.hxx>
#include <editeng/unolingu.hxx>
#include <svx/svditer.hxx>
#include <comphelper/extract.hxx>
#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <comphelper/processfactory.hxx>
#include <editeng/eeitem.hxx>
#include <editeng/forbiddencharacterstable.hxx>
#include <svx/srchdlg.hxx>
#include <unotools/linguprops.hxx>
#include <unotools/lingucfg.hxx>
#include <editeng/editeng.hxx>
#include <vcl/metric.hxx>
#include <sfx2/viewfrm.hxx>
#include <svtools/langtab.hxx>
#include <tools/diagnose_ex.h>

#include "strings.hrc"
#include "sdstring.hrc"
#include "eetext.hxx"
#include "sdpage.hxx"
#include "app.hxx"
#include "Window.hxx"
#include "sdresid.hxx"
#include "DrawViewShell.hxx"
#include "OutlineViewShell.hxx"
#include "drawdoc.hxx"
#include "DrawDocShell.hxx"
#include "FrameView.hxx"
#include "optsitem.hxx"
#include "drawview.hxx"
#include "ViewShellBase.hxx"
#include "SpellDialogChildWindow.hxx"
#include "ToolBarManager.hxx"
#include "framework/FrameworkHelper.hxx"
#include <svx/svxids.hrc>
#include <editeng/editerr.hxx>

using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::linguistic2;

class SfxStyleSheetPool;

namespace sd {

class Outliner::Implementation
{
public:
    /** The original edit mode directly after switching to a different view
        mode.  Used for restoring the edit mode when leaving that view mode
        again.
    */
	EditMode meOriginalEditMode;

    Implementation (void);
    ~Implementation (void);

    /** Return the OutlinerView that was provided by the last call to
        ProvideOutlinerView() (or NULL when there was no such call.)
    */
    OutlinerView* GetOutlinerView (void);

    /** Provide in the member mpOutlineView an instance of OutlinerView that
        is either taken from the ViewShell, when it is an OutlineViewShell,
        or is created.  When an OutlinerView already exists it is initialized.
    */
    void ProvideOutlinerView (
        Outliner& rOutliner,
        const ::boost::shared_ptr<ViewShell>& rpViewShell,
        ::Window* pWindow);

    /** This method is called when the OutlinerView is no longer used.
    */
    void ReleaseOutlinerView (void);

private:
    /** Flag that specifies whether we own the outline view pointed to by
        <member>mpOutlineView</member> and thus have to
        delete it in <member>EndSpelling()</member>.
    */
    bool mbOwnOutlineView;

    /** The outline view used for searching and spelling.  If searching or
        spell checking an outline view this data member points to that view.
        For all other views an instance is created.  The
        <member>mbOwnOutlineView</member> distinguishes between both cases.
    */
	OutlinerView* mpOutlineView;
};




/*************************************************************************
|*
|* Ctor
|*
\************************************************************************/

Outliner::Outliner( SdDrawDocument* pDoc, sal_uInt16 nMode )
    : SdrOutliner( &pDoc->GetItemPool(), nMode ),
      mpImpl(new Implementation()),
      meMode(SEARCH),
      mpView(NULL),
      mpWeakViewShell(),
      mpWindow(NULL),
      mpDrawDocument(pDoc),
      mnConversionLanguage(LANGUAGE_NONE),
      mnIgnoreCurrentPageChangesLevel(0),
      mbStringFound(sal_False),
      mbMatchMayExist(false),
      mnPageCount(0),
      mnObjectCount(0),
      mbEndOfSearch(sal_False),
      mbFoundObject(sal_False),
      mbError(sal_False),
      mbDirectionIsForward(true),
      mbRestrictSearchToSelection(false),
      maMarkListCopy(),
      mbProcessCurrentViewOnly(false),
      mpObj(NULL),
	  mpFirstObj(NULL),
      mpTextObj(NULL),
	  mnText(0),
      mpParaObj(NULL),
      meStartViewMode(PK_STANDARD),
      meStartEditMode(EM_PAGE),
      mnStartPageIndex((sal_uInt16)-1),
      mpStartEditedObject(NULL),
      maStartSelection(),
      mpSearchItem(NULL),
      maObjectIterator(),
      maCurrentPosition(),
      maSearchStartPosition(),
      maLastValidPosition(),
      mbSelectionHasChanged(false),
      mbExpectingSelectionChangeEvent(false),
      mbWholeDocumentProcessed(false),
      mbPrepareSpellingPending(true)
{
    SetStyleSheetPool((SfxStyleSheetPool*) mpDrawDocument->GetStyleSheetPool());
	SetEditTextObjectPool( &pDoc->GetItemPool() );
	SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
	SetForbiddenCharsTable( pDoc->GetForbiddenCharsTable() );

	sal_uLong nCntrl = GetControlWord();
	nCntrl |= EE_CNTRL_ALLOWBIGOBJS;
	nCntrl |= EE_CNTRL_URLSFXEXECUTE;
	nCntrl |= EE_CNTRL_MARKFIELDS;
	nCntrl |= EE_CNTRL_AUTOCORRECT;

    sal_Bool bOnlineSpell = false;

	DrawDocShell* pDocSh = mpDrawDocument->GetDocSh();

	if (pDocSh)
	{
		bOnlineSpell = mpDrawDocument->GetOnlineSpell();
	}
	else
	{
        bOnlineSpell = false;

		try
		{
            const SvtLinguConfig    aLinguConfig;
            Any                     aAny;

		    aAny = aLinguConfig.GetProperty(
                rtl::OUString::createFromAscii( UPN_IS_SPELL_AUTO ) );
		    aAny >>= bOnlineSpell;
		}
		catch( ... )
		{
			DBG_ERROR( "Ill. type in linguistic property" );
		}
	}

	if (bOnlineSpell)
		nCntrl |= EE_CNTRL_ONLINESPELLING;
	else
		nCntrl &= ~EE_CNTRL_ONLINESPELLING;

	SetControlWord(nCntrl);

	Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
	if ( xSpellChecker.is() )
		SetSpeller( xSpellChecker );

	Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
	if( xHyphenator.is() )
		SetHyphenator( xHyphenator );

	SetDefaultLanguage( Application::GetSettings().GetLanguage() );
}




/// Nothing spectecular in the destructor.
Outliner::~Outliner (void)
{
    mpImpl.reset();
}




/** Prepare find&replace or spellchecking.  This distinguishes between three
    cases:
    <ol>
    <li>The current shell is a <type>DrawViewShell</type>: Create a
    <type>OutlinerView</type> object and search all objects of (i) the
    current mark list, (ii) of the current view, or (iii) of all the view
    combinations:
    <ol>
    <li>Draw view, slide view</li>
    <li>Draw view, background view</li>
    <li>Notes view, slide view</li>
    <li>Notes view, background view</li>
    <li>Handout view, slide view</li>
    <li>Handout view, background view</li>
    </ol>

    <li>When the current shell is a <type>SdOutlineViewShell</type> then
    directly operate on it.  No switching into other views takes place.</li>

    <li>For a <type>SlideViewShell</type> no action is performed.</li>
    </ol>
*/
void Outliner::PrepareSpelling (void)
{
    mbPrepareSpellingPending = false;

    ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
    if (pBase != NULL)
        SetViewShell (pBase->GetMainViewShell());
    SetRefDevice( SD_MOD()->GetRefDevice( *mpDrawDocument->GetDocSh() ) );

    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    if (pViewShell)
    {
        mbStringFound = sal_False;

        mbWholeDocumentProcessed = false;
        // Supposed that we are not located at the very beginning/end of
        // the document then there may be a match in the document
        // prior/after the current position.
        mbMatchMayExist = sal_True;

        maObjectIterator = ::sd::outliner::Iterator();
        maSearchStartPosition = ::sd::outliner::Iterator();
        RememberStartPosition();

        mpImpl->ProvideOutlinerView(*this, pViewShell, mpWindow);

        HandleChangedSelection ();
    }
    ClearModifyFlag();
}





void Outliner::StartSpelling (void)
{
    meMode = SPELL;
    mbDirectionIsForward = true;
    mpSearchItem = NULL;
}

/** Proxy for method from base class to avoid compiler warning */
void Outliner::StartSpelling(EditView& rView, unsigned char c)
{
	SdrOutliner::StartSpelling( rView, c );
}

/** Free all resources acquired during the search/spell check.  After a
    spell check the start position is restored here.
*/
void Outliner::EndSpelling (void)
{
    // Keep old view shell alive until we release the outliner view.
    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    ::boost::shared_ptr<ViewShell> pOldViewShell (pViewShell);

    ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
    if (pBase != NULL)
        pViewShell = pBase->GetMainViewShell();
    else
        pViewShell.reset();
    mpWeakViewShell = pViewShell;

    // When in <member>PrepareSpelling()</member> a new outline view has
    // been created then delete it here.
    sal_Bool bViewIsDrawViewShell(pViewShell && pViewShell->ISA(DrawViewShell));
    if (bViewIsDrawViewShell)
    {
        SetStatusEventHdl(Link());
        mpView = pViewShell->GetView();
        mpView->UnmarkAllObj (mpView->GetSdrPageView());
        mpView->SdrEndTextEdit();
        // Make FuSelection the current function.
        pViewShell->GetDispatcher()->Execute(
            SID_OBJECT_SELECT,
            SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);

        // Remove and, if previously created by us, delete the outline
        // view.
        OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
        if (pOutlinerView != NULL)
        {
            RemoveView(pOutlinerView);
            mpImpl->ReleaseOutlinerView();
        }

        SetUpdateMode(sal_True);
    }

    // #95811# Before clearing the modify flag use it as a hint that
    // changes were done at SpellCheck
    if(IsModified())
    {
        if(mpView && mpView->ISA(OutlineView))
            static_cast<OutlineView*>(mpView)->PrepareClose(sal_False);
        if(mpDrawDocument && !mpDrawDocument->IsChanged())
            mpDrawDocument->SetChanged(sal_True);
    }

    // #95811# now clear the modify flag to have a specified state of
    // Outliner
    ClearModifyFlag();

    // When spell checking then restore the start position.
    if (meMode==SPELL || meMode==TEXT_CONVERSION)
        RestoreStartPosition ();

    mpWeakViewShell.reset();
    mpView = NULL;
    mpWindow = NULL;
}




sal_Bool Outliner::SpellNextDocument (void)
{
    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    if (pViewShell->ISA(OutlineViewShell))
    {
        // When doing a spell check in the outline view then there is
        // only one document.
        mbEndOfSearch = true;
        EndOfSearch ();
    }
    else
    {
        if (mpView->ISA(OutlineView))
            ((OutlineView*)mpView)->PrepareClose(sal_False);
        mpDrawDocument->GetDocSh()->SetWaitCursor( sal_True );

        Initialize (true);

        mpWindow = pViewShell->GetActiveWindow();
        OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
        if (pOutlinerView != NULL)
            pOutlinerView->SetWindow(mpWindow);
        ProvideNextTextObject ();

        mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
        ClearModifyFlag();
    }

    return mbEndOfSearch ? sal_False : sal_True;

}


/*************************************************************************
|*
|* Spelling: naechstes TextObjekt pruefen
|*
\************************************************************************/

::svx::SpellPortions Outliner::GetNextSpellSentence (void)
{
    ::svx::SpellPortions aResult;

    DetectChange();
    // Iterate over sentences and text shapes until a sentence with a
    // spelling error has been found.  If no such sentence can be
    // found the loop is left through a break.
    // It is the responsibility of the sd outliner object to correctly
    // iterate over all text shapes, i.e. switch between views, wrap
    // around at the end of the document, stop when all text shapes
    // have been examined exactly once.
    bool bFoundNextSentence = false;
    while ( ! bFoundNextSentence)
    {
        OutlinerView* pOutlinerView = GetView(0);
        if (pOutlinerView != NULL)
        {
            ESelection aCurrentSelection (pOutlinerView->GetSelection());
            if ( ! mbMatchMayExist
                && maStartSelection.IsLess(aCurrentSelection))
                EndOfSearch();

            // Advance to the next sentence.
            bFoundNextSentence = SpellSentence (
                pOutlinerView->GetEditView(),
                aResult, false);
        }

        // When no sentence with spelling errors has been found in the
        // currently selected text shape or there is no selected text
        // shape then advance to the next text shape.
        if ( ! bFoundNextSentence)
            if ( ! SpellNextDocument())
                // All text objects have been processed so exit the
                // loop and return an empty portions list.
                break;
    }

    return aResult;
}




/** Go to next match.
*/
bool Outliner::StartSearchAndReplace (const SvxSearchItem* pSearchItem)
{
    sal_Bool bEndOfSearch = sal_True;

    mpDrawDocument->GetDocSh()->SetWaitCursor( sal_True );
    if (mbPrepareSpellingPending)
        PrepareSpelling();
    ViewShellBase* pBase = PTR_CAST(ViewShellBase,SfxViewShell::Current());
    // Determine whether we have to abort the search.  This is necessary
    // when the main view shell does not support searching.
    bool bAbort = false;
    if (pBase != NULL)
    {
        ::boost::shared_ptr<ViewShell> pShell (pBase->GetMainViewShell());
        SetViewShell(pShell);
        if (pShell.get() == NULL)
            bAbort = true;
        else
            switch (pShell->GetShellType())
            {
                case ViewShell::ST_DRAW:
                case ViewShell::ST_IMPRESS:
                case ViewShell::ST_NOTES:
                case ViewShell::ST_HANDOUT:
                case ViewShell::ST_OUTLINE:
                    bAbort = false;
                    break;
                default:
                    bAbort = true;
                    break;
            }
    }

    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    if ( ! pViewShell)
    {
        OSL_ASSERT(pViewShell);
        return true;
    }

    if ( ! bAbort)
    {
        meMode = SEARCH;
        mpSearchItem = pSearchItem;

        mbFoundObject = sal_False;

        Initialize ( ! mpSearchItem->GetBackward());

        const sal_uInt16 nCommand (mpSearchItem->GetCommand());
        if (nCommand == SVX_SEARCHCMD_REPLACE_ALL)
            bEndOfSearch = SearchAndReplaceAll ();
        else
        {
            RememberStartPosition ();
            bEndOfSearch = SearchAndReplaceOnce ();
            //#107233# restore start position if nothing was found
            if(!mbStringFound)
                RestoreStartPosition ();
            else
                mnStartPageIndex = (sal_uInt16)-1;
        }
	if ( Application::IsAccessibilityEnabled() )
	{
		SvxSearchDialog* pSearchDlg =
			((SvxSearchDialog*)(SfxViewFrame::Current()->GetChildWindow(
			SvxSearchDialogWrapper::GetChildWindowId())->GetWindow()));
		pSearchDlg->SetDocWin( pViewShell->GetActiveWindow() );
		pSearchDlg->SetSrchFlag();
	}
        }
    else
        mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );

    return bEndOfSearch;
}




void Outliner::Initialize (bool bDirectionIsForward)
{
    const bool bIsAtEnd (maObjectIterator == ::sd::outliner::OutlinerContainer(this).end());
    const bool bOldDirectionIsForward = mbDirectionIsForward;
    mbDirectionIsForward = bDirectionIsForward;

    if (maObjectIterator == ::sd::outliner::Iterator())
    {
        // Initialize a new search.
        maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
        maCurrentPosition = *maObjectIterator;

        ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
        if ( ! pViewShell)
        {
            OSL_ASSERT(pViewShell);
            return;
        }

        // In case we are searching in an outline view then first remove the
        // current selection and place cursor at its start or end.
		if (pViewShell->ISA(OutlineViewShell))
        {
            ESelection aSelection = mpImpl->GetOutlinerView()->GetSelection ();
            if (mbDirectionIsForward)
            {
                aSelection.nEndPara = aSelection.nStartPara;
                aSelection.nEndPos = aSelection.nStartPos;
            }
            else
            {
                aSelection.nStartPara = aSelection.nEndPara;
                aSelection.nStartPos = aSelection.nEndPos;
            }
            mpImpl->GetOutlinerView()->SetSelection (aSelection);
        }

        // When not beginning the search at the beginning of the search area
        // then there may be matches before the current position.
        mbMatchMayExist = (maObjectIterator!=::sd::outliner::OutlinerContainer(this).begin());
    }
    else if (bOldDirectionIsForward != mbDirectionIsForward)
    {
        // Requested iteration direction has changed.  Turn around the iterator.
        maObjectIterator.Reverse();
        if (bIsAtEnd)
        {
            // The iterator has pointed to end(), which after the search
            // direction is reversed, becomes begin().
            maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
        }
        else
        {
            // The iterator has pointed to the object one ahead/before the current
            // one.  Now move it to the one before/ahead the current one.
            ++maObjectIterator;
            ++maObjectIterator;
        }

        mbMatchMayExist = true;
    }

    // Initialize the last valid position with where the search starts so
    // that it always points to a valid position.
    maLastValidPosition = *::sd::outliner::OutlinerContainer(this).current();
}




bool Outliner::SearchAndReplaceAll (void)
{
    // Save the current position to be restored after having replaced all
    // matches.
    RememberStartPosition ();

    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    if ( ! pViewShell)
    {
        OSL_ASSERT(pViewShell);
        return true;
    }

    if (pViewShell->ISA(OutlineViewShell))
    {
        // Put the cursor to the beginning/end of the outliner.
        mpImpl->GetOutlinerView()->SetSelection (GetSearchStartPosition ());

        // The outliner does all the work for us when we are in this mode.
        SearchAndReplaceOnce();
    }
    else if (pViewShell->ISA(DrawViewShell))
    {
        // Go to beginning/end of document.
        maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
        // Switch to the current object only if it is a valid text object.
        ::sd::outliner::IteratorPosition aNewPosition (*maObjectIterator);
        if (IsValidTextObject (aNewPosition))
        {
            maCurrentPosition = aNewPosition;
            SetObject (maCurrentPosition);
        }

        // Search/replace until the end of the document is reached.
        bool bFoundMatch;
        do
        {
            bFoundMatch = ! SearchAndReplaceOnce();
        }
        while (bFoundMatch);
    }

    RestoreStartPosition ();

    return true;
}




bool Outliner::SearchAndReplaceOnce (void)
{
    DetectChange ();

    OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
	DBG_ASSERT(pOutlinerView!=NULL && GetEditEngine().HasView( &pOutlinerView->GetEditView() ),
        "SearchAndReplace without valid view!" );

	if( NULL == pOutlinerView || !GetEditEngine().HasView( &pOutlinerView->GetEditView() ) )
		return true;

    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
	if( bool(pViewShell))
	{
		mpView = pViewShell->GetView();
		mpWindow = pViewShell->GetActiveWindow();
		pOutlinerView->SetWindow(mpWindow);

		if (pViewShell->ISA(DrawViewShell) )
		{
            // When replacing we first check if there is a selection
            // indicating a match.  If there is then replace it.  The
            // following call to StartSearchAndReplace will then search for
            // the next match.
            if (meMode == SEARCH
                && mpSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
                if (pOutlinerView->GetSelection().HasRange())
                    pOutlinerView->StartSearchAndReplace(*mpSearchItem);

            // Search for the next match.
            sal_uLong nMatchCount = 0;
            if (mpSearchItem->GetCommand() != SVX_SEARCHCMD_REPLACE_ALL)
                nMatchCount = pOutlinerView->StartSearchAndReplace(*mpSearchItem);

            // Go to the next text object when there have been no matches in
            // the current object or the whole object has already been
            // processed.
            if (nMatchCount==0 || mpSearchItem->GetCommand()==SVX_SEARCHCMD_REPLACE_ALL)
            {
                ProvideNextTextObject ();

                if ( ! mbEndOfSearch)
                {
                    // Remember the current position as the last one with a
                    // text object.
                    maLastValidPosition = maCurrentPosition;

                    // Now that the mbEndOfSearch flag guards this block the
                    // following assertion and return should not be
                    // necessary anymore.
                    DBG_ASSERT(GetEditEngine().HasView(&pOutlinerView->GetEditView() ),
                        "SearchAndReplace without valid view!" );
                    if ( ! GetEditEngine().HasView( &pOutlinerView->GetEditView() ) )
                    {
                        mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
                        return true;
                    }

                    if (meMode == SEARCH)
                        nMatchCount = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
                }
            }
		}
		else if (pViewShell->ISA(OutlineViewShell))
		{
            mpDrawDocument->GetDocSh()->SetWaitCursor (sal_False);
            // The following loop is executed more then once only when a
            // wrap around search is done.
            while (true)
            {
                int nResult = pOutlinerView->StartSearchAndReplace(*mpSearchItem);
                if (nResult == 0)
                {
                    if (HandleFailedSearch ())
                    {
                        pOutlinerView->SetSelection (GetSearchStartPosition ());
                        continue;
                    }
                }
                else
                    mbStringFound = true;
                break;
            }
		}
	}

	mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );

	return mbEndOfSearch;
}




/** Try to detect whether the document or the view (shell) has changed since
    the last time <member>StartSearchAndReplace()</member> has been called.
*/
void Outliner::DetectChange (void)
{
    ::sd::outliner::IteratorPosition aPosition (maCurrentPosition);

    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
        ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell));

    // Detect whether the view has been switched from the outside.
    if (pDrawViewShell.get() != NULL
        && (aPosition.meEditMode != pDrawViewShell->GetEditMode()
            || aPosition.mePageKind != pDrawViewShell->GetPageKind()))
    {
        // Either the edit mode or the page kind has changed.
        SetStatusEventHdl(Link());

        SdrPageView* pPageView = mpView->GetSdrPageView();
        if (pPageView != NULL)
            mpView->UnmarkAllObj (pPageView);
        mpView->SdrEndTextEdit();
        SetUpdateMode(sal_False);
        OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
        if (pOutlinerView != NULL)
            pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1) ) );
        if (meMode == SPELL)
            SetPaperSize( Size(1, 1) );
        SetText( String(), GetParagraph( 0 ) );

        RememberStartPosition ();

        mnPageCount = mpDrawDocument->GetSdPageCount(pDrawViewShell->GetPageKind());
        maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
    }

    // Detect change of the set of selected objects.  If their number has
    // changed start again with the first selected object.
    else if (DetectSelectionChange())
	{
        HandleChangedSelection ();
        maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
	}

    // Detect change of page count.  Restart search at first/last page in
    // that case.
	else if (aPosition.meEditMode == EM_PAGE
        && mpDrawDocument->GetSdPageCount(aPosition.mePageKind) != mnPageCount)
    {
        // The number of pages has changed.
        mnPageCount = mpDrawDocument->GetSdPageCount(aPosition.mePageKind);
        maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
    }
    else if (aPosition.meEditMode == EM_MASTERPAGE
        && mpDrawDocument->GetSdPageCount(aPosition.mePageKind) != mnPageCount)
	{
        // The number of master pages has changed.
        mnPageCount = mpDrawDocument->GetSdPageCount(aPosition.mePageKind);
        maObjectIterator = ::sd::outliner::OutlinerContainer(this).current();
	}
}




bool Outliner::DetectSelectionChange (void)
{
    bool bSelectionHasChanged = false;
    sal_uLong nMarkCount = mpView->GetMarkedObjectList().GetMarkCount();

    // If mpObj is NULL then we have not yet found our first match.
    // Detecting a change makes no sense.
    if (mpObj != NULL)
        switch (nMarkCount)
        {
            case 0:
                // The selection has changed when previously there have been
                // selected objects.
                bSelectionHasChanged = mbRestrictSearchToSelection;
                break;
            case 1:
                // Check if the only selected object is not the one that we
                // had selected.
                if (mpView != NULL)
                {
                    SdrMark* pMark = mpView->GetMarkedObjectList().GetMark(0);
                    if (pMark != NULL)
                        bSelectionHasChanged = (mpObj != pMark->GetMarkedSdrObj ());
                }
                break;
            default:
                // We had selected exactly one object.
                bSelectionHasChanged = true;
                break;
        }

    return bSelectionHasChanged;
}




void Outliner::RememberStartPosition (void)
{
    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    if ( ! pViewShell)
    {
        OSL_ASSERT(pViewShell);
        return;
    }

    if (pViewShell->ISA(DrawViewShell))
    {
        ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
            ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell));
        if (pDrawViewShell.get() != NULL)
        {
            meStartViewMode = pDrawViewShell->GetPageKind();
            meStartEditMode = pDrawViewShell->GetEditMode();
            mnStartPageIndex = pDrawViewShell->GetCurPageId() - 1;
        }

        if (mpView != NULL)
        {
            mpStartEditedObject = mpView->GetTextEditObject();
            if (mpStartEditedObject != NULL)
            {
                // Try to retrieve current caret position only when there is an
                // edited object.
                ::Outliner* pOutliner =
                    static_cast<DrawView*>(mpView)->GetTextEditOutliner();
                if (pOutliner!=NULL && pOutliner->GetViewCount()>0)
                {
                    OutlinerView* pOutlinerView = pOutliner->GetView(0);
                    maStartSelection = pOutlinerView->GetSelection();
                }
            }
        }
    }
    else if (pViewShell->ISA(OutlineViewShell))
    {
        // Remember the current cursor position.
        OutlinerView* pView = GetView(0);
        if (pView != NULL)
            pView->GetSelection();
    }
    else
    {
        mnStartPageIndex = (sal_uInt16)-1;
    }
}




void Outliner::RestoreStartPosition (void)
{
    bool bRestore = true;
    // Take a negative start page index as indicator that restoring the
    // start position is not requested.
    if (mnStartPageIndex == (sal_uInt16)-1 )
        bRestore = false;
    // Dont't restore when the view shell is not valid.
    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    if( !bool(pViewShell))
        bRestore = false;

    if (bRestore)
    {
        if (pViewShell->ISA(DrawViewShell))
        {
            ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
                ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell));
            SetViewMode (meStartViewMode);
            if (pDrawViewShell.get() != NULL)
                SetPage (meStartEditMode, mnStartPageIndex);


            if (mpStartEditedObject != NULL)
            {
                // Turn on the text toolbar as it is done in FuText so that
                // undo manager setting/restoring in
                // sd::View::{Beg,End}TextEdit() works on the same view shell.
                pViewShell->GetViewShellBase().GetToolBarManager()->SetToolBarShell(
                    ToolBarManager::TBG_FUNCTION,
                    RID_DRAW_TEXT_TOOLBOX);

                mpView->SdrBeginTextEdit(mpStartEditedObject);
                ::Outliner* pOutliner =
                      static_cast<DrawView*>(mpView)->GetTextEditOutliner();
                if (pOutliner!=NULL && pOutliner->GetViewCount()>0)
                {
                    OutlinerView* pOutlinerView = pOutliner->GetView(0);
                    pOutlinerView->SetSelection(maStartSelection);
                }
            }
        }
        else if (pViewShell->ISA(OutlineViewShell))
        {
            // Set cursor to its old position.
            OutlinerView* pView = GetView(0);
            if (pView != NULL)
                pView->SetSelection (maStartSelection);
        }
    }
}




/** The main purpose of this method is to iterate over all shape objects of
    the search area (current selection, current view, or whole document)
    until a text object has been found that contains at least one match or
    until no such object can be found anymore.   These two conditions are
    expressed by setting one of the flags <member>mbFoundObject</member> or
    <member>mbEndOfSearch</member> to <TRUE/>.
*/
void Outliner::ProvideNextTextObject (void)
{
    mbEndOfSearch = false;
    mbFoundObject = false;

    mpView->UnmarkAllObj (mpView->GetSdrPageView());
    try
    {
	    mpView->SdrEndTextEdit();
    }
    catch (::com::sun::star::uno::Exception e)
    {
        DBG_UNHANDLED_EXCEPTION();
    }
	SetUpdateMode(sal_False);
    OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
    if (pOutlinerView != NULL)
        pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1) ) );
    if (meMode == SPELL)
        SetPaperSize( Size(1, 1) );
	SetText( String(), GetParagraph( 0 ) );

	mpTextObj = NULL;

    // Iterate until a valid text object has been found or the search ends.
	do
	{
		mpObj = NULL;
		mpParaObj = NULL;

        if (maObjectIterator != ::sd::outliner::OutlinerContainer(this).end())
        {
            maCurrentPosition = *maObjectIterator;
            // Switch to the current object only if it is a valid text object.
            if (IsValidTextObject (maCurrentPosition))
            {
                mpObj = SetObject (maCurrentPosition);
            }
            ++maObjectIterator;

            if (mpObj != NULL)
            {
                PutTextIntoOutliner ();

                ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
                if( bool(pViewShell))
                    switch (meMode)
                    {
                        case SEARCH:
                            PrepareSearchAndReplace ();
                            break;
                        case SPELL:
                            PrepareSpellCheck ();
                            break;
                        case TEXT_CONVERSION:
                            PrepareConversion();
                            break;
                    }
            }
        }
        else
        {
            mbEndOfSearch = true;
            EndOfSearch ();
        }
	}
	while ( ! (mbFoundObject || mbEndOfSearch));
}




void Outliner::EndOfSearch (void)
{
    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    if ( ! pViewShell)
    {
        OSL_ASSERT(pViewShell);
        return;
    }

    // Before we display a dialog we first jump to where the last valid text
    // object was found.  All page and view mode switching since then was
    // temporary and should not be visible to the user.
    if ( ! pViewShell->ISA(OutlineViewShell))
        SetObject (maLastValidPosition);

    if (mbRestrictSearchToSelection)
        ShowEndOfSearchDialog ();
    else
    {
        // When no match has been found so far then terminate the search.
        if ( ! mbMatchMayExist)
        {
            ShowEndOfSearchDialog ();
            mbEndOfSearch = sal_True;
        }
        // Ask the user whether to wrap around and continue the search or
        // to terminate.
        else if (meMode==TEXT_CONVERSION || ShowWrapArroundDialog ())
        {
            mbMatchMayExist = false;
            // Everything back to beginning (or end?) of the document.
            maObjectIterator = ::sd::outliner::OutlinerContainer(this).begin();
            if (pViewShell->ISA(OutlineViewShell))
            {
                // Set cursor to first character of the document.
                OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
                if (pOutlinerView != NULL)
                    pOutlinerView->SetSelection (GetSearchStartPosition ());
            }

            mbEndOfSearch = false;
        }
        else
        {
            // No wrap around.
            mbEndOfSearch = true;
        }
    }
}

void Outliner::ShowEndOfSearchDialog (void)
{
    String aString;
    if (meMode == SEARCH)
    {
        if (mbStringFound)
            aString = String( SdResId(STR_END_SEARCHING) );
        else
            aString = String( SdResId(STR_STRING_NOTFOUND) );
    }
    else
    {
        if (mpView->AreObjectsMarked())
            aString = String(SdResId(STR_END_SPELLING_OBJ));
        else
            aString = String(SdResId(STR_END_SPELLING));
    }

    // Show the message in an info box that is modal with respect to the
    // whole application.
    InfoBox aInfoBox (NULL, aString);
    ShowModalMessageBox (aInfoBox);

    mbWholeDocumentProcessed = true;
}




bool Outliner::ShowWrapArroundDialog (void)
{
    bool bDoWrapArround = false;

    // Determine whether to show the dialog.
    bool bShowDialog = false;
    if (mpSearchItem != NULL)
    {
        // When searching display the dialog only for single find&replace.
        sal_uInt16 nCommand = mpSearchItem->GetCommand();
        bShowDialog = (nCommand==SVX_SEARCHCMD_REPLACE)
            || (nCommand==SVX_SEARCHCMD_FIND);
    }
    else
        // Spell checking needs the dialog, too.
        bShowDialog = (meMode == SPELL);

    if (bShowDialog)
    {
        // The question text depends on the search direction.
        sal_Bool bImpress = mpDrawDocument!=NULL
            && mpDrawDocument->GetDocumentType() == DOCUMENT_TYPE_IMPRESS;
        sal_uInt16 nStringId;
        if (mbDirectionIsForward)
            nStringId = bImpress
                ? STR_SAR_WRAP_FORWARD
                : STR_SAR_WRAP_FORWARD_DRAW;
        else
            nStringId = bImpress
                ? STR_SAR_WRAP_BACKWARD
                : STR_SAR_WRAP_BACKWARD_DRAW;

        // Pop up question box that asks the user whether to wrap around.
        // The dialog is made modal with respect to the whole application.
        QueryBox aQuestionBox (
            NULL,
            WB_YES_NO | WB_DEF_YES,
            String(SdResId(nStringId)));
        aQuestionBox.SetImage (QueryBox::GetStandardImage());
        sal_uInt16 nBoxResult = ShowModalMessageBox(aQuestionBox);
        bDoWrapArround = (nBoxResult == BUTTONID_YES);
    }

    return bDoWrapArround;
}




bool Outliner::IsValidTextObject (const ::sd::outliner::IteratorPosition& rPosition)
{
    SdrTextObj* pObject = dynamic_cast< SdrTextObj* >( rPosition.mxObject.get() );
    return (pObject != NULL) && pObject->HasText() && ! pObject->IsEmptyPresObj();
}




void Outliner::PutTextIntoOutliner()
{
	mpTextObj = dynamic_cast<SdrTextObj*>( mpObj );
    if ( mpTextObj && mpTextObj->HasText() && !mpTextObj->IsEmptyPresObj() )
    {
		SdrText* pText = mpTextObj->getText( mnText );
		mpParaObj = pText ? pText->GetOutlinerParaObject() : NULL;

        if (mpParaObj != NULL)
        {
            SetText(*mpParaObj);

            ClearModifyFlag();
        }
    }
    else
    {
        mpTextObj = NULL;
    }
}




void Outliner::PrepareSpellCheck (void)
{
    EESpellState eState = HasSpellErrors();
    DBG_ASSERT(eState != EE_SPELL_NOSPELLER, "No SpellChecker");

    if (eState == EE_SPELL_NOLANGUAGE)
    {
        mbError = sal_True;
        mbEndOfSearch = sal_True;
        ErrorBox aErrorBox (NULL,
            WB_OK,
            String(SdResId(STR_NOLANGUAGE)));
        ShowModalMessageBox (aErrorBox);
    }
    else if (eState != EE_SPELL_OK)
    {
        // When spell checking we have to test whether we have processed the
        // whole document and have reached the start page again.
        if (meMode == SPELL)
        {
            if (maSearchStartPosition == ::sd::outliner::Iterator())
                // Remember the position of the first text object so that we
                // know when we have processed the whole document.
                maSearchStartPosition = maObjectIterator;
            else if (maSearchStartPosition == maObjectIterator)
            {
                mbEndOfSearch = true;
            }
        }

        EnterEditMode( sal_False );
    }
}




void Outliner::PrepareSearchAndReplace (void)
{
    if (HasText( *mpSearchItem ))
    {
        mbStringFound = true;
        mbMatchMayExist = true;

        EnterEditMode ();

        mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
        // Start search at the right end of the current object's text
        // depending on the search direction.
        OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
        if (pOutlinerView != NULL)
            pOutlinerView->SetSelection (GetSearchStartPosition ());
    }
}




void Outliner::SetViewMode (PageKind ePageKind)
{
    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
        ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell));
    if (pDrawViewShell.get()!=NULL && ePageKind != pDrawViewShell->GetPageKind())
    {
        // Restore old edit mode.
        pDrawViewShell->ChangeEditMode(mpImpl->meOriginalEditMode, sal_False);

        SetStatusEventHdl(Link());
        ::rtl::OUString sViewURL;
        switch (ePageKind)
        {
            case PK_STANDARD:
            default:
                sViewURL = framework::FrameworkHelper::msImpressViewURL;
                break;
            case PK_NOTES:
                sViewURL = framework::FrameworkHelper::msNotesViewURL;
                break;
            case PK_HANDOUT:
                sViewURL = framework::FrameworkHelper::msHandoutViewURL;
                break;
        }
        // The text object iterator is destroyed when the shells are
        // switched but we need it so save it and restore it afterwards.
        ::sd::outliner::Iterator aIterator (maObjectIterator);
        bool bMatchMayExist = mbMatchMayExist;

        ViewShellBase& rBase = pViewShell->GetViewShellBase();
        SetViewShell(::boost::shared_ptr<ViewShell>());
        framework::FrameworkHelper::Instance(rBase)->RequestView(
            sViewURL,
            framework::FrameworkHelper::msCenterPaneURL);

        // Force (well, request) a synchronous update of the configuration.
        // In a better world we would handle the asynchronous view update
        // instead.  But that would involve major restructuring of the
        // Outliner code.
        framework::FrameworkHelper::Instance(rBase)->RequestSynchronousUpdate();
        SetViewShell(rBase.GetMainViewShell());

        // Switching to another view shell has intermediately called
        // EndSpelling().  A PrepareSpelling() is pending, so call that now.
        PrepareSpelling();

        // Update the number of pages so that
        // <member>DetectChange()</member> has the correct value to compare
        // to.
        mnPageCount = mpDrawDocument->GetSdPageCount(ePageKind);

        maObjectIterator = aIterator;
        mbMatchMayExist = bMatchMayExist;

        // Save edit mode so that it can be restored when switching the view
        // shell again.
        pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell);
        OSL_ASSERT(pDrawViewShell.get()!=NULL);
        if (pDrawViewShell.get() != NULL)
            mpImpl->meOriginalEditMode = pDrawViewShell->GetEditMode();
    }
}




void Outliner::SetPage (EditMode eEditMode, sal_uInt16 nPageIndex)
{
    if ( ! mbRestrictSearchToSelection)
    {
        ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
        ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
            ::boost::dynamic_pointer_cast<DrawViewShell>(pViewShell));
        OSL_ASSERT(pDrawViewShell.get()!=NULL);
        if (pDrawViewShell.get() != NULL)
        {
            pDrawViewShell->ChangeEditMode(eEditMode, sal_False);
            pDrawViewShell->SwitchPage(nPageIndex);
        }
    }
}




void Outliner::EnterEditMode (sal_Bool bGrabFocus)
{
    OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
    if (pOutlinerView != NULL)
    {
        pOutlinerView->SetOutputArea( Rectangle( Point(), Size(1, 1)));
        SetPaperSize( mpTextObj->GetLogicRect().GetSize() );
        SdrPageView* pPV = mpView->GetSdrPageView();

        // Make FuText the current function.
        SfxUInt16Item aItem (SID_TEXTEDIT, 1);
        ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
        pViewShell->GetDispatcher()->
            Execute(SID_TEXTEDIT, SFX_CALLMODE_SYNCHRON |
                SFX_CALLMODE_RECORD, &aItem, 0L);

        // To be consistent with the usual behaviour in the Office the text
        // object that is put into edit mode would have also to be selected.
        // Starting the text edit mode is not enough so we do it here by
        // hand.
        mbExpectingSelectionChangeEvent = true;
        mpView->UnmarkAllObj (pPV);
        mpView->MarkObj (mpTextObj, pPV);

		if( mpTextObj )
			mpTextObj->setActiveText( mnText );

        // Turn on the edit mode for the text object.
        mpView->SdrBeginTextEdit(mpTextObj, pPV, mpWindow, sal_True, this, pOutlinerView, sal_True, sal_True, bGrabFocus);

        SetUpdateMode(sal_True);
        mbFoundObject = sal_True;
    }
}




/*************************************************************************
|*
|* SpellChecker: Error-LinkHdl
|*
\************************************************************************/

IMPL_LINK_INLINE_START( Outliner, SpellError, void *, nLang )
{
    mbError = true;
	String aError( SvtLanguageTable::GetLanguageString( (LanguageType)(sal_uLong)nLang ) );
	ErrorHandler::HandleError(* new StringErrorInfo(
								ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aError) );
	return 0;
}
IMPL_LINK_INLINE_END( Outliner, SpellError, void *, nLang )




ESelection Outliner::GetSearchStartPosition (void)
{
    ESelection aPosition;
    if (mbDirectionIsForward)
    {
        // The default constructor uses the beginning of the text as default.
        aPosition = ESelection ();
    }
    else
    {
        // Retrieve the position after the last character in the last
        // paragraph.
        sal_uInt32 nParagraphCount = GetParagraphCount();
        if (nParagraphCount == 0)
            aPosition = ESelection();
        else
        {
            xub_StrLen nLastParagraphLength = GetEditEngine().GetTextLen (
                nParagraphCount-1);
            aPosition = ESelection (nParagraphCount-1, nLastParagraphLength);
        }
    }

    return aPosition;
}




bool Outliner::HasNoPreviousMatch (void)
{
    OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();

    DBG_ASSERT (pOutlinerView!=NULL, "outline view in Outliner::HasNoPreviousMatch is NULL");

    // Detect whether the cursor stands at the beginning
    // resp. at the end of the text.
    return pOutlinerView->GetSelection().IsEqual(GetSearchStartPosition ()) == sal_True;
}




bool Outliner::HandleFailedSearch (void)
{
    bool bContinueSearch = false;

    OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
    if (pOutlinerView != NULL && mpSearchItem != NULL)
    {
        // Detect whether there is/may be a prior match.  If there is then
        // ask the user whether to wrap around.  Otherwise tell the user
        // that there is no match.
        if (HasNoPreviousMatch ())
        {
            // No match found in the whole presentation.  Tell the user.
            InfoBox aInfoBox (NULL,
                String(SdResId(STR_SAR_NOT_FOUND)));
            ShowModalMessageBox (aInfoBox);
        }

        else
        {
            // No further matches found.  Ask the user whether to wrap
            // around and start again.
            bContinueSearch = ShowWrapArroundDialog ();
        }
    }

    return bContinueSearch;
}


SdrObject* Outliner::SetObject (
    const ::sd::outliner::IteratorPosition& rPosition)
{
    SetViewMode (rPosition.mePageKind);
    SetPage (rPosition.meEditMode, (sal_uInt16)rPosition.mnPageIndex);
	mnText = rPosition.mnText;
    return rPosition.mxObject.get();
}




void Outliner::SetViewShell (const ::boost::shared_ptr<ViewShell>& rpViewShell)
{
    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
    if (pViewShell != rpViewShell)
    {
        // Set the new view shell.
        mpWeakViewShell = rpViewShell;
        // When the outline view is not owned by us then we have to clear
        // that pointer so that the current one for the new view shell will
        // be used (in ProvideOutlinerView).
        //        if ( ! mbOwnOutlineView)
        //            mpOutlineView = NULL;
        if (rpViewShell)
        {
            mpView = rpViewShell->GetView();

            mpWindow = rpViewShell->GetActiveWindow();

            mpImpl->ProvideOutlinerView(*this, rpViewShell, mpWindow);
            OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
            if (pOutlinerView != NULL)
                pOutlinerView->SetWindow(mpWindow);
        }
        else
        {
            mpView = NULL;
            mpWindow = NULL;
        }
    }
}




void Outliner::HandleChangedSelection (void)
{
    maMarkListCopy.clear();
    mbRestrictSearchToSelection = (mpView->AreObjectsMarked()==sal_True);
    if (mbRestrictSearchToSelection)
    {
        // Make a copy of the current mark list.
        const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
        sal_uLong nCount = rMarkList.GetMarkCount();
        if (nCount > 0)
        {
            maMarkListCopy.clear();
            maMarkListCopy.reserve (nCount);
            for (sal_uLong i=0; i<nCount; i++)
                maMarkListCopy.push_back (rMarkList.GetMark(i)->GetMarkedSdrObj ());
        }
        else
            // No marked object.  Is this case possible?
            mbRestrictSearchToSelection = false;
    }
}





void Outliner::StartConversion( sal_Int16 nSourceLanguage,  sal_Int16 nTargetLanguage,
        const Font *pTargetFont, sal_Int32 nOptions, sal_Bool bIsInteractive )
{
    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
	sal_Bool bMultiDoc = pViewShell->ISA(DrawViewShell);

    meMode = TEXT_CONVERSION;
    mbDirectionIsForward = true;
    mpSearchItem = NULL;
    mnConversionLanguage = nSourceLanguage;

	BeginConversion();

    OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
	if (pOutlinerView != NULL)
    {
        pOutlinerView->StartTextConversion(
            nSourceLanguage,
            nTargetLanguage,
            pTargetFont,
            nOptions,
            bIsInteractive,
            bMultiDoc);
    }

	EndConversion();
}




/** Prepare to do a text conversion on the current text object. This
	includes putting it into edit mode.
*/
void Outliner::PrepareConversion (void)
{
    SetUpdateMode(sal_True);
	if( HasConvertibleTextPortion( mnConversionLanguage ) )
	{
	    SetUpdateMode(sal_False);
		mbStringFound = sal_True;
		mbMatchMayExist = sal_True;

		EnterEditMode ();

		mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
		// Start search at the right end of the current object's text
		// depending on the search direction.
//		mpOutlineView->SetSelection (GetSearchStartPosition ());
	}
	else
	{
	    SetUpdateMode(sal_False);
	}
}




void Outliner::BeginConversion (void)
{
	SetRefDevice( SD_MOD()->GetRefDevice( *mpDrawDocument->GetDocSh() ) );

    ViewShellBase* pBase = PTR_CAST(ViewShellBase, SfxViewShell::Current());
    if (pBase != NULL)
        SetViewShell (pBase->GetMainViewShell());

    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
	if (pViewShell)
	{
		mbStringFound = sal_False;

        // Supposed that we are not located at the very beginning/end of the
        // document then there may be a match in the document prior/after
        // the current position.
        mbMatchMayExist = sal_True;

        maObjectIterator = ::sd::outliner::Iterator();
        maSearchStartPosition = ::sd::outliner::Iterator();
    	RememberStartPosition();

        mpImpl->ProvideOutlinerView(*this, pViewShell, mpWindow);

        HandleChangedSelection ();
	}
    ClearModifyFlag();
}




void Outliner::EndConversion()
{
	EndSpelling();
}




sal_Bool Outliner::ConvertNextDocument()
{
    ::boost::shared_ptr<ViewShell> pViewShell (mpWeakViewShell.lock());
	if (pViewShell && pViewShell->ISA(OutlineViewShell) )
		return false;

	mpDrawDocument->GetDocSh()->SetWaitCursor( sal_True );

    Initialize ( true );

    OutlinerView* pOutlinerView = mpImpl->GetOutlinerView();
    if (pOutlinerView != NULL)
    {
        mpWindow = pViewShell->GetActiveWindow();
        pOutlinerView->SetWindow(mpWindow);
    }
    ProvideNextTextObject ();

	mpDrawDocument->GetDocSh()->SetWaitCursor( sal_False );
	ClearModifyFlag();

    // for text conversion we automatically wrap around one
	// time and stop at the start shape
	if( mpFirstObj )
	{
		if( (mnText == 0) && (mpFirstObj == mpObj) )
			return false;
	}
	else
	{
		mpFirstObj = mpObj;
	}

	return !mbEndOfSearch;
}




sal_uInt16 Outliner::ShowModalMessageBox (Dialog& rMessageBox)
{
    // We assume that the parent of the given message box is NULL, i.e. it is
    // modal with respect to the top application window. However, this
    // does not affect the search dialog.  Therefore we have to lock it here
    // while the message box is being shown.  We also have to take into
    // account that we are called during a spell check and the search dialog
    // is not available.
    ::Window* pSearchDialog = NULL;
    SfxChildWindow* pChildWindow = NULL;
    switch (meMode)
    {
        case SEARCH:
            pChildWindow = SfxViewFrame::Current()->GetChildWindow(
                SvxSearchDialogWrapper::GetChildWindowId());
            break;

        case SPELL:
            pChildWindow = SfxViewFrame::Current()->GetChildWindow(
                SpellDialogChildWindow::GetChildWindowId());
            break;

        case TEXT_CONVERSION:
            // There should no messages boxes be displayed while doing the
            // hangul hanja conversion.
            break;
    }

    if (pChildWindow != NULL)
        pSearchDialog = pChildWindow->GetWindow();
    if (pSearchDialog != NULL)
        pSearchDialog->EnableInput(sal_False,sal_True);

    sal_uInt16 nResult = rMessageBox.Execute();

    // Unlock the search dialog.
    if (pSearchDialog != NULL)
        pSearchDialog->EnableInput(sal_True,sal_True);

    return nResult;
}




//===== Outliner::Implementation ==============================================

Outliner::Implementation::Implementation (void)
    : meOriginalEditMode(EM_PAGE),
      mbOwnOutlineView(false),
      mpOutlineView(NULL)
{
}




Outliner::Implementation::~Implementation (void)
{
    if (mbOwnOutlineView && mpOutlineView!=NULL)
    {
        mpOutlineView->SetWindow(NULL);
        delete mpOutlineView;
        mpOutlineView = NULL;
    }
}




OutlinerView* Outliner::Implementation::GetOutlinerView ()
{
    return mpOutlineView;
}




/** We try to create a new OutlinerView only when there is none available,
    either from an OutlinerViewShell or a previous call to
    ProvideOutlinerView().  This is necessary to support the spell checker
    which can not cope with exchanging the OutlinerView.
*/
void Outliner::Implementation::ProvideOutlinerView (
    Outliner& rOutliner,
    const ::boost::shared_ptr<ViewShell>& rpViewShell,
    ::Window* pWindow)
{
    if (rpViewShell.get() != NULL)
    {
        switch (rpViewShell->GetShellType())
        {
            case ViewShell::ST_DRAW:
            case ViewShell::ST_IMPRESS:
            case ViewShell::ST_NOTES:
            case ViewShell::ST_HANDOUT:
            {
                // Create a new outline view to do the search on.
                bool bInsert = false;
                if (mpOutlineView!=NULL && !mbOwnOutlineView)
                    mpOutlineView = NULL;
                if (mpOutlineView == NULL)
                {
                    mpOutlineView = new OutlinerView(&rOutliner, pWindow);
                    mbOwnOutlineView = true;
                    bInsert = true;
                }
                else
                    mpOutlineView->SetWindow(pWindow);
                sal_uLong nStat = mpOutlineView->GetControlWord();
                nStat &= ~EV_CNTRL_AUTOSCROLL;
                mpOutlineView->SetControlWord(nStat);
                if (bInsert)
                    rOutliner.InsertView( mpOutlineView );
                rOutliner.SetUpdateMode(sal_False);
                mpOutlineView->SetOutputArea (Rectangle (Point(), Size(1, 1)));
                rOutliner.SetPaperSize( Size(1, 1) );
                rOutliner.SetText( String(), rOutliner.GetParagraph( 0 ) );

                meOriginalEditMode =
                    ::boost::static_pointer_cast<DrawViewShell>(rpViewShell)->GetEditMode();
            }
            break;

            case ViewShell::ST_OUTLINE:
            {
                if (mpOutlineView!=NULL && mbOwnOutlineView)
                    delete mpOutlineView;
                mpOutlineView = rOutliner.GetView(0);
                mbOwnOutlineView = false;
            }
            break;

            default:
            case ViewShell::ST_NONE:
            case ViewShell::ST_PRESENTATION:
                // Ignored
                break;
        }
    }
}




void Outliner::Implementation::ReleaseOutlinerView (void)
{
    if (mbOwnOutlineView)
    {
        OutlinerView* pView = mpOutlineView;
        mpOutlineView = NULL;
        mbOwnOutlineView = false;
        if (pView != NULL)
        {
            pView->SetWindow(NULL);
            delete pView;
        }
    }
    else
    {
        mpOutlineView = NULL;
    }
}

} // end of namespace sd
