/**************************************************************
 * 
 * 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 "ViewShell.hxx"
#include "ViewShellImplementation.hxx"

#ifndef _COM_SUN_STAR_EMBED_EMBEDSTATE_HPP_
#include <com/sun/star/embed/EmbedStates.hpp>
#endif
#include "ViewShellBase.hxx"
#include "ShellFactory.hxx"
#include "DrawController.hxx"
#include "LayerTabBar.hxx"

#include <sfx2/viewfrm.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#ifndef _SCRBAR_HXX //autogen
#include <vcl/scrbar.hxx>
#endif
#include <svl/eitem.hxx>
#include <svx/ruler.hxx>
#ifndef _SVXIDS_HXX
#include <svx/svxids.hrc>
#endif
#include <svx/fmshell.hxx>
#ifndef SD_WINDOW_UPDATER_HXX
#include "WindowUpdater.hxx"
#endif
#include "GraphicViewShell.hxx"
#include <sfx2/childwin.hxx>
#include <sdxfer.hxx>
#include "GraphicViewShell.hxx"
#include <sfx2/childwin.hxx>

#include "app.hrc"
#include "helpids.h"
#include "strings.hrc"
#include "res_bmp.hrc"
#include "OutlineView.hxx"
#include "Client.hxx"
#include "sdresid.hxx"
#include "DrawDocShell.hxx"
#include "slideshow.hxx"
#include "drawdoc.hxx"
#include "sdpage.hxx"
#include "zoomlist.hxx"
#include "FrameView.hxx"
#include "optsitem.hxx"
#include "BezierObjectBar.hxx"
#include "TextObjectBar.hxx"
#include "GraphicObjectBar.hxx"
#include "MediaObjectBar.hxx"
#include "ViewShellManager.hxx"
#include "FormShellManager.hxx"
#include <svx/fmshell.hxx>
#include <svx/dialogs.hrc>
#include <svx/extrusionbar.hxx>
#include <svx/fontworkbar.hxx>
#include <svx/svdoutl.hxx>
#include <tools/diagnose_ex.h>

// #96090#
#include <svl/slstitm.hxx>
#include <sfx2/request.hxx>
#include "SpellDialogChildWindow.hxx"

#include "Window.hxx"
#include "fupoor.hxx"

#include <editeng/numitem.hxx>
#include <editeng/eeitem.hxx>
#include <svl/poolitem.hxx>
#include <glob.hrc>

#ifndef SO2_DECL_SVINPLACEOBJECT_DEFINED
#define SO2_DECL_SVINPLACEOBJECT_DEFINED
SO2_DECL_REF(SvInPlaceObject)
#endif

namespace sd { namespace ui { namespace table {
	extern SfxShell* CreateTableObjectBar( ViewShell& rShell, ::sd::View* pView );
} } }

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::presentation;

namespace {

class ViewShellObjectBarFactory
    : public ::sd::ShellFactory<SfxShell>
{
public:
    ViewShellObjectBarFactory (::sd::ViewShell& rViewShell);
    virtual ~ViewShellObjectBarFactory (void);
    virtual SfxShell* CreateShell (
        ::sd::ShellId nId,
        ::Window* pParentWindow,
        ::sd::FrameView* pFrameView);
    virtual void ReleaseShell (SfxShell* pShell);
private:
    ::sd::ViewShell& mrViewShell;
    /** This cache holds the already created object bars.
    */
    typedef ::std::map< ::sd::ShellId,SfxShell*> ShellCache;
    ShellCache maShellCache;
};


} // end of anonymous namespace


