/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



#include "precompiled_sd.hxx"

#include "controller/SlideSorterController.hxx"

#include "SlideSorter.hxx"
#include "controller/SlsPageSelector.hxx"
#include "controller/SlsSelectionFunction.hxx"
#include "controller/SlsProperties.hxx"
#include "controller/SlsCurrentSlideManager.hxx"
#include "SlsListener.hxx"
#include "controller/SlsFocusManager.hxx"
#include "SlsSelectionCommand.hxx"
#include "controller/SlsAnimator.hxx"
#include "controller/SlsClipboard.hxx"
#include "controller/SlsInsertionIndicatorHandler.hxx"
#include "controller/SlsScrollBarManager.hxx"
#include "controller/SlsSelectionManager.hxx"
#include "controller/SlsSlotManager.hxx"
#include "controller/SlsTransferableData.hxx"
#include "controller/SlsVisibleAreaManager.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"
#include "view/SlsFontProvider.hxx"
#include "view/SlsPageObjectLayouter.hxx"
#include "view/SlsPageObjectPainter.hxx"
#include "view/SlsTheme.hxx"
#include "view/SlsToolTip.hxx"
#include "cache/SlsPageCache.hxx"
#include "cache/SlsPageCacheManager.hxx"

#include "drawdoc.hxx"
#include "DrawViewShell.hxx"
#include "TextLogger.hxx"
#include "ViewShellBase.hxx"
#include "Window.hxx"
#include "FrameView.hxx"
#include "DrawDocShell.hxx"
#include "sdpage.hxx"
#include "res_bmp.hrc"
#include "sdresid.hxx"
#include "strings.hrc"
#include "app.hrc"
#include "glob.hrc"
#include "sdmod.hxx"
#include "sdxfer.hxx"
#include "FrameView.hxx"
#include "ViewShellHint.hxx"
#include "AccessibleSlideSorterView.hxx"
#include "AccessibleSlideSorterObject.hxx"

#include <vcl/window.hxx>
#include <svx/svdopage.hxx>
#include <svx/svxids.hrc>
#include <svx/ruler.hxx>
#include <svx/zoomitem.hxx>
#include <svtools/tabbar.hxx>
#include <sfx2/request.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/dispatch.hxx>
#include <tools/link.hxx>
#include <vcl/svapp.hxx>

#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/drawing/XDrawPages.hpp>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::sd::slidesorter::model;
using namespace ::sd::slidesorter::view;
using namespace ::sd::slidesorter::controller;
using namespace ::basegfx;

