Impress: Kill the so much hated ButtonBar in slide sorter.

Change-Id: I9eb570e04fc43f2be2ceecd14cb3a41535e49b9b
diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index 26754cb..6eda345 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -373,7 +373,6 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
    sd/source/ui/slidesorter/shell/SlideSorterService \
    sd/source/ui/slidesorter/shell/SlideSorterViewShell \
    sd/source/ui/slidesorter/view/SlideSorterView \
    sd/source/ui/slidesorter/view/SlsButtonBar \
    sd/source/ui/slidesorter/view/SlsFontProvider \
    sd/source/ui/slidesorter/view/SlsFramePainter \
    sd/source/ui/slidesorter/view/SlsInsertAnimator \
diff --git a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
index ae9a6e9..a28b3a8 100644
--- a/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
+++ b/sd/source/ui/slidesorter/controller/SlideSorterController.cxx
@@ -471,7 +471,7 @@ bool SlideSorterController::Command (
                        SdResId(nPopupId),
                        pWindow,
                        &aMenuLocation);
                    mrSlideSorter.GetView().UpdatePageUnderMouse(false);
                    mrSlideSorter.GetView().UpdatePageUnderMouse();
                    ::rtl::Reference<SelectionFunction> pFunction(GetCurrentSelectionFunction());
                    if (pFunction.is())
                        pFunction->ResetMouseAnchor();
@@ -519,7 +519,7 @@ bool SlideSorterController::Command (
                    ScrollBarManager::Unit_Slide,
                    -pData->GetNotchDelta());
            }
            mrSlideSorter.GetView().UpdatePageUnderMouse(rEvent.GetMousePosPixel(), false);
            mrSlideSorter.GetView().UpdatePageUnderMouse(rEvent.GetMousePosPixel());

            bEventHasBeenHandled = true;
        }
diff --git a/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx b/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx
index 86e9658..c703d64 100644
--- a/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsAnimationFunction.cxx
@@ -57,23 +57,6 @@ double AnimationFunction::Blend (



void AnimationFunction::ApplyButtonAlphaChange(
    const model::SharedPageDescriptor& rpDescriptor,
    view::SlideSorterView& rView,
    const double nButtonAlpha,
    const double nButtonBarAlpha)
{
    if (rpDescriptor)
    {
        rpDescriptor->GetVisualState().SetButtonAlpha(nButtonAlpha);
        rpDescriptor->GetVisualState().SetButtonBarAlpha(nButtonBarAlpha);
        rView.RequestRepaint(rpDescriptor);
    }
}




//===== AnimationBezierFunction ===============================================

AnimationBezierFunction::AnimationBezierFunction (
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
index 16c23ad..a451c12 100644
--- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
@@ -50,7 +50,6 @@
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"
#include "view/SlsPageObjectLayouter.hxx"
#include "view/SlsButtonBar.hxx"
#include "framework/FrameworkHelper.hxx"
#include "ViewShellBase.hxx"
#include "DrawController.hxx"
@@ -87,8 +86,6 @@ static const sal_uInt32 MOUSE_DRAG               (0x00000800);
static const sal_uInt32 OVER_SELECTED_PAGE       (0x00010000);
static const sal_uInt32 OVER_UNSELECTED_PAGE     (0x00020000);
static const sal_uInt32 OVER_FADE_INDICATOR      (0x00040000);
static const sal_uInt32 OVER_BUTTON_AREA         (0x00080000);
static const sal_uInt32 OVER_BUTTON              (0x00100000);
static const sal_uInt32 SHIFT_MODIFIER           (0x00200000);
static const sal_uInt32 CONTROL_MODIFIER         (0x00400000);

@@ -124,7 +121,6 @@ public:
    model::SharedPageDescriptor mpHitDescriptor;
    SdrPage* mpHitPage;
    sal_uInt32 mnEventCode;
    bool mbIsOverButton;
    InsertionIndicatorHandler::Mode meDragMode;
    bool mbMakeSelectionVisible;
    bool mbIsLeaving;
@@ -276,7 +272,6 @@ private:
    bool mbAutoScrollInstalled;
    sal_Int32 mnAnchorIndex;
    sal_Int32 mnSecondIndex;
    view::ButtonBar::Lock maButtonBarLock;

    virtual void UpdateModelPosition (const Point& rMouseModelPosition);
    virtual void UpdateSelection (void);
@@ -317,29 +312,6 @@ private:
};


/** Handle events while the left mouse button is pressed over the button
    bar.
*/
class ButtonModeHandler : public SelectionFunction::ModeHandler
{
public:
    ButtonModeHandler (
        SlideSorter& rSlideSorter,
        SelectionFunction& rSelectionFunction);
    virtual ~ButtonModeHandler (void);
    virtual void Abort (void);

    virtual SelectionFunction::Mode GetMode (void) const;

protected:
    virtual bool ProcessButtonDownEvent (SelectionFunction::EventDescriptor& rDescriptor);
    virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor);
    virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor);
};




//===== SelectionFunction =====================================================

TYPEINIT1(SelectionFunction, FuPoor);
@@ -834,24 +806,6 @@ void SelectionFunction::SwitchToMultiSelectionMode (



bool SelectionFunction::SwitchToButtonMode (void)
{
    // Do not show the buttons for draw pages.
    ::boost::shared_ptr<ViewShell> pMainViewShell (mrSlideSorter.GetViewShellBase()->GetMainViewShell());
    if (pMainViewShell
        && pMainViewShell->GetShellType()!=ViewShell::ST_DRAW
        && mpModeHandler->GetMode() != ButtonMode)
    {
        SwitchMode(::boost::shared_ptr<ModeHandler>(new ButtonModeHandler(mrSlideSorter, *this)));
        return true;
    }
    else
        return false;
}




void SelectionFunction::SwitchMode (const ::boost::shared_ptr<ModeHandler>& rpHandler)
{
    // Not all modes allow mouse over indicator.
@@ -860,10 +814,9 @@ void SelectionFunction::SwitchMode (const ::boost::shared_ptr<ModeHandler>& rpHa
        if ( ! rpHandler->IsMouseOverIndicatorAllowed())
        {
            mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor());
            mrSlideSorter.GetView().GetButtonBar().ResetPage();
        }
        else
            mrSlideSorter.GetView().UpdatePageUnderMouse(false);
            mrSlideSorter.GetView().UpdatePageUnderMouse();
    }

    mpModeHandler = rpHandler;
@@ -905,7 +858,6 @@ SelectionFunction::EventDescriptor::EventDescriptor (
      mpHitDescriptor(),
      mpHitPage(),
      mnEventCode(nEventType),
      mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()),
      meDragMode(InsertionIndicatorHandler::MoveMode),
      mbMakeSelectionVisible(true),
      mbIsLeaving(false)
@@ -941,7 +893,6 @@ SelectionFunction::EventDescriptor::EventDescriptor (
      mpHitDescriptor(),
      mpHitPage(),
      mnEventCode(nEventType),
      mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()),
      meDragMode(InsertionIndicatorHandler::GetModeFromDndAction(nDragAction)),
      mbMakeSelectionVisible(true),
      mbIsLeaving(false)
@@ -994,11 +945,6 @@ sal_uInt32 SelectionFunction::EventDescriptor::EncodeMouseEvent (
    if (rEvent.IsMod1())
        nEventCode |= CONTROL_MODIFIER;

    // Detect whether the mouse is over one of the active elements inside a
    // page object.
    if (mbIsOverButton)
        nEventCode |= OVER_BUTTON;

    return nEventCode;
}

@@ -1013,11 +959,6 @@ sal_uInt32 SelectionFunction::EventDescriptor::EncodeState (void) const
            nEventCode |= OVER_SELECTED_PAGE;
        else
            nEventCode |= OVER_UNSELECTED_PAGE;

        // Detect whether the mouse is over one of the active elements
        // inside a page object.
        if (mbIsOverButton)
            nEventCode |= OVER_BUTTON;
    }

    return nEventCode;