namespace sd {

static const int DELTA_ZOOM = 10;

sal_Bool ViewShell::IsPageFlipMode(void) const
{
	return this->ISA(DrawViewShell) && mpContentWindow.get() != NULL &&
		mpContentWindow->GetVisibleHeight() >= 1.0;
}

SfxViewFrame* ViewShell::GetViewFrame (void) const
{
    const SfxViewShell* pViewShell = GetViewShell();
    if (pViewShell != NULL)
    {
        return pViewShell->GetViewFrame();
    }
    else
    {
        OSL_ASSERT (GetViewShell()!=NULL);
        return NULL;
    }
}


/*************************************************************************
|*
|* SFX-Slotmap und Standardinterface deklarieren
|*
\************************************************************************/
TYPEINIT1(ViewShell, SfxShell);


ViewShell::ViewShell( SfxViewFrame*, ::Window* pParentWindow, ViewShellBase& rViewShellBase, bool bAllowCenter)
:	SfxShell(&rViewShellBase)
,	mbCenterAllowed(bAllowCenter)
,	mpParentWindow(pParentWindow)
{
	construct();
}

ViewShell::~ViewShell()
{
    // Keep the content window from accessing in its destructor the
    // WindowUpdater.
    if (mpContentWindow)
        mpContentWindow->SetViewShell(NULL);

	delete mpZoomList;

    mpLayerTabBar.reset();

    if (mpImpl->mpSubShellFactory.get() != NULL)
        GetViewShellBase().GetViewShellManager()->RemoveSubShellFactory(
            this,mpImpl->mpSubShellFactory);

    if (mpContentWindow)
    {
        OSL_TRACE("destroying mpContentWindow at %x with parent %x", mpContentWindow.get(),
            mpContentWindow->GetParent());
        mpContentWindow.reset();
    }
}


/*************************************************************************
|*
|* gemeinsamer Initialiserungsanteil der beiden Konstruktoren
|*
\************************************************************************/

void ViewShell::construct(void)
{
	mbHasRulers = false;
	mpActiveWindow = 0;
	mpView = 0;
	mpFrameView = 0;
	mpZoomList = 0;
	mbStartShowWithDialog = sal_False;
	mnPrintedHandoutPageNum = 1;
    mnPrintedHandoutPageCount = 0;
	mpWindowUpdater.reset( new ::sd::WindowUpdater() );
	mpImpl.reset(new Implementation(*this));
	meShellType = ST_NONE;

    OSL_ASSERT (GetViewShell()!=NULL);

    if (IsMainViewShell())
        GetDocSh()->Connect (this);

	mpZoomList = new ZoomList( this );

	mpContentWindow.reset(new ::sd::Window(GetParentWindow()));
    SetActiveWindow (mpContentWindow.get());

    GetParentWindow()->SetBackground (Wallpaper());
    mpContentWindow->SetBackground (Wallpaper());
	mpContentWindow->SetCenterAllowed(mbCenterAllowed);
	mpContentWindow->SetViewShell(this);
    mpContentWindow->SetPosSizePixel(
        GetParentWindow()->GetPosPixel(),GetParentWindow()->GetSizePixel());
    mpContentWindow->Show();
    static_cast< ::Window*>(mpContentWindow.get())->Resize();
    OSL_TRACE("content window has size %d %d",
        mpContentWindow->GetSizePixel().Width(),
        mpContentWindow->GetSizePixel().Height());

    if ( ! GetDocSh()->IsPreview())
    {
        // Create scroll bars and the filler between the scroll bars.
        mpHorizontalScrollBar.reset (new ScrollBar(GetParentWindow(), WinBits(WB_HSCROLL | WB_DRAG)));
        mpHorizontalScrollBar->EnableRTL (sal_False);
        mpHorizontalScrollBar->SetRange(Range(0, 32000));
        mpHorizontalScrollBar->SetScrollHdl(LINK(this, ViewShell, HScrollHdl));
        mpHorizontalScrollBar->Show();

        mpVerticalScrollBar.reset (new ScrollBar(GetParentWindow(), WinBits(WB_VSCROLL | WB_DRAG)));
        mpVerticalScrollBar->SetRange(Range(0, 32000));
        mpVerticalScrollBar->SetScrollHdl(LINK(this, ViewShell, VScrollHdl));
        mpVerticalScrollBar->Show();
        maScrBarWH = Size(
            mpVerticalScrollBar->GetSizePixel().Width(),
            mpHorizontalScrollBar->GetSizePixel().Height());

        mpScrollBarBox.reset(new ScrollBarBox(GetParentWindow(), WB_SIZEABLE));
        mpScrollBarBox->Show();
    }

	String aName( RTL_CONSTASCII_USTRINGPARAM( "ViewShell" ));
	SetName (aName);

	GetDoc()->StartOnlineSpelling(sal_False);

    mpWindowUpdater->SetViewShell (*this);
    mpWindowUpdater->SetDocument (GetDoc());

    // Re-initialize the spell dialog.
    ::sd::SpellDialogChildWindow* pSpellDialog =
          static_cast< ::sd::SpellDialogChildWindow*> (
              GetViewFrame()->GetChildWindow (
                  ::sd::SpellDialogChildWindow::GetChildWindowId()));
    if (pSpellDialog != NULL)
        pSpellDialog->InvalidateSpellDialog();

    // Register the sub shell factory.
    mpImpl->mpSubShellFactory.reset(new ViewShellObjectBarFactory(*this));
    GetViewShellBase().GetViewShellManager()->AddSubShellFactory(this,mpImpl->mpSubShellFactory);

    GetParentWindow()->Show();
}




void ViewShell::Init (bool bIsMainViewShell)
{
    mpImpl->mbIsInitialized = true;
    SetIsMainViewShell(bIsMainViewShell);
    if (bIsMainViewShell)
        SetActiveWindow (mpContentWindow.get());
}




void ViewShell::Exit (void)
{
    sd::View* pView = GetView();
    if (pView!=NULL && pView->IsTextEdit())
    {
        pView->SdrEndTextEdit();
        pView->UnmarkAll();
    }

    Deactivate (sal_True);

    if (IsMainViewShell())
    {
        GetDocSh()->Disconnect(this);
    }

    SetIsMainViewShell(false);
}




/*************************************************************************
|*
|* Aktivierung: Arbeitsfenster den Fokus zuweisen
|*
\************************************************************************/

void ViewShell::Activate(sal_Bool bIsMDIActivate)
{
    // Do not forward to SfxShell::Activate()

	// Laut MI darf keiner GrabFocus rufen, der nicht genau weiss von
	// welchem Window der Focus gegrabt wird. Da Activate() vom SFX teilweise
	// asynchron verschickt wird, kann es sein, dass ein falsches Window
	// den Focus hat (#29682#):
	//GetViewFrame()->GetWindow().GrabFocus();

    if (mpHorizontalRuler.get() != NULL)
        mpHorizontalRuler->SetActive(sal_True);
    if (mpVerticalRuler.get() != NULL)
        mpVerticalRuler->SetActive(sal_True);

    if (bIsMDIActivate)
    {
        // Damit der Navigator auch einen aktuellen Status bekommt
        SfxBoolItem aItem( SID_NAVIGATOR_INIT, sal_True );
        if (GetDispatcher() != NULL)
            GetDispatcher()->Execute(
                SID_NAVIGATOR_INIT,
                SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
                &aItem,
                0L);

        SfxViewShell* pViewShell = GetViewShell();
        OSL_ASSERT (pViewShell!=NULL);
		SfxBindings& rBindings = pViewShell->GetViewFrame()->GetBindings();
		rBindings.Invalidate( SID_3D_STATE, sal_True, sal_False );

		rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( GetViewShellBase() ) );
		if(xSlideShow.is() && xSlideShow->isRunning() )
		{
			xSlideShow->activate(GetViewShellBase());
		}
		if(HasCurrentFunction())
		{
			GetCurrentFunction()->Activate();
		}

		if(!GetDocSh()->IsUIActive())
			UpdatePreview( GetActualPage(), sal_True );

		//HMH::sd::View* pView = GetView();

		//HMHif (pView)
		//HMH{
		//HMH	pView->ShowMarkHdl();
		//HMH}
	}

	ReadFrameViewData( mpFrameView );

    if (IsMainViewShell())
        GetDocSh()->Connect(this);
}

void ViewShell::UIActivating( SfxInPlaceClient*  )
{
    OSL_ASSERT (GetViewShell()!=NULL);
    GetViewShellBase().GetToolBarManager()->ToolBarsDestroyed();
}



void ViewShell::UIDeactivated( SfxInPlaceClient*  )
{
    OSL_ASSERT (GetViewShell()!=NULL);
    GetViewShellBase().GetToolBarManager()->ToolBarsDestroyed();
    if ( GetDrawView() )
        GetViewShellBase().GetToolBarManager()->SelectionHasChanged(*this, *GetDrawView());
}

/*************************************************************************
|*
|* Deaktivierung
|*
\************************************************************************/