namespace sd { namespace slidesorter { namespace controller {


SlideSorterController::SlideSorterController (SlideSorter& rSlideSorter)
    : mrSlideSorter(rSlideSorter),
      mrModel(mrSlideSorter.GetModel()),
      mrView(mrSlideSorter.GetView()),
      mpPageSelector(),
      mpFocusManager(),
      mpSlotManager(),
      mpClipboard(),
      mpScrollBarManager(),
      mpCurrentSlideManager(),
      mpSelectionManager(),
      mpInsertionIndicatorHandler(new InsertionIndicatorHandler(rSlideSorter)),
      mpAnimator(new Animator(rSlideSorter)),
      mpVisibleAreaManager(new VisibleAreaManager(rSlideSorter)),
      mpListener(),
      mnModelChangeLockCount(0),
      mbIsForcedRearrangePending(false),
      mbPreModelChangeDone(false),
      mbPostModelChangePending(false),
      maSelectionBeforeSwitch(),
      mnCurrentPageBeforeSwitch(0),
      mpEditModeChangeMasterPage(NULL),
      maTotalWindowArea(),
      mnPaintEntranceCount(0),
      mbIsContextMenuOpen(false)
{
    SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
    OSL_ASSERT(pWindow);
    if (pWindow)
    {
        // The whole background is painted by the view and controls.
        ::Window* pParentWindow = pWindow->GetParent();
        OSL_ASSERT(pParentWindow!=NULL);
        pParentWindow->SetBackground (Wallpaper());

        // Connect the view with the window that has been created by our base
        // class.
        pWindow->SetBackground(Wallpaper());
        pWindow->SetCenterAllowed(false);
        pWindow->SetMapMode(MapMode(MAP_PIXEL));
        pWindow->SetViewSize(mrView.GetModelArea().GetSize());
    }
}




void SlideSorterController::Init (void)
{
    mpCurrentSlideManager.reset(new CurrentSlideManager(mrSlideSorter));
    mpPageSelector.reset(new PageSelector(mrSlideSorter));
    mpFocusManager.reset(new FocusManager(mrSlideSorter));
    mpSlotManager.reset(new SlotManager(mrSlideSorter));
    mpClipboard.reset(new Clipboard(mrSlideSorter));
    mpScrollBarManager.reset(new ScrollBarManager(mrSlideSorter));
    mpSelectionManager.reset(new SelectionManager(mrSlideSorter));

    mpScrollBarManager->LateInitialization();

    // Create the selection function.
    SfxRequest aRequest (
        SID_OBJECT_SELECT,
        0,
        mrModel.GetDocument()->GetItemPool());
    mrSlideSorter.SetCurrentFunction(CreateSelectionFunction(aRequest));

    mpListener = new Listener(mrSlideSorter);

    mpPageSelector->GetCoreSelection();
    GetSelectionManager()->SelectionHasChanged();
}




SlideSorterController::~SlideSorterController (void)
{
    try
    {
        uno::Reference<lang::XComponent> xComponent (
            static_cast<XWeak*>(mpListener.get()), uno::UNO_QUERY);
        if (xComponent.is())
            xComponent->dispose();
    }
    catch( uno::Exception& e )
    {
        (void)e;
        DBG_ERROR( "sd::SlideSorterController::~SlideSorterController(), exception caught!" );
    }

    // dispose should have been called by now so that nothing is to be done
    // to shut down cleanly.
}




void SlideSorterController::Dispose (void)
{
    mpInsertionIndicatorHandler->End(Animator::AM_Immediate);
    mpSelectionManager.reset();
    mpAnimator->Dispose();
}




model::SharedPageDescriptor SlideSorterController::GetPageAt (
    const Point& aWindowPosition)
{
    sal_Int32 nHitPageIndex (mrView.GetPageIndexAtPoint(aWindowPosition));
    model::SharedPageDescriptor pDescriptorAtPoint;
    if (nHitPageIndex >= 0)
    {
        pDescriptorAtPoint = mrModel.GetPageDescriptor(nHitPageIndex);

        // Depending on a property we may have to check that the mouse is no
        // just over the page object but over the preview area.
        if (pDescriptorAtPoint
            && mrSlideSorter.GetProperties()->IsOnlyPreviewTriggersMouseOver()
            && ! pDescriptorAtPoint->HasState(PageDescriptor::ST_Selected))
        {
            // Make sure that the mouse is over the preview area.
            if ( ! mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox(
                pDescriptorAtPoint,
                view::PageObjectLayouter::Preview,
                view::PageObjectLayouter::WindowCoordinateSystem).IsInside(aWindowPosition))
            {
                pDescriptorAtPoint.reset();
            }
        }
    }

    return pDescriptorAtPoint;
}




PageSelector& SlideSorterController::GetPageSelector (void)
{
    OSL_ASSERT(mpPageSelector.get()!=NULL);
    return *mpPageSelector.get();
}




FocusManager& SlideSorterController::GetFocusManager (void)
{
    OSL_ASSERT(mpFocusManager.get()!=NULL);
    return *mpFocusManager.get();
}




Clipboard& SlideSorterController::GetClipboard (void)
{
    OSL_ASSERT(mpClipboard.get()!=NULL);
    return *mpClipboard.get();
}




ScrollBarManager& SlideSorterController::GetScrollBarManager (void)
{
    OSL_ASSERT(mpScrollBarManager.get()!=NULL);
    return *mpScrollBarManager.get();
}




::boost::shared_ptr<CurrentSlideManager> SlideSorterController::GetCurrentSlideManager (void) const
{
    OSL_ASSERT(mpCurrentSlideManager.get()!=NULL);
    return mpCurrentSlideManager;
}




::boost::shared_ptr<SlotManager> SlideSorterController::GetSlotManager (void) const
{
    OSL_ASSERT(mpSlotManager.get()!=NULL);
    return mpSlotManager;
}




::boost::shared_ptr<SelectionManager> SlideSorterController::GetSelectionManager (void) const
{
    OSL_ASSERT(mpSelectionManager.get()!=NULL);
    return mpSelectionManager;
}




::boost::shared_ptr<InsertionIndicatorHandler>
    SlideSorterController::GetInsertionIndicatorHandler (void) const
{
    OSL_ASSERT(mpInsertionIndicatorHandler.get()!=NULL);
    return mpInsertionIndicatorHandler;
}
    



void SlideSorterController::Paint (
    const Rectangle& rBBox,
    ::Window* pWindow)
{
    if (mnPaintEntranceCount == 0)
    {
        ++mnPaintEntranceCount;

        try
        {
            mrView.CompleteRedraw(pWindow, Region(rBBox), 0);
        }
        catch (const Exception&)
        {
            // Ignore all exceptions.
        }

        --mnPaintEntranceCount;
    }
}




void SlideSorterController::FuTemporary (SfxRequest& rRequest)
{
    mpSlotManager->FuTemporary (rRequest);
}




void SlideSorterController::FuPermanent (SfxRequest &rRequest)
{
    mpSlotManager->FuPermanent (rRequest);
}




void SlideSorterController::FuSupport (SfxRequest &rRequest)
{
    mpSlotManager->FuSupport (rRequest);
}




bool SlideSorterController::Command (
    const CommandEvent& rEvent,
    ::sd::Window* pWindow)
{
    bool bEventHasBeenHandled = false;

    if (pWindow == NULL)
        return false;
    
    ViewShell* pViewShell = mrSlideSorter.GetViewShell();
    if (pViewShell == NULL)
        return false;
    
    switch (rEvent.GetCommand())
    {
        case COMMAND_CONTEXTMENU:
        {
            SdPage* pPage = NULL;
            sal_uInt16 nPopupId;

            model::PageEnumeration aSelectedPages (
                PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel));
            if (aSelectedPages.HasMoreElements())
                pPage = aSelectedPages.GetNextElement()->GetPage();

            // Choose the popup menu depending on a) the type of the main
            // view shell, b) the edit mode, and c) on whether the selection
            // is empty or not.
            ViewShell::ShellType eMainViewShellType (ViewShell::ST_NONE);
            ::boost::shared_ptr<ViewShell> pMainViewShell (
                pViewShell->GetViewShellBase().GetMainViewShell());
            if (pMainViewShell.get() != NULL)
                eMainViewShellType = pMainViewShell->GetShellType();
            switch (eMainViewShellType)
            {
                case ViewShell::ST_DRAW:
                    if (pPage != NULL)
                        nPopupId = RID_SLIDE_SORTER_DRAW_SEL_POPUP;
                    else
                        nPopupId = RID_SLIDE_SORTER_DRAW_NOSEL_POPUP;
                    break;

                default:
                    if (mrModel.GetEditMode() == EM_PAGE)
                        if (pPage != NULL)
                            nPopupId = RID_SLIDE_SORTER_IMPRESS_SEL_POPUP;
                        else
                            nPopupId = RID_SLIDE_SORTER_IMPRESS_NOSEL_POPUP;
                    else
                        if (pPage != NULL)
                            nPopupId = RID_SLIDE_SORTER_MASTER_SEL_POPUP;
                        else
                            nPopupId = RID_SLIDE_SORTER_MASTER_NOSEL_POPUP;
            }
            ::boost::scoped_ptr<InsertionIndicatorHandler::ForceShowContext> pContext;
            if (pPage == NULL)
            {
                // When there is no selection, then we show the insertion
                // indicator so that the user knows where a page insertion
                // would take place.
                mpInsertionIndicatorHandler->Start(false);
                mpInsertionIndicatorHandler->UpdateIndicatorIcon(SD_MOD()->pTransferClip);
                mpInsertionIndicatorHandler->UpdatePosition(
                    pWindow->PixelToLogic(rEvent.GetMousePosPixel()),
                    InsertionIndicatorHandler::MoveMode);
                pContext.reset(new InsertionIndicatorHandler::ForceShowContext(
                    mpInsertionIndicatorHandler));
            }

            pWindow->ReleaseMouse();

            Point aMenuLocation (0,0);
            if (rEvent.IsMouseEvent())
            {
                // We have to explicitly specify the location of the menu
                // when the slide sorter is placed in an undocked child
                // menu.  But when it is docked it does not hurt, so we
                // specify the location always.
                aMenuLocation = rEvent.GetMousePosPixel();
            }
            else
            {
                // The event is not a mouse event.  Use the center of the
                // focused page as top left position of the context menu.
                model::SharedPageDescriptor pDescriptor (
                    GetFocusManager().GetFocusedPageDescriptor());
                if (pDescriptor.get() != NULL)
                {
                    Rectangle aBBox (
                        mrView.GetLayouter().GetPageObjectLayouter()->GetBoundingBox (
                            pDescriptor,
                            PageObjectLayouter::PageObject,
                            PageObjectLayouter::ModelCoordinateSystem));
                    aMenuLocation = aBBox.Center();
                }
            }
            
            mbIsContextMenuOpen = true;
            if (pViewShell != NULL)
            {
                SfxDispatcher* pDispatcher = pViewShell->GetDispatcher();
                if (pDispatcher != NULL)
                {
                    pDispatcher->ExecutePopup(
                        SdResId(nPopupId),
                        pWindow,
                        &aMenuLocation);
                    mrSlideSorter.GetView().UpdatePageUnderMouse(false);
                    ::rtl::Reference<SelectionFunction> pFunction(GetCurrentSelectionFunction());
                    if (pFunction.is())
                        pFunction->ResetMouseAnchor();
                }
            }
            mbIsContextMenuOpen = false;
            if (pPage == NULL)
            {
                // Remember the position of the insertion indicator before
                // it is hidden, so that a pending slide insertion slot call
                // finds the right place to insert a new slide.
                GetSelectionManager()->SetInsertionPosition(
                    GetInsertionIndicatorHandler()->GetInsertionPageIndex());
            }
            pContext.reset();
            bEventHasBeenHandled = true;
        }
        break;

        case COMMAND_WHEEL:
        {
            const CommandWheelData* pData = rEvent.GetWheelData();
            if (pData == NULL)
                return false;
            if (pData->IsMod1())
            {
                // We do not support zooming with control+mouse wheel.
                return false;
            }
            // Determine whether to scroll horizontally or vertically.  This
            // depends on the orientation of the scroll bar and the
            // IsHoriz() flag of the event.
            if ((mrSlideSorter.GetView().GetOrientation()==view::Layouter::HORIZONTAL)
                == pData->IsHorz())
            {
                GetScrollBarManager().Scroll(
                    ScrollBarManager::Orientation_Vertical,
                    ScrollBarManager::Unit_Slide,
                    -pData->GetNotchDelta());
            }
            else
            {
                GetScrollBarManager().Scroll(
                    ScrollBarManager::Orientation_Horizontal,
                    ScrollBarManager::Unit_Slide,
                    -pData->GetNotchDelta());
            }
            mrSlideSorter.GetView().UpdatePageUnderMouse(rEvent.GetMousePosPixel(), false);

            bEventHasBeenHandled = true;
        }
        break;
	}