@@ -1109,10 +1050,7 @@ bool SelectionFunction::ModeHandler::ProcessButtonUpEvent (EventDescriptor&)
bool SelectionFunction::ModeHandler::ProcessMotionEvent (EventDescriptor& rDescriptor)
{
    if (mbIsMouseOverIndicatorAllowed)
        mrSlideSorter.GetView().UpdatePageUnderMouse(
            rDescriptor.maMousePosition,
            (rDescriptor.mnEventCode & LEFT_BUTTON) != 0,
            true);
        mrSlideSorter.GetView().UpdatePageUnderMouse(rDescriptor.maMousePosition);

    if (rDescriptor.mbIsLeaving)
    {
@@ -1294,26 +1232,6 @@ bool NormalModeHandler::ProcessButtonDownEvent (
            RangeSelect(rDescriptor.mpHitDescriptor);
            break;

        case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | OVER_BUTTON:
        case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | OVER_BUTTON:
            OSL_ASSERT(mrSlideSorter.GetView().GetButtonBar().IsMouseOverButton());

            // Switch to button mode only when the buttons are visible
            // (or being faded in.)
            if (mrSlideSorter.GetView().GetButtonBar().IsVisible(rDescriptor.mpHitDescriptor))
            {
                if (mrSelectionFunction.SwitchToButtonMode())
                    ReprocessEvent(rDescriptor);
            }
            else
            {
                // When the buttons are not (yet) visible then behave like
                // the left button had been clicked over any other part of
                // the slide.
                SetCurrentPage(rDescriptor.mpHitDescriptor);
            }
            break;

            // Right button for context menu.
        case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE:
            // Single right click and shift+F10 select as preparation to
@@ -1372,10 +1290,7 @@ bool NormalModeHandler::ProcessButtonUpEvent (
        case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | CONTROL_MODIFIER:
            mrSlideSorter.GetController().GetPageSelector().SelectPage(
                rDescriptor.mpHitDescriptor);
            mrSlideSorter.GetView().UpdatePageUnderMouse(
                rDescriptor.mpHitDescriptor,
                rDescriptor.maMousePosition,
                false);
            mrSlideSorter.GetView().SetPageUnderMouse(rDescriptor.mpHitDescriptor);
            break;
        case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE:
            break;
@@ -1506,8 +1421,7 @@ MultiSelectionModeHandler::MultiSelectionModeHandler (
      maSavedPointer(mrSlideSorter.GetContentWindow()->GetPointer()),
      mbAutoScrollInstalled(false),
      mnAnchorIndex(-1),
      mnSecondIndex(-1),
      maButtonBarLock(rSlideSorter)
      mnSecondIndex(-1)
{
}

@@ -1867,105 +1781,6 @@ bool DragAndDropModeHandler::ProcessDragEvent (SelectionFunction::EventDescripto



//===== ButtonModeHandler =====================================================

ButtonModeHandler::ButtonModeHandler (
    SlideSorter& rSlideSorter,
    SelectionFunction& rSelectionFunction)
    : ModeHandler(rSlideSorter, rSelectionFunction, true)
{
}




ButtonModeHandler::~ButtonModeHandler (void)
{
}




SelectionFunction::Mode ButtonModeHandler::GetMode (void) const
{
    return SelectionFunction::ButtonMode;
}




void ButtonModeHandler::Abort (void)
{
}




bool ButtonModeHandler::ProcessButtonDownEvent (SelectionFunction::EventDescriptor& rDescriptor)
{
    switch (rDescriptor.mnEventCode)
    {
        case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | OVER_BUTTON:
        case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | OVER_BUTTON:
            // Remember page and button index.  When mouse button is
            // released over same page and button then invoke action of that
            // button.
            mrSlideSorter.GetView().GetButtonBar().ProcessButtonDownEvent(
                rDescriptor.mpHitDescriptor,
                rDescriptor.maMouseModelPosition);
            return true;

        default:
            return false;
    }
}




bool ButtonModeHandler::ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor)
{
    switch (rDescriptor.mnEventCode & BUTTON_MASK)
    {
        case LEFT_BUTTON:
            mrSlideSorter.GetView().GetButtonBar().ProcessButtonUpEvent(
                rDescriptor.mpHitDescriptor,
                rDescriptor.maMouseModelPosition);
            mrSelectionFunction.SwitchToNormalMode();
            return true;
    }

    return false;
}




bool ButtonModeHandler::ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor)
{
    switch (rDescriptor.mnEventCode & (MOUSE_MOTION | BUTTON_MASK))
    {
        case MOUSE_MOTION | LEFT_BUTTON:
            mrSlideSorter.GetView().GetButtonBar().ProcessMouseMotionEvent(
                rDescriptor.mpHitDescriptor,
                rDescriptor.maMouseModelPosition,
                true);
            return true;

        case MOUSE_MOTION:
            mrSlideSorter.GetView().GetButtonBar().ProcessMouseMotionEvent(
                rDescriptor.mpHitDescriptor,
                rDescriptor.maMouseModelPosition,
                false);
            return true;
    }

    return false;
}




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

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx
index c93ec65..8f11973 100644
--- a/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx
+++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx
@@ -59,15 +59,6 @@ public:
    /** Blend two points together according to the given weight.
    */
    static double Blend (const double nStartValue, const double nEndValue, const double nWeight);

    /** Apply a gradual change the alpha value from the old value to a
        new value (set prior to this call.)
    */
    static void ApplyButtonAlphaChange(
        const model::SharedPageDescriptor& rpDescriptor,
        view::SlideSorterView& rView,
        const double nButtonAlpha,
        const double nButtonBarAlpha);
};


diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx
index 9fb5754..61dc459 100644
--- a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx
+++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx
@@ -108,7 +108,6 @@ public:
    void SwitchToNormalMode (void);
    void SwitchToDragAndDropMode(const Point aMousePosition);
    void SwitchToMultiSelectionMode (const Point aMousePosition, const sal_uInt32 nEventCode);
    bool SwitchToButtonMode (void);

    void ResetShiftKeySelectionAnchor (void);
    /** Special case handling for when the context menu is hidden.  This
diff --git a/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx b/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx
index 98f26db..5e3562e 100644
--- a/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx
+++ b/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx
@@ -63,13 +63,6 @@ public:
    Point GetLocationOffset (void) const;
    bool SetLocationOffset (const Point& rPoint);

    double GetButtonAlpha (void) const;
    void SetButtonAlpha (const double nAlpha);
    double GetButtonBarAlpha (void) const;
    void SetButtonBarAlpha (const double nAlpha);
    sal_Int32 GetButtonAlphaAnimationId (void) const;
    void SetButtonAlphaAnimationId (const sal_Int32 nAnimationId);

    sal_Int32 mnPageId; // For debugging

private:
@@ -81,10 +74,6 @@ private:

    Point maLocationOffset;
    sal_Int32 mnLocationAnimationId;

    double mnButtonAlpha;
    double mnButtonBarAlpha;
    sal_Int32 mnButtonAlphaAnimationId;
};

} } } // end of namespace ::sd::slidesorter::model
diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx
index 30208ef..f8cf71e 100644
--- a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx
+++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx
@@ -63,7 +63,6 @@ class SlideSorterModel;

namespace sd { namespace slidesorter { namespace view {

class ButtonBar;
class LayeredDevice;
class Layouter;
class PageObjectPainter;
@@ -213,25 +212,14 @@ public:
    /** The page under the mouse is not highlighted in some contexts.  Call
        this method on context changes.
    */
    void UpdatePageUnderMouse (bool bAnimate);
    void UpdatePageUnderMouse (
        const Point& rMousePosition,
        const bool bIsMouseButtonDown,
        const bool bAnimate = true);
    void UpdatePageUnderMouse (
        const model::SharedPageDescriptor& rpDescriptor,
        const Point& rMousePosition,
        const bool bIsMouseButtonDown,
        const bool bAnimate = true);
    void SetPageUnderMouse (
        const model::SharedPageDescriptor& rpDescriptor,
        const bool bAnimate = true);
    void UpdatePageUnderMouse ();
    void UpdatePageUnderMouse (const Point& rMousePosition);
    void SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor);

    bool SetState (
        const model::SharedPageDescriptor& rpDescriptor,
        const model::PageDescriptor::State eState,
        const bool bStateValue,
        const bool bAnimate = true);
        const bool bStateValue);

    void UpdateOrientation (void);

@@ -252,7 +240,6 @@ public:
        SharedSdWindow mpWindow;
    };

    ButtonBar& GetButtonBar (void) const;
    ToolTip& GetToolTip (void) const;

protected:
@@ -278,7 +265,6 @@ private:
    ::boost::shared_ptr<SelectionPainter> mpSelectionPainter;
    Region maRedrawRegion;
    SharedILayerPainter mpBackgroundPainter;
    ::boost::scoped_ptr<ButtonBar> mpButtonBar;
    ::boost::scoped_ptr<ToolTip> mpToolTip;
    bool mbIsRearrangePending;
    ::std::vector<Link> maVisibilityChangeListeners;
diff --git a/sd/source/ui/slidesorter/inc/view/SlsButtonBar.hxx b/sd/source/ui/slidesorter/inc/view/SlsButtonBar.hxx
deleted file mode 100644
index c08c328..0000000
--- a/sd/source/ui/slidesorter/inc/view/SlsButtonBar.hxx
+++ /dev/null
@@ -1,294 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_VIEW_BUTTON_BAR_HXX
#define SD_SLIDESORTER_VIEW_BUTTON_BAR_HXX

#include "model/SlsSharedPageDescriptor.hxx"
#include <tools/gen.hxx>
#include <rtl/ustring.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/bmpacc.hxx>
#include <boost/scoped_ptr.hpp>

namespace sd { namespace slidesorter {
class SlideSorter;
} }


namespace sd { namespace slidesorter { namespace view {

class Theme;

class Button;
typedef ::boost::shared_ptr<Button> SharedButton;

/** This is a container of buttons and a coordinating controller.
    The last means that it receives mouse events and forwards them to
    the right button.
*/
class ButtonBar
{
public:
    ButtonBar (SlideSorter& rSlideSorter);
    ~ButtonBar (void);

    void ProcessButtonDownEvent (
        const model::SharedPageDescriptor& rpDescriptor,
        const Point aMouseModelLocation);
    void ProcessButtonUpEvent (
        const model::SharedPageDescriptor& rpDescriptor,
        const Point aMouseModelLocation);
    void ProcessMouseMotionEvent (
        const model::SharedPageDescriptor& rpDescriptor,
        const Point aMouseModelLocation,
        const bool bIsMouseButtonDown);

    void ResetPage (void);

    bool IsMouseOverBar (void) const;

    /** Paint the specified page object.  When this is not the same as the
        one under the mouse (mpDescriptor) then the buttons are all
        painted in their normal state.
    */
    void Paint (
        OutputDevice& rDevice,
        const model::SharedPageDescriptor& rpPageDescriptor);

    bool IsMouseOverButton (void) const;

    /** Return the help text for the button under the mouse.
        @return
            When the mouse is not over a button then an empty string
            is returned.
    */
    ::rtl::OUString GetButtonHelpText (void) const;

    /** Request the button bar to be shown.
        @param bAnimate
            This flag controls whether to just show the button bar (<FALSE/>)
            or to fade it in smoothly (<TRUE/>.)
    */
    void RequestFadeIn (
        const model::SharedPageDescriptor& rpDescriptor,
        const bool bAnimate);

    /** Request the button bar to be hidden.
        @param bAnimate
            This flag controls whether to just hide the button bar (<FALSE/>)
            or to fade it out smoothly (<TRUE/>.)
    */
    void RequestFadeOut (
        const model::SharedPageDescriptor& rpDescriptor,
        const bool bAnimate);

    /** Return whether the button bar is visible for the givn descriptor (or
        being faded in.)
    */
    bool IsVisible (const model::SharedPageDescriptor& rpDescriptor);

    void HandleDataChangeEvent (void);

    class BackgroundTheme;

    /** While at least one Lock object exists the button bar will not be
        displayed.  Used, e.g. during a mouse multiselection to avoid
        confusing and unhelpfull visual signals.
    */
    class Lock
    {
    public:
        Lock (SlideSorter& rSlideSorter);
        ~Lock (void);
    private:
        ButtonBar& mrButtonBar;
    };

private:
    SlideSorter& mrSlideSorter;
    Size maPageObjectSize;
    Rectangle maButtonBoundingBox;
    Point maBackgroundLocation;
    model::SharedPageDescriptor mpDescriptor;
    bool mbIsExcluded;
    boost::shared_ptr<Button> mpButtonUnderMouse;
    // The button on which the mouse button was pressed.
    boost::shared_ptr<Button> mpDownButton;
    ::std::vector<SharedButton> maRegularButtons;
    ::std::vector<SharedButton> maExcludedButtons;
    BitmapEx maNormalBackground;
    bool mbIsMouseOverBar;
    ::boost::scoped_ptr<BackgroundTheme> mpBackgroundTheme;
    int mnLockCount;

    /** Remember the specified page.  If it differs from mpDescriptor then
        the buttons are placed anew.
        @return
            The returned flag indicates whether the mpDescriptor member
            is set to a new value.
    */
    bool SetPage (const model::SharedPageDescriptor& rpDescriptor);
    SharedButton GetButtonAt (const Point aModelLocation);
    bool SetButtonUnderMouse (const SharedButton& rButton = SharedButton());
    void PaintButtonBackground (
        OutputDevice& rDevice,
        const model::SharedPageDescriptor& rpPageDescriptor,
        const Point aOffset);
    void LayoutButtons (const Size aPageModelSize);
    bool LayoutButtons (void);
    BitmapEx CreateBackground (
        const OutputDevice& rTemplateDevice,
        const bool bIsButtonDown) const;
    bool IsMouseOverBar (const Point aModelLocation) const;
    void StartFadeAnimation (
        const model::SharedPageDescriptor& rpDescriptor,
        const double nTargetAlpha,
        const bool bFadeIn);

    void AcquireLock (void);
    void ReleaseLock (void);
};




class Button
{
public:
    Button (
        SlideSorter& rSlideSorter,
        const BitmapEx& rLargeIcon,
        const BitmapEx& rLargeHoverIcon,
        const BitmapEx& rMediumIcon,
        const BitmapEx& rMediumHoverIcon,
        const BitmapEx& rSmallIcon,
        const BitmapEx& rSmallHoverIcon,
        const ::rtl::OUString& rsHelpText);
    virtual ~Button (void);

    enum State { State_Normal, State_Hover, State_Down };
    enum IconSize { IconSize_Large, IconSize_Medium, IconSize_Small };

    /** Set a new state.
        @return
            When the new state is different from the old state
            then <TRUE/> is returned.
    */
    bool SetState (const State eState);

    virtual void Place (const Rectangle aButtonBarBox);
    virtual void Paint (
        OutputDevice& rDevice,
        const Point aOffset,
        const double nAlpha,
        const ::boost::shared_ptr<Theme>& rpTheme) const;
    virtual void ProcessClick (const model::SharedPageDescriptor& rpDescriptor) = 0;