void ViewShell::Deactivate(sal_Bool bIsMDIActivate)
{
	// remove view from a still active drag'n'drop session
	SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;

    if (IsMainViewShell())
        GetDocSh()->Disconnect(this);

	if( pDragTransferable )
		pDragTransferable->SetView( NULL );

    OSL_ASSERT (GetViewShell()!=NULL);

	// View-Attribute an der FrameView merken
	WriteFrameViewData();

	if (bIsMDIActivate)
	{
		rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( GetViewShellBase() ) );
		if(xSlideShow.is() && xSlideShow->isRunning() )
		{
			xSlideShow->deactivate(GetViewShellBase());
		}
		if(HasCurrentFunction())
		{
			GetCurrentFunction()->Deactivate();
		}
	}

    if (mpHorizontalRuler.get() != NULL)
        mpHorizontalRuler->SetActive(sal_False);
    if (mpVerticalRuler.get() != NULL)
        mpVerticalRuler->SetActive(sal_False);

	SfxShell::Deactivate(bIsMDIActivate);
}




void ViewShell::Shutdown (void)
{
    Exit ();
}




/*************************************************************************
|*
|* Keyboard event
|*
\************************************************************************/

sal_Bool ViewShell::KeyInput(const KeyEvent& rKEvt, ::sd::Window* pWin)
{
	sal_Bool bReturn(sal_False);

	if(pWin)
	{
		SetActiveWindow(pWin);
	}

	if(!bReturn)
	{
		// #76008#
		// give key input first to SfxViewShell to give CTRL+Key
		// (e.g. CTRL+SHIFT+'+', to front) priority.
        OSL_ASSERT (GetViewShell()!=NULL);
		bReturn = (sal_Bool)GetViewShell()->KeyInput(rKEvt);
	}

	if(!bReturn)
	{
		rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( GetViewShellBase() ) );
		if(xSlideShow.is() && xSlideShow->isRunning())
		{
			bReturn = xSlideShow->keyInput(rKEvt);
		}
		else
		{
			bool bConsumed = false;
			if( GetView() )
				bConsumed = GetView()->getSmartTags().KeyInput(rKEvt);


			if( !bConsumed )
			{
				rtl::Reference< sdr::SelectionController > xSelectionController( GetView()->getSelectionController() );
				if( !xSelectionController.is() || !xSelectionController->onKeyInput( rKEvt, pWin ) )
				{
					if(HasCurrentFunction())
						bReturn = GetCurrentFunction()->KeyInput(rKEvt);
				}
				else
				{
					bReturn = sal_True;
				}
			}
		}
	}

	if(!bReturn && GetActiveWindow())
	{
		KeyCode aKeyCode = rKEvt.GetKeyCode();

		if (aKeyCode.IsMod1() && aKeyCode.IsShift()
			&& aKeyCode.GetCode() == KEY_R)
		{
			InvalidateWindows();
			bReturn = sal_True;
		}
	}

	return(bReturn);
}

/*************************************************************************
|*
|* MouseButtonDown event
|*
\************************************************************************/

void ViewShell::MouseButtonDown(const MouseEvent& rMEvt, ::sd::Window* pWin)
{
    // We have to lock tool bar updates while the mouse button is pressed in
    // order to prevent the shape under the mouse to be moved (this happens
    // when the number of docked tool bars changes as result of a changed
    // selection;  this changes the window size and thus the mouse position
    // in model coordinates: with respect to model coordinates the mouse
    // moves.)
    OSL_ASSERT(mpImpl->mpUpdateLockForMouse.expired());
    mpImpl->mpUpdateLockForMouse = ViewShell::Implementation::ToolBarManagerLock::Create(
        GetViewShellBase().GetToolBarManager());

	if ( pWin && !pWin->HasFocus() )
	{
        pWin->GrabFocus();
        SetActiveWindow(pWin);
//		  GetViewFrame()->GetWindow().GrabFocus();
	}

	// MouseEvent in E3dView eintragen
    if (GetView() != NULL)
        GetView()->SetMouseEvent(rMEvt);

	bool bConsumed = false;
	if( GetView() )
		bConsumed = GetView()->getSmartTags().MouseButtonDown( rMEvt );

	if( !bConsumed )
	{
		rtl::Reference< sdr::SelectionController > xSelectionController( GetView()->getSelectionController() );
		if( !xSelectionController.is() || !xSelectionController->onMouseButtonDown( rMEvt, pWin ) )
		{
			if(HasCurrentFunction())
			{
				GetCurrentFunction()->MouseButtonDown(rMEvt);
			}
		}
	}
}

/*************************************************************************
|*
|* MouseMove event
|*
\************************************************************************/

void ViewShell::MouseMove(const MouseEvent& rMEvt, ::sd::Window* pWin)
{
    if (rMEvt.IsLeaveWindow())
    {
        if ( ! mpImpl->mpUpdateLockForMouse.expired())
        {
            ::boost::shared_ptr<ViewShell::Implementation::ToolBarManagerLock> pLock(
                mpImpl->mpUpdateLockForMouse);
            if (pLock.get() != NULL)
                pLock->Release();
        }
    }

	if ( pWin )
	{
		SetActiveWindow(pWin);
	}

	// MouseEvent in E3dView eintragen
    if (GetView() != NULL)
        GetView()->SetMouseEvent(rMEvt);

	if(HasCurrentFunction())
	{
		rtl::Reference< sdr::SelectionController > xSelectionController( GetView()->getSelectionController() );
		if( !xSelectionController.is() || !xSelectionController->onMouseMove( rMEvt, pWin ) )
		{
			if(HasCurrentFunction())
				GetCurrentFunction()->MouseMove(rMEvt);
		}
	}
}

/*************************************************************************
|*
|* MouseButtonUp event
|*
\************************************************************************/

void ViewShell::MouseButtonUp(const MouseEvent& rMEvt, ::sd::Window* pWin)
{
	if ( pWin )
	{
		SetActiveWindow(pWin);
	}

	// MouseEvent in E3dView eintragen
    if (GetView() != NULL)
        GetView()->SetMouseEvent(rMEvt);

	if( HasCurrentFunction())
	{
		rtl::Reference< sdr::SelectionController > xSelectionController( GetView()->getSelectionController() );
		if( !xSelectionController.is() || !xSelectionController->onMouseButtonUp( rMEvt, pWin ) )
		{
			if(HasCurrentFunction())
				GetCurrentFunction()->MouseButtonUp(rMEvt);
		}
	}

    if ( ! mpImpl->mpUpdateLockForMouse.expired())
    {
        ::boost::shared_ptr<ViewShell::Implementation::ToolBarManagerLock> pLock(
            mpImpl->mpUpdateLockForMouse);
        if (pLock.get() != NULL)
            pLock->Release();
    }
}