    return bEventHasBeenHandled;
}




void SlideSorterController::LockModelChange (void)
{
    mnModelChangeLockCount += 1;
}




void SlideSorterController::UnlockModelChange (void)
{
    mnModelChangeLockCount -= 1;
    if (mnModelChangeLockCount==0 && mbPostModelChangePending)
    {
        PostModelChange();
    }
}




void SlideSorterController::PreModelChange (void)
{
    // Prevent PreModelChange to execute more than once per model lock.
    if (mbPostModelChangePending)
        return;
    mbPreModelChangeDone = true;
    
    if (mrSlideSorter.GetViewShell() != NULL)
        mrSlideSorter.GetViewShell()->Broadcast(
            ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START));

    GetCurrentSlideManager()->PrepareModelChange();

    if (mrSlideSorter.GetContentWindow())
        mrView.PreModelChange();

    mbPostModelChangePending = true;
}




void SlideSorterController::PostModelChange (void)
{
    mbPostModelChangePending = false;
    mrModel.Resync();

    SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
    if (pWindow)
    {
        GetCurrentSlideManager()->HandleModelChange();

        mrView.PostModelChange ();

        pWindow->SetViewOrigin (Point (0,0));
        pWindow->SetViewSize (mrView.GetModelArea().GetSize());

        // The visibility of the scroll bars may have to be changed.  Then
        // the size of the view has to change, too.  Let Rearrange() handle
        // that.
        Rearrange(mbIsForcedRearrangePending);
    }

    if (mrSlideSorter.GetViewShell() != NULL)
        mrSlideSorter.GetViewShell()->Broadcast(
            ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END));
}