    /** Return the bounding box of the layouted button.
    */
    Rectangle GetBoundingBox (void) const;
    /** Return the minimum size required to completely paint the
        button.
    */
    virtual Size GetSize (void) const;
    virtual Size GetSize (const IconSize eIconSize) const;
    ::rtl::OUString GetHelpText (void) const;
    void SetActiveState (const bool bIsActive);
    bool IsActive (void) const;
    void SetIconSize (const IconSize eIconSize);
    /** By default a button is always enabled.  Override to change this.
    */
    virtual bool IsEnabled (void) const;

protected:
    SlideSorter& mrSlideSorter;
    State meState;
    Rectangle maBoundingBox;
    const ::rtl::OUString msHelpText;
    // Buttons that lie (partly) outside the button bar are deactivated.
    bool mbIsActive;
    IconSize meIconSize;

    const BitmapEx maLargeIcon;
    const BitmapEx maLargeHoverIcon;
    const BitmapEx maMediumIcon;
    const BitmapEx maMediumHoverIcon;
    const BitmapEx maSmallIcon;
    const BitmapEx maSmallHoverIcon;
};



class UnhideButton : public Button
{
public:
    UnhideButton (SlideSorter& rSlideSorter);

protected:
    virtual void ProcessClick (const model::SharedPageDescriptor& rpDescriptor);
};


class StartShowButton : public Button
{
public:
    StartShowButton (SlideSorter& rSlideSorter);
    virtual bool IsEnabled (void) const;

protected:
    virtual void ProcessClick (const model::SharedPageDescriptor& rpDescriptor);
};


class HideButton : public Button
{
public:
    HideButton (SlideSorter& rSlideSorter);

protected:
    virtual void ProcessClick (const model::SharedPageDescriptor& rpDescriptor);
};


class DuplicateButton : public Button
{
public:
    DuplicateButton (SlideSorter& rSlideSorter);
    virtual bool IsEnabled (void) const;

protected:
    virtual void ProcessClick (const model::SharedPageDescriptor& rpDescriptor);
};


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

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx
index ca45f8b..ff2b006 100644
--- a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx
+++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx
@@ -41,7 +41,6 @@ class PageCache;

namespace sd { namespace slidesorter { namespace view {

class ButtonBar;
class Layouter;
class PageObjectLayouter;
class FramePainter;
@@ -96,7 +95,6 @@ private:
    Bitmap maMouseOverBackground;
    Bitmap maMouseOverFocusedBackground;
    Bitmap maMouseOverSelectedAndFocusedBackground;
    ButtonBar& mrButtonBar;
    Size maSize;

    void PaintBackground (
diff --git a/sd/source/ui/slidesorter/inc/view/SlsResource.hrc b/sd/source/ui/slidesorter/inc/view/SlsResource.hrc
index d7a645b..6f1f0df 100644
--- a/sd/source/ui/slidesorter/inc/view/SlsResource.hrc
+++ b/sd/source/ui/slidesorter/inc/view/SlsResource.hrc
@@ -21,71 +21,6 @@

#include "glob.hrc"

#define IMAGE_COMMAND1_LARGE            1
#define IMAGE_COMMAND1_LARGE_HOVER      2
#define IMAGE_COMMAND1_MEDIUM           3
#define IMAGE_COMMAND1_MEDIUM_HOVER     4
#define IMAGE_COMMAND1_SMALL            5
#define IMAGE_COMMAND1_SMALL_HOVER      6

#define IMAGE_COMMAND1_LARGE_HC         7
#define IMAGE_COMMAND1_LARGE_HOVER_HC   8
#define IMAGE_COMMAND1_MEDIUM_HC        9
#define IMAGE_COMMAND1_MEDIUM_HOVER_HC  10
#define IMAGE_COMMAND1_SMALL_HC         11
#define IMAGE_COMMAND1_SMALL_HOVER_HC   12


#define IMAGE_COMMAND2_LARGE            20
#define IMAGE_COMMAND2_LARGE_HOVER      21
#define IMAGE_COMMAND2_MEDIUM           22
#define IMAGE_COMMAND2_MEDIUM_HOVER     23
#define IMAGE_COMMAND2_SMALL            24
#define IMAGE_COMMAND2_SMALL_HOVER      25

#define IMAGE_COMMAND2_LARGE_HC         26
#define IMAGE_COMMAND2_LARGE_HOVER_HC   27
#define IMAGE_COMMAND2_MEDIUM_HC        28
#define IMAGE_COMMAND2_MEDIUM_HOVER_HC  29
#define IMAGE_COMMAND2_SMALL_HC         30
#define IMAGE_COMMAND2_SMALL_HOVER_HC   31

#define IMAGE_COMMAND2B_LARGE           40
#define IMAGE_COMMAND2B_LARGE_HOVER     41
#define IMAGE_COMMAND2B_MEDIUM          42
#define IMAGE_COMMAND2B_MEDIUM_HOVER    43
#define IMAGE_COMMAND2B_SMALL           44
#define IMAGE_COMMAND2B_SMALL_HOVER     45

#define IMAGE_COMMAND2B_LARGE_HC        46
#define IMAGE_COMMAND2B_LARGE_HOVER_HC  47
#define IMAGE_COMMAND2B_MEDIUM_HC       48
#define IMAGE_COMMAND2B_MEDIUM_HOVER_HC 49
#define IMAGE_COMMAND2B_SMALL_HC        50
#define IMAGE_COMMAND2B_SMALL_HOVER_HC  51


#define IMAGE_COMMAND3_LARGE            60
#define IMAGE_COMMAND3_LARGE_HOVER      61
#define IMAGE_COMMAND3_MEDIUM           62
#define IMAGE_COMMAND3_MEDIUM_HOVER     63
#define IMAGE_COMMAND3_SMALL            64
#define IMAGE_COMMAND3_SMALL_HOVER      65

#define IMAGE_COMMAND3_LARGE_HC         66
#define IMAGE_COMMAND3_LARGE_HOVER_HC   67
#define IMAGE_COMMAND3_MEDIUM_HC        68
#define IMAGE_COMMAND3_MEDIUM_HOVER_HC  69
#define IMAGE_COMMAND3_SMALL_HC         70
#define IMAGE_COMMAND3_SMALL_HOVER_HC   71

#define IMAGE_BUTTONBAR_LARGE           80
#define IMAGE_BUTTONBAR_LARGE_HC        81
#define IMAGE_BUTTONBAR_MEDIUM          82
#define IMAGE_BUTTONBAR_MEDIUM_HC       83
#define IMAGE_BUTTONBAR_SMALL           84
#define IMAGE_BUTTONBAR_SMALL_HC        85

#define IMAGE_SHADOW                    90
#define IMAGE_INSERT_SHADOW             91
#define IMAGE_HIDE_SLIDE_OVERLAY        92
diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx
index 2d60385..2a26a8e 100644
--- a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx
+++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx
@@ -46,16 +46,6 @@ class Properties;

namespace sd { namespace slidesorter { namespace view {

const int Theme_ButtonCornerRadius = 3;
const int Theme_ButtonMaxAlpha = 0;
const int Theme_ButtonBarMaxAlpha = 0;
const int Theme_ButtonPaintType = 1;
const int Theme_ButtonBorder = 4;
const int Theme_ButtonGap = 0;
const int Theme_ButtonFadeInDelay = 800;
const int Theme_ButtonFadeInDuration = 100;
const int Theme_ButtonFadeOutDelay = 0;
const int Theme_ButtonFadeOutDuration = 100;
const int Theme_ToolTipDelay = 1000;
const int Theme_FocusIndicatorWidth = 3;

@@ -104,7 +94,6 @@ public:
        Gradient_MouseOverPage,
        Gradient_MouseOverSelectedAndFocusedPage,
        Gradient_FocusedPage,
        Gradient_ButtonBackground,
        _GradientColorType_Size_
    };
    enum GradientColorClass {
@@ -133,39 +122,11 @@ public:
        Icon_RawInsertShadow,
        Icon_HideSlideOverlay,
        Icon_FocusBorder,
        Icon_ButtonBarLarge,
        Icon_ButtonBarMedium,
        Icon_ButtonBarSmall,
        Icon_Command1Large,
        Icon_Command1LargeHover,
        Icon_Command1Medium,
        Icon_Command1MediumHover,
        Icon_Command1Small,
        Icon_Command1SmallHover,
        Icon_Command2Large,
        Icon_Command2LargeHover,
        Icon_Command2Medium,
        Icon_Command2MediumHover,
        Icon_Command2Small,
        Icon_Command2SmallHover,
        Icon_Command2BLarge,
        Icon_Command2BLargeHover,
        Icon_Command2BMedium,
        Icon_Command2BMediumHover,
        Icon_Command2BSmall,
        Icon_Command2BSmallHover,
        Icon_Command3Large,
        Icon_Command3LargeHover,
        Icon_Command3Medium,
        Icon_Command3MediumHover,
        Icon_Command3Small,
        Icon_Command3SmallHover,
        _IconType_Size_
    };
    const BitmapEx& GetIcon (const IconType eType);

private:
    bool mbIsHighContrastMode;
    class GradientDescriptor
    {
    public:
diff --git a/sd/source/ui/slidesorter/model/SlsVisualState.cxx b/sd/source/ui/slidesorter/model/SlsVisualState.cxx
index 4cbafc0..f3cfeca 100644
--- a/sd/source/ui/slidesorter/model/SlsVisualState.cxx
+++ b/sd/source/ui/slidesorter/model/SlsVisualState.cxx
@@ -38,10 +38,7 @@ VisualState::VisualState (const sal_Int32 nPageId)
      meOldVisualState(VS_None),
      mnStateAnimationId(controller::Animator::NotAnAnimationId),
      maLocationOffset(0,0),
      mnLocationAnimationId(controller::Animator::NotAnAnimationId),
      mnButtonAlpha(1.0),
      mnButtonBarAlpha(1.0),
      mnButtonAlphaAnimationId(controller::Animator::NotAnAnimationId)
      mnLocationAnimationId(controller::Animator::NotAnAnimationId)
{
}

@@ -104,42 +101,6 @@ bool VisualState::SetLocationOffset (const Point& rOffset)
}


double VisualState::GetButtonAlpha (void) const
{
    return mnButtonAlpha;
}


void VisualState::SetButtonAlpha (const double nAlpha)
{
    mnButtonAlpha = nAlpha;
}


double VisualState::GetButtonBarAlpha (void) const
{
    return mnButtonBarAlpha;
}


void VisualState::SetButtonBarAlpha (const double nAlpha)
{
    mnButtonBarAlpha = nAlpha;
}


sal_Int32 VisualState::GetButtonAlphaAnimationId (void) const
{
    return mnButtonAlphaAnimationId;
}


void VisualState::SetButtonAlphaAnimationId (const sal_Int32 nAnimationId)
{
    mnButtonAlphaAnimationId = nAnimationId;
}


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

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx
index c403162..23516a9 100644
--- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx
+++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx
@@ -39,7 +39,6 @@
#include "view/SlsPageObjectLayouter.hxx"
#include "view/SlsPageObjectPainter.hxx"
#include "view/SlsILayerPainter.hxx"
#include "view/SlsButtonBar.hxx"
#include "view/SlsToolTip.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsProperties.hxx"
@@ -167,7 +166,6 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter)
      mpSelectionPainter(),
      mpBackgroundPainter(
          new BackgroundPainter(mrSlideSorter.GetTheme()->GetColor(Theme::Color_Background))),
      mpButtonBar(new ButtonBar(mrSlideSorter)),
      mpToolTip(new ToolTip(mrSlideSorter)),
      mbIsRearrangePending(true),
      maVisibilityChangeListeners()
@@ -223,7 +221,7 @@ void SlideSorterView::Dispose (void)
    mpLayeredDevice->Dispose();
    mpPreviewCache.reset();

    SetPageUnderMouse(SharedPageDescriptor(),false);
    SetPageUnderMouse(SharedPageDescriptor());

    // Hide the page to avoid problems in the view when deleting
    // visualized objects
@@ -342,9 +340,6 @@ void SlideSorterView::HandleDataChangeEvent (void)
    if (pPainter)
        pPainter->SetColor(mrSlideSorter.GetTheme()->GetColor(Theme::Color_Background));

    if (mpButtonBar)
        mpButtonBar->HandleDataChangeEvent();

    RequestRepaint();
}

@@ -395,7 +390,7 @@ void SlideSorterView::Rearrange (void)
    {
        mbIsRearrangePending = false;
        Layout();
        UpdatePageUnderMouse(false);
        UpdatePageUnderMouse();
        //        RequestRepaint();
    }
}
@@ -577,7 +572,7 @@ void SlideSorterView::DeterminePageObjectVisibilities (void)