/*************************************************************************
|*
|* Command event
|*
\************************************************************************/

void ViewShell::Command(const CommandEvent& rCEvt, ::sd::Window* pWin)
{
	sal_Bool bDone = HandleScrollCommand (rCEvt, pWin);

	if( !bDone )
	{
		if( rCEvt.GetCommand() == COMMAND_INPUTLANGUAGECHANGE )
		{
            //#i42732# update state of fontname if input language changes
            GetViewFrame()->GetBindings().Invalidate( SID_ATTR_CHAR_FONT );
            GetViewFrame()->GetBindings().Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
		}
		else
		{
		    bool bConsumed = false;
   			if( GetView() )
   			{
				bConsumed = GetView()->getSmartTags().Command(rCEvt);
		    }
			
			if( !bConsumed && HasCurrentFunction())
		    {
		        GetCurrentFunction()->Command(rCEvt);
            }
		}
	}
}

long ViewShell::Notify(NotifyEvent& rNEvt, ::sd::Window* pWin)
{
    // handle scroll commands when they arrived at child windows
    long nRet = sal_False;
    if( rNEvt.GetType() == EVENT_COMMAND )
    {
        // note: dynamic_cast is not possible as GetData() returns a void*
        CommandEvent* pCmdEvent = reinterpret_cast< CommandEvent* >(rNEvt.GetData());
        nRet = HandleScrollCommand(*pCmdEvent, pWin);
    }
    return nRet;
}


bool ViewShell::HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWin)
{
    bool bDone = false;

    switch( rCEvt.GetCommand() )
    {
        case COMMAND_WHEEL:
			{
				Reference< XSlideShowController > xSlideShowController( SlideShow::GetSlideShowController(GetViewShellBase() ) );
				if( xSlideShowController.is() )
				{
					// We ignore zooming with control+mouse wheel.
					const CommandWheelData* pData = rCEvt.GetWheelData();
					if( pData && !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) && !pData->IsHorz() )
					{
						long nDelta = pData->GetDelta();
						if( nDelta > 0 )
						{
							xSlideShowController->gotoPreviousSlide();
						}
						else if( nDelta < 0 )
						{
							xSlideShowController->gotoNextEffect();
						}
					}
					break;
				}
			}
			// fall through when not running slideshow
        case COMMAND_STARTAUTOSCROLL:
        case COMMAND_AUTOSCROLL:
        {
            const CommandWheelData* pData = rCEvt.GetWheelData();

            if (pData != NULL)
            {
                if (pData->IsMod1())
                {
                    if( !GetDocSh()->IsUIActive() )
                    {
                        const long  nOldZoom = GetActiveWindow()->GetZoom();
                        long        nNewZoom;

                        if( pData->GetDelta() < 0L )
                            nNewZoom = Max( (long) pWin->GetMinZoom(), (long)(nOldZoom - DELTA_ZOOM) );
                        else
                            nNewZoom = Min( (long) pWin->GetMaxZoom(), (long)(nOldZoom + DELTA_ZOOM) );

                        SetZoom( nNewZoom );
                        Invalidate( SID_ATTR_ZOOM );
						Invalidate( SID_ATTR_ZOOMSLIDER );

                        bDone = true;
                    }
                }
                else
                {
                    if( mpContentWindow.get() == pWin )
                    {
                        sal_uLong nScrollLines = pData->GetScrollLines();
                        if(IsPageFlipMode())
                            nScrollLines = COMMAND_WHEEL_PAGESCROLL;
                        CommandWheelData aWheelData( pData->GetDelta(),pData->GetNotchDelta(),
                            nScrollLines,pData->GetMode(),pData->GetModifier(),pData->IsHorz() );
                        CommandEvent aReWrite( rCEvt.GetMousePosPixel(),rCEvt.GetCommand(),
                            rCEvt.IsMouseEvent(),(const void *) &aWheelData );
                        bDone = pWin->HandleScrollCommand( aReWrite,
                            mpHorizontalScrollBar.get(),
                            mpVerticalScrollBar.get()) == sal_True;
                    }
                }
            }
        }
        break;

        default:
        break;
    }

    return bDone;
}



void ViewShell::SetupRulers (void)
{
	if(mbHasRulers && (mpContentWindow.get() != NULL) && !SlideShow::IsRunning(GetViewShellBase()))
	{
		long nHRulerOfs = 0;

		if ( mpVerticalRuler.get() == NULL )
		{
			mpVerticalRuler.reset(CreateVRuler(GetActiveWindow()));
			if ( mpVerticalRuler.get() != NULL )
			{
				nHRulerOfs = mpVerticalRuler->GetSizePixel().Width();
				mpVerticalRuler->SetActive(sal_True);
				mpVerticalRuler->Show();
			}
		}
		if ( mpHorizontalRuler.get() == NULL )
		{
			mpHorizontalRuler.reset(CreateHRuler(GetActiveWindow(), sal_True));
			if ( mpHorizontalRuler.get() != NULL )
			{
				mpHorizontalRuler->SetWinPos(nHRulerOfs);
				mpHorizontalRuler->SetActive(sal_True);
				mpHorizontalRuler->Show();
			}
		}
	}
}