void SlideSorterController::HandleModelChange (void)
{
    // Ignore this call when the document is not in a valid state, i.e. has
    // not the same number of regular and notes pages.
    bool bIsDocumentValid = (mrModel.GetDocument()->GetPageCount() % 2 == 1);

    if (bIsDocumentValid)
    {
        ModelChangeLock aLock (*this);
        PreModelChange();
    }
}




IMPL_LINK(SlideSorterController, WindowEventHandler, VclWindowEvent*, pEvent)
{
    if (pEvent != NULL)
    {
        ::Window* pWindow = pEvent->GetWindow();
        SharedSdWindow pActiveWindow (mrSlideSorter.GetContentWindow());
        switch (pEvent->GetId())
        {
            case VCLEVENT_WINDOW_ACTIVATE:
            case VCLEVENT_WINDOW_SHOW:
                if (pActiveWindow && pWindow == pActiveWindow->GetParent())
                    mrView.RequestRepaint();
                break;

            case VCLEVENT_WINDOW_HIDE:
                if (pActiveWindow && pWindow == pActiveWindow->GetParent())
                    mrView.SetPageUnderMouse(SharedPageDescriptor());
                break;

            case VCLEVENT_WINDOW_GETFOCUS:
                if (pActiveWindow)
                    if (pWindow == pActiveWindow.get())
                        GetFocusManager().ShowFocus(false);
                break;

            case VCLEVENT_WINDOW_LOSEFOCUS:
                if (pActiveWindow && pWindow == pActiveWindow.get())
                {
                    GetFocusManager().HideFocus();
                    mrView.GetToolTip().Hide();
                    
                    // Select the current slide so that it is properly
                    // visualized when the focus is moved to the edit view.
                    GetPageSelector().SelectPage(GetCurrentSlideManager()->GetCurrentSlide());
                }
                break;

            case VCLEVENT_APPLICATION_DATACHANGED:
            {
                // Invalidate the preview cache.
                cache::PageCacheManager::Instance()->InvalidateAllCaches();

                // Update the draw mode.
                sal_uLong nDrawMode (Application::GetSettings().GetStyleSettings().GetHighContrastMode()
                    ? ViewShell::OUTPUT_DRAWMODE_CONTRAST
                    : ViewShell::OUTPUT_DRAWMODE_COLOR);
                if (mrSlideSorter.GetViewShell() != NULL)
                    mrSlideSorter.GetViewShell()->GetFrameView()->SetDrawMode(nDrawMode);
                if( bool(pActiveWindow) )
                    pActiveWindow->SetDrawMode(nDrawMode);
                mrView.HandleDrawModeChange();
                
                // When the system font has changed a layout has to be done.
                mrView.Resize();
                FontProvider::Instance().Invalidate();

                // Update theme colors.
                mrSlideSorter.GetProperties()->HandleDataChangeEvent();
                mrSlideSorter.GetTheme()->Update(mrSlideSorter.GetProperties());
                mrView.HandleDataChangeEvent();
            }
            break;

            default:
                break;
        }
    }

    return sal_True;
}