        // Restore the mouse over state.
        UpdatePageUnderMouse(true);
        UpdatePageUnderMouse();
    }
}

@@ -870,15 +865,6 @@ void SlideSorterView::RemoveVisibilityChangeListener(const Link&rListener)



ButtonBar& SlideSorterView::GetButtonBar (void) const
{
    OSL_ASSERT(mpButtonBar);
    return *mpButtonBar;
}




ToolTip& SlideSorterView::GetToolTip (void) const
{
    OSL_ASSERT(mpToolTip);
@@ -900,7 +886,7 @@ void SlideSorterView::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint



void SlideSorterView::UpdatePageUnderMouse (bool bAnimate)
void SlideSorterView::UpdatePageUnderMouse ()
{
    ::boost::shared_ptr<ScrollBar> pVScrollBar (mrSlideSorter.GetVerticalScrollBar());
    ::boost::shared_ptr<ScrollBar> pHScrollBar (mrSlideSorter.GetHorizontalScrollBar());
@@ -909,7 +895,7 @@ void SlideSorterView::UpdatePageUnderMouse (bool bAnimate)
    {
        // One of the scroll bars is tracking mouse movement.  Do not
        // highlight the slide under the mouse in this case.
        SetPageUnderMouse(SharedPageDescriptor(),false);
        SetPageUnderMouse(SharedPageDescriptor());
        return;
    }

@@ -920,81 +906,38 @@ void SlideSorterView::UpdatePageUnderMouse (bool bAnimate)
        const Rectangle aWindowBox (pWindow->GetPosPixel(), pWindow->GetSizePixel());
        if (aWindowBox.IsInside(aPointerState.maPos))
        {
            UpdatePageUnderMouse (
                aPointerState.maPos,
                (aPointerState.mnState & MOUSE_LEFT)!=0,
                bAnimate);
            UpdatePageUnderMouse(aPointerState.maPos);
            return;
        }
    }

    SetPageUnderMouse(SharedPageDescriptor(),false);
    SetPageUnderMouse(SharedPageDescriptor());
}




void SlideSorterView::UpdatePageUnderMouse (
    const Point& rMousePosition,
    const bool bIsMouseButtonDown,
    const bool bAnimate)
    const Point& rMousePosition)
{
    UpdatePageUnderMouse(
        mrSlideSorter.GetController().GetPageAt(rMousePosition),
        rMousePosition,
        bIsMouseButtonDown,
        bAnimate);
}




void SlideSorterView::UpdatePageUnderMouse (
    const model::SharedPageDescriptor& rpDescriptor,
    const Point& rMousePosition,
    const bool bIsMouseButtonDown,
    const bool bAnimate)
{
    // Update the page under the mouse.
    SetPageUnderMouse(rpDescriptor, bAnimate);

    // Tell the button bar about the new mouse position.
    SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
    const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition));

    ::boost::shared_ptr<ViewShell> pMainViewShell (mrSlideSorter.GetViewShellBase()->GetMainViewShell());
    if (pMainViewShell
        && pMainViewShell->GetShellType()!=ViewShell::ST_DRAW)
    {
        const bool bIsMouseOverButtonBar (GetButtonBar().IsMouseOverBar());
        GetButtonBar().ProcessMouseMotionEvent(rpDescriptor, aMouseModelPosition, bIsMouseButtonDown);
        // Set the help text of the slide when the mouse was moved from the
        // button bar back over the preview.
        if (rpDescriptor
            && GetButtonBar().IsMouseOverBar() != bIsMouseOverButtonBar
            && bIsMouseOverButtonBar)
        {
            mpToolTip->ShowDefaultHelpText();
        }
    }
    SetPageUnderMouse(mrSlideSorter.GetController().GetPageAt(rMousePosition));
}




void SlideSorterView::SetPageUnderMouse (
    const model::SharedPageDescriptor& rpDescriptor,
    const bool bAnimate)
    const model::SharedPageDescriptor& rpDescriptor)
{
    if (mpPageUnderMouse != rpDescriptor)
    {
        if (mpPageUnderMouse)
            SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, false, bAnimate);
            SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, false);

        mpPageUnderMouse = rpDescriptor;

        if (mpPageUnderMouse)
            SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, true, bAnimate);
            SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, true);

        // Change the quick help text to display the name of the page under
        // the mouse.
@@ -1008,8 +951,7 @@ void SlideSorterView::SetPageUnderMouse (
bool SlideSorterView::SetState (
    const model::SharedPageDescriptor& rpDescriptor,
    const PageDescriptor::State eState,
    const bool bStateValue,
    const bool bAnimate)
    const bool bStateValue)
{
    model::SharedPageDescriptor pDescriptor (rpDescriptor);
    if ( ! pDescriptor)
@@ -1029,20 +971,6 @@ bool SlideSorterView::SetState (
            RequestRepaint(pDescriptor);
    }

    ::boost::shared_ptr<ViewShell> pMainViewShell(mrSlideSorter.GetViewShellBase()->GetMainViewShell());
    if (pMainViewShell
        && pMainViewShell->GetShellType()!=ViewShell::ST_DRAW)
    {
        // Fade in or out the buttons.
        if (eState == PageDescriptor::ST_MouseOver)
        {
            if (bStateValue)
                GetButtonBar().RequestFadeIn(rpDescriptor, bAnimate);
            else
                GetButtonBar().RequestFadeOut(rpDescriptor, bAnimate);
        }
    }

    return bModified;
}

diff --git a/sd/source/ui/slidesorter/view/SlsButtonBar.cxx b/sd/source/ui/slidesorter/view/SlsButtonBar.cxx
deleted file mode 100644
index 2e41520..0000000
--- a/sd/source/ui/slidesorter/view/SlsButtonBar.cxx
+++ /dev/null
@@ -1,1226 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/


#include "view/SlsButtonBar.hxx"

#include "SlideSorter.hxx"
#include "SlsResource.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "model/SlideSorterModel.hxx"
#include "view/SlsTheme.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsToolTip.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsSlotManager.hxx"
#include "controller/SlsCurrentSlideManager.hxx"
#include "controller/SlsPageSelector.hxx"
#include "controller/SlsAnimator.hxx"
#include "controller/SlsAnimationFunction.hxx"
#include "app.hrc"
#include "strings.hrc"
#include "drawdoc.hxx"
#include "sdmod.hxx"
#include "optsitem.hxx"
#include <svx/svxids.hrc>
#include <sfx2/dispatch.hxx>
#include <vcl/bmpacc.hxx>
#include <vcl/virdev.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <com/sun/star/presentation/XPresentation2.hpp>
#include <boost/bind.hpp>

using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::presentation::XPresentation2;

namespace sd { namespace slidesorter { namespace view {

/** Base class for the painter of the background bar onto which the buttons
    are painted.  It also provides some size information.
*/
class ButtonBar::BackgroundTheme
{
public:
    BackgroundTheme(
        const ::boost::shared_ptr<Theme>& rpTheme,
        const ::std::vector<SharedButton>& rButtons);
    virtual ~BackgroundTheme() { }
    /** Set the preview bounding box, the maximal area in which to display
        buttons.  A call to this method triggers a call to Layout().
    */
    void SetPreviewBoundingBox (const Rectangle& rPreviewBoundingBox);
    Button::IconSize GetIconSize (void) const;

    virtual BitmapEx CreateBackground () const;
    virtual Point GetBackgroundLocation (void);
    virtual Rectangle GetButtonArea (void);

protected:
    ::boost::shared_ptr<Theme> mpTheme;
    Rectangle maPreviewBoundingBox;
    Size maMinimumLargeButtonAreaSize;
    Size maMinimumMediumButtonAreaSize;
    Size maMinimumSmallButtonAreaSize;
    Button::IconSize meIconSize;
    Rectangle maButtonArea;
    Point maBackgroundLocation;