const SfxPoolItem* ViewShell::GetNumBulletItem(SfxItemSet& aNewAttr, sal_uInt16& nNumItemId)
{	
	const SfxPoolItem* pTmpItem = NULL;
	
	if(aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem) == SFX_ITEM_SET)
	{
		return pTmpItem;
	}
	else
	{
		nNumItemId = aNewAttr.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
		SfxItemState eState = aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem);
		if (eState == SFX_ITEM_SET)
			return pTmpItem;
		else
		{
			sal_Bool bOutliner = sal_False;
			sal_Bool bTitle = sal_False;

			if( mpView )
     			{
				const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
				const sal_uInt32 nCount = rMarkList.GetMarkCount();
            
				for(sal_uInt32 nNum = 0; nNum < nCount; nNum++)
				{
					SdrObject* pObj = rMarkList.GetMark(nNum)->GetMarkedSdrObj();
					if( pObj->GetObjInventor() == SdrInventor )
					{
						switch(pObj->GetObjIdentifier())
						{
						case OBJ_TITLETEXT:
							bTitle = sal_True;
							break;
						case OBJ_OUTLINETEXT:
							bOutliner = sal_True;
							break;
						}
					}
				}
			}

			const SvxNumBulletItem *pItem = NULL;
			if(bOutliner)
			{				
				SfxStyleSheetBasePool* pSSPool = mpView->GetDocSh()->GetStyleSheetPool();
				String aStyleName((SdResId(STR_LAYOUT_OUTLINE)));
				aStyleName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " 1" ) );
				SfxStyleSheetBase* pFirstStyleSheet = pSSPool->Find( aStyleName, SD_STYLE_FAMILY_PSEUDO);
				if( pFirstStyleSheet )
					pFirstStyleSheet->GetItemSet().GetItemState(EE_PARA_NUMBULLET, sal_False, (const SfxPoolItem**)&pItem);
			}

			if( pItem == NULL )
				pItem = (SvxNumBulletItem*) aNewAttr.GetPool()->GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET);

			aNewAttr.Put(*pItem, EE_PARA_NUMBULLET);
		
			if(bTitle && aNewAttr.GetItemState(EE_PARA_NUMBULLET,sal_True) == SFX_ITEM_ON )
			{
				SvxNumBulletItem* pItem = (SvxNumBulletItem*)aNewAttr.GetItem(EE_PARA_NUMBULLET,sal_True);
				SvxNumRule* pRule = pItem->GetNumRule();
				if(pRule)
				{
					SvxNumRule aNewRule( *pRule );
					aNewRule.SetFeatureFlag( NUM_NO_NUMBERS, sal_True );

					SvxNumBulletItem aNewItem( aNewRule, EE_PARA_NUMBULLET );
					aNewAttr.Put(aNewItem);
				}
			}

			SfxItemState eState = aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem);
			if (eState == SFX_ITEM_SET)
				return pTmpItem;

		}
	}
	return pTmpItem;
}


sal_Bool ViewShell::HasRuler (void)
{
    return mbHasRulers;
}




void ViewShell::Resize (void)
{
	SetupRulers ();

    if (mpParentWindow == NULL)
        return;
    
    // Make sure that the new size is not degenerate.
    const Size aSize (mpParentWindow->GetSizePixel());
	if (aSize.Width()==0 || aSize.Height()==0)
		return;

    // Remember the new position and size.
	maViewPos = Point(0,0); //mpParentWindow->GetPosPixel();
	maViewSize = aSize;

    // Rearrange the UI elements to take care of the new position and size.
    ArrangeGUIElements ();
    // end of included AdjustPosSizePixel.

    Size aS (GetParentWindow()->GetOutputSizePixel());
	Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel();
	Rectangle aVisArea = GetParentWindow()->PixelToLogic(
        Rectangle( Point(0,0), aVisSizePixel));
    Rectangle aCurrentVisArea (GetDocSh()->GetVisArea(ASPECT_CONTENT));
    Rectangle aWindowRect = GetActiveWindow()->LogicToPixel(aCurrentVisArea);
	if (GetDocSh()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
        && IsMainViewShell())
	{
        //        GetDocSh()->SetVisArea(aVisArea);
	}

    //	VisAreaChanged(aVisArea);

	::sd::View* pView = GetView();

	if (pView)
	{
		pView->VisAreaChanged(GetActiveWindow());
	}
}

SvBorder ViewShell::GetBorder (bool )
{
    SvBorder aBorder;

	// Horizontal scrollbar.
    if (mpHorizontalScrollBar.get()!=NULL
        && mpHorizontalScrollBar->IsVisible())
    {
        aBorder.Bottom() = maScrBarWH.Height();
    }

	// Vertical scrollbar.
    if (mpVerticalScrollBar.get()!=NULL
        && mpVerticalScrollBar->IsVisible())
    {
        aBorder.Right() = maScrBarWH.Width();
    }

    // Place horizontal ruler below tab bar.
    if (mbHasRulers && mpContentWindow.get() != NULL)
    {
        SetupRulers();
        if (mpHorizontalRuler.get() != NULL)
            aBorder.Top() = mpHorizontalRuler->GetSizePixel().Height();
        if (mpVerticalRuler.get() != NULL)
            aBorder.Left() = mpVerticalRuler->GetSizePixel().Width();
    }

    return aBorder;
}




void ViewShell::ArrangeGUIElements (void)
{
    if (mpImpl->mbArrangeActive)
        return;
    mpImpl->mbArrangeActive = true;

    // Calculate border for in-place editing.
	long nLeft = maViewPos.X();
	long nTop  = maViewPos.Y();
	long nRight = maViewPos.X() + maViewSize.Width();
	long nBottom = maViewPos.Y() + maViewSize.Height();

	// Horizontal scrollbar.
    if (mpHorizontalScrollBar.get()!=NULL
        && mpHorizontalScrollBar->IsVisible())
    {
        int nLocalLeft = nLeft;
        if (mpLayerTabBar.get()!=NULL && mpLayerTabBar->IsVisible())
            nLocalLeft += mpLayerTabBar->GetSizePixel().Width();
        nBottom -= maScrBarWH.Height();
        mpHorizontalScrollBar->SetPosSizePixel (
            Point(nLocalLeft,nBottom),
            Size(nRight-nLocalLeft-maScrBarWH.Width(),maScrBarWH.Height()));
    }

	// Vertical scrollbar.
    if (mpVerticalScrollBar.get()!=NULL
        && mpVerticalScrollBar->IsVisible())
    {
        nRight -= maScrBarWH.Width();
        mpVerticalScrollBar->SetPosSizePixel (
            Point(nRight,nTop),
            Size (maScrBarWH.Width(),nBottom-nTop));
    }

    // Filler in the lower right corner.
    if (mpScrollBarBox.get() != NULL)
    {
        if (mpHorizontalScrollBar.get()!=NULL
            && mpHorizontalScrollBar->IsVisible()
            && mpVerticalScrollBar.get()!=NULL
            && mpVerticalScrollBar->IsVisible())
        {
            mpScrollBarBox->Show();
            mpScrollBarBox->SetPosSizePixel(Point(nRight, nBottom), maScrBarWH);
        }
        else
            mpScrollBarBox->Hide();
    }

    // Place horizontal ruler below tab bar.
    if (mbHasRulers && mpContentWindow.get() != NULL)
    {
        if (mpHorizontalRuler.get() != NULL)
        {
            Size aRulerSize = mpHorizontalRuler->GetSizePixel();
            aRulerSize.Width() = nRight - nLeft;
            mpHorizontalRuler->SetPosSizePixel (
                Point(nLeft,nTop), aRulerSize);
            if (mpVerticalRuler.get() != NULL)
                mpHorizontalRuler->SetBorderPos(
                    mpVerticalRuler->GetSizePixel().Width()-1);
            nTop += aRulerSize.Height();
        }
        if (mpVerticalRuler.get() != NULL)
        {
            Size aRulerSize = mpVerticalRuler->GetSizePixel();
            aRulerSize.Height() = nBottom  - nTop;
            mpVerticalRuler->SetPosSizePixel (
                Point (nLeft,nTop), aRulerSize);
            nLeft += aRulerSize.Width();
        }
    }

	rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( GetViewShellBase() ) );

    // The size of the window of the center pane is set differently from
    // that of the windows in the docking windows.
    bool bSlideShowActive = (xSlideShow.is() && xSlideShow->isRunning()) && !xSlideShow->isFullScreen() && xSlideShow->getAnimationMode() == ANIMATIONMODE_SHOW;
    if ( !bSlideShowActive)
    {
        OSL_ASSERT (GetViewShell()!=NULL);

        if (mpContentWindow)
            mpContentWindow->SetPosSizePixel(
                Point(nLeft,nTop),
                Size(nRight-nLeft,nBottom-nTop));
    }

    // Windows in the center and rulers at the left and top side.
	maAllWindowRectangle = Rectangle(
        maViewPos,
        Size(maViewSize.Width()-maScrBarWH.Width(),
            maViewSize.Height()-maScrBarWH.Height()));

    if (mpContentWindow.get() != NULL)
    {
        mpContentWindow->UpdateMapOrigin();
    }

    UpdateScrollBars();

    mpImpl->mbArrangeActive = false;
}