void SlideSorterController::GetCtrlState (SfxItemSet& rSet)
{
	if (rSet.GetItemState(SID_RELOAD) != SFX_ITEM_UNKNOWN)
	{
		// "Letzte Version" vom SFx en/disablen lassen
        SfxViewFrame* pSlideViewFrame = SfxViewFrame::Current();
		DBG_ASSERT(pSlideViewFrame!=NULL,
            "SlideSorterController::GetCtrlState: ViewFrame not found");
		if (pSlideViewFrame)
		{
			pSlideViewFrame->GetSlotState (SID_RELOAD, NULL, &rSet);
		}
		else		// MI sagt: kein MDIFrame --> disablen
		{
			rSet.DisableItem(SID_RELOAD);
		}
	}

    // Output quality.
	if (rSet.GetItemState(SID_OUTPUT_QUALITY_COLOR)==SFX_ITEM_AVAILABLE
        ||rSet.GetItemState(SID_OUTPUT_QUALITY_GRAYSCALE)==SFX_ITEM_AVAILABLE
        ||rSet.GetItemState(SID_OUTPUT_QUALITY_BLACKWHITE)==SFX_ITEM_AVAILABLE
        ||rSet.GetItemState(SID_OUTPUT_QUALITY_CONTRAST)==SFX_ITEM_AVAILABLE)
	{
		if (mrSlideSorter.GetContentWindow())
		{
			sal_uLong nMode = mrSlideSorter.GetContentWindow()->GetDrawMode();
			sal_uInt16 nQuality = 0;

			switch (nMode)
			{
				case ViewShell::OUTPUT_DRAWMODE_COLOR:
					nQuality = 0;
					break;
				case ViewShell::OUTPUT_DRAWMODE_GRAYSCALE:
					nQuality = 1;
					break;
				case ViewShell::OUTPUT_DRAWMODE_BLACKWHITE:
					nQuality = 2;
					break;
				case ViewShell::OUTPUT_DRAWMODE_CONTRAST:
					nQuality = 3;
					break;
			}

			rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_COLOR,
					(sal_Bool)(nQuality==0)));
			rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_GRAYSCALE,
					(sal_Bool)(nQuality==1)));
			rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_BLACKWHITE,
					(sal_Bool)(nQuality==2)));
			rSet.Put (SfxBoolItem (SID_OUTPUT_QUALITY_CONTRAST,
					(sal_Bool)(nQuality==3)));
		}
	}

	if (rSet.GetItemState(SID_MAIL_SCROLLBODY_PAGEDOWN) == SFX_ITEM_AVAILABLE)
	{
		rSet.Put (SfxBoolItem( SID_MAIL_SCROLLBODY_PAGEDOWN, sal_True));
	}
}