    virtual void Layout (void);

private:
    /// Compute the size of the are for the given button size.
    static Size MinimumSize( Button::IconSize eSize, const ::std::vector<SharedButton>& rButtons );
    void UpdateMinimumIconSizes(const ::std::vector<SharedButton>& rButtons);
};


namespace {
    /** The source mask is essentially multiplied with the given alpha value.
        The result is writen to the result mask.
    */
    void AdaptTransparency (AlphaMask& rMask, const AlphaMask& rSourceMask, const double nAlpha)
    {
        BitmapWriteAccess* pBitmap = rMask.AcquireWriteAccess();
        const BitmapReadAccess* pSourceBitmap = const_cast<AlphaMask&>(rSourceMask).AcquireReadAccess();

        if (pBitmap!=NULL && pSourceBitmap!=NULL)
        {
            const sal_Int32 nWidth (pBitmap->Width());
            const sal_Int32 nHeight (pBitmap->Height());

            for (sal_Int32 nY = 0; nY<nHeight; ++nY)
                for (sal_Int32 nX = 0; nX<nWidth; ++nX)
                {
                    const sal_uInt8 nValue (255 - pSourceBitmap->GetPixel(nY, nX).GetBlueOrIndex());
                    const sal_uInt8 nNewValue (static_cast<sal_uInt8>(nValue * (1-nAlpha)));
                    pBitmap->SetPixel(nY, nX, 255-nNewValue);
                }
        }
    }

} // end of anonymous namespace


//===== ButtonBar::Lock =======================================================

ButtonBar::Lock::Lock (SlideSorter& rSlideSorter)
    : mrButtonBar(rSlideSorter.GetView().GetButtonBar())
{
    mrButtonBar.AcquireLock();
}




ButtonBar::Lock::~Lock (void)
{
    mrButtonBar.ReleaseLock();
}




//===== ButtonBar =============================================================

ButtonBar::ButtonBar (SlideSorter& rSlideSorter)
    : mrSlideSorter(rSlideSorter),
      maPageObjectSize(0,0),
      maButtonBoundingBox(),
      maBackgroundLocation(),
      mpDescriptor(),
      mbIsExcluded(false),
      mpButtonUnderMouse(),
      mpDownButton(),
      maRegularButtons(),
      maExcludedButtons(),
      maNormalBackground(),
      mbIsMouseOverBar(false),
      mpBackgroundTheme(),
      mnLockCount(0)
{
    HandleDataChangeEvent();
}




ButtonBar::~ButtonBar (void)
{
}




void ButtonBar::ProcessButtonDownEvent (
    const model::SharedPageDescriptor& rpDescriptor,
    const Point aMouseModelLocation)
{
    SetButtonUnderMouse(GetButtonAt(aMouseModelLocation));
    if (mpButtonUnderMouse)
        mpButtonUnderMouse->SetState(Button::State_Down);
    mpDownButton = mpButtonUnderMouse;

    mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
}




void ButtonBar::ProcessButtonUpEvent (
    const model::SharedPageDescriptor& rpDescriptor,
    const Point aMouseModelLocation)
{
    SetButtonUnderMouse(GetButtonAt(aMouseModelLocation));
    if (mpButtonUnderMouse)
    {
        mpButtonUnderMouse->SetState(Button::State_Hover);
        if (mpButtonUnderMouse == mpDownButton)
        {
            // This is done only when the buttons are sufficiently visible.
            if (mpDescriptor->GetVisualState().GetButtonAlpha()<0.7)
            {
                mpButtonUnderMouse->ProcessClick(mpDescriptor);
                mbIsExcluded = mpDescriptor->HasState(model::PageDescriptor::ST_Excluded);
                ProcessMouseMotionEvent (rpDescriptor, aMouseModelLocation, false);
            }
        }
    }
    mpDownButton.reset();
    mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
}




void ButtonBar::ProcessMouseMotionEvent (
    const model::SharedPageDescriptor& rpDescriptor,
    const Point aMouseModelLocation,
    const bool bIsMouseButtonDown)
{
    model::SharedPageDescriptor pOldDescriptor (mpDescriptor);
    bool bPageHasChanged (false);
    bool bButtonHasChanged (false);
    bool bButtonStateHasChanged (false);

    // Update the page object for which to manage the buttons.
    bPageHasChanged = SetPage(rpDescriptor);
    mbIsMouseOverBar = IsMouseOverBar(aMouseModelLocation);

    // Update button under mouse.
    if (rpDescriptor)
    {
        bButtonHasChanged = SetButtonUnderMouse(GetButtonAt(aMouseModelLocation));

        if (mpButtonUnderMouse)
        {
            // When the mouse button is down, mark the button under the
            // mouse only as pressed when it is the same button the mouse
            // button was pressed over, and where the button release would
            // lead to a click action.
            if (bIsMouseButtonDown)
            {
                if (mpButtonUnderMouse==mpDownButton)
                    bButtonStateHasChanged = mpButtonUnderMouse->SetState(Button::State_Down);
            }
            else
                bButtonStateHasChanged = mpButtonUnderMouse->SetState(Button::State_Hover);
        }
    }

    // Show a quick help text when the mouse is over a button.
    if (bButtonHasChanged)
    {
        SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
        if (pWindow)
        {
            if (mpButtonUnderMouse)
                mrSlideSorter.GetView().GetToolTip().ShowHelpText(mpButtonUnderMouse->GetHelpText());
            else
                mrSlideSorter.GetView().GetToolTip().ShowDefaultHelpText();
        }
    }

    if (bPageHasChanged || bButtonHasChanged || bButtonStateHasChanged)
    {
        if (pOldDescriptor)
            mrSlideSorter.GetView().RequestRepaint(pOldDescriptor);
        if (mpDescriptor && pOldDescriptor!=mpDescriptor)
            mrSlideSorter.GetView().RequestRepaint(mpDescriptor);
    }
}




void ButtonBar::ResetPage (void)
{
    SetPage(model::SharedPageDescriptor());
}




bool ButtonBar::SetPage (const model::SharedPageDescriptor& rpDescriptor)
{
    if (mpDescriptor != rpDescriptor)
    {
        mpDescriptor = rpDescriptor;

        if (mpDescriptor)
            mbIsExcluded = mpDescriptor->HasState(model::PageDescriptor::ST_Excluded);
        else
            mbIsExcluded = false;
        SetButtonUnderMouse();
        mpDownButton.reset();

        return true;
    }
    else
        return false;
}




SharedButton ButtonBar::GetButtonAt (const Point aModelLocation)
{
    if (IsMouseOverBar(aModelLocation))
    {
        const Point aLocalLocation (aModelLocation - mpDescriptor->GetBoundingBox().TopLeft());
        ::std::vector<SharedButton>& rButtons (
            mbIsExcluded ? maExcludedButtons : maRegularButtons);
        for (sal_uInt32 nIndex=0; nIndex<rButtons.size(); ++nIndex)
        {
            if (rButtons[sal_uInt32(nIndex)]->GetBoundingBox().IsInside(aLocalLocation))
            {
                if (rButtons[sal_uInt32(nIndex)]->IsEnabled())
                    return rButtons[sal_uInt32(nIndex)];
                else
                    return SharedButton();
            }
        }
    }

    return SharedButton();
}




bool ButtonBar::IsMouseOverBar (void) const
{
    return mbIsMouseOverBar;
}




bool ButtonBar::SetButtonUnderMouse (const SharedButton& rButton)
{
    if (mpButtonUnderMouse != rButton)
    {
        if (mpButtonUnderMouse)
            mpButtonUnderMouse->SetState(Button::State_Normal);

        mpButtonUnderMouse = rButton;

        return true;
    }
    else
        return false;
}




void ButtonBar::Paint (
    OutputDevice& rDevice,
    const model::SharedPageDescriptor& rpDescriptor)
{
    if ( ! rpDescriptor)
        return;

    const double nButtonBarAlpha (rpDescriptor->GetVisualState().GetButtonBarAlpha());
    if (nButtonBarAlpha >= 1)
        return;

    LayoutButtons(rpDescriptor->GetBoundingBox().GetSize());

    const Point aOffset (rpDescriptor->GetBoundingBox().TopLeft());

    // Paint the background.
    PaintButtonBackground(rDevice, rpDescriptor, aOffset);

    // Paint the buttons.
    const ::std::vector<SharedButton>& rButtons (
        rpDescriptor->HasState(model::PageDescriptor::ST_Excluded)
            ? maExcludedButtons
            : maRegularButtons);


    const double nButtonAlpha (rpDescriptor->GetVisualState().GetButtonAlpha());
    for (sal_uInt32 nIndex=0; nIndex<rButtons.size(); ++nIndex)
        rButtons[nIndex]->Paint(
            rDevice,
            aOffset,
            nButtonAlpha,
            mrSlideSorter.GetTheme());
}




bool ButtonBar::IsMouseOverButton (void) const
{
    return mpButtonUnderMouse;
}




void ButtonBar::PaintButtonBackground (
    OutputDevice& rDevice,
    const model::SharedPageDescriptor& rpDescriptor,
    const Point aOffset)
{
    if (maNormalBackground.IsEmpty())
    {
        if (mpBackgroundTheme)
            maNormalBackground = mpBackgroundTheme->CreateBackground();
    }
    if (!maNormalBackground.IsEmpty())
    {
        AlphaMask aMask (maNormalBackground.GetSizePixel());
        AdaptTransparency(
            aMask,
            maNormalBackground.GetAlpha(),
            rpDescriptor->GetVisualState().GetButtonBarAlpha());
        rDevice.DrawBitmapEx(maBackgroundLocation+aOffset, BitmapEx(maNormalBackground.GetBitmap(), aMask));
    }
}




bool ButtonBar::IsMouseOverBar (const Point aModelLocation) const
{
    if ( ! mpDescriptor || ! mpDescriptor->GetBoundingBox().IsInside(aModelLocation))
        return false;

    if ( ! maButtonBoundingBox.IsInside(aModelLocation - mpDescriptor->GetBoundingBox().TopLeft()))
        return false;

    return true;
}




void ButtonBar::LayoutButtons (const Size aPageObjectSize)
{
    if (maPageObjectSize != aPageObjectSize)
    {
        maPageObjectSize = aPageObjectSize;

        if (mpBackgroundTheme)
        {
            mpBackgroundTheme->SetPreviewBoundingBox(
                mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetBoundingBox(
                    Point(0,0),
                    PageObjectLayouter::Preview,
                    PageObjectLayouter::ModelCoordinateSystem));
            LayoutButtons();
        }

        // Release the background bitmaps so that on the next paint
        // they are created anew in the right size.
        maNormalBackground.SetEmpty();
    }
}




bool ButtonBar::LayoutButtons (void)
{
    const sal_Int32 nGap = Theme_ButtonGap;
    const sal_Int32 nBorder = Theme_ButtonBorder;

    const Button::IconSize eIconSize (mpBackgroundTheme->GetIconSize());

    // Tell buttons which size they are.
    for (sal_uInt32 nIndex=0; nIndex<maExcludedButtons.size(); ++nIndex)
        maExcludedButtons[nIndex]->SetIconSize(eIconSize);
    for (sal_uInt32 nIndex=0; nIndex<maRegularButtons.size(); ++nIndex)
        maRegularButtons[nIndex]->SetIconSize(eIconSize);

    // Determine maximal height and total width of the buttons.
    // Start with the buttons used for the excluded state.
    sal_Int32 nMaximumHeight (0);
    sal_Int32 nExcludedTotalWidth ((maExcludedButtons.size()-1) * nGap + 2*nBorder);
    for (sal_uInt32 nIndex=0; nIndex<maExcludedButtons.size(); ++nIndex)
    {
        const Size aSize (maExcludedButtons[nIndex]->GetSize());
        if (aSize.Height() > nMaximumHeight)
            nMaximumHeight = aSize.Height();
        nExcludedTotalWidth += aSize.Width();
    }

    // Do the same for the regular buttons.
    sal_Int32 nRegularTotalWidth ((maRegularButtons.size()-1) * nGap + 2*nBorder);
    for (sal_uInt32 nIndex=0; nIndex<maRegularButtons.size(); ++nIndex)
    {
        const Size aSize (maRegularButtons[nIndex]->GetSize());
        if (aSize.Height() > nMaximumHeight)
            nMaximumHeight = aSize.Height();
        nRegularTotalWidth += aSize.Width();
    }
    nMaximumHeight += 2*nBorder;

    // Set up the bounding box of the button bar.
    maButtonBoundingBox = mpBackgroundTheme->GetButtonArea();
    maBackgroundLocation = mpBackgroundTheme->GetBackgroundLocation();
    if (Theme_ButtonPaintType == 1)
    {
        // Center the buttons.
        maButtonBoundingBox.Left() += (maButtonBoundingBox.GetWidth() - nRegularTotalWidth)/2;
        maButtonBoundingBox.Right() = maButtonBoundingBox.Left() + nRegularTotalWidth - 1;
    }

    // Place the buttons.
    Rectangle aBox (maButtonBoundingBox);
    aBox.Right() -= nBorder;
    for (sal_Int32 nIndex=maRegularButtons.size()-1; nIndex>=0; --nIndex)
    {
        maRegularButtons[nIndex]->Place(aBox);
        aBox.Right() = maRegularButtons[nIndex]->GetBoundingBox().Left() - nGap;
    }

    // For slides excluded from the show there is only one icon placed
    // exactly like the second of the regular icons.
    if (maRegularButtons.size()>=2 && maExcludedButtons.size()>=1)
    {
        aBox = maRegularButtons[1]->GetBoundingBox();
        maExcludedButtons[0]->Place(aBox);
    }

    // We return true only when there is no inactive button.
    for (sal_uInt32 nIndex=0; nIndex<maExcludedButtons.size(); ++nIndex)
        if ( ! maExcludedButtons[nIndex]->IsActive())
            return false;
    for (sal_uInt32 nIndex=0; nIndex<maRegularButtons.size(); ++nIndex)
        if ( ! maRegularButtons[nIndex]->IsActive())
            return false;

    return true;
}




void ButtonBar::RequestFadeIn (
    const model::SharedPageDescriptor& rpDescriptor,
    const bool bAnimate)
{
    if ( ! rpDescriptor)
        return;
    if (mnLockCount > 0)
        return;

    const double nMinAlpha (0);
    if ( ! bAnimate)
    {
        rpDescriptor->GetVisualState().SetButtonAlpha(nMinAlpha);
        rpDescriptor->GetVisualState().SetButtonBarAlpha(nMinAlpha);
    }
    else
        StartFadeAnimation(rpDescriptor, nMinAlpha, true);
}




void ButtonBar::RequestFadeOut (
    const model::SharedPageDescriptor& rpDescriptor,
    const bool bAnimate)
{
    if ( ! rpDescriptor)
        return;
    if (mnLockCount > 0)
        return;

    const double nMaxAlpha (1);
    if ( ! bAnimate)
    {
        rpDescriptor->GetVisualState().SetButtonAlpha(nMaxAlpha);
        rpDescriptor->GetVisualState().SetButtonBarAlpha(nMaxAlpha);
    }
    else
        StartFadeAnimation(rpDescriptor, nMaxAlpha, false);
}




bool ButtonBar::IsVisible (const model::SharedPageDescriptor& rpDescriptor)
{
    const double nMaxAlpha (1);
    return rpDescriptor && rpDescriptor->GetVisualState().GetButtonBarAlpha() < nMaxAlpha;
}




void ButtonBar::HandleDataChangeEvent (void)
{
    maExcludedButtons.clear();
    maExcludedButtons.push_back(::boost::shared_ptr<Button>(new UnhideButton(mrSlideSorter)));

    maRegularButtons.clear();
    maRegularButtons.push_back(::boost::shared_ptr<Button>(new StartShowButton(mrSlideSorter)));
    maRegularButtons.push_back(::boost::shared_ptr<Button>(new HideButton(mrSlideSorter)));
    maRegularButtons.push_back(::boost::shared_ptr<Button>(new DuplicateButton(mrSlideSorter)));

    mpBackgroundTheme.reset(
        new BackgroundTheme(
            mrSlideSorter.GetTheme(),
            maRegularButtons));

    // Force layout on next Paint().
    maPageObjectSize = Size(0,0);
}




void ButtonBar::StartFadeAnimation (
    const model::SharedPageDescriptor& rpDescriptor,
    const double nTargetAlpha,
    const bool bFadeIn)
{
    model::SharedPageDescriptor pDescriptor (rpDescriptor);

    const double nCurrentButtonAlpha (pDescriptor->GetVisualState().GetButtonAlpha());
    const double nCurrentButtonBarAlpha (pDescriptor->GetVisualState().GetButtonBarAlpha());

    // Stop a running animation.
    const controller::Animator::AnimationId nId (
        pDescriptor->GetVisualState().GetButtonAlphaAnimationId());
    if (nId != controller::Animator::NotAnAnimationId)
        mrSlideSorter.GetController().GetAnimator()->RemoveAnimation(nId);

    // Prepare the blending functors that translate [0,1] animation
    // times into alpha values of buttons and button bar.
    const ::boost::function<double(double)> aButtonBlendFunctor (
        ::boost::bind(
            controller::AnimationFunction::Blend,
            nCurrentButtonAlpha,
            nTargetAlpha,
            ::boost::bind(controller::AnimationFunction::Linear, _1)));
    const ::boost::function<double(double)> aButtonBarBlendFunctor (
        ::boost::bind(
            controller::AnimationFunction::Blend,
            nCurrentButtonBarAlpha,
            nTargetAlpha,
            ::boost::bind(controller::AnimationFunction::Linear, _1)));

    // Delay the fade in a little bit when the buttons are not visible at
    // all so that we do not leave a trail of half-visible buttons when the
    // mouse is moved across the screen.  No delay on fade out or when the
    // buttons are already showing.  Fade out is faster than fade in.
    const double nDelay (nCurrentButtonBarAlpha>0 && nCurrentButtonBarAlpha<1
        ? 0
        : (bFadeIn ? Theme_ButtonFadeInDelay : Theme_ButtonFadeOutDelay));
    const double nDuration (bFadeIn ? Theme_ButtonFadeInDuration : Theme_ButtonFadeOutDuration);
    pDescriptor->GetVisualState().SetButtonAlphaAnimationId(
        mrSlideSorter.GetController().GetAnimator()->AddAnimation(
            ::boost::bind(
                controller::AnimationFunction::ApplyButtonAlphaChange,
                pDescriptor,
                ::boost::ref(mrSlideSorter.GetView()),
                ::boost::bind(aButtonBlendFunctor, _1),
                ::boost::bind(aButtonBarBlendFunctor, _1)),
            static_cast<sal_Int32>(nDelay),
            static_cast<sal_Int32>(nDuration),
            ::boost::bind(
                &model::VisualState::SetButtonAlphaAnimationId,
                ::boost::ref(pDescriptor->GetVisualState()),
                controller::Animator::NotAnAnimationId)
            ));
}




void ButtonBar::AcquireLock (void)
{
    if (mnLockCount == 0 && mpDescriptor)
        RequestFadeOut(mpDescriptor, true);

    ++mnLockCount;
}




void ButtonBar::ReleaseLock (void)
{
    --mnLockCount;

    if (mnLockCount == 0 && mpDescriptor)
        RequestFadeIn(mpDescriptor, true);
}




//===== BackgroundTheme =====================================================

ButtonBar::BackgroundTheme::BackgroundTheme (
    const ::boost::shared_ptr<Theme>& rpTheme,
    const ::std::vector<SharedButton>& rButtons)
    : mpTheme(rpTheme),
      meIconSize( Button::IconSize_Large ),
      maButtonArea(),
      maBackgroundLocation()
{
    UpdateMinimumIconSizes(rButtons);
}




void ButtonBar::BackgroundTheme::SetPreviewBoundingBox (const Rectangle& rPreviewBoundingBox)
{
    maPreviewBoundingBox = rPreviewBoundingBox;
    Layout();
}


Size ButtonBar::BackgroundTheme::MinimumSize( Button::IconSize eSize,
        const ::std::vector<SharedButton>& rButtons )
{
    int nMaximumHeight = 0;
    const int nGap = Theme_ButtonGap;
    const int nBorder = Theme_ButtonBorder;

    int nTotalWidth = (rButtons.size()-1) * nGap + 2*nBorder;
    for ( int nIndex = 0; nIndex < int( rButtons.size() ); ++nIndex )
    {
        // Update large size.
        Size aSize( rButtons[nIndex]->GetSize(eSize) );
        if ( aSize.Height() > nMaximumHeight )
            nMaximumHeight = aSize.Height();
        nTotalWidth += aSize.Width();
    }
    return Size( nTotalWidth, nMaximumHeight + 2*nBorder );
}


void ButtonBar::BackgroundTheme::UpdateMinimumIconSizes (
    const ::std::vector<SharedButton>& rButtons)
{
    maMinimumLargeButtonAreaSize = MinimumSize( Button::IconSize_Large, rButtons );
    maMinimumMediumButtonAreaSize = MinimumSize( Button::IconSize_Medium, rButtons );
    maMinimumSmallButtonAreaSize = MinimumSize( Button::IconSize_Small, rButtons );
}


Button::IconSize ButtonBar::BackgroundTheme::GetIconSize (void) const
{
    return meIconSize;
}



BitmapEx ButtonBar::BackgroundTheme::CreateBackground () const
{
    OSL_ASSERT(mpTheme);

    // Get images.
    switch (meIconSize)
    {
        case Button::IconSize_Large:
        default:
            return mpTheme->GetIcon(Theme::Icon_ButtonBarLarge);

        case Button::IconSize_Medium:
            return mpTheme->GetIcon(Theme::Icon_ButtonBarMedium);

        case Button::IconSize_Small:
            return mpTheme->GetIcon(Theme::Icon_ButtonBarSmall);
    }
}




Point ButtonBar::BackgroundTheme::GetBackgroundLocation (void)
{
    return maBackgroundLocation;
}




Rectangle ButtonBar::BackgroundTheme::GetButtonArea (void)
{
    return maButtonArea;
}




void ButtonBar::BackgroundTheme::Layout (void)
{
    Size aImageSize (mpTheme->GetIcon(Theme::Icon_ButtonBarLarge).GetSizePixel());
    if (aImageSize.Width() >= maPreviewBoundingBox.GetWidth())
    {
        aImageSize = mpTheme->GetIcon(Theme::Icon_ButtonBarMedium).GetSizePixel();
        if (aImageSize.Width() >= maPreviewBoundingBox.GetWidth())
        {
            meIconSize = Button::IconSize_Small;
            aImageSize = mpTheme->GetIcon(Theme::Icon_ButtonBarSmall).GetSizePixel();
        }
        else
            meIconSize = Button::IconSize_Medium;
    }
    else
    {
        meIconSize = Button::IconSize_Large;
    }

    maBackgroundLocation = Point(
        maPreviewBoundingBox.Left()
            + (maPreviewBoundingBox.GetWidth()-aImageSize.Width())/2,
        maPreviewBoundingBox.Bottom() - aImageSize.Height());
    maButtonArea = Rectangle(maBackgroundLocation, aImageSize);
}




//===== Button ================================================================

Button::Button (
    SlideSorter& rSlideSorter,
    const BitmapEx& rLargeIcon,
    const BitmapEx& rLargeHoverIcon,
    const BitmapEx& rMediumIcon,
    const BitmapEx& rMediumHoverIcon,
    const BitmapEx& rSmallIcon,
    const BitmapEx& rSmallHoverIcon,
    const ::rtl::OUString& rsHelpText)
    : mrSlideSorter(rSlideSorter),
      meState(State_Normal),
      maBoundingBox(),
      msHelpText(rsHelpText),
      mbIsActive(false),
      meIconSize(IconSize_Large),
      maLargeIcon(rLargeIcon),
      maLargeHoverIcon(rLargeHoverIcon.IsEmpty() ? rLargeIcon : rLargeHoverIcon),
      maMediumIcon(rMediumIcon),
      maMediumHoverIcon(rMediumHoverIcon.IsEmpty() ? rMediumIcon : rMediumHoverIcon),
      maSmallIcon(rSmallIcon),
      maSmallHoverIcon(rSmallHoverIcon.IsEmpty() ? rSmallIcon : rSmallHoverIcon)
{
}


Button::~Button (void)
{
}




bool Button::SetState (const State eState)
{
    if (meState != eState)
    {
        meState = eState;
        return true;
    }
    else
        return false;
}




Rectangle Button::GetBoundingBox (void) const
{
    if (mbIsActive)
        return maBoundingBox;
    else
        return Rectangle();
}




::rtl::OUString Button::GetHelpText (void) const
{
    if (mbIsActive)
        return msHelpText;
    else
        return ::rtl::OUString();
}




void Button::SetActiveState (const bool bIsActive)
{
    mbIsActive = bIsActive;
}




bool Button::IsActive (void) const
{
    return mbIsActive;
}




void Button::SetIconSize (const IconSize eIconSize)
{
    meIconSize = eIconSize;
}




bool Button::IsEnabled (void) const
{
    return true;
}


void Button::Place (const Rectangle aButtonBarBox)
{
    const sal_Int32 nWidth (GetSize().Width());
    maBoundingBox = Rectangle(
        aButtonBarBox.Right() - nWidth,
        aButtonBarBox.Top(),
        aButtonBarBox.Right(),
        aButtonBarBox.Bottom());
    SetActiveState(aButtonBarBox.IsInside(maBoundingBox));
}


void Button::Paint (
    OutputDevice& rDevice,
    const Point aOffset,
    const double nAlpha,
    const ::boost::shared_ptr<Theme>&) const
{
    if ( ! mbIsActive)
        return;

    const sal_uInt16 nSavedAntialiasingMode (rDevice.GetAntialiasing());
    rDevice.SetAntialiasing(nSavedAntialiasingMode | ANTIALIASING_ENABLE_B2DDRAW);

    rDevice.SetLineColor();

    // Choose icon.
    BitmapEx aIcon;
    switch (meIconSize)
    {
        case IconSize_Large:
        default:
            if (meState == State_Normal)
                aIcon = maLargeIcon;
            else
                aIcon = maLargeHoverIcon;
            break;

        case IconSize_Medium:
            if (meState == State_Normal)
                aIcon = maMediumIcon;
            else
                aIcon = maMediumHoverIcon;
            break;

        case IconSize_Small:
            if (meState == State_Normal)
                aIcon = maSmallIcon;
            else
                aIcon = maSmallHoverIcon;
            break;
    }

    // Paint icon.
    if ( ! aIcon.IsEmpty())
    {
        AlphaMask aMask (aIcon.GetSizePixel());
        AdaptTransparency(aMask, aIcon.GetAlpha(), nAlpha);
        rDevice.DrawBitmapEx(
            Point(
                maBoundingBox.Left()
                    + aOffset.X()
                    + (maBoundingBox.GetWidth()-aIcon.GetSizePixel().Width())/2,
                maBoundingBox.Top()
                    + aOffset.Y()
                    + (maBoundingBox.GetHeight()-aIcon.GetSizePixel().Height())/2),
            BitmapEx(aIcon.GetBitmap(), aMask));
    }

    rDevice.SetAntialiasing(nSavedAntialiasingMode);
}


Size Button::GetSize (void) const
{
    return GetSize(meIconSize);
}


Size Button::GetSize (const Button::IconSize eIconSize) const
{
    switch (eIconSize)
    {
        case IconSize_Large:
        default:
            return maLargeIcon.GetSizePixel();

        case IconSize_Medium:
            return maMediumIcon.GetSizePixel();

        case IconSize_Small:
            return maSmallIcon.GetSizePixel();
    }
}




//===== UnhideButton ==========================================================

UnhideButton::UnhideButton (SlideSorter& rSlideSorter)
    : Button(
        rSlideSorter,
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2BLarge),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2BLargeHover),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2BMedium),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2BMediumHover),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2BSmall),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2BSmallHover),
        String(SdResId(STRING_SHOW_SLIDE)))
{
}