void ViewShell::SetUIUnit(FieldUnit eUnit)
{
    // Set unit at horizontal and vertical rulers.
    if (mpHorizontalRuler.get() != NULL)
        mpHorizontalRuler->SetUnit(eUnit);


	if (mpVerticalRuler.get() != NULL)
        mpVerticalRuler->SetUnit(eUnit);
}

/*************************************************************************
|*
|* DefTab an den horizontalen Linealen setzen
|*
\************************************************************************/
void ViewShell::SetDefTabHRuler( sal_uInt16 nDefTab )
{
    if (mpHorizontalRuler.get() != NULL)
        mpHorizontalRuler->SetDefTabDist( nDefTab );
}




/** Tell the FmFormShell that the view shell is closing.  Give it the
    oportunity to prevent that.
*/
sal_uInt16 ViewShell::PrepareClose (sal_Bool bUI, sal_Bool bForBrowsing)
{
    sal_uInt16 nResult = sal_True;

    FmFormShell* pFormShell = GetViewShellBase().GetFormShellManager()->GetFormShell();
    if (pFormShell != NULL)
        nResult = pFormShell->PrepareClose (bUI, bForBrowsing);

	return nResult;
}




void ViewShell::UpdatePreview (SdPage*, sal_Bool )
{
    // Do nothing.  After the actual preview has been removed,
    // OutlineViewShell::UpdatePreview() is the place where something
    // usefull is still done.
}

::svl::IUndoManager* ViewShell::ImpGetUndoManager (void) const
{
	const ViewShell* pMainViewShell = GetViewShellBase().GetMainViewShell().get();

	if( pMainViewShell == 0 )
		pMainViewShell = this;

	::sd::View* pView = pMainViewShell->GetView();

	// check for text edit our outline view
	if( pView )
	{
		if( pMainViewShell->GetShellType() == ViewShell::ST_OUTLINE )
		{
			OutlineView* pOlView = dynamic_cast< OutlineView* >( pView );
			if( pOlView )
			{
				::Outliner* pOutl = pOlView->GetOutliner();
				if( pOutl )
					return &pOutl->GetUndoManager();
			}
		}
		else if( pView->IsTextEdit() )
		{
			SdrOutliner* pOL = pView->GetTextEditOutliner();
			if( pOL )
				return &pOL->GetUndoManager();
		}
	}

	if( GetDocSh() )
		return GetDocSh()->GetUndoManager();

	return NULL;
}




void ViewShell::ImpGetUndoStrings(SfxItemSet &rSet) const
{
	::svl::IUndoManager* pUndoManager = ImpGetUndoManager();
	if(pUndoManager)
	{
		sal_uInt16 nCount(pUndoManager->GetUndoActionCount());
		if(nCount)
		{
			// prepare list
			List aStringList;
			sal_uInt16 a;

			for( a = 0; a < nCount; a++)
			{
				// generate one String in list per undo step
				String* pInsertString = new String(pUndoManager->GetUndoActionComment(a));
				aStringList.Insert(pInsertString, LIST_APPEND);
			}

			// set item
			rSet.Put(SfxStringListItem(SID_GETUNDOSTRINGS, &aStringList));

			// delete Strings again
			for(a = 0; a < nCount; a++)
				delete (String*)aStringList.GetObject(a);
		}
		else
		{
			rSet.DisableItem(SID_GETUNDOSTRINGS);
		}
	}
}

// -----------------------------------------------------------------------------

void ViewShell::ImpGetRedoStrings(SfxItemSet &rSet) const
{
	::svl::IUndoManager* pUndoManager = ImpGetUndoManager();
	if(pUndoManager)
	{
		sal_uInt16 nCount(pUndoManager->GetRedoActionCount());
		if(nCount)
		{
			// prepare list
			List aStringList;
			sal_uInt16 a;

			for( a = 0; a < nCount; a++)
			{
				// generate one String in list per undo step
				String* pInsertString = new String(pUndoManager->GetRedoActionComment(a));
				aStringList.Insert(pInsertString, LIST_APPEND);
			}

			// set item
			rSet.Put(SfxStringListItem(SID_GETREDOSTRINGS, &aStringList));

			// delete Strings again
			for(a = 0; a < nCount; a++)
				delete (String*)aStringList.GetObject(a);
		}
		else
		{
			rSet.DisableItem(SID_GETREDOSTRINGS);
		}
	}
}

// -----------------------------------------------------------------------------