void SlideSorterController::GetStatusBarState (SfxItemSet& rSet)
{
    mpSlotManager->GetStatusBarState (rSet);
}




void SlideSorterController::ExecCtrl (SfxRequest& rRequest)
{
    mpSlotManager->ExecCtrl (rRequest);
}




void SlideSorterController::GetAttrState (SfxItemSet& rSet)
{
    mpSlotManager->GetAttrState (rSet);
}




void SlideSorterController::ExecStatusBar (SfxRequest& )
{
}




void SlideSorterController::UpdateAllPages (void)
{
    // Do a redraw.
    mrSlideSorter.GetContentWindow()->Invalidate();
}




Rectangle SlideSorterController::Resize (const Rectangle& rAvailableSpace)
{
    Rectangle aContentArea (rAvailableSpace);

    if (maTotalWindowArea != rAvailableSpace)
    {
        maTotalWindowArea = rAvailableSpace;
        aContentArea = Rearrange(true);
    }

    return aContentArea;
}




Rectangle  SlideSorterController::Rearrange (bool bForce)
{
    Rectangle aNewContentArea (maTotalWindowArea);

    if (aNewContentArea.IsEmpty())
        return aNewContentArea;

    if (mnModelChangeLockCount>0)
    {
        mbIsForcedRearrangePending |= bForce;
        return aNewContentArea;
    }
    else
        mbIsForcedRearrangePending = false;

    SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
    if (pWindow)
    {
        if (bForce)
            mrView.UpdateOrientation();

        // Place the scroll bars.
        aNewContentArea = GetScrollBarManager().PlaceScrollBars(
            maTotalWindowArea,
            mrView.GetOrientation() != view::Layouter::VERTICAL,
            mrView.GetOrientation() != view::Layouter::HORIZONTAL);

        bool bSizeHasChanged (false);
        // Only when bForce is not true we have to test for a size change in
        // order to determine whether the window and the view have to be resized.
        if ( ! bForce)
        {
            Rectangle aCurrentContentArea (pWindow->GetPosPixel(), pWindow->GetOutputSizePixel());
            bSizeHasChanged = (aNewContentArea != aCurrentContentArea);
        }
        if (bForce || bSizeHasChanged)
        {
            // The browser window gets the remaining space.
            pWindow->SetPosSizePixel (aNewContentArea.TopLeft(), aNewContentArea.GetSize());
            mrView.Resize();
        }

        // Adapt the scroll bars to the new zoom factor of the browser
        // window and the arrangement of the page objects.
        GetScrollBarManager().UpdateScrollBars(false, !bForce);

        // Keep the current slide in the visible area.
        GetVisibleAreaManager().RequestCurrentSlideVisible();

        mrView.RequestRepaint();
    }

    return aNewContentArea;
}