void UnhideButton::ProcessClick (const model::SharedPageDescriptor& rpDescriptor)
{
    if ( ! rpDescriptor)
        return;
    mrSlideSorter.GetController().GetSlotManager()->ChangeSlideExclusionState(
        (rpDescriptor->HasState(model::PageDescriptor::ST_Selected)
            ? model::SharedPageDescriptor()
            : rpDescriptor),
        false);
}




//===== StartSlideShowButton ==================================================

StartShowButton::StartShowButton (SlideSorter& rSlideSorter)
    : Button(
        rSlideSorter,
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command1Large),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command1LargeHover),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command1Medium),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command1MediumHover),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command1Small),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command1SmallHover),
        String(SdResId(STRING_START_SLIDESHOW)))
{
}




bool StartShowButton::IsEnabled (void) const
{
    ViewShell* pViewShell = mrSlideSorter.GetViewShell();
    if (pViewShell == NULL)
        return false;
    SfxDispatcher* pDispatcher = pViewShell->GetDispatcher();
    if (pDispatcher == NULL)
        return false;

    const SfxPoolItem* pState = NULL;
    const SfxItemState eState (pDispatcher->QueryState(SID_PRESENTATION, pState));
    return (eState & SFX_ITEM_DISABLED) == 0;
}




void StartShowButton::ProcessClick (const model::SharedPageDescriptor& rpDescriptor)
{
    // Hide the tool tip early, while the slide show still intializes.
    mrSlideSorter.GetView().GetToolTip().SetPage(model::SharedPageDescriptor());

    Reference< XPresentation2 > xPresentation(
        mrSlideSorter.GetModel().GetDocument()->getPresentation());
    if (xPresentation.is())
    {
        Sequence<PropertyValue> aProperties (1);
        aProperties[0].Name = ::rtl::OUString("FirstPage");
        const ::rtl::OUString sName (rpDescriptor->GetPage()->GetName());
        aProperties[0].Value = Any(sName);

        // We have to temporarily change the options value
        // StartWithActualPage to make the slide show use the
        // specified first page.
        const DocumentType eType (mrSlideSorter.GetModel().GetDocument()->GetDocumentType());
        const sal_Bool bSavedState (SD_MOD()->GetSdOptions(eType)->IsStartWithActualPage());
        SD_MOD()->GetSdOptions(eType)->SetStartWithActualPage(sal_False);

        xPresentation->startWithArguments(aProperties);

        // Restore previous StartWithActualPage value.
        SD_MOD()->GetSdOptions(eType)->SetStartWithActualPage(bSavedState);
    }
}