void ViewShell::ImpSidUndo(sal_Bool, SfxRequest& rReq)
{
	::svl::IUndoManager* pUndoManager = ImpGetUndoManager();
	sal_uInt16 nNumber(1);
	const SfxItemSet* pReqArgs = rReq.GetArgs();

	if(pReqArgs)
	{
		SfxUInt16Item* pUIntItem = (SfxUInt16Item*)&pReqArgs->Get(SID_UNDO);
		nNumber = pUIntItem->GetValue();
	}

	if(nNumber && pUndoManager)
	{
		sal_uInt16 nCount(pUndoManager->GetUndoActionCount());
		if(nCount >= nNumber)
		{
            try
            {
			    // #94637# when UndoStack is cleared by ModifyPageUndoAction
			    // the nCount may have changed, so test GetUndoActionCount()
			    while(nNumber-- && pUndoManager->GetUndoActionCount())
			    {
				    pUndoManager->Undo();
			    }
            }
            catch( const Exception& e )
            {
                // no need to handle. By definition, the UndoManager handled this by clearing the
                // Undo/Redo stacks
            }
		}

		// #91081# refresh rulers, maybe UNDO was move of TAB marker in ruler
		if (mbHasRulers)
		{
			Invalidate(SID_ATTR_TABSTOP);
		}
	}

	// This one is corresponding to the default handling
	// of SID_UNDO in sfx2
	GetViewFrame()->GetBindings().InvalidateAll(sal_False);

	rReq.Done();
}

// -----------------------------------------------------------------------------

void ViewShell::ImpSidRedo(sal_Bool, SfxRequest& rReq)
{
	::svl::IUndoManager* pUndoManager = ImpGetUndoManager();
	sal_uInt16 nNumber(1);
	const SfxItemSet* pReqArgs = rReq.GetArgs();

	if(pReqArgs)
	{
		SfxUInt16Item* pUIntItem = (SfxUInt16Item*)&pReqArgs->Get(SID_REDO);
		nNumber = pUIntItem->GetValue();
	}

	if(nNumber && pUndoManager)
	{
		sal_uInt16 nCount(pUndoManager->GetRedoActionCount());
		if(nCount >= nNumber)
		{
            try
            {
			    // #94637# when UndoStack is cleared by ModifyPageRedoAction
			    // the nCount may have changed, so test GetRedoActionCount()
			    while(nNumber-- && pUndoManager->GetRedoActionCount())
			    {
				    pUndoManager->Redo();
			    }
            }
            catch( const Exception& e )
            {
                // no need to handle. By definition, the UndoManager handled this by clearing the
                // Undo/Redo stacks
            }
		}

		// #91081# refresh rulers, maybe REDO was move of TAB marker in ruler
		if (mbHasRulers)
		{
			Invalidate(SID_ATTR_TABSTOP);
		}
	}

	// This one is corresponding to the default handling
	// of SID_UNDO in sfx2
	GetViewFrame()->GetBindings().InvalidateAll(sal_False);

	rReq.Done();
}

// -----------------------------------------------------------------------------

void ViewShell::ExecReq( SfxRequest& rReq )
{
    sal_uInt16 nSlot = rReq.GetSlot();
    switch( nSlot )
    {
		case SID_MAIL_SCROLLBODY_PAGEDOWN:
		{
			FunctionReference xFunc( GetCurrentFunction() );
			if( xFunc.is() )
			{
				xFunc->ScrollStart();
				ScrollLines( 0, -1 );
				xFunc->ScrollEnd();
			}

            rReq.Done();
		}
		break;

		case SID_OUTPUT_QUALITY_COLOR:
		case SID_OUTPUT_QUALITY_GRAYSCALE:
		case SID_OUTPUT_QUALITY_BLACKWHITE:
		case SID_OUTPUT_QUALITY_CONTRAST:
		{
			sal_uLong nMode = OUTPUT_DRAWMODE_COLOR;

            switch( nSlot )
			{
			    case SID_OUTPUT_QUALITY_COLOR: nMode = OUTPUT_DRAWMODE_COLOR; break;
			    case SID_OUTPUT_QUALITY_GRAYSCALE: nMode = OUTPUT_DRAWMODE_GRAYSCALE; break;
			    case SID_OUTPUT_QUALITY_BLACKWHITE: nMode = OUTPUT_DRAWMODE_BLACKWHITE; break;
			    case SID_OUTPUT_QUALITY_CONTRAST: nMode = OUTPUT_DRAWMODE_CONTRAST; break;
			}

			GetActiveWindow()->SetDrawMode( nMode );
            mpFrameView->SetDrawMode( nMode );
// #110094#-7
//            GetView()->ReleaseMasterPagePaintCache();
			GetActiveWindow()->Invalidate();

			Invalidate();
			rReq.Done();
			break;
		}
    }
}




/** This default implemenation returns only an empty reference.  See derived
    classes for more interesting examples.
*/
::com::sun::star::uno::Reference<
    ::com::sun::star::accessibility::XAccessible>
ViewShell::CreateAccessibleDocumentView (::sd::Window* )
{
    return ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible> ();
}



::sd::WindowUpdater* ViewShell::GetWindowUpdater (void) const
{
    return mpWindowUpdater.get();
}




ViewShellBase& ViewShell::GetViewShellBase (void) const
{
    return *static_cast<ViewShellBase*>(GetViewShell());
}




ViewShell::ShellType ViewShell::GetShellType (void) const
{
    return meShellType;
}




DrawDocShell* ViewShell::GetDocSh (void) const
{
    return GetViewShellBase().GetDocShell();
}




SdDrawDocument* ViewShell::GetDoc (void) const
{
    return GetViewShellBase().GetDocument();
}

ErrCode ViewShell::DoVerb (long )
{
    return ERRCODE_NONE;
}

void ViewShell::SetCurrentFunction( const FunctionReference& xFunction)
{
	if( mxCurrentFunction.is() && (mxOldFunction != mxCurrentFunction) )
		mxCurrentFunction->Dispose();
	FunctionReference xTemp( mxCurrentFunction );
    mxCurrentFunction = xFunction;
}

void ViewShell::SetOldFunction(const FunctionReference& xFunction)
{
	if( mxOldFunction.is() && (xFunction != mxOldFunction) && (mxCurrentFunction != mxOldFunction) )
		mxOldFunction->Dispose();

	FunctionReference xTemp( mxOldFunction );
    mxOldFunction = xFunction;
}