FunctionReference SlideSorterController::CreateSelectionFunction (SfxRequest& rRequest)
{
	FunctionReference xFunc( SelectionFunction::Create(mrSlideSorter, rRequest) );
    return xFunc;
}




::rtl::Reference<SelectionFunction> SlideSorterController::GetCurrentSelectionFunction (void)
{
	FunctionReference pFunction (mrSlideSorter.GetViewShell()->GetCurrentFunction());
    return ::rtl::Reference<SelectionFunction>(dynamic_cast<SelectionFunction*>(pFunction.get()));
}




void SlideSorterController::PrepareEditModeChange (void)
{
    //  Before we throw away the page descriptors we prepare for selecting
    //  descriptors in the other mode and for restoring the current
    //  selection when switching back to the current mode.
    if (mrModel.GetEditMode() == EM_PAGE)
    {
        maSelectionBeforeSwitch.clear();

        // Search for the first selected page and determine the master page
        // used by its page object.  It will be selected after the switch.
        // In the same loop the current selection is stored.
        PageEnumeration aSelectedPages (
            PageEnumerationProvider::CreateSelectedPagesEnumeration(mrModel));
        while (aSelectedPages.HasMoreElements())
        {
            SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
            SdPage* pPage = pDescriptor->GetPage();
            // Remember the master page of the first selected descriptor.
            if (pPage!=NULL && mpEditModeChangeMasterPage==NULL)
                mpEditModeChangeMasterPage = &static_cast<SdPage&>(
                    pPage->TRG_GetMasterPage());

            maSelectionBeforeSwitch.push_back(pPage);
        }

        // Remember the current page.
        if (mrSlideSorter.GetViewShell() != NULL)
            mnCurrentPageBeforeSwitch = (mrSlideSorter.GetViewShell()->GetViewShellBase()
            .GetMainViewShell()->GetActualPage()->GetPageNum()-1)/2;
    }
}




bool SlideSorterController::ChangeEditMode (EditMode eEditMode)
{
    bool bResult (false);
    if (mrModel.GetEditMode() != eEditMode)
    {
        ModelChangeLock aLock (*this);
        PreModelChange();
        // Do the actual edit mode switching.
        bResult = mrModel.SetEditMode(eEditMode);
        if (bResult)
            HandleModelChange();
    }
    return bResult;
}




void SlideSorterController::FinishEditModeChange (void)
{
    if (mrModel.GetEditMode() == EM_MASTERPAGE)
    {
        mpPageSelector->DeselectAllPages();

        // Search for the master page that was determined in
        // PrepareEditModeChange() and make it the current page.
        PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
        while (aAllPages.HasMoreElements())
        {
            SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
            if (pDescriptor->GetPage() == mpEditModeChangeMasterPage)
            {
                GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
                mpPageSelector->SelectPage(pDescriptor);
                break;
            }
        }
    }
    else
    {
        PageSelector::BroadcastLock aBroadcastLock (*mpPageSelector);

        SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(mnCurrentPageBeforeSwitch));
        GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);

        // Restore the selection.
        mpPageSelector->DeselectAllPages();
        ::std::vector<SdPage*>::iterator iPage;
        for (iPage=maSelectionBeforeSwitch.begin();
             iPage!=maSelectionBeforeSwitch.end();
             ++iPage)
        {
            mpPageSelector->SelectPage(*iPage);
        }
        maSelectionBeforeSwitch.clear( );
    }
    mpEditModeChangeMasterPage = NULL;
}