//===== HideButton ============================================================

HideButton::HideButton (SlideSorter& rSlideSorter)
    : Button(
        rSlideSorter,
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2Large),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2LargeHover),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2Medium),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2MediumHover),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2Small),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command2SmallHover),
        String(SdResId(STRING_HIDE_SLIDE)))
{
}




void HideButton::ProcessClick (const model::SharedPageDescriptor& rpDescriptor)
{
    if ( ! rpDescriptor)
        return;
    mrSlideSorter.GetController().GetSlotManager()->ChangeSlideExclusionState(
        (rpDescriptor->HasState(model::PageDescriptor::ST_Selected)
            ? model::SharedPageDescriptor()
            : rpDescriptor),
        true);
}




//===== DuplicateButton =======================================================

DuplicateButton::DuplicateButton (SlideSorter& rSlideSorter)
    : Button(
        rSlideSorter,
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command3Large),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command3LargeHover),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command3Medium),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command3MediumHover),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command3Small),
        rSlideSorter.GetTheme()->GetIcon(Theme::Icon_Command3SmallHover),
        String(SdResId(STRING_DUPLICATE_SLIDE)))
{
}




bool DuplicateButton::IsEnabled (void) const
{
    ViewShell* pViewShell = mrSlideSorter.GetViewShell();
    if (pViewShell == NULL)
        return false;
    SfxDispatcher* pDispatcher = pViewShell->GetDispatcher();
    if (pDispatcher == NULL)
        return false;

    const SfxPoolItem* pState = NULL;
    const SfxItemState eState (pDispatcher->QueryState(
        SID_DUPLICATE_PAGE,
        pState));
    return (eState & SFX_ITEM_DISABLED) == 0;
}