/** this method deactivates the current function. If an old function is
	saved, this will become activated and current function.
*/
void ViewShell::Cancel()
{
	if(mxCurrentFunction.is() && (mxCurrentFunction != mxOldFunction ))
	{
		FunctionReference xTemp( mxCurrentFunction );
		mxCurrentFunction.clear();
		xTemp->Deactivate();
		xTemp->Dispose();
	}

	if(mxOldFunction.is())
	{
		mxCurrentFunction = mxOldFunction;
		mxCurrentFunction->Activate();
	}
}

void ViewShell::DeactivateCurrentFunction( bool bPermanent /* == false */ )
{
	if( mxCurrentFunction.is() )
	{
		if(bPermanent && (mxOldFunction == mxCurrentFunction))
			mxOldFunction.clear();

		mxCurrentFunction->Deactivate();
		if( mxCurrentFunction != mxOldFunction )
			mxCurrentFunction->Dispose();

		FunctionReference xTemp( mxCurrentFunction );
		mxCurrentFunction.clear();
	}
}

void ViewShell::DisposeFunctions()
{
	if(mxCurrentFunction.is())
	{
		FunctionReference xTemp( mxCurrentFunction );
		mxCurrentFunction.clear();
		xTemp->Deactivate();
		xTemp->Dispose();
	}

	if(mxOldFunction.is())
	{
		FunctionReference xTemp( mxOldFunction );
		mxOldFunction->Dispose();
		mxOldFunction.clear();
	}
}

bool ViewShell::IsMainViewShell (void) const
{
    return mpImpl->mbIsMainViewShell;
    //    return GetViewShellBase().GetMainViewShell() == this;
}

void ViewShell::SetIsMainViewShell (bool bIsMainViewShell)
{
    if (bIsMainViewShell != mpImpl->mbIsMainViewShell)
    {
        mpImpl->mbIsMainViewShell = bIsMainViewShell;
        if (bIsMainViewShell)
        {
            GetDocSh()->Connect (this);
        }
        else
        {
            GetDocSh()->Disconnect (this);
        }
    }
}




::sd::Window* ViewShell::GetActiveWindow (void) const
{
    return mpActiveWindow;
}




void ViewShell::PrePaint()
{
}




void ViewShell::Paint (const Rectangle&, ::sd::Window* )
{
}




void ViewShell::Draw(OutputDevice &, const Region &)
{
}




ZoomList* ViewShell::GetZoomList (void)
{
    return mpZoomList;
}




void ViewShell::ShowUIControls (bool bVisible)
{
    mpImpl->mbIsShowingUIControls = bVisible;

	if (mbHasRulers)
	{
		if (mpHorizontalRuler.get() != NULL)
			mpHorizontalRuler->Show( bVisible );

		if (mpVerticalRuler.get() != NULL)
            mpVerticalRuler->Show( bVisible );
	}

	if (mpVerticalScrollBar.get() != NULL)
		mpVerticalScrollBar->Show( bVisible );

	if (mpHorizontalScrollBar.get() != NULL)
		mpHorizontalScrollBar->Show( bVisible );

	if (mpScrollBarBox.get() != NULL)
        mpScrollBarBox->Show(bVisible);

    if (mpContentWindow.get() != NULL)
        mpContentWindow->Show( bVisible );
}





bool ViewShell::RelocateToParentWindow (::Window* pParentWindow)
{
    mpParentWindow = pParentWindow;

    mpParentWindow->SetBackground (Wallpaper());

    if (mpContentWindow.get() != NULL)
        mpContentWindow->SetParent(pParentWindow);

    if (mpHorizontalScrollBar.get() != NULL)
        mpHorizontalScrollBar->SetParent(mpParentWindow);
    if (mpVerticalScrollBar.get() != NULL)
        mpVerticalScrollBar->SetParent(mpParentWindow);
    if (mpScrollBarBox.get() != NULL)
        mpScrollBarBox->SetParent(mpParentWindow);

    return true;
}



} // end of namespace sd





//===== ViewShellObjectBarFactory =============================================

namespace {

ViewShellObjectBarFactory::ViewShellObjectBarFactory (
    ::sd::ViewShell& rViewShell)
    : mrViewShell (rViewShell)
{
}




ViewShellObjectBarFactory::~ViewShellObjectBarFactory (void)
{
    for (ShellCache::iterator aI(maShellCache.begin());
         aI!=maShellCache.end();
         aI++)
    {
        delete aI->second;
    }
}




SfxShell* ViewShellObjectBarFactory::CreateShell (
    ::sd::ShellId nId,
    ::Window*,
    ::sd::FrameView* )
{
    SfxShell* pShell = NULL;

    ShellCache::iterator aI (maShellCache.find(nId));
    if (aI == maShellCache.end() || aI->second==NULL)
    {
        ::sd::View* pView = mrViewShell.GetView();
        switch (nId)
        {
            case RID_BEZIER_TOOLBOX:
                pShell = new ::sd::BezierObjectBar(&mrViewShell, pView);
                break;

            case RID_DRAW_TEXT_TOOLBOX:
                pShell = new ::sd::TextObjectBar(
                    &mrViewShell, mrViewShell.GetDoc()->GetPool(), pView);
                break;

            case RID_DRAW_GRAF_TOOLBOX:
                pShell = new ::sd::GraphicObjectBar(&mrViewShell, pView);
                break;

            case RID_DRAW_MEDIA_TOOLBOX:
                pShell = new ::sd::MediaObjectBar(&mrViewShell, pView);
                break;

			case RID_DRAW_TABLE_TOOLBOX:
				pShell = ::sd::ui::table::CreateTableObjectBar( mrViewShell, pView );
				break;

            case RID_SVX_EXTRUSION_BAR:
                pShell = new ::svx::ExtrusionBar(
                    &mrViewShell.GetViewShellBase());
                break;

            case RID_SVX_FONTWORK_BAR:
                pShell = new ::svx::FontworkBar(
                    &mrViewShell.GetViewShellBase());
                break;

            default:
                pShell = NULL;
                break;
        }
    }
    else
        pShell = aI->second;

    return pShell;
}




void ViewShellObjectBarFactory::ReleaseShell (SfxShell* pShell)
{
    if (pShell != NULL)
        delete pShell;
}

} // end of anonymous namespace