void SlideSorterController::PageNameHasChanged (int nPageIndex, const String& rsOldName)
{
    // Request a repaint for the page object whose name has changed.
    model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nPageIndex));
    if (pDescriptor.get() != NULL)
        mrView.RequestRepaint(pDescriptor);

    // Get a pointer to the corresponding accessible object and notify
    // that of the name change.
    do
    {
        SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
        if ( ! pWindow)
            break;

        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
            xAccessible (pWindow->GetAccessible(sal_False));
        if ( ! xAccessible.is())
            break;

        // Now comes a small hack.  We assume that the accessible object is
        // an instantiation of AccessibleSlideSorterView and cast it to that
        // class.  The cleaner alternative to this cast would be a new member
        // in which we would store the last AccessibleSlideSorterView object
        // created by SlideSorterViewShell::CreateAccessibleDocumentView().
        // But then there is no guaranty that the accessible object obtained
        // from the window really is that instance last created by
        // CreateAccessibleDocumentView().
        // However, the dynamic cast together with the check of the result
        // being NULL should be safe enough.
        ::accessibility::AccessibleSlideSorterView* pAccessibleView
              = dynamic_cast< ::accessibility::AccessibleSlideSorterView*>(xAccessible.get());
        if (pAccessibleView == NULL)
            break;

        ::accessibility::AccessibleSlideSorterObject* pChild
              = pAccessibleView->GetAccessibleChildImplementation(nPageIndex);
        if (pChild == NULL || pChild->GetPage() == NULL)
            break;

        ::rtl::OUString sOldName (rsOldName);
        ::rtl::OUString sNewName (pChild->GetPage()->GetName());
        pChild->FireAccessibleEvent(
            ::com::sun::star::accessibility::AccessibleEventId::NAME_CHANGED,
            makeAny(sOldName),
            makeAny(sNewName));
    }
    while (false);
}




bool SlideSorterController::IsContextMenuOpen (void) const
{
    return mbIsContextMenuOpen;
}




void SlideSorterController::SetDocumentSlides (const Reference<container::XIndexAccess>& rxSlides)
{
    if (mrModel.GetDocumentSlides() != rxSlides)
    {
        ModelChangeLock aLock (*this);
        PreModelChange();

        mrModel.SetDocumentSlides(rxSlides);
    }
}




::boost::shared_ptr<Animator> SlideSorterController::GetAnimator (void) const
{
    return mpAnimator;
}




VisibleAreaManager& SlideSorterController::GetVisibleAreaManager (void) const
{
    OSL_ASSERT(mpVisibleAreaManager);
    return *mpVisibleAreaManager;
}




void SlideSorterController::CheckForMasterPageAssignment (void)
{
    if (mrModel.GetPageCount()%2==0)
        return;
    PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
    while (aAllPages.HasMoreElements())
    {
        SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
        if (pDescriptor->UpdateMasterPage())
        {
            mrView.GetPreviewCache()->InvalidatePreviewBitmap (
                pDescriptor->GetPage(),
                true);
        }
    }
}




void SlideSorterController::CheckForSlideTransitionAssignment (void)
{
    if (mrModel.GetPageCount()%2==0)
        return;
    PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
    while (aAllPages.HasMoreElements())
    {
        SharedPageDescriptor pDescriptor (aAllPages.GetNextElement());
        if (pDescriptor->UpdateTransitionFlag())
        {
            mrView.GetPreviewCache()->InvalidatePreviewBitmap (
                pDescriptor->GetPage(),
                true);
        }
    }
}




//===== SlideSorterController::ModelChangeLock ================================

SlideSorterController::ModelChangeLock::ModelChangeLock (
    SlideSorterController& rController)
    : mpController(&rController)
{
    mpController->LockModelChange();
}




SlideSorterController::ModelChangeLock::~ModelChangeLock (void)
{
    Release();
}




void SlideSorterController::ModelChangeLock::Release (void)
{
    if (mpController != NULL)
    {
        mpController->UnlockModelChange();
        mpController = NULL;
    }
}

} } } // end of namespace ::sd::slidesorter