void DuplicateButton::ProcessClick (const model::SharedPageDescriptor& rpDescriptor)
{
    if ( ! rpDescriptor)
        return;

    mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor(),false);

    // When the page under the button is not selected then set the
    // selection to just this page.
    if ( ! rpDescriptor->HasState(model::PageDescriptor::ST_Selected))
    {
        mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
        mrSlideSorter.GetController().GetPageSelector().SelectPage(rpDescriptor);
    }
    // Duplicate the selected pages.  Insert the new pages right
    // after the current selection and select them
    if (mrSlideSorter.GetViewShell() != NULL
        && mrSlideSorter.GetViewShell()->GetDispatcher() != NULL)
    {
        mrSlideSorter.GetViewShell()->GetDispatcher()->Execute(
            SID_DUPLICATE_PAGE,
            SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
    }
}



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

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx
index 5cb1536..d289c95 100644
--- a/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx
+++ b/sd/source/ui/slidesorter/view/SlsPageObjectPainter.cxx
@@ -34,7 +34,6 @@
#include "view/SlsPageObjectLayouter.hxx"
#include "view/SlsLayouter.hxx"
#include "view/SlsTheme.hxx"
#include "view/SlsButtonBar.hxx"
#include "SlsFramePainter.hxx"
#include "cache/SlsPageCache.hxx"
#include "controller/SlsProperties.hxx"
@@ -67,7 +66,6 @@ PageObjectPainter::PageObjectPainter (
      maFocusedSelectionBackground(),
      maMouseOverBackground(),
      maMouseOverFocusedBackground(),
      mrButtonBar(rSlideSorter.GetView().GetButtonBar()),
      maSize()
{
    // Replace the color (not the alpha values) in the focus border with a
@@ -111,7 +109,6 @@ void PageObjectPainter::PaintPageObject (
    PaintPreview(rDevice, rpDescriptor);
    PaintPageNumber(rDevice, rpDescriptor);
    PaintTransitionEffect(rDevice, rpDescriptor);
    mrButtonBar.Paint(rDevice, rpDescriptor);

    rDevice.SetAntialiasing(nSavedAntialiasingMode);
}
diff --git a/sd/source/ui/slidesorter/view/SlsResource.src b/sd/source/ui/slidesorter/view/SlsResource.src
index 16cb3b9..2862d8d 100644
--- a/sd/source/ui/slidesorter/view/SlsResource.src
+++ b/sd/source/ui/slidesorter/view/SlsResource.src
@@ -29,238 +29,6 @@

Resource RID_SLIDESORTER_ICONS
{
    Image IMAGE_COMMAND1_LARGE
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_large.png" ; };
    };
    Image IMAGE_COMMAND1_LARGE_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_large_hover.png" ; };
    };
    Image IMAGE_COMMAND1_MEDIUM
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_medium.png" ; };
    };
    Image IMAGE_COMMAND1_MEDIUM_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_medium_hover.png" ; };
    };
    Image IMAGE_COMMAND1_SMALL
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_small.png" ; };
    };
    Image IMAGE_COMMAND1_SMALL_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_small_hover.png" ; };
    };

    Image IMAGE_COMMAND1_LARGE_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_large_hc.png" ; };
    };
    Image IMAGE_COMMAND1_LARGE_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_large_hover_hc.png" ; };
    };
    Image IMAGE_COMMAND1_MEDIUM_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_medium_hc.png" ; };
    };
    Image IMAGE_COMMAND1_MEDIUM_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_medium_hover_hc.png" ; };
    };
    Image IMAGE_COMMAND1_SMALL_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_small_hc.png" ; };
    };
    Image IMAGE_COMMAND1_SMALL_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command1_small_hover_hc.png" ; };
    };


    Image IMAGE_COMMAND2_LARGE
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_large.png" ; };
    };
    Image IMAGE_COMMAND2_LARGE_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_large_hover.png" ; };
    };
    Image IMAGE_COMMAND2_MEDIUM
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_medium.png" ; };
    };
    Image IMAGE_COMMAND2_MEDIUM_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_medium_hover.png" ; };
    };
    Image IMAGE_COMMAND2_SMALL
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_small.png" ; };
    };
    Image IMAGE_COMMAND2_SMALL_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_small_hover.png" ; };
    };

    Image IMAGE_COMMAND2_LARGE_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_large_hc.png" ; };
    };
    Image IMAGE_COMMAND2_LARGE_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_large_hover_hc.png" ; };
    };
    Image IMAGE_COMMAND2_MEDIUM_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_medium_hc.png" ; };
    };
    Image IMAGE_COMMAND2_MEDIUM_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_medium_hover_hc.png" ; };
    };
    Image IMAGE_COMMAND2_SMALL_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_small_hc.png" ; };
    };
    Image IMAGE_COMMAND2_SMALL_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2_small_hover_hc.png" ; };
    };


    Image IMAGE_COMMAND2B_LARGE
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_large.png" ; };
    };
    Image IMAGE_COMMAND2B_LARGE_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_large_hover.png" ; };
    };
    Image IMAGE_COMMAND2B_MEDIUM
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_medium.png" ; };
    };
    Image IMAGE_COMMAND2B_MEDIUM_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_medium_hover.png" ; };
    };
    Image IMAGE_COMMAND2B_SMALL
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_small.png" ; };
    };
    Image IMAGE_COMMAND2B_SMALL_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_small_hover.png" ; };
    };

    Image IMAGE_COMMAND2B_LARGE_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_large_hc.png" ; };
    };
    Image IMAGE_COMMAND2B_LARGE_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_large_hover_hc.png" ; };
    };
    Image IMAGE_COMMAND2B_MEDIUM_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_medium_hc.png" ; };
    };
    Image IMAGE_COMMAND2B_MEDIUM_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_medium_hover_hc.png" ; };
    };
    Image IMAGE_COMMAND2B_SMALL_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_small_hc.png" ; };
    };
    Image IMAGE_COMMAND2B_SMALL_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command2b_small_hover_hc.png" ; };
    };


    Image IMAGE_COMMAND3_LARGE
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_large.png" ; };
    };
    Image IMAGE_COMMAND3_LARGE_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_large_hover.png" ; };
    };
    Image IMAGE_COMMAND3_MEDIUM
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_medium.png" ; };
    };
    Image IMAGE_COMMAND3_MEDIUM_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_medium_hover.png" ; };
    };
    Image IMAGE_COMMAND3_SMALL
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_small.png" ; };
    };
    Image IMAGE_COMMAND3_SMALL_HOVER
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_small_hover.png" ; };
    };

    Image IMAGE_COMMAND3_LARGE_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_large_hc.png" ; };
    };
    Image IMAGE_COMMAND3_LARGE_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_large_hover_hc.png" ; };
    };
    Image IMAGE_COMMAND3_MEDIUM_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_medium_hc.png" ; };
    };
    Image IMAGE_COMMAND3_MEDIUM_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_medium_hover_hc.png" ; };
    };
    Image IMAGE_COMMAND3_SMALL_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_small_hc.png" ; };
    };
    Image IMAGE_COMMAND3_SMALL_HOVER_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command3_small_hover_hc.png" ; };
    };


    Image IMAGE_BUTTONBAR_LARGE
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command_background_large.png" ; };
    };
    Image IMAGE_BUTTONBAR_MEDIUM
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command_background_medium.png" ; };
    };
    Image IMAGE_BUTTONBAR_SMALL
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command_background_small.png" ; };
    };

    Image IMAGE_BUTTONBAR_LARGE_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command_background_large_hc.png" ; };
    };
    Image IMAGE_BUTTONBAR_MEDIUM_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command_background_medium_hc.png" ; };
    };
    Image IMAGE_BUTTONBAR_SMALL_HC
    {
        ImageBitmap = Bitmap { File = "slide_sorter_command_background_small_hc.png" ; };
    };



    Image IMAGE_SHADOW
    {
        ImageBitmap = Bitmap { File = "slide_sorter_shadow.png" ; };
diff --git a/sd/source/ui/slidesorter/view/SlsTheme.cxx b/sd/source/ui/slidesorter/view/SlsTheme.cxx
index c6b2bc5..4e7556d 100644
--- a/sd/source/ui/slidesorter/view/SlsTheme.cxx
+++ b/sd/source/ui/slidesorter/view/SlsTheme.cxx
@@ -73,8 +73,7 @@ ColorData HGBAdapt (


Theme::Theme (const ::boost::shared_ptr<controller::Properties>& rpProperties)
    : mbIsHighContrastMode(false),
      maBackgroundColor(rpProperties->GetBackgroundColor().GetColor()),
    : maBackgroundColor(rpProperties->GetBackgroundColor().GetColor()),
      maPageBackgroundColor(COL_WHITE),
      maGradients(),
      maIcons(),
@@ -101,9 +100,6 @@ Theme::Theme (const ::boost::shared_ptr<controller::Properties>& rpProperties)

void Theme::Update (const ::boost::shared_ptr<controller::Properties>& rpProperties)
{
    const bool bSavedHighContrastMode (mbIsHighContrastMode);
    mbIsHighContrastMode = rpProperties->IsHighContrastModeActive();

    // Set up colors.
    maBackgroundColor = rpProperties->GetBackgroundColor().GetColor();
    maPageBackgroundColor = svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
@@ -127,7 +123,6 @@ void Theme::Update (const ::boost::shared_ptr<controller::Properties>& rpPropert
    SetGradient(Gradient_MouseOverSelectedAndFocusedPage, aSelectionColor, 75, 75, +100,+100, -50,-75);
    SetGradient(Gradient_FocusedPage, aSelectionColor, -1,-1, 0,0, -50,-75);

    SetGradient(Gradient_ButtonBackground, Black, -1,-1, 0,0, 0,0);
    SetGradient(Gradient_NormalPage, maBackgroundColor, -1,-1, 0,0, 0,0);

    // The focused gradient needs special handling because its fill color is
@@ -136,87 +131,14 @@ void Theme::Update (const ::boost::shared_ptr<controller::Properties>& rpPropert
    GetGradient(Gradient_FocusedPage).maFillColor2 = GetGradient(Gradient_NormalPage).maFillColor2;

    // Set up icons.
    if (bSavedHighContrastMode != mbIsHighContrastMode || maIcons.empty())
    if (maIcons.empty())
    {
        LocalResource aResource (RID_SLIDESORTER_ICONS);

        maIcons.resize(_IconType_Size_);
        if (mbIsHighContrastMode)
        {
            InitializeIcon(Icon_RawShadow, IMAGE_SHADOW);
            InitializeIcon(Icon_RawInsertShadow, IMAGE_INSERT_SHADOW);
            InitializeIcon(Icon_HideSlideOverlay, IMAGE_HIDE_SLIDE_OVERLAY);

            InitializeIcon(Icon_ButtonBarLarge, IMAGE_BUTTONBAR_LARGE_HC);
            InitializeIcon(Icon_ButtonBarMedium, IMAGE_BUTTONBAR_MEDIUM_HC);
            InitializeIcon(Icon_ButtonBarSmall, IMAGE_BUTTONBAR_SMALL_HC);

            InitializeIcon(Icon_Command1Large, IMAGE_COMMAND1_LARGE_HC);
            InitializeIcon(Icon_Command1LargeHover, IMAGE_COMMAND1_LARGE_HOVER_HC);
            InitializeIcon(Icon_Command1Medium, IMAGE_COMMAND1_MEDIUM_HC);
            InitializeIcon(Icon_Command1MediumHover, IMAGE_COMMAND1_MEDIUM_HOVER_HC);
            InitializeIcon(Icon_Command1Small, IMAGE_COMMAND1_SMALL_HC);
            InitializeIcon(Icon_Command1SmallHover, IMAGE_COMMAND1_SMALL_HOVER_HC);

            InitializeIcon(Icon_Command2Large, IMAGE_COMMAND2_LARGE_HC);
            InitializeIcon(Icon_Command2LargeHover, IMAGE_COMMAND2_LARGE_HOVER_HC);
            InitializeIcon(Icon_Command2Medium, IMAGE_COMMAND2_MEDIUM_HC);
            InitializeIcon(Icon_Command2MediumHover, IMAGE_COMMAND2_MEDIUM_HOVER_HC);
            InitializeIcon(Icon_Command2Small, IMAGE_COMMAND2_SMALL_HC);
            InitializeIcon(Icon_Command2SmallHover, IMAGE_COMMAND2_SMALL_HOVER_HC);

            InitializeIcon(Icon_Command2BLarge, IMAGE_COMMAND2B_LARGE_HC);
            InitializeIcon(Icon_Command2BLargeHover, IMAGE_COMMAND2B_LARGE_HOVER_HC);
            InitializeIcon(Icon_Command2BMedium, IMAGE_COMMAND2B_MEDIUM_HC);
            InitializeIcon(Icon_Command2BMediumHover, IMAGE_COMMAND2B_MEDIUM_HOVER_HC);
            InitializeIcon(Icon_Command2BSmall, IMAGE_COMMAND2B_SMALL_HC);
            InitializeIcon(Icon_Command2BSmallHover, IMAGE_COMMAND2B_SMALL_HOVER_HC);

            InitializeIcon(Icon_Command3Large, IMAGE_COMMAND3_LARGE_HC);
            InitializeIcon(Icon_Command3LargeHover, IMAGE_COMMAND3_LARGE_HOVER_HC);
            InitializeIcon(Icon_Command3Medium, IMAGE_COMMAND3_SMALL_HC);
            InitializeIcon(Icon_Command3MediumHover, IMAGE_COMMAND3_SMALL_HOVER_HC);
            InitializeIcon(Icon_Command3Small, IMAGE_COMMAND3_SMALL_HC);
            InitializeIcon(Icon_Command3SmallHover, IMAGE_COMMAND3_SMALL_HOVER_HC);
        }
        else
        {
            InitializeIcon(Icon_RawShadow, IMAGE_SHADOW);
            InitializeIcon(Icon_RawInsertShadow, IMAGE_INSERT_SHADOW);
            InitializeIcon(Icon_HideSlideOverlay, IMAGE_HIDE_SLIDE_OVERLAY);

            InitializeIcon(Icon_ButtonBarLarge, IMAGE_BUTTONBAR_LARGE);
            InitializeIcon(Icon_ButtonBarMedium, IMAGE_BUTTONBAR_MEDIUM);
            InitializeIcon(Icon_ButtonBarSmall, IMAGE_BUTTONBAR_SMALL);

            InitializeIcon(Icon_Command1Large, IMAGE_COMMAND1_LARGE);
            InitializeIcon(Icon_Command1LargeHover, IMAGE_COMMAND1_LARGE_HOVER);
            InitializeIcon(Icon_Command1Medium, IMAGE_COMMAND1_MEDIUM);
            InitializeIcon(Icon_Command1MediumHover, IMAGE_COMMAND1_MEDIUM_HOVER);
            InitializeIcon(Icon_Command1Small, IMAGE_COMMAND1_SMALL);
            InitializeIcon(Icon_Command1SmallHover, IMAGE_COMMAND1_SMALL_HOVER);

            InitializeIcon(Icon_Command2Large, IMAGE_COMMAND2_LARGE);
            InitializeIcon(Icon_Command2LargeHover, IMAGE_COMMAND2_LARGE_HOVER);
            InitializeIcon(Icon_Command2Medium, IMAGE_COMMAND2_MEDIUM);
            InitializeIcon(Icon_Command2MediumHover, IMAGE_COMMAND2_MEDIUM_HOVER);
            InitializeIcon(Icon_Command2Small, IMAGE_COMMAND2_SMALL);
            InitializeIcon(Icon_Command2SmallHover, IMAGE_COMMAND2_SMALL_HOVER);

            InitializeIcon(Icon_Command2BLarge, IMAGE_COMMAND2B_LARGE);
            InitializeIcon(Icon_Command2BLargeHover, IMAGE_COMMAND2B_LARGE_HOVER);
            InitializeIcon(Icon_Command2BMedium, IMAGE_COMMAND2B_MEDIUM);
            InitializeIcon(Icon_Command2BMediumHover, IMAGE_COMMAND2B_MEDIUM_HOVER);
            InitializeIcon(Icon_Command2BSmall, IMAGE_COMMAND2B_SMALL);
            InitializeIcon(Icon_Command2BSmallHover, IMAGE_COMMAND2B_SMALL_HOVER);

            InitializeIcon(Icon_Command3Large, IMAGE_COMMAND3_LARGE);
            InitializeIcon(Icon_Command3LargeHover, IMAGE_COMMAND3_LARGE_HOVER);
            InitializeIcon(Icon_Command3Medium, IMAGE_COMMAND3_MEDIUM);
            InitializeIcon(Icon_Command3MediumHover, IMAGE_COMMAND3_MEDIUM_HOVER);
            InitializeIcon(Icon_Command3Small, IMAGE_COMMAND3_SMALL);
            InitializeIcon(Icon_Command3SmallHover, IMAGE_COMMAND3_SMALL_HOVER);
        }
        InitializeIcon(Icon_RawShadow, IMAGE_SHADOW);
        InitializeIcon(Icon_RawInsertShadow, IMAGE_INSERT_SHADOW);
        InitializeIcon(Icon_HideSlideOverlay, IMAGE_HIDE_SLIDE_OVERLAY);
        InitializeIcon(Icon_FocusBorder, IMAGE_FOCUS_BORDER);
    }
}